[21] | 1 | /** |
---|
| 2 | * This source file is part of OgreColladaPlugin |
---|
| 3 | * an addon for OGRE (Object-oriented Graphics Rendering Engine) |
---|
| 4 | * For the latest info, see http://www.ogre3d.org/ |
---|
| 5 | * |
---|
| 6 | * This program is free software; you can redistribute it and/or modify it under |
---|
| 7 | * the terms of the GNU Lesser General Public License as published by the Free Software |
---|
| 8 | * Foundation; either version 2 of the License, or (at your option) any later |
---|
| 9 | * version. |
---|
| 10 | |
---|
| 11 | * This program is distributed in the hope that it will be useful, but WITHOUT |
---|
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
---|
| 13 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. |
---|
| 14 | |
---|
| 15 | * You should have received a copy of the GNU Lesser General Public License along with |
---|
| 16 | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
---|
| 17 | * Place - Suite 330, Boston, MA 02111-1307, USA, or go to |
---|
| 18 | * http://www.gnu.org/copyleft/lesser.txt. |
---|
| 19 | * |
---|
| 20 | * @author Philipp Hartl |
---|
| 21 | * @see README |
---|
| 22 | */ |
---|
| 23 | |
---|
| 24 | #include "OgreColladaGeometry.h" |
---|
| 25 | #include "OgreColladaDocument.h" |
---|
| 26 | #include "OgreColladaLibrary.h" |
---|
| 27 | #include "OgreColladaMaterial.h" |
---|
| 28 | #include "OgreColladaScene.h" |
---|
| 29 | #include "OgreColladaSyntax.h" |
---|
| 30 | #include "OgreColladaUtils.h" |
---|
| 31 | |
---|
| 32 | #include "OgreSceneManager.h" |
---|
| 33 | #include "OgreMovableObject.h" |
---|
| 34 | #include "OgreMeshManager.h" |
---|
| 35 | #include "OgreSubMesh.h" |
---|
| 36 | #include "OgreEntity.h" |
---|
| 37 | #include "OgreStringConverter.h" |
---|
| 38 | |
---|
| 39 | namespace Ogre |
---|
| 40 | { |
---|
| 41 | //------------------------------------------------------------------------- |
---|
| 42 | ColladaGeometry::ColladaGeometry(ColladaDocument *doc, xmlNode *n) : ColladaEntity(doc, n) |
---|
| 43 | { |
---|
| 44 | mOgreMesh = NULL; |
---|
| 45 | mEntityName = ""; |
---|
| 46 | mBB = NULL; |
---|
| 47 | mBBReset = false; |
---|
| 48 | } |
---|
| 49 | |
---|
| 50 | //------------------------------------------------------------------------- |
---|
| 51 | ColladaGeometry::~ColladaGeometry(void) |
---|
| 52 | { |
---|
| 53 | if (!mSources.empty()) |
---|
| 54 | { |
---|
| 55 | for (ColladaGeometrySourcePtrVector::iterator i = mSources.begin(); i != mSources.end(); ++i) |
---|
| 56 | { |
---|
| 57 | (*i)->data.clear(); |
---|
| 58 | OGRE_DELETE(*i); |
---|
| 59 | } |
---|
| 60 | mSources.clear(); |
---|
| 61 | } |
---|
| 62 | if (!mVertexInputs.empty()) |
---|
| 63 | { |
---|
| 64 | for (ColladaGeometryInputDataPtrVector::iterator i = mVertexInputs.begin(); i != mVertexInputs.end(); ++i) |
---|
| 65 | { |
---|
| 66 | // source already freed |
---|
| 67 | OGRE_DELETE(*i); |
---|
| 68 | } |
---|
| 69 | mVertexInputs.clear(); |
---|
| 70 | } |
---|
| 71 | if (!mPolygons.empty()) |
---|
| 72 | { |
---|
| 73 | for (ColladaGeometryPolygonPtrVector::iterator i = mPolygons.begin(); i != mPolygons.end(); ++i) |
---|
| 74 | { |
---|
| 75 | for (ColladaGeometryInputDataPtrVector::iterator j = (*i)->inputs.begin(); j != (*i)->inputs.end(); ++j) |
---|
| 76 | { |
---|
| 77 | // source already freed |
---|
| 78 | OGRE_DELETE(*j); |
---|
| 79 | } |
---|
| 80 | (*i)->inputs.clear(); |
---|
| 81 | (*i)->material = NULL; |
---|
| 82 | OGRE_DELETE(*i); |
---|
| 83 | } |
---|
| 84 | mPolygons.clear(); |
---|
| 85 | } |
---|
| 86 | |
---|
| 87 | if (mOgreMesh != NULL) |
---|
| 88 | { |
---|
| 89 | for (ColladaGeometryOgreMeshIndexData::iterator it = mOgreMesh->indices.begin(); it != mOgreMesh->indices.end(); ++it) |
---|
| 90 | { |
---|
| 91 | OGRE_DELETE_ARRAY((*it)->indices); |
---|
| 92 | OGRE_DELETE(*it); |
---|
| 93 | } |
---|
| 94 | mOgreMesh->indices.clear(); |
---|
| 95 | OGRE_DELETE_ARRAY(mOgreMesh->vertices); |
---|
| 96 | OGRE_DELETE(mOgreMesh); |
---|
| 97 | } |
---|
| 98 | |
---|
| 99 | if (mBBReset) mBB = NULL; |
---|
| 100 | else OGRE_DELETE(mBB); |
---|
| 101 | } |
---|
| 102 | |
---|
| 103 | //------------------------------------------------------------------------- |
---|
| 104 | void ColladaGeometry::calcBoundingBox(void) |
---|
| 105 | { |
---|
| 106 | if (!mBB) |
---|
| 107 | { |
---|
| 108 | // calculate a bounding box |
---|
| 109 | ColladaGeometrySource *src = mVertexInputs.at(0)->source; |
---|
| 110 | |
---|
| 111 | float minX, minY, minZ, maxX, maxY, maxZ; |
---|
| 112 | minX = maxX = src->data.at(0); |
---|
| 113 | minY = maxY = src->data.at(1); |
---|
| 114 | minZ = maxZ = src->data.at(2); |
---|
| 115 | |
---|
| 116 | for (uint i = 0; i < src->count; i++) |
---|
| 117 | { |
---|
| 118 | uint index = i * 3; |
---|
| 119 | |
---|
| 120 | if (minX > src->data.at(index)) minX = src->data.at(index); |
---|
| 121 | if (minY > src->data.at(index + 1)) minY = src->data.at(index + 1); |
---|
| 122 | if (minZ > src->data.at(index + 2)) minZ = src->data.at(index + 2); |
---|
| 123 | |
---|
| 124 | if (maxX < src->data.at(index)) maxX = src->data.at(index); |
---|
| 125 | if (maxY < src->data.at(index + 1)) maxY = src->data.at(index + 1); |
---|
| 126 | if (maxZ < src->data.at(index + 2)) maxZ = src->data.at(index + 2); |
---|
| 127 | } |
---|
| 128 | |
---|
| 129 | mBB = new ColladaBoundingBox(Vector3(minX, minY, minZ), Vector3(maxX, maxY, maxZ)); |
---|
| 130 | } |
---|
| 131 | } |
---|
| 132 | |
---|
| 133 | //------------------------------------------------------------------------- |
---|
| 134 | void ColladaGeometry::createTriangleList(void) |
---|
| 135 | { |
---|
| 136 | // walk through all polygons, there must be at least one at index 0 |
---|
| 137 | uint polygonCount = static_cast<uint>(mPolygons.size()); |
---|
| 138 | ColladaGeometryPolygon *polygon = mPolygons.at(0); |
---|
| 139 | if (polygon == NULL) return; |
---|
| 140 | |
---|
| 141 | // for simple life |
---|
| 142 | ColladaGeometryInputData *vertexInput = NULL; |
---|
| 143 | ColladaGeometryInputData *normalInput = NULL; |
---|
| 144 | ColladaGeometryInputData *texcoordInput = NULL; |
---|
| 145 | |
---|
| 146 | // get all trivial sources through vertex inputs, one index array for all |
---|
| 147 | ColladaGeometryInputDataPtrVector::iterator it; |
---|
| 148 | for (it = mVertexInputs.begin(); it != mVertexInputs.end(); ++it) |
---|
| 149 | { |
---|
| 150 | if ((*it)->semantic == ColladaGeometrySpecific::POSITION) vertexInput = *it; |
---|
| 151 | if ((*it)->semantic == ColladaGeometrySpecific::NORMAL) normalInput = *it; |
---|
| 152 | if ((*it)->semantic == ColladaGeometrySpecific::TEXCOORD) texcoordInput = *it; |
---|
| 153 | } |
---|
| 154 | |
---|
| 155 | // look for detailed normals and texcoords, each source with its own index data |
---|
| 156 | for (it = polygon->inputs.begin(); it != polygon->inputs.end(); ++it) |
---|
| 157 | { |
---|
| 158 | if ((*it)->semantic == ColladaGeometrySpecific::NORMAL) normalInput = *it; |
---|
| 159 | if ((*it)->semantic == ColladaGeometrySpecific::TEXCOORD) texcoordInput = *it; |
---|
| 160 | } |
---|
| 161 | |
---|
| 162 | // vertex, normal, texcoord source counts |
---|
| 163 | uint vertexcount = static_cast<uint>(vertexInput->source->data.size()); |
---|
| 164 | uint normalcount = 0; |
---|
| 165 | uint texcoordcount = 0; |
---|
| 166 | if (normalInput != NULL) normalcount = static_cast<uint>(normalInput->source->data.size()); |
---|
| 167 | if (texcoordInput != NULL) texcoordcount = static_cast<uint>(texcoordInput->source->data.size()); |
---|
| 168 | |
---|
| 169 | // create new ogre mesh structure |
---|
| 170 | mOgreMesh = new ColladaGeometryOgreMesh(); |
---|
| 171 | mOgreMesh->drawNormals = ((normalInput != NULL) && (normalcount > 0)); |
---|
| 172 | // are there more normals per vertex? |
---|
| 173 | bool normalsEx = (mOgreMesh->drawNormals && (normalcount != vertexcount)); |
---|
| 174 | mOgreMesh->drawTexCoords = ((texcoordInput != NULL) && (texcoordcount > 0)); |
---|
| 175 | // more texcoords per vertex |
---|
| 176 | bool texcoordsEx = (mOgreMesh->drawTexCoords && (texcoordcount != vertexcount)); |
---|
| 177 | |
---|
| 178 | // calc stride size for vertex array |
---|
| 179 | uint stridesize = vertexInput->source->stride; |
---|
| 180 | if (mOgreMesh->drawNormals) stridesize += normalInput->source->stride; |
---|
| 181 | if (mOgreMesh->drawTexCoords) stridesize += texcoordInput->source->stride; |
---|
| 182 | |
---|
| 183 | // how many triangles are in one polygon? |
---|
| 184 | // if there are more than one polygon per geometry, the amount should not change! |
---|
| 185 | uint trianglesppolygon = 1; |
---|
| 186 | uint i = 0; |
---|
| 187 | for (i = polygon->vertexCount; i > 3; i--) trianglesppolygon++; |
---|
| 188 | |
---|
| 189 | /** simple case, each vertex has at maximum only one normal and/or one texture information |
---|
| 190 | * (vertexcount == normalcount == texcoordcount, all data have the same indices) |
---|
| 191 | * so we only have to triangulate the polygon primitive |
---|
| 192 | */ |
---|
| 193 | if (!normalsEx && !texcoordsEx) |
---|
| 194 | { |
---|
| 195 | // create space for the vertex array |
---|
| 196 | mOgreMesh->vertexCount = vertexInput->source->count; |
---|
| 197 | mOgreMesh->vertices = new float[mOgreMesh->vertexCount * stridesize]; |
---|
| 198 | |
---|
| 199 | // (1) fill up vertices with vertex (normal, texcoord) data |
---|
| 200 | // the mesh could be created anyway if polygonCount > 0 |
---|
| 201 | uint offset = 0; |
---|
| 202 | for (i = 0; i < mOgreMesh->vertexCount; i++) |
---|
| 203 | { |
---|
| 204 | mOgreMesh->vertices[i * stridesize] = vertexInput->source->data[i * 3]; |
---|
| 205 | mOgreMesh->vertices[i * stridesize + 1] = vertexInput->source->data[i * 3 + 1]; |
---|
| 206 | mOgreMesh->vertices[i * stridesize + 2] = vertexInput->source->data[i * 3 + 2]; |
---|
| 207 | mDoc->correctAxis(&mOgreMesh->vertices[i * stridesize]); |
---|
| 208 | |
---|
| 209 | offset = 3; |
---|
| 210 | if (mOgreMesh->drawNormals) |
---|
| 211 | { |
---|
| 212 | mOgreMesh->vertices[i * stridesize + offset] = normalInput->source->data[i * 3]; |
---|
| 213 | mOgreMesh->vertices[i * stridesize + offset + 1] = normalInput->source->data[i * 3 + 1]; |
---|
| 214 | mOgreMesh->vertices[i * stridesize + offset + 2] = normalInput->source->data[i * 3 + 2]; |
---|
| 215 | mDoc->correctAxis(&mOgreMesh->vertices[i * stridesize + offset]); |
---|
| 216 | offset += 3; |
---|
| 217 | } |
---|
| 218 | |
---|
| 219 | if (mOgreMesh->drawTexCoords) |
---|
| 220 | { |
---|
| 221 | mOgreMesh->vertices[i * stridesize + offset] = texcoordInput->source->data[i * 2]; |
---|
| 222 | mOgreMesh->vertices[i * stridesize + offset + 1] = texcoordInput->source->data[i * 2 + 1]; |
---|
| 223 | } |
---|
| 224 | } |
---|
| 225 | |
---|
| 226 | // (2) fill up indices array for each polygon primitive |
---|
| 227 | for (ColladaGeometryPolygonPtrVector::iterator it = mPolygons.begin(); it != mPolygons.end(); ++it) |
---|
| 228 | { |
---|
| 229 | polygon = *it; |
---|
| 230 | |
---|
| 231 | // create enough space for the index array |
---|
| 232 | ColladaGeometryIndexData *tmpIndices = new ColladaGeometryIndexData(); |
---|
| 233 | tmpIndices->count = trianglesppolygon * polygon->primitiveCount * 3; |
---|
| 234 | tmpIndices->indices = new unsigned short[tmpIndices->count]; |
---|
| 235 | tmpIndices->material = ((*it)->setMaterial) ? (*it)->material->getId() : ""; |
---|
| 236 | |
---|
| 237 | // set vertexInput pointer at indices |
---|
| 238 | vertexInput = polygon->inputs.at(0); |
---|
| 239 | |
---|
| 240 | offset = trianglesppolygon * 3; |
---|
| 241 | uint index = 0; |
---|
| 242 | for (i = 0; i < polygon->primitiveCount; i++) |
---|
| 243 | { |
---|
| 244 | index = offset * i; |
---|
| 245 | |
---|
| 246 | // first triangle |
---|
| 247 | tmpIndices->indices[index] = vertexInput->indices[i * polygon->vertexCount]; |
---|
| 248 | tmpIndices->indices[index + 1] = vertexInput->indices[i * polygon->vertexCount + 1]; |
---|
| 249 | tmpIndices->indices[index + 2] = vertexInput->indices[i * polygon->vertexCount + 2]; |
---|
| 250 | |
---|
| 251 | // are there more than one triangle in one primitive? |
---|
| 252 | for (uint j = 1; j < trianglesppolygon; j++) |
---|
| 253 | { |
---|
| 254 | tmpIndices->indices[index + j * 3] = vertexInput->indices[i * polygon->vertexCount]; |
---|
| 255 | tmpIndices->indices[index + j * 3 + 1] = vertexInput->indices[i * polygon->vertexCount + j + 1]; |
---|
| 256 | tmpIndices->indices[index + j * 3 + 2] = vertexInput->indices[i * polygon->vertexCount + j + 2]; |
---|
| 257 | } |
---|
| 258 | } |
---|
| 259 | |
---|
| 260 | // save index array |
---|
| 261 | mOgreMesh->indices.push_back(tmpIndices); |
---|
| 262 | } |
---|
| 263 | } |
---|
| 264 | /** tricky case, each vertex can have more than one normal and/or texture |
---|
| 265 | * normals or texcoord arrays with different indices |
---|
| 266 | */ |
---|
| 267 | else |
---|
| 268 | { |
---|
| 269 | // space for vertex count |
---|
| 270 | mOgreMesh->vertexCount = 0; |
---|
| 271 | ColladaGeometryPolygonPtrVector::iterator it; |
---|
| 272 | for (it = mPolygons.begin(); it != mPolygons.end(); ++it) |
---|
| 273 | { |
---|
| 274 | // the vertexCount should not change! |
---|
| 275 | mOgreMesh->vertexCount += (*it)->primitiveCount * (*it)->vertexCount; |
---|
| 276 | } |
---|
| 277 | mOgreMesh->vertices = new float[mOgreMesh->vertexCount * stridesize]; |
---|
| 278 | |
---|
| 279 | for (it = mPolygons.begin(); it != mPolygons.end(); ++it) |
---|
| 280 | { |
---|
| 281 | polygon = (*it); |
---|
| 282 | |
---|
| 283 | // create enough space for the index array |
---|
| 284 | ColladaGeometryIndexData *tmpIndices = new ColladaGeometryIndexData(); |
---|
| 285 | tmpIndices->count = trianglesppolygon * polygon->primitiveCount * 3; |
---|
| 286 | tmpIndices->indices = new unsigned short[tmpIndices->count]; |
---|
| 287 | tmpIndices->material = ((*it)->setMaterial) ? (*it)->material->getId() : ""; |
---|
| 288 | |
---|
| 289 | // get vertex indices |
---|
| 290 | intVector *vertexIndices = &polygon->inputs.at(0)->indices; |
---|
| 291 | |
---|
| 292 | // get normal indices |
---|
| 293 | intVector *normalIndices = &normalInput->indices; |
---|
| 294 | if (!normalsEx) normalIndices = vertexIndices; |
---|
| 295 | |
---|
| 296 | // get texture indices |
---|
| 297 | intVector *textureIndices = &texcoordInput->indices; |
---|
| 298 | if (!texcoordsEx) textureIndices = vertexIndices; |
---|
| 299 | |
---|
| 300 | // fill up mVertices and mIndices array in one pass |
---|
| 301 | for (i = 0; i < polygon->primitiveCount; i++) |
---|
| 302 | { |
---|
| 303 | // starting index for one primitive |
---|
| 304 | uint pindex = i * polygon->vertexCount; |
---|
| 305 | |
---|
| 306 | // (1) vertices |
---|
| 307 | uint j; |
---|
| 308 | for (j = 0; j < polygon->vertexCount; j++) |
---|
| 309 | { |
---|
| 310 | uint vindex = pindex + j; // vertex index |
---|
| 311 | |
---|
| 312 | // vertex data |
---|
| 313 | mOgreMesh->vertices[vindex * stridesize] = vertexInput->source->data[vertexIndices->at(vindex) * 3]; |
---|
| 314 | mOgreMesh->vertices[vindex * stridesize + 1] = vertexInput->source->data[vertexIndices->at(vindex) * 3 + 1]; |
---|
| 315 | mOgreMesh->vertices[vindex * stridesize + 2] = vertexInput->source->data[vertexIndices->at(vindex) * 3 + 2]; |
---|
| 316 | mDoc->correctAxis(&mOgreMesh->vertices[vindex * stridesize]); |
---|
| 317 | |
---|
| 318 | uint offset = 3; |
---|
| 319 | if (mOgreMesh->drawNormals) |
---|
| 320 | { |
---|
| 321 | mOgreMesh->vertices[vindex * stridesize + offset] = normalInput->source->data[normalIndices->at(vindex) * 3]; |
---|
| 322 | mOgreMesh->vertices[vindex * stridesize + offset + 1] = normalInput->source->data[normalIndices->at(vindex) * 3 + 1]; |
---|
| 323 | mOgreMesh->vertices[vindex * stridesize + offset + 2] = normalInput->source->data[normalIndices->at(vindex) * 3 + 2]; |
---|
| 324 | mDoc->correctAxis(&mOgreMesh->vertices[vindex * stridesize + offset]); |
---|
| 325 | |
---|
| 326 | offset += 3; |
---|
| 327 | } |
---|
| 328 | |
---|
| 329 | if (mOgreMesh->drawTexCoords) |
---|
| 330 | { |
---|
| 331 | mOgreMesh->vertices[vindex * stridesize + offset] = texcoordInput->source->data[textureIndices->at(vindex) * 2]; |
---|
| 332 | mOgreMesh->vertices[vindex * stridesize + offset + 1] = texcoordInput->source->data[textureIndices->at(vindex) * 2 + 1]; |
---|
| 333 | } |
---|
| 334 | } |
---|
| 335 | |
---|
| 336 | // (2) indices |
---|
| 337 | uint iindex = i * trianglesppolygon * 3; // indices index |
---|
| 338 | |
---|
| 339 | // first triangle |
---|
| 340 | tmpIndices->indices[iindex] = pindex; |
---|
| 341 | tmpIndices->indices[iindex + 1] = pindex + 1; |
---|
| 342 | tmpIndices->indices[iindex + 2] = pindex + 2; |
---|
| 343 | |
---|
| 344 | // are there more than one triangle in one primitive? |
---|
| 345 | for (j = 1; j < trianglesppolygon; j++) |
---|
| 346 | { |
---|
| 347 | tmpIndices->indices[iindex + j * 3] = pindex; |
---|
| 348 | tmpIndices->indices[iindex + j * 3 + 1] = pindex + j + 1; |
---|
| 349 | tmpIndices->indices[iindex + j * 3 + 2] = pindex + j + 2; |
---|
| 350 | } |
---|
| 351 | } |
---|
| 352 | |
---|
| 353 | // save index array |
---|
| 354 | mOgreMesh->indices.push_back(tmpIndices); |
---|
| 355 | } |
---|
| 356 | } |
---|
| 357 | |
---|
| 358 | // TEST |
---|
| 359 | // printVertices(stridesize); |
---|
| 360 | // printIndices(); |
---|
| 361 | } |
---|
| 362 | |
---|
| 363 | //------------------------------------------------------------------------- |
---|
| 364 | MovableObject *ColladaGeometry::getOgreInstance(void) const |
---|
| 365 | { |
---|
| 366 | if (mOgreMesh != NULL && !mEntityName.empty()) |
---|
| 367 | { |
---|
| 368 | // create hw-buffers and push the data there, material will be set too |
---|
| 369 | createOgreMesh(); |
---|
| 370 | |
---|
| 371 | return mDoc->getSceneManager()->createEntity(mEntityName, mId); |
---|
| 372 | } |
---|
| 373 | |
---|
| 374 | return NULL; |
---|
| 375 | } |
---|
| 376 | |
---|
| 377 | //------------------------------------------------------------------------- |
---|
| 378 | void ColladaGeometry::createOgreMesh(void) const |
---|
| 379 | { |
---|
| 380 | //if (MeshManager::getSingleton().getByName(mId) != static_cast<ResourcePtr>(NULL)) return; |
---|
| 381 | ResourcePtr p; |
---|
| 382 | if (MeshManager::getSingleton().getByName(mId) != p) |
---|
| 383 | return; |
---|
| 384 | |
---|
| 385 | MeshPtr pMesh = MeshManager::getSingleton().createManual(mId, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); |
---|
| 386 | pMesh->sharedVertexData = new VertexData(); |
---|
| 387 | pMesh->sharedVertexData->vertexCount = mOgreMesh->vertexCount; |
---|
| 388 | VertexDeclaration *pVertexDecl = pMesh->sharedVertexData->vertexDeclaration; |
---|
| 389 | |
---|
| 390 | size_t offset = 0; |
---|
| 391 | |
---|
| 392 | // position |
---|
| 393 | pVertexDecl->addElement(0, offset, VET_FLOAT3, VES_POSITION); |
---|
| 394 | offset += VertexElement::getTypeSize(VET_FLOAT3); |
---|
| 395 | |
---|
| 396 | // normals |
---|
| 397 | if (mOgreMesh->drawNormals) |
---|
| 398 | { |
---|
| 399 | pVertexDecl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); |
---|
| 400 | offset += VertexElement::getTypeSize(VET_FLOAT3); |
---|
| 401 | } |
---|
| 402 | |
---|
| 403 | // colour (diffuse, specular) |
---|
| 404 | |
---|
| 405 | // texture coordinates |
---|
| 406 | if (mOgreMesh->drawTexCoords) |
---|
| 407 | { |
---|
| 408 | pVertexDecl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); |
---|
| 409 | offset += VertexElement::getTypeSize(VET_FLOAT2); |
---|
| 410 | } |
---|
| 411 | |
---|
| 412 | HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( |
---|
| 413 | offset, pMesh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); |
---|
| 414 | |
---|
| 415 | // set vertex buffer binding so buffer 0 is bound to our vertex buffer |
---|
| 416 | VertexBufferBinding* bind = pMesh->sharedVertexData->vertexBufferBinding; |
---|
| 417 | bind->setBinding(0, vbuf); |
---|
| 418 | // upload the vertex data to the card |
---|
| 419 | vbuf->writeData(0, vbuf->getSizeInBytes(), mOgreMesh->vertices, true); |
---|
| 420 | |
---|
| 421 | // for each polygon create a new submesh, for multimaterial e.g. |
---|
| 422 | // submesh with index buffer |
---|
| 423 | for (ColladaGeometryOgreMeshIndexData::iterator it = mOgreMesh->indices.begin(); it != mOgreMesh->indices.end(); ++it) |
---|
| 424 | { |
---|
| 425 | SubMesh *pSubMesh = pMesh->createSubMesh(); |
---|
| 426 | pSubMesh->indexData->indexCount = (*it)->count; |
---|
| 427 | pSubMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( |
---|
| 428 | HardwareIndexBuffer::IT_16BIT, pSubMesh->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); |
---|
| 429 | HardwareIndexBufferSharedPtr ibuf = pSubMesh->indexData->indexBuffer; |
---|
| 430 | // upload the index data |
---|
| 431 | ibuf->writeData(0, ibuf->getSizeInBytes(), (*it)->indices, true); |
---|
| 432 | |
---|
| 433 | if (!(*it)->material.empty()) pSubMesh->setMaterialName((*it)->material); |
---|
| 434 | pSubMesh->useSharedVertices = true; |
---|
| 435 | pSubMesh->operationType = RenderOperation::OT_TRIANGLE_LIST; |
---|
| 436 | } |
---|
| 437 | |
---|
| 438 | // there should be an AABB in every case, maybe overwritten from the collada scene node import |
---|
| 439 | // be careful by AABB if the object is duplicated and translated |
---|
| 440 | pMesh->_setBounds(mBB->getAABB()); |
---|
| 441 | pMesh->_setBoundingSphereRadius(mBB->getRadius()); |
---|
| 442 | |
---|
| 443 | pMesh->load(); |
---|
| 444 | } |
---|
| 445 | |
---|
| 446 | //------------------------------------------------------------------------- |
---|
| 447 | bool ColladaGeometry::doImport(void) |
---|
| 448 | { |
---|
| 449 | if (mLoaded) return mStatus; |
---|
| 450 | else mLoaded = true; |
---|
| 451 | |
---|
| 452 | // get <mesh> node, must occur exactly one time [1,1] |
---|
| 453 | xmlNode *mesh = ColladaUtils::getChildByTagName(mNode, CS_ELM_MESH); |
---|
| 454 | if (mesh != NULL) mStatus = importMesh(mesh); |
---|
| 455 | |
---|
| 456 | // get <extra> nodes, can occur [0,*] |
---|
| 457 | // xmlNodePtrVector extras = ColladaUtils::getChildsByTagName(mNode, CS_ELM_EXTRA); |
---|
| 458 | // for (xmlNodePtrVector::iterator i = extras.begin(); i != extras.end(); ++i) importExtra((*i)); |
---|
| 459 | |
---|
| 460 | if (mStatus) |
---|
| 461 | { |
---|
| 462 | calcBoundingBox(); |
---|
| 463 | |
---|
| 464 | // create the vertices and indices by simple triangulation |
---|
| 465 | if (mType == POLYGONS || mType == TRIANGLES) createTriangleList(); |
---|
| 466 | } |
---|
| 467 | |
---|
| 468 | return mStatus; |
---|
| 469 | } |
---|
| 470 | |
---|
| 471 | //------------------------------------------------------------------------- |
---|
| 472 | void ColladaGeometry::importExtra(xmlNode *extraNode) |
---|
| 473 | { |
---|
| 474 | // not yet implemented |
---|
| 475 | } |
---|
| 476 | |
---|
| 477 | //------------------------------------------------------------------------- |
---|
| 478 | bool ColladaGeometry::importMesh(xmlNode *meshNode) |
---|
| 479 | { |
---|
| 480 | bool bPrimitives = false; |
---|
| 481 | |
---|
| 482 | // vertices must occur exactly one time |
---|
| 483 | if (!importVerticesNode(meshNode)) return false; |
---|
| 484 | |
---|
| 485 | // look for polygon primitives |
---|
| 486 | bPrimitives = importPolygonsNodes(meshNode, CS_ELM_POLYGONS); |
---|
| 487 | if (bPrimitives) |
---|
| 488 | { |
---|
| 489 | mType = POLYGONS; |
---|
| 490 | return true; |
---|
| 491 | } |
---|
| 492 | |
---|
| 493 | // triangles |
---|
| 494 | bPrimitives = importPolygonsNodes(meshNode, CS_ELM_TRIANGLES); |
---|
| 495 | if (bPrimitives) |
---|
| 496 | { |
---|
| 497 | mType = TRIANGLES; |
---|
| 498 | return true; |
---|
| 499 | } |
---|
| 500 | |
---|
| 501 | return false; |
---|
| 502 | } |
---|
| 503 | |
---|
| 504 | //------------------------------------------------------------------------- |
---|
| 505 | bool ColladaGeometry::importPolygonsNodes(xmlNode *meshNode, const String &primitive) |
---|
| 506 | { |
---|
| 507 | // there can be more than one <polygons> node, e.g. multi materials |
---|
| 508 | xmlNodePtrVector polygonsNodes = ColladaUtils::getChildsByTagName(meshNode, primitive); |
---|
| 509 | if (polygonsNodes.empty()) return false; |
---|
| 510 | |
---|
| 511 | // walk through all <polygons> |
---|
| 512 | for (xmlNodePtrVector::iterator it = polygonsNodes.begin(); it != polygonsNodes.end(); ++it) |
---|
| 513 | { |
---|
| 514 | xmlNode *polygonsNode = *it; |
---|
| 515 | |
---|
| 516 | ColladaGeometryPolygon *polygon = new ColladaGeometryPolygon(); |
---|
| 517 | |
---|
| 518 | // attribute material refers to a <material> node |
---|
| 519 | String material = ColladaUtils::getProperty(polygonsNode, CS_ATR_INPUT_MATERIAL); |
---|
| 520 | polygon->setMaterial = false; |
---|
| 521 | // search for material, get ptr |
---|
| 522 | if (!material.empty()) |
---|
| 523 | { |
---|
| 524 | material.erase(0,1); // remove the # sign |
---|
| 525 | polygon->material = mDoc->getLibrary()->getMaterial(material); |
---|
| 526 | if (polygon->material != NULL) |
---|
| 527 | { |
---|
| 528 | // import material entity |
---|
| 529 | if (!(polygon->setMaterial = polygon->material->doImport())) |
---|
| 530 | { |
---|
| 531 | LogManager::getSingleton().logMessage("ColladaGeometry::importPolygonsNodes - loading of assigned material " + material + " failed! " + mId); |
---|
| 532 | } |
---|
| 533 | } |
---|
| 534 | else |
---|
| 535 | { |
---|
| 536 | LogManager::getSingleton().logMessage("ColladaGeometry::importPolygonsNodes - can't find assigned material with id " + material + "! " + mId); |
---|
| 537 | } |
---|
| 538 | } |
---|
| 539 | |
---|
| 540 | // the number of polygon primitives |
---|
| 541 | String count = ColladaUtils::getProperty(polygonsNode, CS_ATR_COUNT); |
---|
| 542 | polygon->primitiveCount = (!count.empty()) ? static_cast<uint>(atoi(count.c_str())) : 0; |
---|
| 543 | |
---|
| 544 | // walk through <param>, <input>, <p> childs |
---|
| 545 | xmlNode *c = NULL; |
---|
| 546 | for (c = polygonsNode->children; c != NULL; c = c->next) |
---|
| 547 | { |
---|
| 548 | if (c->type != XML_ELEMENT_NODE) continue; |
---|
| 549 | String tagname = (const char *)c->name; |
---|
| 550 | |
---|
| 551 | // <param>, ignore it |
---|
| 552 | if (tagname == CS_ELM_PARAM) continue; |
---|
| 553 | // <input> |
---|
| 554 | else if (tagname == CS_ELM_INPUT) |
---|
| 555 | { |
---|
| 556 | // get semantic attribute |
---|
| 557 | String semantic = ColladaUtils::getProperty(c, CS_ATR_INPUT_SEMANTIC); |
---|
| 558 | ColladaGeometrySpecific::Semantic tmpsemantic = ColladaGeometrySpecific::getSemantic(semantic); |
---|
| 559 | |
---|
| 560 | if (tmpsemantic == ColladaGeometrySpecific::VERTEX || |
---|
| 561 | tmpsemantic == ColladaGeometrySpecific::NORMAL || |
---|
| 562 | tmpsemantic == ColladaGeometrySpecific::TEXCOORD) |
---|
| 563 | { |
---|
| 564 | // if (tmpsemantic == ColladaGeometryInput::NORMAL) mhasFaceNormals = true; |
---|
| 565 | // if (tmpsemantic == ColladaGeometryInput::TEXCOORD) mhasFaceTexCoords = true; |
---|
| 566 | |
---|
| 567 | String idx = ColladaUtils::getProperty(c, CS_ATR_IDX); |
---|
| 568 | String source = ColladaUtils::getProperty(c, CS_ATR_INPUT_SOURCE); |
---|
| 569 | |
---|
| 570 | ColladaGeometrySource *gsource = NULL; |
---|
| 571 | // the source node points at <vertices>, already imported by importVerticesNode |
---|
| 572 | if (tmpsemantic != ColladaGeometrySpecific::VERTEX) |
---|
| 573 | { |
---|
| 574 | gsource = importSourceNode(ColladaUtils::getChildById(meshNode, source.c_str())); |
---|
| 575 | if (gsource == NULL) |
---|
| 576 | { |
---|
| 577 | LogManager::getSingleton().logMessage("ColladaGeometry::importVerticesNode - unable to find/import <source> with id " + source); |
---|
| 578 | continue; |
---|
| 579 | } |
---|
| 580 | } |
---|
| 581 | |
---|
| 582 | // make new inputdata and push it on the vector |
---|
| 583 | ColladaGeometryInputData *input = new ColladaGeometryInputData(); |
---|
| 584 | input->idx = (!idx.empty()) ? static_cast<uint>(atoi(idx.c_str())) : polygon->inputs.size(); |
---|
| 585 | input->semantic = tmpsemantic; |
---|
| 586 | input->source = gsource; |
---|
| 587 | |
---|
| 588 | // check for duplicate <input> |
---|
| 589 | bool idxrepeat = false; |
---|
| 590 | for (ColladaGeometryInputDataPtrVector::iterator jt = polygon->inputs.begin(); jt != polygon->inputs.end() && !idxrepeat; ++jt) |
---|
| 591 | { |
---|
| 592 | if ((*jt)->idx == input->idx) idxrepeat = true; |
---|
| 593 | } |
---|
| 594 | if (!idxrepeat) polygon->inputs.push_back(input); |
---|
| 595 | else OGRE_DELETE(input); // free unneeded geometry input data |
---|
| 596 | } |
---|
| 597 | // unknwon or unsupported |
---|
| 598 | else |
---|
| 599 | { |
---|
| 600 | LogManager::getSingleton().logMessage("ColladaGeometry::importPolygonsNode - unknown <semantic> " + semantic + " in <geometry> " + mId); |
---|
| 601 | continue; |
---|
| 602 | } |
---|
| 603 | } |
---|
| 604 | // <p> first appearance, break, cause we will parse the primitves later |
---|
| 605 | else if (tagname == CS_ELM_P) break; |
---|
| 606 | // unknwon or unsupported |
---|
| 607 | else |
---|
| 608 | { |
---|
| 609 | LogManager::getSingleton().logMessage("ColladaGeometry::importPolygonsNodes - unknown child: " + tagname); |
---|
| 610 | continue; |
---|
| 611 | } |
---|
| 612 | } |
---|
| 613 | |
---|
| 614 | // there should be at least one <input> with semantic="VERTEX" |
---|
| 615 | if (polygon->inputs.at(0)->semantic != ColladaGeometrySpecific::VERTEX) continue; |
---|
| 616 | polygon->inputCount = static_cast<uint>(polygon->inputs.size()); |
---|
| 617 | |
---|
| 618 | uint indexCount = 0; |
---|
| 619 | polygon->vertexCount = 0; |
---|
| 620 | uint tmppCount = 0; |
---|
| 621 | |
---|
| 622 | // parse primitives, <p> nodes, line by line |
---|
| 623 | for (; c != NULL; c = c->next) |
---|
| 624 | { |
---|
| 625 | if (c->type != XML_ELEMENT_NODE) continue; |
---|
| 626 | |
---|
| 627 | // get all indices (vertices, normals, texcoords) |
---|
| 628 | // ATTENTION: holes <h/> are currently not supported !! |
---|
| 629 | String primitive = ColladaUtils::getContentDirect(c); |
---|
| 630 | |
---|
| 631 | // split the primitive string |
---|
| 632 | StringVector sallindices = StringUtil::split(primitive," "); |
---|
| 633 | if (sallindices.empty()) continue; |
---|
| 634 | |
---|
| 635 | // get the amount of vertex indices of one polygon, quad patches are pleasant |
---|
| 636 | indexCount = static_cast<uint>(sallindices.size()) / polygon->inputCount; |
---|
| 637 | if (indexCount != polygon->vertexCount) |
---|
| 638 | { |
---|
| 639 | // skip the false primitive line, but be aware of false geometries (e.g. holes)! |
---|
| 640 | // perhaps it is better to stop reading immediately? |
---|
| 641 | if (polygon->vertexCount > 0) |
---|
| 642 | { |
---|
| 643 | LogManager::getSingleton().logMessage("ColladaGeometry::importPolygonsNodes - different index count? " + mId); |
---|
| 644 | LogManager::getSingleton().logMessage("ColladaGeometry::importPolygonsNodes - primitive: " + primitive); |
---|
| 645 | continue; |
---|
| 646 | } |
---|
| 647 | polygon->vertexCount = indexCount; |
---|
| 648 | } |
---|
| 649 | |
---|
| 650 | // we can parse more than quad patches |
---|
| 651 | // but should we do this? currently there is only a simple algortihm which triangulate |
---|
| 652 | if (polygon->vertexCount > 4) |
---|
| 653 | { |
---|
| 654 | LogManager::getSingleton().logMessage("ColladaGeometry::importPolygonsNodes - why are you not using quad patches?"); |
---|
| 655 | } |
---|
| 656 | |
---|
| 657 | intVector iallindices; |
---|
| 658 | iallindices.reserve(sallindices.size()); |
---|
| 659 | |
---|
| 660 | // fill up a temp indices vector with conversions to int |
---|
| 661 | for (StringVector::iterator st = sallindices.begin(); st != sallindices.end(); ++st) |
---|
| 662 | { |
---|
| 663 | iallindices.push_back(atoi((*st).c_str())); |
---|
| 664 | } |
---|
| 665 | |
---|
| 666 | // fill up the corresponding index vectors with indices |
---|
| 667 | for (uint offset = 0; offset < static_cast<uint>(iallindices.size()); offset += polygon->inputCount) |
---|
| 668 | { |
---|
| 669 | // in order of inputs |
---|
| 670 | for (ColladaGeometryInputDataPtrVector::iterator pt = polygon->inputs.begin(); pt != polygon->inputs.end(); ++pt) |
---|
| 671 | { |
---|
| 672 | (*pt)->indices.push_back(iallindices[offset + (*pt)->idx]); |
---|
| 673 | } |
---|
| 674 | } |
---|
| 675 | |
---|
| 676 | tmppCount++; |
---|
| 677 | } |
---|
| 678 | |
---|
| 679 | // if there was a failure in parsing primitives, the amount is not still the same |
---|
| 680 | if (tmppCount < polygon->primitiveCount) polygon->primitiveCount = tmppCount; |
---|
| 681 | |
---|
| 682 | mPolygons.push_back(polygon); |
---|
| 683 | } |
---|
| 684 | |
---|
| 685 | return true; |
---|
| 686 | } |
---|
| 687 | |
---|
| 688 | //------------------------------------------------------------------------- |
---|
| 689 | ColladaGeometrySource *ColladaGeometry::importSourceNode(xmlNode *sourceNode) |
---|
| 690 | { |
---|
| 691 | if (sourceNode == NULL) return NULL; |
---|
| 692 | |
---|
| 693 | // get unique identifier |
---|
| 694 | String id = ColladaUtils::getProperty(sourceNode, CS_ATR_ID); |
---|
| 695 | |
---|
| 696 | // check if source is already loaded |
---|
| 697 | for (ColladaGeometrySourcePtrVector::iterator itsource = mSources.begin(); itsource != mSources.end(); ++itsource) |
---|
| 698 | { |
---|
| 699 | if ((*itsource)->id == id) return *itsource; |
---|
| 700 | } |
---|
| 701 | |
---|
| 702 | // get all <technique> child nodes |
---|
| 703 | xmlNodePtrVector techniques = ColladaUtils::getChildsByTagName(sourceNode, CS_ELM_TECHNIQUE); |
---|
| 704 | |
---|
| 705 | // currently we are only interested in "COMMON" profile |
---|
| 706 | xmlNode *technique = NULL; |
---|
| 707 | for (xmlNodePtrVector::iterator it = techniques.begin(); it != techniques.end(); ++it) |
---|
| 708 | { |
---|
| 709 | String profile = ColladaUtils::getProperty(*it, CS_ATR_PROFILE); |
---|
| 710 | if (profile == CS_VAL_TECHNIQUE_PROFILE_COMMON) |
---|
| 711 | { |
---|
| 712 | technique = *it; |
---|
| 713 | break; |
---|
| 714 | } |
---|
| 715 | } |
---|
| 716 | if (technique == NULL) return NULL; |
---|
| 717 | |
---|
| 718 | // currently ignore <asset>, <param> |
---|
| 719 | // get <accessor> information |
---|
| 720 | xmlNode *accessor = ColladaUtils::getChildByTagName(technique, CS_ELM_ACCESSOR); |
---|
| 721 | if (accessor == NULL) return NULL; |
---|
| 722 | // currently ignore <combiner>, <joints>, <program> |
---|
| 723 | |
---|
| 724 | // get count and stride properties |
---|
| 725 | String count = ColladaUtils::getProperty(accessor, CS_ATR_COUNT); |
---|
| 726 | String stride = ColladaUtils::getProperty(accessor, CS_ATR_ACCESSOR_STRIDE); |
---|
| 727 | |
---|
| 728 | // new source record |
---|
| 729 | ColladaGeometrySource *source = new ColladaGeometrySource(); |
---|
| 730 | source->id = id; |
---|
| 731 | source->count = (!count.empty()) ? static_cast<uint>(atoi(count.c_str())) : 0; |
---|
| 732 | source->stride = (!stride.empty()) ? static_cast<uint>(atoi(stride.c_str())) : 0; |
---|
| 733 | |
---|
| 734 | // get data from <float_array> |
---|
| 735 | xmlNode *data = ColladaUtils::getChildByTagName(sourceNode, CS_ELM_FLOAT_ARRAY); |
---|
| 736 | if (data == NULL) return NULL; |
---|
| 737 | |
---|
| 738 | String content = ColladaUtils::getContentDirect(data); |
---|
| 739 | if (content.empty()) return NULL; |
---|
| 740 | |
---|
| 741 | // split string data by carriage return and line feed |
---|
| 742 | StringVector lines = StringUtil::split(content,"\r\n"); |
---|
| 743 | if (lines.size() != source->count) source->count = static_cast<uint>(lines.size()); |
---|
| 744 | // reserve enough space |
---|
| 745 | source->data.reserve(source->count * source->stride); |
---|
| 746 | // walk through each data per line |
---|
| 747 | for (StringVector::iterator jt = lines.begin(); jt != lines.end(); ++jt) |
---|
| 748 | { |
---|
| 749 | // split each line by a blank |
---|
| 750 | StringVector line = StringUtil::split(*jt," "); |
---|
| 751 | // for vertices (x, y, z), normals (x, y, z), texcoord (s, t), ... |
---|
| 752 | for (StringVector::iterator kt = line.begin(); kt != line.end(); ++kt) |
---|
| 753 | { |
---|
| 754 | source->data.push_back( StringConverter::parseReal(*kt) ); |
---|
| 755 | } |
---|
| 756 | } |
---|
| 757 | |
---|
| 758 | mSources.push_back(source); |
---|
| 759 | |
---|
| 760 | return source; |
---|
| 761 | } |
---|
| 762 | |
---|
| 763 | //------------------------------------------------------------------------- |
---|
| 764 | bool ColladaGeometry::importVerticesNode(xmlNode *meshNode) |
---|
| 765 | { |
---|
| 766 | // get <vertices ...> node of mesh |
---|
| 767 | xmlNode *vertices = ColladaUtils::getChildByTagName(meshNode, CS_ELM_VERTICES); |
---|
| 768 | if (vertices == NULL) |
---|
| 769 | { |
---|
| 770 | LogManager::getSingleton().logMessage("ColladaGeometry::importVerticesNode - no <vertices> node found in <geometry> " + mId); |
---|
| 771 | return false; |
---|
| 772 | } |
---|
| 773 | |
---|
| 774 | // walk through <input> childs |
---|
| 775 | for (xmlNode *c = vertices->children; c != NULL; c = c->next) |
---|
| 776 | { |
---|
| 777 | if (c->type != XML_ELEMENT_NODE) continue; |
---|
| 778 | |
---|
| 779 | String tagname = (const char *)c->name; |
---|
| 780 | // <input> |
---|
| 781 | if (tagname == CS_ELM_INPUT) |
---|
| 782 | { |
---|
| 783 | // get semantic attribute type |
---|
| 784 | String semantic = ColladaUtils::getProperty(c, CS_ATR_INPUT_SEMANTIC); |
---|
| 785 | ColladaGeometrySpecific::Semantic tmpsemantic = ColladaGeometrySpecific::getSemantic(semantic); |
---|
| 786 | |
---|
| 787 | if (tmpsemantic == ColladaGeometrySpecific::POSITION || |
---|
| 788 | tmpsemantic == ColladaGeometrySpecific::NORMAL || |
---|
| 789 | tmpsemantic == ColladaGeometrySpecific::COLOR || |
---|
| 790 | tmpsemantic == ColladaGeometrySpecific::TEXCOORD) |
---|
| 791 | { |
---|
| 792 | // if (tmpsemantic == ColladaGeometryInput::NORMAL) mhasNormals = true; |
---|
| 793 | // if (tmpsemantic == ColladaGeometryInput::TEXCOORD) mhasTexCoords = true; |
---|
| 794 | |
---|
| 795 | // get source string |
---|
| 796 | String source = ColladaUtils::getProperty(c, CS_ATR_INPUT_SOURCE); |
---|
| 797 | if (source.empty()) continue; |
---|
| 798 | |
---|
| 799 | // import source |
---|
| 800 | ColladaGeometrySource *gsource = importSourceNode(ColladaUtils::getChildById(meshNode, source.c_str())); |
---|
| 801 | if (gsource == NULL) |
---|
| 802 | { |
---|
| 803 | LogManager::getSingleton().logMessage("ColladaGeometry::importVerticesNode - unable to find/import <source> with id " + source); |
---|
| 804 | continue; |
---|
| 805 | } |
---|
| 806 | |
---|
| 807 | // make new inputdata and push it on the vector |
---|
| 808 | ColladaGeometryInputData *idata = new ColladaGeometryInputData(); |
---|
| 809 | idata->semantic = tmpsemantic; |
---|
| 810 | idata->source = gsource; |
---|
| 811 | |
---|
| 812 | mVertexInputs.push_back(idata); |
---|
| 813 | } |
---|
| 814 | // unknown or unsupported |
---|
| 815 | else |
---|
| 816 | { |
---|
| 817 | LogManager::getSingleton().logMessage("ColladaGeometry::importVerticesNode - unknown <semantic> " + semantic + " in <geometry> " + mId); |
---|
| 818 | continue; |
---|
| 819 | } |
---|
| 820 | } |
---|
| 821 | // unknown or unsupported |
---|
| 822 | else |
---|
| 823 | { |
---|
| 824 | LogManager::getSingleton().logMessage("ColladaGeometry::importVerticesNode - unknown child: " + tagname); |
---|
| 825 | } |
---|
| 826 | } |
---|
| 827 | |
---|
| 828 | // there must be at least one <input semantic="POSITION" ...> |
---|
| 829 | return (mVertexInputs.at(0)->semantic == ColladaGeometrySpecific::POSITION); |
---|
| 830 | } |
---|
| 831 | |
---|
| 832 | //---------------------------------------------------------------------------- |
---|
| 833 | void ColladaGeometry::printIndices(void) |
---|
| 834 | { |
---|
| 835 | LogManager::getSingleton().logMessage(StringConverter::toString(mOgreMesh->indices.size())); |
---|
| 836 | for (ColladaGeometryOgreMeshIndexData::iterator it = mOgreMesh->indices.begin(); it != mOgreMesh->indices.end(); ++it) |
---|
| 837 | { |
---|
| 838 | String result = ""; |
---|
| 839 | for (uint i = 0; i < (*it)->count; i++) |
---|
| 840 | { |
---|
| 841 | if (i % 3 == 0) result += "\n"; |
---|
| 842 | result += " " + StringConverter::toString((*it)->indices[i]); |
---|
| 843 | } |
---|
| 844 | LogManager::getSingleton().logMessage(result + " " + StringConverter::toString((*it)->count) + " " + (*it)->material); |
---|
| 845 | } |
---|
| 846 | } |
---|
| 847 | |
---|
| 848 | //---------------------------------------------------------------------------- |
---|
| 849 | void ColladaGeometry::printVertices(const unsigned short x) |
---|
| 850 | { |
---|
| 851 | String result = ""; |
---|
| 852 | LogManager::getSingleton().logMessage(StringConverter::toString(mOgreMesh->vertexCount)); |
---|
| 853 | for (uint i = 0; i < mOgreMesh->vertexCount * x; i++) |
---|
| 854 | { |
---|
| 855 | if (i % x == 0) result += "\n"; |
---|
| 856 | result += " " + StringConverter::toString(mOgreMesh->vertices[i]); |
---|
| 857 | } |
---|
| 858 | LogManager::getSingleton().logMessage(result); |
---|
| 859 | } |
---|
| 860 | |
---|
| 861 | //---------------------------------------------------------------------------- |
---|
| 862 | void ColladaGeometry::setBoundingBox(ColladaBoundingBox *b) |
---|
| 863 | { |
---|
| 864 | if (mBB == NULL) return; |
---|
| 865 | |
---|
| 866 | mBB = b; |
---|
| 867 | mBBReset = true; |
---|
| 868 | } |
---|
| 869 | |
---|
| 870 | //---------------------------------------------------------------------------- |
---|
| 871 | namespace ColladaGeometrySpecific |
---|
| 872 | { |
---|
| 873 | Semantic getSemantic(const String &s) |
---|
| 874 | { |
---|
| 875 | if (s == CS_VAL_INPUT_SEMANTIC_POSITION) return POSITION; |
---|
| 876 | else if (s == CS_VAL_INPUT_SEMANTIC_VERTEX) return VERTEX; |
---|
| 877 | else if (s == CS_VAL_INPUT_SEMANTIC_NORMAL) return NORMAL; |
---|
| 878 | else if (s == CS_VAL_INPUT_SEMANTIC_TEXCOORD) return TEXCOORD; |
---|
| 879 | else if (s == CS_VAL_INPUT_SEMANTIC_COLOR) return COLOR; |
---|
| 880 | else return UNKNOWN; |
---|
| 881 | } |
---|
| 882 | } |
---|
| 883 | } |
---|