Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

# OgreEdgeListBuilder.cpp

Go to the documentation of this file.

    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