| 1 | /* | 
|---|
| 2 | ----------------------------------------------------------------------------- | 
|---|
| 3 | This source file is part of OGRE | 
|---|
| 4 |     (Object-oriented Graphics Rendering Engine) | 
|---|
| 5 | For the latest info, see http://www.ogre3d.org/ | 
|---|
| 6 |  | 
|---|
| 7 | Copyright (c) 2000-2013 Torus Knot Software Ltd | 
|---|
| 8 |  | 
|---|
| 9 | Permission is hereby granted, free of charge, to any person obtaining a copy | 
|---|
| 10 | of this software and associated documentation files (the "Software"), to deal | 
|---|
| 11 | in the Software without restriction, including without limitation the rights | 
|---|
| 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 
|---|
| 13 | copies of the Software, and to permit persons to whom the Software is | 
|---|
| 14 | furnished to do so, subject to the following conditions: | 
|---|
| 15 |  | 
|---|
| 16 | The above copyright notice and this permission notice shall be included in | 
|---|
| 17 | all copies or substantial portions of the Software. | 
|---|
| 18 |  | 
|---|
| 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
|---|
| 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
|---|
| 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | 
|---|
| 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
|---|
| 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 
|---|
| 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 
|---|
| 25 | THE SOFTWARE. | 
|---|
| 26 | ----------------------------------------------------------------------------- | 
|---|
| 27 | */ | 
|---|
| 28 | #ifndef __EdgeListBuilder_H__ | 
|---|
| 29 | #define __EdgeListBuilder_H__ | 
|---|
| 30 |  | 
|---|
| 31 | #include "OgrePrerequisites.h" | 
|---|
| 32 | #include "OgreVector4.h" | 
|---|
| 33 | #include "OgreHardwareVertexBuffer.h" | 
|---|
| 34 | #include "OgreRenderOperation.h" | 
|---|
| 35 | #include "OgreHeaderPrefix.h" | 
|---|
| 36 |  | 
|---|
| 37 | namespace Ogre { | 
|---|
| 38 |         /** \addtogroup Core | 
|---|
| 39 |         *  @{ | 
|---|
| 40 |         */ | 
|---|
| 41 |         /** \addtogroup Math | 
|---|
| 42 |         *  @{ | 
|---|
| 43 |         */ | 
|---|
| 44 |  | 
|---|
| 45 |  | 
|---|
| 46 |     /** This class contains the information required to describe the edge connectivity of a | 
|---|
| 47 |         given set of vertices and indexes.  | 
|---|
| 48 |     @remarks  | 
|---|
| 49 |         This information is built using the EdgeListBuilder class. Note that for a given mesh, | 
|---|
| 50 |         which can be made up of multiple submeshes, there are separate edge lists for when  | 
|---|
| 51 |     */ | 
|---|
| 52 |         class _OgreExport EdgeData : public EdgeDataAlloc | 
|---|
| 53 |     { | 
|---|
| 54 |     public: | 
|---|
| 55 |                  | 
|---|
| 56 |                 EdgeData(); | 
|---|
| 57 |                  | 
|---|
| 58 |         /** Basic triangle structure. */ | 
|---|
| 59 |         struct Triangle { | 
|---|
| 60 |             /** The set of indexes this triangle came from (NB it is possible that the triangles on  | 
|---|
| 61 |                one side of an edge are using a different vertex buffer from those on the other side.) */ | 
|---|
| 62 |             size_t indexSet;  | 
|---|
| 63 |             /** The vertex set these vertices came from. */ | 
|---|
| 64 |             size_t vertexSet; | 
|---|
| 65 |             /// Vertex indexes, relative to the original buffer | 
|---|
| 66 |             size_t vertIndex[3]; | 
|---|
| 67 |             /** Vertex indexes, relative to a shared vertex buffer with | 
|---|
| 68 |                 duplicates eliminated (this buffer is not exposed) */ | 
|---|
| 69 |             size_t sharedVertIndex[3]; | 
|---|
| 70 |  | 
|---|
| 71 |                         Triangle() :indexSet(0), vertexSet(0) {} | 
|---|
| 72 |         }; | 
|---|
| 73 |         /** Edge data. */ | 
|---|
| 74 |         struct Edge { | 
|---|
| 75 |             /** The indexes of the 2 tris attached, note that tri 0 is the one where the  | 
|---|
| 76 |                 indexes run _anti_ clockwise along the edge. Indexes must be | 
|---|
| 77 |                 reversed for tri 1. */ | 
|---|
| 78 |             size_t triIndex[2]; | 
|---|
| 79 |             /** The vertex indices for this edge. Note that both vertices will be in the vertex | 
|---|
| 80 |                 set as specified in 'vertexSet', which will also be the same as tri 0 */ | 
|---|
| 81 |             size_t vertIndex[2]; | 
|---|
| 82 |             /** Vertex indices as used in the shared vertex list, not exposed. */ | 
|---|
| 83 |             size_t sharedVertIndex[2]; | 
|---|
| 84 |             /** Indicates if this is a degenerate edge, ie it does not have 2 triangles */ | 
|---|
| 85 |             bool degenerate; | 
|---|
| 86 |         }; | 
|---|
| 87 |  | 
|---|
| 88 |         /** Array of 4D vector of triangle face normal, which is unit vector orthogonal | 
|---|
| 89 |             to the triangles, plus distance from origin. | 
|---|
| 90 |             Use aligned policy here because we are intended to use in SIMD optimised routines. */ | 
|---|
| 91 |         typedef std::vector<Vector4, STLAllocator<Vector4, CategorisedAlignAllocPolicy<MEMCATEGORY_GEOMETRY> > > TriangleFaceNormalList; | 
|---|
| 92 |  | 
|---|
| 93 |         /** Working vector used when calculating the silhouette. | 
|---|
| 94 |             Use std::vector<char> instead of std::vector<bool> which might implemented | 
|---|
| 95 |             similar bit-fields causing loss performance. */ | 
|---|
| 96 |         typedef vector<char>::type TriangleLightFacingList; | 
|---|
| 97 |  | 
|---|
| 98 |         typedef vector<Triangle>::type TriangleList; | 
|---|
| 99 |         typedef vector<Edge>::type EdgeList; | 
|---|
| 100 |  | 
|---|
| 101 |         /** A group of edges sharing the same vertex data. */ | 
|---|
| 102 |         struct EdgeGroup | 
|---|
| 103 |         { | 
|---|
| 104 |             /** The vertex set index that contains the vertices for this edge group. */ | 
|---|
| 105 |             size_t vertexSet; | 
|---|
| 106 |             /** Pointer to vertex data used by this edge group. */ | 
|---|
| 107 |             const VertexData* vertexData; | 
|---|
| 108 |             /** Index to main triangles array, indicate the first triangle of this edge | 
|---|
| 109 |                 group, and all triangles of this edge group are stored continuous in | 
|---|
| 110 |                 main triangles array. | 
|---|
| 111 |             */ | 
|---|
| 112 |             size_t triStart; | 
|---|
| 113 |             /** Number triangles of this edge group. */ | 
|---|
| 114 |             size_t triCount; | 
|---|
| 115 |             /** The edges themselves. */ | 
|---|
| 116 |             EdgeList edges; | 
|---|
| 117 |  | 
|---|
| 118 |         }; | 
|---|
| 119 |  | 
|---|
| 120 |         typedef vector<EdgeGroup>::type EdgeGroupList; | 
|---|
| 121 |  | 
|---|
| 122 |         /** Main triangles array, stores all triangles of this edge list. Note that | 
|---|
| 123 |             triangles are grouping against edge group. | 
|---|
| 124 |         */ | 
|---|
| 125 |         TriangleList triangles; | 
|---|
| 126 |         /** All triangle face normals. It should be 1:1 with triangles. */ | 
|---|
| 127 |         TriangleFaceNormalList triangleFaceNormals; | 
|---|
| 128 |         /** Triangle light facing states. It should be 1:1 with triangles. */ | 
|---|
| 129 |         TriangleLightFacingList triangleLightFacings; | 
|---|
| 130 |         /** All edge groups of this edge list. */ | 
|---|
| 131 |         EdgeGroupList edgeGroups; | 
|---|
| 132 |         /** Flag indicate the mesh is manifold. */ | 
|---|
| 133 |         bool isClosed; | 
|---|
| 134 |  | 
|---|
| 135 |  | 
|---|
| 136 |         /** Calculate the light facing state of the triangles in this edge list | 
|---|
| 137 |         @remarks | 
|---|
| 138 |             This is normally the first stage of calculating a silhouette, i.e. | 
|---|
| 139 |             establishing which tris are facing the light and which are facing | 
|---|
| 140 |             away. This state is stored in the 'triangleLightFacings'. | 
|---|
| 141 |         @param lightPos 4D position of the light in object space, note that  | 
|---|
| 142 |             for directional lights (which have no position), the w component | 
|---|
| 143 |             is 0 and the x/y/z position are the direction. | 
|---|
| 144 |         */ | 
|---|
| 145 |         void updateTriangleLightFacing(const Vector4& lightPos); | 
|---|
| 146 |         /** Updates the face normals for this edge list based on (changed) | 
|---|
| 147 |             position information, useful for animated objects.  | 
|---|
| 148 |         @param vertexSet The vertex set we are updating | 
|---|
| 149 |         @param positionBuffer The updated position buffer, must contain ONLY xyz | 
|---|
| 150 |         */ | 
|---|
| 151 |         void updateFaceNormals(size_t vertexSet, const HardwareVertexBufferSharedPtr& positionBuffer); | 
|---|
| 152 |  | 
|---|
| 153 |  | 
|---|
| 154 |  | 
|---|
| 155 |         /// Debugging method | 
|---|
| 156 |         void log(Log* log); | 
|---|
| 157 |          | 
|---|
| 158 |     }; | 
|---|
| 159 |  | 
|---|
| 160 |     /** General utility class for building edge lists for geometry. | 
|---|
| 161 |     @remarks | 
|---|
| 162 |         You can add multiple sets of vertex and index data to build and edge list.  | 
|---|
| 163 |         Edges will be built between the various sets as well as within sets; this allows  | 
|---|
| 164 |         you to use a model which is built from multiple SubMeshes each using  | 
|---|
| 165 |         separate index and (optionally) vertex data and still get the same connectivity  | 
|---|
| 166 |         information. It's important to note that the indexes for the edge will be constrained | 
|---|
| 167 |         to a single vertex buffer though (this is required in order to render the edge). | 
|---|
| 168 |     */ | 
|---|
| 169 |     class _OgreExport EdgeListBuilder  | 
|---|
| 170 |     { | 
|---|
| 171 |     public: | 
|---|
| 172 |  | 
|---|
| 173 |         EdgeListBuilder(); | 
|---|
| 174 |         virtual ~EdgeListBuilder(); | 
|---|
| 175 |         /** Add a set of vertex geometry data to the edge builder.  | 
|---|
| 176 |         @remarks | 
|---|
| 177 |             You must add at least one set of vertex data to the builder before invoking the | 
|---|
| 178 |             build method. | 
|---|
| 179 |         */ | 
|---|
| 180 |         void addVertexData(const VertexData* vertexData); | 
|---|
| 181 |         /** Add a set of index geometry data to the edge builder.  | 
|---|
| 182 |         @remarks | 
|---|
| 183 |             You must add at least one set of index data to the builder before invoking the | 
|---|
| 184 |             build method. | 
|---|
| 185 |         @param indexData The index information which describes the triangles. | 
|---|
| 186 |         @param vertexSet The vertex data set this index data refers to; you only need to alter this | 
|---|
| 187 |             if you have added multiple sets of vertices | 
|---|
| 188 |         @param opType The operation type used to render these indexes. Only triangle types | 
|---|
| 189 |             are supported (no point or line types) | 
|---|
| 190 |         */ | 
|---|
| 191 |         void addIndexData(const IndexData* indexData, size_t vertexSet = 0,  | 
|---|
| 192 |             RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST); | 
|---|
| 193 |  | 
|---|
| 194 |         /** Builds the edge information based on the information built up so far. | 
|---|
| 195 |         @remarks | 
|---|
| 196 |             The caller takes responsibility for deleting the returned structure. | 
|---|
| 197 |         */ | 
|---|
| 198 |         EdgeData* build(void); | 
|---|
| 199 |  | 
|---|
| 200 |         /// Debugging method | 
|---|
| 201 |         void log(Log* l); | 
|---|
| 202 |     protected: | 
|---|
| 203 |  | 
|---|
| 204 |         /** A vertex can actually represent several vertices in the final model, because | 
|---|
| 205 |                 vertices along texture seams etc will have been duplicated. In order to properly | 
|---|
| 206 |                 evaluate the surface properties, a single common vertex is used for these duplicates, | 
|---|
| 207 |                 and the faces hold the detail of the duplicated vertices. | 
|---|
| 208 |                 */ | 
|---|
| 209 |         struct CommonVertex { | 
|---|
| 210 |             Vector3  position;  /// Location of point in euclidean space | 
|---|
| 211 |                 size_t index;       /// Place of vertex in common vertex list | 
|---|
| 212 |             size_t vertexSet;   /// The vertex set this came from | 
|---|
| 213 |             size_t indexSet;    /// The index set this was referenced (first) from | 
|---|
| 214 |             size_t originalIndex; /// Place of vertex in original vertex set | 
|---|
| 215 |         }; | 
|---|
| 216 |         /** A set of indexed geometry data */ | 
|---|
| 217 |         struct Geometry { | 
|---|
| 218 |             size_t vertexSet;           /// The vertex data set this geometry data refers to | 
|---|
| 219 |             size_t indexSet;            /// The index data set this geometry data refers to | 
|---|
| 220 |             const IndexData* indexData; /// The index information which describes the triangles. | 
|---|
| 221 |             RenderOperation::OperationType opType;  /// The operation type used to render this geometry | 
|---|
| 222 |         }; | 
|---|
| 223 |         /** Comparator for sorting geometries by vertex set */ | 
|---|
| 224 |         struct geometryLess { | 
|---|
| 225 |             bool operator()(const Geometry& a, const Geometry& b) const | 
|---|
| 226 |             { | 
|---|
| 227 |                 if (a.vertexSet < b.vertexSet) return true; | 
|---|
| 228 |                 if (a.vertexSet > b.vertexSet) return false; | 
|---|
| 229 |                 return a.indexSet < b.indexSet; | 
|---|
| 230 |             } | 
|---|
| 231 |         }; | 
|---|
| 232 |         /** Comparator for unique vertex list */ | 
|---|
| 233 |         struct vectorLess { | 
|---|
| 234 |             bool operator()(const Vector3& a, const Vector3& b) const | 
|---|
| 235 |             { | 
|---|
| 236 |                 if (a.x < b.x) return true; | 
|---|
| 237 |                 if (a.x > b.x) return false; | 
|---|
| 238 |                 if (a.y < b.y) return true; | 
|---|
| 239 |                 if (a.y > b.y) return false; | 
|---|
| 240 |                 return a.z < b.z; | 
|---|
| 241 |             } | 
|---|
| 242 |         }; | 
|---|
| 243 |  | 
|---|
| 244 |         typedef vector<const VertexData*>::type VertexDataList; | 
|---|
| 245 |         typedef vector<Geometry>::type GeometryList; | 
|---|
| 246 |         typedef vector<CommonVertex>::type CommonVertexList; | 
|---|
| 247 |  | 
|---|
| 248 |         GeometryList mGeometryList; | 
|---|
| 249 |         VertexDataList mVertexDataList; | 
|---|
| 250 |         CommonVertexList mVertices; | 
|---|
| 251 |         EdgeData* mEdgeData; | 
|---|
| 252 |                 /// Map for identifying common vertices | 
|---|
| 253 |                 typedef map<Vector3, size_t, vectorLess>::type CommonVertexMap; | 
|---|
| 254 |                 CommonVertexMap mCommonVertexMap; | 
|---|
| 255 |         /** Edge map, used to connect edges. Note we allow many triangles on an edge, | 
|---|
| 256 |         after connected an existing edge, we will remove it and never used again. | 
|---|
| 257 |         */ | 
|---|
| 258 |         typedef multimap< std::pair<size_t, size_t>, std::pair<size_t, size_t> >::type EdgeMap; | 
|---|
| 259 |         EdgeMap mEdgeMap; | 
|---|
| 260 |  | 
|---|
| 261 |         void buildTrianglesEdges(const Geometry &geometry); | 
|---|
| 262 |  | 
|---|
| 263 |         /// Finds an existing common vertex, or inserts a new one | 
|---|
| 264 |         size_t findOrCreateCommonVertex(const Vector3& vec, size_t vertexSet,  | 
|---|
| 265 |             size_t indexSet, size_t originalIndex); | 
|---|
| 266 |         /// Connect existing edge or create a new edge - utility method during building | 
|---|
| 267 |         void connectOrCreateEdge(size_t vertexSet, size_t triangleIndex, size_t vertIndex0, size_t vertIndex1,  | 
|---|
| 268 |             size_t sharedVertIndex0, size_t sharedVertIndex1); | 
|---|
| 269 |     }; | 
|---|
| 270 |         /** @} */ | 
|---|
| 271 |         /** @} */ | 
|---|
| 272 |  | 
|---|
| 273 | } | 
|---|
| 274 |  | 
|---|
| 275 | #include "OgreHeaderSuffix.h" | 
|---|
| 276 |  | 
|---|
| 277 | #endif | 
|---|
| 278 |  | 
|---|