00001
00002
00003 #include "SGFFile.h"
00004
00005 #include "Configuration.h"
00006 #include "FileUtils.h"
00007 #include "Utils.h"
00008
00009
00010 namespace pge {
00011
00012
00013
00014
00015
00016
00017
00018 SGFFile::SGFFile(const std::string &filename) {
00019 m_document = new xml::CXMLDocument(filename);
00020 if(m_document != NULL && m_document->isFileOpen()) {
00021 if(parseContent()) {
00022
00023 }
00024 delete m_document;
00025 }
00026 }
00027
00028
00029
00030
00031
00032
00033
00034 SGFFile::~SGFFile(void) {
00035 }
00036
00037
00038
00039
00040
00041
00042
00043 std::vector<SGFFile::SGFMesh>* SGFFile::getMeshs(void) {
00044 return &m_meshs;
00045 }
00046
00047
00048
00049
00050
00051
00052
00053 std::vector<SGFFile::SGFLight>* SGFFile::getLights(void) {
00054 return &m_lights;
00055 }
00056
00057
00058
00059
00060
00061
00062
00063 void SGFFile::sgfLightToLight(SGFLight *sgfLight, Light *dest, Vector4f ambient, Vector4f specular) {
00064 if(dest == NULL) {
00065 return;
00066 }
00067 dest->m_position = Vector4f(sgfLight->m_position.m_v[0], sgfLight->m_position.m_v[1], sgfLight->m_position.m_v[2], 1.0f);
00068 dest->m_diffuse = Vector4f(sgfLight->m_color.m_v[0], sgfLight->m_color.m_v[1], sgfLight->m_color.m_v[2], 1.0f);
00069 dest->m_ambient = ambient;
00070 dest->m_specular = specular;
00071 }
00072
00073
00074
00075
00076
00077
00078
00079 bool SGFFile::parseContent(void) {
00080 int i;
00081 xml::CXMLNodeSet *meshs;
00082 xml::CXMLNode meshNode;
00083 xml::CXMLNodeSet *lights;
00084 xml::CXMLNode lightNode;
00085
00086
00087
00088 meshs = m_document->evaluateXPathExpression("/sgf/mesh", NULL);
00089 if(meshs != NULL) {
00090 for(i = 0; i < meshs->getNodeNum(); i++) {
00091 if(meshs->getNodeAt(i, &meshNode)) {
00092 if(!parseMesh(&meshNode)) {
00093 return false;
00094 }
00095 } else {
00096 return false;
00097 }
00098 }
00099
00100 delete meshs;
00101 meshs = NULL;
00102 }
00103
00104
00105 lights = m_document->evaluateXPathExpression("/sgf/light", NULL);
00106 if(lights != NULL) {
00107 for(i = 0; i < lights->getNodeNum(); i++) {
00108 if(lights->getNodeAt(i, &lightNode)) {
00109 if(!parseLight(&lightNode)) {
00110 return false;
00111 }
00112 } else {
00113 return false;
00114 }
00115 }
00116
00117 delete lights;
00118 lights = NULL;
00119 }
00120
00121 return true;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 bool SGFFile::parseMesh(xml::CXMLNode *meshNode) {
00131
00132
00133
00134 xml::CXMLNode verticesNode;
00135 xml::CXMLNode vertexNode;
00136 xml::CXMLNode primNode;
00137 xml::CXMLNode tempNode;
00138 xml::CXMLAttribute attr;
00139
00140 std::string str;
00141 SGFMesh mesh;
00142 SGFPrimitive primitive;
00143 Vector3f vertex;
00144 bool hasMorePrimitives = false;
00145
00146
00148
00149
00150 if(meshNode->getFirstChildNode(&verticesNode)) {
00151
00152
00153 if(verticesNode.getFirstChildNode(&vertexNode)) {
00154
00155
00156 if(vertexNode.getAttributeByName("x", &attr)) {
00157 vertex.m_v[0] = utils::stringToFloat(attr.m_value);
00158 }
00159 if(vertexNode.getAttributeByName("y", &attr)) {
00160 vertex.m_v[1] = utils::stringToFloat(attr.m_value);
00161 }
00162 if(vertexNode.getAttributeByName("z", &attr)) {
00163 vertex.m_v[2] = utils::stringToFloat(attr.m_value);
00164 }
00165
00166 mesh.m_vertices.push_back(vertex);
00167
00168 while(vertexNode.getNextSiblingNode(&vertexNode)) {
00169
00170 if(vertexNode.getAttributeByName("x", &attr)) {
00171 vertex.m_v[0] = utils::stringToFloat(attr.m_value);
00172 }
00173 if(vertexNode.getAttributeByName("y", &attr)) {
00174 vertex.m_v[1] = utils::stringToFloat(attr.m_value);
00175 }
00176 if(vertexNode.getAttributeByName("z", &attr)) {
00177 vertex.m_v[2] = utils::stringToFloat(attr.m_value);
00178 }
00179
00180 mesh.m_vertices.push_back(vertex);
00181 }
00182 }
00183 }
00184
00186
00187 if(verticesNode.getNextSiblingNode(&primNode)) {
00188 hasMorePrimitives = true;
00189 while(hasMorePrimitives) {
00190
00191 if(primNode.getName(&str)) {
00192
00193 if(str == "triangle") {
00194 primitive.m_isTriangle = true;
00195 } else {
00196 primitive.m_isTriangle = false;
00197 }
00198
00199
00200 if(primNode.getFirstDescendantByName("indices", &tempNode)) {
00201 if(tempNode.getAttributeByName("i0", &attr)) {
00202 primitive.m_indices[0] = utils::stringToInt(attr.m_value);
00203 }
00204 if(tempNode.getAttributeByName("i1", &attr)) {
00205 primitive.m_indices[1] = utils::stringToInt(attr.m_value);
00206 }
00207 if(tempNode.getAttributeByName("i2", &attr)) {
00208 primitive.m_indices[2] = utils::stringToInt(attr.m_value);
00209 }
00210
00211 if(str == "quad") {
00212 if(tempNode.getAttributeByName("i3", &attr)) {
00213 primitive.m_indices[3] = utils::stringToInt(attr.m_value);
00214 }
00215 }
00216 }
00217
00218
00219 if(primNode.getFirstDescendantByName("texCoord", &tempNode)) {
00220
00221 if(tempNode.getAttributeByName("u", &attr)) {
00222 primitive.m_texCoords[0].m_v[0] = utils::stringToFloat(attr.m_value);
00223 }
00224 if(tempNode.getAttributeByName("v", &attr)) {
00225 primitive.m_texCoords[0].m_v[1] = utils::stringToFloat(attr.m_value);
00226 }
00227
00228
00229 if(tempNode.getNextSiblingNode(&tempNode)) {
00230 if(tempNode.getAttributeByName("u", &attr)) {
00231 primitive.m_texCoords[1].m_v[0] = utils::stringToFloat(attr.m_value);
00232 }
00233 if(tempNode.getAttributeByName("v", &attr)) {
00234 primitive.m_texCoords[1].m_v[1] = utils::stringToFloat(attr.m_value);
00235 }
00236
00237
00238 if(tempNode.getNextSiblingNode(&tempNode)) {
00239 if(tempNode.getAttributeByName("u", &attr)) {
00240 primitive.m_texCoords[2].m_v[0] = utils::stringToFloat(attr.m_value);
00241 }
00242 if(tempNode.getAttributeByName("v", &attr)) {
00243 primitive.m_texCoords[2].m_v[1] = utils::stringToFloat(attr.m_value);
00244 }
00245
00246
00247 if(str == "quad") {
00248
00249 if(tempNode.getNextSiblingNode(&tempNode)) {
00250 if(tempNode.getAttributeByName("u", &attr)) {
00251 primitive.m_texCoords[3].m_v[0] = utils::stringToFloat(attr.m_value);
00252 }
00253 if(tempNode.getAttributeByName("v", &attr)) {
00254 primitive.m_texCoords[3].m_v[1] = utils::stringToFloat(attr.m_value);
00255 }
00256 }
00257 }
00258 }
00259 }
00260 }
00261
00262
00263 if(primNode.getFirstDescendantByName("texture", &tempNode)) {
00264 if(tempNode.getText(&primitive.m_textureFile)) {
00265 primitive.m_textureFile = fileutils::getFilename(primitive.m_textureFile, '\\');
00266 } else {
00267 primitive.m_textureFile = DEFAULT_TEXTURE_FILE;
00268 }
00269 }
00270 }
00271
00272
00273 if(primitive.m_isTriangle) {
00274 mesh.m_triangles.push_back(primitive);
00275 } else {
00276 SGFPrimitive t0;
00277 SGFPrimitive t1;
00278 quadToTriangles(primitive, &t0, &t1);
00279 mesh.m_triangles.push_back(t0);
00280 mesh.m_triangles.push_back(t1);
00281 }
00282
00283
00284 if(!primNode.getNextSiblingNode(&primNode)) {
00285 hasMorePrimitives = false;
00286 }
00287 }
00288 }
00289
00290 m_meshs.push_back(mesh);
00291
00292 return true;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301 bool SGFFile::parseLight(xml::CXMLNode *lightNode) {
00302
00303
00304
00305 xml::CXMLNode energyNode;
00306 xml::CXMLNode colorNode;
00307 xml::CXMLNode positionNode;
00308 xml::CXMLAttribute attr;
00309
00310 std::string str;
00311 SGFLight light;
00312
00313
00314
00315 if(lightNode->getFirstChildNode(&energyNode)) {
00316
00317
00318 if(energyNode.getText(&str)) {
00319 light.m_intensity = utils::stringToFloat(str);
00320 } else {
00321 return false;
00322 }
00323
00324
00325 if(energyNode.getNextSiblingNode(&colorNode)) {
00326
00327 if(colorNode.getAttributeByName("red", &attr)) {
00328 light.m_color.m_v[0] = utils::stringToFloat(attr.m_value);
00329 }
00330 if(colorNode.getAttributeByName("green", &attr)) {
00331 light.m_color.m_v[1] = utils::stringToFloat(attr.m_value);
00332 }
00333 if(colorNode.getAttributeByName("blue", &attr)) {
00334 light.m_color.m_v[2] = utils::stringToFloat(attr.m_value);
00335 }
00336 } else {
00337 return false;
00338 }
00339
00340
00341 if(colorNode.getNextSiblingNode(&positionNode)) {
00342
00343 if(positionNode.getAttributeByName("x", &attr)) {
00344 light.m_position.m_v[0] = utils::stringToFloat(attr.m_value);
00345 }
00346 if(positionNode.getAttributeByName("y", &attr)) {
00347 light.m_position.m_v[1] = utils::stringToFloat(attr.m_value);
00348 }
00349 if(positionNode.getAttributeByName("z", &attr)) {
00350 light.m_position.m_v[2] = utils::stringToFloat(attr.m_value);
00351 }
00352 } else {
00353 return false;
00354 }
00355 }
00356
00357 m_lights.push_back(light);
00358
00359 return true;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368 void SGFFile::quadToTriangles(SGFPrimitive quad, SGFPrimitive *t0, SGFPrimitive *t1) {
00369 if(t0 == NULL || t1 == NULL) {
00370 return;
00371 }
00372
00373
00374 t0->m_indices[0] = quad.m_indices[0];
00375 t0->m_indices[1] = quad.m_indices[1];
00376 t0->m_indices[2] = quad.m_indices[2];
00377
00378
00379 t0->m_texCoords[0] = quad.m_texCoords[0];
00380 t0->m_texCoords[1] = quad.m_texCoords[1];
00381 t0->m_texCoords[2] = quad.m_texCoords[2];
00382
00383
00384 t0->m_textureFile = quad.m_textureFile;
00385
00386 t0->m_isTriangle = true;
00387
00388
00389
00390 t1->m_indices[0] = quad.m_indices[2];
00391 t1->m_indices[1] = quad.m_indices[3];
00392 t1->m_indices[2] = quad.m_indices[0];
00393
00394
00395 t1->m_texCoords[0] = quad.m_texCoords[2];
00396 t1->m_texCoords[1] = quad.m_texCoords[3];
00397 t1->m_texCoords[2] = quad.m_texCoords[0];
00398
00399
00400 t1->m_textureFile = quad.m_textureFile;
00401
00402 t1->m_isTriangle = true;
00403 }
00404 };