00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <assert.h>
00023
00024 #include "body._h"
00025 #include "bodyinst.h"
00026 #include "ram.h"
00027 #include "errorlog.h"
00028 #include "strblock.h"
00029
00030
00031
00032 typedef struct geBodyInst
00033 {
00034 const geBody *BodyTemplate;
00035 geBodyInst_Geometry ExportGeometry;
00036 int LastLevelOfDetail;
00037 geBodyInst_Index FaceCount;
00038 } geBodyInst;
00039
00040
00041
00042 void GENESISCC geBodyInst_PostScale(const geXForm3d *M,const geVec3d *S,geXForm3d *Scaled)
00043 {
00044 Scaled->AX = M->AX * S->X;
00045 Scaled->BX = M->BX * S->X;
00046 Scaled->CX = M->CX * S->X;
00047
00048 Scaled->AY = M->AY * S->Y;
00049 Scaled->BY = M->BY * S->Y;
00050 Scaled->CY = M->CY * S->Y;
00051
00052 Scaled->AZ = M->AZ * S->Z;
00053 Scaled->BZ = M->BZ * S->Z;
00054 Scaled->CZ = M->CZ * S->Z;
00055 Scaled->Translation = M->Translation;
00056 }
00057
00058
00059 geBodyInst *GENESISCC geBodyInst_Create(const geBody *B)
00060 {
00061 geBodyInst *BI;
00062 assert( B != NULL );
00063 assert( geBody_IsValid(B) != GE_FALSE );
00064
00065 BI = GE_RAM_ALLOCATE_STRUCT(geBodyInst);
00066 if (BI == NULL)
00067 {
00068 geErrorLog_Add(ERR_BODY_ENOMEM, NULL);
00069 return NULL;
00070 }
00071 BI->BodyTemplate = B;
00072 {
00073 geBodyInst_Geometry *G = &(BI->ExportGeometry);
00074 G->SkinVertexCount =0;
00075 G->SkinVertexArray = NULL;
00076
00077 G->NormalCount = 0;
00078 G->NormalArray = NULL;
00079
00080 G->FaceCount = (geBody_Index) 0;
00081 G->FaceListSize = 0;
00082 G->FaceList = NULL;
00083 }
00084
00085 BI->LastLevelOfDetail = -1;
00086 BI->FaceCount = 0;
00087
00088 return BI;
00089 }
00090
00091
00092 void GENESISCC geBodyInst_Destroy( geBodyInst **BI)
00093 {
00094 geBodyInst_Geometry *G;
00095 assert( BI != NULL );
00096 assert( *BI != NULL );
00097 G = &( (*BI)->ExportGeometry );
00098 if (G->SkinVertexArray != NULL )
00099 {
00100 geRam_Free( G->SkinVertexArray );
00101 G->SkinVertexArray = NULL;
00102 }
00103 if (G->NormalArray != NULL )
00104 {
00105 geRam_Free( G->NormalArray );
00106 G->NormalArray = NULL;
00107 }
00108 if (G->FaceList != NULL )
00109 {
00110 geRam_Free( G->FaceList );
00111 G->FaceList = NULL;
00112 }
00113 geRam_Free( *BI );
00114 *BI = NULL;
00115 }
00116
00117
00118
00119 #define GE_BODYINST_FACELIST_SIZE_FOR_TRIANGLE (8)
00120
00121 static geBodyInst_Geometry *GENESISCC geBodyInst_GetGeometryPrep(
00122 geBodyInst *BI,
00123 int LevelOfDetail)
00124 {
00125 const geBody *B;
00126 geBodyInst_Geometry *G;
00127
00128 assert( BI != NULL );
00129 assert( geBody_IsValid(BI->BodyTemplate) != GE_FALSE );
00130 B = BI->BodyTemplate;
00131
00132 G = &(BI->ExportGeometry);
00133 assert( G != NULL );
00134
00135 if (G->SkinVertexCount != B->XSkinVertexCount)
00136 {
00137 if (G->SkinVertexArray!=NULL)
00138 {
00139 geRam_Free(G->SkinVertexArray);
00140 }
00141 G->SkinVertexArray = GE_RAM_ALLOCATE_ARRAY(geBodyInst_SkinVertex,B->XSkinVertexCount);
00142 if ( G->SkinVertexArray == NULL )
00143 {
00144 geErrorLog_Add(ERR_BODY_ENOMEM, NULL);
00145 G->SkinVertexCount = 0;
00146 return NULL;
00147 }
00148 G->SkinVertexCount = B->XSkinVertexCount;
00149 }
00150
00151 if (G->NormalCount != B->SkinNormalCount)
00152 {
00153 if (G->NormalArray!=NULL)
00154 {
00155 geRam_Free(G->NormalArray);
00156 }
00157 G->NormalArray = GE_RAM_ALLOCATE_ARRAY( geVec3d,B->SkinNormalCount);
00158 if ( G->NormalArray == NULL )
00159 {
00160 geErrorLog_Add(ERR_BODY_ENOMEM, NULL);
00161 G->NormalCount = 0;
00162 return NULL;
00163 }
00164 G->NormalCount = B->SkinNormalCount;
00165 }
00166
00167 if (BI->FaceCount != B->SkinFaces[GE_BODY_HIGHEST_LOD].FaceCount)
00168 {
00169 if (G->FaceList!=NULL)
00170 {
00171 geRam_Free(G->FaceList);
00172 }
00173 G->FaceListSize = sizeof(geBody_Index) *
00174 B->SkinFaces[GE_BODY_HIGHEST_LOD].FaceCount *
00175 GE_BODYINST_FACELIST_SIZE_FOR_TRIANGLE;
00176 G->FaceList = GE_RAM_ALLOCATE_ARRAY(geBody_Index,
00177 B->SkinFaces[GE_BODY_HIGHEST_LOD].FaceCount *
00178 GE_BODYINST_FACELIST_SIZE_FOR_TRIANGLE);
00179 if ( G->FaceList == NULL )
00180 {
00181 geErrorLog_Add(ERR_BODY_ENOMEM, NULL);
00182 BI->FaceCount = 0;
00183 return NULL;
00184 }
00185 BI->FaceCount = B->SkinFaces[GE_BODY_HIGHEST_LOD].FaceCount;
00186 }
00187 return G;
00188 }
00189
00190 const geBodyInst_Geometry *GENESISCC geBodyInst_GetGeometry(
00191 const geBodyInst *BI,
00192 const geVec3d *ScaleVector,
00193 const geXFArray *BoneTransformArray,
00194 int LevelOfDetail,
00195 const geCamera *Camera)
00196 {
00197 geBodyInst_Geometry *G;
00198 const geBody *B;
00199 geXForm3d *BoneXFArray;
00200 int BoneXFCount;
00201 geBody_Index BoneIndex;
00202
00203 geBoolean GottaUpdateFaces = GE_FALSE;
00204 assert( BI != NULL );
00205 assert( BoneTransformArray != NULL );
00206 assert( geBody_IsValid(BI->BodyTemplate) != GE_FALSE );
00207
00208 G = geBodyInst_GetGeometryPrep((geBodyInst *)BI,LevelOfDetail);
00209 if (G == NULL)
00210 {
00211 return NULL;
00212 }
00213
00214
00215 B = BI->BodyTemplate;
00216
00217 BoneXFArray = geXFArray_GetElements(BoneTransformArray,&BoneXFCount);
00218 if ( BoneXFArray == NULL)
00219 {
00220 geErrorLog_Add(ERR_BODY_BONEXFARRAY, NULL);
00221 return NULL;
00222 }
00223 if (BoneXFCount != B->BoneCount)
00224 {
00225 geErrorLog_Add(ERR_BODY_BONEXFARRAY, NULL);
00226 return NULL;
00227 }
00228
00229
00230 {
00231 int i,LevelOfDetailBit;
00232
00233 if (Camera != NULL)
00234 {
00235
00236 geBody_XSkinVertex *S;
00237 geBodyInst_SkinVertex *D;
00238 LevelOfDetailBit = 1 << LevelOfDetail;
00239 BoneIndex = -1;
00240 geVec3d_Set(&(G->Maxs), -GE_BODY_REALLY_BIG_NUMBER, -GE_BODY_REALLY_BIG_NUMBER, -GE_BODY_REALLY_BIG_NUMBER );
00241 geVec3d_Set(&(G->Mins), GE_BODY_REALLY_BIG_NUMBER, GE_BODY_REALLY_BIG_NUMBER, GE_BODY_REALLY_BIG_NUMBER );
00242 for (i=B->XSkinVertexCount,S=B->XSkinVertexArray,D=G->SkinVertexArray;
00243 i>0;
00244 i--,S++,D++)
00245 {
00246 geXForm3d ObjectToCamera;
00247 if (S->BoneIndex!=BoneIndex)
00248 {
00249 BoneIndex = S->BoneIndex;
00250 geXForm3d_Multiply( geCamera_GetCameraSpaceXForm(Camera),
00251 &(BoneXFArray[BoneIndex]),
00252 &ObjectToCamera);
00253 geBodyInst_PostScale(&ObjectToCamera,ScaleVector,&ObjectToCamera);
00254 }
00255 if ( S->LevelOfDetailMask && LevelOfDetailBit )
00256 {
00257 geVec3d *VecDestPtr = &(D->SVPoint);
00258 geXForm3d_Transform( &(ObjectToCamera),
00259 &(S->XPoint),VecDestPtr);
00260 #ifdef ONE_OVER_Z_PIPELINE
00261 geCamera_ProjectZ( Camera, VecDestPtr, VecDestPtr);
00262 #else
00263 geCamera_Project( Camera, VecDestPtr, VecDestPtr);
00264 #endif
00265 D->SVU = S->XU;
00266 D->SVV = S->XV;
00267 if (VecDestPtr->X > G->Maxs.X ) G->Maxs.X = VecDestPtr->X;
00268 if (VecDestPtr->X < G->Mins.X ) G->Mins.X = VecDestPtr->X;
00269 if (VecDestPtr->Y > G->Maxs.Y ) G->Maxs.Y = VecDestPtr->Y;
00270 if (VecDestPtr->Y < G->Mins.Y ) G->Mins.Y = VecDestPtr->Y;
00271 if (VecDestPtr->Z > G->Maxs.Z ) G->Maxs.Z = VecDestPtr->Z;
00272 if (VecDestPtr->Z < G->Mins.Z ) G->Mins.Z = VecDestPtr->Z;
00273 D->ReferenceBoneIndex=BoneIndex;
00274 }
00275 }
00276 }
00277 else
00278 {
00279
00280 geBody_XSkinVertex *S;
00281 geBodyInst_SkinVertex *D;
00282 LevelOfDetailBit = 1 << LevelOfDetail;
00283 BoneIndex = -1;
00284 geVec3d_Set(&(G->Maxs), -GE_BODY_REALLY_BIG_NUMBER, -GE_BODY_REALLY_BIG_NUMBER, -GE_BODY_REALLY_BIG_NUMBER );
00285 geVec3d_Set(&(G->Mins), GE_BODY_REALLY_BIG_NUMBER, GE_BODY_REALLY_BIG_NUMBER, GE_BODY_REALLY_BIG_NUMBER );
00286
00287 for (i=B->XSkinVertexCount,S=B->XSkinVertexArray,D=G->SkinVertexArray;
00288 i>0;
00289 i--,S++,D++)
00290 {
00291 geXForm3d ObjectToWorld;
00292 if (S->BoneIndex!=BoneIndex)
00293 {
00294 BoneIndex = S->BoneIndex;
00295 geBodyInst_PostScale(&BoneXFArray[BoneIndex],ScaleVector,&ObjectToWorld);
00296
00297 }
00298 if ( S->LevelOfDetailMask && LevelOfDetailBit )
00299 {
00300 geVec3d *VecDestPtr = &(D->SVPoint);
00301 geXForm3d_Transform( &(ObjectToWorld),
00302 &(S->XPoint),VecDestPtr);
00303 D->SVU = S->XU;
00304 D->SVV = S->XV;
00305 if (VecDestPtr->X > G->Maxs.X ) G->Maxs.X = VecDestPtr->X;
00306 if (VecDestPtr->X < G->Mins.X ) G->Mins.X = VecDestPtr->X;
00307 if (VecDestPtr->Y > G->Maxs.Y ) G->Maxs.Y = VecDestPtr->Y;
00308 if (VecDestPtr->Y < G->Mins.Y ) G->Mins.Y = VecDestPtr->Y;
00309 if (VecDestPtr->Z > G->Maxs.Z ) G->Maxs.Z = VecDestPtr->Z;
00310 if (VecDestPtr->Z < G->Mins.Z ) G->Mins.Z = VecDestPtr->Z;
00311 D->ReferenceBoneIndex=BoneIndex;
00312 }
00313 }
00314 }
00315
00316 {
00317 geBody_Normal *S;
00318 geVec3d *D;
00319
00320 for (i=B->SkinNormalCount,S=B->SkinNormalArray,D=G->NormalArray;
00321 i>0;
00322 i--,S++,D++)
00323 {
00324 if ( S->LevelOfDetailMask && LevelOfDetailBit )
00325 {
00326 geXForm3d_Rotate(&(BoneXFArray[S->BoneIndex]),
00327 &(S->Normal),D);
00328 }
00329 }
00330 }
00331
00332 }
00333
00334
00335 if (LevelOfDetail != BI->LastLevelOfDetail)
00336 {
00337
00338 int i,j;
00339 geBody_Index Count;
00340 const geBody_Triangle *T;
00341 geBody_Index *D;
00342 Count = B->SkinFaces[LevelOfDetail].FaceCount;
00343
00344 for (i=0,T=B->SkinFaces[LevelOfDetail].FaceArray,D=G->FaceList;
00345 i<Count;
00346 i++,T++,B++)
00347 {
00348 *D = GE_BODYINST_FACE_TRIANGLE;
00349 D++;
00350 *D = T->MaterialIndex;
00351 D++;
00352 for (j=0; j<3; j++)
00353 {
00354 *D = T->VtxIndex[j];
00355 D++;
00356 *D = T->NormalIndex[j];
00357 D++;
00358 }
00359 }
00360 assert( ((uint32)D) - ((uint32)G->FaceList) == (uint32)(G->FaceListSize) );
00361 G->FaceCount = Count;
00362 ((geBodyInst *)BI)->LastLevelOfDetail = LevelOfDetail;
00363 }
00364
00365
00366
00367 return G;
00368 }
00369