00001 #define BLENDER_HACK_DTIME 0.02
00002
00003 #include "KX_ConvertActuators.h"
00004
00005
00006
00007 #include "SCA_PropertyActuator.h"
00008 #include "SCA_LogicManager.h"
00009 #include "SCA_AddObjectActuator.h"
00010 #include "SCA_EndObjectActuator.h"
00011 #include "SCA_ReplaceMeshActuator.h"
00012 #include "SCA_GroupActuator.h"
00013 #include "SCA_RandomActuator.h"
00014
00015 #include "KX_SceneActuator.h"
00016 #include "KX_IpoActuator.h"
00017 #include "KX_SoundActuator.h"
00018 #include "KX_ObjectActuator.h"
00019 #include "KX_TrackToActuator.h"
00020 #include "KX_ConstraintActuator.h"
00021 #include "KX_CameraActuator.h"
00022 #include "KX_Scene.h"
00023 #include "OpenALScene.h"
00024 #include "IntValue.h"
00025
00026 #include "KX_GameObject.h"
00027 #include "KX_BlenderKetsjiConversionMaps.h"
00028 #include "blender.h"
00029 #include "game.h"
00030 #include "sound.h"
00034
00035 #define KX_BLENDERTRUNC(x) (( x < 0.0001 && x > -0.0001 ) ? 0.0 : x)
00036
00037 void BL_ConvertActuators(struct Object* blenderobject,KX_GameObject* gameobj,SCA_LogicManager* logicmgr,KX_Scene* scene,int & executePriority)
00038 {
00039
00040 int uniqueint = 0;
00041 bActuator* bact = (bActuator*) blenderobject->actuators.first;
00042 while(bact)
00043 {
00044 CCString uniquename = bact->name;
00045 CCString objectname = gameobj->GetName();
00046
00047 SCA_IActuator* gameact = NULL;
00048 switch (bact->type)
00049 {
00050 case ACT_OBJECT:
00051 {
00052
00053 bObjectActuator* obact = (bObjectActuator*) bact->data;
00054 MT_Vector3 forcevec(KX_BLENDERTRUNC(obact->forceloc[0]),
00055 KX_BLENDERTRUNC(obact->forceloc[1]),
00056 KX_BLENDERTRUNC(obact->forceloc[2]));
00057 MT_Vector3 torquevec(obact->forcerot[0],obact->forcerot[1],obact->forcerot[2]);
00058 MT_Vector3 dlocvec ( KX_BLENDERTRUNC(obact->dloc[0]),
00059 KX_BLENDERTRUNC(obact->dloc[1]),
00060 KX_BLENDERTRUNC(obact->dloc[2]));
00061 MT_Vector3 drotvec ( KX_BLENDERTRUNC(obact->drot[0]),obact->drot[1],obact->drot[2]);
00062 MT_Vector3 linvelvec ( KX_BLENDERTRUNC(obact->linearvelocity[0]),
00063 KX_BLENDERTRUNC(obact->linearvelocity[1]),
00064 KX_BLENDERTRUNC(obact->linearvelocity[2]));
00065 MT_Vector3 angvelvec ( KX_BLENDERTRUNC(obact->angularvelocity[0]),
00066 KX_BLENDERTRUNC(obact->angularvelocity[1]),
00067 KX_BLENDERTRUNC(obact->angularvelocity[2]));
00068
00069 forcevec /= BLENDER_HACK_DTIME;
00070 torquevec /= BLENDER_HACK_DTIME;
00071 dlocvec /= BLENDER_HACK_DTIME;
00072 drotvec /= BLENDER_HACK_DTIME;
00073 linvelvec /= BLENDER_HACK_DTIME;
00074 angvelvec /= BLENDER_HACK_DTIME;
00075
00076
00077
00078
00079
00080 KX_LocalFlags bitLocalFlag;
00081
00082 bitLocalFlag.Force = bool((obact->flag & ACT_FORCE_LOCAL)!=0);
00083 bitLocalFlag.Torque = bool((obact->flag & ACT_TORQUE_LOCAL) !=0);
00084 bitLocalFlag.DLoc = bool((obact->flag & ACT_DLOC_LOCAL)!=0);
00085 bitLocalFlag.DRot = bool((obact->flag & ACT_DROT_LOCAL)!=0);
00086 bitLocalFlag.LinearVelocity = bool((obact->flag & ACT_LIN_VEL_LOCAL)!=0);
00087 bitLocalFlag.AngularVelocity = bool((obact->flag & ACT_ANG_VEL_LOCAL)!=0);
00088
00089 KX_ObjectActuator* tmpgameact = new KX_ObjectActuator(gameobj,
00090 forcevec.getValue(),
00091 torquevec.getValue(),
00092 dlocvec.getValue(),
00093 drotvec.getValue(),
00094 linvelvec.getValue(),
00095 angvelvec.getValue(),
00096 bitLocalFlag
00097 );
00098 gameact = tmpgameact;
00099 break;
00100 }
00101 case ACT_IPO:
00102 {
00103 bIpoActuator* ipoact = (bIpoActuator*) bact->data;
00104 CCString propname = ( ipoact->name ? ipoact->name : "");
00105
00106 KX_IpoActuator* tmpgameact = new KX_IpoActuator(gameobj,propname ,ipoact->sta/2,ipoact->end/2,
00107 ipoact->type + 1
00108
00109 );
00110 gameact = tmpgameact;
00111 break;
00112 }
00113 case ACT_LAMP:
00114 {
00115 break;
00116 }
00117 case ACT_CAMERA:
00118 {
00119 bCameraActuator *camact = (bCameraActuator *) bact->data;
00120 if (camact->ob) {
00121 KX_GameObject *tmpgob =
00122 *map_blender_to_gameobject[CHashedPtr(camact->ob)];
00123
00124
00125
00126 KX_CameraActuator *tmpcamact
00127 = new KX_CameraActuator(gameobj,
00128 tmpgob,
00129 camact->height,
00130 camact->min,
00131 camact->max,
00132 camact->axis=='x');
00133 gameact = tmpcamact;
00134 }
00135 break;
00136 }
00137 case ACT_MATERIAL:
00138 {
00139 break;
00140 }
00141 case ACT_SOUND:
00142 {
00143 bSoundActuator* soundact = (bSoundActuator*) bact->data;
00144
00145 short startFrame = soundact->sta, stopFrame = soundact->end;
00146 KX_SoundActuator::KX_SOUNDACT_TYPE
00147 soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NODEF;
00148
00149 switch(soundact->type) {
00150 case ACT_SND_PLAY_STOP_SOUND:
00151 soundActuatorType = KX_SoundActuator::KX_SOUNDACT_PLAYSTOP;
00152 break;
00153 case ACT_SND_PLAY_END_SOUND:
00154 soundActuatorType = KX_SoundActuator::KX_SOUNDACT_PLAYEND;
00155 break;
00156 case ACT_SND_LOOP_STOP_SOUND:
00157 soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPSTOP;
00158 break;
00159 case ACT_SND_LOOP_END_SOUND:
00160 soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPEND;
00161 break;
00162 case ACT_SND_NEW_SOUND:
00163 soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NEWSOUND;
00164 break;
00165
00166 default:
00167
00168 soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NODEF;
00169 }
00170
00171 if (soundActuatorType != KX_SoundActuator::KX_SOUNDACT_NODEF)
00172 {
00173 SND_SoundObject* sndobj = new SND_SoundObject();
00174 if (soundact->sound)
00175 {
00176 sndobj->setSample(soundact->sound->name);
00177
00178 KX_SoundActuator* tmpsoundact =
00179 new KX_SoundActuator(gameobj,
00180 sndobj,
00181 soundActuatorType,
00182 startFrame,
00183 stopFrame,
00184 0);
00185 gameact = tmpsoundact;
00186
00187 scene->GetSoundScene()->addObject(sndobj);
00188 } else
00189 {
00190 printf ("ERROR: GameObject %s has a SoundActuator %s without sound\n",
00191 objectname.ReadPtr(),
00192 uniquename.ReadPtr() );
00193
00194 }
00195
00196 }
00197 break;
00198 }
00199
00200 case ACT_PROPERTY:
00201 {
00202
00203 bPropertyActuator* propact = (bPropertyActuator*) bact->data;
00204
00205 CValue* destinationObj = (propact->ob ?
00206 *map_blender_to_gameobject[CHashedPtr(propact->ob)] :
00207 NULL);
00208
00209 SCA_PropertyActuator* tmppropact = new SCA_PropertyActuator(
00210 gameobj,
00211 destinationObj,
00212 propact->name,
00213 propact->value,
00214 propact->type+1);
00215
00216 gameact = tmppropact;
00217 break;
00218 }
00219 case ACT_EDIT_OBJECT:
00220 {
00221 bEditObjectActuator *editobact
00222 = (bEditObjectActuator *) bact->data;
00223
00224
00225
00226 switch (editobact->type) {
00227 case ACT_EDOB_ADD_OBJECT:
00228 {
00229
00230 if (editobact->ob)
00231 {
00232 CValue* originalval = *map_blender_to_gameobject[CHashedPtr(editobact->ob)];
00233 if (originalval)
00234 {
00235 MT_Vector3 linvelvec ( KX_BLENDERTRUNC(editobact->linVelocity[0]),
00236 KX_BLENDERTRUNC(editobact->linVelocity[1]),
00237 KX_BLENDERTRUNC(editobact->linVelocity[2]));
00238 SCA_AddObjectActuator* tmpaddact =
00239 new SCA_AddObjectActuator(gameobj,
00240 originalval,
00241 editobact->time,
00242 scene,
00243 linvelvec.getValue(),
00244 editobact->localflag!=0);
00245
00246
00247 gameact = tmpaddact;
00248 }
00249 else
00250 {
00251
00252 exit(0);
00253 }
00254 } else
00255 {
00256 printf ("ERROR: GameObject %s has a AddObjectActuator %s without object\n",
00257 objectname.ReadPtr(),
00258 uniquename.ReadPtr() );
00259 }
00260 }
00261 break;
00262 case ACT_EDOB_END_OBJECT:
00263 {
00264 SCA_EndObjectActuator* tmpendact
00265 = new SCA_EndObjectActuator(gameobj,scene);
00266 gameact = tmpendact;
00267 }
00268 break;
00269 case ACT_EDOB_REPLACE_MESH:
00270 {
00271 if (editobact->me)
00272 {
00273 RAS_MeshObject *tmpmesh
00274 = BL_ConvertMesh(editobact->me, blenderobject);
00275 SCA_ReplaceMeshActuator* tmpreplaceact
00276 = new SCA_ReplaceMeshActuator(gameobj,tmpmesh,scene);
00277 gameact = tmpreplaceact;
00278 } else
00279 {
00280 printf ("ERROR: GameObject %s ReplaceMeshActuator %s without object\n",
00281 objectname.ReadPtr(),
00282 uniquename.ReadPtr() );
00283
00284 }
00285 }
00286 break;
00287 case ACT_EDOB_TRACK_TO:
00288 {
00289 if (editobact->ob)
00290 {
00291 SCA_IObject* originalval = *map_blender_to_gameobject[CHashedPtr(editobact->ob)];
00292
00293
00294
00295
00296 KX_TrackToActuator* tmptrackact
00297 = new KX_TrackToActuator(gameobj,
00298 originalval,
00299 editobact->time,
00300 editobact->flag,
00301 blenderobject->trackflag,
00302 blenderobject->upflag
00303 );
00304 gameact = tmptrackact;
00305 } else
00306 {
00307 printf("ERROR: GameObject %s no object in EditObjectActuator %s\n",
00308 objectname.ReadPtr(),
00309 uniquename.ReadPtr() );
00310
00311
00312 }
00313 }
00314 }
00315 break;
00316 }
00317 case ACT_CONSTRAINT:
00318 {
00319 float min = 0.0, max = 0.0;
00320 int locrot;
00321 bConstraintActuator *conact
00322 = (bConstraintActuator*) bact->data;
00323
00324
00325 switch (conact->flag) {
00326 case ACT_CONST_LOCX:
00327 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCX;
00328 min = conact->minloc[0];
00329 max = conact->maxloc[0];
00330 break;
00331 case ACT_CONST_LOCY:
00332 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCY;
00333 min = conact->minloc[1];
00334 max = conact->maxloc[1];
00335 break;
00336 case ACT_CONST_LOCZ:
00337 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCZ;
00338 min = conact->minloc[2];
00339 max = conact->maxloc[2];
00340 case ACT_CONST_ROTX:
00341 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTX;
00342 min = MT_2_PI * conact->minrot[0] / 360.0;
00343 max = MT_2_PI * conact->minrot[0] / 360.0;
00344 break;
00345 case ACT_CONST_ROTY:
00346 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTY;
00347 min = MT_2_PI * conact->minrot[1] / 360.0;
00348 max = MT_2_PI * conact->minrot[1] / 360.0;
00349 break;
00350 case ACT_CONST_ROTZ:
00351 locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTZ;
00352 min = MT_2_PI * conact->minrot[2] / 360.0;
00353 max = MT_2_PI * conact->minrot[2] / 360.0;
00354 break;
00355 default:
00356 ;
00357 }
00358 KX_ConstraintActuator *tmpconact
00359 = new KX_ConstraintActuator(gameobj,
00360 conact->damp,
00361 min,
00362 max,
00363 locrot);
00364 gameact = tmpconact;
00365 break;
00366 }
00367 case ACT_GROUP:
00368 {
00369 bGroupActuator *groupact
00370 = (bGroupActuator *) bact->data;
00371 SCA_GroupActuator *tmpgroupact = NULL;
00372 int mode = -1, startF = -1, stopF = -1;
00373 void *keyP = NULL, *propP = NULL;
00374 switch (groupact->type) {
00375 case ACT_GROUP_PLAY:
00376 mode = SCA_GroupActuator::KX_ACT_GROUP_PLAY;
00377 startF = groupact->sta;
00378 stopF = groupact->end;
00379 break;
00380 case ACT_GROUP_PINGPONG:
00381 mode = SCA_GroupActuator::KX_ACT_GROUP_PINGPONG;
00382 startF = groupact->sta;
00383 stopF = groupact->end;
00384 break;
00385 case ACT_GROUP_FLIPPER:
00386 mode = SCA_GroupActuator::KX_ACT_GROUP_FLIPPER;
00387 startF = groupact->sta;
00388 stopF = groupact->end;
00389 break;
00390 case ACT_GROUP_LOOP_STOP:
00391 mode = SCA_GroupActuator::KX_ACT_GROUP_LOOPSTOP;
00392 startF = groupact->sta;
00393 stopF = groupact->end;
00394 break;
00395 case ACT_GROUP_LOOP_END:
00396 mode = SCA_GroupActuator::KX_ACT_GROUP_LOOPEND;
00397 startF = groupact->sta;
00398 stopF = groupact->end;
00399 break;
00400
00401
00402
00403
00404 case ACT_GROUP_SET:
00405 mode = SCA_GroupActuator::KX_ACT_GROUP_SETKEY;
00406 break;
00407 case ACT_GROUP_FROM_PROP:
00408 mode = SCA_GroupActuator::KX_ACT_GROUP_PROPERTY;
00409 break;
00410 default:
00411 ;
00412 }
00413 tmpgroupact = new SCA_GroupActuator(gameobj, mode, startF,
00414 stopF, keyP, propP);
00415 gameact = tmpgroupact;
00416 }
00417 break;
00418 case ACT_SCENE:
00419 {
00420 bSceneActuator *sceneact = (bSceneActuator *) bact->data;
00421 KX_SceneActuator* tmpsceneact;
00422 int mode = KX_SceneActuator::KX_SCENE_NODEF;
00423 KX_Camera *cam = NULL;
00424
00425 switch (sceneact->type) {
00426 case ACT_SCENE_SET:
00427 mode = KX_SceneActuator::KX_SCENE_SET_SCENE;
00428
00429 break;
00430 case ACT_SCENE_CAMERA:
00431 if (sceneact->camera)
00432 {
00433 mode = KX_SceneActuator::KX_SCENE_SET_CAMERA;
00434 cam = (KX_Camera*) *map_blender_to_gameobject[CHashedPtr(sceneact->camera)];
00435 } else
00436 {
00437
00438 }
00439 break;
00440 case ACT_SCENE_RESTART:
00441 mode = KX_SceneActuator::KX_SCENE_RESTART;
00442 break;
00443 default:
00444 ;
00445 }
00446
00447 tmpsceneact = new KX_SceneActuator(gameobj, mode, scene, cam);
00448
00449 gameact = tmpsceneact;
00450 }
00451 break;
00452 case ACT_RANDOM:
00453 {
00454 bRandomActuator *randAct
00455 = (bRandomActuator *) bact->data;
00456
00457 unsigned long seedArg = randAct->seed;
00458 SCA_RandomActuator::KX_RANDOMACT_MODE modeArg
00459 = SCA_RandomActuator::KX_RANDOMACT_NODEF;
00460 SCA_RandomActuator *tmprandomact;
00461 float paraArg1 = 0.0;
00462 float paraArg2 = 0.0;
00463
00464 switch (randAct->distribution) {
00465 case ACT_RANDOM_BOOL_CONST:
00466 modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_CONST;
00467 paraArg1 = (float) randAct->int_arg_1;
00468 break;
00469 case ACT_RANDOM_BOOL_UNIFORM:
00470 modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_UNIFORM;
00471 break;
00472 case ACT_RANDOM_BOOL_BERNOUILLI:
00473 paraArg1 = randAct->float_arg_1;
00474 modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_BERNOUILLI;
00475 break;
00476 case ACT_RANDOM_INT_CONST:
00477 modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_CONST;
00478 paraArg1 = (float) randAct->int_arg_1;
00479 break;
00480 case ACT_RANDOM_INT_UNIFORM:
00481 paraArg1 = (float) randAct->int_arg_1;
00482 paraArg2 = (float) randAct->int_arg_2;
00483 modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_UNIFORM;
00484 break;
00485 case ACT_RANDOM_INT_POISSON:
00486 paraArg1 = randAct->float_arg_1;
00487 modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_POISSON;
00488 break;
00489 case ACT_RANDOM_FLOAT_CONST:
00490 paraArg1 = randAct->float_arg_1;
00491 modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_CONST;
00492 break;
00493 case ACT_RANDOM_FLOAT_UNIFORM:
00494 paraArg1 = randAct->float_arg_1;
00495 paraArg2 = randAct->float_arg_2;
00496 modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_UNIFORM;
00497 break;
00498 case ACT_RANDOM_FLOAT_NORMAL:
00499 paraArg1 = randAct->float_arg_1;
00500 paraArg2 = randAct->float_arg_2;
00501 modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_NORMAL;
00502 break;
00503 case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL:
00504 paraArg1 = randAct->float_arg_1;
00505 modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL;
00506 break;
00507 default:
00508 ;
00509 }
00510 tmprandomact = new SCA_RandomActuator(gameobj,
00511 seedArg,
00512 modeArg,
00513 paraArg1,
00514 paraArg2,
00515 randAct->propname);
00516 gameact = tmprandomact;
00517 }
00518 break;
00519 default:
00520 ;
00521 }
00522
00523 if (gameact)
00524 {
00525
00526 gameact->SetExecutePriority(executePriority++);
00527 uniquename += "#ACT#";
00528 uniqueint++;
00529 CIntValue* uniqueval = new CIntValue(uniqueint);
00530 uniquename += uniqueval->GetText();
00531 uniqueval->Release();
00532 gameact->SetName(CCString(bact->name));
00533
00534 gameobj->AddActuator(gameact);
00535
00536
00537 map_blender_to_gameactuator.insert(CHashedPtr(bact),gameact);
00538 }
00539
00540 bact = bact->next;
00541 }
00542 }