00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <assert.h>
00033 #include <string.h>
00034 #include <math.h>
00035 #include <stdio.h>
00036
00037 #include "world.h"
00038
00039 #include "Actor.h"
00040 #include "Ram.h"
00041 #include "Puppet.h"
00042 #include "Body.h"
00043 #include "Motion.h"
00044 #include "ErrorLog.h"
00045 #include "strblock.h"
00046 #ifdef _DEBUG
00047 #include <crtdbg.h>
00048 #endif
00049
00050
00051
00052
00053
00054
00055 #define ACTOR_MOTIONS_MAX 0x0FFFF // really arbitrary. just for sanity checking
00056 #define ACTOR_CUES_MAX 0x0FFFF // arbitrary.
00057
00058 typedef struct geActor
00059 {
00060 int32 RefCount;
00061 gePuppet *Puppet;
00062 gePose *Pose;
00063 geActor_BlendingType BlendingType;
00064 geActor_Def *ActorDefinition;
00065
00066 geMotion *CueMotion;
00067 geVec3d BoundingBoxMinCorner;
00068 geVec3d BoundingBoxMaxCorner;
00069 int BoundingBoxCenterBoneIndex;
00070 int StepBoneIndex;
00071 void * UserData;
00072
00073 geExtBox RenderHintExtBox;
00074 int RenderHintExtBoxCenterBoneIndex;
00075 geBoolean RenderHintExtBoxEnabled;
00076 } geActor;
00077
00078
00079 typedef struct geActor_Def
00080 {
00081 geBody *Body;
00082 geVFile * TextureFileContext;
00083
00084 int32 MotionCount;
00085 geMotion **MotionArray;
00086
00087 int32 RefCount;
00088
00089 geActor_Def *ValidityCheck;
00090 } geActor_Def;
00091
00092
00093 int geActor_Count = 0;
00094 int geActor_RefCount = 0;
00095 int geActor_DefCount = 0;
00096 int geActor_DefRefCount = 0;
00097
00098
00099 GENESISAPI int GENESISCC geActor_GetCount(void)
00100 {
00101 return geActor_Count;
00102 }
00103
00104 GENESISAPI geBoolean GENESISCC geActor_IsValid(const geActor *A)
00105 {
00106 if (A==NULL)
00107 return GE_FALSE;
00108 if (geActor_DefIsValid(A->ActorDefinition)==GE_FALSE)
00109 return GE_FALSE;
00110 if (A->Pose == NULL)
00111 return GE_FALSE;
00112 if (A->CueMotion == NULL)
00113 return GE_FALSE;
00114 if (geBody_IsValid(A->ActorDefinition->Body) == GE_FALSE )
00115 return GE_FALSE;
00116
00117 return GE_TRUE;
00118 }
00119
00120
00121
00122 GENESISAPI void GENESISCC geActor_GetNonWorldExtBox(const geActor *A, geExtBox *ExtBox)
00123 {
00124 assert( geActor_IsValid(A) != GE_FALSE);
00125 assert( ExtBox != NULL );
00126
00127 geVec3d_Copy(&(A->BoundingBoxMinCorner), &(ExtBox->Min));
00128 geVec3d_Copy(&(A->BoundingBoxMaxCorner), &(ExtBox->Max));
00129 }
00130 GENESISAPI void GENESISCC geActor_GetPosition(const geActor *A, geVec3d *Pos)
00131 {
00132 geXForm3d Transform;
00133 assert( geActor_IsValid(A) != GE_FALSE);
00134 assert( Pos != NULL );
00135 gePose_GetJointTransform( A->Pose,
00136 A->BoundingBoxCenterBoneIndex,
00137 &Transform);
00138 assert ( geXForm3d_IsOrthonormal(&Transform) != GE_FALSE );
00139 geVec3d_Copy(&(Transform.Translation), Pos);
00140 }
00141
00142
00143
00144 GENESISAPI geFloat GENESISCC geActor_GetAlpha(const geActor *A)
00145 {
00146 assert( A != NULL ) ;
00147 assert( A->Puppet != NULL ) ;
00148 return gePuppet_GetAlpha(A->Puppet);
00149 }
00150
00151
00152 GENESISAPI void GENESISCC geActor_SetAlpha(geActor *A, geFloat Alpha)
00153 {
00154 assert( A != NULL ) ;
00155 assert( A->Puppet != NULL ) ;
00156 gePuppet_SetAlpha( A->Puppet, Alpha ) ;
00157 }
00158
00159 GENESISAPI geBoolean GENESISCC geActor_DefIsValid(const geActor_Def *A)
00160 {
00161 if (A==NULL)
00162 return GE_FALSE;
00163 if (A->ValidityCheck != A)
00164 return GE_FALSE;
00165 return GE_TRUE;
00166 }
00167
00168 static geBoolean GENESISCC geActor_GetBoneIndex(const geActor *A, const char *BoneName, int *BoneIndex)
00169 {
00170 geXForm3d Dummy;
00171 int ParentBoneIndex;
00172 assert( geActor_IsValid(A) != GE_FALSE);
00173 assert( BoneIndex != NULL );
00174
00175 if ( BoneName != NULL )
00176 {
00177 if (geBody_GetBoneByName(A->ActorDefinition->Body,
00178 BoneName,
00179 BoneIndex,
00180 &Dummy,
00181 &ParentBoneIndex) ==GE_FALSE)
00182 {
00183 geErrorLog_AddString(-1,"Named bone not found:", BoneName);
00184
00185 return GE_FALSE;
00186 }
00187 }
00188 else
00189 {
00190 *BoneIndex = GE_POSE_ROOT_JOINT;
00191 }
00192 return GE_TRUE;
00193 }
00194
00195
00196 GENESISAPI geActor_Def *GENESISCC geActor_GetActorDef(const geActor *A)
00197 {
00198 assert( geActor_DefIsValid(A->ActorDefinition) != GE_FALSE );
00199 return A->ActorDefinition;
00200 }
00201
00202 GENESISAPI void GENESISCC geActor_DefCreateRef(geActor_Def *A)
00203 {
00204 assert( geActor_DefIsValid(A) != GE_FALSE );
00205 A->RefCount++;
00206 geActor_DefRefCount++;
00207 }
00208
00209 GENESISAPI geActor_Def *GENESISCC geActor_DefCreate(void)
00210 {
00211 geActor_Def *Ad;
00212
00213 Ad = GE_RAM_ALLOCATE_STRUCT( geActor_Def );
00214 if ( Ad == NULL )
00215 {
00216 geErrorLog_Add( ERR_ACTOR_ENOMEM , NULL);
00217 return NULL;
00218 }
00219
00220 Ad->Body = NULL;
00221 Ad->MotionCount = 0;
00222 Ad->MotionArray = NULL;
00223 Ad->ValidityCheck = Ad;
00224 Ad->RefCount = 0;
00225 geActor_DefCount++;
00226 return Ad;
00227 }
00228
00229 GENESISAPI void GENESISCC geActor_CreateRef(geActor *Actor)
00230 {
00231 assert( geActor_IsValid(Actor) );
00232 Actor->RefCount ++;
00233 geActor_RefCount++;
00234 }
00235
00236 GENESISAPI geActor *GENESISCC geActor_Create(geActor_Def *ActorDefinition)
00237 {
00238 geActor *A;
00239 assert( geActor_DefIsValid(ActorDefinition) != GE_FALSE );
00240
00241 if (ActorDefinition->Body == NULL)
00242 {
00243 geErrorLog_AddString(-1,"geActor_Def must have a body before Actors can be created", NULL);
00244 return NULL;
00245 }
00246 assert( geBody_IsValid(ActorDefinition->Body) != GE_FALSE );
00247
00248 A = GE_RAM_ALLOCATE_STRUCT( geActor );
00249 if ( A == NULL )
00250 {
00251 geErrorLog_Add( ERR_ACTOR_ENOMEM , NULL);
00252 goto ActorCreateFailure;
00253 }
00254 A->Puppet = NULL;
00255 A->Pose = NULL;
00256 A->CueMotion = NULL;
00257
00258 A->Pose = gePose_Create();
00259 if (A->Pose == NULL)
00260 {
00261 geErrorLog_Add(ERR_ACTOR_ENOMEM, NULL);
00262 goto ActorCreateFailure;
00263 }
00264
00265 A->RefCount = 0;
00266 A->BlendingType = GE_ACTOR_BLEND_HERMITE;
00267 A->ActorDefinition = ActorDefinition;
00268 A->CueMotion = geMotion_Create(GE_TRUE);
00269 A->BoundingBoxCenterBoneIndex = GE_POSE_ROOT_JOINT;
00270 A->RenderHintExtBoxCenterBoneIndex = GE_POSE_ROOT_JOINT;
00271 A->RenderHintExtBoxEnabled = GE_FALSE;
00272 A->StepBoneIndex = GE_POSE_ROOT_JOINT;
00273 geExtBox_Set(&(A->RenderHintExtBox), 0.0f,0.0f,0.0f,0.0f,0.0f,0.0f);
00274 if (A->CueMotion == NULL)
00275 {
00276 geErrorLog_Add( ERR_ACTOR_ENOMEM , NULL);
00277 goto ActorCreateFailure;
00278 }
00279
00280
00281 {
00282 int i;
00283 int BoneCount;
00284
00285 BoneCount = geBody_GetBoneCount(A->ActorDefinition->Body);
00286 for (i=0; i<BoneCount; i++)
00287 {
00288 const char *Name;
00289 geXForm3d Attachment;
00290 int ParentBone;
00291 int Index;
00292 geBody_GetBone( A->ActorDefinition->Body, i, &Name,&Attachment, &ParentBone );
00293 if (gePose_AddJoint( A->Pose,
00294 ParentBone,Name,&Attachment,&Index)==GE_FALSE)
00295 {
00296 geErrorLog_Add(ERR_ACTOR_ENOMEM, NULL);
00297 goto ActorCreateFailure;
00298 }
00299 }
00300 }
00301
00302
00303 geVec3d_Clear(&(A->BoundingBoxMinCorner));
00304 geVec3d_Clear(&(A->BoundingBoxMaxCorner));
00305 assert( geActor_IsValid(A) != GE_FALSE );
00306 geActor_DefCreateRef(ActorDefinition);
00307 geActor_Count++;
00308 return A;
00309
00310 ActorCreateFailure:
00311 if ( A!= NULL)
00312 {
00313 if (A->Pose != NULL)
00314 gePose_Destroy(&(A->Pose));
00315 if (A->CueMotion != NULL)
00316 geMotion_Destroy(&(A->CueMotion));
00317 geRam_Free( A );
00318 }
00319 return NULL;
00320 }
00321
00322 GENESISAPI geBoolean GENESISCC geActor_DefDestroy(geActor_Def **pActorDefinition)
00323 {
00324 int i;
00325 geActor_Def *Ad;
00326 assert( pActorDefinition != NULL );
00327 assert( *pActorDefinition != NULL );
00328 assert( geActor_DefIsValid( *pActorDefinition ) != GE_FALSE );
00329
00330 Ad = *pActorDefinition;
00331
00332 if (Ad->RefCount > 0)
00333 {
00334 Ad->RefCount--;
00335 geActor_DefRefCount--;
00336 return GE_FALSE;
00337 }
00338
00339 if (Ad->Body != NULL)
00340 {
00341 geBody_Destroy( &(Ad->Body) );
00342 Ad->Body = NULL;
00343 }
00344 if (Ad->MotionArray != NULL)
00345 {
00346 for (i=0; i<Ad->MotionCount; i++)
00347 {
00348 geMotion_Destroy( &(Ad->MotionArray[i]) );
00349 Ad->MotionArray[i] = NULL;
00350 }
00351 geRam_Free( Ad->MotionArray );
00352 Ad->MotionArray = NULL;
00353 }
00354
00355 Ad->MotionCount = 0;
00356
00357 geRam_Free(*pActorDefinition);
00358 *pActorDefinition = NULL;
00359 geActor_DefCount--;
00360 return GE_TRUE;
00361 }
00362
00363
00364 GENESISAPI geBoolean GENESISCC geActor_Destroy(geActor **pA)
00365 {
00366 geActor *A;
00367 assert( pA != NULL );
00368 assert( *pA != NULL );
00369 assert( geActor_IsValid(*pA) != GE_FALSE );
00370
00371 A = *pA;
00372 if (A->RefCount > 0)
00373 {
00374 A->RefCount --;
00375 geActor_RefCount--;
00376 return GE_FALSE;
00377 }
00378
00379 geActor_DefDestroy(&(A->ActorDefinition));
00380 if (A->Puppet != NULL)
00381 {
00382 gePuppet_Destroy( &(A->Puppet) );
00383 A->Puppet = NULL;
00384 }
00385 if ( A->Pose != NULL )
00386 {
00387 gePose_Destroy( &( A->Pose ) );
00388 A->Pose = NULL;
00389 }
00390 if ( A->CueMotion != NULL )
00391 {
00392 geMotion_Destroy(&(A->CueMotion));
00393 A->CueMotion = NULL;
00394 }
00395 geRam_Free(*pA);
00396 geActor_Count--;
00397 *pA = NULL;
00398 return GE_TRUE;
00399
00400 }
00401
00402
00403 GENESISAPI geBoolean GENESISCC geActor_DestroyDirect(geActor **pA)
00404 {
00405 geActor *CurrentActor=NULL;
00406 int i=0;
00407
00408
00409
00410
00411 CurrentActor = *pA;
00412
00413 if(!CurrentActor)
00414 return GE_FALSE;
00415
00416 gePuppet_Destroy( &(CurrentActor->Puppet) );
00417 gePose_Destroy( &( CurrentActor->Pose ) );
00418 geMotion_Destroy(&(CurrentActor->CueMotion));
00419
00420 assert( _CrtIsValidPointer( &CurrentActor->ActorDefinition, sizeof(CurrentActor->ActorDefinition), FALSE ) );
00421
00422 if(geActor_DefIsValid(CurrentActor->ActorDefinition)==GE_TRUE )
00423 {
00424
00425 if (CurrentActor->ActorDefinition->Body != NULL)
00426 {
00427 geBody_Destroy( &(CurrentActor->ActorDefinition->Body) );
00428 CurrentActor->ActorDefinition->Body = NULL;
00429 }
00430 if (CurrentActor->ActorDefinition->MotionArray != NULL)
00431 {
00432 for (i=0; i<CurrentActor->ActorDefinition->MotionCount; i++)
00433 {
00434 geMotion_Destroy( &(CurrentActor->ActorDefinition->MotionArray[i]) );
00435 CurrentActor->ActorDefinition->MotionArray[i] = NULL;
00436 }
00437 geRam_Free( CurrentActor->ActorDefinition->MotionArray );
00438 CurrentActor->ActorDefinition->MotionArray = NULL;
00439 }
00440
00441 CurrentActor->ActorDefinition->TextureFileContext=NULL;
00442 CurrentActor->ActorDefinition->ValidityCheck = NULL;
00443
00444
00445 geRam_Free(CurrentActor->ActorDefinition);
00446 CurrentActor->ActorDefinition = NULL;
00447
00448 }
00449
00450 CurrentActor->UserData = NULL;
00451
00452
00453 geRam_Free(CurrentActor);
00454 CurrentActor = NULL;
00455
00456 return GE_TRUE;
00457 }
00458
00459 GENESISAPI geBoolean GENESISCC geActor_SetBody( geActor_Def *ActorDefinition, geBody *BodyGeometry)
00460 {
00461 assert( geBody_IsValid(BodyGeometry) != GE_FALSE );
00462
00463 if (ActorDefinition->RefCount > 0)
00464 {
00465 geErrorLog_Add(-1, NULL);
00466 return GE_FALSE;
00467 }
00468
00469 if (ActorDefinition->Body != NULL)
00470 {
00471 geBody_Destroy( &(ActorDefinition->Body) );
00472 }
00473
00474 ActorDefinition->Body = BodyGeometry;
00475 return GE_TRUE;
00476 }
00477
00478
00479 #pragma message ("consider removing this and related parameters to setpose")
00480 GENESISAPI void GENESISCC geActor_SetBlendingType( geActor *A, geActor_BlendingType BlendingType )
00481 {
00482 assert( geActor_IsValid(A) != GE_FALSE );
00483
00484 assert( (BlendingType == GE_ACTOR_BLEND_LINEAR) ||
00485 (BlendingType == GE_ACTOR_BLEND_HERMITE) );
00486
00487 if (BlendingType == GE_ACTOR_BLEND_LINEAR)
00488 {
00489 A->BlendingType = GE_POSE_BLEND_LINEAR;
00490 }
00491 else
00492 {
00493 A->BlendingType = GE_POSE_BLEND_HERMITE;
00494 }
00495 }
00496
00497 GENESISAPI geVFile *geActor_DefGetFileContext(const geActor_Def *A)
00498 {
00499 assert( geActor_DefIsValid(A) != GE_FALSE );
00500 return A->TextureFileContext;
00501 }
00502
00503
00504
00505 GENESISAPI geBoolean GENESISCC geActor_AddMotion(geActor_Def *Ad, geMotion *NewMotion, int *Index)
00506 {
00507 geMotion **NewMArray;
00508 assert( geActor_DefIsValid(Ad) != GE_FALSE );
00509 assert( NewMotion != NULL );
00510 assert( Index != NULL );
00511
00512 if (Ad->MotionCount >= ACTOR_MOTIONS_MAX)
00513 {
00514 geErrorLog_Add(ERR_ACTOR_TOO_MANY_MOTIONS, NULL);
00515 return GE_FALSE;
00516 }
00517 NewMArray = GE_RAM_REALLOC_ARRAY( Ad->MotionArray, geMotion*, Ad->MotionCount +1 );
00518 if ( NewMArray == NULL )
00519 {
00520 geErrorLog_Add(ERR_ACTOR_ENOMEM, NULL);
00521 return GE_FALSE;
00522 }
00523
00524 Ad->MotionArray = NewMArray;
00525
00526 Ad->MotionArray[Ad->MotionCount]= NewMotion;
00527 Ad->MotionCount++;
00528 *Index = Ad->MotionCount;
00529 return GE_TRUE;
00530 };
00531
00532 GENESISAPI void GENESISCC geActor_ClearPose(geActor *A, const geXForm3d *Transform)
00533 {
00534 assert( geActor_IsValid(A) != GE_FALSE );
00535 assert ( (Transform==NULL) || (geXForm3d_IsOrthonormal(Transform) != GE_FALSE) );
00536 gePose_Clear( A->Pose ,Transform);
00537 }
00538
00539 GENESISAPI void GENESISCC geActor_SetPose(geActor *A, const geMotion *M,
00540 geFloat Time, const geXForm3d *Transform)
00541 {
00542 assert( geActor_IsValid(A) != GE_FALSE );
00543 assert( M != NULL );
00544 assert ( (Transform==NULL) || (geXForm3d_IsOrthonormal(Transform) != GE_FALSE) );
00545
00546 gePose_SetMotion( A->Pose,M,Time,Transform);
00547 }
00548
00549 GENESISAPI void GENESISCC geActor_BlendPose(geActor *A, const geMotion *M,
00550 geFloat Time,
00551 const geXForm3d *Transform,
00552 geFloat BlendAmount)
00553 {
00554 assert( geActor_IsValid(A) != GE_FALSE );
00555 assert( M != NULL );
00556 assert ( (Transform==NULL) || (geXForm3d_IsOrthonormal(Transform) != GE_FALSE) );
00557
00558 gePose_BlendMotion( A->Pose,M,Time,Transform,
00559 BlendAmount,A->BlendingType);
00560 }
00561
00562
00563 GENESISAPI int GENESISCC geActor_GetMotionCount(const geActor_Def *Ad)
00564 {
00565 assert( geActor_DefIsValid(Ad) != GE_FALSE );
00566 return Ad->MotionCount;
00567 }
00568
00569
00570 GENESISAPI geMotion *GENESISCC geActor_GetMotionByIndex(const geActor_Def *Ad, int Index )
00571 {
00572 assert( geActor_DefIsValid(Ad) != GE_FALSE );
00573 assert( Index >= 0 );
00574 assert( Index < Ad->MotionCount );
00575 assert( Ad->MotionArray != NULL );
00576
00577 return Ad->MotionArray[Index];
00578 }
00579
00580 GENESISAPI geMotion *GENESISCC geActor_GetMotionByName(const geActor_Def *Ad, const char *Name )
00581 {
00582 int i;
00583 const char *TestName;
00584 assert( geActor_DefIsValid(Ad) != GE_FALSE );
00585 assert( Name != NULL );
00586 for (i=0; i<Ad->MotionCount; i++)
00587 {
00588 TestName = geMotion_GetName(Ad->MotionArray[i]);
00589 if (TestName != NULL)
00590 {
00591 if (strcmp(TestName,Name)==0)
00592 return Ad->MotionArray[i];
00593 }
00594
00595 }
00596 return NULL;
00597 }
00598
00599 GENESISAPI const char *GENESISCC geActor_GetMotionName(const geActor_Def *Ad, int Index )
00600 {
00601 assert( geActor_DefIsValid(Ad) != GE_FALSE );
00602 assert( Index >= 0 );
00603 assert( Index < Ad->MotionCount );
00604 assert( Ad->MotionArray != NULL );
00605 return geMotion_GetName(Ad->MotionArray[Index]);
00606 }
00607
00608 GENESISAPI geBody *GENESISCC geActor_GetBody(const geActor_Def *Ad)
00609 {
00610 assert( geActor_DefIsValid(Ad) != GE_FALSE );
00611 return Ad->Body;
00612 }
00613
00614 #pragma message ("Keep this function: geActor_DefHasBoneNamed()?")
00615
00616 GENESISAPI geBoolean GENESISCC geActor_DefHasBoneNamed(const geActor_Def *Ad, const char *Name )
00617 {
00618 int DummyIndex,DummyParent;
00619 geXForm3d DummyAttachment;
00620
00621 assert( geActor_DefIsValid(Ad) != GE_FALSE );
00622 assert( Name != NULL );
00623 if (geBody_GetBoneByName(geActor_GetBody(Ad),Name,
00624 &DummyIndex, &DummyAttachment, &DummyParent ) == GE_FALSE )
00625 {
00626 return GE_FALSE;
00627 }
00628 return GE_TRUE;
00629 }
00630
00631
00632 #define GE_ACTOR_BODY_NAME "Body"
00633 #define GE_ACTOR_HEADER_NAME "Header"
00634 #define GE_MOTION_DIRECTORY_NAME "Motions"
00635
00636 #define ACTOR_FILE_TYPE 0x52544341 // 'ACTR'
00637 #define ACTOR_FILE_VERSION 0x00F1 // Restrict version to 16 bits
00638
00639
00640
00641 static geActor_Def * GENESISCC geActor_DefCreateHeader(geVFile *pFile, geBoolean *HasBody)
00642 {
00643 uint32 u;
00644 uint32 version;
00645 geActor_Def *Ad;
00646
00647 assert( pFile != NULL );
00648 assert( HasBody != NULL );
00649
00650 if(geVFile_Read(pFile, &u, sizeof(u)) == GE_FALSE)
00651 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); return NULL;}
00652 if (u != ACTOR_FILE_TYPE)
00653 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); return NULL;}
00654
00655 if(geVFile_Read(pFile, &version, sizeof(version)) == GE_FALSE)
00656 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); return NULL;}
00657 if ( (version != ACTOR_FILE_VERSION) )
00658 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); return NULL;}
00659
00660 Ad = geActor_DefCreate();
00661 if (Ad==NULL)
00662 { geErrorLog_Add( ERR_ACTOR_ENOMEM , NULL); return NULL; }
00663
00664 Ad->TextureFileContext = geVFile_GetContext(pFile);
00665 assert(Ad->TextureFileContext);
00666
00667 if(geVFile_Read(pFile, HasBody, sizeof(*HasBody)) == GE_FALSE)
00668 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); geActor_DefDestroy(&Ad); return NULL;}
00669
00670 if(geVFile_Read(pFile, &(Ad->MotionCount), sizeof(Ad->MotionCount)) == GE_FALSE)
00671 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); geActor_DefDestroy(&Ad); return NULL;}
00672
00673 return Ad;
00674 }
00675
00676
00677 static geBoolean GENESISCC geActor_DefWriteHeader(const geActor_Def *Ad, geVFile *pFile)
00678 {
00679 uint32 u;
00680 geBoolean Flag;
00681
00682 assert( geActor_DefIsValid(Ad) != GE_FALSE );
00683 assert( pFile != NULL );
00684
00685
00686 u = ACTOR_FILE_TYPE;
00687 if(geVFile_Write(pFile, &u, sizeof(u)) == GE_FALSE)
00688 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); return GE_FALSE; }
00689
00690
00691 u = ACTOR_FILE_VERSION;
00692 if(geVFile_Write(pFile, &u, sizeof(u)) == GE_FALSE)
00693 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); return GE_FALSE;}
00694
00695 if (Ad->Body != NULL)
00696 Flag = GE_TRUE;
00697 else
00698 Flag = GE_FALSE;
00699
00700 if(geVFile_Write(pFile, &Flag, sizeof(Flag)) == GE_FALSE)
00701 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); return GE_FALSE;}
00702
00703 if(geVFile_Write(pFile, &(Ad->MotionCount), sizeof(Ad->MotionCount)) == GE_FALSE)
00704 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); return GE_FALSE;}
00705
00706 return GE_TRUE;
00707 }
00708
00709
00710
00711 GENESISAPI geActor_Def *GENESISCC geActor_DefCreateFromFile(geVFile *pFile)
00712 {
00713 int i;
00714 geActor_Def *Ad = NULL;
00715 geVFile *VFile = NULL;
00716 geVFile *SubFile = NULL;
00717 geVFile *MotionDirectory = NULL;
00718 geBoolean HasBody = GE_FALSE;
00719 geBody * Body = NULL;
00720
00721 assert( pFile != NULL );
00722
00723 VFile = geVFile_OpenNewSystem(pFile,GE_VFILE_TYPE_VIRTUAL, NULL,
00724 NULL, GE_VFILE_OPEN_DIRECTORY | GE_VFILE_OPEN_READONLY);
00725 if (VFile == NULL)
00726 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); goto CreateError;}
00727
00728 SubFile = geVFile_Open(VFile,GE_ACTOR_HEADER_NAME,GE_VFILE_OPEN_READONLY);
00729 if (SubFile == NULL)
00730 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); goto CreateError;}
00731
00732 Ad = geActor_DefCreateHeader(SubFile,&HasBody);
00733 if (Ad == NULL)
00734 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); goto CreateError;}
00735 geVFile_Close(SubFile);
00736
00737
00738 if (HasBody != GE_FALSE)
00739 {
00740 SubFile = geVFile_Open(VFile,GE_ACTOR_BODY_NAME,GE_VFILE_OPEN_READONLY);
00741 if (SubFile == NULL)
00742 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); goto CreateError;}
00743
00744 Body = geBody_CreateFromFile(SubFile);
00745 if (Body == NULL)
00746 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); goto CreateError; }
00747 if (geActor_SetBody(Ad,Body)==GE_FALSE)
00748 { geErrorLog_Add( ERR_ACTOR_ENOMEM , NULL); goto CreateError; }
00749 geVFile_Close(SubFile);
00750 }
00751
00752 MotionDirectory = geVFile_Open(VFile,GE_MOTION_DIRECTORY_NAME,
00753 GE_VFILE_OPEN_DIRECTORY | GE_VFILE_OPEN_READONLY);
00754 if (MotionDirectory == NULL)
00755 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); return NULL;}
00756
00757 if (Ad->MotionCount>0)
00758 {
00759 Ad->MotionArray = GE_RAM_ALLOCATE_ARRAY( geMotion*, Ad->MotionCount);
00760 for (i=0; i<Ad->MotionCount; i++)
00761 Ad->MotionArray[i] = NULL;
00762
00763 for (i=0; i<Ad->MotionCount; i++)
00764 {
00765 char FName[1000];
00766 sprintf(FName,"%d",i);
00767
00768 SubFile = geVFile_Open(MotionDirectory,FName,GE_VFILE_OPEN_READONLY);
00769 if (SubFile == NULL)
00770 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); goto CreateError;}
00771 Ad->MotionArray[i] = geMotion_CreateFromFile(SubFile);
00772 if (Ad->MotionArray[i] == NULL)
00773 { geErrorLog_Add( ERR_ACTOR_FILE_READ , NULL); goto CreateError;}
00774 geVFile_Close(SubFile);
00775 }
00776 }
00777 else
00778 {
00779 Ad->MotionArray = NULL;
00780 }
00781 geVFile_Close(MotionDirectory);
00782 geVFile_Close(VFile);
00783 return Ad;
00784
00785 CreateError:
00786 if (SubFile != NULL)
00787 geVFile_Close(SubFile);
00788 if (MotionDirectory != NULL)
00789 geVFile_Close(MotionDirectory);
00790 if (VFile != NULL)
00791 geVFile_Close(VFile);
00792 if (Ad != NULL)
00793 geActor_DefDestroy(&Ad);
00794 return NULL;
00795 }
00796
00797
00798 GENESISAPI geBoolean GENESISCC geActor_DefWriteToFile(const geActor_Def *Ad, geVFile *pFile)
00799 {
00800 int i;
00801 geVFile *VFile;
00802 geVFile *SubFile;
00803 geVFile *MotionDirectory;
00804
00805 assert( geActor_DefIsValid(Ad) != GE_FALSE );
00806 assert( pFile != NULL );
00807
00808 VFile = geVFile_OpenNewSystem(pFile,GE_VFILE_TYPE_VIRTUAL, NULL,
00809 NULL, GE_VFILE_OPEN_DIRECTORY | GE_VFILE_OPEN_CREATE);
00810 if (VFile == NULL)
00811 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); goto WriteError;}
00812
00813 SubFile = geVFile_Open(VFile,GE_ACTOR_HEADER_NAME,GE_VFILE_OPEN_CREATE);
00814 if (SubFile == NULL)
00815 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); goto WriteError;}
00816
00817 if (geActor_DefWriteHeader(Ad,SubFile)==GE_FALSE)
00818 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); goto WriteError;}
00819 if (geVFile_Close(SubFile)==GE_FALSE)
00820 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); goto WriteError;}
00821
00822 if (Ad->Body != NULL)
00823 {
00824 SubFile = geVFile_Open(VFile,GE_ACTOR_BODY_NAME,GE_VFILE_OPEN_CREATE);
00825 if (SubFile == NULL)
00826 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); goto WriteError;}
00827 if (geBody_WriteToFile(Ad->Body,SubFile)==GE_FALSE)
00828 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); goto WriteError;}
00829 if (geVFile_Close(SubFile)==GE_FALSE)
00830 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); goto WriteError;}
00831 }
00832
00833 MotionDirectory = geVFile_Open(VFile,GE_MOTION_DIRECTORY_NAME,
00834 GE_VFILE_OPEN_DIRECTORY | GE_VFILE_OPEN_CREATE);
00835 if (MotionDirectory == NULL)
00836 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); goto WriteError;}
00837
00838 for (i=0; i<Ad->MotionCount; i++)
00839 {
00840 char FName[1000];
00841 sprintf(FName,"%d",i);
00842
00843 SubFile = geVFile_Open(MotionDirectory,FName,GE_VFILE_OPEN_CREATE);
00844 if (SubFile == NULL)
00845 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); goto WriteError;}
00846 if (geMotion_WriteToBinaryFile(Ad->MotionArray[i],SubFile)==GE_FALSE)
00847 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); goto WriteError;}
00848 if (geVFile_Close(SubFile)==GE_FALSE)
00849 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); goto WriteError;}
00850 }
00851
00852 if (geVFile_Close(MotionDirectory)==GE_FALSE)
00853 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); goto WriteError;}
00854 if (geVFile_Close(VFile)==GE_FALSE)
00855 { geErrorLog_Add( ERR_ACTOR_FILE_WRITE , NULL); goto WriteError;}
00856
00857 return GE_TRUE;
00858 WriteError:
00859 return GE_FALSE;
00860 }
00861
00862 GENESISAPI geBoolean GENESISCC geActor_GetBoneTransform(const geActor *A, const char *BoneName, geXForm3d *Transform)
00863 {
00864 int BoneIndex;
00865
00866 assert( geActor_IsValid(A)!=GE_FALSE );
00867 assert( Transform!= NULL );
00868
00869 if (geActor_GetBoneIndex(A,BoneName,&BoneIndex)==GE_FALSE)
00870 {
00871 geErrorLog_AddString(-1,"Named bone not found", BoneName);
00872 return GE_FALSE;
00873 }
00874
00875 gePose_GetJointTransform( A->Pose, BoneIndex, Transform);
00876 assert ( geXForm3d_IsOrthonormal(Transform) != GE_FALSE );
00877
00878 return GE_TRUE;
00879 }
00880
00881
00882 GENESISAPI geBoolean GENESISCC geActor_GetBoneTransformByIndex(const geActor *A, int BoneIndex, geXForm3d *Transform)
00883 {
00884 assert( geActor_IsValid(A)!=GE_FALSE );
00885 assert( Transform!= NULL );
00886
00887 gePose_GetJointTransform( A->Pose, BoneIndex, Transform);
00888 assert ( geXForm3d_IsOrthonormal(Transform) != GE_FALSE );
00889
00890 return GE_TRUE;
00891 }
00892
00893 static void GENESISCC geActor_AccumulateMinMax(
00894 geVec3d *P,geVec3d *Mins,geVec3d *Maxs)
00895 {
00896 assert( geVec3d_IsValid( P ) != GE_FALSE );
00897 assert( geVec3d_IsValid(Mins) != GE_FALSE );
00898 assert( geVec3d_IsValid(Maxs) != GE_FALSE );
00899
00900 if (P->X < Mins->X) Mins->X = P->X;
00901 if (P->Y < Mins->Y) Mins->Y = P->Y;
00902 if (P->Z < Mins->Z) Mins->Z = P->Z;
00903
00904 if (P->X > Maxs->X) Maxs->X = P->X;
00905 if (P->Y > Maxs->Y) Maxs->Y = P->Y;
00906 if (P->Z > Maxs->Z) Maxs->Z = P->Z;
00907 }
00908
00909
00910 static geBoolean GENESISCC geActor_GetBoneBoundingBoxByIndex(
00911 const geActor *A,
00912 int BoneIndex,
00913 geVec3d *Corner,
00914 geVec3d *DX,
00915 geVec3d *DY,
00916 geVec3d *DZ)
00917 {
00918 geVec3d Min,Max;
00919 geVec3d Orientation;
00920 geXForm3d Transform;
00921
00922 assert( geActor_IsValid(A) != GE_FALSE );
00923 assert( geActor_DefIsValid(A->ActorDefinition) != GE_FALSE );
00924 assert( A->ActorDefinition->Body != NULL );
00925
00926 assert( Corner );
00927 assert( DX );
00928 assert( DY );
00929 assert( DZ );
00930 assert( (BoneIndex < gePose_GetJointCount(A->Pose)) || (BoneIndex ==GE_POSE_ROOT_JOINT));
00931 assert( (BoneIndex >=0) || (BoneIndex ==GE_POSE_ROOT_JOINT));
00932
00933 if (geBody_GetBoundingBox( A->ActorDefinition->Body, BoneIndex, &Min, &Max )==GE_FALSE)
00934 {
00935 return GE_FALSE;
00936 }
00937
00938
00939 {
00940 geVec3d Scale;
00941 gePose_GetScale(A->Pose, &Scale);
00942 assert( geVec3d_IsValid(&Scale) != GE_FALSE );
00943
00944 Min.X *= Scale.X;
00945 Min.Y *= Scale.Y;
00946 Min.Z *= Scale.Z;
00947
00948 Max.X *= Scale.X;
00949 Max.Y *= Scale.Y;
00950 Max.Z *= Scale.Z;
00951 }
00952
00953
00954 gePose_GetJointTransform(A->Pose,BoneIndex,&(Transform));
00955
00956 geVec3d_Subtract(&Max,&Min,&Orientation);
00957
00958 DX->X = Orientation.X; DX->Y = DX->Z = 0.0f;
00959 DY->Y = Orientation.Y; DY->X = DY->Z = 0.0f;
00960 DZ->Z = Orientation.Z; DZ->X = DZ->Y = 0.0f;
00961
00962
00963 geXForm3d_Transform(&(Transform),&Min,&Min);
00964 geXForm3d_Rotate(&(Transform),DX,DX);
00965 geXForm3d_Rotate(&(Transform),DY,DY);
00966 geXForm3d_Rotate(&(Transform),DZ,DZ);
00967
00968 *Corner = Min;
00969 return GE_TRUE;
00970 }
00971
00972
00973
00974 GENESISAPI geBoolean GENESISCC geActor_GetBoneExtBoxByIndex(
00975 const geActor *A,
00976 int BoneIndex,
00977 geExtBox *ExtBox)
00978 {
00979 geVec3d Min;
00980 geVec3d DX,DY,DZ,Corner;
00981
00982 assert( ExtBox );
00983
00984 if (geActor_GetBoneBoundingBoxByIndex(A,BoneIndex,&Min,&DX,&DY,&DZ)==GE_FALSE)
00985 {
00986 return GE_FALSE;
00987 }
00988
00989 ExtBox->Min = Min;
00990 ExtBox->Max = Min;
00991 Corner = Min;
00992
00993 geVec3d_Add(&Corner,&DX,&Corner);
00994 geActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
00995 geVec3d_Add(&Corner,&DZ,&Corner);
00996 geActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
00997 geVec3d_Subtract(&Corner,&DX,&Corner);
00998 geActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
00999 geVec3d_Add(&Corner,&DY,&Corner);
01000 geActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
01001 geVec3d_Add(&Corner,&DX,&Corner);
01002 geActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
01003 geVec3d_Subtract(&Corner,&DZ,&Corner);
01004 geActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
01005 geVec3d_Subtract(&Corner,&DX,&Corner);
01006 geActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
01007
01008 return GE_TRUE;
01009 }
01010
01011 GENESISAPI geBoolean GENESISCC geActor_GetBoneExtBox(const geActor *A,
01012 const char *BoneName,
01013 geExtBox *ExtBox)
01014 {
01015 int BoneIndex;
01016 assert( geActor_IsValid(A) != GE_FALSE);
01017 assert( ExtBox != NULL );
01018
01019 if (geActor_GetBoneIndex(A,BoneName,&BoneIndex)==GE_FALSE)
01020 {
01021 geErrorLog_AddString(-1,"Named bone for bounding box not found", BoneName);
01022 return GE_FALSE;
01023 }
01024 return geActor_GetBoneExtBoxByIndex(A,BoneIndex,ExtBox);
01025 }
01026
01027
01028 GENESISAPI geBoolean GENESISCC geActor_GetBoneBoundingBox(const geActor *A,
01029 const char *BoneName,
01030 geVec3d *Corner,
01031 geVec3d *DX,
01032 geVec3d *DY,
01033 geVec3d *DZ)
01034 {
01035 int BoneIndex;
01036 assert( geActor_IsValid(A) != GE_FALSE);
01037 assert( Corner != NULL );
01038 assert( DX != NULL );
01039 assert( DY != NULL );
01040 assert( DZ != NULL );
01041
01042 if (geActor_GetBoneIndex(A,BoneName,&BoneIndex)==GE_FALSE)
01043 {
01044 geErrorLog_AddString(-1,"Named bone for bounding box not found", BoneName);
01045 return GE_FALSE;
01046 }
01047 if (geActor_GetBoneBoundingBoxByIndex(A,BoneIndex,Corner,DX,DY,DZ)==GE_FALSE)
01048 {
01049 geErrorLog_AddString(-1,"Failed to get bounding box named:", BoneName);
01050
01051 return GE_FALSE;
01052 }
01053 return GE_TRUE;
01054 }
01055
01056
01057
01058 GENESISAPI geBoolean GENESISCC geActor_GetExtBox(const geActor *A, geExtBox *ExtBox)
01059 {
01060 geXForm3d Transform;
01061
01062 assert( geActor_IsValid(A) != GE_FALSE);
01063 assert( ExtBox != NULL );
01064
01065 gePose_GetJointTransform( A->Pose,
01066 A->BoundingBoxCenterBoneIndex,
01067 &Transform);
01068 assert ( geXForm3d_IsOrthonormal(&Transform) != GE_FALSE );
01069 geVec3d_Add( &(Transform.Translation), &(A->BoundingBoxMinCorner), &(ExtBox->Min));
01070 geVec3d_Add( &(Transform.Translation), &(A->BoundingBoxMaxCorner), &(ExtBox->Max));
01071 return GE_TRUE;
01072 }
01073
01074
01075 GENESISAPI geBoolean GENESISCC geActor_SetExtBox(geActor *A,
01076 const geExtBox *ExtBox,
01077 const char *CenterOnThisNamedBone)
01078 {
01079
01080 assert( geActor_IsValid(A) != GE_FALSE);
01081 assert( geExtBox_IsValid(ExtBox) != GE_FALSE);
01082
01083 A->BoundingBoxMinCorner = ExtBox->Min;
01084 A->BoundingBoxMaxCorner = ExtBox->Max;
01085
01086 if (geActor_GetBoneIndex(A,CenterOnThisNamedBone,&(A->BoundingBoxCenterBoneIndex))==GE_FALSE)
01087 {
01088 geErrorLog_AddString(-1,"Named bone for bounding box not found", CenterOnThisNamedBone);
01089 return GE_FALSE;
01090 }
01091
01092 return GE_TRUE;
01093 }
01094
01095
01096
01097 GENESISAPI geBoolean GENESISCC geActor_GetRenderHintExtBox(const geActor *A, geExtBox *Box, geBoolean *Enabled)
01098 {
01099 geXForm3d Transform;
01100
01101 assert( geActor_IsValid(A) != GE_FALSE);
01102 assert( Box != NULL );
01103 assert( Enabled != NULL );
01104
01105 gePose_GetJointTransform( A->Pose,
01106 A->RenderHintExtBoxCenterBoneIndex,
01107 &Transform);
01108 assert ( geXForm3d_IsOrthonormal(&Transform) != GE_FALSE );
01109
01110 *Box = A->RenderHintExtBox;
01111 geExtBox_Translate ( Box, Transform.Translation.X,
01112 Transform.Translation.Y,
01113 Transform.Translation.Z );
01114
01115 *Enabled = A->RenderHintExtBoxEnabled;
01116 return GE_TRUE;
01117 }
01118
01119
01120 GENESISAPI geBoolean GENESISCC geActor_SetRenderHintExtBox(geActor *A, const geExtBox *Box,
01121 const char *CenterOnThisNamedBone)
01122 {
01123 assert( geActor_IsValid(A) != GE_FALSE);
01124 assert( Box != NULL );
01125 assert( Box->Max.X >= Box->Min.X );
01126 assert( Box->Max.Y >= Box->Min.Y );
01127 assert( Box->Max.Z >= Box->Min.Z );
01128
01129 if (geActor_GetBoneIndex(A,CenterOnThisNamedBone,&(A->RenderHintExtBoxCenterBoneIndex))==GE_FALSE)
01130 {
01131 geErrorLog_AddString(-1,"Named bone for render hint box not found", CenterOnThisNamedBone);
01132 return GE_FALSE;
01133 }
01134
01135 A->RenderHintExtBox = *Box;
01136 if ( (Box->Min.X == 0.0f) && (Box->Max.X == 0.0f)
01137 && (Box->Min.Y == 0.0f) && (Box->Max.Y == 0.0f)
01138 && (Box->Min.Z == 0.0f) && (Box->Max.Z == 0.0f) )
01139 {
01140 A->RenderHintExtBoxEnabled = GE_FALSE;
01141 }
01142 else
01143 {
01144 A->RenderHintExtBoxEnabled = GE_TRUE;
01145 }
01146
01147 return GE_TRUE;
01148 }
01149
01150
01151 GENESISAPI void *GENESISCC geActor_GetUserData(const geActor *A)
01152 {
01153 assert( geActor_IsValid(A) != GE_FALSE);
01154 return A->UserData;
01155 }
01156
01157 GENESISAPI void GENESISCC geActor_SetUserData(geActor *A, void *UserData)
01158 {
01159 assert( geActor_IsValid(A) != GE_FALSE);
01160 A->UserData = UserData;
01161 }
01162
01163 #define MAX(aa,bb) ( (aa)>(bb)?(aa):(bb) )
01164 #define MIN(aa,bb) ( (aa)<(bb)?(aa):(bb) )
01165
01166 static void GENESISCC geActor_StretchBoundingBox( geVec3d *Min, geVec3d *Max,
01167 const geVec3d *Corner,
01168 const geVec3d *DX, const geVec3d *DY, const geVec3d *DZ)
01169 {
01170 geVec3d P;
01171
01172 P = *Corner;
01173 Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
01174 Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
01175
01176 geVec3d_Add (Corner ,DX,&P);
01177 Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
01178 Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
01179
01180 geVec3d_Add (&P, DZ,&P);
01181 Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
01182 Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
01183
01184 geVec3d_Subtract(&P,DX,&P);
01185 Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
01186 Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
01187
01188 geVec3d_Add (&P,DY,&P);
01189 Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
01190 Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
01191
01192 geVec3d_Add (&P,DX,&P);
01193 Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
01194 Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
01195
01196 geVec3d_Subtract(&P,DZ,&P);
01197 Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
01198 Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
01199
01200 geVec3d_Subtract(&P,DX,&P);
01201 Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
01202 Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
01203 }
01204
01205
01206
01207 GENESISAPI int geActor_GetBoneCount(const geActor *A)
01208 {
01209 return geBody_GetBoneCount( A->ActorDefinition->Body );
01210 }
01211
01212 GENESISAPI geBoolean GENESISCC geActor_GetDynamicExtBox( const geActor *A, geExtBox *ExtBox)
01213 {
01214 #define GE_ACTOR_REALLY_BIG_NUMBER (9e9f)
01215
01216 geVec3d Corner;
01217 geVec3d DX;
01218 geVec3d DY;
01219 geVec3d DZ;
01220 int Count,i,BCount;
01221
01222 assert( geActor_IsValid(A) != GE_FALSE);
01223 assert( A->ActorDefinition->Body != NULL );
01224
01225 geVec3d_Set(&(ExtBox->Min),
01226 GE_ACTOR_REALLY_BIG_NUMBER,GE_ACTOR_REALLY_BIG_NUMBER,GE_ACTOR_REALLY_BIG_NUMBER);
01227 geVec3d_Set(&(ExtBox->Max),
01228 -GE_ACTOR_REALLY_BIG_NUMBER,-GE_ACTOR_REALLY_BIG_NUMBER,-GE_ACTOR_REALLY_BIG_NUMBER);
01229
01230 BCount = 0;
01231 Count = geBody_GetBoneCount( A->ActorDefinition->Body );
01232 for (i=0; i< Count; i++)
01233 {
01234 if (geActor_GetBoneBoundingBoxByIndex(A,i,&Corner,&DX,&DY,&DZ)!=GE_FALSE)
01235 {
01236 geActor_StretchBoundingBox( &(ExtBox->Min),
01237 &(ExtBox->Max),&Corner,&DX,&DY,&DZ);
01238 BCount ++;
01239 }
01240 }
01241 if (BCount>0)
01242 {
01243 return GE_TRUE;
01244 }
01245 return GE_FALSE;
01246 }
01247
01248
01249
01250 GENESISAPI geBoolean GENESISCC geActor_Attach( geActor *Slave, const char *SlaveBoneName,
01251 const geActor *Master, const char *MasterBoneName,
01252 const geXForm3d *Attachment)
01253 {
01254 int SlaveBoneIndex,MasterBoneIndex;
01255
01256 assert( geActor_IsValid(Slave) != GE_FALSE);
01257 assert( geActor_IsValid(Master) != GE_FALSE);
01258 assert( geXForm3d_IsOrthonormal(Attachment) != GE_FALSE );
01259
01260 assert( MasterBoneName != NULL );
01261
01262 if (geActor_GetBoneIndex(Slave,SlaveBoneName,&(SlaveBoneIndex))==GE_FALSE)
01263 {
01264 geErrorLog_AddString(-1,"Named bone for slave not found", SlaveBoneName);
01265 return GE_FALSE;
01266 }
01267
01268 if (geActor_GetBoneIndex(Master,MasterBoneName,&(MasterBoneIndex))==GE_FALSE)
01269 {
01270 geErrorLog_AddString(-1,"Named bone for master not found", MasterBoneName);
01271 return GE_FALSE;
01272 }
01273
01274 return gePose_Attach( Slave->Pose, SlaveBoneIndex,
01275 Master->Pose, MasterBoneIndex,
01276 Attachment);
01277 }
01278
01279
01280 GENESISAPI void GENESISCC geActor_Detach(geActor *A)
01281 {
01282 assert( geActor_IsValid(A) != GE_FALSE);
01283
01284 gePose_Detach( A->Pose );
01285 }
01286
01287
01288 GENESISAPI geBoolean GENESISCC geActor_GetBoneAttachment(const geActor *A,
01289 const char *BoneName,
01290 geXForm3d *Attachment)
01291 {
01292
01293 int BoneIndex;
01294 assert( geActor_IsValid(A) != GE_FALSE);
01295 assert( Attachment != NULL );
01296
01297 if (geActor_GetBoneIndex(A,BoneName,&(BoneIndex))==GE_FALSE)
01298 {
01299 geErrorLog_AddString(-1,"Named bone not found", BoneName);
01300 return GE_FALSE;
01301 }
01302
01303 gePose_GetJointAttachment(A->Pose,BoneIndex, Attachment);
01304 assert ( geXForm3d_IsOrthonormal(Attachment) != GE_FALSE );
01305
01306 return GE_TRUE;
01307 }
01308
01309 GENESISAPI geBoolean GENESISCC geActor_SetBoneAttachment(geActor *A,
01310 const char *BoneName,
01311 geXForm3d *Attachment)
01312 {
01313
01314 int BoneIndex;
01315
01316 assert( geActor_IsValid(A) != GE_FALSE);
01317 assert( geXForm3d_IsOrthonormal(Attachment) != GE_FALSE );
01318
01319 if (geActor_GetBoneIndex(A,BoneName,&(BoneIndex))==GE_FALSE)
01320 {
01321 geErrorLog_AddString(-1,"Named bone not found", BoneName);
01322 return GE_FALSE;
01323 }
01324
01325 gePose_SetJointAttachment(A->Pose,BoneIndex, Attachment);
01326 return GE_TRUE;
01327 }
01328
01329
01330
01331
01332
01333 #define ACTOR_CUE_MINIMUM_BLEND (0.0001f)
01334 #define ACTOR_CUE_MAXIMUM_BLEND (0.999f)
01335
01336
01337 static geBoolean GENESISCC geActor_IsAnimationCueDead(geActor *A, int Index)
01338 {
01339 geBoolean Kill= GE_FALSE;
01340 geFloat BlendAmount;
01341 geMotion *M;
01342 assert( geActor_IsValid(A) != GE_FALSE);
01343 assert( (Index>=0) && (Index<geMotion_GetSubMotionCount(A->CueMotion)));
01344
01345 M = A->CueMotion;
01346
01347 BlendAmount = geMotion_GetBlendAmount(M,Index,0.0f);
01348 if (BlendAmount <= ACTOR_CUE_MINIMUM_BLEND)
01349 {
01350 int KeyCount;
01351 gePath *P;
01352 geFloat KeyTime;
01353
01354 P = geMotion_GetBlendPath(M,Index);
01355 assert( P != NULL );
01356 KeyCount = gePath_GetKeyframeCount(P,GE_PATH_TRANSLATION_CHANNEL);
01357 if (KeyCount>0)
01358 {
01359 geXForm3d Dummy;
01360 geFloat TimeOffset = -geMotion_GetTimeOffset( M, Index);
01361 gePath_GetKeyframe( P, KeyCount-1, GE_PATH_TRANSLATION_CHANNEL, &KeyTime, &Dummy );
01362
01363 if ( KeyTime <= TimeOffset )
01364 {
01365 Kill = GE_TRUE;
01366 }
01367 }
01368 else
01369 {
01370 Kill = GE_TRUE;
01371 }
01372 }
01373 return Kill;
01374 }
01375
01376
01377 static void GENESISCC geActor_KillCue( geActor *A, int Index )
01378 {
01379 geMotion *M;
01380 assert( geActor_IsValid(A) != GE_FALSE);
01381 assert( (Index>=0) && (Index<geMotion_GetSubMotionCount(A->CueMotion)));
01382 M = geMotion_RemoveSubMotion(A->CueMotion,Index);
01383 }
01384
01385 GENESISAPI geBoolean GENESISCC geActor_AnimationNudge(geActor *A, geXForm3d *Offset)
01386 {
01387 geMotion *M;
01388 int i,Count;
01389 assert( geActor_IsValid(A) != GE_FALSE);
01390 assert( geXForm3d_IsOrthonormal(Offset) != GE_FALSE );
01391 M = A->CueMotion;
01392 Count = geMotion_GetSubMotionCount(M);
01393
01394 for (i=Count-1; i>=0; i--)
01395 {
01396 geXForm3d Transform;
01397 const geXForm3d *pTransform;
01398 pTransform = geMotion_GetBaseTransform( M, i );
01399 if ( pTransform != NULL )
01400 {
01401 Transform = *pTransform;
01402
01403 geXForm3d_Multiply(Offset,&Transform,&Transform);
01404 geXForm3d_Orthonormalize(&Transform);
01405
01406 geMotion_SetBaseTransform( M, i, &Transform);
01407 }
01408 }
01409 return GE_TRUE;
01410 }
01411
01412 GENESISAPI geBoolean GENESISCC geActor_AnimationRemoveLastCue( geActor *A )
01413 {
01414 int Count;
01415 assert( geActor_IsValid(A) != GE_FALSE);
01416 Count = geMotion_GetSubMotionCount(A->CueMotion);
01417 if (Count>0)
01418 {
01419 geActor_KillCue( A, Count-1 );
01420 return GE_TRUE;
01421 }
01422 return GE_FALSE;
01423 }
01424
01425 GENESISAPI geBoolean GENESISCC geActor_AnimationCue( geActor *A,
01426 geMotion *Motion,
01427 geFloat TimeScaleFactor,
01428 geFloat TimeIntoMotion,
01429 geFloat BlendTime,
01430 geFloat BlendFromAmount,
01431 geFloat BlendToAmount,
01432 const geXForm3d *MotionTransform)
01433 {
01434 int Index;
01435
01436 assert( geActor_IsValid(A) != GE_FALSE);
01437
01438 assert( (BlendFromAmount>=0.0f) && (BlendFromAmount<=1.0f));
01439 assert( ( BlendToAmount>=0.0f) && ( BlendToAmount<=1.0f));
01440 assert( (MotionTransform==NULL) || (geXForm3d_IsOrthonormal(MotionTransform)) != GE_FALSE );
01441
01442 assert( Motion != NULL );
01443
01444 assert( BlendTime >= 0.0f);
01445 if (BlendTime==0.0f)
01446 {
01447 BlendFromAmount = BlendToAmount;
01448 BlendTime = 1.0f;
01449 }
01450
01451 if (geMotion_AddSubMotion( A->CueMotion, TimeScaleFactor, -TimeIntoMotion, Motion,
01452 TimeIntoMotion, BlendFromAmount,
01453 TimeIntoMotion + BlendTime, BlendToAmount,
01454 MotionTransform, &Index )==GE_FALSE)
01455 {
01456 return GE_FALSE;
01457 }
01458
01459 return GE_TRUE;
01460 }
01461
01462
01463 GENESISAPI geBoolean GENESISCC geActor_AnimationStep(geActor *A, geFloat DeltaTime )
01464 {
01465 int i,Coverage,Count;
01466 geMotion *M;
01467 geMotion *SubM;
01468
01469 assert( geActor_IsValid(A) != GE_FALSE);
01470 assert( DeltaTime >= 0.0f );
01471
01472 gePose_ClearCoverage(A->Pose,0);
01473
01474 M = A->CueMotion;
01475
01476 Count = geMotion_GetSubMotionCount(M);
01477
01478 for (i=Count-1; i>=0; i--)
01479 {
01480 geFloat TimeOffset = geMotion_GetTimeOffset( M, i );
01481 TimeOffset = TimeOffset - DeltaTime;
01482 geMotion_SetTimeOffset( M, i, TimeOffset);
01483
01484 if (geActor_IsAnimationCueDead(A,i))
01485 {
01486 geActor_KillCue(A,i);
01487 }
01488 else
01489 {
01490 geBoolean SetWithBlending= GE_TRUE;
01491 geFloat BlendAmount;
01492
01493 SubM = geMotion_GetSubMotion(M,i);
01494 assert( SubM != NULL );
01495
01496 BlendAmount = geMotion_GetBlendAmount( M,i,0.0f );
01497
01498 if (BlendAmount >= ACTOR_CUE_MAXIMUM_BLEND)
01499 {
01500 SetWithBlending = GE_FALSE;
01501 }
01502 Coverage = gePose_AccumulateCoverage(A->Pose,SubM, SetWithBlending);
01503 if ( Coverage == 0 )
01504 {
01505 geActor_KillCue(A,i);
01506 }
01507 }
01508 }
01509
01510 gePose_SetMotion( A->Pose, M, 0.0f, NULL );
01511 geMotion_SetupEventIterator(M,-DeltaTime,0.0f);
01512
01513 return GE_TRUE;
01514 }
01515
01516
01517 GENESISAPI geBoolean GENESISCC geActor_AnimationStepBoneOptimized(geActor *A, geFloat DeltaTime, const char *BoneName )
01518 {
01519 int i,Coverage,Count;
01520 geMotion *M;
01521 geMotion *SubM;
01522
01523 assert( geActor_IsValid(A) != GE_FALSE);
01524 assert( DeltaTime >= 0.0f );
01525
01526 if (BoneName == NULL)
01527 {
01528 A->StepBoneIndex = GE_POSE_ROOT_JOINT;
01529 }
01530 else
01531 {
01532 geBoolean LookupBoneName= GE_TRUE;
01533 const char *LastBoneName;
01534 geXForm3d Attachment;
01535 int LastParentBoneIndex;
01536 if (A->StepBoneIndex >= 0)
01537 {
01538 geBody_GetBone( A->ActorDefinition->Body,A->StepBoneIndex,&LastBoneName,&Attachment,&LastParentBoneIndex);
01539 if ( (LastBoneName != NULL) )
01540 if (strcmp(LastBoneName,BoneName)==0)
01541 LookupBoneName = GE_FALSE;
01542 }
01543 if (LookupBoneName != GE_FALSE)
01544 {
01545 if (geActor_GetBoneIndex(A,BoneName,&(A->StepBoneIndex))==GE_FALSE)
01546 {
01547 geErrorLog_AddString(-1,"Named bone not found", BoneName);
01548 return GE_FALSE;
01549 }
01550 }
01551 }
01552
01553
01554 gePose_ClearCoverage(A->Pose,0);
01555
01556 M = A->CueMotion;
01557
01558 Count = geMotion_GetSubMotionCount(M);
01559
01560 for (i=Count-1; i>=0; i--)
01561 {
01562 geFloat TimeOffset = geMotion_GetTimeOffset( M, i );
01563 TimeOffset = TimeOffset - DeltaTime;
01564 geMotion_SetTimeOffset( M, i, TimeOffset);
01565
01566 if (geActor_IsAnimationCueDead(A,i))
01567 {
01568 geActor_KillCue(A,i);
01569 }
01570 else
01571 {
01572 geBoolean SetWithBlending= GE_TRUE;
01573 geFloat BlendAmount;
01574
01575 SubM = geMotion_GetSubMotion(M,i);
01576 assert( SubM != NULL );
01577
01578 BlendAmount = geMotion_GetBlendAmount( M,i,0.0f );
01579
01580 if (BlendAmount >= ACTOR_CUE_MAXIMUM_BLEND)
01581 {
01582 SetWithBlending = GE_FALSE;
01583 }
01584 Coverage = gePose_AccumulateCoverage(A->Pose,SubM, SetWithBlending);
01585 if ( Coverage == 0 )
01586 {
01587 geActor_KillCue(A,i);
01588 }
01589 }
01590 }
01591
01592 gePose_SetMotionForABone( A->Pose, M, 0.0f, NULL, A->StepBoneIndex );
01593 geMotion_SetupEventIterator(M,-DeltaTime,0.0f);
01594
01595 return GE_TRUE;
01596 }
01597
01598
01599
01600 GENESISAPI geBoolean GENESISCC geActor_AnimationTestStep(geActor *A, geFloat DeltaTime)
01601 {
01602 assert( geActor_IsValid(A) != GE_FALSE);
01603 assert( DeltaTime >= 0.0f );
01604
01605 gePose_SetMotion( A->Pose, A->CueMotion , DeltaTime, NULL );
01606
01607 return GE_TRUE;
01608 }
01609
01610 GENESISAPI geBoolean GENESISCC geActor_AnimationTestStepBoneOptimized(geActor *A, geFloat DeltaTime, const char *BoneName)
01611 {
01612 assert( geActor_IsValid(A) != GE_FALSE);
01613 assert( DeltaTime >= 0.0f );
01614
01615 if (BoneName == NULL)
01616 {
01617 A->StepBoneIndex = GE_POSE_ROOT_JOINT;
01618 }
01619 else
01620 {
01621 geBoolean LookupBoneName= GE_TRUE;
01622 const char *LastBoneName;
01623 geXForm3d Attachment;
01624 int LastParentBoneIndex;
01625 if (A->StepBoneIndex >= 0)
01626 {
01627 geBody_GetBone( A->ActorDefinition->Body,A->StepBoneIndex,&LastBoneName,&Attachment,&LastParentBoneIndex);
01628 if ( (LastBoneName != NULL) )
01629 if (strcmp(LastBoneName,BoneName)==0)
01630 LookupBoneName = GE_FALSE;
01631 }
01632 if (LookupBoneName != GE_FALSE)
01633 {
01634 if (geActor_GetBoneIndex(A,BoneName,&(A->StepBoneIndex))==GE_FALSE)
01635 {
01636 geErrorLog_AddString(-1,"Named bone not found", BoneName);
01637 return GE_FALSE;
01638 }
01639 }
01640 }
01641 gePose_SetMotionForABone( A->Pose, A->CueMotion , DeltaTime, NULL,A->StepBoneIndex );
01642
01643 return GE_TRUE;
01644 }
01645
01646
01647
01648 GENESISAPI geBoolean GENESISCC geActor_GetAnimationEvent(
01649 geActor *A,
01650 const char **ppEventString)
01651
01652
01653
01654 {
01655 geFloat Time;
01656 assert( geActor_IsValid(A) != GE_FALSE);
01657
01658 return geMotion_GetNextEvent(A->CueMotion, &Time, ppEventString );
01659 }
01660
01661
01662 #ifndef NDEBUG
01663 static geBoolean GENESISCC geActor_TransformCompare(const geXForm3d *T1, const geXForm3d *T2)
01664 {
01665 #define SINGLE_TERM_ERROR_THRESHOLD (0.0001f)
01666 if (fabs(T1->AX - T2->AX)>SINGLE_TERM_ERROR_THRESHOLD) return GE_FALSE;
01667 if (fabs(T1->BX - T2->BX)>SINGLE_TERM_ERROR_THRESHOLD) return GE_FALSE;
01668 if (fabs(T1->CX - T2->CX)>SINGLE_TERM_ERROR_THRESHOLD) return GE_FALSE;
01669 if (fabs(T1->AY - T2->AY)>SINGLE_TERM_ERROR_THRESHOLD) return GE_FALSE;
01670 if (fabs(T1->BY - T2->BY)>SINGLE_TERM_ERROR_THRESHOLD) return GE_FALSE;
01671 if (fabs(T1->CY - T2->CY)>SINGLE_TERM_ERROR_THRESHOLD) return GE_FALSE;
01672 if (fabs(T1->AZ - T2->AZ)>SINGLE_TERM_ERROR_THRESHOLD) return GE_FALSE;
01673 if (fabs(T1->BZ - T2->BZ)>SINGLE_TERM_ERROR_THRESHOLD) return GE_FALSE;
01674 if (fabs(T1->CZ - T2->CZ)>SINGLE_TERM_ERROR_THRESHOLD) return GE_FALSE;
01675
01676 if (fabs(T1->Translation.X - T2->Translation.X)>SINGLE_TERM_ERROR_THRESHOLD) return GE_FALSE;
01677 if (fabs(T1->Translation.Y - T2->Translation.Y)>SINGLE_TERM_ERROR_THRESHOLD) return GE_FALSE;
01678 if (fabs(T1->Translation.Z - T2->Translation.Z)>SINGLE_TERM_ERROR_THRESHOLD) return GE_FALSE;
01679 return GE_TRUE;
01680 }
01681 #endif
01682
01683
01684
01685 GENESISAPI geBoolean GENESISCC geActor_GetLightingOptions(const geActor *Actor,
01686 geBoolean *UseFillLight,
01687 geVec3d *FillLightNormal,
01688 geFloat *FillLightRed,
01689 geFloat *FillLightGreen,
01690 geFloat *FillLightBlue,
01691 geFloat *AmbientLightRed,
01692 geFloat *AmbientLightGreen,
01693 geFloat *AmbientLightBlue,
01694 geBoolean *UseAmbientLightFromFloor,
01695 int *MaximumDynamicLightsToUse,
01696 const char **LightReferenceBoneName,
01697 geBoolean *PerBoneLighting)
01698 {
01699 int BoneIndex;
01700 assert( geActor_IsValid(Actor)!=GE_FALSE );
01701
01702 assert( UseFillLight != NULL );
01703 assert( FillLightNormal != NULL );
01704 assert( FillLightRed != NULL );
01705 assert( FillLightGreen != NULL );
01706 assert( FillLightBlue != NULL );
01707 assert( AmbientLightRed != NULL );
01708 assert( AmbientLightGreen != NULL );
01709 assert( AmbientLightBlue != NULL );
01710 assert( UseAmbientLightFromFloor != NULL );
01711 assert( MaximumDynamicLightsToUse != NULL );
01712 assert( LightReferenceBoneName != NULL );
01713
01714 if (Actor->Puppet == NULL)
01715 {
01716 geErrorLog_AddString(-1,"Can't set lighting options until actor is prepared for rendering", NULL);
01717 return GE_FALSE;
01718 }
01719
01720 gePuppet_GetLightingOptions( Actor->Puppet,
01721 UseFillLight,
01722 FillLightNormal,
01723 FillLightRed,
01724 FillLightGreen,
01725 FillLightBlue,
01726 AmbientLightRed,
01727 AmbientLightGreen,
01728 AmbientLightBlue,
01729 UseAmbientLightFromFloor,
01730 MaximumDynamicLightsToUse,
01731 &BoneIndex,
01732 PerBoneLighting);
01733
01734 if (BoneIndex>=0 && (BoneIndex < geBody_GetBoneCount(Actor->ActorDefinition->Body)))
01735 {
01736 geXForm3d DummyAttachment;
01737 int DummyParentBoneIndex;
01738 geBody_GetBone( Actor->ActorDefinition->Body,
01739 BoneIndex,
01740 LightReferenceBoneName,
01741 &DummyAttachment,
01742 &DummyParentBoneIndex);
01743 }
01744 else
01745 {
01746 LightReferenceBoneName = NULL;
01747 }
01748
01749 return GE_TRUE;
01750 }
01751
01752
01753 GENESISAPI void GENESISCC geActor_SetEnvironOptions( geActor *A, geEnvironmentOptions *opts )
01754 {
01755 assert ( geActor_IsValid(A) != GE_FALSE );
01756 assert ( A->Puppet != NULL );
01757 gePuppet_SetEnvironmentOptions( A->Puppet, opts );
01758 }
01759
01760 GENESISAPI geEnvironmentOptions GENESISCC geActor_GetEnvironOptions( geActor *A )
01761 {
01762 assert ( geActor_IsValid(A) != GE_FALSE );
01763 assert ( A->Puppet != NULL );
01764 return gePuppet_GetEnvironmentOptions( A->Puppet );
01765 }
01766
01767 GENESISAPI geBoolean GENESISCC geActor_SetLightingOptions(geActor *A,
01768 geBoolean UseFillLight,
01769 const geVec3d *FillLightNormal,
01770 geFloat FillLightRed,
01771 geFloat FillLightGreen,
01772 geFloat FillLightBlue,
01773 geFloat AmbientLightRed,
01774 geFloat AmbientLightGreen,
01775 geFloat AmbientLightBlue,
01776 geBoolean AmbientLightFromFloor,
01777 int MaximumDynamicLightsToUse,
01778 const char *LightReferenceBoneName,
01779 geBoolean PerBoneLighting )
01780 {
01781 int BoneIndex;
01782
01783 assert( geActor_IsValid(A)!=GE_FALSE );
01784 assert( FillLightNormal != NULL );
01785
01786 if (A->Puppet == NULL)
01787 {
01788 geErrorLog_AddString(-1,"Can't set lighting options until actor is prepared for rendering", NULL);
01789 return GE_FALSE;
01790 }
01791 if (geActor_GetBoneIndex(A,LightReferenceBoneName,&BoneIndex)==GE_FALSE)
01792 {
01793 geErrorLog_AddString(-1,"Named bone for light reference not found", LightReferenceBoneName);
01794 return GE_FALSE;
01795 }
01796
01797 gePuppet_SetLightingOptions( A->Puppet,
01798 UseFillLight,
01799 FillLightNormal,
01800 FillLightRed,
01801 FillLightGreen,
01802 FillLightBlue,
01803 AmbientLightRed,
01804 AmbientLightGreen,
01805 AmbientLightBlue,
01806 AmbientLightFromFloor,
01807 MaximumDynamicLightsToUse,
01808 BoneIndex,
01809 PerBoneLighting);
01810 return GE_TRUE;
01811 }
01812
01813 GENESISAPI void GENESISCC geActor_SetScale(geActor *A, geFloat ScaleX,geFloat ScaleY,geFloat ScaleZ)
01814 {
01815 geVec3d S;
01816 assert( A != NULL );
01817
01818 geVec3d_Set(&S,ScaleX,ScaleY,ScaleZ);
01819 gePose_SetScale(A->Pose,&S);
01820 }
01821
01822
01823
01824 GENESISAPI geBoolean GENESISCC geActor_SetShadow(geActor *A,
01825 geBoolean DoShadow,
01826 geFloat Radius,
01827 const geBitmap *ShadowMap,
01828 const char *BoneName)
01829 {
01830 int BoneIndex;
01831
01832 assert( geActor_IsValid(A)!=GE_FALSE );
01833 assert( (DoShadow==GE_FALSE) || (DoShadow==GE_TRUE));
01834 assert( Radius >= 0.0f);
01835
01836 if (A->Puppet == GE_FALSE)
01837 {
01838 geErrorLog_AddString(-1,"Can't set shadow options until actor is prepared for rendering", NULL);
01839 return GE_FALSE;
01840 }
01841
01842 if (geActor_GetBoneIndex(A,BoneName,&BoneIndex)==GE_FALSE)
01843 {
01844 geErrorLog_AddString(-1,"Named bone for shadow not found", BoneName);
01845 return GE_FALSE;
01846 }
01847
01848 gePuppet_SetShadow(A->Puppet,DoShadow,Radius,ShadowMap,BoneIndex);
01849
01850 return GE_TRUE;
01851 }
01852
01853
01854 geBoolean GENESISCC geActor_RenderPrep( geActor *A, geWorld *World)
01855 {
01856 assert( geActor_IsValid(A) != GE_FALSE );
01857 #pragma message ("need to make a world method that does this. so World doesn't get passed in")
01858 assert( geActor_DefIsValid(A->ActorDefinition) != GE_FALSE );
01859 assert( geBody_IsValid(A->ActorDefinition->Body) != GE_FALSE );
01860
01861 if (A->Puppet!=NULL)
01862 {
01863 gePuppet_Destroy(&(A->Puppet));
01864 A->Puppet =NULL;
01865 }
01866
01867 A->Puppet = gePuppet_Create(A->ActorDefinition->TextureFileContext, A->ActorDefinition->Body,World);
01868 if ( A->Puppet == NULL )
01869 {
01870 geErrorLog_Add( ERR_ACTOR_RENDER_PREP , NULL);
01871 return GE_FALSE;
01872 }
01873 {
01874 geExtBox EB;
01875
01876 geActor_GetDynamicExtBox(A, &EB);
01877 geBody_SetBoundingBox(A->ActorDefinition->Body, GE_BODY_ROOT, &EB.Min, &EB.Max);
01878 if (geActor_GetBoneExtBoxByIndex(A,GE_POSE_ROOT_JOINT,&EB) == GE_FALSE)
01879 {
01880 geErrorLog_AddString(-1,"Failure to get Root Bounding box from puppet", NULL);
01881 return GE_FALSE;
01882 }
01883
01884 A->BoundingBoxMinCorner = EB.Min;
01885 A->BoundingBoxMaxCorner = EB.Max;
01886 }
01887
01888 return GE_TRUE;
01889 }
01890
01891 geBoolean GENESISCC geActor_RenderThroughFrustum(const geActor *A, geEngine *Engine, geWorld *World,geCamera *Camera, Frustum_Info *FInfo)
01892 {
01893 geExtBox Box;
01894
01895 assert( geActor_IsValid(A) != GE_FALSE );
01896 assert( A->Puppet != NULL );
01897
01898 if (!geActor_GetDynamicExtBox( A, &Box))
01899 {
01900 geErrorLog_AddString(-1, "geActor_RenderThroughFrustum: geActor_GetDynamicAABoundingBox failed.", NULL);
01901 return GE_FALSE;
01902 }
01903
01904 if (gePuppet_RenderThroughFrustum( A->Puppet, A->Pose, &Box, Engine, World, Camera, FInfo)==GE_FALSE)
01905 {
01906 geErrorLog_Add( ERR_ACTOR_RENDER_FAILED , NULL);
01907 return GE_FALSE;
01908 }
01909 return GE_TRUE;
01910 }
01911
01912 geBoolean GENESISCC geActor_Render(const geActor *A, geEngine *Engine, geWorld *World,geCamera *Camera)
01913 {
01914 assert( geActor_IsValid(A) != GE_FALSE );
01915 assert( A->Puppet != NULL );
01916
01917 if (A->RenderHintExtBoxEnabled)
01918 {
01919 geBoolean Enabled;
01920 geExtBox Box;
01921 if (geActor_GetRenderHintExtBox(A, &Box, &Enabled)==GE_FALSE)
01922 {
01923 geErrorLog_Add( -1 , NULL);
01924 return GE_FALSE;
01925 }
01926 if (gePuppet_Render( A->Puppet, A->Pose, Engine,World, Camera, &Box )==GE_FALSE)
01927 {
01928 geErrorLog_Add( ERR_ACTOR_RENDER_FAILED , NULL);
01929 return GE_FALSE;
01930 }
01931 }
01932 else
01933 {
01934 if (gePuppet_Render( A->Puppet, A->Pose, Engine,World, Camera, NULL )==GE_FALSE)
01935 {
01936 geErrorLog_Add( ERR_ACTOR_RENDER_FAILED , NULL);
01937 return GE_FALSE;
01938 }
01939 }
01940 return GE_TRUE;
01941 }
01942
01943 GENESISAPI int GENESISCC geActor_GetMaterialCount(const geActor *A)
01944 {
01945 assert( geActor_IsValid(A) != GE_FALSE );
01946 assert( A->Puppet != NULL );
01947
01948 return gePuppet_GetMaterialCount( A->Puppet );
01949 }
01950
01951 GENESISAPI geBoolean GENESISCC geActor_GetMaterial(const geActor *A, int MaterialIndex,
01952 geBitmap **Bitmap, geFloat *Red, geFloat *Green, geFloat *Blue)
01953 {
01954 assert( geActor_IsValid(A) != GE_FALSE );
01955 assert( A->Puppet != NULL );
01956
01957 return gePuppet_GetMaterial(A->Puppet, MaterialIndex, Bitmap, Red, Green, Blue );
01958 }
01959
01960
01961 GENESISAPI geBoolean GENESISCC geActor_SetMaterial(geActor *A, int MaterialIndex,
01962 geBitmap *Bitmap, geFloat Red, geFloat Green, geFloat Blue)
01963 {
01964 assert( geActor_IsValid(A) != GE_FALSE );
01965 assert( A->Puppet != NULL );
01966
01967 return gePuppet_SetMaterial(A->Puppet,MaterialIndex, Bitmap, Red, Green, Blue );
01968 }
01969
01970 GENESISAPI geBoolean GENESISCC geActor_SetStaticLightingOptions(geActor *A, geBoolean AmbientLightFromStaticLights, geBoolean TestRayCollision, int MaxStaticLightsToUse )
01971 { assert( geActor_IsValid(A)!=GE_FALSE );
01972 if (A->Puppet == NULL)
01973 {
01974 geErrorLog_AddString(-1,"Can't set lighting options until actor is prepared for rendering", NULL);
01975 return GE_FALSE;
01976 }
01977 gePuppet_SetStaticLightingOptions( A->Puppet,
01978 AmbientLightFromStaticLights,
01979 MaxStaticLightsToUse,
01980 TestRayCollision
01981 );
01982 return GE_TRUE;
01983 }
01984
01985 GENESISAPI geBoolean GENESISCC geActor_GetStaticLightingOptions( const geActor *Actor, geBoolean *UseAmbientLightFromStaticLights, geBoolean *TestRayCollision, int *MaxStaticLightsToUse )
01986 { assert( geActor_IsValid(Actor)!=GE_FALSE );
01987 assert( UseAmbientLightFromStaticLights != NULL );
01988 assert( TestRayCollision != NULL );
01989 if (Actor->Puppet == NULL)
01990 {
01991 geErrorLog_AddString(-1,"Can't set lighting options until actor is prepared for rendering", NULL);
01992 return GE_FALSE;
01993 }
01994
01995 gePuppet_GetStaticLightingOptions( Actor->Puppet,
01996 UseAmbientLightFromStaticLights,
01997 TestRayCollision,
01998 MaxStaticLightsToUse
01999 );
02000 return GE_TRUE;
02001 }