bool MA_ParseEdge(idParser& parser, maAttribHeader_t* header) { maMesh_t* pMesh = &maGlobal.currentObject->mesh; idToken token; //Allocate enough space for all the verts if this is the first attribute for verticies if(!pMesh->edges) { pMesh->numEdges = header->size; pMesh->edges = (idVec3 *)Mem_Alloc( sizeof( idVec3 ) * pMesh->numEdges ); } //Get the start and end index for this attribute int minIndex, maxIndex; if(!MA_ParseHeaderIndex(header, minIndex, maxIndex, "EdgeHeader", NULL)) { //This was just a header return true; } //Read each vert for(int i = minIndex; i <= maxIndex; i++) { pMesh->edges[i].x = parser.ParseFloat(); pMesh->edges[i].y = parser.ParseFloat(); pMesh->edges[i].z = parser.ParseFloat(); } return true; }
void MA_ParseNodeHeader( idParser &parser, maNodeHeader_t *header ) { memset( header, 0, sizeof( maNodeHeader_t ) ); idToken token; while( parser.ReadToken( &token ) ) { if( !token.Icmp( "-" ) ) { parser.ReadToken( &token ); if( !token.Icmp( "n" ) ) { parser.ReadToken( &token ); strcpy( header->name, token.c_str() ); } else if( !token.Icmp( "p" ) ) { parser.ReadToken( &token ); strcpy( header->parent, token.c_str() ); } } else if( !token.Icmp( ";" ) ) { break; } } }
bool MA_ParseColor(idParser& parser, maAttribHeader_t* header) { maMesh_t* pMesh = &maGlobal.currentObject->mesh; idToken token; //Allocate enough space for all the verts if this is the first attribute for verticies if(!pMesh->colors) { pMesh->numColors = header->size; pMesh->colors = (byte *)Mem_Alloc( sizeof( byte ) * pMesh->numColors * 4 ); } //Get the start and end index for this attribute int minIndex, maxIndex; if(!MA_ParseHeaderIndex(header, minIndex, maxIndex, "ColorHeader", NULL)) { //This was just a header return true; } //Read each vert for(int i = minIndex; i <= maxIndex; i++) { pMesh->colors[i*4] = parser.ParseFloat() * 255; pMesh->colors[i*4+1] = parser.ParseFloat() * 255; pMesh->colors[i*4+2] = parser.ParseFloat() * 255; pMesh->colors[i*4+3] = parser.ParseFloat() * 255; } return true; }
/* ================ idTypeInfoGen::ParseConstantValue ================ */ void idTypeInfoGen::ParseConstantValue( const char *scope, idParser &src, idStr &value ) { idToken token; idStr constantString; int indent = 0; while( src.ReadToken( &token ) ) { if ( token == "(" ) { indent++; } else if ( token == ")" ) { indent--; } else if ( indent == 0 && ( token == ";" || token == "," || token == "}" ) ) { src.UnreadToken( &token ); break; } else if ( token.type == TT_NAME ) { constantString = token; while( src.CheckTokenString( "::" ) ) { src.ExpectTokenType( TT_NAME, 0, &token ); constantString += "::" + token; } value += va( "%d", GetIntegerConstant( scope, constantString, src ) ); continue; } value += token; } }
/* ================ sdDeclDamageFilter::ParseFilter ================ */ bool sdDeclDamageFilter::ParseFilter( damageFilter_t& filter, idParser& src ) { idToken token; if( !src.ReadToken( &token ) || token.Cmp( "{" ) ) { return false; } while ( true ) { if ( !src.ReadToken( &token ) ) { return false; } if ( !token.Cmp( "}" ) ) { break; } if( !token.Icmp( "damage" ) ) { bool error; filter.damage = src.ParseFloat( &error ); if ( error ) { src.Error( "sdDeclDamageFilter::ParseLevel Invalid Parm for 'damage'" ); return false; } if ( src.PeekTokenString( "%" ) ) { src.ReadToken( &token ); filter.mode = DFM_PERCENT; } else { filter.mode = DFM_NORMAL; } } else if( !token.Icmp( "target" ) ) { if ( !src.ReadToken( &token ) ) { src.Error( "sdDeclDamageFilter::ParseLevel Missing Parm for 'target'" ); return false; } filter.target = gameLocal.declTargetInfoType.LocalFind( token, false ); if ( !filter.target ) { src.Error( "sdDeclDamageFilter::ParseLevel Invalid Target '%s'", token.c_str() ); return false; } } else if( !token.Icmp( "noScale" ) ) { filter.noScale = true; } else { src.Error( "sdDeclDamageFilter::ParseLevel Unknown Parameter %s", token.c_str() ); return false; } } return true; }
bool MA_ParseTransform(idParser& parser) { maNodeHeader_t header; maTransform_t* transform; memset(&header, 0, sizeof(header)); //Allocate room for the transform transform = (maTransform_t *)Mem_Alloc( sizeof( maTransform_t ) ); memset(transform, 0, sizeof(maTransform_t)); transform->scale.x = transform->scale.y = transform->scale.z = 1; //Get the header info from the transform MA_ParseNodeHeader(parser, &header); //Read the transform attributes idToken token; while(parser.ReadToken(&token)) { if(IsNodeComplete(token)) { parser.UnreadToken(&token); break; } if(!token.Icmp("setAttr")) { parser.ReadToken(&token); if(!token.Icmp(".t")) { if(!MA_ReadVec3(parser, transform->translate)) { return false; } transform->translate.y *= -1; } else if (!token.Icmp(".r")) { if(!MA_ReadVec3(parser, transform->rotate)) { return false; } } else if (!token.Icmp(".s")) { if(!MA_ReadVec3(parser, transform->scale)) { return false; } } else { parser.SkipRestOfLine(); } } } if(header.parent[0] != 0) { //Find the parent maTransform_t** parent; maGlobal.model->transforms.Get(header.parent, &parent); if(parent) { transform->parent = *parent; } } //Add this transform to the list maGlobal.model->transforms.Set(header.name, transform); return true; }
/* ================ idDict::Parse ================ */ bool idDict::Parse( idParser &parser ) { idToken token; idToken token2; bool errors; errors = false; parser.ExpectTokenString( "{" ); parser.ReadToken( &token ); while( ( token.type != TT_PUNCTUATION ) || ( token != "}" ) ) { if ( token.type != TT_STRING ) { parser.Error( "Expected quoted string, but found '%s'", token.c_str() ); } if ( !parser.ReadToken( &token2 ) ) { parser.Error( "Unexpected end of file" ); } if ( FindKey( token ) ) { parser.Warning( "'%s' already defined", token.c_str() ); errors = true; } Set( token, token2 ); if ( !parser.ReadToken( &token ) ) { parser.Error( "Unexpected end of file" ); } } return !errors; }
bool MA_ReadVec3(idParser& parser, idVec3& vec) { idToken token; if(!parser.SkipUntilString("double3")) { throw idException( va("Maya Loader '%s': Invalid Vec3", parser.GetFileName()) ); } //We need to flip y and z because of the maya coordinate system vec.x = parser.ParseFloat(); vec.z = parser.ParseFloat(); vec.y = parser.ParseFloat(); return true; }
/* ============ sdDeclRadialMenu::ParsePage ============ */ bool sdDeclRadialMenu::ParsePage( idParser& src ) { idToken token; if( !src.ReadToken( &token )) { src.Error( "sdDeclRadialMenu::ParsePage: Unexpected end of file while parsing declName" ); return false; } if( token.Length() > 0 ) { pages.Append( gameLocal.declRadialMenuType.LocalFind( token ) ); } else { gameLocal.Warning( "sdDeclRadialMenu::ParsePage: parsed an empty page in '%s'", GetName() ); } return true; }
bool MA_ParseTVert( idParser &parser, maAttribHeader_t *header ) { maMesh_t *pMesh = &maGlobal.currentObject->mesh; idToken token; //This is not the texture coordinates. It is just the name so ignore it if( strstr( header->name, "uvsn" ) ) { return true; } //Allocate enough space for all the data if( !pMesh->tvertexes ) { pMesh->numTVertexes = header->size; pMesh->tvertexes = ( idVec2 * ) Mem_Alloc( sizeof( idVec2 ) * pMesh->numTVertexes ); } //Get the start and end index for this attribute int minIndex, maxIndex; if( !MA_ParseHeaderIndex( header, minIndex, maxIndex, "TextureCoordHeader", "uvsp" ) ) { //This was just a header return true; } parser.ReadToken( &token ); if( !token.Icmp( "-" ) ) { idToken tk2; parser.ReadToken( &tk2 ); if( !tk2.Icmp( "type" ) ) { parser.SkipUntilString( "float2" ); } else { parser.UnreadToken( &tk2 ); parser.UnreadToken( &token ); } } else { parser.UnreadToken( &token ); } //Read each tvert for( int i = minIndex; i <= maxIndex; i++ ) { pMesh->tvertexes[i].x = parser.ParseFloat(); pMesh->tvertexes[i].y = 1.0f - parser.ParseFloat(); } return true; }
/* ============ sdDeclRadialMenu::ParseItem ============ */ bool sdDeclRadialMenu::ParseItem( idParser& src ) { idToken token; if( !src.ReadToken( &token )) { src.Error( "sdDeclRadialMenu::ParseItem: Unexpected end of file while parsing itemName" ); return false; } item_t& item = items.Alloc(); item.title = declHolder.FindLocStr( token.c_str() ); bool success = ParseKeys( src, item.keys ); gameLocal.CacheDictionaryMedia( item.keys ); return success; }
bool MA_ParseNormal(idParser& parser, maAttribHeader_t* header) { maMesh_t* pMesh = &maGlobal.currentObject->mesh; idToken token; //Allocate enough space for all the verts if this is the first attribute for verticies if(!pMesh->normals) { pMesh->numNormals = header->size; pMesh->normals = (idVec3 *)Mem_Alloc( sizeof( idVec3 ) * pMesh->numNormals ); } //Get the start and end index for this attribute int minIndex, maxIndex; if(!MA_ParseHeaderIndex(header, minIndex, maxIndex, "NormalHeader", NULL)) { //This was just a header return true; } parser.ReadToken(&token); if(!token.Icmp("-")) { idToken tk2; parser.ReadToken(&tk2); if(!tk2.Icmp("type")) { parser.SkipUntilString("float3"); } else { parser.UnreadToken(&tk2); parser.UnreadToken(&token); } } else { parser.UnreadToken(&token); } //Read each vert for(int i = minIndex; i <= maxIndex; i++) { pMesh->normals[i].x = parser.ParseFloat(); //Adjust the normals for the change in coordinate systems pMesh->normals[i].z = parser.ParseFloat(); pMesh->normals[i].y = -parser.ParseFloat(); pMesh->normals[i].Normalize(); } pMesh->normalsParsed = true; pMesh->nextNormal = 0; return true; }
bool MA_ParseAttribHeader(idParser &parser, maAttribHeader_t* header) { idToken token; memset(header, 0, sizeof(maAttribHeader_t)); parser.ReadToken(&token); if(!token.Icmp("-")) { parser.ReadToken(&token); if (!token.Icmp("s")) { header->size = parser.ParseInt(); parser.ReadToken(&token); } } strcpy(header->name, token.c_str()); return true; }
/* ================ sdPersistentRankInfo::Parse ================ */ bool sdPersistentRankInfo::Parse( idParser& src ) { idToken token; while ( true ) { if ( src.ReadToken( &token ) == 0 ) { break; } if ( token.Icmp( "badge" ) == 0 ) { if ( !ParseBadge( src ) ) { return false; } } else { src.Warning( "Unexpected Token: '%s'", token.c_str() ); return false; } } return true; }
/* ================ idTypeInfoGen::GetFloatConstant ================ */ float idTypeInfoGen::GetFloatConstant( const char *scope, const char *name, idParser &src ) { idConstantInfo *constant = FindConstant( idStr( scope ) + name ); if ( constant == NULL ) { constant = FindConstant( name ); } if ( constant ) { return EvaluateFloatString( constant->value ); } src.Warning( "unknown value '%s' in constant expression", name ); return 0; }
bool MA_ParseVertexTransforms(idParser& parser, maAttribHeader_t* header) { maMesh_t* pMesh = &maGlobal.currentObject->mesh; idToken token; //Allocate enough space for all the verts if this is the first attribute for verticies if(!pMesh->vertTransforms) { if(header->size == 0) { header->size = 1; } pMesh->numVertTransforms = header->size; pMesh->vertTransforms = (idVec4 *)Mem_Alloc( sizeof( idVec4 ) * pMesh->numVertTransforms ); pMesh->nextVertTransformIndex = 0; } //Get the start and end index for this attribute int minIndex, maxIndex; if(!MA_ParseHeaderIndex(header, minIndex, maxIndex, "VertexTransformHeader", NULL)) { //This was just a header return true; } parser.ReadToken(&token); if(!token.Icmp("-")) { idToken tk2; parser.ReadToken(&tk2); if(!tk2.Icmp("type")) { parser.SkipUntilString("float3"); } else { parser.UnreadToken(&tk2); parser.UnreadToken(&token); } } else { parser.UnreadToken(&token); } //Read each vert for(int i = minIndex; i <= maxIndex; i++) { pMesh->vertTransforms[pMesh->nextVertTransformIndex].x = parser.ParseFloat(); pMesh->vertTransforms[pMesh->nextVertTransformIndex].z = parser.ParseFloat(); pMesh->vertTransforms[pMesh->nextVertTransformIndex].y = -parser.ParseFloat(); //w hold the vert index pMesh->vertTransforms[pMesh->nextVertTransformIndex].w = i; pMesh->nextVertTransformIndex++; } return true; }
void idTokenParser::LoadFromParser( idParser& parser, const char* guiName ) { idToken tok; idTokenIndexes tokIdxs; tokIdxs.SetName( guiName ); while( parser.ReadToken( &tok ) ) { tokIdxs.Append( tokens.AddUnique( idBinaryToken( tok ) ) ); } guiTokenIndexes.Append( tokIdxs ); currentToken = 0; }
/* ============ sdDemoCamera::ParseKey ============ */ bool sdDemoCamera::ParseKey( const idToken& key, idParser& src ) { idToken token; if ( !key.Icmp( "name" ) ) { if ( !src.ExpectAnyToken( &token ) ) { return false; } name = token; return true; } return false; }
/* ================ idTypeInfoGen::ParseArraySize ================ */ int idTypeInfoGen::ParseArraySize( const char *scope, idParser &src ) { idToken token; idStr sizeString, constantString; int size, totalSize; if ( !src.CheckTokenString( "[" ) ) { return 0; } totalSize = 1; sizeString = ""; while( src.ReadToken( &token ) ) { if ( token == "]" ) { if ( sizeString.Length() ) { size = EvaluateIntegerString( sizeString ); if ( size ) { totalSize *= size; } sizeString = ""; } if ( !src.CheckTokenString( "[" ) ) { break; } } else if ( token.type == TT_NAME ) { constantString = token; while( src.CheckTokenString( "::" ) ) { src.ExpectTokenType( TT_NAME, 0, &token ); constantString += "::" + token; } sizeString += va( "%d", GetIntegerConstant( scope, constantString, src ) ); } else { sizeString += token; } } return totalSize; }
void MA_ParseCreateNode(idParser& parser) { idToken token; parser.ReadToken(&token); if(!token.Icmp("transform")) { MA_ParseTransform(parser); } else if(!token.Icmp("mesh")) { MA_ParseMesh(parser); } else if(!token.Icmp("file")) { MA_ParseFileNode(parser); } else if(!token.Icmp("shadingEngine") || !token.Icmp("lambert") || !token.Icmp("phong") || !token.Icmp("blinn") ) { MA_ParseMaterialNode(parser); } }
void MA_ParseFileNode( idParser &parser ) { //Get the header info from the node maNodeHeader_t header; MA_ParseNodeHeader( parser, &header ); //Read the transform attributes idToken token; while( parser.ReadToken( &token ) ) { if( IsNodeComplete( token ) ) { parser.UnreadToken( &token ); break; } if( !token.Icmp( "setAttr" ) ) { maAttribHeader_t attribHeader; MA_ParseAttribHeader( parser, &attribHeader ); if( strstr( attribHeader.name, ".ftn" ) ) { parser.SkipUntilString( "string" ); parser.ReadToken( &token ); if( !token.Icmp( "(" ) ) { parser.ReadToken( &token ); } maFileNode_t *fileNode; fileNode = ( maFileNode_t * ) Mem_Alloc( sizeof( maFileNode_t ) ); strcpy( fileNode->name, header.name ); strcpy( fileNode->path, token.c_str() ); maGlobal.model->fileNodes.Set( fileNode->name, fileNode ); } else { parser.SkipRestOfLine(); } } } }
/* ============ sdDemoCamera_Anim::Parse ============ */ bool sdDemoCamera_Anim::Parse( idParser& src ) { if ( !src.ExpectTokenString( "{" ) ) { return false; } idToken token; int cycle = 1; idVec3 offset( vec3_origin ); while( true ) { if ( !src.ExpectAnyToken( &token ) ) { return false; } if ( !token.Cmp( "}" ) ) { break; } else if ( !token.Icmp( "anim" ) ) { if ( !src.ExpectAnyToken( &token ) ) { return false; } if ( !cameraMD5.LoadAnim( token ) ) { return false; } } else if ( !token.Icmp( "cycle" ) ) { cycle = src.ParseInt(); } else if ( !token.Icmp( "offset" ) ) { if ( !src.Parse1DMatrix( 3, offset.ToFloatPtr() ) ) { return false; } } else if ( !sdDemoCamera::ParseKey( token, src ) ) { src.Error( "sdDemoCamera_Anim::Parse : Unknown keyword '%s'", token.c_str() ); return false; } } if ( !cycle ) { cycle = 1; } cameraMD5.SetCycle( cycle ); cameraMD5.SetOffset( offset ); return true; }
/* ============ sdDemoCamera_Fixed::Parse ============ */ bool sdDemoCamera_Fixed::Parse( idParser& src ) { if ( !src.ExpectTokenString( "{" ) ) { return false; } idToken token; while( true ) { if ( !src.ExpectAnyToken( &token ) ) { return false; } if ( !token.Cmp( "}" ) ) { break; } else if ( !token.Icmp( "origin" ) ) { if ( !src.Parse1DMatrix( 3, origin.ToFloatPtr() ) ) { return false; } } else if ( !token.Icmp( "axis" ) ) { if ( !src.Parse2DMatrix( 3, 3, axis.ToFloatPtr() ) ) { return false; } } else if ( !token.Icmp( "angles" ) ) { idAngles angles; if ( !src.Parse1DMatrix( 3, angles.ToFloatPtr() ) ) { return false; } axis = angles.ToMat3(); } else if ( !token.Icmp( "fov" ) ) { fov = src.ParseFloat(); } else if ( !sdDemoCamera::ParseKey( token, src ) ) { src.Error( "sdDemoCamera_Fixed::Parse : Unknown keyword '%s'", token.c_str() ); return false; } } return true; }
bool MA_ParseConnectAttr(idParser& parser) { idStr temp; idStr srcName; idStr srcType; idStr destName; idStr destType; idToken token; parser.ReadToken(&token); temp = token; int dot = temp.Find("."); if(dot == -1) { throw idException(va("Maya Loader '%s': Invalid Connect Attribute.", parser.GetFileName())); } srcName = temp.Left(dot); srcType = temp.Right(temp.Length()-dot-1); parser.ReadToken(&token); temp = token; dot = temp.Find("."); if(dot == -1) { throw idException(va("Maya Loader '%s': Invalid Connect Attribute.", parser.GetFileName())); } destName = temp.Left(dot); destType = temp.Right(temp.Length()-dot-1); if(srcType.Find("oc") != -1) { //Is this attribute a material node attribute maMaterialNode_t** matNode; maGlobal.model->materialNodes.Get(srcName, &matNode); if(matNode) { maMaterialNode_t** destNode; maGlobal.model->materialNodes.Get(destName, &destNode); if(destNode) { (*destNode)->child = *matNode; } } //Is this attribute a file node maFileNode_t** fileNode; maGlobal.model->fileNodes.Get(srcName, &fileNode); if(fileNode) { maMaterialNode_t** destNode; maGlobal.model->materialNodes.Get(destName, &destNode); if(destNode) { (*destNode)->file = *fileNode; } } } if(srcType.Find("iog") != -1) { //Is this an attribute for one of our meshes for(int i = 0; i < maGlobal.model->objects.Num(); i++) { if(!strcmp(maGlobal.model->objects[i]->name, srcName)) { //maGlobal.model->objects[i]->materialRef = MA_AddMaterial(destName); strcpy(maGlobal.model->objects[i]->materialName, destName); break; } } } return true; }
void MA_ParseMesh(idParser& parser) { maObject_t *object; object = (maObject_t *)Mem_Alloc( sizeof( maObject_t ) ); memset( object, 0, sizeof( maObject_t ) ); maGlobal.model->objects.Append( object ); maGlobal.currentObject = object; object->materialRef = -1; //Get the header info from the mesh maNodeHeader_t header; MA_ParseNodeHeader(parser, &header); //Find my parent if(header.parent[0] != 0) { //Find the parent maTransform_t** parent; maGlobal.model->transforms.Get(header.parent, &parent); if(parent) { maGlobal.currentObject->mesh.transform = *parent; } } strcpy(object->name, header.name); //Read the transform attributes idToken token; while(parser.ReadToken(&token)) { if(IsNodeComplete(token)) { parser.UnreadToken(&token); break; } if(!token.Icmp("setAttr")) { maAttribHeader_t header; MA_ParseAttribHeader(parser, &header); if(strstr(header.name, ".vt")) { MA_ParseVertex(parser, &header); } else if (strstr(header.name, ".ed")) { MA_ParseEdge(parser, &header); } else if (strstr(header.name, ".pt")) { MA_ParseVertexTransforms(parser, &header); } else if (strstr(header.name, ".n")) { MA_ParseNormal(parser, &header); } else if (strstr(header.name, ".fc")) { MA_ParseFace(parser, &header); } else if (strstr(header.name, ".clr")) { MA_ParseColor(parser, &header); } else if (strstr(header.name, ".uvst")) { MA_ParseTVert(parser, &header); } else { parser.SkipRestOfLine(); } } } maMesh_t* pMesh = &maGlobal.currentObject->mesh; //Get the verts from the edge for(int i = 0; i < pMesh->numFaces; i++) { for(int j = 0; j < 3; j++) { int edge = pMesh->faces[i].edge[j]; if(edge < 0) { edge = idMath::Fabs(edge)-1; pMesh->faces[i].vertexNum[j] = pMesh->edges[edge].y; } else { pMesh->faces[i].vertexNum[j] = pMesh->edges[edge].x; } } } //Get the normals if(pMesh->normalsParsed) { for(int i = 0; i < pMesh->numFaces; i++) { for(int j = 0; j < 3; j++) { //Is this vertex shared int sharedFace = -1; int sharedVert = -1; if(MA_QuickIsVertShared(i, j)) { MA_GetSharedFace(i, j, sharedFace, sharedVert); } if(sharedFace != -1) { //Get the normal from the share pMesh->faces[i].vertexNormals[j] = pMesh->faces[sharedFace].vertexNormals[sharedVert]; } else { //The vertex is not shared so get the next normal if(pMesh->nextNormal >= pMesh->numNormals) { //We are using more normals than exist throw idException(va("Maya Loader '%s': Invalid Normals Index.", parser.GetFileName())); } pMesh->faces[i].vertexNormals[j] = pMesh->normals[pMesh->nextNormal]; pMesh->nextNormal++; } } } } //Now that the normals are good...lets reorder the verts to make the tris face the right way for(int i = 0; i < pMesh->numFaces; i++) { int tmp = pMesh->faces[i].vertexNum[1]; pMesh->faces[i].vertexNum[1] = pMesh->faces[i].vertexNum[2]; pMesh->faces[i].vertexNum[2] = tmp; idVec3 tmpVec = pMesh->faces[i].vertexNormals[1]; pMesh->faces[i].vertexNormals[1] = pMesh->faces[i].vertexNormals[2]; pMesh->faces[i].vertexNormals[2] = tmpVec; tmp = pMesh->faces[i].tVertexNum[1]; pMesh->faces[i].tVertexNum[1] = pMesh->faces[i].tVertexNum[2]; pMesh->faces[i].tVertexNum[2] = tmp; tmp = pMesh->faces[i].vertexColors[1]; pMesh->faces[i].vertexColors[1] = pMesh->faces[i].vertexColors[2]; pMesh->faces[i].vertexColors[2] = tmp; } //Now apply the pt transformations for(int i = 0; i < pMesh->numVertTransforms; i++) { pMesh->vertexes[(int)pMesh->vertTransforms[i].w] += pMesh->vertTransforms[i].ToVec3(); } MA_VERBOSE((va("MESH %s - parent %s\n", header.name, header.parent))); MA_VERBOSE((va("\tverts:%d\n",maGlobal.currentObject->mesh.numVertexes))); MA_VERBOSE((va("\tfaces:%d\n",maGlobal.currentObject->mesh.numFaces))); }
bool MA_ParseFace(idParser& parser, maAttribHeader_t* header) { maMesh_t* pMesh = &maGlobal.currentObject->mesh; idToken token; //Allocate enough space for all the verts if this is the first attribute for verticies if(!pMesh->faces) { pMesh->numFaces = header->size; pMesh->faces = (maFace_t *)Mem_Alloc( sizeof( maFace_t ) * pMesh->numFaces ); } //Get the start and end index for this attribute int minIndex, maxIndex; if(!MA_ParseHeaderIndex(header, minIndex, maxIndex, "FaceHeader", NULL)) { //This was just a header return true; } //Read the face data int currentFace = minIndex-1; while(parser.ReadToken(&token)) { if(IsNodeComplete(token)) { parser.UnreadToken(&token); break; } if(!token.Icmp("f")) { int count = parser.ParseInt(); if(count != 3) { throw idException(va("Maya Loader '%s': Face is not a triangle.", parser.GetFileName())); } //Increment the face number because a new face always starts with an "f" token currentFace++; //We cannot reorder edges until later because the normal processing //assumes the edges are in the original order pMesh->faces[currentFace].edge[0] = parser.ParseInt(); pMesh->faces[currentFace].edge[1] = parser.ParseInt(); pMesh->faces[currentFace].edge[2] = parser.ParseInt(); //Some more init stuff pMesh->faces[currentFace].vertexColors[0] = pMesh->faces[currentFace].vertexColors[1] = pMesh->faces[currentFace].vertexColors[2] = -1; } else if(!token.Icmp("mu")) { /* int uvstIndex = */ parser.ParseInt(); int count = parser.ParseInt(); if(count != 3) { throw idException(va("Maya Loader '%s': Invalid texture coordinates.", parser.GetFileName())); } pMesh->faces[currentFace].tVertexNum[0] = parser.ParseInt(); pMesh->faces[currentFace].tVertexNum[1] = parser.ParseInt(); pMesh->faces[currentFace].tVertexNum[2] = parser.ParseInt(); } else if(!token.Icmp("mf")) { int count = parser.ParseInt(); if(count != 3) { throw idException(va("Maya Loader '%s': Invalid texture coordinates.", parser.GetFileName())); } pMesh->faces[currentFace].tVertexNum[0] = parser.ParseInt(); pMesh->faces[currentFace].tVertexNum[1] = parser.ParseInt(); pMesh->faces[currentFace].tVertexNum[2] = parser.ParseInt(); } else if(!token.Icmp("fc")) { int count = parser.ParseInt(); if(count != 3) { throw idException(va("Maya Loader '%s': Invalid vertex color.", parser.GetFileName())); } pMesh->faces[currentFace].vertexColors[0] = parser.ParseInt(); pMesh->faces[currentFace].vertexColors[1] = parser.ParseInt(); pMesh->faces[currentFace].vertexColors[2] = parser.ParseInt(); } } return true; }
/* ==================== idModelExport::ParseExportSection ==================== */ int idModelExport::ParseExportSection( idParser &parser ) { idToken command; idToken token; idStr defaultCommands; idLexer lex; idStr temp; idStr parms; int count; // only export sections that match our export mask if( g_exportMask.GetString()[ 0 ] ) { if( parser.CheckTokenString( "{" ) ) { parser.SkipBracedSection( false ); return 0; } parser.ReadToken( &token ); if( token.Icmp( g_exportMask.GetString() ) ) { parser.SkipBracedSection(); return 0; } parser.ExpectTokenString( "{" ); } else if( !parser.CheckTokenString( "{" ) ) { // skip the export mask parser.ReadToken( &token ); parser.ExpectTokenString( "{" ); } count = 0; lex.SetFlags( LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); while( 1 ) { if( !parser.ReadToken( &command ) ) { parser.Error( "Unexpoected end-of-file" ); break; } if( command == "}" ) { break; } if( command == "options" ) { parser.ParseRestOfLine( defaultCommands ); } else if( command == "addoptions" ) { parser.ParseRestOfLine( temp ); defaultCommands += " "; defaultCommands += temp; } else if( ( command == "mesh" ) || ( command == "anim" ) || ( command == "camera" ) ) { if( !parser.ReadToken( &token ) ) { parser.Error( "Expected filename" ); } temp = token; parser.ParseRestOfLine( parms ); if( defaultCommands.Length() ) { sprintf( temp, "%s %s", temp.c_str(), defaultCommands.c_str() ); } if( parms.Length() ) { sprintf( temp, "%s %s", temp.c_str(), parms.c_str() ); } lex.LoadMemory( temp, temp.Length(), parser.GetFileName() ); Reset(); if( ParseOptions( lex ) ) { const char *game = cvarSystem->GetCVarString( "fs_game" ); if( strlen( game ) == 0 ) { game = BASE_GAMEDIR; } if( command == "mesh" ) { dest.SetFileExtension( MD5_MESH_EXT ); } else if( command == "anim" ) { dest.SetFileExtension( MD5_ANIM_EXT ); } else if( command == "camera" ) { dest.SetFileExtension( MD5_CAMERA_EXT ); } else { dest.SetFileExtension( command ); } idStr back = commandLine; sprintf( commandLine, "%s %s -dest %s -game %s%s", command.c_str(), src.c_str(), dest.c_str(), game, commandLine.c_str() ); if( ConvertMayaToMD5() ) { count++; } else { parser.Warning( "Failed to export '%s' : %s", src.c_str(), Maya_Error.c_str() ); } } lex.FreeSource(); } else { parser.Error( "Unknown token: %s", command.c_str() ); parser.SkipBracedSection( false ); break; } } return count; }
/* ================ sdDeclToolTip::ParseTimeline ================ */ bool sdDeclToolTip::ParseTimeline( idParser& src ) { idToken token; src.SkipUntilString( "{", &token ); while ( true ) { if( !src.ReadToken( &token ) ) { return false; } if ( !token.Icmp( "onTime" ) ) { src.ReadToken( &token ); int time; if ( token.type == TT_NUMBER ) { time = ( token.GetIntValue() / 100.0f ) * GetLength(); } else if ( token.type == TT_NAME && !token.Icmp( "end" ) ) { time = TLTIME_END; } else { src.Error( "sdDeclToolTip::ParseTimeline number expected for 'onTime'" ); return false; } timelinePair_t event; event.first = time; if ( timeline.Num() > 0 ) { timelinePair_t lastEvent = timeline.Back(); if ( lastEvent.first > time && time != TLTIME_END ) { src.Error( "sdDeclToolTip::ParseTimeline time events must be in increasing order: '%i'", time ); return false; } } src.ReadToken( &token ); if ( !token.Icmp( "guiEvent" ) ) { event.second.eventType = TL_GUIEVENT; if( !src.ExpectTokenType( TT_STRING, 0, &token ) ) { src.Error( "sdDeclToolTip::ParseTimeline string expected after 'guiEvent'" ); return false; } event.second.arg1 = token; } else if ( !token.Icmp( "pause" ) ) { event.second.eventType = TL_PAUSE; } else if ( !token.Icmp( "unpause" ) ) { event.second.eventType = TL_UNPAUSE; } else if ( !token.Icmp( "showInventory" ) ) { event.second.eventType = TL_SHOWINVENTORY; if( !src.ExpectTokenType( TT_STRING, 0, &token ) ) { src.Error( "sdDeclToolTip::ParseTimeline string expected after 'guiEvent'" ); return false; } event.second.arg1 = token; } else if ( !token.Icmp( "hideInventory" ) ) { event.second.eventType = TL_HIDEINVENTORY; } else if ( !token.Icmp( "waypointHighlight" ) ) { event.second.eventType = TL_WAYPOINTHIGHLIGHT; if( !src.ExpectTokenType( TT_STRING, 0, &token ) ) { src.Error( "sdDeclToolTip::ParseTimeline string expected after 'guiEvent'" ); return false; } event.second.arg1 = token; } else if ( !token.Icmp( "lookAtTask" ) ) { event.second.eventType = TL_LOOKATTASK; } else { src.Error( "sdDeclToolTip::ParseTimeline unexpected timeline event '%s'", token.c_str() ); return false; } timeline.Append( event ); } else if ( !token.Icmp( "unpauseWeaponSlot" ) ) { if( !src.ExpectTokenType( TT_NUMBER, 0, &token ) ) { src.Error( "sdDeclToolTip::ParseTimeline number expected after 'unpauseWeaponSlot'" ); return false; } unpauseWeaponSlot = token.GetIntValue(); if ( unpauseWeaponSlot > 9 || unpauseWeaponSlot < 0 ) { src.Warning( "sdDeclToolTip::ParseTimeline 0-9 expected as value for 'unpauseWeaponSlot'" ); unpauseWeaponSlot = -1; } unpauseKeyString.SetKey( va( "_weapon%i", unpauseWeaponSlot - 1 ) ); } else if( !token.Cmp( "}" ) ) { break; } else { src.Error( "sdDeclToolTip::ParseTimeline Invalid Token '%s'", token.c_str() ); return false; } } return true; }
/* ================ idTypeInfoGen::ParseScope ================ */ void idTypeInfoGen::ParseScope( const char *scope, bool isTemplate, idParser &src, idClassTypeInfo *typeInfo ) { int indent; idToken token; idClassTypeInfo *classInfo; idEnumTypeInfo *enumInfo; idStr varType; bool isConst = false; bool isStatic = false; indent = 1; while( indent ) { if ( !src.ReadToken( &token ) ) { break; } if ( token == "{" ) { do { if ( token == "{" ) { indent++; } else if ( token == "}" ) { indent--; } varType += token + " "; } while( indent > 1 && src.ReadToken( &token ) ); } else if ( token == "}" ) { assert( indent == 1 ); indent--; } else if ( token == "<" ) { do { if ( token == "<" ) { indent++; } else if ( token == ">" ) { indent--; } varType += token + " "; } while( indent > 1 && src.ReadToken( &token ) ); } else if ( token == ";" ) { varType = ""; isConst = false; isStatic = false; } else if ( token == "public" || token == "protected" || token == "private" ) { if ( !src.ExpectTokenString( ":" ) ) { break; } varType = ""; isConst = false; isStatic = false; } else if ( token == "friend" ) { // skip friend classes/methods while( src.ReadToken( &token ) ) { if ( token == "{" ) { indent++; } else if ( token == "}" ) { indent--; if ( indent == 1 ) { break; } } else if ( token == ";" && indent == 1 ) { break; } } varType = ""; isConst = false; isStatic = false; } else if ( token == "template" ) { varType = ""; if ( src.CheckTokenString( "<" ) ) { int indent = 1; varType += "< "; while( src.ReadToken( &token ) ) { if ( token == "<" ) { indent++; } else if ( token == ">" ) { indent--; if ( indent == 0 ) { break; } } varType += token + " "; } varType += ">"; } if ( src.CheckTokenString( "class" ) ) { // parse template class classInfo = ParseClassType( scope, varType, true, false, src ); if ( classInfo ) { classes.Append( classInfo ); } } else { // skip template methods while( src.ReadToken( &token ) ) { if ( token == "{" ) { indent++; } else if ( token == "}" ) { indent--; if ( indent == 1 ) { break; } } else if ( token == ";" && indent == 1 ) { break; } } } varType = ""; isConst = false; isStatic = false; } else if ( token == "namespace" ) { // parse namespace classInfo = ParseClassType( scope, "", isTemplate, false, src ); delete classInfo; } else if ( token == "class" ) { // parse class classInfo = ParseClassType( scope, "", isTemplate, false, src ); if ( classInfo ) { classes.Append( classInfo ); } } else if ( token == "struct" ) { // parse struct classInfo = ParseClassType( scope, "", isTemplate, false, src ); if ( classInfo ) { classes.Append( classInfo ); varType = classInfo->scope + classInfo->typeName; } } else if ( token == "union" ) { // parse union classInfo = ParseClassType( scope, "", isTemplate, false, src ); if ( classInfo ) { classes.Append( classInfo ); } } else if ( token == "enum" ) { // parse enum enumInfo = ParseEnumType( scope, isTemplate, false, src ); if ( enumInfo ) { enums.Append( enumInfo ); varType = enumInfo->scope + enumInfo->typeName; } } else if ( token == "typedef" ) { if ( token == "class" ) { // parse typedef class classInfo = ParseClassType( scope, "", isTemplate, true, src ); if ( classInfo ) { classes.Append( classInfo ); } } else if ( src.CheckTokenString( "struct" ) ) { // parse typedef struct classInfo = ParseClassType( scope, "", isTemplate, true, src ); if ( classInfo ) { classes.Append( classInfo ); } } else if ( src.CheckTokenString( "union" ) ) { // parse typedef union classInfo = ParseClassType( scope, "", isTemplate, true, src ); if ( classInfo ) { classes.Append( classInfo ); } } else if ( src.CheckTokenString( "enum" ) ) { // parse typedef enum enumInfo = ParseEnumType( scope, isTemplate, true, src ); if ( enumInfo ) { enums.Append( enumInfo ); } } else { // skip other typedefs while( src.ReadToken( &token ) ) { if ( token == "{" ) { indent++; } else if ( token == "}" ) { indent--; } else if ( token == ";" && indent == 1 ) { break; } } } varType = ""; isConst = false; isStatic = false; } else if ( token == "const" ) { varType += token + " "; isConst = true; } else if ( token == "static" ) { varType += token + " "; isStatic = true; } else if ( token.type == TT_NAME ) { assert( indent == 1 ); // if this is a class operator if ( token == "operator" ) { while( src.ReadToken( &token ) ) { if ( token == "(" ) { src.UnreadToken( &token ); break; } } } // if this is a class method if ( src.CheckTokenString( "(" ) ) { indent++; while( indent > 1 && src.ReadToken( &token ) ) { if ( token == "(" ) { indent++; } else if ( token == ")" ) { indent--; } } if ( src.CheckTokenString( "(" ) ) { indent++; while( indent > 1 && src.ReadToken( &token ) ) { if ( token == "(" ) { indent++; } else if ( token == ")" ) { indent--; } } } if ( src.CheckTokenString( "const" ) ) { } if ( src.CheckTokenString( "=" ) ) { src.ExpectTokenString( "0" ); } else if ( src.CheckTokenString( "{" ) ) { indent++; while( indent > 1 && src.ReadToken( &token ) ) { if ( token == "{" ) { indent++; } else if ( token == "}" ) { indent--; } } } varType = ""; isConst = false; isStatic = false; } else if ( ( isStatic || isConst ) && src.CheckTokenString( "=" ) ) { // constant idConstantInfo *constantInfo = new idConstantInfo; constantInfo->name = scope + token; constantInfo->type = varType; constantInfo->type.StripTrailing( ' ' ); ParseConstantValue( scope, src, constantInfo->value ); constants.Append( constantInfo ); } else if ( isStatic ) { // static class variable varType += token + " "; } else { // check for class variables while( 1 ) { int arraySize = ParseArraySize( scope, src ); if ( arraySize ) { idClassVariableInfo var; var.name = token; var.type = varType; var.type.StripTrailing( ' ' ); var.type += va( "[%d]", arraySize ); var.bits = 0; typeInfo->variables.Append( var ); if ( !src.CheckTokenString( "," ) ) { varType = ""; isConst = false; isStatic = false; break; } varType.StripTrailing( "* " ); } else { int bits = 0; if ( src.CheckTokenString( ":" ) ) { idToken bitSize; src.ExpectTokenType( TT_NUMBER, TT_INTEGER, &bitSize ); bits = bitSize.GetIntValue(); } if ( src.CheckTokenString( "," ) ) { idClassVariableInfo var; var.name = token; var.type = varType; var.type.StripTrailing( ' ' ); var.bits = bits; typeInfo->variables.Append( var ); varType.StripTrailing( "* " ); } else if ( src.CheckTokenString( ";" ) ) { idClassVariableInfo var; var.name = token; var.type = varType; var.type.StripTrailing( ' ' ); var.bits = bits; typeInfo->variables.Append( var ); varType = ""; isConst = false; isStatic = false; break; } else { varType += token + " "; break; } } while( src.CheckTokenString( "*" ) ) { varType += "* "; } if ( !src.ExpectTokenType( TT_NAME, 0, &token ) ) { break; } } } } else { varType += token + " "; } } }
/* ================ sdPersistentRankInfo::ParseBadge ================ */ bool sdPersistentRankInfo::ParseBadge( idParser& src ) { if ( !src.ExpectTokenString( "{" ) ) { return false; } sdBadge& badge = badges.Alloc(); badge.category = ""; badge.title = ""; idToken token; while ( true ) { if ( src.ReadToken( &token ) == 0 ) { src.Warning( "Unexpected End of File" ); return false; } if ( token.Icmp( "task" ) == 0 ) { idDict taskInfo; if ( !taskInfo.Parse( src ) ) { return false; } sdBadge::sdTask& task = badge.tasks.Alloc(); task.Clear(); task.total = taskInfo.GetFloat( "total" ); task.text = taskInfo.GetString( "text" ); const idKeyValue* match = NULL; while ( ( match = taskInfo.MatchPrefix( "field", match ) ) != NULL ) { task.fields.Alloc() = match->GetValue(); } } else if ( token.Icmp( "category" ) == 0 ) { if ( src.ReadToken( &token ) == 0 ) { return false; } badge.category = token; } else if ( token.Icmp( "title" ) == 0 ) { if ( src.ReadToken( &token ) == 0 ) { return false; } badge.title = token; } else if ( token.Icmp( "level" ) == 0 ) { if ( src.ReadToken( &token ) == 0 ) { return false; } badge.level = token.GetIntValue(); } else if ( token.Icmp( "alwaysAvailable" ) == 0 ) { badge.alwaysAvailable = true; } else if ( token.Icmp( "}" ) == 0 ) { break; } else { src.Warning( "Unexpected Token: '%s'", token.c_str() ); return false; } } return true; }