void clASELoader::ASE_ReadGeomObject( iIStream* FStream, int Depth, int ParentIdx ) { guard(); int RealParentIdx = ParentIdx; LString GeomObjectName( "" ); clVAMender* Mesh = NULL; LMatrix4 NodeTM; NodeTM.IdentityMatrix(); int MaterialIndex = -1; bool MotionBlur = false; bool CastShadow = true; bool ReceiveShadow = true; while ( !FStream->Eof() ) { LString Line = FStream->ReadLineTrimLeadSpaces(); if ( LStr::ContainsSubStr( Line, "}" ) ) { break; } else if ( LStr::StartsWith( Line, ASE_NodeTM ) ) { NodeTM = ASE_ReadNodeTM( FStream ); } else if ( LStr::StartsWith( Line, ASE_TMAnimation ) ) { ASE_ReadTMAnimation( FStream ); } else if ( LStr::StartsWith( Line, ASE_NodeName ) ) { GeomObjectName = LStr::GetToken( Line, 2 ); #ifdef ASE_HEAVY_DEBUG Env->Logger->Log( L_DEBUG, "Reading geom object: " + GeomObjectName ); #endif } else if ( LStr::StartsWith( Line, ASE_NodeParent ) ) { LString ParentName = LStr::GetToken( Line, 2 ); int Parent = FMesh->FindRigidByName( ParentName ); if ( Parent != -1 ) { RealParentIdx = Parent; } } else if ( LStr::StartsWith( Line, ASE_GeomObject ) || LStr::StartsWith( Line, ASE_Group ) ) { // recursive structure ASE_ReadGeomObject( FStream, Depth + 1, RealParentIdx ); } else if ( LStr::StartsWith( Line, ASE_ShapeObject ) ) { // recursive structure ASE_ReadShapeObject( FStream ); } else if ( LStr::StartsWith( Line, ASE_Mesh ) ) { FATAL( Mesh != NULL, "Mesh was already defined. Check " + ASE_Mesh + " in ASE file" ); Mesh = ASE_ReadMesh( FStream ); } else if ( LStr::StartsWith( Line, ASE_MaterialRef ) ) { MaterialIndex = LStr::ToInt( LStr::GetToken( Line, 2 ) ); FATAL( MaterialIndex >= static_cast<int>( FMaterialList.size() ), "Invalid " + ASE_MaterialRef + " value in ASE file: " + LStr::ToStr( MaterialIndex ) + " (current size: " + LStr::ToStr( FMaterialList.size() ) + ")" ); FATAL( !Mesh, "Mesh should be defined prior to " + ASE_MaterialRef ); } else if ( LStr::StartsWith( Line, ASE_MotionBlur ) ) { MotionBlur = LStr::ToInt( LStr::GetToken( Line, 2 ) ) > 0; } else if ( LStr::StartsWith( Line, ASE_CastShadow ) ) { CastShadow = LStr::ToInt( LStr::GetToken( Line, 2 ) ) > 0; } else if ( LStr::StartsWith( Line, ASE_ReceiveShadow ) ) { ReceiveShadow = LStr::ToInt( LStr::GetToken( Line, 2 ) ) > 0; } else { ASE_SkipBlock( FStream, Line ); } } if ( FMaterialList.size() == 0 ) { // no materials were found in ASE file - use basic default sASEMaterial Material; Material.FName = DEFAULT_MATERIAL_FALLBACK; FMaterialList.resize( 1 ); FMaterialList[ 0 ] = Material; MaterialIndex = 0; } if ( MaterialIndex == -1 ) { MaterialIndex = 0; } if ( !Mesh ) { return; } if ( FMaterialList[ MaterialIndex ].FSubMaterials.size() == 0 ) { Mesh->ReplaceAllSubMaterials( -1 ); } // create geometry with default material #ifdef ASE_HEAVY_DEBUG Env->Logger->Log( L_DEBUG, "Building vertex arrays..." ); #endif clVertexAttribs* VA = Mesh->CreateVertexAttribs( -1 ); if ( VA ) { VA->SetMotionBlur( MotionBlur ); VA->SetCastShadow( CastShadow ); VA->SetReceiveShadow( ReceiveShadow ); AddNode( RealParentIdx, VA, FMaterialList[ MaterialIndex ], GeomObjectName, NodeTM ); } // create geometry with submaterials for ( size_t i = 0; i != FMaterialList[ MaterialIndex ].FSubMaterials.size(); ++i ) { clVertexAttribs* VA = Mesh->CreateVertexAttribs( static_cast<int>( i ) ); if ( VA ) { VA->SetMotionBlur( MotionBlur ); VA->SetCastShadow( CastShadow ); VA->SetReceiveShadow( ReceiveShadow ); #ifdef ASE_HEAVY_DEBUG Env->Logger->Log( L_DEBUG, "Extracting submaterial: " + FMaterialList[ MaterialIndex ].FSubMaterials[i].FName ); #endif AddNode( RealParentIdx, VA, FMaterialList[ MaterialIndex ].FSubMaterials[i], GeomObjectName, NodeTM ); } else { // Mesh->GetLastError() contains textual error description } } delete Mesh; unguard(); }
static int ASE_ReadSubModel (CFILE *cfP, tASEModel *pm) { tASESubModelList *pml; tASESubModel *psm; if (CharTok (" \t") != '{') return ASE_Error ("syntax error"); if (!(pml = (tASESubModelList *) D2_ALLOC (sizeof (tASESubModelList)))) return ASE_Error ("out of memory"); memset (pml, 0, sizeof (*pml)); pml->pNextModel = pm->pSubModels; pm->pSubModels = pml; psm = &pm->pSubModels->sm; psm->nId = pm->nSubModels++; psm->nBomb = -1; psm->nMissile = -1; psm->nGun = -1; psm->nGunPoint = -1; psm->nBullets = -1; psm->bRender = 1; psm->nType = 0; psm->bBarrel = 0; while ((pszToken = ASE_ReadLine (cfP))) { if (*pszToken == '}') return 1; if (!strcmp (pszToken, "*NODE_NAME")) { strcpy (psm->szName, StrTok (" \t\"")); if (strstr (psm->szName, "$GUNPNT")) psm->nGunPoint = atoi (psm->szName + 8); if (strstr (psm->szName, "$BULLETS")) psm->nBullets = 1; else if (strstr (psm->szName, "GLOW") != NULL) psm->bGlow = 1; else if (strstr (psm->szName, "$DUMMY") != NULL) psm->bRender = 0; else if (strstr (psm->szName, "$THRUSTER") != NULL) psm->bThruster = 1; else if (strstr (psm->szName, "$WINGTIP") != NULL) { psm->bWeapon = 1; psm->nGun = 0; psm->nBomb = psm->nMissile = -1; psm->nType = atoi (psm->szName + 8) + 1; } else if (strstr (psm->szName, "$GUN") != NULL) { psm->bWeapon = 1; psm->nGun = atoi (psm->szName + 4) + 1; psm->nWeaponPos = atoi (psm->szName + 6) + 1; psm->nBomb = psm->nMissile = -1; } else if (strstr (psm->szName, "$BARREL") != NULL) { psm->bWeapon = 1; psm->nGun = atoi (psm->szName + 7) + 1; psm->nWeaponPos = atoi (psm->szName + 9) + 1; psm->nBomb = psm->nMissile = -1; psm->bBarrel = 1; } else if (strstr (psm->szName, "$MISSILE") != NULL) { psm->bWeapon = 1; psm->nMissile = atoi (psm->szName + 8) + 1; psm->nWeaponPos = atoi (psm->szName + 10) + 1; psm->nGun = psm->nBomb = -1; } else if (strstr (psm->szName, "$BOMB") != NULL) { psm->bWeapon = 1; psm->nBomb = atoi (psm->szName + 6) + 1; psm->nGun = psm->nMissile = -1; } } else if (!strcmp (pszToken, "*NODE_PARENT")) { strcpy (psm->szParent, StrTok (" \t\"")); } if (!strcmp (pszToken, "*NODE_TM")) { if (!ASE_ReadNode (cfP, pm)) return ASE_Error (NULL); } else if (!strcmp (pszToken, "*MESH")) { if (!ASE_ReadMesh (cfP, pm)) return ASE_Error (NULL); } else if (!strcmp (pszToken, "*MATERIAL_REF")) { psm->nBitmap = IntTok (" \t"); } } return ASE_Error ("unexpected end of file"); }