00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "Render_XmlSceneLoader.h"
00025 #include <Kernel/OVR_Log.h>
00026
00027 #ifdef OVR_DEFINE_NEW
00028 #undef new
00029 #endif
00030
00031 namespace OVR { namespace Render {
00032
00033 XmlHandler::XmlHandler() : pXmlDocument(NULL)
00034 {
00035 pXmlDocument = new tinyxml2::XMLDocument();
00036 }
00037
00038 XmlHandler::~XmlHandler()
00039 {
00040 delete pXmlDocument;
00041 }
00042
00043 bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRender,
00044 OVR::Render::Scene* pScene,
00045 OVR::Array<Ptr<CollisionModel> >* pCollisions,
00046 OVR::Array<Ptr<CollisionModel> >* pGroundCollisions)
00047 {
00048 if(pXmlDocument->LoadFile(fileName) != 0)
00049 {
00050 return false;
00051 }
00052
00053
00054 filePath[0] = 0;
00055 SPInt pos = 0;
00056 SPInt len = strlen(fileName);
00057 for(SPInt i = len; i > 0; i--)
00058 {
00059 if (fileName[i-1]=='\\' || fileName[i-1]=='/')
00060 {
00061 memcpy(filePath, fileName, i);
00062 filePath[i] = 0;
00063 break;
00064 }
00065 }
00066
00067
00068 OVR_DEBUG_LOG_TEXT(("Loading textures..."));
00069 XMLElement* pXmlTexture = pXmlDocument->FirstChildElement("scene")->FirstChildElement("textures");
00070 if (pXmlTexture)
00071 {
00072 pXmlTexture->QueryIntAttribute("count", &textureCount);
00073 pXmlTexture = pXmlTexture->FirstChildElement("texture");
00074 }
00075
00076 for(int i = 0; i < textureCount; ++i)
00077 {
00078 const char* textureName = pXmlTexture->Attribute("fileName");
00079 SPInt dotpos = strcspn(textureName, ".");
00080 char fname[300];
00081
00082 if (pos == len)
00083 {
00084 OVR_sprintf(fname, 300, "%s", textureName);
00085 }
00086 else
00087 {
00088 OVR_sprintf(fname, 300, "%s%s", filePath, textureName);
00089 }
00090
00091 SysFile* pFile = new SysFile(fname);
00092 Ptr<Texture> texture;
00093 if (textureName[dotpos + 1] == 'd' || textureName[dotpos + 1] == 'D')
00094 {
00095
00096 texture.SetPtr(*LoadTextureDDS(pRender, pFile));
00097 }
00098 else
00099 {
00100 texture.SetPtr(*LoadTextureTga(pRender, pFile));
00101 }
00102
00103 Textures.PushBack(texture);
00104 pFile->Close();
00105 pFile->Release();
00106 pXmlTexture = pXmlTexture->NextSiblingElement("texture");
00107 }
00108 OVR_DEBUG_LOG_TEXT(("Done.\n"));
00109
00110
00111 pXmlDocument->FirstChildElement("scene")->FirstChildElement("models")->
00112 QueryIntAttribute("count", &modelCount);
00113
00114 OVR_DEBUG_LOG(("Loading models... %i models to load...", modelCount));
00115 XMLElement* pXmlModel = pXmlDocument->FirstChildElement("scene")->
00116 FirstChildElement("models")->FirstChildElement("model");
00117 for(int i = 0; i < modelCount; ++i)
00118 {
00119 if (i % 15 == 0)
00120 {
00121 OVR_DEBUG_LOG_TEXT(("%i models remaining...", modelCount - i));
00122 }
00123 Models.PushBack(*new Model(Prim_Triangles));
00124 bool isCollisionModel = false;
00125 pXmlModel->QueryBoolAttribute("isCollisionModel", &isCollisionModel);
00126 Models[i]->IsCollisionModel = isCollisionModel;
00127 if (isCollisionModel)
00128 {
00129 Models[i]->Visible = false;
00130 }
00131
00132
00133 OVR::Array<Vector3f> *vertices = new OVR::Array<Vector3f>();
00134 ParseVectorString(pXmlModel->FirstChildElement("vertices")->FirstChild()->
00135 ToText()->Value(), vertices);
00136
00137 for (unsigned int vertexIndex = 0; vertexIndex < vertices->GetSize(); ++vertexIndex)
00138 {
00139 vertices->At(vertexIndex).x *= -1.0f;
00140 }
00141
00142
00143 OVR::Array<Vector3f> *normals = new OVR::Array<Vector3f>();
00144 ParseVectorString(pXmlModel->FirstChildElement("normals")->FirstChild()->
00145 ToText()->Value(), normals);
00146
00147 for (unsigned int normalIndex = 0; normalIndex < normals->GetSize(); ++normalIndex)
00148 {
00149 normals->At(normalIndex).z *= -1.0f;
00150 }
00151
00152
00153 OVR::Array<Vector3f> *diffuseUVs = new OVR::Array<Vector3f>();
00154 OVR::Array<Vector3f> *lightmapUVs = new OVR::Array<Vector3f>();
00155 int diffuseTextureIndex = -1;
00156 int lightmapTextureIndex = -1;
00157 XMLElement* pXmlCurMaterial = pXmlModel->FirstChildElement("material");
00158
00159 while(pXmlCurMaterial != NULL)
00160 {
00161 if(pXmlCurMaterial->Attribute("name", "diffuse"))
00162 {
00163 pXmlCurMaterial->FirstChildElement("texture")->
00164 QueryIntAttribute("index", &diffuseTextureIndex);
00165 if(diffuseTextureIndex > -1)
00166 {
00167 ParseVectorString(pXmlCurMaterial->FirstChildElement("texture")->
00168 FirstChild()->ToText()->Value(), diffuseUVs, true);
00169 }
00170 }
00171 else if(pXmlCurMaterial->Attribute("name", "lightmap"))
00172 {
00173 pXmlCurMaterial->FirstChildElement("texture")->
00174 QueryIntAttribute("index", &lightmapTextureIndex);
00175 if(lightmapTextureIndex > -1)
00176 {
00177 XMLElement* firstChildElement = pXmlCurMaterial->FirstChildElement("texture");
00178 XMLNode* firstChild = firstChildElement->FirstChild();
00179 XMLText* text = firstChild->ToText();
00180 const char* value = text->Value();
00181 ParseVectorString(value, lightmapUVs, true);
00182 }
00183 }
00184
00185 pXmlCurMaterial = pXmlCurMaterial->NextSiblingElement("material");
00186 }
00187
00188
00189 Ptr<ShaderFill> shader = *new ShaderFill(*pRender->CreateShaderSet());
00190 shader->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Vertex, VShader_MVP));
00191 if(diffuseTextureIndex > -1)
00192 {
00193 shader->SetTexture(0, Textures[diffuseTextureIndex]);
00194 if(lightmapTextureIndex > -1)
00195 {
00196 shader->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_MultiTexture));
00197 shader->SetTexture(1, Textures[lightmapTextureIndex]);
00198 }
00199 else
00200 {
00201 shader->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_Texture));
00202 }
00203 }
00204 else
00205 {
00206 shader->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_LitGouraud));
00207 }
00208 Models[i]->Fill = shader;
00209
00210
00211 const UPInt numVerts = vertices->GetSize();
00212 for(UPInt v = 0; v < numVerts; ++v)
00213 {
00214 if(diffuseTextureIndex > -1)
00215 {
00216 if(lightmapTextureIndex > -1)
00217 {
00218 Models[i]->AddVertex(vertices->At(v).z, vertices->At(v).y, vertices->At(v).x, Color(255, 255, 255),
00219 diffuseUVs->At(v).x, diffuseUVs->At(v).y, lightmapUVs->At(v).x, lightmapUVs->At(v).y,
00220 normals->At(v).x, normals->At(v).y, normals->At(v).z);
00221 }
00222 else
00223 {
00224 Models[i]->AddVertex(vertices->At(v).z, vertices->At(v).y, vertices->At(v).x, Color(255, 255, 255),
00225 diffuseUVs->At(v).x, diffuseUVs->At(v).y, 0, 0,
00226 normals->At(v).x, normals->At(v).y, normals->At(v).z);
00227 }
00228 }
00229 else
00230 {
00231 Models[i]->AddVertex(vertices->At(v).z, vertices->At(v).y, vertices->At(v).x, Color(255, 0, 0, 128),
00232 0, 0, 0, 0,
00233 normals->At(v).x, normals->At(v).y, normals->At(v).z);
00234 }
00235 }
00236
00237
00238 const char* indexStr = pXmlModel->FirstChildElement("indices")->
00239 FirstChild()->ToText()->Value();
00240 UPInt stringLength = strlen(indexStr);
00241
00242 for(UPInt j = 0; j < stringLength;)
00243 {
00244 UPInt k = j + 1;
00245 for(; k < stringLength; ++k)
00246 {
00247 if(indexStr[k] == ' ')
00248 {
00249 break;
00250 }
00251 }
00252 char text[20];
00253 for(UPInt l = 0; l < k - j; ++l)
00254 {
00255 text[l] = indexStr[j + l];
00256 }
00257 text[k - j] = '\0';
00258 Models[i]->Indices.InsertAt(0, (unsigned short)atoi(text));
00259 j = k + 1;
00260 }
00261
00262 delete vertices;
00263 delete normals;
00264 delete diffuseUVs;
00265 delete lightmapUVs;
00266
00267 pScene->World.Add(Models[i]);
00268 pScene->Models.PushBack(Models[i]);
00269 pXmlModel = pXmlModel->NextSiblingElement("model");
00270 }
00271 OVR_DEBUG_LOG(("Done."));
00272
00273
00274 OVR_DEBUG_LOG(("Loading collision models... "));
00275 XMLElement* pXmlCollisionModel = pXmlDocument->FirstChildElement("scene")->FirstChildElement("collisionModels");
00276 if (pXmlCollisionModel)
00277 {
00278 pXmlCollisionModel->QueryIntAttribute("count", &collisionModelCount);
00279 pXmlCollisionModel = pXmlCollisionModel->FirstChildElement("collisionModel");
00280 }
00281
00282 XMLElement* pXmlPlane = NULL;
00283 for(int i = 0; i < collisionModelCount; ++i)
00284 {
00285 Ptr<CollisionModel> cm = *new CollisionModel();
00286 int planeCount = 0;
00287 pXmlCollisionModel->QueryIntAttribute("planeCount", &planeCount);
00288
00289 pXmlPlane = pXmlCollisionModel->FirstChildElement("plane");
00290 for(int j = 0; j < planeCount; ++j)
00291 {
00292 Vector3f norm;
00293 pXmlPlane->QueryFloatAttribute("nx", &norm.x);
00294 pXmlPlane->QueryFloatAttribute("ny", &norm.y);
00295 pXmlPlane->QueryFloatAttribute("nz", &norm.z);
00296 float D;
00297 pXmlPlane->QueryFloatAttribute("d", &D);
00298 D -= 0.5f;
00299 Planef p(norm.z, norm.y, norm.x * -1.0f, D);
00300 cm->Add(p);
00301 pXmlPlane = pXmlPlane->NextSiblingElement("plane");
00302 }
00303
00304 pCollisions->PushBack(cm);
00305 pXmlCollisionModel = pXmlCollisionModel->NextSiblingElement("collisionModel");
00306 }
00307 OVR_DEBUG_LOG(("done."));
00308
00309
00310 OVR_DEBUG_LOG(("Loading ground collision models..."));
00311 pXmlCollisionModel = pXmlDocument->FirstChildElement("scene")->FirstChildElement("groundCollisionModels");
00312 if (pXmlCollisionModel)
00313 {
00314 pXmlCollisionModel->QueryIntAttribute("count", &groundCollisionModelCount);
00315 pXmlCollisionModel = pXmlCollisionModel->FirstChildElement("collisionModel");
00316 }
00317 pXmlPlane = NULL;
00318 for(int i = 0; i < groundCollisionModelCount; ++i)
00319 {
00320 Ptr<CollisionModel> cm = *new CollisionModel();
00321 int planeCount = 0;
00322 pXmlCollisionModel->QueryIntAttribute("planeCount", &planeCount);
00323
00324 pXmlPlane = pXmlCollisionModel->FirstChildElement("plane");
00325 for(int j = 0; j < planeCount; ++j)
00326 {
00327 Vector3f norm;
00328 pXmlPlane->QueryFloatAttribute("nx", &norm.x);
00329 pXmlPlane->QueryFloatAttribute("ny", &norm.y);
00330 pXmlPlane->QueryFloatAttribute("nz", &norm.z);
00331 float D;
00332 pXmlPlane->QueryFloatAttribute("d", &D);
00333 Planef p(norm.z, norm.y, norm.x * -1.0f, D);
00334 cm->Add(p);
00335 pXmlPlane = pXmlPlane->NextSiblingElement("plane");
00336 }
00337
00338 pGroundCollisions->PushBack(cm);
00339 pXmlCollisionModel = pXmlCollisionModel->NextSiblingElement("collisionModel");
00340 }
00341 OVR_DEBUG_LOG(("done."));
00342 return true;
00343 }
00344
00345 void XmlHandler::ParseVectorString(const char* str, OVR::Array<OVR::Vector3f> *array,
00346 bool is2element)
00347 {
00348 UPInt stride = is2element ? 2 : 3;
00349 UPInt stringLength = strlen(str);
00350 UPInt element = 0;
00351 float v[3];
00352
00353 for(UPInt j = 0; j < stringLength;)
00354 {
00355 UPInt k = j + 1;
00356 for(; k < stringLength; ++k)
00357 {
00358 if(str[k] == ' ')
00359 {
00360 break;
00361 }
00362 }
00363 char text[20];
00364 for(UPInt l = 0; l < k - j; ++l)
00365 {
00366 text[l] = str[j + l];
00367 }
00368 text[k - j] = '\0';
00369 v[element] = (float)atof(text);
00370
00371 if(element == (stride - 1))
00372 {
00373
00374 OVR::Vector3f vect;
00375 vect.x = v[0];
00376 vect.y = v[1];
00377 vect.z = is2element ? 0.0f : v[2];
00378 array->PushBack(vect);
00379 }
00380
00381 j = k + 1;
00382 element = (element + 1) % stride;
00383 }
00384 }
00385
00386 }}
00387
00388 #ifdef OVR_DEFINE_NEW
00389 #define new OVR_DEFINE_NEW
00390 #endif