LEFT | RIGHT |
1 /* | 1 /* |
2 * $Id$ | |
3 * | |
4 * ***** BEGIN GPL LICENSE BLOCK ***** | 2 * ***** BEGIN GPL LICENSE BLOCK ***** |
5 * | 3 * |
6 * This program is free software; you can redistribute it and/or | 4 * This program is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU General Public License | 5 * modify it under the terms of the GNU General Public License |
8 * as published by the Free Software Foundation; either version 2 | 6 * as published by the Free Software Foundation; either version 2 |
9 * of the License, or (at your option) any later version. | 7 * of the License, or (at your option) any later version. |
10 * | 8 * |
11 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
(...skipping 11 matching lines...) Expand all Loading... |
25 * Contributor(s): none yet. | 23 * Contributor(s): none yet. |
26 * | 24 * |
27 * ***** END GPL LICENSE BLOCK ***** | 25 * ***** END GPL LICENSE BLOCK ***** |
28 * Convert blender data to ketsji | 26 * Convert blender data to ketsji |
29 */ | 27 */ |
30 | 28 |
31 /** \file gameengine/Converter/BL_BlenderDataConversion.cpp | 29 /** \file gameengine/Converter/BL_BlenderDataConversion.cpp |
32 * \ingroup bgeconv | 30 * \ingroup bgeconv |
33 */ | 31 */ |
34 | 32 |
35 | 33 #ifdef _MSC_VER |
36 #if defined(WIN32) && !defined(FREE_WINDOWS) | 34 # pragma warning (disable:4786) |
37 #pragma warning (disable : 4786) | |
38 #endif | 35 #endif |
39 | 36 |
40 #include <math.h> | 37 #include <math.h> |
| 38 #include <vector> |
| 39 #include <algorithm> |
41 | 40 |
42 #include "BL_BlenderDataConversion.h" | 41 #include "BL_BlenderDataConversion.h" |
43 #include "KX_BlenderGL.h" | |
44 #include "KX_BlenderScalarInterpolator.h" | 42 #include "KX_BlenderScalarInterpolator.h" |
45 | 43 |
46 #include "RAS_IPolygonMaterial.h" | 44 #include "RAS_IPolygonMaterial.h" |
47 #include "KX_PolygonMaterial.h" | |
48 | 45 |
49 // Expressions | 46 // Expressions |
50 #include "ListValue.h" | 47 #include "ListValue.h" |
51 #include "IntValue.h" | 48 #include "IntValue.h" |
52 // Collision & Fuzzics LTD | 49 // Collision & Fuzzics LTD |
53 | 50 |
54 #include "PHY_Pro.h" | 51 #include "PHY_Pro.h" |
55 | 52 |
56 | 53 |
57 #include "KX_Scene.h" | 54 #include "KX_Scene.h" |
(...skipping 16 matching lines...) Expand all Loading... |
74 #include "MT_Transform.h" | 71 #include "MT_Transform.h" |
75 #include "MT_MinMax.h" | 72 #include "MT_MinMax.h" |
76 #include "SCA_IInputDevice.h" | 73 #include "SCA_IInputDevice.h" |
77 #include "RAS_TexMatrix.h" | 74 #include "RAS_TexMatrix.h" |
78 #include "RAS_ICanvas.h" | 75 #include "RAS_ICanvas.h" |
79 #include "RAS_MaterialBucket.h" | 76 #include "RAS_MaterialBucket.h" |
80 //#include "KX_BlenderPolyMaterial.h" | 77 //#include "KX_BlenderPolyMaterial.h" |
81 #include "RAS_Polygon.h" | 78 #include "RAS_Polygon.h" |
82 #include "RAS_TexVert.h" | 79 #include "RAS_TexVert.h" |
83 #include "RAS_BucketManager.h" | 80 #include "RAS_BucketManager.h" |
84 #include "RAS_IRenderTools.h" | |
85 #include "BL_Material.h" | 81 #include "BL_Material.h" |
86 #include "KX_BlenderMaterial.h" | 82 #include "KX_BlenderMaterial.h" |
87 #include "BL_Texture.h" | 83 #include "BL_Texture.h" |
88 | 84 |
89 #include "DNA_action_types.h" | 85 #include "DNA_action_types.h" |
90 #include "BKE_main.h" | 86 #include "BKE_main.h" |
91 #include "BKE_global.h" | 87 #include "BKE_global.h" |
92 #include "BKE_object.h" | 88 #include "BKE_object.h" |
93 #include "BL_ModifierDeformer.h" | 89 #include "BL_ModifierDeformer.h" |
94 #include "BL_ShapeDeformer.h" | 90 #include "BL_ShapeDeformer.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 #include "BKE_mesh.h" | 132 #include "BKE_mesh.h" |
137 #include "MT_Point3.h" | 133 #include "MT_Point3.h" |
138 | 134 |
139 #include "BLI_math.h" | 135 #include "BLI_math.h" |
140 | 136 |
141 extern "C" { | 137 extern "C" { |
142 #include "BKE_scene.h" | 138 #include "BKE_scene.h" |
143 #include "BKE_customdata.h" | 139 #include "BKE_customdata.h" |
144 #include "BKE_cdderivedmesh.h" | 140 #include "BKE_cdderivedmesh.h" |
145 #include "BKE_DerivedMesh.h" | 141 #include "BKE_DerivedMesh.h" |
| 142 #include "BKE_material.h" /* give_current_material */ |
146 #include "BKE_image.h" | 143 #include "BKE_image.h" |
147 #include "IMB_imbuf_types.h" | 144 #include "BKE_cdderivedmesh.h" |
| 145 #include "BKE_DerivedMesh.h" |
| 146 #include "BKE_material.h" /* give_current_material */ |
| 147 |
| 148 extern Material defmaterial;» /* material.c */ |
148 } | 149 } |
149 | |
150 #include "BKE_material.h" /* give_current_material */ | |
151 /* end of blender include block */ | |
152 | |
153 #include "KX_BlenderInputDevice.h" | |
154 #include "KX_ConvertProperties.h" | |
155 #include "KX_HashedPtr.h" | |
156 | |
157 | |
158 #include "KX_ScalarInterpolator.h" | |
159 | |
160 #include "KX_IpoConvert.h" | |
161 #include "SYS_System.h" | |
162 | |
163 #include "SG_Node.h" | |
164 #include "SG_BBox.h" | |
165 #include "SG_Tree.h" | |
166 | |
167 #include "KX_ConvertPhysicsObject.h" | |
168 #ifdef USE_BULLET | |
169 #include "CcdPhysicsEnvironment.h" | |
170 #include "CcdGraphicController.h" | |
171 #endif | |
172 #include "KX_MotionState.h" | |
173 | |
174 // This file defines relationships between parents and children | |
175 // in the game engine. | |
176 | |
177 #include "KX_SG_NodeRelationships.h" | |
178 #include "KX_SG_BoneParentNodeRelationship.h" | |
179 | |
180 #include "BL_ArmatureObject.h" | |
181 #include "BL_DeformableGameObject.h" | |
182 | |
183 #ifdef __cplusplus | |
184 extern "C" { | |
185 #endif | |
186 //XXX #include "BSE_headerbuttons.h" | |
187 //XXX void update_for_newframe(); | |
188 //void scene_update_for_newframe(struct Scene *sce, unsigned int lay); | |
189 //#include "BKE_ipo.h" | |
190 //void do_all_data_ipos(void); | |
191 #ifdef __cplusplus | |
192 } | |
193 #endif | |
194 | |
195 static bool default_light_mode = 0; | |
196 | |
197 static unsigned int KX_rgbaint2uint_new(unsigned int icol) | |
198 { | |
199 union | |
200 { | |
201 unsigned int integer; | |
202 unsigned char cp[4]; | |
203 } out_color, in_color; | |
204 ········ | |
205 in_color.integer = icol; | |
206 out_color.cp[0] = in_color.cp[3]; // red | |
207 out_color.cp[1] = in_color.cp[2]; // green | |
208 out_color.cp[2] = in_color.cp[1]; // blue | |
209 out_color.cp[3] = in_color.cp[0]; // alpha | |
210 ········ | |
211 return out_color.integer; | |
212 } | |
213 | |
214 /* Now the real converting starts... */ | |
215 static unsigned int KX_Mcol2uint_new(MCol col) | |
216 { | |
217 /* color has to be converted without endian sensitivity. So no shifting!
*/ | |
218 union | |
219 { | |
220 MCol col; | |
221 unsigned int integer; | |
222 unsigned char cp[4]; | |
223 } out_color, in_color; | |
224 | |
225 in_color.col = col; | |
226 out_color.cp[0] = in_color.cp[3]; // red | |
227 out_color.cp[1] = in_color.cp[2]; // green | |
228 out_color.cp[2] = in_color.cp[1]; // blue | |
229 out_color.cp[3] = in_color.cp[0]; // alpha | |
230 ········ | |
231 return out_color.integer; | |
232 } | |
233 | |
234 static void SetDefaultLightMode(Scene* scene) | |
235 { | |
236 default_light_mode = false; | |
237 Scene *sce_iter; | |
238 Base *base; | |
239 | |
240 for(SETLOOPER(scene, sce_iter, base)) | |
241 { | |
242 if (base->object->type == OB_LAMP) | |
243 { | |
244 default_light_mode = true; | |
245 return; | |
246 } | |
247 } | |
248 } | |
249 | |
250 | |
251 // -- | |
252 static void GetRGB(short type, | |
253 MFace* mface, | |
254 MCol* mmcol, | |
255 Material *mat, | |
256 unsigned int &c0,· | |
257 unsigned int &c1,· | |
258 unsigned int &c2,· | |
259 unsigned int &c3) | |
260 { | |
261 unsigned int color = 0xFFFFFFFFL; | |
262 switch(type) | |
263 { | |
264 case 0: // vertex colors | |
265 { | |
266 if(mmcol) { | |
267 c0 = KX_Mcol2uint_new(mmcol[0]); | |
268 c1 = KX_Mcol2uint_new(mmcol[1]); | |
269 c2 = KX_Mcol2uint_new(mmcol[2]); | |
270 if (mface->v4) | |
271 c3 = KX_Mcol2uint_new(mmcol[3]); | |
272 }else // backup white | |
273 { | |
274 c0 = KX_rgbaint2uint_new(color); | |
275 c1 = KX_rgbaint2uint_new(color); | |
276 c2 = KX_rgbaint2uint_new(color);········ | |
277 if (mface->v4) | |
278 c3 = KX_rgbaint2uint_new( color ); | |
279 } | |
280 } break; | |
281 ················ | |
282 ········ | |
283 case 1: // material rgba | |
284 { | |
285 if (mat) { | |
286 union { | |
287 unsigned char cp[4]; | |
288 unsigned int integer; | |
289 } col_converter; | |
290 col_converter.cp[3] = (unsigned char) (mat->r*25
5.0); | |
291 col_converter.cp[2] = (unsigned char) (mat->g*25
5.0); | |
292 col_converter.cp[1] = (unsigned char) (mat->b*25
5.0); | |
293 col_converter.cp[0] = (unsigned char) (mat->alph
a*255.0); | |
294 color = col_converter.integer; | |
295 } | |
296 c0 = KX_rgbaint2uint_new(color); | |
297 c1 = KX_rgbaint2uint_new(color); | |
298 c2 = KX_rgbaint2uint_new(color);········ | |
299 if (mface->v4) | |
300 c3 = KX_rgbaint2uint_new(color); | |
301 } break; | |
302 ················ | |
303 default: // white | |
304 { | |
305 c0 = KX_rgbaint2uint_new(color); | |
306 c1 = KX_rgbaint2uint_new(color); | |
307 c2 = KX_rgbaint2uint_new(color);········ | |
308 if (mface->v4) | |
309 c3 = KX_rgbaint2uint_new(color); | |
310 } break; | |
311 } | |
312 } | |
313 | |
314 typedef struct MTF_localLayer | |
315 { | |
316 MTFace *face; | |
317 const char *name; | |
318 }MTF_localLayer; | |
319 | |
320 static bool imageHasAlpha(Image *ima) | |
321 { | |
322 ImBuf *ibuf; | |
323 void *lock; | |
324 int depth; | |
325 ········ | |
326 ibuf= BKE_image_acquire_ibuf(ima, NULL, &lock); | |
327 depth = (ibuf?ibuf->depth:0); | |
328 BKE_image_release_ibuf(ima, lock); | |
329 | |
330 if (depth == 32) | |
331 return true; | |
332 else | |
333 return false; | |
334 } | |
335 | |
336 // ------------------------------------ | |
337 bool ConvertMaterial( | |
338 BL_Material *material, | |
339 Material *mat,· | |
340 MTFace* tface,·· | |
341 const char *tfaceName, | |
342 MFace* mface,· | |
343 MCol* mmcol, | |
344 MTF_localLayer *layers, | |
345 bool glslmat) | |
346 { | |
347 material->Initialize(); | |
348 int numchan = -1, texalpha = 0; | |
349 bool validmat = (mat!=0); | |
350 bool validface = (tface!=0); | |
351 ········ | |
352 short type = 0; | |
353 if( validmat ) | |
354 type = 1; // material color· | |
355 ········ | |
356 material->IdMode = DEFAULT_BLENDER; | |
357 material->glslmat = (validmat)? glslmat: false; | |
358 material->materialindex = mface->mat_nr; | |
359 | |
360 // -------------------------------- | |
361 if(validmat) { | |
362 | |
363 // use vertex colors by explicitly setting | |
364 if(mat->mode &MA_VERTEXCOLP || glslmat) | |
365 type = 0; | |
366 | |
367 // use lighting? | |
368 material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT; | |
369 material->ras_mode |= ( mat->game.flag & GEMAT_TWOSIDED )?TWOSID
ED:0; | |
370 | |
371 MTex *mttmp = 0; | |
372 numchan = getNumTexChannels(mat); | |
373 int valid_index = 0; | |
374 ················ | |
375 /* In Multitexture use the face texture if and only if | |
376 * it is set in the buttons | |
377 * In GLSL is not working yet :/ 3.2011 */ | |
378 bool facetex = false; | |
379 if(validface && mat->mode &MA_FACETEXTURE)· | |
380 facetex = true; | |
381 | |
382 numchan = numchan>MAXTEX?MAXTEX:numchan; | |
383 if (facetex && numchan == 0) numchan = 1; | |
384 ········ | |
385 // foreach MTex | |
386 for(int i=0; i<numchan; i++) { | |
387 // use face tex | |
388 | |
389 if(i==0 && facetex ) { | |
390 facetex = false; | |
391 Image*tmp = (Image*)(tface->tpage); | |
392 | |
393 if(tmp) { | |
394 material->img[i] = tmp; | |
395 material->texname[i] = material->img[i]-
>id.name; | |
396 material->flag[i] |= MIPMAP; | |
397 | |
398 material->flag[i] |= ( mat->game.alpha_b
lend & GEMAT_ALPHA_SORT )?USEALPHA:0; | |
399 material->flag[i] |= ( mat->game.alpha_b
lend & GEMAT_ALPHA )?USEALPHA:0; | |
400 material->flag[i] |= ( mat->game.alpha_b
lend & GEMAT_ADD )?CALCALPHA:0; | |
401 | |
402 if(material->img[i]->flag & IMA_REFLECT) | |
403 material->mapping[i].mapping |=
USEREFL; | |
404 else | |
405 { | |
406 mttmp = getImageFromMaterial( ma
t, i ); | |
407 if(mttmp && mttmp->texco &TEXCO_
UV) | |
408 { | |
409 STR_String uvName = mttm
p->uvname; | |
410 | |
411 if (!uvName.IsEmpty()) | |
412 material->mappin
g[i].uvCoName = mttmp->uvname; | |
413 else | |
414 material->mappin
g[i].uvCoName = ""; | |
415 } | |
416 material->mapping[i].mapping |=
USEUV; | |
417 } | |
418 | |
419 valid_index++; | |
420 } | |
421 else { | |
422 material->img[i] = 0; | |
423 material->texname[i] = ""; | |
424 } | |
425 continue; | |
426 } | |
427 | |
428 mttmp = getImageFromMaterial( mat, i ); | |
429 if( mttmp ) { | |
430 if( mttmp->tex ) { | |
431 if( mttmp->tex->type == TEX_IMAGE ) { | |
432 material->mtexname[i] = mttmp->t
ex->id.name; | |
433 material->img[i] = mttmp->tex->i
ma; | |
434 if( material->img[i] ) { | |
435 | |
436 material->texname[i] = m
aterial->img[i]->id.name; | |
437 material->flag[i] |= ( m
ttmp->tex->imaflag &TEX_MIPMAP )?MIPMAP:0; | |
438 // ---------------------
-- | |
439 if( mttmp->tex->imaflag
&TEX_USEALPHA ) { | |
440 material->flag[i
] |= USEALPHA; | |
441 } | |
442 // ---------------------
-- | |
443 else if( mttmp->tex->ima
flag &TEX_CALCALPHA ) { | |
444 material->flag[i
] |= CALCALPHA; | |
445 } | |
446 else if(mttmp->tex->flag
&TEX_NEGALPHA) { | |
447 material->flag[i
] |= USENEGALPHA; | |
448 } | |
449 | |
450 material->color_blend[i]
= mttmp->colfac; | |
451 material->flag[i] |= ( m
ttmp->mapto & MAP_ALPHA )?TEXALPHA:0; | |
452 material->flag[i] |= ( m
ttmp->texflag& MTEX_NEGATIVE )?TEXNEG:0; | |
453 | |
454 if(!glslmat && (material
->flag[i] & TEXALPHA)) | |
455 texalpha = 1; | |
456 } | |
457 } | |
458 else if(mttmp->tex->type == TEX_ENVMAP)
{ | |
459 if( mttmp->tex->env->stype == EN
V_LOAD ) { | |
460 ········································ | |
461 material->mtexname[i]
= mttmp->tex->id.name; | |
462 EnvMap *env = mttmp->tex
->env; | |
463 env->ima = mttmp->tex->i
ma; | |
464 material->cubemap[i] = e
nv; | |
465 | |
466 if (material->cubemap[i]
) | |
467 { | |
468 if (!material->c
ubemap[i]->cube[0]) | |
469 BL_Textu
re::SplitEnvMap(material->cubemap[i]); | |
470 | |
471 material->texnam
e[i]= material->cubemap[i]->ima->id.name; | |
472 material->mappin
g[i].mapping |= USEENV; | |
473 } | |
474 } | |
475 } | |
476 material->flag[i] |= (mat->ipo!=0)?HASIP
O:0; | |
477 /// -------------------------------- | |
478 // mapping methods | |
479 material->mapping[i].mapping |= ( mttmp-
>texco & TEXCO_REFL )?USEREFL:0; | |
480 ········································ | |
481 if(mttmp->texco & TEXCO_OBJECT) { | |
482 material->mapping[i].mapping |=
USEOBJ; | |
483 if(mttmp->object) | |
484 material->mapping[i].obj
coname = mttmp->object->id.name; | |
485 } | |
486 else if(mttmp->texco &TEXCO_REFL) | |
487 material->mapping[i].mapping |=
USEREFL; | |
488 else if(mttmp->texco &(TEXCO_ORCO|TEXCO_
GLOB)) | |
489 material->mapping[i].mapping |=
USEORCO; | |
490 else if(mttmp->texco &TEXCO_UV) | |
491 { | |
492 STR_String uvName = mttmp->uvnam
e; | |
493 | |
494 if (!uvName.IsEmpty()) | |
495 material->mapping[i].uvC
oName = mttmp->uvname; | |
496 else | |
497 material->mapping[i].uvC
oName = ""; | |
498 material->mapping[i].mapping |=
USEUV; | |
499 } | |
500 else if(mttmp->texco &TEXCO_NORM) | |
501 material->mapping[i].mapping |=
USENORM; | |
502 else if(mttmp->texco &TEXCO_TANGENT) | |
503 material->mapping[i].mapping |=
USETANG; | |
504 else | |
505 material->mapping[i].mapping |=
DISABLE; | |
506 ········································ | |
507 material->mapping[i].scale[0] = mttmp->s
ize[0]; | |
508 material->mapping[i].scale[1] = mttmp->s
ize[1]; | |
509 material->mapping[i].scale[2] = mttmp->s
ize[2]; | |
510 material->mapping[i].offsets[0] = mttmp-
>ofs[0]; | |
511 material->mapping[i].offsets[1] = mttmp-
>ofs[1]; | |
512 material->mapping[i].offsets[2] = mttmp-
>ofs[2]; | |
513 | |
514 material->mapping[i].projplane[0] = mttm
p->projx; | |
515 material->mapping[i].projplane[1] = mttm
p->projy; | |
516 material->mapping[i].projplane[2] = mttm
p->projz; | |
517 /// -------------------------------- | |
518 ········································ | |
519 switch( mttmp->blendtype ) { | |
520 case MTEX_BLEND: | |
521 material->blend_mode[i] = BLEND_
MIX; | |
522 break; | |
523 case MTEX_MUL: | |
524 material->blend_mode[i] = BLEND_
MUL; | |
525 break; | |
526 case MTEX_ADD: | |
527 material->blend_mode[i] = BLEND_
ADD; | |
528 break; | |
529 case MTEX_SUB: | |
530 material->blend_mode[i] = BLEND_
SUB; | |
531 break; | |
532 case MTEX_SCREEN: | |
533 material->blend_mode[i] = BLEND_
SCR; | |
534 break; | |
535 } | |
536 valid_index++; | |
537 } | |
538 } | |
539 } | |
540 | |
541 // above one tex the switches here | |
542 // are not used | |
543 switch(valid_index) { | |
544 case 0: | |
545 material->IdMode = DEFAULT_BLENDER; | |
546 break; | |
547 case 1: | |
548 material->IdMode = ONETEX; | |
549 break; | |
550 default: | |
551 material->IdMode = GREATERTHAN2; | |
552 break; | |
553 } | |
554 material->SetUsers(mat->id.us); | |
555 | |
556 material->num_enabled = valid_index; | |
557 | |
558 material->speccolor[0] = mat->specr; | |
559 material->speccolor[1] = mat->specg; | |
560 material->speccolor[2] = mat->specb; | |
561 material->hard = (float)mat->har/4.0f; | |
562 material->matcolor[0] = mat->r; | |
563 material->matcolor[1] = mat->g; | |
564 material->matcolor[2] = mat->b; | |
565 material->matcolor[3] = mat->alpha; | |
566 material->alpha = mat->alpha; | |
567 material->emit = mat->emit; | |
568 material->spec_f = mat->spec; | |
569 material->ref = mat->ref; | |
570 material->amb = mat->amb; | |
571 | |
572 material->ras_mode |= (mat->material_type == MA_TYPE_WIRE)? WIRE
: 0; | |
573 } | |
574 else { // No Material | |
575 int valid = 0; | |
576 | |
577 // check for tface tex to fallback on | |
578 if( validface ){ | |
579 material->img[0] = (Image*)(tface->tpage); | |
580 // ------------------------ | |
581 if(material->img[0]) { | |
582 material->texname[0] = material->img[0]->id.name
; | |
583 material->mapping[0].mapping |= ( (material->img
[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0; | |
584 | |
585 /* see if depth of the image is 32bits */ | |
586 if(imageHasAlpha(material->img[0])) { | |
587 material->flag[0] |= USEALPHA; | |
588 material->alphablend = GEMAT_ALPHA; | |
589 } | |
590 else | |
591 material->alphablend = GEMAT_SOLID; | |
592 | |
593 valid++; | |
594 } | |
595 } | |
596 else | |
597 material->alphablend = GEMAT_SOLID; | |
598 | |
599 material->SetUsers(-1); | |
600 material->num_enabled = valid; | |
601 material->IdMode = TEXFACE; | |
602 material->speccolor[0] = 1.f; | |
603 material->speccolor[1] = 1.f; | |
604 material->speccolor[2] = 1.f; | |
605 material->hard = 35.f; | |
606 material->matcolor[0] = 0.5f; | |
607 material->matcolor[1] = 0.5f; | |
608 material->matcolor[2] = 0.5f; | |
609 material->spec_f = 0.5f; | |
610 material->ref = 0.8f; | |
611 | |
612 // No material - old default TexFace properties | |
613 material->ras_mode |= USE_LIGHT; | |
614 } | |
615 MT_Point2 uv[4]; | |
616 MT_Point2 uv2[4]; | |
617 const char *uvName = "", *uv2Name = ""; | |
618 | |
619 ········ | |
620 uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f); | |
621 | |
622 /* No material, what to do? let's see what is in the UV and set the mat
erial accordingly | |
623 light and visible is always on */ | |
624 if( validface ) { | |
625 material->tile = tface->tile; | |
626 ························ | |
627 uv[0].setValue(tface->uv[0]); | |
628 uv[1].setValue(tface->uv[1]); | |
629 uv[2].setValue(tface->uv[2]); | |
630 | |
631 if (mface->v4)· | |
632 uv[3].setValue(tface->uv[3]); | |
633 | |
634 uvName = tfaceName; | |
635 }· | |
636 else { | |
637 // nothing at all | |
638 material->alphablend = GEMAT_SOLID; | |
639 material->tile = 0; | |
640 ················ | |
641 uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f); | |
642 } | |
643 | |
644 if (validmat && validface) { | |
645 material->alphablend = mat->game.alpha_blend; | |
646 } | |
647 | |
648 // with ztransp enabled, enforce alpha blending mode | |
649 if(validmat && (mat->mode & MA_TRANSP) && (mat->mode & MA_ZTRANSP) && (m
aterial->alphablend == GEMAT_SOLID)) | |
650 material->alphablend = GEMAT_ALPHA; | |
651 | |
652 // always zsort alpha + add | |
653 if((ELEM3(material->alphablend, GEMAT_ALPHA, GEMAT_ALPHA_SORT, GEMAT_ADD
) || texalpha) && (material->alphablend != GEMAT_CLIP )) { | |
654 material->ras_mode |= ALPHA; | |
655 material->ras_mode |= (mat && (mat->game.alpha_blend & GEMAT_ALP
HA_SORT))? ZSORT: 0; | |
656 } | |
657 | |
658 // get uv sets | |
659 if(validmat)· | |
660 { | |
661 bool isFirstSet = true; | |
662 | |
663 // only two sets implemented, but any of the eight· | |
664 // sets can make up the two layers | |
665 for (int vind = 0; vind<material->num_enabled; vind++) | |
666 { | |
667 BL_Mapping &map = material->mapping[vind]; | |
668 | |
669 if (map.uvCoName.IsEmpty()) | |
670 isFirstSet = false; | |
671 else | |
672 { | |
673 for (int lay=0; lay<MAX_MTFACE; lay++) | |
674 { | |
675 MTF_localLayer& layer = layers[lay]; | |
676 if (layer.face == 0) break; | |
677 | |
678 if (strcmp(map.uvCoName.ReadPtr(), layer
.name)==0) | |
679 { | |
680 MT_Point2 uvSet[4]; | |
681 | |
682 uvSet[0].setValue(layer.face->uv
[0]); | |
683 uvSet[1].setValue(layer.face->uv
[1]); | |
684 uvSet[2].setValue(layer.face->uv
[2]); | |
685 | |
686 if (mface->v4)· | |
687 uvSet[3].setValue(layer.
face->uv[3]); | |
688 else | |
689 uvSet[3].setValue(0.0f,
0.0f); | |
690 | |
691 if (isFirstSet) | |
692 { | |
693 uv[0] = uvSet[0]; uv[1]
= uvSet[1]; | |
694 uv[2] = uvSet[2]; uv[3]
= uvSet[3]; | |
695 isFirstSet = false; | |
696 uvName = layer.name; | |
697 } | |
698 else if(strcmp(layer.name, uvNam
e) != 0) | |
699 { | |
700 uv2[0] = uvSet[0]; uv2[1
] = uvSet[1]; | |
701 uv2[2] = uvSet[2]; uv2[3
] = uvSet[3]; | |
702 map.mapping |= USECUSTOM
UV; | |
703 uv2Name = layer.name; | |
704 } | |
705 } | |
706 } | |
707 } | |
708 } | |
709 } | |
710 | |
711 unsigned int rgb[4]; | |
712 GetRGB(type,mface,mmcol,mat,rgb[0],rgb[1],rgb[2], rgb[3]); | |
713 | |
714 // swap the material color, so MCol on bitmap font works | |
715 if (validmat && type==1 && (mat->game.flag & GEMAT_TEXT)) | |
716 { | |
717 rgb[0] = KX_rgbaint2uint_new(rgb[0]); | |
718 rgb[1] = KX_rgbaint2uint_new(rgb[1]); | |
719 rgb[2] = KX_rgbaint2uint_new(rgb[2]); | |
720 rgb[3] = KX_rgbaint2uint_new(rgb[3]); | |
721 } | |
722 | |
723 material->SetConversionRGB(rgb); | |
724 material->SetConversionUV(uvName, uv); | |
725 material->SetConversionUV2(uv2Name, uv2); | |
726 | |
727 if(validmat) | |
728 material->matname =(mat->id.name); | |
729 | |
730 material->tface = tface; | |
731 material->material = mat; | |
732 return true; | |
733 } | |
734 | |
735 /* blenderobj can be NULL, make sure its checked for */ | |
736 RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
KX_BlenderSceneConverter *converter) | |
737 { | |
738 RAS_MeshObject *meshobj; | |
739 int lightlayer = blenderobj ? blenderobj->lay:(1<<20)-1; // all layers i
f no object. | |
740 | |
741 if ((meshobj = converter->FindGameMesh(mesh/*, ob->lay*/)) != NULL) | |
742 return meshobj; | |
743 // Get DerivedMesh data | |
744 DerivedMesh *dm = CDDM_from_mesh(mesh, blenderobj); | |
745 | |
746 MVert *mvert = dm->getVertArray(dm); | |
747 int totvert = dm->getNumVerts(dm); | |
748 | |
749 MFace *mface = dm->getFaceArray(dm); | |
750 MTFace *tface = static_cast<MTFace*>(dm->getFaceDataArray(dm, CD_MTFACE)
); | |
751 MCol *mcol = static_cast<MCol*>(dm->getFaceDataArray(dm, CD_MCOL)); | |
752 float (*tangent)[4] = NULL; | |
753 int totface = dm->getNumFaces(dm); | |
754 const char *tfaceName = ""; | |
755 | |
756 if(tface) { | |
757 DM_add_tangent_layer(dm); | |
758 tangent = (float(*)[4])dm->getFaceDataArray(dm, CD_TANGENT); | |
759 } | |
760 | |
761 meshobj = new RAS_MeshObject(mesh); | |
762 | |
763 // Extract avaiable layers | |
764 MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE]; | |
765 for (int lay=0; lay<MAX_MTFACE; lay++) { | |
766 layers[lay].face = 0; | |
767 layers[lay].name = ""; | |
768 } | |
769 | |
770 int validLayers = 0; | |
771 for (int i=0; i<dm->faceData.totlayer; i++) | |
772 { | |
773 if (dm->faceData.layers[i].type == CD_MTFACE) | |
774 { | |
775 assert(validLayers <= 8); | |
776 | |
777 layers[validLayers].face = (MTFace*)(dm->faceData.layers
[i].data); | |
778 layers[validLayers].name = dm->faceData.layers[i].name; | |
779 if(tface == layers[validLayers].face) | |
780 tfaceName = layers[validLayers].name; | |
781 validLayers++; | |
782 } | |
783 } | |
784 | |
785 meshobj->SetName(mesh->id.name + 2); | |
786 meshobj->m_sharedvertex_map.resize(totvert); | |
787 RAS_IPolyMaterial* polymat = NULL; | |
788 STR_String imastr; | |
789 // These pointers will hold persistent material structure during the con
version | |
790 // to avoid countless allocation/deallocation of memory. | |
791 BL_Material* bl_mat = NULL; | |
792 KX_BlenderMaterial* kx_blmat = NULL; | |
793 KX_PolygonMaterial* kx_polymat = NULL; | |
794 | |
795 for (int f=0;f<totface;f++,mface++) | |
796 { | |
797 Material* ma = 0; | |
798 bool collider = true; | |
799 MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0); | |
800 MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0
); | |
801 unsigned int rgb0,rgb1,rgb2,rgb3 = 0; | |
802 | |
803 MT_Point3 pt0, pt1, pt2, pt3; | |
804 MT_Vector3 no0(0,0,0), no1(0,0,0), no2(0,0,0), no3(0,0,0); | |
805 MT_Vector4 tan0(0,0,0,0), tan1(0,0,0,0), tan2(0,0,0,0), tan3(0,0
,0,0); | |
806 | |
807 /* get coordinates, normals and tangents */ | |
808 pt0.setValue(mvert[mface->v1].co); | |
809 pt1.setValue(mvert[mface->v2].co); | |
810 pt2.setValue(mvert[mface->v3].co); | |
811 if (mface->v4) pt3.setValue(mvert[mface->v4].co); | |
812 | |
813 if(mface->flag & ME_SMOOTH) { | |
814 float n0[3], n1[3], n2[3], n3[3]; | |
815 | |
816 normal_short_to_float_v3(n0, mvert[mface->v1].no); | |
817 normal_short_to_float_v3(n1, mvert[mface->v2].no); | |
818 normal_short_to_float_v3(n2, mvert[mface->v3].no); | |
819 no0 = n0; | |
820 no1 = n1; | |
821 no2 = n2; | |
822 | |
823 if(mface->v4) { | |
824 normal_short_to_float_v3(n3, mvert[mface->v4].no
); | |
825 no3 = n3; | |
826 } | |
827 } | |
828 else { | |
829 float fno[3]; | |
830 | |
831 if(mface->v4) | |
832 normal_quad_v3( fno,mvert[mface->v1].co, mvert[m
face->v2].co, mvert[mface->v3].co, mvert[mface->v4].co); | |
833 else | |
834 normal_tri_v3( fno,mvert[mface->v1].co, mvert[mf
ace->v2].co, mvert[mface->v3].co); | |
835 | |
836 no0 = no1 = no2 = no3 = MT_Vector3(fno); | |
837 } | |
838 | |
839 if(tangent) { | |
840 tan0 = tangent[f*4 + 0]; | |
841 tan1 = tangent[f*4 + 1]; | |
842 tan2 = tangent[f*4 + 2]; | |
843 | |
844 if (mface->v4) | |
845 tan3 = tangent[f*4 + 3]; | |
846 } | |
847 if(blenderobj) | |
848 ma = give_current_material(blenderobj, mface->mat_nr+1); | |
849 else | |
850 ma = mesh->mat ? mesh->mat[mface->mat_nr]:NULL; | |
851 | |
852 { | |
853 bool visible = true; | |
854 bool twoside = false; | |
855 | |
856 if(converter->GetMaterials()) { | |
857 /* do Blender Multitexture and Blender GLSL mate
rials */ | |
858 unsigned int rgb[4]; | |
859 MT_Point2 uv[4]; | |
860 | |
861 /* first is the BL_Material */ | |
862 if (!bl_mat) | |
863 bl_mat = new BL_Material(); | |
864 ConvertMaterial(bl_mat, ma, tface, tfaceName, mf
ace, mcol, | |
865 layers, converter->GetGLSLMaterials()); | |
866 | |
867 /* vertex colors and uv's were stored in bl_mat
temporarily */ | |
868 bl_mat->GetConversionRGB(rgb); | |
869 rgb0 = rgb[0]; rgb1 = rgb[1]; | |
870 rgb2 = rgb[2]; rgb3 = rgb[3]; | |
871 | |
872 bl_mat->GetConversionUV(uv); | |
873 uv0 = uv[0]; uv1 = uv[1]; | |
874 uv2 = uv[2]; uv3 = uv[3]; | |
875 | |
876 bl_mat->GetConversionUV2(uv); | |
877 uv20 = uv[0]; uv21 = uv[1]; | |
878 uv22 = uv[2]; uv23 = uv[3]; | |
879 ································ | |
880 /* then the KX_BlenderMaterial */ | |
881 if (kx_blmat == NULL) | |
882 kx_blmat = new KX_BlenderMaterial(); | |
883 | |
884 kx_blmat->Initialize(scene, bl_mat, (ma?&ma->gam
e:NULL)); | |
885 polymat = static_cast<RAS_IPolyMaterial*>(kx_blm
at); | |
886 } | |
887 else { | |
888 /* do Texture Face materials */ | |
889 Image* bima = (tface)? (Image*)tface->tpage: NUL
L; | |
890 imastr = (tface)? (bima? (bima)->id.name : "" )
: ""; | |
891 ················ | |
892 char alpha_blend=0; | |
893 short tile=0; | |
894 int tilexrep=4,tileyrep = 4; | |
895 | |
896 /* set material properties - old TexFace */ | |
897 if (ma) { | |
898 alpha_blend = ma->game.alpha_blend; | |
899 /* Texture Face mode ignores texture but
requires "Face Textures to be True "*/ | |
900 // XXX dfelinto: have to decide on that
DO NOT COMMIT before (if committed please poke me :) | |
901 /** | |
902 if ((ma->mode &MA_FACETEXTURE)==0 && (ma
->game.flag &GEMAT_TEXT)==0) { | |
903 bima = NULL; | |
904 imastr = ""; | |
905 alpha_blend = GEMAT_SOLID;·············· | |
906 } | |
907 else | |
908 alpha_blend = ma->game.alpha_ble
nd; | |
909 */ | |
910 } | |
911 /* check for tface tex to fallback on */ | |
912 else { | |
913 if (bima) { | |
914 /* see if depth of the image is
32 */ | |
915 if (imageHasAlpha(bima)) | |
916 alpha_blend = GEMAT_ALPH
A; | |
917 else | |
918 alpha_blend = GEMAT_SOLI
D; | |
919 } | |
920 else { | |
921 alpha_blend = GEMAT_SOLID; | |
922 } | |
923 } | |
924 | |
925 if (bima) { | |
926 tilexrep = bima->xrep; | |
927 tileyrep = bima->yrep; | |
928 } | |
929 | |
930 /* set UV properties */ | |
931 if(tface) { | |
932 uv0.setValue(tface->uv[0]); | |
933 uv1.setValue(tface->uv[1]); | |
934 uv2.setValue(tface->uv[2]); | |
935 ········ | |
936 if (mface->v4) | |
937 uv3.setValue(tface->uv[3]); | |
938 | |
939 tile = tface->tile; | |
940 }· | |
941 else { | |
942 /* no texfaces */ | |
943 tile = 0; | |
944 } | |
945 | |
946 /* get vertex colors */ | |
947 if (mcol) { | |
948 /* we have vertex colors */ | |
949 rgb0 = KX_Mcol2uint_new(mcol[0]); | |
950 rgb1 = KX_Mcol2uint_new(mcol[1]); | |
951 rgb2 = KX_Mcol2uint_new(mcol[2]); | |
952 ········································ | |
953 if (mface->v4) | |
954 rgb3 = KX_Mcol2uint_new(mcol[3])
; | |
955 } | |
956 else { | |
957 /* no vertex colors, take from material,
otherwise white */ | |
958 unsigned int color = 0xFFFFFFFFL; | |
959 | |
960 if (ma) | |
961 { | |
962 union | |
963 { | |
964 unsigned char cp[4]; | |
965 unsigned int integer; | |
966 } col_converter; | |
967 ················································ | |
968 col_converter.cp[3] = (unsigned
char) (ma->r*255.0); | |
969 col_converter.cp[2] = (unsigned
char) (ma->g*255.0); | |
970 col_converter.cp[1] = (unsigned
char) (ma->b*255.0); | |
971 col_converter.cp[0] = (unsigned
char) (ma->alpha*255.0); | |
972 ················································ | |
973 color = col_converter.integer; | |
974 } | |
975 | |
976 rgb0 = KX_rgbaint2uint_new(color); | |
977 rgb1 = KX_rgbaint2uint_new(color); | |
978 rgb2 = KX_rgbaint2uint_new(color);······ | |
979 ········································ | |
980 if (mface->v4) | |
981 rgb3 = KX_rgbaint2uint_new(color
); | |
982 } | |
983 | |
984 // only zsort alpha + add | |
985 bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEM
AT_ADD, GEMAT_ALPHA_SORT); | |
986 bool zsort = (alpha_blend == GEMAT_ALPHA_SORT); | |
987 bool light = (ma)?(ma->mode & MA_SHLESS)==0:defa
ult_light_mode; | |
988 | |
989 // don't need zort anymore, deal as if it it's a
lpha blend | |
990 if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend
= GEMAT_ALPHA; | |
991 | |
992 if (kx_polymat == NULL) | |
993 kx_polymat = new KX_PolygonMaterial(); | |
994 kx_polymat->Initialize(imastr, ma, (int)mface->m
at_nr, | |
995 tile, tilexrep, tileyrep,· | |
996 alpha_blend, alpha, zsort, light, lightl
ayer, tface, (unsigned int*)mcol); | |
997 polymat = static_cast<RAS_IPolyMaterial*>(kx_pol
ymat); | |
998 ········ | |
999 if (ma) { | |
1000 polymat->m_specular = MT_Vector3(ma->spe
cr, ma->specg, ma->specb)*ma->spec; | |
1001 polymat->m_shininess = (float)ma->har/4.
0; // 0 < ma->har <= 512 | |
1002 polymat->m_diffuse = MT_Vector3(ma->r, m
a->g, ma->b)*(ma->emit + ma->ref); | |
1003 } | |
1004 else { | |
1005 polymat->m_specular.setValue(0.0f,0.0f,0
.0f); | |
1006 polymat->m_shininess = 35.0; | |
1007 } | |
1008 } | |
1009 | |
1010 // set render flags | |
1011 if (ma) | |
1012 { | |
1013 visible = ((ma->game.flag & GEMAT_INVISIBLE)==0)
; | |
1014 twoside = (ma->game.flag & GEMAT_TWOSIDED); | |
1015 collider = ((ma->game.flag & GEMAT_NOPHYSICS)==0
); | |
1016 } | |
1017 else{ | |
1018 visible = true; | |
1019 twoside = false; | |
1020 collider = true; | |
1021 } | |
1022 | |
1023 /* mark face as flat, so vertices are split */ | |
1024 bool flat = (mface->flag & ME_SMOOTH) == 0; | |
1025 | |
1026 // see if a bucket was reused or a new one was created | |
1027 // this way only one KX_BlenderMaterial object has to ex
ist per bucket | |
1028 bool bucketCreated;· | |
1029 RAS_MaterialBucket* bucket = scene->FindBucket(polymat,
bucketCreated); | |
1030 if (bucketCreated) { | |
1031 // this is needed to free up memory afterwards | |
1032 converter->RegisterPolyMaterial(polymat); | |
1033 if(converter->GetMaterials()) { | |
1034 converter->RegisterBlenderMaterial(bl_ma
t); | |
1035 // the poly material has been stored in
the bucket, next time we must create a new one | |
1036 bl_mat = NULL; | |
1037 kx_blmat = NULL; | |
1038 } else { | |
1039 // the poly material has been stored in
the bucket, next time we must create a new one | |
1040 kx_polymat = NULL; | |
1041 } | |
1042 } else { | |
1043 // from now on, use the polygon material from th
e material bucket | |
1044 polymat = bucket->GetPolyMaterial(); | |
1045 // keep the material pointers, they will be reus
ed for next face | |
1046 } | |
1047 ················································· | |
1048 int nverts = (mface->v4)? 4: 3; | |
1049 RAS_Polygon *poly = meshobj->AddPolygon(bucket, nverts); | |
1050 | |
1051 poly->SetVisible(visible); | |
1052 poly->SetCollider(collider); | |
1053 poly->SetTwoside(twoside); | |
1054 //poly->SetEdgeCode(mface->edcode); | |
1055 | |
1056 meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,fla
t,mface->v1); | |
1057 meshobj->AddVertex(poly,1,pt1,uv1,uv21,tan1,rgb1,no1,fla
t,mface->v2); | |
1058 meshobj->AddVertex(poly,2,pt2,uv2,uv22,tan2,rgb2,no2,fla
t,mface->v3); | |
1059 | |
1060 if (nverts==4) | |
1061 meshobj->AddVertex(poly,3,pt3,uv3,uv23,tan3,rgb3
,no3,flat,mface->v4); | |
1062 } | |
1063 | |
1064 if (tface)· | |
1065 tface++; | |
1066 if (mcol) | |
1067 mcol+=4; | |
1068 | |
1069 for (int lay=0; lay<MAX_MTFACE; lay++) | |
1070 { | |
1071 MTF_localLayer &layer = layers[lay]; | |
1072 if (layer.face == 0) break; | |
1073 | |
1074 layer.face++; | |
1075 } | |
1076 } | |
1077 // keep meshobj->m_sharedvertex_map for reinstance phys mesh. | |
1078 // 2.49a and before it did: meshobj->m_sharedvertex_map.clear(); | |
1079 // but this didnt save much ram. - Campbell | |
1080 meshobj->EndConversion(); | |
1081 | |
1082 // pre calculate texture generation | |
1083 for(list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial(); | |
1084 mit != meshobj->GetLastMaterial(); ++ mit) { | |
1085 mit->m_bucket->GetPolyMaterial()->OnConstruction(lightlayer); | |
1086 } | |
1087 | |
1088 if (layers) | |
1089 delete []layers; | |
1090 ········ | |
1091 dm->release(dm); | |
1092 // cleanup material | |
1093 if (bl_mat) | |
1094 delete bl_mat; | |
1095 if (kx_blmat) | |
1096 delete kx_blmat; | |
1097 if (kx_polymat) | |
1098 delete kx_polymat; | |
1099 converter->RegisterGameMesh(meshobj, mesh); | |
1100 return meshobj; | |
1101 } | |
1102 | |
1103 ········ | |
1104 ········ | |
1105 static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blender
object) | |
1106 { | |
1107 PHY_MaterialProps *materialProps = new PHY_MaterialProps; | |
1108 ········ | |
1109 MT_assert(materialProps && "Create physics material properties failed"); | |
1110 ················ | |
1111 Material* blendermat = give_current_material(blenderobject, 0); | |
1112 ················ | |
1113 if (blendermat) | |
1114 { | |
1115 MT_assert(0.0f <= blendermat->reflect && blendermat->reflect <=
1.0f); | |
1116 ········ | |
1117 materialProps->m_restitution = blendermat->reflect; | |
1118 materialProps->m_friction = blendermat->friction; | |
1119 materialProps->m_fh_spring = blendermat->fh; | |
1120 materialProps->m_fh_damping = blendermat->xyfrict; | |
1121 materialProps->m_fh_distance = blendermat->fhdist; | |
1122 materialProps->m_fh_normal = (blendermat->dynamode & MA_FH_NOR)
!= 0; | |
1123 } | |
1124 else { | |
1125 //give some defaults | |
1126 materialProps->m_restitution = 0.f; | |
1127 materialProps->m_friction = 0.5; | |
1128 materialProps->m_fh_spring = 0.f; | |
1129 materialProps->m_fh_damping = 0.f; | |
1130 materialProps->m_fh_distance = 0.f; | |
1131 materialProps->m_fh_normal = false; | |
1132 | |
1133 } | |
1134 ········ | |
1135 return materialProps; | |
1136 } | |
1137 | |
1138 static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blendero
bject) | |
1139 { | |
1140 PHY_ShapeProps *shapeProps = new PHY_ShapeProps; | |
1141 ········ | |
1142 MT_assert(shapeProps); | |
1143 ················ | |
1144 shapeProps->m_mass = blenderobject->mass; | |
1145 ········ | |
1146 // This needs to be fixed in blender. For now, we use: | |
1147 ········ | |
1148 // in Blender, inertia stands for the size value which is equivalent to | |
1149 // the sphere radius | |
1150 shapeProps->m_inertia = blenderobject->formfactor; | |
1151 ········ | |
1152 MT_assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.
0f); | |
1153 MT_assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <=
1.0f); | |
1154 ········ | |
1155 shapeProps->m_lin_drag = 1.0 - blenderobject->damping; | |
1156 shapeProps->m_ang_drag = 1.0 - blenderobject->rdamping; | |
1157 ········ | |
1158 shapeProps->m_friction_scaling[0] = blenderobject->anisotropicFriction[0
];· | |
1159 shapeProps->m_friction_scaling[1] = blenderobject->anisotropicFriction[1
]; | |
1160 shapeProps->m_friction_scaling[2] = blenderobject->anisotropicFriction[2
]; | |
1161 shapeProps->m_do_anisotropic = ((blenderobject->gameflag & OB_ANISOTROPI
C_FRICTION) != 0); | |
1162 ········ | |
1163 shapeProps->m_do_fh = (blenderobject->gameflag & OB_DO_FH) != 0;· | |
1164 shapeProps->m_do_rot_fh = (blenderobject->gameflag & OB_ROT_FH) != 0; | |
1165 ········ | |
1166 // velocity clamping XXX | |
1167 shapeProps->m_clamp_vel_min = blenderobject->min_vel; | |
1168 shapeProps->m_clamp_vel_max = blenderobject->max_vel; | |
1169 ········ | |
1170 return shapeProps; | |
1171 } | |
1172 | |
1173 ········ | |
1174 ········ | |
1175 ········ | |
1176 ················ | |
1177 ////////////////////////////////////////////////////////// | |
1178 ········ | |
1179 | |
1180 | |
1181 static float my_boundbox_mesh(Mesh *me, float *loc, float *size) | |
1182 { | |
1183 MVert *mvert; | |
1184 BoundBox *bb; | |
1185 MT_Point3 min, max; | |
1186 float mloc[3], msize[3]; | |
1187 float radius=0.0f, vert_radius, *co; | |
1188 int a; | |
1189 ········ | |
1190 if(me->bb==0) me->bb= (struct BoundBox *)MEM_callocN(sizeof(BoundBox), "
boundbox"); | |
1191 bb= me->bb; | |
1192 ········ | |
1193 INIT_MINMAX(min, max); | |
1194 | |
1195 if (!loc) loc= mloc; | |
1196 if (!size) size= msize; | |
1197 ········ | |
1198 mvert= me->mvert; | |
1199 for(a=0; a<me->totvert; a++, mvert++) { | |
1200 co= mvert->co; | |
1201 ················ | |
1202 /* bounds */ | |
1203 DO_MINMAX(co, min, max); | |
1204 ················ | |
1205 /* radius */ | |
1206 vert_radius= co[0]*co[0] + co[1]*co[1] + co[2]*co[2]; | |
1207 if (vert_radius > radius) | |
1208 radius= vert_radius; | |
1209 } | |
1210 ················ | |
1211 if(me->totvert) { | |
1212 loc[0]= (min[0]+max[0])/2.0; | |
1213 loc[1]= (min[1]+max[1])/2.0; | |
1214 loc[2]= (min[2]+max[2])/2.0; | |
1215 ················ | |
1216 size[0]= (max[0]-min[0])/2.0; | |
1217 size[1]= (max[1]-min[1])/2.0; | |
1218 size[2]= (max[2]-min[2])/2.0; | |
1219 } | |
1220 else { | |
1221 loc[0]= loc[1]= loc[2]= 0.0; | |
1222 size[0]= size[1]= size[2]= 0.0; | |
1223 } | |
1224 ················ | |
1225 bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= loc[0]-size[0]; | |
1226 bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= loc[0]+size[0]; | |
1227 ················ | |
1228 bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= loc[1]-size[1]; | |
1229 bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= loc[1]+size[1]; | |
1230 | |
1231 bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= loc[2]-size[2]; | |
1232 bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= loc[2]+size[2]; | |
1233 | |
1234 return sqrt(radius); | |
1235 } | |
1236 ················ | |
1237 | |
1238 | |
1239 | |
1240 static void my_tex_space_mesh(Mesh *me) | |
1241 { | |
1242 KeyBlock *kb; | |
1243 float *fp, loc[3], size[3], min[3], max[3]; | |
1244 int a; | |
1245 | |
1246 my_boundbox_mesh(me, loc, size); | |
1247 ········ | |
1248 if(me->texflag & AUTOSPACE) { | |
1249 if(me->key) { | |
1250 kb= me->key->refkey; | |
1251 if (kb) { | |
1252 ········ | |
1253 INIT_MINMAX(min, max); | |
1254 ················ | |
1255 fp= (float *)kb->data; | |
1256 for(a=0; a<kb->totelem; a++, fp+=3) {··· | |
1257 DO_MINMAX(fp, min, max); | |
1258 } | |
1259 if(kb->totelem) { | |
1260 loc[0]= (min[0]+max[0])/2.0; loc[1]= (mi
n[1]+max[1])/2.0; loc[2]= (min[2]+max[2])/2.0; | |
1261 size[0]= (max[0]-min[0])/2.0; size[1]= (
max[1]-min[1])/2.0; size[2]= (max[2]-min[2])/2.0; | |
1262 }· | |
1263 else { | |
1264 loc[0]= loc[1]= loc[2]= 0.0; | |
1265 size[0]= size[1]= size[2]= 0.0; | |
1266 } | |
1267 ································ | |
1268 } | |
1269 } | |
1270 ········ | |
1271 VECCOPY(me->loc, loc); | |
1272 VECCOPY(me->size, size); | |
1273 me->rot[0]= me->rot[1]= me->rot[2]= 0.0; | |
1274 ········ | |
1275 if(me->size[0]==0.0) me->size[0]= 1.0; | |
1276 else if(me->size[0]>0.0 && me->size[0]<0.00001) me->size[0]= 0.0
0001; | |
1277 else if(me->size[0]<0.0 && me->size[0]> -0.00001) me->size[0]= -
0.00001; | |
1278 ········ | |
1279 if(me->size[1]==0.0) me->size[1]= 1.0; | |
1280 else if(me->size[1]>0.0 && me->size[1]<0.00001) me->size[1]= 0.0
0001; | |
1281 else if(me->size[1]<0.0 && me->size[1]> -0.00001) me->size[1]= -
0.00001; | |
1282 ················································ | |
1283 if(me->size[2]==0.0) me->size[2]= 1.0; | |
1284 else if(me->size[2]>0.0 && me->size[2]<0.00001) me->size[2]= 0.0
0001; | |
1285 else if(me->size[2]<0.0 && me->size[2]> -0.00001) me->size[2]= -
0.00001; | |
1286 } | |
1287 ········ | |
1288 } | |
1289 | |
1290 static void my_get_local_bounds(Object *ob, DerivedMesh *dm, float *center, floa
t *size) | |
1291 { | |
1292 BoundBox *bb= NULL; | |
1293 /* uses boundbox, function used by Ketsji */ | |
1294 switch (ob->type) | |
1295 { | |
1296 case OB_MESH: | |
1297 if (dm) | |
1298 { | |
1299 float min_r[3], max_r[3]; | |
1300 INIT_MINMAX(min_r, max_r); | |
1301 dm->getMinMax(dm, min_r, max_r); | |
1302 size[0]= 0.5*fabs(max_r[0] - min_r[0]); | |
1303 size[1]= 0.5*fabs(max_r[1] - min_r[1]); | |
1304 size[2]= 0.5*fabs(max_r[2] - min_r[2]); | |
1305 ········································ | |
1306 center[0]= 0.5*(max_r[0] + min_r[0]); | |
1307 center[1]= 0.5*(max_r[1] + min_r[1]); | |
1308 center[2]= 0.5*(max_r[2] + min_r[2]); | |
1309 return; | |
1310 } else | |
1311 { | |
1312 bb= ( (Mesh *)ob->data )->bb; | |
1313 if(bb==0)· | |
1314 { | |
1315 my_tex_space_mesh((struct Mesh *)ob->dat
a); | |
1316 bb= ( (Mesh *)ob->data )->bb; | |
1317 } | |
1318 } | |
1319 break; | |
1320 case OB_CURVE: | |
1321 case OB_SURF: | |
1322 center[0]= center[1]= center[2]= 0.0; | |
1323 size[0] = size[1]=size[2]=0.0; | |
1324 break; | |
1325 case OB_FONT: | |
1326 center[0]= center[1]= center[2]= 0.0; | |
1327 size[0] = size[1]=size[2]=1.0; | |
1328 break; | |
1329 case OB_MBALL: | |
1330 bb= ob->bb; | |
1331 break; | |
1332 } | |
1333 ········ | |
1334 if(bb==NULL)· | |
1335 { | |
1336 center[0]= center[1]= center[2]= 0.0; | |
1337 size[0] = size[1]=size[2]=1.0; | |
1338 } | |
1339 else· | |
1340 { | |
1341 size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]); | |
1342 size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]); | |
1343 size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]); | |
1344 ········································ | |
1345 center[0]= 0.5*(bb->vec[0][0] + bb->vec[4][0]); | |
1346 center[1]= 0.5*(bb->vec[0][1] + bb->vec[2][1]); | |
1347 center[2]= 0.5*(bb->vec[0][2] + bb->vec[1][2]); | |
1348 } | |
1349 } | |
1350 ········ | |
1351 | |
1352 | |
1353 | |
1354 ////////////////////////////////////////////////////// | |
1355 | |
1356 | |
1357 void BL_CreateGraphicObjectNew(KX_GameObject* gameobj, | |
1358 const MT_Point3& loca
lAabbMin, | |
1359 const MT_Point3& loca
lAabbMax, | |
1360 KX_Scene* kxscene, | |
1361 bool isActive, | |
1362 e_PhysicsEngine physi
cs_engine) | |
1363 { | |
1364 if (gameobj->GetMeshCount() > 0)· | |
1365 { | |
1366 switch (physics_engine) | |
1367 { | |
1368 #ifdef USE_BULLET | |
1369 case UseBullet: | |
1370 { | |
1371 CcdPhysicsEnvironment* env = (CcdPhysicsEnvironm
ent*)kxscene->GetPhysicsEnvironment(); | |
1372 assert(env); | |
1373 PHY_IMotionState* motionstate = new KX_MotionSta
te(gameobj->GetSGNode()); | |
1374 CcdGraphicController* ctrl = new CcdGraphicContr
oller(env, motionstate); | |
1375 gameobj->SetGraphicController(ctrl); | |
1376 ctrl->setNewClientInfo(gameobj->getClientInfo())
; | |
1377 ctrl->setLocalAabb(localAabbMin, localAabbMax); | |
1378 if (isActive) { | |
1379 // add first, this will create the proxy
handle, only if the object is visible | |
1380 if (gameobj->GetVisible()) | |
1381 env->addCcdGraphicController(ctr
l); | |
1382 // update the mesh if there is a deforme
r, this will also update the bounding box for modifiers | |
1383 RAS_Deformer* deformer = gameobj->GetDef
ormer(); | |
1384 if (deformer) | |
1385 deformer->UpdateBuckets(); | |
1386 } | |
1387 } | |
1388 break; | |
1389 #endif | |
1390 default: | |
1391 break; | |
1392 } | |
1393 } | |
1394 } | |
1395 | |
1396 void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, | |
1397 struct Object* blenderobject, | |
1398 RAS_MeshObject* meshobj, | |
1399 KX_Scene* kxscene, | |
1400 int activeLayerBitInfo, | |
1401 e_PhysicsEngine physics_
engine, | |
1402 KX_BlenderSceneConverter *conve
rter, | |
1403 bool processCompoundChildren | |
1404 ) | |
1405 ········································ | |
1406 { | |
1407 //SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/ | |
1408 //int userigidbody = SYS_GetCommandLineInt(syshandle,"norigidbody",0); | |
1409 //bool bRigidBody = (userigidbody == 0); | |
1410 | |
1411 // object has physics representation? | |
1412 if (!(blenderobject->gameflag & OB_COLLISION)) | |
1413 return; | |
1414 | |
1415 // get Root Parent of blenderobject | |
1416 struct Object* parent= blenderobject->parent; | |
1417 while(parent && parent->parent) { | |
1418 parent= parent->parent; | |
1419 } | |
1420 | |
1421 bool isCompoundChild = false; | |
1422 bool hasCompoundChildren = !parent && (blenderobject->gameflag & OB_CHIL
D); | |
1423 | |
1424 /* When the parent is not OB_DYNAMIC and has no OB_COLLISION then it get
s no bullet controller | |
1425 * and cant be apart of the parents compound shape */ | |
1426 if (parent && (parent->gameflag & (OB_DYNAMIC | OB_COLLISION))) { | |
1427 ················ | |
1428 if ((parent->gameflag & OB_CHILD) != 0 && (blenderobject->gamefl
ag & OB_CHILD)) | |
1429 { | |
1430 isCompoundChild = true; | |
1431 }· | |
1432 } | |
1433 if (processCompoundChildren != isCompoundChild) | |
1434 return; | |
1435 | |
1436 | |
1437 PHY_ShapeProps* shapeprops = | |
1438 CreateShapePropsFromBlenderObject(blenderobject); | |
1439 | |
1440 ········ | |
1441 PHY_MaterialProps* smmaterial =· | |
1442 CreateMaterialFromBlenderObject(blenderobject); | |
1443 ········································ | |
1444 KX_ObjectProperties objprop; | |
1445 objprop.m_lockXaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_A
XIS) !=0; | |
1446 objprop.m_lockYaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_A
XIS) !=0; | |
1447 objprop.m_lockZaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_A
XIS) !=0; | |
1448 objprop.m_lockXRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_
X_ROT_AXIS) !=0; | |
1449 objprop.m_lockYRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_
Y_ROT_AXIS) !=0; | |
1450 objprop.m_lockZRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_
Z_ROT_AXIS) !=0; | |
1451 | |
1452 objprop.m_isCompoundChild = isCompoundChild; | |
1453 objprop.m_hasCompoundChildren = hasCompoundChildren; | |
1454 objprop.m_margin = blenderobject->margin; | |
1455 ········ | |
1456 // ACTOR is now a separate feature | |
1457 objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0; | |
1458 objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0; | |
1459 objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0; | |
1460 objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY)
!= 0; | |
1461 ········ | |
1462 ///contact processing threshold is only for rigid bodies and static geom
etry, not 'dynamic' | |
1463 if (objprop.m_angular_rigidbody || !objprop.m_dyna ) | |
1464 { | |
1465 objprop.m_contactProcessingThreshold = blenderobject->m_contactP
rocessingThreshold; | |
1466 } else | |
1467 { | |
1468 objprop.m_contactProcessingThreshold = 0.f; | |
1469 } | |
1470 | |
1471 objprop.m_sensor = (blenderobject->gameflag & OB_SENSOR) != 0; | |
1472 ········ | |
1473 if (objprop.m_softbody) | |
1474 { | |
1475 ///for game soft bodies | |
1476 if (blenderobject->bsoft) | |
1477 { | |
1478 objprop.m_gamesoftFlag = blenderobject->bsoft->flag; | |
1479 /////////////////// | |
1480 objprop.m_soft_linStiff = blenderobject->bsoft->linStiff
; | |
1481 objprop.m_soft_angStiff = blenderobject->bsoft->angStiff
; /* angular stiffness 0..1 */ | |
1482 objprop.m_soft_volume= blenderobject->bsoft->volume;
/* volume preservation 0..1 */ | |
1483 | |
1484 objprop.m_soft_viterations= blenderobject->bsoft->vitera
tions; /* Velocities solver iterations */ | |
1485 objprop.m_soft_piterations= blenderobject->bsoft->pitera
tions; /* Positions solver iterations */ | |
1486 objprop.m_soft_diterations= blenderobject->bsoft->ditera
tions; /* Drift solver iterations */ | |
1487 objprop.m_soft_citerations= blenderobject->bsoft->citera
tions; /* Cluster solver iterations */ | |
1488 | |
1489 objprop.m_soft_kSRHR_CL= blenderobject->bsoft->kSRHR_CL;
/* Soft vs rigid hardness [0,1] (cluster only) */ | |
1490 objprop.m_soft_kSKHR_CL= blenderobject->bsoft->kSKHR_CL;
/* Soft vs kinetic hardness [0,1] (cluster only) */ | |
1491 objprop.m_soft_kSSHR_CL= blenderobject->bsoft->kSSHR_CL;
/* Soft vs soft hardness [0,1] (cluster only) */ | |
1492 objprop.m_soft_kSR_SPLT_CL= blenderobject->bsoft->kSR_SP
LT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ | |
1493 | |
1494 objprop.m_soft_kSK_SPLT_CL= blenderobject->bsoft->kSK_SP
LT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ | |
1495 objprop.m_soft_kSS_SPLT_CL= blenderobject->bsoft->kSS_SP
LT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ | |
1496 objprop.m_soft_kVCF= blenderobject->bsoft->kVCF;
/* Velocities correction factor (Baumgarte) */ | |
1497 objprop.m_soft_kDP= blenderobject->bsoft->kDP;
/* Damping coefficient [0,1] */ | |
1498 | |
1499 objprop.m_soft_kDG= blenderobject->bsoft->kDG;
/* Drag coefficient [0,+inf] */ | |
1500 objprop.m_soft_kLF= blenderobject->bsoft->kLF;
/* Lift coefficient [0,+inf] */ | |
1501 objprop.m_soft_kPR= blenderobject->bsoft->kPR;
/* Pressure coefficient [-inf,+inf] */ | |
1502 objprop.m_soft_kVC= blenderobject->bsoft->kVC;
/* Volume conversation coefficient [0,+inf] */ | |
1503 | |
1504 objprop.m_soft_kDF= blenderobject->bsoft->kDF;
/* Dynamic friction coefficient [0,1] */ | |
1505 objprop.m_soft_kMT= blenderobject->bsoft->kMT;
/* Pose matching coefficient [0,1] */ | |
1506 objprop.m_soft_kCHR= blenderobject->bsoft->kCHR;
/* Rigid contacts hardness [0,1] */ | |
1507 objprop.m_soft_kKHR= blenderobject->bsoft->kKHR;
/* Kinetic contacts hardness [0,1] */ | |
1508 | |
1509 objprop.m_soft_kSHR= blenderobject->bsoft->kSHR;
/* Soft contacts hardness [0,1] */ | |
1510 objprop.m_soft_kAHR= blenderobject->bsoft->kAHR;
/* Anchors hardness [0,1] */ | |
1511 objprop.m_soft_collisionflags= blenderobject->bsoft->col
lisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft v
ersus Soft or Rigid */ | |
1512 objprop.m_soft_numclusteriterations= blenderobject->bsof
t->numclusteriterations; /* number of iterations to refine collision clus
ters*/ | |
1513 //objprop.m_soft_welding = blenderobject->bsoft->welding
; /* welding */ | |
1514 /* disable welding: it doesn't bring any additional stab
ility and it breaks the relation between soft body collision shape and graphic m
esh */ | |
1515 objprop.m_soft_welding = 0.f;··········· | |
1516 objprop.m_margin = blenderobject->bsoft->margin; | |
1517 objprop.m_contactProcessingThreshold = 0.f; | |
1518 } else | |
1519 { | |
1520 objprop.m_gamesoftFlag = OB_BSB_BENDING_CONSTRAINTS | OB
_BSB_SHAPE_MATCHING | OB_BSB_AERO_VPOINT; | |
1521 ························ | |
1522 objprop.m_soft_linStiff = 0.5;; | |
1523 objprop.m_soft_angStiff = 1.f; /* angular stiff
ness 0..1 */ | |
1524 objprop.m_soft_volume= 1.f; /* volum
e preservation 0..1 */ | |
1525 | |
1526 | |
1527 objprop.m_soft_viterations= 0; | |
1528 objprop.m_soft_piterations= 1; | |
1529 objprop.m_soft_diterations= 0; | |
1530 objprop.m_soft_citerations= 4; | |
1531 | |
1532 objprop.m_soft_kSRHR_CL= 0.1f; | |
1533 objprop.m_soft_kSKHR_CL= 1.f; | |
1534 objprop.m_soft_kSSHR_CL= 0.5; | |
1535 objprop.m_soft_kSR_SPLT_CL= 0.5f; | |
1536 | |
1537 objprop.m_soft_kSK_SPLT_CL= 0.5f; | |
1538 objprop.m_soft_kSS_SPLT_CL= 0.5f; | |
1539 objprop.m_soft_kVCF= 1; | |
1540 objprop.m_soft_kDP= 0; | |
1541 | |
1542 objprop.m_soft_kDG= 0; | |
1543 objprop.m_soft_kLF= 0; | |
1544 objprop.m_soft_kPR= 0; | |
1545 objprop.m_soft_kVC= 0; | |
1546 | |
1547 objprop.m_soft_kDF= 0.2f; | |
1548 objprop.m_soft_kMT= 0.05f; | |
1549 objprop.m_soft_kCHR= 1.0f; | |
1550 objprop.m_soft_kKHR= 0.1f; | |
1551 | |
1552 objprop.m_soft_kSHR= 1.f; | |
1553 objprop.m_soft_kAHR= 0.7f; | |
1554 objprop.m_soft_collisionflags= OB_BSB_COL_SDF_RS + OB_BS
B_COL_VF_SS; | |
1555 objprop.m_soft_numclusteriterations= 16; | |
1556 objprop.m_soft_welding = 0.f; | |
1557 objprop.m_margin = 0.f; | |
1558 objprop.m_contactProcessingThreshold = 0.f; | |
1559 } | |
1560 } | |
1561 | |
1562 objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0; | |
1563 objprop.m_disableSleeping = (blenderobject->gameflag & OB_COLLISION_RESP
ONSE) != 0;//abuse the OB_COLLISION_RESPONSE flag | |
1564 //mmm, for now, taks this for the size of the dynamicobject | |
1565 // Blender uses inertia for radius of dynamic object | |
1566 objprop.m_radius = blenderobject->inertia; | |
1567 objprop.m_in_active_layer = (blenderobject->lay & activeLayerBitInfo) !=
0; | |
1568 objprop.m_dynamic_parent=NULL; | |
1569 objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0; | |
1570 objprop.m_boundclass = objprop.m_dyna?KX_BOUNDSPHERE:KX_BOUNDMESH; | |
1571 ········ | |
1572 if ((blenderobject->gameflag & OB_SOFT_BODY) && !(blenderobject->gamefla
g & OB_BOUNDS)) | |
1573 { | |
1574 objprop.m_boundclass = KX_BOUNDMESH; | |
1575 } | |
1576 | |
1577 KX_BoxBounds bb; | |
1578 DerivedMesh* dm = NULL; | |
1579 if (gameobj->GetDeformer()) | |
1580 dm = gameobj->GetDeformer()->GetPhysicsMesh(); | |
1581 my_get_local_bounds(blenderobject,dm,objprop.m_boundobject.box.m_center,
bb.m_extends); | |
1582 if (blenderobject->gameflag & OB_BOUNDS) | |
1583 { | |
1584 switch (blenderobject->boundtype) | |
1585 { | |
1586 case OB_BOUND_BOX: | |
1587 objprop.m_boundclass = KX_BOUNDBOX; | |
1588 //mmm, has to be divided by 2 to be proper exten
ds | |
1589 objprop.m_boundobject.box.m_extends[0]=2.f*bb.m_
extends[0]; | |
1590 objprop.m_boundobject.box.m_extends[1]=2.f*bb.m_
extends[1]; | |
1591 objprop.m_boundobject.box.m_extends[2]=2.f*bb.m_
extends[2]; | |
1592 break; | |
1593 case OB_BOUND_POLYT: | |
1594 if (blenderobject->type == OB_MESH) | |
1595 { | |
1596 objprop.m_boundclass = KX_BOUNDPOLYTOPE; | |
1597 break; | |
1598 } | |
1599 // Object is not a mesh... fall through OB_BOUND
_POLYH to· | |
1600 // OB_BOUND_SPHERE | |
1601 case OB_BOUND_POLYH: | |
1602 if (blenderobject->type == OB_MESH) | |
1603 { | |
1604 objprop.m_boundclass = KX_BOUNDMESH; | |
1605 break; | |
1606 } | |
1607 // Object is not a mesh... can't use polyhedron. | |
1608 // Fall through and become a sphere. | |
1609 case OB_BOUND_SPHERE: | |
1610 { | |
1611 objprop.m_boundclass = KX_BOUNDSPHERE; | |
1612 objprop.m_boundobject.c.m_radius = MT_max(bb.m_e
xtends[0], MT_max(bb.m_extends[1], bb.m_extends[2])); | |
1613 break; | |
1614 } | |
1615 case OB_BOUND_CYLINDER: | |
1616 { | |
1617 objprop.m_boundclass = KX_BOUNDCYLINDER; | |
1618 objprop.m_boundobject.c.m_radius = MT_max(bb.m_e
xtends[0], bb.m_extends[1]); | |
1619 objprop.m_boundobject.c.m_height = 2.f*bb.m_exte
nds[2]; | |
1620 break; | |
1621 } | |
1622 case OB_BOUND_CONE: | |
1623 { | |
1624 objprop.m_boundclass = KX_BOUNDCONE; | |
1625 objprop.m_boundobject.c.m_radius = MT_max(bb.m_e
xtends[0], bb.m_extends[1]); | |
1626 objprop.m_boundobject.c.m_height = 2.f*bb.m_exte
nds[2]; | |
1627 break; | |
1628 } | |
1629 case OB_BOUND_CAPSULE: | |
1630 { | |
1631 objprop.m_boundclass = KX_BOUNDCAPSULE; | |
1632 objprop.m_boundobject.c.m_radius = MT_max(bb.m_e
xtends[0], bb.m_extends[1]); | |
1633 objprop.m_boundobject.c.m_height = 2.f*(bb.m_ext
ends[2]-objprop.m_boundobject.c.m_radius); | |
1634 if (objprop.m_boundobject.c.m_height < 0.f) | |
1635 objprop.m_boundobject.c.m_height = 0.f; | |
1636 break; | |
1637 } | |
1638 } | |
1639 } | |
1640 | |
1641 ········ | |
1642 if (parent/* && (parent->gameflag & OB_DYNAMIC)*/) { | |
1643 // parented object cannot be dynamic | |
1644 KX_GameObject *parentgameobject = converter->FindGameObject(pare
nt); | |
1645 objprop.m_dynamic_parent = parentgameobject; | |
1646 //cannot be dynamic: | |
1647 objprop.m_dyna = false; | |
1648 objprop.m_softbody = false; | |
1649 shapeprops->m_mass = 0.f; | |
1650 } | |
1651 | |
1652 ········ | |
1653 objprop.m_concave = (blenderobject->boundtype & 4) != 0; | |
1654 ········ | |
1655 switch (physics_engine) | |
1656 { | |
1657 #ifdef USE_BULLET | |
1658 case UseBullet: | |
1659 KX_ConvertBulletObject(gameobj, meshobj, dm, kxscene, sh
apeprops, smmaterial, &objprop); | |
1660 break; | |
1661 | |
1662 #endif | |
1663 case UseDynamo: | |
1664 //KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapepr
ops, smmaterial, &objprop); | |
1665 break; | |
1666 ························ | |
1667 case UseNone: | |
1668 default: | |
1669 break; | |
1670 } | |
1671 delete shapeprops; | |
1672 delete smmaterial; | |
1673 if (dm) { | |
1674 dm->needsFree = 1; | |
1675 dm->release(dm); | |
1676 } | |
1677 } | |
1678 | |
1679 | |
1680 | |
1681 | |
1682 | |
1683 static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l
ayerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConve
rter *converter) { | |
1684 RAS_LightObject lightobj; | |
1685 KX_LightObject *gamelight; | |
1686 ········ | |
1687 lightobj.m_att1 = la->att1; | |
1688 lightobj.m_att2 = (la->mode & LA_QUAD)?la->att2:0.0; | |
1689 lightobj.m_red = la->r; | |
1690 lightobj.m_green = la->g; | |
1691 lightobj.m_blue = la->b; | |
1692 lightobj.m_distance = la->dist; | |
1693 lightobj.m_energy = la->energy; | |
1694 lightobj.m_layer = layerflag; | |
1695 lightobj.m_spotblend = la->spotblend; | |
1696 lightobj.m_spotsize = la->spotsize; | |
1697 ········ | |
1698 lightobj.m_nodiffuse = (la->mode & LA_NO_DIFF) != 0; | |
1699 lightobj.m_nospecular = (la->mode & LA_NO_SPEC) != 0; | |
1700 ········ | |
1701 bool glslmat = converter->GetGLSLMaterials(); | |
1702 | |
1703 // in GLSL NEGATIVE LAMP is handled inside the lamp update function | |
1704 if(glslmat==0) { | |
1705 if (la->mode & LA_NEG) | |
1706 { | |
1707 lightobj.m_red = -lightobj.m_red; | |
1708 lightobj.m_green = -lightobj.m_green; | |
1709 lightobj.m_blue = -lightobj.m_blue; | |
1710 } | |
1711 } | |
1712 ················ | |
1713 if (la->type==LA_SUN) { | |
1714 lightobj.m_type = RAS_LightObject::LIGHT_SUN; | |
1715 } else if (la->type==LA_SPOT) { | |
1716 lightobj.m_type = RAS_LightObject::LIGHT_SPOT; | |
1717 } else { | |
1718 lightobj.m_type = RAS_LightObject::LIGHT_NORMAL; | |
1719 } | |
1720 | |
1721 gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertoo
ls, | |
1722 lightobj, glslmat); | |
1723 | |
1724 BL_ConvertLampIpos(la, gamelight, converter); | |
1725 ········ | |
1726 return gamelight; | |
1727 } | |
1728 | |
1729 static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_Blen
derSceneConverter *converter) { | |
1730 Camera* ca = static_cast<Camera*>(ob->data); | |
1731 RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->clipsta, ca->clipe
nd, ca->type == CAM_PERSP, ca->YF_dofdist); | |
1732 KX_Camera *gamecamera; | |
1733 ········ | |
1734 gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata); | |
1735 gamecamera->SetName(ca->id.name + 2); | |
1736 ········ | |
1737 BL_ConvertCameraIpos(ca, gamecamera, converter); | |
1738 ········ | |
1739 return gamecamera; | |
1740 } | |
1741 | |
1742 static KX_GameObject *gameobject_from_blenderobject( | |
1743 Object *ob,· | |
1744 KX_Scene *kxscen
e,· | |
1745 RAS_IRenderTools
*rendertools,· | |
1746 KX_BlenderSceneC
onverter *converter)· | |
1747 { | |
1748 KX_GameObject *gameobj = NULL; | |
1749 ········ | |
1750 switch(ob->type) | |
1751 { | |
1752 case OB_LAMP: | |
1753 { | |
1754 KX_LightObject* gamelight= gamelight_from_blamp(ob, static_cast<
Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter); | |
1755 gameobj = gamelight; | |
1756 ················ | |
1757 gamelight->AddRef(); | |
1758 kxscene->GetLightList()->Add(gamelight); | |
1759 | |
1760 break; | |
1761 } | |
1762 ········ | |
1763 case OB_CAMERA: | |
1764 { | |
1765 KX_Camera* gamecamera = gamecamera_from_bcamera(ob, kxscene, con
verter); | |
1766 gameobj = gamecamera; | |
1767 ················ | |
1768 //don't add a reference: the camera list in kxscene->m_cameras i
s not released at the end | |
1769 //gamecamera->AddRef(); | |
1770 kxscene->AddCamera(gamecamera); | |
1771 ················ | |
1772 break; | |
1773 } | |
1774 ········ | |
1775 case OB_MESH: | |
1776 { | |
1777 Mesh* mesh = static_cast<Mesh*>(ob->data); | |
1778 float center[3], extents[3]; | |
1779 float radius = my_boundbox_mesh((Mesh*) ob->data, center, extent
s); | |
1780 RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,convert
er); | |
1781 ················ | |
1782 // needed for python scripting | |
1783 kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),
meshobj); | |
1784 ········ | |
1785 gameobj = new BL_DeformableGameObject(ob,kxscene,KX_Scene::m_cal
lbacks); | |
1786 ········ | |
1787 // set transformation | |
1788 gameobj->AddMesh(meshobj); | |
1789 ········ | |
1790 // for all objects: check whether they want to | |
1791 // respond to updates | |
1792 bool ignoreActivityCulling =·· | |
1793 ((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0); | |
1794 gameobj->SetIgnoreActivityCulling(ignoreActivityCulling); | |
1795 gameobj->SetOccluder((ob->gameflag & OB_OCCLUDER) != 0, false); | |
1796 ········ | |
1797 // two options exists for deform: shape keys and armature | |
1798 // only support relative shape key | |
1799 bool bHasShapeKey = mesh->key != NULL && mesh->key->type==KEY_RE
LATIVE; | |
1800 bool bHasDvert = mesh->dvert != NULL && ob->defbase.first; | |
1801 bool bHasArmature = (BL_ModifierDeformer::HasArmatureDeformer(ob
) && ob->parent && ob->parent->type == OB_ARMATURE && bHasDvert); | |
1802 bool bHasModifier = BL_ModifierDeformer::HasCompatibleDeformer(o
b); | |
1803 #ifdef USE_BULLET | |
1804 bool bHasSoftBody = (!ob->parent && (ob->gameflag & OB_SOFT_BODY
)); | |
1805 #endif | |
1806 if (bHasModifier) { | |
1807 BL_ModifierDeformer *dcont = new BL_ModifierDeformer((BL
_DeformableGameObject *)gameobj, | |
1808
kxscene->GetBlenderScene(), ob,
meshobj); | |
1809 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); | |
1810 if (bHasShapeKey && bHasArmature) | |
1811 dcont->LoadShapeDrivers(ob->parent); | |
1812 } else if (bHasShapeKey) { | |
1813 // not that we can have shape keys without dvert!· | |
1814 BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_Defor
mableGameObject*)gameobj,· | |
1815
ob, meshobj); | |
1816 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); | |
1817 if (bHasArmature) | |
1818 dcont->LoadShapeDrivers(ob->parent); | |
1819 } else if (bHasArmature) { | |
1820 BL_SkinDeformer *dcont = new BL_SkinDeformer((BL_Deforma
bleGameObject*)gameobj, | |
1821
ob, meshobj); | |
1822 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); | |
1823 } else if (bHasDvert) { | |
1824 // this case correspond to a mesh that can potentially d
eform but not with the | |
1825 // object to which it is attached for the moment. A skin
mesh was created in | |
1826 // BL_ConvertMesh() so must create a deformer too! | |
1827 BL_MeshDeformer *dcont = new BL_MeshDeformer((BL_Deforma
bleGameObject*)gameobj, | |
1828
ob, meshobj); | |
1829 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); | |
1830 #ifdef USE_BULLET | |
1831 } else if (bHasSoftBody) { | |
1832 KX_SoftBodyDeformer *dcont = new KX_SoftBodyDeformer(mes
hobj, (BL_DeformableGameObject*)gameobj); | |
1833 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); | |
1834 #endif | |
1835 } | |
1836 ················ | |
1837 MT_Point3 min = MT_Point3(center) - MT_Vector3(extents); | |
1838 MT_Point3 max = MT_Point3(center) + MT_Vector3(extents); | |
1839 SG_BBox bbox = SG_BBox(min, max); | |
1840 gameobj->GetSGNode()->SetBBox(bbox); | |
1841 gameobj->GetSGNode()->SetRadius(radius); | |
1842 ········ | |
1843 break; | |
1844 } | |
1845 ········ | |
1846 case OB_ARMATURE: | |
1847 { | |
1848 gameobj = new BL_ArmatureObject( | |
1849 kxscene, | |
1850 KX_Scene::m_callbacks, | |
1851 ob, | |
1852 kxscene->GetBlenderScene() // handle | |
1853 ); | |
1854 /* Get the current pose from the armature object and apply it as
the rest pose */ | |
1855 break; | |
1856 } | |
1857 ········ | |
1858 case OB_EMPTY: | |
1859 { | |
1860 gameobj = new KX_EmptyObject(kxscene,KX_Scene::m_callbacks); | |
1861 // set transformation | |
1862 break; | |
1863 } | |
1864 | |
1865 case OB_FONT: | |
1866 { | |
1867 /* font objects have no bounding box */ | |
1868 gameobj = new KX_FontObject(kxscene,KX_Scene::m_callbacks, rende
rtools, ob); | |
1869 | |
1870 /* add to the list only the visible fonts */ | |
1871 if((ob->lay & kxscene->GetBlenderScene()->lay) != 0) | |
1872 kxscene->AddFont(static_cast<KX_FontObject*>(gameobj)); | |
1873 break; | |
1874 } | |
1875 | |
1876 } | |
1877 if (gameobj)· | |
1878 { | |
1879 gameobj->SetLayer(ob->lay); | |
1880 gameobj->SetBlenderObject(ob); | |
1881 /* set the visibility state based on the objects render option i
n the outliner */ | |
1882 if(ob->restrictflag & OB_RESTRICT_RENDER) gameobj->SetVisible(0,
0); | |
1883 } | |
1884 return gameobj; | |
1885 } | |
1886 | |
1887 struct parentChildLink { | |
1888 struct Object* m_blenderchild; | |
1889 SG_Node* m_gamechildnode; | |
1890 }; | |
1891 | |
1892 #include "DNA_constraint_types.h" | |
1893 //XXX #include "BIF_editconstraint.h" | |
1894 | |
1895 bPoseChannel *get_active_posechannel2 (Object *ob) | |
1896 { | |
1897 bArmature *arm= (bArmature*)ob->data; | |
1898 bPoseChannel *pchan; | |
1899 ········ | |
1900 /* find active */ | |
1901 for(pchan= (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan= pchan
->next) { | |
1902 if(pchan->bone && (pchan->bone == arm->act_bone) && (pchan->bone
->layer & arm->layer)) | |
1903 return pchan; | |
1904 } | |
1905 ········ | |
1906 return NULL; | |
1907 } | |
1908 | |
1909 ListBase *get_active_constraints2(Object *ob) | |
1910 { | |
1911 if (!ob) | |
1912 return NULL; | |
1913 | |
1914 // XXX - shouldnt we care about the pose data and not the mode??? | |
1915 if (ob->mode & OB_MODE_POSE) {· | |
1916 bPoseChannel *pchan; | |
1917 | |
1918 pchan = get_active_posechannel2(ob); | |
1919 if (pchan) | |
1920 return &pchan->constraints; | |
1921 } | |
1922 else· | |
1923 return &ob->constraints; | |
1924 | |
1925 return NULL; | |
1926 } | |
1927 | |
1928 | |
1929 void RBJconstraints(Object *ob)//not used | |
1930 { | |
1931 ListBase *conlist; | |
1932 bConstraint *curcon; | |
1933 | |
1934 conlist = get_active_constraints2(ob); | |
1935 | |
1936 if (conlist) { | |
1937 for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bCo
nstraint *)curcon->next) { | |
1938 | |
1939 printf("%i\n",curcon->type); | |
1940 } | |
1941 | |
1942 | |
1943 } | |
1944 } | |
1945 | |
1946 #include "PHY_IPhysicsEnvironment.h" | |
1947 #include "KX_IPhysicsController.h" | |
1948 #include "PHY_DynamicTypes.h" | |
1949 | |
1950 KX_IPhysicsController* getPhId(CListValue* sumolist,STR_String busc){//not used | |
1951 | |
1952 for (int j=0;j<sumolist->GetCount();j++) | |
1953 { | |
1954 KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j); | |
1955 if (gameobje->GetName()==busc) | |
1956 return gameobje->GetPhysicsController(); | |
1957 } | |
1958 | |
1959 return 0; | |
1960 | |
1961 } | |
1962 | |
1963 KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist){ | |
1964 | |
1965 for (int j=0;j<sumolist->GetCount();j++) | |
1966 { | |
1967 KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j); | |
1968 if (gameobje->GetName()==busc) | |
1969 return gameobje; | |
1970 } | |
1971 ········ | |
1972 return 0; | |
1973 | |
1974 } | |
1975 | |
1976 // convert blender objects into ketsji gameobjects | |
1977 void BL_ConvertBlenderObjects(struct Main* maggie, | |
1978 KX_Scene* kxscene, | |
1979 KX_KetsjiEngine* ketsj
iEngine, | |
1980 e_PhysicsEngine
physics_engine, | |
1981 RAS_IRenderTools* rend
ertools, | |
1982 RAS_ICanvas* canvas, | |
1983 KX_BlenderSceneConvert
er* converter, | |
1984 bool alwaysUseExpandFr
aming | |
1985 ) | |
1986 {······· | |
1987 | |
1988 Scene *blenderscene = kxscene->GetBlenderScene(); | |
1989 // for SETLOOPER | |
1990 Scene *sce_iter; | |
1991 Base *base; | |
1992 | |
1993 // Get the frame settings of the canvas. | |
1994 // Get the aspect ratio of the canvas as designed by the user. | |
1995 | |
1996 RAS_FrameSettings::RAS_FrameType frame_type; | |
1997 int aspect_width; | |
1998 int aspect_height; | |
1999 vector<MT_Vector3> inivel,iniang; | |
2000 set<Group*> grouplist; // list of groups to be converted | |
2001 set<Object*> allblobj; // all objects converted | |
2002 set<Object*> groupobj; // objects from groups (never in active layer) | |
2003 | |
2004 if (alwaysUseExpandFraming) { | |
2005 frame_type = RAS_FrameSettings::e_frame_extend; | |
2006 aspect_width = canvas->GetWidth(); | |
2007 aspect_height = canvas->GetHeight(); | |
2008 } else { | |
2009 if (blenderscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { | |
2010 frame_type = RAS_FrameSettings::e_frame_bars; | |
2011 } else if (blenderscene->gm.framing.type == SCE_GAMEFRAMING_EXTE
ND) { | |
2012 frame_type = RAS_FrameSettings::e_frame_extend; | |
2013 } else { | |
2014 frame_type = RAS_FrameSettings::e_frame_scale; | |
2015 } | |
2016 ················ | |
2017 aspect_width = blenderscene->gm.xsch; | |
2018 aspect_height = blenderscene->gm.ysch; | |
2019 } | |
2020 ········ | |
2021 RAS_FrameSettings frame_settings( | |
2022 frame_type, | |
2023 blenderscene->gm.framing.col[0], | |
2024 blenderscene->gm.framing.col[1], | |
2025 blenderscene->gm.framing.col[2], | |
2026 aspect_width, | |
2027 aspect_height | |
2028 ); | |
2029 kxscene->SetFramingType(frame_settings); | |
2030 | |
2031 kxscene->SetGravity(MT_Vector3(0,0, -blenderscene->gm.gravity)); | |
2032 ········ | |
2033 /* set activity culling parameters */ | |
2034 kxscene->SetActivityCulling( (blenderscene->gm.mode & WO_ACTIVITY_CULLIN
G) != 0); | |
2035 kxscene->SetActivityCullingRadius(blenderscene->gm.activityBoxRadius); | |
2036 kxscene->SetDbvtCulling((blenderscene->gm.mode & WO_DBVT_CULLING) != 0); | |
2037 ········ | |
2038 // no occlusion culling by default | |
2039 kxscene->SetDbvtOcclusionRes(0); | |
2040 | |
2041 int activeLayerBitInfo = blenderscene->lay; | |
2042 ········ | |
2043 // list of all object converted, active and inactive | |
2044 CListValue* sumolist = new CListValue(); | |
2045 ········ | |
2046 vector<parentChildLink> vec_parent_child; | |
2047 ········ | |
2048 CListValue* objectlist = kxscene->GetObjectList(); | |
2049 CListValue* inactivelist = kxscene->GetInactiveList(); | |
2050 CListValue* parentlist = kxscene->GetRootParentList(); | |
2051 ········ | |
2052 SCA_LogicManager* logicmgr = kxscene->GetLogicManager(); | |
2053 SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager(); | |
2054 ········ | |
2055 CListValue* logicbrick_conversionlist = new CListValue(); | |
2056 ········ | |
2057 //SG_TreeFactory tf; | |
2058 ········ | |
2059 // Convert actions to actionmap | |
2060 bAction *curAct; | |
2061 for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)c
urAct->id.next) | |
2062 { | |
2063 logicmgr->RegisterActionName(curAct->id.name + 2, curAct); | |
2064 } | |
2065 | |
2066 SetDefaultLightMode(blenderscene); | |
2067 // Let's support scene set. | |
2068 // Beware of name conflict in linked data, it will not crash but will cr
eate confusion | |
2069 // in Python scripting and in certain actuators (replace mesh). Linked s
cene *should* have | |
2070 // no conflicting name for Object, Object data and Action. | |
2071 for (SETLOOPER(blenderscene, sce_iter, base)) | |
2072 { | |
2073 Object* blenderobject = base->object; | |
2074 allblobj.insert(blenderobject); | |
2075 | |
2076 KX_GameObject* gameobj = gameobject_from_blenderobject( | |
2077
base->object,· | |
2078
kxscene,· | |
2079
rendertools,· | |
2080
converter); | |
2081 ················································································ | |
2082 bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo)
!=0; | |
2083 bool addobj=true; | |
2084 ················ | |
2085 if (converter->addInitFromFrame) | |
2086 if (!isInActiveLayer) | |
2087 addobj=false; | |
2088 | |
2089 if (gameobj&&addobj) | |
2090 { | |
2091 MT_Point3 posPrev;······················ | |
2092 MT_Matrix3x3 angor;····················· | |
2093 if (converter->addInitFromFrame) blenderscene->r.cfra=bl
enderscene->r.sfra; | |
2094 ························ | |
2095 MT_Point3 pos; | |
2096 pos.setValue( | |
2097 blenderobject->loc[0]+blenderobject->dloc[0], | |
2098 blenderobject->loc[1]+blenderobject->dloc[1], | |
2099 blenderobject->loc[2]+blenderobject->dloc[2] | |
2100 ); | |
2101 MT_Vector3 eulxyz(blenderobject->rot); | |
2102 MT_Vector3 scale(blenderobject->size); | |
2103 if (converter->addInitFromFrame){//rcruiz | |
2104 float eulxyzPrev[3]; | |
2105 blenderscene->r.cfra=blenderscene->r.sfra-1; | |
2106 //XXX update_for_newframe(); | |
2107 MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[
0]+blenderobject->dloc[0], | |
2108
blenderobject->loc[1]+blenderobject->dloc[1], | |
2109
blenderobject->loc[2]+blenderobject->dloc[2] | |
2110 ); | |
2111 eulxyzPrev[0]=blenderobject->rot[0]; | |
2112 eulxyzPrev[1]=blenderobject->rot[1]; | |
2113 eulxyzPrev[2]=blenderobject->rot[2]; | |
2114 | |
2115 double fps = (double) blenderscene->r.frs_sec/ | |
2116 (double) blenderscene->r.frs_sec_base; | |
2117 | |
2118 tmp.scale(fps, fps, fps); | |
2119 inivel.push_back(tmp); | |
2120 tmp=eulxyz-eulxyzPrev; | |
2121 tmp.scale(fps, fps, fps); | |
2122 iniang.push_back(tmp); | |
2123 blenderscene->r.cfra=blenderscene->r.sfra; | |
2124 //XXX update_for_newframe(); | |
2125 }··············· | |
2126 ················································ | |
2127 gameobj->NodeSetLocalPosition(pos); | |
2128 gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz)); | |
2129 gameobj->NodeSetLocalScale(scale); | |
2130 gameobj->NodeUpdateGS(0); | |
2131 ························ | |
2132 BL_ConvertIpos(blenderobject,gameobj,converter); | |
2133 BL_ConvertMaterialIpos(blenderobject, gameobj, converter
); | |
2134 ························ | |
2135 sumolist->Add(gameobj->AddRef()); | |
2136 ························ | |
2137 BL_ConvertProperties(blenderobject,gameobj,timemgr,kxsce
ne,isInActiveLayer); | |
2138 ························ | |
2139 gameobj->SetName(blenderobject->id.name + 2); | |
2140 ········ | |
2141 // update children/parent hierarchy | |
2142 if ((blenderobject->parent != 0)&&(!converter->addInitFr
omFrame)) | |
2143 { | |
2144 // blender has an additional 'parentinverse' off
set in each object | |
2145 SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::K
X_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc); | |
2146 SG_Node* parentinversenode = new SG_Node(NULL,kx
scene,callback); | |
2147 ························ | |
2148 // define a normal parent relationship for this
node. | |
2149 KX_NormalParentRelation * parent_relation = KX_N
ormalParentRelation::New(); | |
2150 parentinversenode->SetParentRelation(parent_rela
tion); | |
2151 ········ | |
2152 parentChildLink pclink; | |
2153 pclink.m_blenderchild = blenderobject; | |
2154 pclink.m_gamechildnode = parentinversenode; | |
2155 vec_parent_child.push_back(pclink); | |
2156 | |
2157 float* fl = (float*) blenderobject->parentinv; | |
2158 MT_Transform parinvtrans(fl); | |
2159 parentinversenode->SetLocalPosition(parinvtrans.
getOrigin()); | |
2160 // problem here: the parent inverse transform co
mbines scaling and rotation· | |
2161 // in the basis but the scenegraph needs separat
e rotation and scaling. | |
2162 // This is not important for OpenGL (it uses 4x4
matrix) but it is important | |
2163 // for the physic engine that needs a separate s
caling | |
2164 //parentinversenode->SetLocalOrientation(parinvt
rans.getBasis()); | |
2165 | |
2166 // Extract the rotation and the scaling from the
basis | |
2167 MT_Matrix3x3 ori(parinvtrans.getBasis()); | |
2168 MT_Vector3 x(ori.getColumn(0)); | |
2169 MT_Vector3 y(ori.getColumn(1)); | |
2170 MT_Vector3 z(ori.getColumn(2)); | |
2171 MT_Vector3 parscale(x.length(), y.length(), z.le
ngth()); | |
2172 if (!MT_fuzzyZero(parscale[0])) | |
2173 x /= parscale[0]; | |
2174 if (!MT_fuzzyZero(parscale[1])) | |
2175 y /= parscale[1]; | |
2176 if (!MT_fuzzyZero(parscale[2])) | |
2177 z /= parscale[2]; | |
2178 ori.setColumn(0, x);··································································· | |
2179 ori.setColumn(1, y);··································································· | |
2180 ori.setColumn(2, z);··································································· | |
2181 parentinversenode->SetLocalOrientation(ori); | |
2182 parentinversenode->SetLocalScale(parscale); | |
2183 ································ | |
2184 parentinversenode->AddChild(gameobj->GetSGNode()
); | |
2185 } | |
2186 ························ | |
2187 // needed for python scripting | |
2188 logicmgr->RegisterGameObjectName(gameobj->GetName(),game
obj); | |
2189 | |
2190 // needed for group duplication | |
2191 logicmgr->RegisterGameObj(blenderobject, gameobj); | |
2192 for (int i = 0; i < gameobj->GetMeshCount(); i++) | |
2193 logicmgr->RegisterGameMeshName(gameobj->GetMesh(
i)->GetName(), blenderobject); | |
2194 ········ | |
2195 converter->RegisterGameObject(gameobj, blenderobject);·· | |
2196 // this was put in rapidly, needs to be looked at more c
losely | |
2197 // only draw/use objects in active 'blender' layers | |
2198 ········ | |
2199 logicbrick_conversionlist->Add(gameobj->AddRef()); | |
2200 ························ | |
2201 if (converter->addInitFromFrame){ | |
2202 posPrev=gameobj->NodeGetWorldPosition(); | |
2203 angor=gameobj->NodeGetWorldOrientation(); | |
2204 } | |
2205 if (isInActiveLayer) | |
2206 { | |
2207 objectlist->Add(gameobj->AddRef()); | |
2208 //tf.Add(gameobj->GetSGNode()); | |
2209 ································ | |
2210 gameobj->NodeUpdateGS(0); | |
2211 gameobj->AddMeshUser(); | |
2212 ················ | |
2213 } | |
2214 else | |
2215 { | |
2216 //we must store this object otherwise it will be
deleted· | |
2217 //at the end of this function if it is not a roo
t object | |
2218 inactivelist->Add(gameobj->AddRef()); | |
2219 } | |
2220 if (gameobj->IsDupliGroup()) | |
2221 grouplist.insert(blenderobject->dup_group); | |
2222 if (converter->addInitFromFrame){ | |
2223 gameobj->NodeSetLocalPosition(posPrev); | |
2224 gameobj->NodeSetLocalOrientation(angor); | |
2225 } | |
2226 ················································ | |
2227 } | |
2228 /* Note about memory leak issues: | |
2229 When a CValue derived class is created, m_refcount is initial
ized to 1 | |
2230 so the class must be released after being used to make sure t
hat it won't· | |
2231 hang in memory. If the object needs to be stored for a long t
ime,· | |
2232 use AddRef() so that this Release() does not free the object. | |
2233 Make sure that for any AddRef() there is a Release()!!!!· | |
2234 Do the same for any object derived from CValue, CExpression a
nd NG_NetworkMessage | |
2235 */ | |
2236 if (gameobj) | |
2237 gameobj->Release(); | |
2238 | |
2239 } | |
2240 | |
2241 if (!grouplist.empty()) | |
2242 { | |
2243 // now convert the group referenced by dupli group object | |
2244 // keep track of all groups already converted | |
2245 set<Group*> allgrouplist = grouplist; | |
2246 set<Group*> tempglist; | |
2247 // recurse | |
2248 while (!grouplist.empty()) | |
2249 { | |
2250 set<Group*>::iterator git; | |
2251 tempglist.clear(); | |
2252 tempglist.swap(grouplist); | |
2253 for (git=tempglist.begin(); git!=tempglist.end(); git++) | |
2254 { | |
2255 Group* group = *git; | |
2256 GroupObject* go; | |
2257 for(go=(GroupObject*)group->gobject.first; go; g
o=(GroupObject*)go->next)· | |
2258 { | |
2259 Object* blenderobject = go->ob; | |
2260 if (converter->FindGameObject(blenderobj
ect) == NULL) | |
2261 { | |
2262 allblobj.insert(blenderobject); | |
2263 groupobj.insert(blenderobject); | |
2264 KX_GameObject* gameobj = gameobj
ect_from_blenderobject( | |
2265
blenderobject,· | |
2266
kxscene,· | |
2267
rendertools,· | |
2268
converter); | |
2269 ················································································ | |
2270 // this code is copied from abov
e except that | |
2271 // object from groups are never
in active layer | |
2272 bool isInActiveLayer = false; | |
2273 bool addobj=true; | |
2274 ················································ | |
2275 if (converter->addInitFromFrame) | |
2276 if (!isInActiveLayer) | |
2277 addobj=false; | |
2278 ······················································································································· | |
2279 if (gameobj&&addobj) | |
2280 { | |
2281 MT_Point3 posPrev;····························· | |
2282 MT_Matrix3x3 angor;···························· | |
2283 if (converter->addInitFr
omFrame)· | |
2284 blenderscene->r.
cfra=blenderscene->r.sfra; | |
2285 ························································ | |
2286 MT_Point3 pos( | |
2287 blenderobject->l
oc[0]+blenderobject->dloc[0], | |
2288 blenderobject->l
oc[1]+blenderobject->dloc[1], | |
2289 blenderobject->l
oc[2]+blenderobject->dloc[2] | |
2290 ); | |
2291 MT_Vector3 eulxyz(blende
robject->rot); | |
2292 MT_Vector3 scale(blender
object->size); | |
2293 if (converter->addInitFr
omFrame){//rcruiz | |
2294 float eulxyzPrev
[3]; | |
2295 blenderscene->r.
cfra=blenderscene->r.sfra-1; | |
2296 //XXX update_for
_newframe(); | |
2297 MT_Vector3 tmp=p
os-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0], | |
2298
blenderobject->loc[1]+blenderobject->dlo
c[1], | |
2299
blenderobject->loc[2]+blenderobject->dlo
c[2] | |
2300
); | |
2301 eulxyzPrev[0]=bl
enderobject->rot[0]; | |
2302 eulxyzPrev[1]=bl
enderobject->rot[1]; | |
2303 eulxyzPrev[2]=bl
enderobject->rot[2]; | |
2304 | |
2305 double fps = (do
uble) blenderscene->r.frs_sec/ | |
2306 (double)
blenderscene->r.frs_sec_base; | |
2307 | |
2308 tmp.scale(fps, f
ps, fps); | |
2309 inivel.push_back
(tmp); | |
2310 tmp=eulxyz-eulxy
zPrev; | |
2311 tmp.scale(fps, f
ps, fps); | |
2312 iniang.push_back
(tmp); | |
2313 blenderscene->r.
cfra=blenderscene->r.sfra; | |
2314 //XXX update_for
_newframe(); | |
2315 }··············· | |
2316 ················································································ | |
2317 gameobj->NodeSetLocalPos
ition(pos); | |
2318 gameobj->NodeSetLocalOri
entation(MT_Matrix3x3(eulxyz)); | |
2319 gameobj->NodeSetLocalSca
le(scale); | |
2320 gameobj->NodeUpdateGS(0)
; | |
2321 ························································ | |
2322 BL_ConvertIpos(blenderob
ject,gameobj,converter); | |
2323 BL_ConvertMaterialIpos(b
lenderobject,gameobj, converter);······· | |
2324 ········································ | |
2325 sumolist->Add(gameobj->A
ddRef()); | |
2326 ························································ | |
2327 BL_ConvertProperties(ble
nderobject,gameobj,timemgr,kxscene,isInActiveLayer); | |
2328 ························································ | |
2329 ········································ | |
2330 gameobj->SetName(blender
object->id.name + 2); | |
2331 ········································ | |
2332 // update children/paren
t hierarchy | |
2333 if ((blenderobject->pare
nt != 0)&&(!converter->addInitFromFrame)) | |
2334 { | |
2335 // blender has a
n additional 'parentinverse' offset in each object | |
2336 SG_Callbacks cal
lback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRe
scheduleFunc); | |
2337 SG_Node* parenti
nversenode = new SG_Node(NULL,kxscene,callback); | |
2338 ························································ | |
2339 // define a norm
al parent relationship for this node. | |
2340 KX_NormalParentR
elation * parent_relation = KX_NormalParentRelation::New(); | |
2341 parentinversenod
e->SetParentRelation(parent_relation); | |
2342 ········································ | |
2343 parentChildLink
pclink; | |
2344 pclink.m_blender
child = blenderobject; | |
2345 pclink.m_gamechi
ldnode = parentinversenode; | |
2346 vec_parent_child
.push_back(pclink); | |
2347 | |
2348 float* fl = (flo
at*) blenderobject->parentinv; | |
2349 MT_Transform par
invtrans(fl); | |
2350 parentinversenod
e->SetLocalPosition(parinvtrans.getOrigin()); | |
2351 | |
2352 // Extract the r
otation and the scaling from the basis | |
2353 MT_Matrix3x3 ori
(parinvtrans.getBasis()); | |
2354 MT_Vector3 x(ori
.getColumn(0)); | |
2355 MT_Vector3 y(ori
.getColumn(1)); | |
2356 MT_Vector3 z(ori
.getColumn(2)); | |
2357 MT_Vector3 local
scale(x.length(), y.length(), z.length()); | |
2358 if (!MT_fuzzyZer
o(localscale[0])) | |
2359 x /= loc
alscale[0]; | |
2360 if (!MT_fuzzyZer
o(localscale[1])) | |
2361 y /= loc
alscale[1]; | |
2362 if (!MT_fuzzyZer
o(localscale[2])) | |
2363 z /= loc
alscale[2]; | |
2364 ori.setColumn(0,
x);···························································· | |
2365 ori.setColumn(1,
y);···························································· | |
2366 ori.setColumn(2,
z);···························································· | |
2367 parentinversenod
e->SetLocalOrientation(ori); | |
2368 parentinversenod
e->SetLocalScale(localscale); | |
2369 ································································ | |
2370 parentinversenod
e->AddChild(gameobj->GetSGNode()); | |
2371 } | |
2372 ························································ | |
2373 // needed for python scr
ipting | |
2374 logicmgr->RegisterGameOb
jectName(gameobj->GetName(),gameobj); | |
2375 | |
2376 // needed for group dupl
ication | |
2377 logicmgr->RegisterGameOb
j(blenderobject, gameobj); | |
2378 for (int i = 0; i < game
obj->GetMeshCount(); i++) | |
2379 logicmgr->Regist
erGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject); | |
2380 ········································ | |
2381 converter->RegisterGameO
bject(gameobj, blenderobject);·· | |
2382 // this was put in rapid
ly, needs to be looked at more closely | |
2383 // only draw/use objects
in active 'blender' layers | |
2384 ········································ | |
2385 logicbrick_conversionlis
t->Add(gameobj->AddRef()); | |
2386 ························································ | |
2387 if (converter->addInitFr
omFrame){ | |
2388 posPrev=gameobj-
>NodeGetWorldPosition(); | |
2389 angor=gameobj->N
odeGetWorldOrientation(); | |
2390 } | |
2391 if (isInActiveLayer) | |
2392 { | |
2393 objectlist->Add(
gameobj->AddRef()); | |
2394 //tf.Add(gameobj
->GetSGNode()); | |
2395 ································································ | |
2396 gameobj->NodeUpd
ateGS(0); | |
2397 gameobj->AddMesh
User(); | |
2398 } | |
2399 else | |
2400 { | |
2401 //we must store
this object otherwise it will be deleted· | |
2402 //at the end of
this function if it is not a root object | |
2403 inactivelist->Ad
d(gameobj->AddRef()); | |
2404 | |
2405 } | |
2406 if (gameobj->IsDupliGrou
p()) | |
2407 { | |
2408 // check that th
e group is not already converted | |
2409 if (allgrouplist
.insert(blenderobject->dup_group).second) | |
2410 grouplis
t.insert(blenderobject->dup_group); | |
2411 } | |
2412 if (converter->addInitFr
omFrame){ | |
2413 gameobj->NodeSet
LocalPosition(posPrev); | |
2414 gameobj->NodeSet
LocalOrientation(angor); | |
2415 } | |
2416 ················································································ | |
2417 } | |
2418 if (gameobj) | |
2419 gameobj->Release(); | |
2420 } | |
2421 } | |
2422 } | |
2423 } | |
2424 } | |
2425 | |
2426 // non-camera objects not supported as camera currently | |
2427 if (blenderscene->camera && blenderscene->camera->type == OB_CAMERA) { | |
2428 KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(bl
enderscene->camera); | |
2429 ················ | |
2430 if(gamecamera) | |
2431 kxscene->SetActiveCamera(gamecamera); | |
2432 } | |
2433 | |
2434 // Set up armatures | |
2435 set<Object*>::iterator oit; | |
2436 for(oit=allblobj.begin(); oit!=allblobj.end(); oit++) | |
2437 { | |
2438 Object* blenderobj = *oit; | |
2439 if (blenderobj->type==OB_MESH) { | |
2440 Mesh *me = (Mesh*)blenderobj->data; | |
2441 ········ | |
2442 if (me->dvert){ | |
2443 BL_DeformableGameObject *obj = (BL_DeformableGam
eObject*)converter->FindGameObject(blenderobj); | |
2444 | |
2445 if (obj && BL_ModifierDeformer::HasArmatureDefor
mer(blenderobj) && blenderobj->parent && blenderobj->parent->type==OB_ARMATURE){ | |
2446 KX_GameObject *par = converter->FindGame
Object(blenderobj->parent); | |
2447 if (par && obj->GetDeformer()) | |
2448 ((BL_SkinDeformer*)obj->GetDefor
mer())->SetArmature((BL_ArmatureObject*) par); | |
2449 } | |
2450 } | |
2451 } | |
2452 } | |
2453 ········ | |
2454 // create hierarchy information | |
2455 int i; | |
2456 vector<parentChildLink>::iterator pcit; | |
2457 ········ | |
2458 for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++p
cit) | |
2459 { | |
2460 ········ | |
2461 struct Object* blenderchild = pcit->m_blenderchild; | |
2462 struct Object* blenderparent = blenderchild->parent; | |
2463 KX_GameObject* parentobj = converter->FindGameObject(blenderpare
nt); | |
2464 KX_GameObject* childobj = converter->FindGameObject(blenderchild
); | |
2465 | |
2466 assert(childobj); | |
2467 | |
2468 if (!parentobj || objectlist->SearchValue(childobj) != objectlis
t->SearchValue(parentobj)) | |
2469 { | |
2470 // special case: the parent and child object are not in
the same layer.· | |
2471 // This weird situation is used in Apricot for test purp
oses. | |
2472 // Resolve it by not converting the child | |
2473 childobj->GetSGNode()->DisconnectFromParent(); | |
2474 delete pcit->m_gamechildnode; | |
2475 // Now destroy the child object but also all its descend
ent that may already be linked | |
2476 // Remove the child reference in the local list! | |
2477 // Note: there may be descendents already if the childre
n of the child were processed | |
2478 // by this loop before the child. In that case, we
must remove the children also | |
2479 CListValue* childrenlist = childobj->GetChildrenRecursiv
e(); | |
2480 childrenlist->Add(childobj->AddRef()); | |
2481 for ( i=0;i<childrenlist->GetCount();i++) | |
2482 { | |
2483 KX_GameObject* obj = static_cast<KX_GameObject*>
(childrenlist->GetValue(i)); | |
2484 if (sumolist->RemoveValue(obj)) | |
2485 obj->Release(); | |
2486 if (logicbrick_conversionlist->RemoveValue(obj)) | |
2487 obj->Release(); | |
2488 } | |
2489 childrenlist->Release(); | |
2490 ························ | |
2491 // now destroy recursively | |
2492 converter->UnregisterGameObject(childobj); // removing o
bjects during conversion make sure this runs too | |
2493 kxscene->RemoveObject(childobj); | |
2494 ························ | |
2495 continue; | |
2496 } | |
2497 | |
2498 switch (blenderchild->partype) | |
2499 { | |
2500 case PARVERT1: | |
2501 { | |
2502 // creat a new vertex parent relationship for th
is node. | |
2503 KX_VertexParentRelation * vertex_parent_relation
= KX_VertexParentRelation::New(); | |
2504 pcit->m_gamechildnode->SetParentRelation(vertex_
parent_relation); | |
2505 break; | |
2506 } | |
2507 case PARSLOW: | |
2508 { | |
2509 // creat a new slow parent relationship for this
node. | |
2510 KX_SlowParentRelation * slow_parent_relation = K
X_SlowParentRelation::New(blenderchild->sf); | |
2511 pcit->m_gamechildnode->SetParentRelation(slow_pa
rent_relation); | |
2512 break; | |
2513 }······· | |
2514 case PARBONE: | |
2515 { | |
2516 // parent this to a bone | |
2517 Bone *parent_bone = get_named_bone( (bArmature *
)(blenderchild->parent)->data, blenderchild->parsubstr); | |
2518 | |
2519 if(parent_bone) { | |
2520 KX_BoneParentRelation *bone_parent_relat
ion = KX_BoneParentRelation::New(parent_bone); | |
2521 pcit->m_gamechildnode->SetParentRelation
(bone_parent_relation); | |
2522 } | |
2523 ························ | |
2524 break; | |
2525 } | |
2526 case PARSKEL: // skinned - ignore | |
2527 break; | |
2528 case PAROBJECT: | |
2529 case PARCURVE: | |
2530 case PARKEY: | |
2531 case PARVERT3: | |
2532 default: | |
2533 // unhandled | |
2534 break; | |
2535 } | |
2536 ········ | |
2537 parentobj-> GetSGNode()->AddChild(pcit->m_gamechildnode); | |
2538 } | |
2539 vec_parent_child.clear(); | |
2540 ········ | |
2541 // find 'root' parents (object that has not parents in SceneGraph) | |
2542 for (i=0;i<sumolist->GetCount();++i) | |
2543 { | |
2544 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); | |
2545 if (gameobj->GetSGNode()->GetSGParent() == 0) | |
2546 { | |
2547 parentlist->Add(gameobj->AddRef()); | |
2548 gameobj->NodeUpdateGS(0); | |
2549 } | |
2550 } | |
2551 | |
2552 // create graphic controller for culling | |
2553 if (kxscene->GetDbvtCulling()) | |
2554 { | |
2555 bool occlusion = false; | |
2556 for (i=0; i<sumolist->GetCount();i++) | |
2557 { | |
2558 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetV
alue(i); | |
2559 if (gameobj->GetMeshCount() > 0)· | |
2560 { | |
2561 MT_Point3 box[2]; | |
2562 gameobj->GetSGNode()->BBox().getmm(box, MT_Trans
form::Identity()); | |
2563 // box[0] is the min, box[1] is the max | |
2564 bool isactive = objectlist->SearchValue(gameobj)
; | |
2565 BL_CreateGraphicObjectNew(gameobj,box[0],box[1],
kxscene,isactive,physics_engine); | |
2566 if (gameobj->GetOccluder()) | |
2567 occlusion = true; | |
2568 } | |
2569 } | |
2570 if (occlusion) | |
2571 kxscene->SetDbvtOcclusionRes(blenderscene->gm.occlusionR
es); | |
2572 } | |
2573 if (blenderscene->world) | |
2574 kxscene->GetPhysicsEnvironment()->setNumTimeSubSteps(blenderscen
e->gm.physubstep); | |
2575 | |
2576 // now that the scenegraph is complete, let's instantiate the deformers. | |
2577 // We need that to create reusable derived mesh and physic shapes | |
2578 for (i=0;i<sumolist->GetCount();++i) | |
2579 { | |
2580 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); | |
2581 if (gameobj->GetDeformer()) | |
2582 gameobj->GetDeformer()->UpdateBuckets(); | |
2583 } | |
2584 | |
2585 // Set up armature constraints | |
2586 for (i=0;i<sumolist->GetCount();++i) | |
2587 { | |
2588 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); | |
2589 if (gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) | |
2590 ((BL_ArmatureObject*)gameobj)->LoadConstraints(converter
); | |
2591 } | |
2592 | |
2593 bool processCompoundChildren = false; | |
2594 | |
2595 // create physics information | |
2596 for (i=0;i<sumolist->GetCount();i++) | |
2597 { | |
2598 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); | |
2599 struct Object* blenderobject = gameobj->GetBlenderObject(); | |
2600 int nummeshes = gameobj->GetMeshCount(); | |
2601 RAS_MeshObject* meshobj = 0; | |
2602 if (nummeshes > 0) | |
2603 { | |
2604 meshobj = gameobj->GetMesh(0); | |
2605 } | |
2606 int layerMask = (groupobj.find(blenderobject) == groupobj.end())
? activeLayerBitInfo : 0; | |
2607 BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,
layerMask,physics_engine,converter,processCompoundChildren); | |
2608 } | |
2609 | |
2610 processCompoundChildren = true; | |
2611 // create physics information | |
2612 for (i=0;i<sumolist->GetCount();i++) | |
2613 { | |
2614 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); | |
2615 struct Object* blenderobject = gameobj->GetBlenderObject(); | |
2616 int nummeshes = gameobj->GetMeshCount(); | |
2617 RAS_MeshObject* meshobj = 0; | |
2618 if (nummeshes > 0) | |
2619 { | |
2620 meshobj = gameobj->GetMesh(0); | |
2621 } | |
2622 int layerMask = (groupobj.find(blenderobject) == groupobj.end())
? activeLayerBitInfo : 0; | |
2623 BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,
layerMask,physics_engine,converter,processCompoundChildren); | |
2624 } | |
2625 ········ | |
2626 //set ini linearVel and int angularVel //rcruiz | |
2627 if (converter->addInitFromFrame) | |
2628 for (i=0;i<sumolist->GetCount();i++) | |
2629 { | |
2630 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetV
alue(i); | |
2631 if (gameobj->IsDynamic()){ | |
2632 gameobj->setLinearVelocity(inivel[i],false); | |
2633 gameobj->setAngularVelocity(iniang[i],false); | |
2634 } | |
2635 ················ | |
2636 ················ | |
2637 }······· | |
2638 | |
2639 // create physics joints | |
2640 for (i=0;i<sumolist->GetCount();i++) | |
2641 { | |
2642 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); | |
2643 struct Object* blenderobject = gameobj->GetBlenderObject(); | |
2644 ListBase *conlist; | |
2645 bConstraint *curcon; | |
2646 conlist = get_active_constraints2(blenderobject); | |
2647 | |
2648 if (conlist) { | |
2649 for (curcon = (bConstraint *)conlist->first; curcon; cur
con=(bConstraint *)curcon->next) { | |
2650 if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT
){ | |
2651 | |
2652 bRigidBodyJointConstraint *dat=(bRigidBo
dyJointConstraint *)curcon->data; | |
2653 | |
2654 if (!dat->child){ | |
2655 | |
2656 PHY_IPhysicsController* physctr2
= 0; | |
2657 | |
2658 if (dat->tar) | |
2659 { | |
2660 KX_GameObject *gotar=get
GameOb(dat->tar->id.name+2,sumolist); | |
2661 if (gotar && gotar->GetP
hysicsController()) | |
2662 physctr2 = (PHY_
IPhysicsController*) gotar->GetPhysicsController()->GetUserData(); | |
2663 } | |
2664 | |
2665 if (gameobj->GetPhysicsControlle
r()) | |
2666 { | |
2667 PHY_IPhysicsController*
physctrl = (PHY_IPhysicsController*) gameobj->GetPhysicsController()->GetUserDat
a(); | |
2668 //we need to pass a full
constraint frame, not just axis | |
2669 ···································· | |
2670 //localConstraintFrameBa
sis | |
2671 MT_Matrix3x3 localCFrame
(MT_Vector3(dat->axX,dat->axY,dat->axZ)); | |
2672 MT_Vector3 axis0 = local
CFrame.getColumn(0); | |
2673 MT_Vector3 axis1 = local
CFrame.getColumn(1); | |
2674 MT_Vector3 axis2 = local
CFrame.getColumn(2); | |
2675 ································································ | |
2676 int constraintId = kxsce
ne->GetPhysicsEnvironment()->createConstraint(physctrl,physctr2,(PHY_ConstraintT
ype)dat->type,(float)dat->pivX, | |
2677 (float)dat->pivY
,(float)dat->pivZ, | |
2678 (float)axis0.x()
,(float)axis0.y(),(float)axis0.z(), | |
2679 (float)axis1.x()
,(float)axis1.y(),(float)axis1.z(), | |
2680 (float)axis2.x()
,(float)axis2.y(),(float)axis2.z(),dat->flag); | |
2681 if (constraintId) | |
2682 { | |
2683 //if it is a gen
eric 6DOF constraint, set all the limits accordingly | |
2684 if (dat->type ==
PHY_GENERIC_6DOF_CONSTRAINT) | |
2685 { | |
2686 int dof; | |
2687 int dofb
it=1; | |
2688 for (dof
=0;dof<6;dof++) | |
2689 { | |
2690
if (dat->flag & dofbit) | |
2691
{ | |
2692
kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,da
t->minLimit[dof],dat->maxLimit[dof]); | |
2693
} else | |
2694
{ | |
2695
//minLimit > maxLimit means free(disabled limit) for this degree of free
dom | |
2696
kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,1,
-1); | |
2697
} | |
2698
dofbit<<=1; | |
2699 } | |
2700 } | |
2701 else if(dat->typ
e == PHY_CONE_TWIST_CONSTRAINT) | |
2702 { | |
2703 int dof; | |
2704 int dofb
it = 1<<3; // bitflag use_angular_limit_x | |
2705 ········································································ | |
2706 for (dof
=3;dof<6;dof++) | |
2707 { | |
2708
if(dat->flag & dofbit) | |
2709
{ | |
2710
kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,da
t->minLimit[dof],dat->maxLimit[dof]); | |
2711
} | |
2712
else | |
2713
{ | |
2714
//maxLimit < 0 means free(disabled limit) for this degree of freedom | |
2715
kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,1,
-1); | |
2716
} | |
2717
dofbit<<=1; | |
2718 }······································································ | |
2719 } | |
2720 else if (dat->ty
pe == PHY_LINEHINGE_CONSTRAINT) | |
2721 { | |
2722 int dof
= 3; // dof for angular x | |
2723 int dofb
it = 1<<3; // bitflag use_angular_limit_x | |
2724 ········································································ | |
2725 if (dat-
>flag & dofbit) | |
2726 { | |
2727
kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof, | |
2728
dat->minLimit[dof],dat->maxLimit[dof]); | |
2729 } else | |
2730 { | |
2731
//minLimit > maxLimit means free(disabled limit) for this degree of freedom | |
2732
kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,1,-1); | |
2733 } | |
2734 } | |
2735 } | |
2736 } | |
2737 } | |
2738 } | |
2739 } | |
2740 } | |
2741 } | |
2742 | |
2743 sumolist->Release(); | |
2744 | |
2745 // convert world | |
2746 KX_WorldInfo* worldinfo = new BlenderWorldInfo(blenderscene, blenderscen
e->world); | |
2747 converter->RegisterWorldInfo(worldinfo); | |
2748 kxscene->SetWorldInfo(worldinfo); | |
2749 | |
2750 #define CONVERT_LOGIC | |
2751 #ifdef CONVERT_LOGIC | |
2752 // convert logic bricks, sensors, controllers and actuators | |
2753 for (i=0;i<logicbrick_conversionlist->GetCount();i++) | |
2754 { | |
2755 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_
conversionlist->GetValue(i)); | |
2756 struct Object* blenderobj = gameobj->GetBlenderObject(); | |
2757 int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ?
activeLayerBitInfo : 0; | |
2758 bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; | |
2759 BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kx
scene,ketsjiEngine,layerMask,isInActiveLayer,rendertools,converter); | |
2760 } | |
2761 for ( i=0;i<logicbrick_conversionlist->GetCount();i++) | |
2762 { | |
2763 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_
conversionlist->GetValue(i)); | |
2764 struct Object* blenderobj = gameobj->GetBlenderObject(); | |
2765 int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ?
activeLayerBitInfo : 0; | |
2766 bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; | |
2767 BL_ConvertControllers(blenderobj,gameobj,logicmgr, layerMask,isI
nActiveLayer,converter); | |
2768 } | |
2769 for ( i=0;i<logicbrick_conversionlist->GetCount();i++) | |
2770 { | |
2771 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_
conversionlist->GetValue(i)); | |
2772 struct Object* blenderobj = gameobj->GetBlenderObject(); | |
2773 int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ?
activeLayerBitInfo : 0; | |
2774 bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; | |
2775 BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,ketsjiEngi
ne,layerMask,isInActiveLayer,canvas,converter); | |
2776 // set the init state to all objects | |
2777 gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_
state:blenderobj->state); | |
2778 } | |
2779 // apply the initial state to controllers, only on the active objects as
this registers the sensors | |
2780 for ( i=0;i<objectlist->GetCount();i++) | |
2781 { | |
2782 KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist-
>GetValue(i)); | |
2783 gameobj->ResetState(); | |
2784 } | |
2785 | |
2786 #endif //CONVERT_LOGIC | |
2787 | |
2788 logicbrick_conversionlist->Release(); | |
2789 ········ | |
2790 // Calculate the scene btree - | |
2791 // too slow - commented out. | |
2792 //kxscene->SetNodeTree(tf.MakeTree()); | |
2793 | |
2794 // instantiate dupli group, we will loop trough the object | |
2795 // that are in active layers. Note that duplicating group | |
2796 // has the effect of adding objects at the end of objectlist. | |
2797 // Only loop through the first part of the list. | |
2798 int objcount = objectlist->GetCount(); | |
2799 for (i=0;i<objcount;i++) | |
2800 { | |
2801 KX_GameObject* gameobj = (KX_GameObject*) objectlist->GetValue(i
); | |
2802 if (gameobj->IsDupliGroup()) | |
2803 { | |
2804 kxscene->DupliGroupRecurse(gameobj, 0); | |
2805 } | |
2806 } | |
2807 | |
2808 KX_Camera *activecam = kxscene->GetActiveCamera(); | |
2809 MT_Scalar distance = (activecam)? activecam->GetCameraFar() - activecam-
>GetCameraNear(): 100.0f; | |
2810 RAS_BucketManager *bucketmanager = kxscene->GetBucketManager(); | |
2811 bucketmanager->OptimizeBuckets(distance); | |
2812 } | |
LEFT | RIGHT |