/tags/JSTUDIO3D_2_5_beta_1/source/Engine/JetEngine/Actor/Actor.cpp
# · C++ · 2320 lines · 1760 code · 431 blank · 129 comment · 439 complexity · 2c32d4b0c58890f14c019605bb4c175f MD5 · raw file
Large files are truncated click here to view the full file
- /****************************************************************************************/
- /* ACTOR.C */
- /* */
- /* Authors: Mike Sandige */
- /* Aaron Oneal (Incarnadine) - aoneal@ij.net */
- /* Description: Actor implementation */
- /* */
- /* The contents of this file are subject to the Jet3D Public License */
- /* Version 1.02 (the "License"); you may not use this file except in */
- /* compliance with the License. You may obtain a copy of the License at */
- /* http://www.jet3d.com */
- /* */
- /* Software distributed under the License is distributed on an "AS IS" */
- /* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */
- /* the License for the specific language governing rights and limitations */
- /* under the License. */
- /* */
- /* The Original Code is Jet3D, released December 12, 1999. */
- /* Copyright (C) 1996-1999 Eclipse Entertainment, L.L.C. All Rights Reserved */
- /* */
- /****************************************************************************************/
- /*
- TODO:
- make cued motions keyed to a 'root' bone. Register the root bone, and then
- all requests are relative to that bone, rather than the current 'anchor' point.
- actually, this doesn't really change much, just _AnimationCue() - and it allows
- a more efficient _TestStep()
- convert BoundingBoxMinCorner, BoundingBoxMaxCorner to use extbox.
-
- */
- #include <assert.h>
- #include <string.h> // _stricmp()
- #include <malloc.h> // free
- #include <math.h>
- #include "Actor.h"
- #include "Ram.h"
- #include "Puppet.h"
- #include "Body.h"
- #include "Motion.h"
- #include "Errorlog.h"
- #include "StrBlock.h"
- #include "Log.h"
- #include "Actor._h"
- #ifdef WIN32
- #pragma warning ( disable : 4115 )
- #include <windows.h>
- #pragma warning ( default : 4115 )
- #endif
- #ifdef BUILD_BE
- #define _stricmp strcasecmp
- #endif
- #define ACTOR_MOTIONS_MAX 0x0FFFF // really arbitrary. just for sanity checking
- #define ACTOR_CUES_MAX 0x0FFFF // arbitrary.
- /*
- typedef struct ActorObj {
- char *ActorDefName, *MotionName;
- jeBoolean CollisionExtBoxDisplay;
- jeExtBox CollisionExtBox;
- jeBoolean RenderExtBoxDisplay;
- jeExtBox RenderHintExtBox;
- char **MotionList;
- int MotionListSize;
- jeMotion *Motion;
- float MotionTime;
- float ScaleX,ScaleY,ScaleZ;
- float MotionTimeScale;
- jeWorld *World;
- jeEngine *Engine;
- jeResourceMgr *ResourceMgr;
- } ActorObj;*/
- // these are useful globals to monitor resources
- int jeActor_Count = 0;
- int jeActor_RefCount = 0;
- int jeActor_DefCount = 0;
- int jeActor_DefRefCount = 0;
- // [MacroArt::Begin]
- // Thanks Dee(cryscan@home.net)
- JETAPI float JETCC jeActor_GetAlpha(const jeActor *A)
- {
- assert( A != NULL ) ;
- assert( A->Puppet != NULL ) ;
- return jePuppet_GetAlpha(A->Puppet);
- }
- JETAPI void JETCC jeActor_SetAlpha(jeActor *A, float Alpha)
- {
- assert( A != NULL ) ;
- assert( A->Puppet != NULL ) ;
- jePuppet_SetAlpha( A->Puppet, Alpha ) ;
- }
- // [MacroArt::End]
- // returns number of actors that are currently created.
- JETAPI int32 JETCC jeActor_GetCount(void)
- {
- return jeActor_Count;
- }
- JETAPI jeBoolean JETCC jeActor_IsValid(const jeActor *A)
- {
- if (A==NULL)
- return JE_FALSE;
- if(A->ActorDefinition)
- {
- if (A->Pose == NULL)
- return JE_FALSE;
- if (A->CueMotion == NULL)
- return JE_FALSE;
- if (jeActor_DefIsValid(A->ActorDefinition)==JE_FALSE)
- return JE_FALSE;
- if (jeBody_IsValid(A->ActorDefinition->Body) == JE_FALSE )
- return JE_FALSE;
- }
- return JE_TRUE;
- }
-
- JETAPI jeBoolean JETCC jeActor_DefIsValid(const jeActor_Def *A)
- {
- if (A==NULL)
- return JE_FALSE;
- if (A->ValidityCheck != A)
- return JE_FALSE;
- return JE_TRUE;
- }
- static jeBoolean JETCF jeActor_GetBoneIndex(const jeActor *A, const char *BoneName, int *BoneIndex)
- {
- jeXForm3d Dummy;
- int ParentBoneIndex;
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( jeActor_DefIsValid(A->ActorDefinition) != JE_FALSE );
- assert( jeBody_IsValid(A->ActorDefinition->Body) != JE_FALSE );
- assert( BoneIndex != NULL );
- if ( BoneName != NULL )
- {
- if (jeBody_GetBoneByName(A->ActorDefinition->Body,
- BoneName,
- BoneIndex,
- &Dummy,
- &ParentBoneIndex) ==JE_FALSE)
- {
- jeErrorLog_AddString(JE_ERR_SUBSYSTEM_FAILURE,"jeActor_GetBoneIndex: Named bone not found:", BoneName);
- return JE_FALSE;
- }
- }
- else
- {
- *BoneIndex = JE_POSE_ROOT_JOINT;
- }
- return JE_TRUE;
- }
- JETAPI jeActor_Def *JETCC jeActor_GetActorDef(const jeActor *A)
- {
- assert( jeActor_DefIsValid(A->ActorDefinition) != JE_FALSE );
- return A->ActorDefinition;
- }
- JETAPI void JETCC jeActor_DefCreateRef(jeActor_Def *A)
- {
- assert( jeActor_DefIsValid(A) != JE_FALSE );
- A->RefCount++;
- jeActor_DefRefCount++;
- }
- JETAPI jeActor_Def *JETCC jeActor_DefCreate(void)
- {
- jeActor_Def *Ad;
- Ad = JE_RAM_ALLOCATE_STRUCT_CLEAR( jeActor_Def );
- if ( Ad == NULL )
- {
- jeErrorLog_Add( JE_ERR_MEMORY_RESOURCE,"jeActor_DefCreateRef: Failed to allocate Actor_Def");
- return NULL;
- }
- Ad->Body = NULL;
- Ad->MotionCount = 0;
- Ad->MotionArray = NULL;
- Ad->ValidityCheck = Ad;
- Ad->RefCount = 0;
- jeActor_DefCount++;
- return Ad;
- }
- JETAPI void JETCC jeActor_CreateRef(jeActor *Actor)
- {
- assert( jeActor_IsValid(Actor) );
- Actor->RefCount ++;
- jeActor_RefCount++;
- }
- JETAPI jeActor * JETCC jeActor_CreateFromDef(jeActor_Def *ActorDefinition)
- {
- jeActor *A;
- A = JE_RAM_ALLOCATE_STRUCT_CLEAR( jeActor );
- if ( A == NULL )
- {
- jeErrorLog_Add( JE_ERR_MEMORY_RESOURCE , "jeActor_Create: Failed to allocate jeActor struct");
- return NULL;
- }
- A->Puppet = NULL;
- A->Pose = NULL;
- A->CueMotion = NULL;
- A->ActorDefinition = NULL;
- A->RefCount = 0;
- A->CanFree = JE_TRUE;
- jeExtBox_Set(&(A->CollisionExtBox), 0.0f,0.0f,0.0f,0.0f,0.0f,0.0f);
- jeExtBox_Set(&(A->RenderHintExtBox), 0.0f,0.0f,0.0f,0.0f,0.0f,0.0f);
- jeXForm3d_SetIdentity(&A->Xf);
- jeActor_Count++;
- if(ActorDefinition != NULL)
- jeActor_SetActorDef(A,ActorDefinition);
- return A;
- }
- JETAPI jeActor *JETCC jeActor_Create()
- {
- jeActor *A;
- A = JE_RAM_ALLOCATE_STRUCT_CLEAR( jeActor );
- if ( A == NULL )
- {
- jeErrorLog_Add( JE_ERR_MEMORY_RESOURCE , "jeActor_Create: Failed to allocate jeActor struct");
- return NULL;
- }
- A->Puppet = NULL;
- A->Pose = NULL;
- A->CueMotion = NULL;
- A->ActorDefinition = NULL;
- A->RefCount = 0;
- A->CanFree = JE_TRUE;
- A->RenderNextTime = JE_TRUE;
- InitializeCriticalSection(&A->RenderLock);
- jeExtBox_Set(&(A->CollisionExtBox), 0.0f,0.0f,0.0f,0.0f,0.0f,0.0f);
- jeExtBox_Set(&(A->RenderHintExtBox), 0.0f,0.0f,0.0f,0.0f,0.0f,0.0f);
- jeXForm3d_SetIdentity(&A->Xf);
- jeActor_Count++;
- return A;
- }
- JETAPI jeBoolean JETCC jeActor_DefDestroy(jeActor_Def **pActorDefinition)
- {
- int i;
- jeActor_Def *Ad;
- assert( pActorDefinition != NULL );
- assert( *pActorDefinition != NULL );
- assert( jeActor_DefIsValid( *pActorDefinition ) != JE_FALSE );
- Ad = *pActorDefinition;
- if (Ad->RefCount > 0)
- {
- Ad->RefCount--;
- jeActor_DefRefCount--;
- return JE_FALSE;
- }
- if (Ad->Body != NULL)
- {
- jeBody_Destroy( &(Ad->Body) );
- Ad->Body = NULL;
- }
- if (Ad->MotionArray != NULL)
- {
- for (i=0; i<Ad->MotionCount; i++)
- {
- if (Ad->MotionArray[i]!=NULL)
- {
- jeMotion_Destroy( &(Ad->MotionArray[i]) );
- }
- Ad->MotionArray[i] = NULL;
- }
- jeRam_Free( Ad->MotionArray );
- Ad->MotionArray = NULL;
- }
-
- Ad->MotionCount = 0;
- jeRam_Free(*pActorDefinition);
- *pActorDefinition = NULL;
- jeActor_DefCount--;
- return JE_TRUE;
- }
- JETAPI jeBoolean JETCC jeActor_Destroy(jeActor **pA)
- {
- jeActor *A;
- jeChain_Link *Link;
- assert( pA != NULL );
- assert( *pA != NULL );
- assert( jeActor_IsValid(*pA) != JE_FALSE );
-
- A = *pA;
- if (A->RefCount > 0)
- {
- A->RefCount --;
- jeActor_RefCount--;
- return JE_FALSE;
- }
- if (A->Puppet != NULL)
- {
- jePuppet_Destroy( &(A->Puppet) );
- A->Puppet = NULL;
- }
- if ( A->Pose != NULL )
- {
- jePose_Destroy( &( A->Pose ) );
- A->Pose = NULL;
- }
- if ( A->CueMotion != NULL )
- {
- jeMotion_Destroy(&(A->CueMotion));
- A->CueMotion = NULL;
- }
- // destroy bone collision list -- Incarnadine
- if(A->BoneCollisionChain != NULL)
- {
- for (Link = jeChain_GetFirstLink(A->BoneCollisionChain); Link; Link = jeChain_LinkGetNext(Link))
- {
- // Icestorm: Added BoneExtBoxes
- jeCollisionBone *Bone;
-
- Bone = (jeCollisionBone*)jeChain_LinkGetLinkData( Link );
- if(Bone)
- {
- free(Bone->BoneName);
- jeRam_Free(Bone->CurrExtBox);
- jeRam_Free(Bone->PrevExtBox);
- jeRam_Free(Bone);
- }
- }
- // destroy object chain
- jeChain_Destroy( &( A->BoneCollisionChain ) );
- A->BoneCollisionChain = NULL;
- }
-
- if(A->ActorDefinition != NULL)
- {
- jeActor_DefDestroy(&(A->ActorDefinition));
- A->ActorDefinition = NULL;
- }
- if(A->Object != NULL)
- {
- jeRam_Free(A->Object);
- A->Object = NULL;
- }
- DeleteCriticalSection(&A->RenderLock);
-
- if(A->CanFree == JE_TRUE)
- {
- jeActor_Count--;
- jeRam_Free(*pA);
- *pA = NULL;
- }
- return JE_TRUE;
- }
- // Incarnadine
- // INCNOTE: This function isn't right, it needs to totally kill the actor
- // Do a new create basically. Look into making a separate function
- // that calls the old actor create function.
- JETAPI void JETCC jeActor_SetActorDef(jeActor *A, jeActor_Def *Def)
- {
- ActorObj *pObj;
- assert(A);
- assert(Def);
- assert( jeActor_DefIsValid(Def) != JE_FALSE );
- assert( jeBody_IsValid(Def->Body) != JE_FALSE );
-
- if(A->Pose != NULL)
- {
- pObj = A->Object;
- A->Object = NULL;
- A->CanFree = JE_FALSE;
- jeActor_Destroy(&A);
- A->CanFree = JE_TRUE;
- A->Object = pObj;
- }
-
- A->ActorDefinition = Def;
- jeExtBox_Set(&(A->CollisionExtBox), 0.0f,0.0f,0.0f,0.0f,0.0f,0.0f);
- jeExtBox_Set(&(A->RenderHintExtBox), 0.0f,0.0f,0.0f,0.0f,0.0f,0.0f);
- jeXForm3d_SetIdentity(&A->Xf);
- A->Pose = jePose_Create();
- if (A->Pose == NULL)
- {
- jeErrorLog_Add(JE_ERR_MEMORY_RESOURCE , "jeActor_Create: Failed to allocate Pose");
- goto ActorCreateFailure;
- }
-
- A->CueMotion = jeMotion_Create(JE_TRUE);
-
- A->BlendingType = JE_ACTOR_BLEND_HERMITE;
- A->BoundingBoxCenterBoneIndex = JE_POSE_ROOT_JOINT;
- A->RenderHintExtBoxCenterBoneIndex = JE_POSE_ROOT_JOINT;
- A->RenderHintExtBoxEnabled = JE_FALSE;
- A->StepBoneIndex = JE_POSE_ROOT_JOINT;
- if (A->CueMotion == NULL)
- {
- jeErrorLog_Add(JE_ERR_MEMORY_RESOURCE , "jeActor_Create: Failed to allocate CueMotion");
- goto ActorCreateFailure;
- }
- A->BoneCollisionChain = jeChain_Create(); // Incarnadine
- A->CollisionFlags = COLLIDE_SOLID; // Incarnadine
- A->LastUsedCollisionBone=NULL; // Icestorm
- A->LastUsedCollisionBoneName=NULL; // Icestorm
- A->needsRelighting = JE_TRUE;
- assert( jeActor_IsValid(A) != JE_FALSE );
-
- {
- int i;
- int BoneCount;
- BoneCount = jeBody_GetBoneCount(A->ActorDefinition->Body);
- for (i=0; i<BoneCount; i++)
- {
- const char *Name;
- jeXForm3d Attachment;
- int ParentBone;
- int Index;
- jeBody_GetBone( A->ActorDefinition->Body, i, &Name,&Attachment, &ParentBone );
- if (jePose_AddJoint( A->Pose,
- ParentBone,Name,&Attachment,&Index)==JE_FALSE)
- {
- jeErrorLog_Add(JE_ERR_SUBSYSTEM_FAILURE,"jeActor_Create: jePose_AddJoint failed");
- A->ActorDefinition;
- return;
- }
- }
- }
- jeActor_DefCreateRef(Def);
- if(A->Object && A->Object->Engine)
- jeActor_AttachEngine(A, A->Object->Engine );
- return;
- ActorCreateFailure:
- if ( A!= NULL)
- {
- if (A->Pose != NULL)
- jePose_Destroy(&(A->Pose));
- if (A->CueMotion != NULL)
- jeMotion_Destroy(&(A->CueMotion));
- jeRam_Free( A );
- }
- }
- JETAPI jeBoolean JETCC jeActor_SetBody( jeActor_Def *ActorDefinition, jeBody *BodyGeometry)
- {
- assert( jeBody_IsValid(BodyGeometry) != JE_FALSE );
-
- if (ActorDefinition->RefCount > 0)
- {
- jeErrorLog_Add(JE_ERR_BAD_PARAMETER,"jeActor_SetBody: ActorDef in use, can't modify body");
- return JE_FALSE;
- }
- if (ActorDefinition->Body != NULL)
- {
- jeBody_Destroy( &(ActorDefinition->Body) );
- }
-
- ActorDefinition->Body = BodyGeometry;
- return JE_TRUE;
- }
- #pragma message ("consider removing this and related parameters to setpose")
- JETAPI void JETCC jeActor_SetBlendingType( jeActor *A, jeActor_BlendingType BlendingType )
- {
- assert( jeActor_IsValid(A) != JE_FALSE );
- assert( (BlendingType == JE_ACTOR_BLEND_LINEAR) ||
- (BlendingType == JE_ACTOR_BLEND_HERMITE) );
- if (BlendingType == JE_ACTOR_BLEND_LINEAR)
- {
- A->BlendingType = (jeActor_BlendingType)JE_POSE_BLEND_LINEAR;
- }
- else
- {
- A->BlendingType = (jeActor_BlendingType)JE_POSE_BLEND_HERMITE;
- }
- }
- jeVFile *jeActor_DefGetFileContext(const jeActor_Def *A)
- {
- assert( jeActor_DefIsValid(A) != JE_FALSE );
- return A->TextureFileContext;
- }
- JETAPI jeBoolean JETCC jeActor_AddMotion(jeActor_Def *Ad, jeMotion *NewMotion, int32 *Index)
- {
- jeMotion **NewMArray;
- assert( jeActor_DefIsValid(Ad) != JE_FALSE );
- assert( NewMotion != NULL );
- assert( Index != NULL );
- if (Ad->MotionCount >= ACTOR_MOTIONS_MAX)
- {
- jeErrorLog_Add(JE_ERR_LIST_FULL,"jeActor_AddMotion: Too many motions");
- return JE_FALSE;
- }
- NewMArray = JE_RAM_REALLOC_ARRAY( Ad->MotionArray, jeMotion*, Ad->MotionCount +1 );
- if ( NewMArray == NULL )
- {
- jeErrorLog_Add(JE_ERR_MEMORY_RESOURCE,"jeActor_AddMotion: Failed to reallocate motion array");
- return JE_FALSE;
- }
- Ad->MotionArray = NewMArray;
- Ad->MotionArray[Ad->MotionCount]= NewMotion;
- Ad->MotionCount++;
- *Index = Ad->MotionCount;
- return JE_TRUE;
- };
- JETAPI void JETCC jeActor_ClearPose(jeActor *A, const jeXForm3d *Transform)
- {
- assert( jeActor_IsValid(A) != JE_FALSE );
- assert ( (Transform==NULL) || (jeXForm3d_IsOrthonormal(Transform) != JE_FALSE) );
- jePose_Clear( A->Pose ,Transform);
- A->Xf = *Transform; //Incarnadine
- A->needsRelighting = JE_TRUE;
- }
- JETAPI void JETCC jeActor_SetPose(jeActor *A, const jeMotion *M,
- jeFloat Time, const jeXForm3d *Transform)
- {
- assert( jeActor_IsValid(A) != JE_FALSE );
- assert( M != NULL );
- assert ( (Transform==NULL) || (jeXForm3d_IsOrthonormal(Transform) != JE_FALSE) );
- jePose_SetMotion( A->Pose,M,Time,Transform);
- A->Xf = *Transform; //Incarnadine
- A->needsRelighting = JE_TRUE;
- }
- JETAPI void JETCC jeActor_BlendPose(jeActor *A, const jeMotion *M,
- jeFloat Time,
- const jeXForm3d *Transform,
- jeFloat BlendAmount)
- {
- assert( jeActor_IsValid(A) != JE_FALSE );
- assert( M != NULL );
- assert ( (Transform==NULL) || (jeXForm3d_IsOrthonormal(Transform) != JE_FALSE) );
- jePose_BlendMotion( A->Pose,M,Time,Transform,
- BlendAmount,(jePose_BlendingType)A->BlendingType);
- A->Xf = *Transform; //Incarnadine
- A->needsRelighting = JE_TRUE;
- }
- JETAPI int32 JETCC jeActor_GetMotionCount(const jeActor_Def *Ad)
- {
- assert( jeActor_DefIsValid(Ad) != JE_FALSE );
- return Ad->MotionCount;
- }
-
- JETAPI jeMotion *JETCC jeActor_GetMotionByIndex(const jeActor_Def *Ad, int32 Index )
- {
- assert( jeActor_DefIsValid(Ad) != JE_FALSE );
- assert( Index >= 0 );
- assert( Index < Ad->MotionCount );
- assert( Ad->MotionArray != NULL );
- return Ad->MotionArray[Index];
- }
- JETAPI jeMotion *JETCC jeActor_GetMotionByName(const jeActor_Def *Ad, const char *Name )
- {
- int i;
- const char *TestName;
- assert( jeActor_DefIsValid(Ad) != JE_FALSE );
- assert( Name != NULL );
- for (i=0; i<Ad->MotionCount; i++)
- {
- TestName = jeMotion_GetName(Ad->MotionArray[i]);
- if (TestName != NULL)
- {
- if (_stricmp(TestName,Name)==0) // Case insensitive compare -- Incarnadine
- return Ad->MotionArray[i];
- }
- }
- return NULL;
- }
- JETAPI const char *JETCC jeActor_GetMotionName(const jeActor_Def *Ad, int32 Index )
- {
- assert( jeActor_DefIsValid(Ad) != JE_FALSE );
- assert( Index >= 0 );
- assert( Index < Ad->MotionCount );
- assert( Ad->MotionArray != NULL );
- return jeMotion_GetName(Ad->MotionArray[Index]);
- }
-
- JETAPI jeBody *JETCC jeActor_GetBody(const jeActor_Def *Ad)
- {
- assert( jeActor_DefIsValid(Ad) != JE_FALSE );
- return Ad->Body;
- }
-
- #pragma message ("consider removing the function: jeActor_DefHasBoneNamed")
- // Returns JE_TRUE if the actor definition has a bone named 'Name'
- JETAPI jeBoolean JETCC jeActor_DefHasBoneNamed(const jeActor_Def *Ad, const char *Name )
- {
- int DummyIndex,DummyParent;
- jeXForm3d DummyAttachment;
- assert( jeActor_DefIsValid(Ad) != JE_FALSE );
- assert( Name != NULL );
- if (jeBody_GetBoneByName(jeActor_GetBody(Ad),Name,
- &DummyIndex, &DummyAttachment, &DummyParent ) == JE_FALSE )
- {
- return JE_FALSE;
- }
- return JE_TRUE;
- }
- #define JE_ACTOR_BODY_NAME "Body"
- #define JE_ACTOR_HEADER_NAME "Header"
- #define JE_MOTION_DIRECTORY_NAME "Motions"
- #define ACTOR_FILE_TYPE 0x52544341 // 'ACTR'
- #define ACTOR_FILE_VERSION 0x00F2 // Restrict version to 16 bits
- static jeActor_Def * JETCF jeActor_DefCreateHeader(jeVFile *pFile, jeBoolean *HasBody)
- {
- uint32 u;
- uint32 version;
- jeActor_Def *Ad;
- assert( pFile != NULL );
- assert( HasBody != NULL );
- if( ! jeVFile_Read(pFile, &u, sizeof(u)) )
- { jeErrorLog_Add( JE_ERR_FILEIO_READ , "jeActor_DefCreateHeader - Failed to read header tag"); jeActor_DefDestroy(&Ad); return NULL;}
- if (u != ACTOR_FILE_TYPE)
- { jeErrorLog_Add( JE_ERR_FILEIO_FORMAT , "jeActor_DefCreateHeader - Failed to recognize format"); return NULL;}
- if(jeVFile_Read(pFile, &version, sizeof(version)) == JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_READ , "jeActor_DefCreateHeader - Read Failed"); return NULL;}
- if ( (version != ACTOR_FILE_VERSION) )
- { jeErrorLog_Add( JE_ERR_FILEIO_VERSION , "jeActor_DefCreateHeader - Bad version"); return NULL;}
- Ad = jeActor_DefCreate();
- if (Ad==NULL)
- { jeErrorLog_Add( JE_ERR_MEMORY_RESOURCE, "jeActor_DefCreateHeader - Failed to create Def struct"); return NULL; }
- if(jeVFile_Read(pFile, HasBody, sizeof(*HasBody)) == JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_READ , "jeActor_DefCreateHeader - Read Failed"); jeActor_DefDestroy(&Ad); return NULL;}
- if(jeVFile_Read(pFile, &(Ad->MotionCount), sizeof(Ad->MotionCount)) == JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_READ , "jeActor_DefCreateHeader - Read failed"); jeActor_DefDestroy(&Ad); return NULL;}
- return Ad;
- }
- static jeBoolean JETCF jeActor_DefWriteHeader(const jeActor_Def *Ad, jeVFile *pFile)
- {
- uint32 u;
- jeBoolean Flag;
-
- assert( jeActor_DefIsValid(Ad) != JE_FALSE );
- assert( pFile != NULL );
- // Write the format flag
- u = ACTOR_FILE_TYPE;
- if(jeVFile_Write(pFile, &u, sizeof(u)) == JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_WRITE , "jeActor_DefWriteHeader - Write failed"); return JE_FALSE; }
- u = ACTOR_FILE_VERSION;
- if(jeVFile_Write(pFile, &u, sizeof(u)) == JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_WRITE , "jeActor_DefWriteHeader - Write failed"); return JE_FALSE;}
- if (Ad->Body != NULL)
- Flag = JE_TRUE;
- else
- Flag = JE_FALSE;
- if(jeVFile_Write(pFile, &Flag, sizeof(Flag)) == JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_WRITE , "jeActor_DefWriteHeader - Write failed"); return JE_FALSE;}
- if(jeVFile_Write(pFile, &(Ad->MotionCount), sizeof(Ad->MotionCount)) == JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_WRITE , "jeActor_DefWriteHeader - Write failed"); return JE_FALSE;}
- #ifdef COUNT_HEADER_SIZES
- Header_Sizes += 16;
- #endif
- return JE_TRUE;
- }
-
- JETAPI jeActor_Def *JETCC jeActor_DefCreateFromFile(jeVFile *pFile)
- {
- int i;
- jeActor_Def *Ad = NULL;
- jeVFile *VFile = NULL;
- jeVFile *SubFile = NULL;
- jeVFile *MotionDirectory = NULL;
- jeBoolean HasBody = JE_FALSE;
- jeBody * Body = NULL;
-
- assert( pFile != NULL );
- VFile = jeVFile_OpenNewSystem(pFile,JE_VFILE_TYPE_VIRTUAL, NULL,
- NULL, JE_VFILE_OPEN_DIRECTORY | JE_VFILE_OPEN_READONLY);
- if (VFile == NULL)
- { jeErrorLog_Add( JE_ERR_FILEIO_OPEN , "jeActor_DefCreateFromFile - Failed to open actor vfile system"); goto CreateError;}
-
- SubFile = jeVFile_Open(VFile,JE_ACTOR_HEADER_NAME,JE_VFILE_OPEN_READONLY);
- if (SubFile == NULL)
- { jeErrorLog_Add( JE_ERR_FILEIO_OPEN , "jeActor_DefCreateFromFile - Failed to open header subfile"); goto CreateError;}
- #if 1
- {
- jeVFile * HFile;
- HFile = jeVFile_GetHintsFile(SubFile);
- if ( ! HFile ) // <> backwards compatibility
- HFile = SubFile;
- Ad = jeActor_DefCreateHeader(HFile, &HasBody);
- }
- #else
- Ad = jeActor_DefCreateHeader( SubFile, &HasBody);
- #endif
- if (Ad == NULL)
- {
- jeErrorLog_Add( JE_ERR_SUBSYSTEM_FAILURE, "jeActor_DefCreateFromFile -");
- goto CreateError;
- }
- if (!jeVFile_Close(SubFile))
- {
- jeErrorLog_Add( JE_ERR_FILEIO_CLOSE ,"jeActor_DefCreateFromFile - Failed to close header subfile");
- goto CreateError;
- }
-
- Ad->TextureFileContext = VFile;
- assert(Ad->TextureFileContext);
- if (HasBody != JE_FALSE)
- {
- SubFile = jeVFile_Open(VFile,JE_ACTOR_BODY_NAME,JE_VFILE_OPEN_READONLY);
- if (SubFile == NULL)
- { jeErrorLog_Add( JE_ERR_FILEIO_READ , "jeActor_DefCreateFromFile - Read failed"); goto CreateError;}
- Body = jeBody_CreateFromFile(SubFile);
- if (Body == NULL)
- {
- jeErrorLog_Add( JE_ERR_FILEIO_READ , "jeActor_DefCreateFromFile - Read failed");
- goto CreateError;
- }
- if (jeActor_SetBody(Ad,Body)==JE_FALSE)
- {
- jeErrorLog_Add( JE_ERR_SUBSYSTEM_FAILURE, "jeActor_DefCreateFromFile -");
- goto CreateError;
- }
- jeVFile_Close(SubFile);
- }
- MotionDirectory = jeVFile_Open(VFile,JE_MOTION_DIRECTORY_NAME,
- JE_VFILE_OPEN_DIRECTORY | JE_VFILE_OPEN_READONLY);
- if (MotionDirectory == NULL)
- { jeErrorLog_Add( JE_ERR_SUBSYSTEM_FAILURE,"jeActor_DefCreateFromFile -"); return NULL;}
- if (Ad->MotionCount>0)
- {
- Ad->MotionArray = JE_RAM_ALLOCATE_ARRAY( jeMotion*, Ad->MotionCount);
- if (Ad->MotionArray == NULL)
- { jeErrorLog_Add( JE_ERR_MEMORY_RESOURCE,"jeActor_DefCreateFromFile - Failed to allocate motion array"); return NULL; }
- for (i=0; i<Ad->MotionCount; i++)
- Ad->MotionArray[i] = NULL;
-
- for (i=0; i<Ad->MotionCount; i++)
- {
- char FName[1000];
- sprintf(FName,"%d",i);
- SubFile = jeVFile_Open(MotionDirectory,FName,JE_VFILE_OPEN_READONLY);
- if (SubFile == NULL)
- { jeErrorLog_Add( JE_ERR_FILEIO_OPEN ,"jeActor_DefCreateFromFile - Failed to open motion subdirectory"); goto CreateError;}
- #if 0
- Ad->MotionArray[i] = jeMotion_CreateFromFile(SubFile);
- #else
- {
- jeVFile * LZFS;
- LZFS = jeVFile_OpenNewSystem(SubFile,JE_VFILE_TYPE_LZ, NULL, NULL,JE_VFILE_OPEN_READONLY);
-
- if ( !LZFS )
- { jeErrorLog_Add( JE_ERR_FILEIO_OPEN ,"jeActor_DefCreateFromFile - Failed to open compressed vfile"); goto CreateError;}
-
- Ad->MotionArray[i] = jeMotion_CreateFromFile(LZFS);
- Log_Printf("Actor : Motions : ");
- if ( ! jeVFile_Close(LZFS) )
- { jeErrorLog_Add( JE_ERR_FILEIO_CLOSE ,"jeActor_DefCreateFromFile - Failed to close compressed vfile"); goto CreateError;}
- }
- #endif
- if (Ad->MotionArray[i] == NULL)
- { jeErrorLog_AddString( JE_ERR_SUBSYSTEM_FAILURE,"jeActor_DefCreateFromFile - Failed to read motion #",jeErrorLog_IntToString(i)); goto CreateError;}
- if (!jeVFile_Close(SubFile) )
- { jeErrorLog_Add( JE_ERR_FILEIO_CLOSE ,"jeActor_DefCreateFromFile - Failed to close sub motion file"); goto CreateError;}
- }
- }
- else
- {
- Ad->MotionArray = NULL;
- }
- if (!jeVFile_Close(MotionDirectory))
- { jeErrorLog_Add( JE_ERR_FILEIO_CLOSE ,"jeActor_DefCreateFromFile - Failed to close motion directory"); goto CreateError;}
- if (!jeVFile_Close(VFile))
- { jeErrorLog_Add( JE_ERR_FILEIO_CLOSE ,"jeActor_DefCreateFromFile - Failed to close actor vfile system"); goto CreateError;}
- return Ad;
- CreateError:
- if (SubFile != NULL)
- jeVFile_Close(SubFile);
- if (MotionDirectory != NULL)
- jeVFile_Close(MotionDirectory);
- if (VFile != NULL)
- jeVFile_Close(VFile);
- if (Ad != NULL)
- jeActor_DefDestroy(&Ad);
- return NULL;
- }
- JETAPI jeBoolean JETCC jeActor_DefWriteToFile(const jeActor_Def *Ad, jeVFile *pFile)
- {
- int i;
- jeVFile *VFile;
- jeVFile *SubFile;
- jeVFile *MotionDirectory;
- assert( jeActor_DefIsValid(Ad) != JE_FALSE );
- assert( pFile != NULL );
- VFile = jeVFile_OpenNewSystem(pFile,JE_VFILE_TYPE_VIRTUAL, NULL,
- NULL, JE_VFILE_OPEN_DIRECTORY | JE_VFILE_OPEN_CREATE);
- if (VFile == NULL)
- { jeErrorLog_Add( JE_ERR_FILEIO_OPEN , "jeActor_DefWriteToFile - Failed to open actor vfile system"); goto WriteError;}
-
- SubFile = jeVFile_Open(VFile,JE_ACTOR_HEADER_NAME,JE_VFILE_OPEN_CREATE);
- if (SubFile == NULL)
- { jeErrorLog_Add( JE_ERR_FILEIO_OPEN , "jeActor_DefWriteToFile - Failed to open actor header subfile"); goto WriteError;}
- #if 1
- {
- jeVFile * HFile;
- HFile = jeVFile_GetHintsFile(SubFile);
- if (jeActor_DefWriteHeader(Ad,HFile)==JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_WRITE , "jeActor_DefWriteToFile - Failed to write hints"); goto WriteError;}
- }
- #else
- if (jeActor_DefWriteHeader(Ad,SubFile)==JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_WRITE , "jeActor_DefWriteToFile - Failed to write header"); goto WriteError;}
- #endif
- if (jeVFile_Close(SubFile)==JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_CLOSE , "jeActor_DefWriteToFile - Failed to close header"); goto WriteError;}
- if (Ad->Body != NULL)
- {
- SubFile = jeVFile_Open(VFile,JE_ACTOR_BODY_NAME,JE_VFILE_OPEN_CREATE);
- if (SubFile == NULL)
- { jeErrorLog_Add( JE_ERR_FILEIO_WRITE , "jeActor_DefWriteToFile - Failed to open body subfile"); goto WriteError;}
- if (jeBody_WriteToFile(Ad->Body,SubFile)==JE_FALSE)
- { jeErrorLog_Add( JE_ERR_SUBSYSTEM_FAILURE , "jeActor_DefWriteToFile - Failed to write body"); goto WriteError;}
- if (jeVFile_Close(SubFile)==JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_CLOSE , "jeActor_DefWriteToFile - Failed to close body subfile"); goto WriteError;}
- }
- MotionDirectory = jeVFile_Open(VFile,JE_MOTION_DIRECTORY_NAME,
- JE_VFILE_OPEN_DIRECTORY | JE_VFILE_OPEN_CREATE);
- if (MotionDirectory == NULL)
- { jeErrorLog_Add( JE_ERR_FILEIO_OPEN , "jeActor_DefWriteToFile - Failed to open motion subdirectory"); goto WriteError;}
-
- // <> CB note : could save some by combining these motions in one LZ file
- for (i=0; i<Ad->MotionCount; i++)
- {
- char FName[1000];
- sprintf(FName,"%d",i);
- SubFile = jeVFile_Open(MotionDirectory,FName,JE_VFILE_OPEN_CREATE);
- if (SubFile == NULL)
- { jeErrorLog_Add( JE_ERR_FILEIO_OPEN , "jeActor_DefWriteToFile - Failed to open motion subfile"); goto WriteError;}
- #if 0 //{
- if (jeMotion_WriteToFile(Ad->MotionArray[i],SubFile)==JE_FALSE)
- { jeErrorLog_AddString( JE_ERR_SUBSYSTEM_FAILURE , "jeActor_DefWriteToFile - Failed to write motion"); goto WriteError;}
- #else //}{
- {
- jeVFile * LZFS;
- LZFS = jeVFile_OpenNewSystem(SubFile,JE_VFILE_TYPE_LZ, NULL, NULL, JE_VFILE_OPEN_CREATE);
- if ( ! LZFS )
- { jeErrorLog_Add( JE_ERR_FILEIO_OPEN , "jeActor_DefWriteToFile - Failed to open compressed system"); goto WriteError;}
- if (jeMotion_WriteToFile(Ad->MotionArray[i],LZFS)==JE_FALSE)
- { jeErrorLog_Add( JE_ERR_SUBSYSTEM_FAILURE , "jeActor_DefWriteToFile - Failed to write motion"); goto WriteError;}
- if ( ! jeVFile_Close(LZFS) )
- { jeErrorLog_Add( JE_ERR_FILEIO_CLOSE , "jeActor_DefWriteToFile - Failed to close compressed system"); goto WriteError;}
- }
- #endif //}
- if (jeVFile_Close(SubFile)==JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_WRITE , "jeActor_DefWriteToFile - Failed to close motion subfile"); goto WriteError;}
- }
- if (jeVFile_Close(MotionDirectory)==JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_WRITE , "jeActor_DefWriteToFile - Failed to close motion subdirectory"); goto WriteError;}
- if (jeVFile_Close(VFile)==JE_FALSE)
- { jeErrorLog_Add( JE_ERR_FILEIO_WRITE , "jeActor_DefWriteToFile - Failed to close actor subsystem"); goto WriteError;}
-
- return JE_TRUE;
- WriteError:
- return JE_FALSE;
- }
- JETAPI jeBoolean JETCC jeActor_GetBoneTransform(const jeActor *A, const char *BoneName, jeXForm3d *Transform)
- {
- int BoneIndex;
- assert( jeActor_IsValid(A)!=JE_FALSE );
- assert( Transform!= NULL );
-
- if (jeActor_GetBoneIndex(A,BoneName,&BoneIndex)==JE_FALSE)
- {
- jeErrorLog_AddString(JE_ERR_SUBSYSTEM_FAILURE,"jeActor_GetBoneTransform: Named bone not found", BoneName);
- return JE_FALSE;
- }
- jePose_GetJointTransform( A->Pose, BoneIndex, Transform);
- assert ( jeXForm3d_IsOrthonormal(Transform) != JE_FALSE );
- return JE_TRUE;
- }
- static void JETCF jeActor_AccumulateMinMax(
- jeVec3d *P,jeVec3d *Mins,jeVec3d *Maxs)
- {
- assert( jeVec3d_IsValid( P ) != JE_FALSE );
- assert( jeVec3d_IsValid(Mins) != JE_FALSE );
- assert( jeVec3d_IsValid(Maxs) != JE_FALSE );
-
- if (P->X < Mins->X) Mins->X = P->X;
- if (P->Y < Mins->Y) Mins->Y = P->Y;
- if (P->Z < Mins->Z) Mins->Z = P->Z;
- if (P->X > Maxs->X) Maxs->X = P->X;
- if (P->Y > Maxs->Y) Maxs->Y = P->Y;
- if (P->Z > Maxs->Z) Maxs->Z = P->Z;
- }
- static jeBoolean JETCF jeActor_GetBoneBoundingBoxByIndex(
- const jeActor *A,
- int BoneIndex,
- jeVec3d *Corner,
- jeVec3d *DX,
- jeVec3d *DY,
- jeVec3d *DZ)
- {
- jeVec3d Min,Max;
- jeVec3d Orientation;
- jeXForm3d Transform;
-
- assert( jeActor_IsValid(A) != JE_FALSE );
- assert( jeActor_DefIsValid(A->ActorDefinition) != JE_FALSE );
- assert( A->ActorDefinition->Body != NULL );
- assert( Corner );
- assert( DX );
- assert( DY );
- assert( DZ );
- assert( (BoneIndex < jePose_GetJointCount(A->Pose)) || (BoneIndex ==JE_POSE_ROOT_JOINT));
- assert( (BoneIndex >=0) || (BoneIndex ==JE_POSE_ROOT_JOINT));
-
- if (jeBody_GetBoundingBox( A->ActorDefinition->Body, BoneIndex, &Min, &Max )==JE_FALSE)
- {
- // not probably a real error. It's possible that the bone has no geometry, so it
- // has no bounding box.
- return JE_FALSE;
- }
- // scale bounding box:
- {
- jeVec3d Scale;
- jePose_GetScale(A->Pose, &Scale);
- assert( jeVec3d_IsValid(&Scale) != JE_FALSE );
- Min.X *= Scale.X;
- Min.Y *= Scale.Y;
- Min.Z *= Scale.Z;
-
- Max.X *= Scale.X;
- Max.Y *= Scale.Y;
- Max.Z *= Scale.Z;
- }
- jePose_GetJointTransform(A->Pose,BoneIndex,&(Transform));
- jeVec3d_Subtract(&Max,&Min,&Orientation);
-
- DX->X = Orientation.X; DX->Y = DX->Z = 0.0f;
- DY->Y = Orientation.Y; DY->X = DY->Z = 0.0f;
- DZ->Z = Orientation.Z; DZ->X = DZ->Y = 0.0f;
-
- // transform into world space
- jeXForm3d_Transform(&(Transform),&Min,&Min);
- jeXForm3d_Rotate(&(Transform),DX,DX);
- jeXForm3d_Rotate(&(Transform),DY,DY);
- jeXForm3d_Rotate(&(Transform),DZ,DZ);
- *Corner = Min;
- return JE_TRUE;
- }
- static jeBoolean JETCF jeActor_GetBoneExtBoxByIndex(
- const jeActor *A,
- int BoneIndex,
- jeExtBox *ExtBox)
- {
- jeVec3d Min;
- jeVec3d DX,DY,DZ,Corner;
- assert( ExtBox );
-
- if (jeActor_GetBoneBoundingBoxByIndex(A,BoneIndex,&Min,&DX,&DY,&DZ)==JE_FALSE)
- {
- // Commented out by Incarnadine: This happens frequently when dealing
- // with boned objects if a bone has no geometry (like any physiqued object
- // with BIP01). It was slowing things down to make this call several times / tick.
- //jeErrorLog_Add(JE_ERR_BAD_PARAMETER,"jeActor_GetBoneExtBoxByIndex - ");
- return JE_FALSE;
- }
- ExtBox->Min = Min;
- ExtBox->Max = Min;
- Corner = Min;
- // should use extent box (extbox) methods rather than this
- jeVec3d_Add(&Corner,&DX,&Corner);
- jeActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
- jeVec3d_Add(&Corner,&DZ,&Corner);
- jeActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
- jeVec3d_Subtract(&Corner,&DX,&Corner);
- jeActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
- jeVec3d_Add(&Corner,&DY,&Corner);
- jeActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
- jeVec3d_Add(&Corner,&DX,&Corner);
- jeActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
- jeVec3d_Subtract(&Corner,&DZ,&Corner);
- jeActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
- jeVec3d_Subtract(&Corner,&DX,&Corner);
- jeActor_AccumulateMinMax(&Corner,&(ExtBox->Min),&(ExtBox->Max));
- return JE_TRUE;
- }
- JETAPI jeBoolean JETCC jeActor_GetBoneExtBox(const jeActor *A,
- const char *BoneName,
- jeExtBox *ExtBox)
- {
- int BoneIndex;
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( ExtBox != NULL );
-
- if (jeActor_GetBoneIndex(A,BoneName,&BoneIndex)==JE_FALSE)
- {
- jeErrorLog_AddString(JE_ERR_SUBSYSTEM_FAILURE,"jeActor_GetBoneExtBox: Named bone for bounding box not found: ", BoneName);
- return JE_FALSE;
- }
- return jeActor_GetBoneExtBoxByIndex(A,BoneIndex,ExtBox);
- }
- JETAPI jeBoolean JETCC jeActor_GetBoneBoundingBox(const jeActor *A,
- const char *BoneName,
- jeVec3d *Corner,
- jeVec3d *DX,
- jeVec3d *DY,
- jeVec3d *DZ)
- {
- int BoneIndex;
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( Corner != NULL );
- assert( DX != NULL );
- assert( DY != NULL );
- assert( DZ != NULL );
- if (jeActor_GetBoneIndex(A,BoneName,&BoneIndex)==JE_FALSE)
- {
- jeErrorLog_AddString(JE_ERR_SUBSYSTEM_FAILURE,"jeActor_GetBoneBoundingBox - Named bone for bounding box not found: ", BoneName);
- return JE_FALSE;
- }
- if (jeActor_GetBoneBoundingBoxByIndex(A,BoneIndex,Corner,DX,DY,DZ)==JE_FALSE)
- {
- jeErrorLog_AddString(JE_ERR_SUBSYSTEM_FAILURE,"jeActor_GetBoneBoundingBox - Failed to get bounding box named: ", BoneName);
- //jeErrorLog_AppendString(BoneName);
- return JE_FALSE;
- }
- return JE_TRUE;
- }
- JETAPI jeBoolean JETCC jeActor_GetExtBox(const jeActor *A, jeExtBox *ExtBox)
- {
- jeXForm3d Transform;
-
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( ExtBox != NULL );
-
- jePose_GetJointTransform( A->Pose,
- A->BoundingBoxCenterBoneIndex,
- &Transform);
- assert ( jeXForm3d_IsOrthonormal(&Transform) != JE_FALSE );
- jeVec3d_Add( &(Transform.Translation), &(A->CollisionExtBox.Min), &(ExtBox->Min));
- jeVec3d_Add( &(Transform.Translation), &(A->CollisionExtBox.Max), &(ExtBox->Max));
- return JE_TRUE;
- }
- JETAPI jeBoolean JETCC jeActor_SetExtBox(jeActor *A,
- const jeExtBox *ExtBox,
- const char *CenterOnThisNamedBone)
- {
-
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( jeExtBox_IsValid(ExtBox) != JE_FALSE);
-
- A->CollisionExtBox.Min = ExtBox->Min;
- A->CollisionExtBox.Max = ExtBox->Max;
-
- if (jeActor_GetBoneIndex(A,CenterOnThisNamedBone,&(A->BoundingBoxCenterBoneIndex))==JE_FALSE)
- {
- jeErrorLog_AddString(JE_ERR_SUBSYSTEM_FAILURE,"jeActor_SetExtBox: Named bone for bounding box not found ", CenterOnThisNamedBone);
- return JE_FALSE;
- }
-
- return JE_TRUE;
- }
- // Gets the rendering hint bounding box from the actor
- JETAPI jeBoolean JETCC jeActor_GetRenderHintExtBox(const jeActor *A, jeExtBox *Box, jeBoolean *Enabled)
- {
- jeXForm3d Transform;
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( Box != NULL );
- assert( Enabled != NULL );
- jePose_GetJointTransform( A->Pose,
- A->RenderHintExtBoxCenterBoneIndex,
- &Transform);
- assert ( jeXForm3d_IsOrthonormal(&Transform) != JE_FALSE );
- *Box = A->RenderHintExtBox;
- jeExtBox_Translate ( Box, Transform.Translation.X,
- Transform.Translation.Y,
- Transform.Translation.Z );
-
- *Enabled = A->RenderHintExtBoxEnabled;
- return JE_TRUE;
- }
- // Sets a rendering hint bounding box from the actor
- JETAPI jeBoolean JETCC jeActor_SetRenderHintExtBox(jeActor *A, const jeExtBox *Box,
- const char *CenterOnThisNamedBone)
- {
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( Box != NULL );
- assert( Box->Max.X >= Box->Min.X );
- assert( Box->Max.Y >= Box->Min.Y );
- assert( Box->Max.Z >= Box->Min.Z );
-
- if (jeActor_GetBoneIndex(A,CenterOnThisNamedBone,&(A->RenderHintExtBoxCenterBoneIndex))==JE_FALSE)
- {
- jeErrorLog_AddString(JE_ERR_SUBSYSTEM_FAILURE,"jeActor_SetRenderHintExtBox: Named bone for render hint box not found: ", CenterOnThisNamedBone);
- return JE_FALSE;
- }
-
- A->RenderHintExtBox = *Box;
- if ( (Box->Min.X == 0.0f) && (Box->Max.X == 0.0f)
- && (Box->Min.Y == 0.0f) && (Box->Max.Y == 0.0f)
- && (Box->Min.Z == 0.0f) && (Box->Max.Z == 0.0f) )
- {
- A->RenderHintExtBoxEnabled = JE_FALSE;
- }
- else
- {
- A->RenderHintExtBoxEnabled = JE_TRUE;
- }
- return JE_TRUE;
- }
- JETAPI void *JETCC jeActor_GetUserData(const jeActor *A)
- {
- assert( jeActor_IsValid(A) != JE_FALSE);
- return A->UserData;
- }
- JETAPI void JETCC jeActor_SetUserData(jeActor *A, void *UserData)
- {
- assert( jeActor_IsValid(A) != JE_FALSE);
- A->UserData = UserData;
- }
- #define MAX(aa,bb) ( (aa)>(bb)?(aa):(bb) )
- #define MIN(aa,bb) ( (aa)<(bb)?(aa):(bb) )
- static void JETCF jeActor_StretchBoundingBox( jeVec3d *Min, jeVec3d *Max,
- const jeVec3d *Corner,
- const jeVec3d *DX, const jeVec3d *DY, const jeVec3d *DZ)
- {
- jeVec3d P;
- P = *Corner;
- Min->X = MIN(Min->X,P.X), Min->Y = MIN(Min->Y,P.Y), Min->Z = MIN(Min->Z,P.Z);
- Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
- jeVec3d_Add (Corner ,DX,&P);
- Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
- Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
- jeVec3d_Add (&P, DZ,&P);
- Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
- Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
- jeVec3d_Subtract(&P,DX,&P);
- Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
- Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
- jeVec3d_Add (&P,DY,&P);
- Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
- Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
- jeVec3d_Add (&P,DX,&P);
- Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
- Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
- jeVec3d_Subtract(&P,DZ,&P);
- Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
- Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
- jeVec3d_Subtract(&P,DX,&P);
- Min->X = MIN(Min->X,P.X); Min->Y = MIN(Min->Y,P.Y); Min->Z = MIN(Min->Z,P.Z);
- Max->X = MAX(Max->X,P.X); Max->Y = MAX(Max->Y,P.Y); Max->Z = MAX(Max->Z,P.Z);
- }
- JETAPI jeBoolean JETCC jeActor_GetDynamicExtBox( const jeActor *A, jeExtBox *ExtBox)
- {
- #define JE_ACTOR_REALLY_BIG_NUMBER (9e9f)
- jeVec3d Corner;
- jeVec3d DX;
- jeVec3d DY;
- jeVec3d DZ;
- int Count,i,BCount;
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( A->ActorDefinition->Body != NULL );
- jeVec3d_Set(&(ExtBox->Min),
- JE_ACTOR_REALLY_BIG_NUMBER,JE_ACTOR_REALLY_BIG_NUMBER,JE_ACTOR_REALLY_BIG_NUMBER);
- jeVec3d_Set(&(ExtBox->Max),
- -JE_ACTOR_REALLY_BIG_NUMBER,-JE_ACTOR_REALLY_BIG_NUMBER,-JE_ACTOR_REALLY_BIG_NUMBER);
-
- BCount = 0;
- Count = jeBody_GetBoneCount( A->ActorDefinition->Body );
- for (i=0; i< Count; i++)
- {
- if (jeActor_GetBoneBoundingBoxByIndex(A,i,&Corner,&DX,&DY,&DZ)!=JE_FALSE)
- {
- jeActor_StretchBoundingBox( &(ExtBox->Min),
- &(ExtBox->Max),&Corner,&DX,&DY,&DZ);
- BCount ++;
- }
- }
- if (BCount>0)
- {
- return JE_TRUE;
- }
- return JE_FALSE;
- }
- JETAPI jeBoolean JETCC jeActor_Attach( jeActor *Slave, const char *SlaveBoneName,
- const jeActor *Master, const char *MasterBoneName,
- const jeXForm3d *Attachment)
- {
- int SlaveBoneIndex,MasterBoneIndex;
- assert( jeActor_IsValid(Slave) != JE_FALSE);
- assert( jeActor_IsValid(Master) != JE_FALSE);
- assert( jeXForm3d_IsOrthonormal(Attachment) != JE_FALSE );
-
- assert( MasterBoneName != NULL ); // might this be possible?
-
- if (jeActor_GetBoneIndex(Slave,SlaveBoneName,&(SlaveBoneIndex))==JE_FALSE)
- {
- jeErrorLog_AddString(JE_ERR_SUBSYSTEM_FAILURE,"jeActor_Attach: Named bone for slave not found: ", SlaveBoneName);
- return JE_FALSE;
- }
-
- if (jeActor_GetBoneIndex(Master,MasterBoneName,&(MasterBoneIndex))==JE_FALSE)
- {
- jeErrorLog_AddString(JE_ERR_SUBSYSTEM_FAILURE,"Named bone for master not found: ", MasterBoneName);
- return JE_FALSE;
- }
-
- return jePose_Attach( Slave->Pose, SlaveBoneIndex,
- Master->Pose, MasterBoneIndex,
- Attachment);
- }
- JETAPI void JETCC jeActor_Detach(jeActor *A)
- {
- assert( jeActor_IsValid(A) != JE_FALSE);
- jePose_Detach( A->Pose );
- }
- JETAPI jeBoolean JETCC jeActor_GetBoneAttachment(const jeActor *A,
- const char *BoneName,
- jeXForm3d *Attachment)
- {
- int BoneIndex;
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( Attachment != NULL );
-
- if (jeActor_GetBoneIndex(A,BoneName,&(BoneIndex))==JE_FALSE)
- {
- jeErrorLog_AddString(JE_ERR_SUBSYSTEM_FAILURE,"jeActor_GetBoneAttachment: Named bone not found: ", BoneName);
- return JE_FALSE;
- }
-
- jePose_GetJointAttachment(A->Pose,BoneIndex, Attachment);
- assert ( jeXForm3d_IsOrthonormal(Attachment) != JE_FALSE );
- return JE_TRUE;
- }
- JETAPI jeBoolean JETCC jeActor_SetBoneAttachment(jeActor *A,
- const char *BoneName,
- jeXForm3d *Attachment)
- {
- int BoneIndex;
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( jeXForm3d_IsOrthonormal(Attachment) != JE_FALSE );
-
- if (jeActor_GetBoneIndex(A,BoneName,&(BoneIndex))==JE_FALSE)
- {
- jeErrorLog_AddString(JE_ERR_SUBSYSTEM_FAILURE,"jeActor_SetBoneAttachment: Named bone not found: ", BoneName);
- return JE_FALSE;
- }
-
- jePose_SetJointAttachment(A->Pose,BoneIndex, Attachment);
- return JE_TRUE;
- }
- //-------------------------------------------------------------------------------------------------
- // Actor Cuing system
- //-------------------------------------------------------------------------------------------------
- #define ACTOR_CUE_MINIMUM_BLEND (0.0001f)
- #define ACTOR_CUE_MAXIMUM_BLEND (0.999f)
- static jeBoolean JETCF jeActor_IsAnimationCueDead(jeActor *A, int Index)
- {
- jeBoolean Kill= JE_FALSE;
- jeFloat BlendAmount;
- jeMotion *M;
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( (Index>=0) && (Index<jeMotion_GetSubMotionCount(A->CueMotion)));
- M = A->CueMotion;
- BlendAmount = jeMotion_GetBlendAmount(M,Index,0.0f);
- if (BlendAmount <= ACTOR_CUE_MINIMUM_BLEND)
- {
- int KeyCount;
- jePath *P;
- jeFloat KeyTime;
- P = jeMotion_GetBlendPath(M,Index);
- assert( P != NULL );
- KeyCount = jePath_GetKeyframeCount(P,JE_PATH_TRANSLATION_CHANNEL);
- if (KeyCount>0)
- {
- jeXForm3d Dummy;
- jeFloat TimeOffset = -jeMotion_GetTimeOffset( M, Index);
- jePath_GetKeyframe( P, KeyCount-1, JE_PATH_TRANSLATION_CHANNEL, &KeyTime, &Dummy );
-
- if ( KeyTime <= TimeOffset )
- {
- Kill = JE_TRUE;
- }
- }
- else
- {
- Kill = JE_TRUE;
- }
- }
- return Kill;
- }
- static void JETCF jeActor_KillCue( jeActor *A, int Index )
- {
- jeMotion *M;
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( (Index>=0) && (Index<jeMotion_GetSubMotionCount(A->CueMotion)));
- M = jeMotion_RemoveSubMotion(A->CueMotion,Index);
- }
- JETAPI jeBoolean JETCC jeActor_AnimationNudge(jeActor *A, jeXForm3d *Offset)
- {
- jeMotion *M;
- int i,Count;
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( jeXForm3d_IsOrthonormal(Offset) != JE_FALSE );
- M = A->CueMotion;
- Count = jeMotion_GetSubMotionCount(M);
-
- for (i=Count-1; i>=0; i--)
- {
- jeXForm3d Transform;
- const jeXForm3d *pTransform;
- pTransform = jeMotion_GetBaseTransform( M, i );
- if ( pTransform != NULL )
- {
- Transform = *pTransform;
-
- jeXForm3d_Multiply(Offset,&Transform,&Transform);
- jeXForm3d_Orthonormalize(&Transform);
- jeMotion_SetBaseTransform( M, i, &Transform);
- }
- }
- return JE_TRUE;
- }
- JETAPI jeBoolean JETCC jeActor_AnimationRemoveLastCue( jeActor *A )
- {
- int Count;
- assert( jeActor_IsValid(A) != JE_FALSE);
- Count = jeMotion_GetSubMotionCount(A->CueMotion);
- if (Count>0)
- {
- jeActor_KillCue( A, Count-1 );
- return JE_TRUE;
- }
- return JE_FALSE;
- }
- JETAPI jeBoolean JETCC jeActor_AnimationCue( jeActor *A,
- jeMotion *Motion,
- jeFloat TimeScaleFactor,
- jeFloat TimeIntoMotion,
- jeFloat BlendTime,
- jeFloat BlendFromAmount,
- jeFloat BlendToAmount,
- const jeXForm3d *MotionTransform)
- {
- int Index;
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( (BlendFromAmount>=0.0f) && (BlendFromAmount<=1.0f));
- assert( ( BlendToAmount>=0.0f) && ( BlendToAmount<=1.0f));
- assert( (MotionTransform==NULL) || (jeXForm3d_IsOrthonormal(MotionTransform)) != JE_FALSE );
- assert( Motion != NULL );
-
- assert( BlendTime >= 0.0f);
- if (BlendTime==0.0f)
- {
- BlendFromAmount = BlendToAmount;
- BlendTime = 1.0f; // anything that is > JE_TKA_TIME_TOLERANCE
- }
- if (jeMotion_AddSubMotion( A->CueMotion, TimeScaleFactor, -TimeIntoMotion, Motion,
- TimeIntoMotion, BlendFromAmount,
- TimeIntoMotion + BlendTime, BlendToAmount,
- MotionTransform, &Index )==JE_FALSE)
- {
- return JE_FALSE;
- }
-
- return JE_TRUE;
- }
- JETAPI jeBoolean JETCC jeActor_AnimationStep(jeActor *A, jeFloat DeltaTime )
- {
- int i,Coverage,Count;
- jeMotion *M;
- jeMotion *SubM;
-
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( DeltaTime >= 0.0f );
-
- jePose_ClearCoverage(A->Pose,0);
- M = A->CueMotion;
- Count = jeMotion_GetSubMotionCount(M);
- for (i=Count-1; i>=0; i--)
- {
- jeFloat TimeOffset = jeMotion_GetTimeOffset( M, i );
- TimeOffset = TimeOffset - DeltaTime;
- jeMotion_SetTimeOffset( M, i, TimeOffset);
- if (jeActor_IsAnimationCueDead(A,i))
- {
- jeActor_KillCue(A,i);
- }
- else
- {
- jeBoolean SetWithBlending= JE_TRUE;
- jeFloat BlendAmount;
-
- SubM = jeMotion_GetSubMotion(M,i);
- assert( SubM != NULL );
-
- BlendAmount = jeMotion_GetBlendAmount( M,i,0.0f );
-
- if (BlendAmount >= ACTOR_CUE_MAXIMUM_BLEND)
- {
- SetWithBlending = JE_FALSE;
- }
- Coverage = jePose_AccumulateCoverage(A->Pose,SubM, SetWithBlending);
- if ( Coverage == 0 )
- {
- jeActor_KillCue(A,i);
- }
- }
- }
- jePose_SetMotion( A->Pose, M, 0.0f, NULL );
- jeMotion_SetupEventIterator(M,-DeltaTime,0.0f);
- return JE_TRUE;
- }
- JETAPI jeBoolean JETCC jeActor_AnimationStepBoneOptimized(jeActor *A, jeFloat DeltaTime, const char *BoneName )
- {
- int i,Coverage,Count;
- jeMotion *M;
- jeMotion *SubM;
-
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( DeltaTime >= 0.0f );
-
- if (BoneName == NULL)
- {
- A->StepBoneIndex = JE_POSE_ROOT_JOINT;
- }
- else
- {
- jeBoolean LookupBoneName= JE_TRUE;
- const char *LastBoneName;
- jeXForm3d Attachment;
- int LastParentBoneIndex;
- if (A->StepBoneIndex >= 0)
- {
- jeBody_GetBone( A->ActorDefinition->Body,A->StepBoneIndex,&LastBoneName,&Attachment,&LastParentBoneIndex);
- if ( (LastBoneName != NULL) )
- if (_stricmp(LastBoneName,BoneName)==0) // Case insensitive compare -- Incarnadine
- LookupBoneName = JE_FALSE;
- }
- if (LookupBoneName != JE_FALSE)
- {
- if (jeActor_GetBoneIndex(A,BoneName,&(A->StepBoneIndex))==JE_FALSE)
- {
- jeErrorLog_AddString(JE_ERR_SUBSYSTEM_FAILURE,"jeActor_AnimationStepBoneOptimized: Named bone not found: ", BoneName);
- return JE_FALSE;
- }
- }
- }
-
- jePose_ClearCoverage(A->Pose,0);
- M = A->CueMotion;
- Count = jeMotion_GetSubMotionCount(M);
- for (i=Count-1; i>=0; i--)
- {
- jeFloat TimeOffset = jeMotion_GetTimeOffset( M, i );
- TimeOffset = TimeOffset - DeltaTime;
- jeMotion_SetTimeOffset( M, i, TimeOffset);
- if (jeActor_IsAnimationCueDead(A,i))
- {
- jeActor_KillCue(A,i);
- }
- else
- {
- jeBoolean SetWithBlending= JE_TRUE;
- jeFloat BlendAmount;
-
- SubM = jeMotion_GetSubMotion(M,i);
- assert( SubM != NULL );
-
- BlendAmount = jeMotion_GetBlendAmount( M,i,0.0f );
-
- if (BlendAmount >= ACTOR_CUE_MAXIMUM_BLEND)
- {
- SetWithBlending = JE_FALSE;
- }
- Coverage = jePose_AccumulateCoverage(A->Pose,SubM, SetWithBlending);
- if ( Coverage == 0 )
- {
- jeActor_KillCue(A,i);
- }
- }
- }
- jePose_SetMotionForABone( A->Pose, M, 0.0f, NULL, A->StepBoneIndex );
- jeMotion_SetupEventIterator(M,-DeltaTime,0.0f);
- return JE_TRUE;
- }
-
- JETAPI jeBoolean JETCC jeActor_AnimationTestStep(jeActor *A, jeFloat DeltaTime)
- {
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( DeltaTime >= 0.0f );
- jePose_SetMotion( A->Pose, A->CueMotion , DeltaTime, NULL );
- return JE_TRUE;
- }
- JETAPI jeBoolean JETCC jeActor_AnimationTestStepBoneOptimized(jeActor *A, jeFloat DeltaTime, const char *BoneName)
- {
- assert( jeActor_IsValid(A) != JE_FALSE);
- assert( DeltaTime >= 0.0f );
- if (BoneName == NULL)
- {
- A->StepBoneIndex = JE_POSE_ROOT_JOINT;
- }
- else
- {
- jeBoolean LookupBoneName= JE_TRUE;
- const char *LastBoneName;
- jeXForm3d Attachment;
- int LastParentBoneIndex;
- if (A->StepBoneIndex >= 0)
- {
- jeBody_GetBone( A->ActorDefinition->Body,A->StepBoneIndex,&LastBoneName,&Attachment,&LastParentBoneIndex);
- if ( (LastBoneName != NULL) )
- if (_stricmp(LastBoneName,BoneName)==0) // Case insensitive compare -- Incarnadine
- LookupBoneName = JE_FALSE;
- }
- if (LookupBoneName != JE_FALSE)
- {
- if (jeActor_GetBoneIndex(A,BoneName,&(A->StepBoneIndex))==JE_FALSE)
- {
- jeErrorLog_AddString(JE_ERR_SUBSYSTEM_FAILURE,"jeActor_AnimationTestStepBoneOptimized: Named bone not found:", BoneName);
- return JE_FALSE;
- }
- }
- }
- jePose_SetMotionForABone( A->Pose, A->CueMotion , DeltaTime, NULL,A->StepBoneIndex );
- return JE_TRUE;
- }
- JETAPI jeBoolean JETCC jeActor_GetAnimationEvent(
- jeActor *A,
- const char **ppEventString) // Return data, if found
- // returns the event string for the 'next' event that occured during the last
- // animation step time delta.
- // if the return value is JE_FALSE, there are no more events, and ppEventString will be Empty
- {
- jeFloat Time;
- assert( jeActor_IsValid(A) != JE_FALSE);
- return jeMotion_GetNextEvent(A->CueMotion, &Time, ppEventString );
- }
- JETAPI jeBoo…