00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright © 2000-2004 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 #include "OgreStableHeaders.h" 00026 #include "OgreEdgeListBuilder.h" 00027 #include "OgreLogManager.h" 00028 #include "OgreStringConverter.h" 00029 #include "OgreVertexIndexData.h" 00030 #include "OgreException.h" 00031 00032 namespace Ogre { 00033 00034 void EdgeData::log(Log* l) 00035 { 00036 EdgeGroupList::iterator i, iend; 00037 EdgeList::iterator ei, eiend; 00038 TriangleList::iterator ti, tiend; 00039 tiend = triangles.end(); 00040 l->logMessage("Edge Data"); 00041 l->logMessage("---------"); 00042 size_t num = 0; 00043 for (ti = triangles.begin(); ti != tiend; ++ti, ++num) 00044 { 00045 Triangle& t = *ti; 00046 l->logMessage("Triangle " + StringConverter::toString(num) + " = {" + 00047 "indexSet=" + StringConverter::toString(t.indexSet) + ", " + 00048 "vertexSet=" + StringConverter::toString(t.vertexSet) + ", " + 00049 "v0=" + StringConverter::toString(t.vertIndex[0]) + ", " + 00050 "v1=" + StringConverter::toString(t.vertIndex[1]) + ", " + 00051 "v2=" + StringConverter::toString(t.vertIndex[2]) + "}"); 00052 } 00053 iend = edgeGroups.end(); 00054 for (i = edgeGroups.begin(); i != iend; ++i) 00055 { 00056 num = 0; 00057 eiend = i->edges.end(); 00058 l->logMessage("Edge Group vertexSet=" + StringConverter::toString(i->vertexSet)); 00059 for (ei = i->edges.begin(); ei != eiend; ++ei, ++num) 00060 { 00061 Edge& e = *ei; 00062 l->logMessage( 00063 "Edge " + StringConverter::toString(num) + " = {\n" + 00064 " tri0=" + StringConverter::toString(e.triIndex[0]) + ", \n" + 00065 " tri1=" + StringConverter::toString(e.triIndex[1]) + ", \n" + 00066 " v0=" + StringConverter::toString(e.vertIndex[0]) + ", \n" + 00067 " v1=" + StringConverter::toString(e.vertIndex[1]) + ", \n" 00068 " degenerate=" + StringConverter::toString(e.degenerate) + " \n" 00069 "}"); 00070 } 00071 } 00072 } 00073 //--------------------------------------------------------------------- 00074 EdgeListBuilder::EdgeListBuilder() 00075 : mEdgeData(0), mWeldVertices(true), mWeldVerticesAcrossVertexSets(true), 00076 mWeldVerticesAcrossIndexSets(true) 00077 { 00078 } 00079 //--------------------------------------------------------------------- 00080 EdgeListBuilder::~EdgeListBuilder() 00081 { 00082 } 00083 //--------------------------------------------------------------------- 00084 void EdgeListBuilder::addVertexData(const VertexData* vertexData) 00085 { 00086 mVertexDataList.push_back(vertexData); 00087 } 00088 //--------------------------------------------------------------------- 00089 void EdgeListBuilder::addIndexData(const IndexData* indexData, 00090 size_t vertexSet, RenderOperation::OperationType opType) 00091 { 00092 mIndexDataList.push_back(indexData); 00093 mIndexDataVertexDataSetList.push_back(vertexSet); 00094 mOperationTypeList.push_back(opType); 00095 } 00096 //--------------------------------------------------------------------- 00097 EdgeData* EdgeListBuilder::build(void) 00098 { 00099 /* Ok, here's the algorithm: 00100 For each set of indices in turn 00101 // First pass, create triangles and create edges 00102 For each set of 3 indexes 00103 Create a new Triangle entry in the list 00104 For each vertex referenced by the tri indexes 00105 Get the position of the vertex as a Vector3 from the correct vertex buffer 00106 Attempt to locate this position in the existing common vertex set 00107 If not found 00108 Create a new common vertex entry in the list 00109 End If 00110 Populate the original vertex index and common vertex index 00111 Next vertex 00112 If commonIndex[0] < commonIndex[1] 00113 Create a new edge 00114 End If 00115 If commonIndex[1] < commonIndex[2] 00116 Create a new edge 00117 End If 00118 If commonIndex[2] < commonIndex[0] 00119 Create a new edge 00120 End If 00121 Next set of 3 indexes 00122 Next index set 00123 // Identify shared edges (works across index sets) 00124 For each triangle in the common triangle list 00125 If commonIndex[0] > commonIndex[1] 00126 Find existing edge and update with second side 00127 End If 00128 If commonIndex[1] > commonIndex[2] 00129 Find existing edge and update with second side 00130 End If 00131 If commonIndex[2] > commonIndex[0] 00132 Find existing edge and update with second side 00133 End If 00134 Next triangle 00135 00136 Note that all edges 'belong' to the index set which originally caused them 00137 to be created, which also means that the 2 vertices on the edge are both referencing the 00138 vertex buffer which this index set uses. 00139 */ 00140 00141 00142 /* 00143 There is a major consideration: 'What is a common vertex'? This is a 00144 crucial decision, since to form a completely close hull, you need to treat 00145 vertices which are not physically the same as equivalent. This is because 00146 there will be 'seams' in the model, where discrepancies in vertex components 00147 other than position (such as normals or texture coordinates) will mean 00148 that there are 2 vertices in the same place, and we MUST 'weld' them 00149 into a single common vertex in order to have a closed hull. Just looking 00150 at the unique vertex indices is not enough, since these seams would render 00151 the hull invalid. 00152 00153 So, we look for positions which are the same across vertices, and treat 00154 those as as single vertex for our edge calculation. However, this has 00155 it's own problems. There are OTHER vertices which may have a common 00156 position that should not be welded. Imagine 2 cubes touching along one 00157 single edge. The common vertices on that edge, if welded, will cause 00158 an ambiguous hull, since the edge will have 4 triangles attached to it, 00159 whilst a manifold mesh should only have 2 triangles attached to each edge. 00160 This is a problem. 00161 00162 We deal with this with fallback techniques. We try the following approaches, 00163 in order, falling back on the next approach if the current one results in 00164 an ambiguous hull: 00165 00166 1. Weld all vertices at the same position across all vertex and index sets. 00167 2. Weld vertices at the same position if they are in the same vertex set, 00168 but regardless of the index set 00169 3. Weld vertices at the same position if they were first referred to in 00170 the same index set, but regardless of the vertex set. 00171 4. Weld vertices only if they are in the same vertex set AND they are first 00172 referenced in the same index set. 00173 5. Never weld vertices at the same position. This will only result in a 00174 valid hull if there are no seams in the mesh (perfect vertex sharing) 00175 00176 If all these techniques fail, the hull cannot be built. 00177 00178 Therefore, when you have a model which has a potentially ambiguous hull, 00179 (meeting at edges), you MUST EITHER: 00180 00181 A. differentiate the individual sub-hulls by separating them by 00182 vertex set or by index set. 00183 or B. ensure that you have no seams, ie you have perfect vertex sharing. 00184 This is typically only feasible when you have no textures and 00185 completely smooth shading 00186 */ 00187 00188 ushort technique = 1; 00189 bool validHull= false; 00190 00191 while (!validHull && technique <= 5) 00192 { 00193 switch (technique) 00194 { 00195 case 1: // weld across everything 00196 mWeldVertices = true; 00197 mWeldVerticesAcrossVertexSets = true; 00198 mWeldVerticesAcrossIndexSets = true; 00199 break; 00200 case 2: // weld across index sets only 00201 mWeldVertices = true; 00202 mWeldVerticesAcrossVertexSets = false; 00203 mWeldVerticesAcrossIndexSets = true; 00204 break; 00205 case 3: // weld across vertex sets only 00206 mWeldVertices = true; 00207 mWeldVerticesAcrossVertexSets = true; 00208 mWeldVerticesAcrossIndexSets = false; 00209 break; 00210 case 4: // weld within same index & vertex set only 00211 mWeldVertices = true; 00212 mWeldVerticesAcrossVertexSets = false; 00213 mWeldVerticesAcrossIndexSets = false; 00214 break; 00215 case 5: // never weld 00216 mWeldVertices = false; 00217 mWeldVerticesAcrossVertexSets = false; 00218 mWeldVerticesAcrossIndexSets = false; 00219 break; 00220 }; 00221 00222 // Log alternate techniques 00223 if (technique > 1) 00224 { 00225 LogManager::getSingleton().logMessage( 00226 "Trying alternate edge building technique " + 00227 StringConverter::toString(technique)); 00228 } 00229 00230 try 00231 { 00232 attemptBuild(); 00233 // if we got here with no exceptions, we're done 00234 validHull = true; 00235 } 00236 catch (Exception& e) 00237 { 00238 if (e.getNumber() == Exception::ERR_DUPLICATE_ITEM) 00239 { 00240 // Ambiguous hull, try next technique 00241 ++technique; 00242 } 00243 else 00244 { 00245 throw; 00246 } 00247 00248 } 00249 } 00250 00251 return mEdgeData; 00252 00253 } 00254 //--------------------------------------------------------------------- 00255 void EdgeListBuilder::attemptBuild(void) 00256 { 00257 // reset 00258 mVertices.clear(); 00259 mUniqueEdges.clear(); 00260 if (mEdgeData) 00261 { 00262 mEdgeData->triangles.clear(); 00263 EdgeData::EdgeGroupList::iterator egi, egiend; 00264 egiend = mEdgeData->edgeGroups.end(); 00265 for(egi = mEdgeData->edgeGroups.begin(); egi != egiend; ++egi) 00266 { 00267 egi->edges.clear(); 00268 } 00269 } 00270 else 00271 { 00272 mEdgeData = new EdgeData(); 00273 } 00274 // resize the edge group list to equal the number of vertex sets 00275 mEdgeData->edgeGroups.resize(mVertexDataList.size()); 00276 // Initialise edge group data 00277 for (unsigned short vSet = 0; vSet < mVertexDataList.size(); ++vSet) 00278 { 00279 mEdgeData->edgeGroups[vSet].vertexSet = vSet; 00280 mEdgeData->edgeGroups[vSet].vertexData = mVertexDataList[vSet]; 00281 } 00282 00283 IndexDataList::iterator i, iend; 00284 std::vector<size_t>::iterator mapi, mapiend; 00285 mapiend = mIndexDataVertexDataSetList.end(); 00286 mapi = mIndexDataVertexDataSetList.begin(); 00287 iend = mIndexDataList.end(); 00288 // Stage 1, build triangles and initial edge list 00289 size_t indexSet = 0; 00290 for (i = mIndexDataList.begin(); i != iend; ++i, ++mapi, ++indexSet) 00291 { 00292 buildTrianglesEdges(indexSet, *mapi); 00293 } 00294 // Stage 2, link edges 00295 connectEdges(); 00296 00297 // Log 00298 //log(LogManager::getSingleton().createLog("EdgeListBuilder.log")); 00299 00300 } 00301 //--------------------------------------------------------------------- 00302 void EdgeListBuilder::buildTrianglesEdges(size_t indexSet, size_t vertexSet) 00303 { 00304 const IndexData* indexData = mIndexDataList[indexSet]; 00305 RenderOperation::OperationType opType = mOperationTypeList[indexSet]; 00306 00307 size_t iterations; 00308 00309 switch (opType) 00310 { 00311 case RenderOperation::OT_TRIANGLE_LIST: 00312 iterations = indexData->indexCount / 3; 00313 break; 00314 case RenderOperation::OT_TRIANGLE_FAN: 00315 case RenderOperation::OT_TRIANGLE_STRIP: 00316 iterations = indexData->indexCount - 2; 00317 break; 00318 default: 00319 break; 00320 }; 00321 00322 00323 00324 // locate position element & the buffer to go with it 00325 const VertexData* vertexData = mVertexDataList[vertexSet]; 00326 const VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); 00327 HardwareVertexBufferSharedPtr vbuf = 00328 vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); 00329 // lock the buffer for reading 00330 unsigned char* pBaseVertex = static_cast<unsigned char*>( 00331 vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); 00332 00333 // Get the indexes ready for reading 00334 unsigned short* p16Idx; 00335 unsigned int* p32Idx; 00336 00337 if (indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT) 00338 { 00339 p32Idx = static_cast<unsigned int*>( 00340 indexData->indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); 00341 } 00342 else 00343 { 00344 p16Idx = static_cast<unsigned short*>( 00345 indexData->indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); 00346 } 00347 00348 // Iterate over all the groups of 3 indexes 00349 Real* pReal; 00350 // Get the triangle start, if we have more than one index set then this 00351 // will not be zero 00352 size_t triStart = mEdgeData->triangles.size(); 00353 // Pre-reserve memory for less thrashing 00354 mEdgeData->triangles.reserve(triStart + iterations); 00355 for (size_t t = 0; t < iterations; ++t) 00356 { 00357 EdgeData::Triangle tri; 00358 tri.indexSet = indexSet; 00359 tri.vertexSet = vertexSet; 00360 00361 unsigned int index[3]; 00362 Vector3 v[3]; 00363 for (size_t i = 0; i < 3; ++i) 00364 { 00365 // Standard 3-index read for tri list or first tri in strip / fan 00366 if (opType == RenderOperation::OT_TRIANGLE_LIST || 00367 t == 0) 00368 { 00369 if (indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT) 00370 { 00371 index[i] = *p32Idx++; 00372 } 00373 else 00374 { 00375 index[i] = *p16Idx++; 00376 } 00377 } 00378 else 00379 { 00380 // Strips and fans are formed from last 2 indexes plus the 00381 // current one for triangles after the first 00382 if (indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT) 00383 { 00384 index[i] = p32Idx[i-2]; 00385 } 00386 else 00387 { 00388 index[i] = p16Idx[i-2]; 00389 } 00390 // Perform single-index increment at the last tri index 00391 if (i == 2) 00392 { 00393 if (indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT) 00394 { 00395 p32Idx++; 00396 } 00397 else 00398 { 00399 p16Idx++; 00400 } 00401 00402 } 00403 00404 } 00405 00406 // Populate tri original vertex index 00407 tri.vertIndex[i] = index[i]; 00408 00409 // Retrieve the vertex position 00410 unsigned char* pVertex = pBaseVertex + (index[i] * vbuf->getVertexSize()); 00411 posElem->baseVertexPointerToElement(pVertex, &pReal); 00412 v[i].x = *pReal++; 00413 v[i].y = *pReal++; 00414 v[i].z = *pReal++; 00415 // find this vertex in the existing vertex map, or create it 00416 tri.sharedVertIndex[i] = 00417 findOrCreateCommonVertex(v[i], vertexSet, indexSet, index[i]); 00418 } 00419 // Calculate triangle normal (NB will require recalculation for 00420 // skeletally animated meshes) 00421 tri.normal = Math::calculateFaceNormal(v[0], v[1], v[2]); 00422 // Add triangle to list 00423 mEdgeData->triangles.push_back(tri); 00424 // Create edges from common list 00425 try { 00426 if (tri.sharedVertIndex[0] < tri.sharedVertIndex[1]) 00427 { 00428 createEdge(vertexSet, triStart + t, 00429 tri.vertIndex[0], tri.vertIndex[1], 00430 tri.sharedVertIndex[0], tri.sharedVertIndex[1]); 00431 } 00432 if (tri.sharedVertIndex[1] < tri.sharedVertIndex[2]) 00433 { 00434 createEdge(vertexSet, triStart + t, 00435 tri.vertIndex[1], tri.vertIndex[2], 00436 tri.sharedVertIndex[1], tri.sharedVertIndex[2]); 00437 } 00438 if (tri.sharedVertIndex[2] < tri.sharedVertIndex[0]) 00439 { 00440 createEdge(vertexSet, triStart + t, 00441 tri.vertIndex[2], tri.vertIndex[0], 00442 tri.sharedVertIndex[2], tri.sharedVertIndex[0]); 00443 } 00444 } 00445 catch (Exception& e) 00446 { 00447 // unlock buffers so this is repeatable if required 00448 indexData->indexBuffer->unlock(); 00449 vbuf->unlock(); 00450 throw; 00451 } 00452 00453 } 00454 indexData->indexBuffer->unlock(); 00455 vbuf->unlock(); 00456 00457 00458 00459 00460 } 00461 //--------------------------------------------------------------------- 00462 void EdgeListBuilder::createEdge(size_t vertexSet, size_t triangleIndex, 00463 size_t vertIndex0, size_t vertIndex1, size_t sharedVertIndex0, 00464 size_t sharedVertIndex1) 00465 { 00466 // Check unique on shared vertices 00467 std::pair<size_t, size_t> vertPair; 00468 vertPair.first = sharedVertIndex0; 00469 vertPair.second = sharedVertIndex1; 00470 UniqueEdgeSet::iterator ui = mUniqueEdges.find(vertPair); 00471 if (ui != mUniqueEdges.end()) 00472 { 00473 Except(Exception::ERR_DUPLICATE_ITEM, 00474 "Edge is shared by too many triangles", 00475 "EdgeListBuilder::createEdge"); 00476 } 00477 mUniqueEdges.insert(vertPair); 00478 00479 EdgeData::Edge e; 00480 e.degenerate = true; // initialise as degenerate 00481 00482 // Set only first tri, the other will be completed in connectEdges 00483 e.triIndex[0] = triangleIndex; 00484 e.sharedVertIndex[0] = sharedVertIndex0; 00485 e.sharedVertIndex[1] = sharedVertIndex1; 00486 e.vertIndex[0] = vertIndex0; 00487 e.vertIndex[1] = vertIndex1; 00488 mEdgeData->edgeGroups[vertexSet].edges.push_back(e); 00489 00490 } 00491 //--------------------------------------------------------------------- 00492 size_t EdgeListBuilder::findOrCreateCommonVertex(const Vector3& vec, 00493 size_t vertexSet, size_t indexSet, size_t originalIndex) 00494 { 00495 // Iterate over existing list 00496 CommonVertexList::iterator i, iend; 00497 iend = mVertices.end(); 00498 size_t index = 0; 00499 for (i = mVertices.begin(); i != iend; ++i, ++index) 00500 { 00501 const CommonVertex& commonVec = *i; 00502 // weld common vertex by position 00503 if (Math::RealEqual(vec.x, commonVec.position.x, 1e-04) && 00504 Math::RealEqual(vec.y, commonVec.position.y, 1e-04) && 00505 Math::RealEqual(vec.z, commonVec.position.z, 1e-04) && 00506 (commonVec.vertexSet == vertexSet || mWeldVerticesAcrossVertexSets) && 00507 (commonVec.indexSet == indexSet || mWeldVerticesAcrossIndexSets) && 00508 (commonVec.originalIndex == originalIndex || mWeldVertices)) 00509 { 00510 return index; 00511 } 00512 00513 00514 } 00515 // Not found, insert 00516 CommonVertex newCommon; 00517 newCommon.index = mVertices.size(); 00518 newCommon.position = vec; 00519 newCommon.vertexSet = vertexSet; 00520 newCommon.indexSet = indexSet; 00521 newCommon.originalIndex = originalIndex; 00522 mVertices.push_back(newCommon); 00523 return newCommon.index; 00524 } 00525 //--------------------------------------------------------------------- 00526 void EdgeListBuilder::connectEdges(void) 00527 { 00528 // Iterate over existing triangles 00529 EdgeData::TriangleList::iterator ti, tiend; 00530 tiend = mEdgeData->triangles.end(); 00531 size_t triIndex = 0; 00532 for (ti = mEdgeData->triangles.begin(); ti != tiend; ++ti, ++triIndex) 00533 { 00534 EdgeData::Triangle& tri = *ti; 00535 EdgeData::Edge* e; 00536 if (tri.sharedVertIndex[0] > tri.sharedVertIndex[1]) 00537 { 00538 e = findEdge(tri.sharedVertIndex[1], tri.sharedVertIndex[0]); 00539 if (e) 00540 { 00541 e->triIndex[1] = triIndex; 00542 e->degenerate = false; 00543 } 00544 } 00545 if (tri.sharedVertIndex[1] > tri.sharedVertIndex[2]) 00546 { 00547 // Find the existing edge (should be reversed order) 00548 e = findEdge(tri.sharedVertIndex[2], tri.sharedVertIndex[1]); 00549 if (e) 00550 { 00551 e->triIndex[1] = triIndex; 00552 e->degenerate = false; 00553 } 00554 } 00555 if (tri.sharedVertIndex[2] > tri.sharedVertIndex[0]) 00556 { 00557 e = findEdge(tri.sharedVertIndex[0], tri.sharedVertIndex[2]); 00558 if (e) 00559 { 00560 e->triIndex[1] = triIndex; 00561 e->degenerate = false; 00562 } 00563 } 00564 00565 } 00566 00567 00568 } 00569 //--------------------------------------------------------------------- 00570 EdgeData::Edge* EdgeListBuilder::findEdge(size_t sharedIndex1, size_t sharedIndex2) 00571 { 00572 // Iterate over the existing edges 00573 EdgeData::EdgeGroupList::iterator i, iend; 00574 EdgeData::EdgeList::iterator ei, eiend; 00575 00576 iend = mEdgeData->edgeGroups.end(); 00577 for (i = mEdgeData->edgeGroups.begin(); i != iend; ++i) 00578 { 00579 eiend = i->edges.end(); 00580 for (ei = i->edges.begin(); ei != eiend; ++ei) 00581 { 00582 EdgeData::Edge& e = *ei; 00583 if (e.sharedVertIndex[0] == sharedIndex1 && e.sharedVertIndex[1] == sharedIndex2) 00584 { 00585 return &(*ei); 00586 } 00587 } 00588 } 00589 00590 // no edge 00591 return 0; 00592 00593 } 00594 //--------------------------------------------------------------------- 00595 //--------------------------------------------------------------------- 00596 void EdgeData::updateTriangleLightFacing(const Vector4& lightPos) 00597 { 00598 // Iterate over the triangles, and determine if they are light facing 00599 EdgeData::TriangleList::iterator ti, tiend; 00600 tiend = triangles.end(); 00601 Vector3 vertToLight; 00602 for (ti = triangles.begin(); ti != tiend; ++ti) 00603 { 00604 EdgeData::Triangle& t = *ti; 00605 // Get pointer to positions, and reference the first position 00606 00607 Real dp = t.normal.dotProduct(lightPos); 00608 t.lightFacing = (dp > 0); 00609 00610 } 00611 00612 } 00613 //--------------------------------------------------------------------- 00614 void EdgeData::updateFaceNormals(size_t vertexSet, 00615 HardwareVertexBufferSharedPtr positionBuffer) 00616 { 00617 assert (positionBuffer->getVertexSize() == sizeof(Real) * 3 00618 && "Position buffer should contain only positions!"); 00619 00620 // Lock buffer for reading 00621 Real* pVert = static_cast<Real*>( 00622 positionBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); 00623 00624 // Iterate over the triangles 00625 EdgeData::TriangleList::iterator i, iend; 00626 iend = triangles.end(); 00627 for (i = triangles.begin(); i != iend; ++i) 00628 { 00629 Triangle& t = *i; 00630 // Only update tris which are using this vertex set 00631 if (t.vertexSet == vertexSet) 00632 { 00633 size_t offset = t.vertIndex[0]*3; 00634 Vector3 v1(pVert + offset); 00635 00636 offset = t.vertIndex[1]*3; 00637 Vector3 v2(pVert + offset); 00638 00639 offset = t.vertIndex[2]*3; 00640 Vector3 v3(pVert + offset); 00641 00642 t.normal = Math::calculateFaceNormal(v1, v2, v3); 00643 } 00644 } 00645 00646 00647 // unlock the buffer 00648 positionBuffer->unlock(); 00649 } 00650 //--------------------------------------------------------------------- 00651 void EdgeListBuilder::log(Log* l) 00652 { 00653 l->logMessage("EdgeListBuilder Log"); 00654 l->logMessage("-------------------"); 00655 l->logMessage("Number of vertex sets: " + StringConverter::toString(mVertexDataList.size())); 00656 l->logMessage("Number of index sets: " + StringConverter::toString(mIndexDataList.size())); 00657 00658 size_t i, j; 00659 // Log original vertex data 00660 for(i = 0; i < mVertexDataList.size(); ++i) 00661 { 00662 const VertexData* vData = mVertexDataList[i]; 00663 l->logMessage("."); 00664 l->logMessage("Original vertex set " + 00665 StringConverter::toString(i) + " - vertex count " + 00666 StringConverter::toString(vData->vertexCount)); 00667 const VertexElement* posElem = vData->vertexDeclaration->findElementBySemantic(VES_POSITION); 00668 HardwareVertexBufferSharedPtr vbuf = 00669 vData->vertexBufferBinding->getBuffer(posElem->getSource()); 00670 // lock the buffer for reading 00671 unsigned char* pBaseVertex = static_cast<unsigned char*>( 00672 vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); 00673 Real* pReal; 00674 for (j = 0; j < vData->vertexCount; ++j) 00675 { 00676 posElem->baseVertexPointerToElement(pBaseVertex, &pReal); 00677 l->logMessage("Vertex " + StringConverter::toString(j) + 00678 ": (" + StringConverter::toString(pReal[0]) + 00679 ", " + StringConverter::toString(pReal[1]) + 00680 ", " + StringConverter::toString(pReal[2]) + ")"); 00681 pBaseVertex += vbuf->getVertexSize(); 00682 } 00683 vbuf->unlock(); 00684 } 00685 00686 // Log original index data 00687 for(i = 0; i < mIndexDataList.size(); i++) 00688 { 00689 const IndexData* iData = mIndexDataList[i]; 00690 l->logMessage("."); 00691 l->logMessage("Original triangle set " + 00692 StringConverter::toString(i) + " - index count " + 00693 StringConverter::toString(iData->indexCount) + " - " + 00694 "vertex set " + StringConverter::toString(mIndexDataVertexDataSetList[i]) + " - " + 00695 "operationType " + StringConverter::toString(mOperationTypeList[i])); 00696 // Get the indexes ready for reading 00697 unsigned short* p16Idx; 00698 unsigned int* p32Idx; 00699 00700 if (iData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT) 00701 { 00702 p32Idx = static_cast<unsigned int*>( 00703 iData->indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); 00704 } 00705 else 00706 { 00707 p16Idx = static_cast<unsigned short*>( 00708 iData->indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); 00709 } 00710 00711 for (j = 0; j < iData->indexCount; ) 00712 { 00713 if (iData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT) 00714 { 00715 if (mOperationTypeList[i] == RenderOperation::OT_TRIANGLE_LIST 00716 || j == 0) 00717 { 00718 l->logMessage("Triangle " + StringConverter::toString(j) + 00719 ": (" + StringConverter::toString(*p32Idx++) + 00720 ", " + StringConverter::toString(*p32Idx++) + 00721 ", " + StringConverter::toString(*p32Idx++) + ")"); 00722 j += 3; 00723 } 00724 else 00725 { 00726 l->logMessage("Triangle " + StringConverter::toString(j) + 00727 ": (" + StringConverter::toString(*p32Idx++) + ")"); 00728 j++; 00729 } 00730 } 00731 else 00732 { 00733 if (mOperationTypeList[i] == RenderOperation::OT_TRIANGLE_LIST 00734 || j == 0) 00735 { 00736 l->logMessage("Index " + StringConverter::toString(j) + 00737 ": (" + StringConverter::toString(*p16Idx++) + 00738 ", " + StringConverter::toString(*p16Idx++) + 00739 ", " + StringConverter::toString(*p16Idx++) + ")"); 00740 j += 3; 00741 } 00742 else 00743 { 00744 l->logMessage("Triangle " + StringConverter::toString(j) + 00745 ": (" + StringConverter::toString(*p16Idx++) + ")"); 00746 j++; 00747 } 00748 } 00749 00750 00751 } 00752 00753 iData->indexBuffer->unlock(); 00754 00755 00756 // Log common vertex list 00757 l->logMessage("."); 00758 l->logMessage("Common vertex list - vertex count " + 00759 StringConverter::toString(mVertices.size())); 00760 for (i = 0; i < mVertices.size(); ++i) 00761 { 00762 CommonVertex& c = mVertices[i]; 00763 l->logMessage("Common vertex " + StringConverter::toString(i) + 00764 ": (vertexSet=" + StringConverter::toString(c.vertexSet) + 00765 ", originalIndex=" + StringConverter::toString(c.originalIndex) + 00766 ", position=" + StringConverter::toString(c.position)); 00767 } 00768 } 00769 00770 } 00771 00772 00773 00774 } 00775
Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:23 2004