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