//----------------------------------------------------------------------------- // Loads and parses the given JSON file pathname and returns a JSON object tree. // The returned object must be Released after use. JSON* JSON::Load(const char* path, const char** perror) { SysFile f; if (!f.Open(path, File::Open_Read, File::Mode_Read)) { AssignError(perror, "Failed to open file"); return NULL; } int len = f.GetLength(); uint8_t* buff = (uint8_t*)OVR_ALLOC(len + 1); int bytes = f.Read(buff, len); f.Close(); if (bytes == 0 || bytes != len) { OVR_FREE(buff); return NULL; } // Ensure the result is null-terminated since Parse() expects null-terminated input. buff[len] = '\0'; JSON* json = JSON::Parse((char*)buff, perror); OVR_FREE(buff); return json; }
BinaryReader::BinaryReader( const char * path, const char ** perror ) : Data( NULL ), Size( 0 ), Offset( 0 ), Allocated( true ) { SysFile f; if ( !f.Open( path, File::Open_Read, File::Mode_Read ) ) { if ( perror != NULL ) { *perror = "Failed to open file"; } return; } Size = f.GetLength(); Data = (UByte*) OVR_ALLOC( Size + 1 ); int bytes = f.Read( (UByte *)Data, Size ); if ( bytes != Size && perror != NULL ) { *perror = "Failed to read file"; } f.Close(); }
// Loads a texture from a disk TGA file. IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, const char* pFilePath, uint8_t alpha) { SysFile sysFile; if(sysFile.Open(pFilePath, FileConstants::Open_Read | FileConstants::Open_Buffered)) return LoadTextureTga(rParams, &sysFile, alpha); return NULL; }
//----------------------------------------------------------------------------- // Serializes the JSON object and writes to the give file path bool JSON::Save(const char* path) { SysFile f; if (!f.Open(path, File::Open_Write | File::Open_Create | File::Open_Truncate, File::Mode_Write)) return false; char* text = PrintValue(0, true); if (text) { intptr_t len = OVR_strlen(text); OVR_ASSERT(len <= (intptr_t)(int)len); int bytes = f.Write((uint8_t*)text, (int)len); f.Close(); OVR_FREE(text); return (bytes == len); } else { return false; } }
bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRender, OVR::Render::Scene* pScene, OVR::Array<Ptr<CollisionModel> >* pCollisions, OVR::Array<Ptr<CollisionModel> >* pGroundCollisions, bool srgbAware /*= false*/, bool anisotropic /*= false*/) { if(pXmlDocument->LoadFile(fileName) != 0) { return false; } // Extract the relative path to our working directory for loading textures filePath[0] = 0; intptr_t pos = 0; intptr_t len = strlen(fileName); for(intptr_t i = len; i > 0; i--) { if (fileName[i-1]=='\\' || fileName[i-1]=='/') { memcpy(filePath, fileName, i); filePath[i] = 0; break; } } // Load the textures OVR_DEBUG_LOG_TEXT(("Loading textures...")); XMLElement* pXmlTexture = pXmlDocument->FirstChildElement("scene")->FirstChildElement("textures"); OVR_ASSERT(pXmlTexture); if (pXmlTexture) { pXmlTexture->QueryIntAttribute("count", &textureCount); pXmlTexture = pXmlTexture->FirstChildElement("texture"); } for(int i = 0; i < textureCount; ++i) { const char* textureName = pXmlTexture->Attribute("fileName"); intptr_t dotpos = strcspn(textureName, "."); char fname[300]; if (pos == len) { OVR_sprintf(fname, 300, "%s", textureName); } else { OVR_sprintf(fname, 300, "%s%s", filePath, textureName); } int textureLoadFlags = 0; textureLoadFlags |= srgbAware ? TextureLoad_SrgbAware : 0; textureLoadFlags |= anisotropic ? TextureLoad_Anisotropic : 0; SysFile* pFile = new SysFile(fname); Ptr<Texture> texture; if (textureName[dotpos + 1] == 'd' || textureName[dotpos + 1] == 'D') { // DDS file Texture* tmp_ptr = LoadTextureDDSTopDown(pRender, pFile, textureLoadFlags); if(tmp_ptr) { texture.SetPtr(*tmp_ptr); } } else { Texture* tmp_ptr = LoadTextureTgaTopDown(pRender, pFile, textureLoadFlags, 255); if(tmp_ptr) { texture.SetPtr(*tmp_ptr); } } Textures.PushBack(texture); pFile->Close(); pFile->Release(); pXmlTexture = pXmlTexture->NextSiblingElement("texture"); } OVR_DEBUG_LOG_TEXT(("Done.\n")); // Load the models pXmlDocument->FirstChildElement("scene")->FirstChildElement("models")-> QueryIntAttribute("count", &modelCount); OVR_DEBUG_LOG(("Loading models... %i models to load...", modelCount)); XMLElement* pXmlModel = pXmlDocument->FirstChildElement("scene")-> FirstChildElement("models")->FirstChildElement("model"); for(int i = 0; i < modelCount; ++i) { if (i % 15 == 0) { OVR_DEBUG_LOG_TEXT(("%i models remaining...", modelCount - i)); } const char* name = pXmlModel->Attribute("name"); Models.PushBack(*new Model(Prim_Triangles, name)); bool isCollisionModel = false; pXmlModel->QueryBoolAttribute("isCollisionModel", &isCollisionModel); Models[i]->IsCollisionModel = isCollisionModel; if (isCollisionModel) { Models[i]->Visible = false; } bool tree_c = (strcmp(name, "tree_C") == 0) || (strcmp(name, "Object03") == 0); //read the vertices OVR::Array<Vector3f> *vertices = new OVR::Array<Vector3f>(); ParseVectorString(pXmlModel->FirstChildElement("vertices")->FirstChild()-> ToText()->Value(), vertices); for (unsigned int vertexIndex = 0; vertexIndex < vertices->GetSize(); ++vertexIndex) { vertices->At(vertexIndex).x *= -1.0f; if (tree_c) { // Move the terrace tree closer to the house vertices->At(vertexIndex).z += 0.5; } } //read the normals OVR::Array<Vector3f> *normals = new OVR::Array<Vector3f>(); ParseVectorString(pXmlModel->FirstChildElement("normals")->FirstChild()-> ToText()->Value(), normals); for (unsigned int normalIndex = 0; normalIndex < normals->GetSize(); ++normalIndex) { normals->At(normalIndex).z *= -1.0f; } //read the textures OVR::Array<Vector3f> *diffuseUVs = new OVR::Array<Vector3f>(); OVR::Array<Vector3f> *lightmapUVs = new OVR::Array<Vector3f>(); int diffuseTextureIndex = -1; int lightmapTextureIndex = -1; XMLElement* pXmlCurMaterial = pXmlModel->FirstChildElement("material"); while(pXmlCurMaterial != NULL) { if(pXmlCurMaterial->Attribute("name", "diffuse")) { pXmlCurMaterial->FirstChildElement("texture")-> QueryIntAttribute("index", &diffuseTextureIndex); if(diffuseTextureIndex > -1) { ParseVectorString(pXmlCurMaterial->FirstChildElement("texture")-> FirstChild()->ToText()->Value(), diffuseUVs, true); } } else if(pXmlCurMaterial->Attribute("name", "lightmap")) { pXmlCurMaterial->FirstChildElement("texture")-> QueryIntAttribute("index", &lightmapTextureIndex); if(lightmapTextureIndex > -1) { XMLElement* firstChildElement = pXmlCurMaterial->FirstChildElement("texture"); XMLNode* firstChild = firstChildElement->FirstChild(); XMLText* text = firstChild->ToText(); const char* value = text->Value(); ParseVectorString(value, lightmapUVs, true); } } pXmlCurMaterial = pXmlCurMaterial->NextSiblingElement("material"); } //set up the shader Ptr<ShaderFill> shader = *new ShaderFill(*pRender->CreateShaderSet()); shader->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Vertex, VShader_MVP)); if(diffuseTextureIndex > -1) { shader->SetTexture(0, Textures[diffuseTextureIndex]); if(lightmapTextureIndex > -1) { shader->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_MultiTexture)); shader->SetTexture(1, Textures[lightmapTextureIndex]); } else { shader->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_Texture)); } } else { shader->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_LitGouraud)); } Models[i]->Fill = shader; //add all the vertices to the model const size_t numVerts = vertices->GetSize(); for(size_t v = 0; v < numVerts; ++v) { if(diffuseTextureIndex > -1) { if(lightmapTextureIndex > -1) { Models[i]->AddVertex(vertices->At(v).z, vertices->At(v).y, vertices->At(v).x, Color(255, 255, 255), diffuseUVs->At(v).x, diffuseUVs->At(v).y, lightmapUVs->At(v).x, lightmapUVs->At(v).y, normals->At(v).x, normals->At(v).y, normals->At(v).z); } else { Models[i]->AddVertex(vertices->At(v).z, vertices->At(v).y, vertices->At(v).x, Color(255, 255, 255), diffuseUVs->At(v).x, diffuseUVs->At(v).y, 0, 0, normals->At(v).x, normals->At(v).y, normals->At(v).z); } } else { Models[i]->AddVertex(vertices->At(v).z, vertices->At(v).y, vertices->At(v).x, Color(255, 255, 255, 255), 0, 0, 0, 0, normals->At(v).x, normals->At(v).y, normals->At(v).z); } } // Read the vertex indices for the triangles const char* indexStr = pXmlModel->FirstChildElement("indices")-> FirstChild()->ToText()->Value(); size_t stringLength = strlen(indexStr); for(size_t j = 0; j < stringLength; ) { size_t k = j + 1; for(; k < stringLength; ++k) { if (indexStr[k] == ' ') break; } char text[20]; for(size_t l = 0; l < k - j; ++l) { text[l] = indexStr[j + l]; } text[k - j] = '\0'; Models[i]->Indices.PushBack((unsigned short)atoi(text)); j = k + 1; } // Reverse index order to match original expected orientation Array<uint16_t>& indices = Models[i]->Indices; size_t indexCount = indices.GetSize(); for (size_t revIndex = 0; revIndex < indexCount/2; revIndex++) { unsigned short itemp = indices[revIndex]; indices[revIndex] = indices[indexCount - revIndex - 1]; indices[indexCount - revIndex - 1] = itemp; } delete vertices; delete normals; delete diffuseUVs; delete lightmapUVs; pScene->World.Add(Models[i]); pScene->Models.PushBack(Models[i]); pXmlModel = pXmlModel->NextSiblingElement("model"); } OVR_DEBUG_LOG(("Done.")); //load the collision models OVR_DEBUG_LOG(("Loading collision models... ")); XMLElement* pXmlCollisionModel = pXmlDocument->FirstChildElement("scene")->FirstChildElement("collisionModels"); if (pXmlCollisionModel) { pXmlCollisionModel->QueryIntAttribute("count", &collisionModelCount); pXmlCollisionModel = pXmlCollisionModel->FirstChildElement("collisionModel"); } XMLElement* pXmlPlane = NULL; for(int i = 0; i < collisionModelCount; ++i) { Ptr<CollisionModel> cm = *new CollisionModel(); int planeCount = 0; OVR_ASSERT(pXmlCollisionModel != NULL); // collisionModelCount should guarantee this. if (pXmlCollisionModel) { pXmlCollisionModel->QueryIntAttribute("planeCount", &planeCount); pXmlPlane = pXmlCollisionModel->FirstChildElement("plane"); for(int j = 0; j < planeCount; ++j) { Vector3f norm; pXmlPlane->QueryFloatAttribute("nx", &norm.x); pXmlPlane->QueryFloatAttribute("ny", &norm.y); pXmlPlane->QueryFloatAttribute("nz", &norm.z); float D; pXmlPlane->QueryFloatAttribute("d", &D); D -= 0.5f; if (i == 26) D += 0.5f; // tighten the terrace collision so player can move right up to rail Planef p(norm.z, norm.y, norm.x * -1.0f, D); cm->Add(p); pXmlPlane = pXmlPlane->NextSiblingElement("plane"); } if (pCollisions) pCollisions->PushBack(cm); pXmlCollisionModel = pXmlCollisionModel->NextSiblingElement("collisionModel"); } } OVR_DEBUG_LOG(("done.")); //load the ground collision models OVR_DEBUG_LOG(("Loading ground collision models...")); pXmlCollisionModel = pXmlDocument->FirstChildElement("scene")->FirstChildElement("groundCollisionModels"); OVR_ASSERT(pXmlCollisionModel); if (pXmlCollisionModel) { pXmlCollisionModel->QueryIntAttribute("count", &groundCollisionModelCount); pXmlCollisionModel = pXmlCollisionModel->FirstChildElement("collisionModel"); pXmlPlane = NULL; for(int i = 0; i < groundCollisionModelCount; ++i) { Ptr<CollisionModel> cm = *new CollisionModel(); int planeCount = 0; pXmlCollisionModel->QueryIntAttribute("planeCount", &planeCount); pXmlPlane = pXmlCollisionModel->FirstChildElement("plane"); for(int j = 0; j < planeCount; ++j) { Vector3f norm; pXmlPlane->QueryFloatAttribute("nx", &norm.x); pXmlPlane->QueryFloatAttribute("ny", &norm.y); pXmlPlane->QueryFloatAttribute("nz", &norm.z); float D = 0.f; pXmlPlane->QueryFloatAttribute("d", &D); Planef p(norm.z, norm.y, norm.x * -1.0f, D); cm->Add(p); pXmlPlane = pXmlPlane->NextSiblingElement("plane"); } if (pGroundCollisions) pGroundCollisions->PushBack(cm); pXmlCollisionModel = pXmlCollisionModel->NextSiblingElement("collisionModel"); } } OVR_DEBUG_LOG(("done.")); return true; }