void MaterialPrecache::PrecacheMaterial(const char *path) { QString shortPath(path); shortPath.remove(".xml"); if (materials.contains(shortPath)) { DBGWARNING("!! Already precached:" << path); return; } std::string fullPath(PATH_MATERIAL_ROOT); fullPath += shortPath.toStdString(); fullPath += ".xml"; Material *material = ParseMaterial(fullPath.c_str()); if (material == nullptr) { DBGWARNING("!! Failed precaching material:" << path); return; } materials.insert(shortPath, material); }
int LuaObjectRenderingImpl::SetMaterial(lua_State* L) { // args=<objID, lodMatNum, matName, matRef> CSolidObject* obj = ParseSolidObject(L, __FUNCTION__, 1, GetObjectType()); if (obj == nullptr) return 0; const string matName = luaL_checkstring(L, 3); const LuaMatType matType = ParseMaterialType(matName); LuaObjectMaterial* objMat = GetObjectMaterial(obj, matName); if (objMat == nullptr) return 0; LuaObjectLODMaterial* lodMat = objMat->GetMaterial(luaL_checknumber(L, 2) - 1); if (lodMat == nullptr) return 0; if (lua_isuserdata(L, 4)) { LuaMatRef** matRef = (LuaMatRef**) luaL_checkudata(L, 4, "MatRef"); if (matRef) { lodMat->matref = **matRef; } } else { lodMat->matref = ParseMaterial(L, 4, matType); } return 0; }
/** * Initializes the MaterialDoc instance with a specific idMaterial. This method will * parse the material into the internal dictionary representation and optionally * allow the idMaterial object to reparse the source. * @param material The idMaterial instance to use. * @param parseMaterial Flag to determine if the material should be parsed into the editor representation. * @param parseRenderMaterial Flag to determine if the idMaterial object should be reparsed. */ void MaterialDoc::SetRenderMaterial(idMaterial* material, bool parseMaterial, bool parseRenderMatierial) { renderMaterial = material; if(!parseMaterial || !renderMaterial) return; if(parseRenderMatierial) { char *declText = (char *) _alloca( material->GetTextLength() + 1 ); material->GetText( declText ); renderMaterial->GetText(declText); ParseMaterialText(declText); } ClearEditMaterial(); name = material->GetName(); idLexer src; char *declText = (char *) _alloca( material->GetTextLength() + 1 ); material->GetText( declText ); renderMaterial->GetText(declText); src.LoadMemory(declText, strlen(declText), "Material"); ParseMaterial(&src); }
bool ObjectImporter::Import (std::wstring file, __out std::vector<int>* identifiers) { if(file == L"") return false; std::wifstream in (file); if(!in.is_open()) return false; std::wstring buff; int mid = -1; while (!in.eof()) { in >> buff; if(buff == ObjImpFormat::material) { mid = ParseMaterial(in); if(mid != -1) { identifiers->push_back(mid); } } in.close(); } return true; }
int LuaObjectRenderingImpl::GetMaterial(lua_State* L) { const LuaMatType matType = ParseMaterialType(luaL_checkstring(L, 1)); if (!lua_istable(L, 2)) luaL_error(L, "Incorrect arguments to GetMaterial"); LuaMatRef** matRef = (LuaMatRef**) lua_newuserdata(L, sizeof(LuaMatRef*)); luaL_getmetatable(L, "MatRef"); lua_setmetatable(L, -2); *matRef = new LuaMatRef; **matRef = ParseMaterial(L, 2, matType); return 1; }
bool XFileUtils::LoadMesh( ID3DXFileData* pFileData, IDirect3DDevice9* pDevice, ID3DXMesh** pNewMesh, ID3DXBuffer** pMaterial, DWORD* pNumAttribute, GSkinInfo** pNewSkininfo) { //检查类型 _XCheckType(pFileData, "Mesh", false); DWORD nVertices = 0; DWORD nFaces = 0; _XCheckExcute(ParseBasemesh(pFileData, &nVertices, &nFaces, nullptr, nullptr, sizeof(XVertex_p3_n3_t1))); ID3DXMesh* pMesh = nullptr; if (FAILED(D3DXCreateMeshFVF(nFaces, nVertices, D3DXMESH_32BIT | D3DXMESH_MANAGED, XVertex_p3_n3_t1::fvf, pDevice, &pMesh))) return false; void* pVertices = nullptr; DWORD* pIndices = nullptr; DWORD* pAttribtues = nullptr; pMesh->LockVertexBuffer(0, &pVertices); pMesh->LockIndexBuffer(0, (void**)&pIndices); pMesh->LockAttributeBuffer(0, &pAttribtues); _XCheckExcute(ParseBasemesh(pFileData, &nVertices, &nFaces, pVertices, pIndices, sizeof(XVertex_p3_n3_t1))); _XCheckExcute(ParseNormals(pFileData, nVertices, pVertices, pIndices, sizeof(XVertex_p3_n3_t1), sizeof(D3DXVECTOR3))); _XCheckExcute(ParseTexcoord(pFileData, pVertices, sizeof(XVertex_p3_n3_t1), sizeof(D3DXVECTOR3) * 2)); _XCheckExcute(ParseMaterial(pFileData, pAttribtues, nFaces, pNumAttribute, pMaterial)); pMesh->UnlockAttributeBuffer(); pMesh->UnlockIndexBuffer(); pMesh->UnlockVertexBuffer(); *pNewMesh = pMesh; ParseSkinInfo(pFileData, pNewSkininfo); return true; }
bool ParseStandardFile (std::wifstream& in, ImportedObjectData* d) { std::wstring flag; bool result = true; while(!in.eof()) { in >> flag; if(!in.eof()) { if(flag == ObjImpFormat::vertexCount) { int count = 0; if(!ParseInteger(in, count)) { DisplayText("File:\n" + in.getloc().name() + "\nDoes not contain any vertex information"); return false; } else if(!count) { DisplayText("File:\n" + in.getloc().name() + "\nHas invalid vertex count (0)"); return false; } //No animations, then only one mesh is valid d->objects.resize(1); d->objects[0].vertex = new std::vector<VERTEX::VertexPNT>(count); d->objects[0].material = 0; } else if(flag == ObjImpFormat::material) { d->objects[0].material = ParseMaterial(in); } else if(flag == ObjImpFormat::v) { result = ParseV(in,d->objects[0]); } else if(flag == ObjImpFormat::vt) { result = ParseVT(in,d->objects[0]); } else if(flag == ObjImpFormat::vn) { result = ParseVN(in,d->objects[0]); } else if(flag == ObjImpFormat::comment) { ParseLine(in, true); } if(!result) return result; } } return result; }
/** * Applies any source changes to the edit representation of the material. */ void MaterialDoc::ApplySourceModify(idStr& text) { if(sourceModify) { //Changes in the source need to clear any undo redo buffer because we have no idea what has changed manager->ClearUndo(); manager->ClearRedo(); ClearEditMaterial(); idLexer src; src.LoadMemory(text, text.Length(), "Material"); src.SetFlags( LEXFL_NOSTRINGCONCAT | // multiple strings seperated by whitespaces are not concatenated LEXFL_NOSTRINGESCAPECHARS | // no escape characters inside strings LEXFL_ALLOWPATHNAMES | // allow path seperators in names LEXFL_ALLOWMULTICHARLITERALS | // allow multi character literals LEXFL_ALLOWBACKSLASHSTRINGCONCAT | // allow multiple strings seperated by '\' to be concatenated LEXFL_NOFATALERRORS // just set a flag instead of fatal erroring ); idToken token; if(!src.ReadToken(&token)) { src.Warning( "Missing decl name" ); return; } ParseMaterial(&src); sourceModify = false; //Check to see if the name has changed if(token.Icmp(name)) { SetMaterialName(token, false); } } }
ModelData* ModelLoader::LoadModelFile(std::string filePath) { ifstream file; file.open(filePath + ".obj"); if (!file) return 0; string str; while (!file.eof()) { file >> str; if (str == "#" || str == "s") ParseComment(file); else if (str == "v") ParsePosition(file); //position else if (str == "vn") ParseNormal(file); //normal else if (str == "vt") ParseTexCoord(file); //texturkoordinat else if (str == "f") ParseFace(file); //face else if (str == "usemtl") ParseMaterial(file); //material else if (str == "g") ParseGroup(file); //group else if (str == "mtllib") //materialfile { ParseMaterialFile(file, filePath); } str = ""; } //ParseFace2(file); ModelData* model = new ModelData(); for (auto it = m_groups.begin(); it != m_groups.end(); ++it) model->Groups.push_back(it->second); return model; }
void ObjParser::Load(LPCSTR Filename, LPDIRECT3DDEVICE9 pDevice) { FILE* fileHandle = fopen(Filename, "r+"); if( fileHandle == NULL ) return; char line[256]; D3DXVECTOR3 vec; while( !feof(fileHandle) )//Foreach Line { fgets(line, 256, fileHandle); #pragma region Line Read switch(line[0]) { case 'm': { LPCSTR name = new CHAR[256]; sscanf_s(line, "mtllib %s", name, 255); ParseMaterial(name); } break; case 'v'://Vertex Item { switch(line[1]) { case ' '://Vertex { sscanf_s(line, "v %f %f %f", &vec.x, &vec.y, &vec.z ); Vertexs.push_back(vec); mVertexsHT.push_back(NULL);//expand HashTable } break; case 't'://Texture Coordinates { D3DXVECTOR3 tex; sscanf_s(line, "vt %f %f %f", &vec.x, &vec.y, &vec.z); Textures.push_back(vec); } break; case 'n'://Normal { D3DXVECTOR3 nor; sscanf_s(line, "vn %f %f %f", &vec.x, &vec.y, &vec.z ); Normals.push_back(vec); } break; default:// Not supposed to happen assert( false ); } } break; case 'f'://Face Item { DWORD quadP[4];//Position Index quad DWORD quadT[4];//Texture Index quad DWORD quadN[4];//Normal Index quad memset(quadP, -1, sizeof(DWORD)*4); memset(quadT, -1, sizeof(DWORD)*4); memset(quadN, -1, sizeof(DWORD)*4); int size = strlen(line); int barCount = std::count(line, line+size, '/'); int readed = 0; //By default .obj file puts faces with CW winding switch( barCount ) { case 0:// tri/quad pos { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d %d %d %d", &quadP[3], &quadP[2], &quadP[1], &quadP[0] ); else readed = sscanf_s(line, "f %d %d %d %d", &quadP[0], &quadP[1], &quadP[2], &quadP[3] ); assert( readed == 3 || readed == 4 ); } break; case 3:// tri pos/tex { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d/%d %d/%d %d/%d", &quadP[2], &quadT[2], &quadP[1], &quadT[1], &quadP[0], &quadT[0] ); else readed = sscanf_s(line, "f %d/%d %d/%d %d/%d", &quadP[0], quadT[0], &quadP[1], quadT[1], &quadP[2], quadT[2] ); assert( readed == 6 ); readed /= 2; } break; case 4:// quad pos/tex { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d/%d %d/%d %d/%d %d/%d", &quadP[3], &quadT[3], &quadP[2], &quadT[2], &quadP[1], &quadT[1], &quadP[0], &quadT[0] ); else readed = sscanf_s(line, "f %d/%d %d/%d %d/%d %d/%d", &quadP[0], &quadT[0], &quadP[1], &quadT[1], &quadP[2], &quadT[2], &quadP[3], &quadT[3] ); assert( readed == 8 ); readed /= 2; } break; case 6:// tri pos/tex/nor { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d", &quadP[2], &quadT[2], &quadN[2], &quadP[1], &quadT[1], &quadN[1], &quadP[0], &quadT[0], &quadN[0] ); else readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d", &quadP[0], &quadT[0], &quadN[0], &quadP[1], &quadT[1], &quadN[1], &quadP[2], &quadT[2], &quadN[2] ); assert( readed == 9 ); readed /= 3; } break; case 8:// quad pos/tex/nor { if( m_Winding == VertexWinding::CCW ) readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", &quadP[3], &quadT[3], &quadN[3], &quadP[2], &quadT[2], &quadN[2], &quadP[1], &quadT[1], &quadN[1], &quadP[0], &quadT[0], &quadN[0] ); else readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", &quadP[0], &quadT[0], &quadN[0], &quadP[1], &quadT[1], &quadN[1], &quadP[2], &quadT[2], &quadN[2], &quadP[3], &quadT[3], &quadN[3] ); assert( readed == 12 ); readed /= 3; } break; default:// Not supposed to happen assert( false ); } //The indexs are in 1 Base, we transform to 0 Base for( int i=0; i < 4 ; ++i ) { quadP[i]--; quadT[i]--; quadN[i]--; } for(int j=0; j < 3 ; ++j) { VertexTextureNormal NewVertex; NewVertex.SetPosition( Vertexs[quadP[j]] ); if( quadT[j] != (DWORD(-1)-1) ) NewVertex.SetTexture ( Textures[quadT[j]].x, Textures[quadT[j]].y ); if( quadN[j] != (DWORD(-1)-1) ) NewVertex.SetNormal ( Normals[quadN[j]] ); DWORD index = AddVertex(quadP[j], NewVertex); mIndexs.push_back(index); } if( readed == 4 )// quad readed { quadP[1] = quadP[2]; quadT[1] = quadT[2]; quadN[1] = quadN[2]; quadP[2] = quadP[3]; quadT[2] = quadT[3]; quadN[1] = quadN[2]; for(int j=0; j < 3 ; ++j) { VertexTextureNormal NewVertex; NewVertex.SetPosition( Vertexs[quadP[j]] ); if( quadT[j] != (DWORD(-1)-1) ) NewVertex.SetTexture ( Textures[quadT[j]].x, Textures[quadT[j]].y ); if( quadN[j] != (DWORD(-1)-1) ) NewVertex.SetNormal ( Normals[quadN[j]] ); DWORD index = AddVertex(quadP[j], NewVertex); mIndexs.push_back(index); } } } break; } #pragma endregion } fclose(fileHandle); DWORD FVF = NULL; D3DVERTEXELEMENT9* pMeshVDeclaration = NULL; int code = 0; IdentifieLoadedFormat(FVF, pMeshVDeclaration, code); if( code == 0 ) return; //Setup Mesh with VertexDeclaration corresponding to the loaded data LPD3DXMESH pMesh = NULL; HRESULT hr = NULL; int FacesCount = mIndexs.size()/3; switch( m_VertexMetaFormat ) { case VertexMetaFormat::VertexDeclaration: { if( FacesCount > 65535 )// if huge mesh, 32 bits face index hr = D3DXCreateMesh(FacesCount, mVertexs.size(), D3DXMESH_32BIT | D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , pMeshVDeclaration, pDevice, &pMesh); else hr = D3DXCreateMesh(FacesCount, mVertexs.size(), D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , pMeshVDeclaration, pDevice, &pMesh); } break; case VertexMetaFormat::FVF: { if( FacesCount > 65535 )// if huge mesh, 32 bits face index hr = D3DXCreateMeshFVF(FacesCount, Vertexs.size(), D3DXMESH_32BIT | D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , FVF, pDevice, &pMesh); else hr = D3DXCreateMeshFVF(FacesCount, Vertexs.size(), D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , FVF, pDevice, &pMesh); } break; default: assert( false ); } assert( !FAILED(hr) ); //Puts vertex data inside loadedData in the smallest format needed //(not nesesarily VertexTextureNormal) void* loadedData = NULL; void* loadedIndex = NULL; size_t size = 0; //Pass to our vertex format PutLoadedDataInVertexDeclarationFormat(loadedData,loadedIndex,size,code, FacesCount); //Free Auxiliary Arrays Vertexs.clear(); Textures.clear(); Normals.clear(); mVertexsHT.clear(); void* data = NULL; //Loads the Vertex Buffer if( FAILED(pMesh->LockVertexBuffer(NULL, &data)) ) return; memcpy(data, loadedData, size*mVertexs.size()); pMesh->UnlockVertexBuffer(); //Loads the Index Buffer if( FAILED(pMesh->LockIndexBuffer(NULL, &data)) ) return; if( FacesCount > 65535 ) memcpy(data, loadedIndex, sizeof(DWORD)*mIndexs.size()); else memcpy(data, loadedIndex, sizeof(WORD)*mIndexs.size()); pMesh->UnlockIndexBuffer(); //Free main Arrays mVertexs.clear(); mIndexs.clear(); //Mesh data ready m_RootMeshContainer = new D3DXMESHCONTAINER; m_RootMeshContainer->MeshData.pMesh = pMesh; return; }
bool ParseAnimationFile (std::wifstream& in, ImportedObjectData* d) { std::wstring flag; bool result = true; int vCount = 0; int currFrame = -1; int currObject = -1; int currAnimation = -1; int currMaterial = -1; int totMeshCount = -1; while(!in.eof()) { in >> flag; if(in.eof()) break; if(flag == ObjImpFormat::vertexCount) { if(!ParseInteger(in, vCount)) { DisplayText("File:\n" + in.getloc().name() + "\nDoes not contain any vertex information"); return false; } } else if(flag == ObjImpFormat::animation) { currAnimation++; int frameCount = 0; if(!ParseInteger(in, d->animations[currAnimation].id)) return false; if(!ParseInteger(in, frameCount)) return false; if(!frameCount) return false; d->animations[currAnimation].frames.resize(frameCount); currFrame = -1; } else if(flag == ObjImpFormat::frame) { float frameTime = 0.0f; int frameNum = -1; if(!ParseInteger(in, frameNum)) return false; if(!ParseFloat(in, frameTime)) { char temp1[2]; _itoa_s(frameNum, temp1, 10); DisplayText("File:\n" + in.getloc().name() + "\nFrame: " + temp1 + "\nInvalid frame time"); return false; } if(frameTime < 0.0f) return false; d->objects.push_back(ObjectData()); currObject = (int)d->objects.size()-1; currFrame++; totMeshCount++; d->animations[currAnimation].frames[currFrame].frameNumber = frameNum; d->animations[currAnimation].frames[currFrame].frameTime = frameTime; d->animations[currAnimation].frames[currFrame].objectIndex = currFrame; d->objects[totMeshCount].vertex = new std::vector<VERTEX::VertexPNT>(vCount); d->objects[totMeshCount].material = currMaterial; } else if(flag == ObjImpFormat::material) { currMaterial = ParseMaterial(in); } else if(flag == ObjImpFormat::v) { result = ParseV(in,d->objects[totMeshCount]); } else if(flag == ObjImpFormat::vt) { result = ParseVT(in,d->objects[totMeshCount]); } else if(flag == ObjImpFormat::vn) { result = ParseVN(in,d->objects[totMeshCount]); } else if(flag == ObjImpFormat::comment) { ParseLine(in, true); } if(!result) return result; } return result; }
void PartSysParser::ParseEmitter(const TabFileRecord& record) { auto systemName = record[COL_PARTSYS_NAME].AsString(); auto& system = mSpecs[tolower(systemName)]; // Create it on demand if (!system) { system = std::make_shared<PartSysSpec>(systemName); } // Add the emitter auto emitter = system->CreateEmitter(record[COL_EMITTER_NAME].AsString()); ParseOptionalFloat(record, COL_DELAY, "Delay", [&] (float value) { emitter->SetDelay(value / 30.0f); }); ParseLifespan(record, emitter); ParseParticleLifespan(record, emitter); ParseParticleRate(record, emitter); ParseOptionalEnum<PartSysEmitterSpace>(record, COL_EMITTER_SPACE, "emitter space", EmitterSpaceMapping, [&](auto space) { emitter->SetSpace(space); }); ParseEmitterNodeName(record, emitter); ParseOptionalEnum<PartSysCoordSys>(record, COL_EMITTER_COORD_SYS, "emitter coord sys", CoordSysMapping, [&](auto coordSys) { emitter->SetCoordSys(coordSys); }); ParseOptionalEnum<PartSysCoordSys>(record, COL_EMITTER_OFFSET_COORD_SYS, "emitter offset coord sys", CoordSysMapping, [&](auto coordSys) { emitter->SetOffsetCoordSys(coordSys); }); ParseOptionalEnum<PartSysParticleType>(record, COL_PARTICLE_TYPE, "particle type", ParticleTypeMapping, [&](PartSysParticleType type) { emitter->SetParticleType(type); }); ParseOptionalEnum<PartSysBlendMode>(record, COL_BLEND_MODE, "blend mode", BlendModeMapping, [&](auto mode) { emitter->SetBlendMode(mode); }); ParseMaterial(record, emitter); ParseOptionalEnum<PartSysCoordSys>(record, COL_PARTICLE_POS_COORD_SYS, "particle pos coord sys", CoordSysMapping, [&](auto coordSys) { emitter->SetParticlePosCoordSys(coordSys); }); ParseOptionalEnum<PartSysCoordSys>(record, COL_PARTICLE_VELOCITY_COORD_SYS, "particle velocity coord sys", CoordSysMapping, [&](auto coordSys) { emitter->SetParticleVelocityCoordSys(coordSys); }); ParseOptionalEnum<PartSysParticleSpace>(record, COL_PARTICLE_SPACE, "particle space", ParticleSpaceMapping, [&](auto space) { emitter->SetParticleSpace(space); }); ParseMesh(record, emitter); // Parse the bounding box ParseOptionalFloat(record, COL_BB_LEFT, "bb left", [&](float val) { emitter->SetBoxLeft(val); }); ParseOptionalFloat(record, COL_BB_TOP, "bb top", [&](float val) { emitter->SetBoxTop(val); }); ParseOptionalFloat(record, COL_BB_RIGHT, "bb right", [&](float val) { emitter->SetBoxRight(val); }); ParseOptionalFloat(record, COL_BB_BOTTOM, "bb bottom", [&](float val) { emitter->SetBoxBottom(val); }); for (int paramId = 0; paramId <= part_attractorBlend; paramId++) { int colIdx = 22 + paramId; auto col = record[colIdx]; if (col) { bool success; std::unique_ptr<PartSysParam> param(ParserParams::Parse((PartSysParamId) paramId, col, emitter->GetLifespan(), emitter->GetParticleLifespan(), success)); if (success) { emitter->SetParam((PartSysParamId)paramId, param); } else { logger->warn("Unable to parse particle system param {} for particle system {} and emitter {} with value {}", paramId, systemName, emitter->GetName(), col.AsString()); } } } }