| 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-2006 Torus Knot Software Ltd |
|---|
| 8 | Also see acknowledgements in Readme.html |
|---|
| 9 | |
|---|
| 10 | This program is free software; you can redistribute it and/or modify it under |
|---|
| 11 | the terms of the GNU Lesser General Public License as published by the Free Software |
|---|
| 12 | Foundation; either version 2 of the License, or (at your option) any later |
|---|
| 13 | version. |
|---|
| 14 | |
|---|
| 15 | This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|---|
| 17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. |
|---|
| 18 | |
|---|
| 19 | You should have received a copy of the GNU Lesser General Public License along with |
|---|
| 20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
|---|
| 21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to |
|---|
| 22 | http://www.gnu.org/copyleft/lesser.txt. |
|---|
| 23 | |
|---|
| 24 | You may alternatively use this source under the terms of a specific version of |
|---|
| 25 | the OGRE Unrestricted License provided you have obtained such a license from |
|---|
| 26 | Torus Knot Software Ltd. |
|---|
| 27 | ----------------------------------------------------------------------------- |
|---|
| 28 | */ |
|---|
| 29 | #ifndef __EdgeListBuilder_H__ |
|---|
| 30 | #define __EdgeListBuilder_H__ |
|---|
| 31 | |
|---|
| 32 | #include "OgrePrerequisites.h" |
|---|
| 33 | #include "OgreVector4.h" |
|---|
| 34 | #include "OgreHardwareVertexBuffer.h" |
|---|
| 35 | #include "OgreRenderOperation.h" |
|---|
| 36 | #include "OgreAlignedAllocator.h" |
|---|
| 37 | |
|---|
| 38 | namespace Ogre { |
|---|
| 39 | |
|---|
| 40 | |
|---|
| 41 | /** This class contains the information required to describe the edge connectivity of a |
|---|
| 42 | given set of vertices and indexes. |
|---|
| 43 | @remarks |
|---|
| 44 | This information is built using the EdgeListBuilder class. Note that for a given mesh, |
|---|
| 45 | which can be made up of multiple submeshes, there are separate edge lists for when |
|---|
| 46 | */ |
|---|
| 47 | class _OgreExport EdgeData |
|---|
| 48 | { |
|---|
| 49 | public: |
|---|
| 50 | /** Basic triangle structure. */ |
|---|
| 51 | struct Triangle { |
|---|
| 52 | /** The set of indexes this triangle came from (NB it is possible that the triangles on |
|---|
| 53 | one side of an edge are using a different vertex buffer from those on the other side.) */ |
|---|
| 54 | size_t indexSet; |
|---|
| 55 | /** The vertex set these vertices came from. */ |
|---|
| 56 | size_t vertexSet; |
|---|
| 57 | size_t vertIndex[3];/// Vertex indexes, relative to the original buffer |
|---|
| 58 | size_t sharedVertIndex[3]; /// Vertex indexes, relative to a shared vertex buffer with |
|---|
| 59 | // duplicates eliminated (this buffer is not exposed) |
|---|
| 60 | }; |
|---|
| 61 | /** Edge data. */ |
|---|
| 62 | struct Edge { |
|---|
| 63 | /** The indexes of the 2 tris attached, note that tri 0 is the one where the |
|---|
| 64 | indexes run _anti_ clockwise along the edge. Indexes must be |
|---|
| 65 | reversed for tri 1. */ |
|---|
| 66 | size_t triIndex[2]; |
|---|
| 67 | /** The vertex indices for this edge. Note that both vertices will be in the vertex |
|---|
| 68 | set as specified in 'vertexSet', which will also be the same as tri 0 */ |
|---|
| 69 | size_t vertIndex[2]; |
|---|
| 70 | /** Vertex indices as used in the shared vertex list, not exposed. */ |
|---|
| 71 | size_t sharedVertIndex[2]; |
|---|
| 72 | /** Indicates if this is a degenerate edge, ie it does not have 2 triangles */ |
|---|
| 73 | bool degenerate; |
|---|
| 74 | }; |
|---|
| 75 | |
|---|
| 76 | // Array of 4D vector of triangle face normal, which is unit vector othogonal |
|---|
| 77 | // to the triangles, plus distance from origin. |
|---|
| 78 | // Use aligned allocator here because we are intented to use in SIMD optimised routines . |
|---|
| 79 | typedef std::vector<Vector4, AlignedAllocator<Vector4> > TriangleFaceNormalList; |
|---|
| 80 | |
|---|
| 81 | // Working vector used when calculating the silhouette. |
|---|
| 82 | // Use std::vector<char> instead of std::vector<bool> which might implemented |
|---|
| 83 | // similar bit-fields causing loss performance. |
|---|
| 84 | typedef std::vector<char> TriangleLightFacingList; |
|---|
| 85 | |
|---|
| 86 | typedef std::vector<Triangle> TriangleList; |
|---|
| 87 | typedef std::vector<Edge> EdgeList; |
|---|
| 88 | |
|---|
| 89 | /** A group of edges sharing the same vertex data. */ |
|---|
| 90 | struct EdgeGroup |
|---|
| 91 | { |
|---|
| 92 | /** The vertex set index that contains the vertices for this edge group. */ |
|---|
| 93 | size_t vertexSet; |
|---|
| 94 | /** Pointer to vertex data used by this edge group. */ |
|---|
| 95 | const VertexData* vertexData; |
|---|
| 96 | /** Index to main triangles array, indicate the first triangle of this edge |
|---|
| 97 | group, and all triangles of this edge group are stored continuous in |
|---|
| 98 | main triangles array. |
|---|
| 99 | */ |
|---|
| 100 | size_t triStart; |
|---|
| 101 | /** Number triangles of this edge group. */ |
|---|
| 102 | size_t triCount; |
|---|
| 103 | /** The edges themselves. */ |
|---|
| 104 | EdgeList edges; |
|---|
| 105 | |
|---|
| 106 | }; |
|---|
| 107 | |
|---|
| 108 | typedef std::vector<EdgeGroup> EdgeGroupList; |
|---|
| 109 | |
|---|
| 110 | /** Main triangles array, stores all triangles of this edge list. Note that |
|---|
| 111 | triangles are grouping against edge group. |
|---|
| 112 | */ |
|---|
| 113 | TriangleList triangles; |
|---|
| 114 | /** All triangle face normals. It should be 1:1 with triangles. */ |
|---|
| 115 | TriangleFaceNormalList triangleFaceNormals; |
|---|
| 116 | /** Triangle light facing states. It should be 1:1 with triangles. */ |
|---|
| 117 | TriangleLightFacingList triangleLightFacings; |
|---|
| 118 | /** All edge groups of this edge list. */ |
|---|
| 119 | EdgeGroupList edgeGroups; |
|---|
| 120 | /** Flag indicate the mesh is manifold. */ |
|---|
| 121 | bool isClosed; |
|---|
| 122 | |
|---|
| 123 | |
|---|
| 124 | /** Calculate the light facing state of the triangles in this edge list |
|---|
| 125 | @remarks |
|---|
| 126 | This is normally the first stage of calculating a silhouette, ie |
|---|
| 127 | establishing which tris are facing the light and which are facing |
|---|
| 128 | away. This state is stored in the 'triangleLightFacings'. |
|---|
| 129 | @param lightPos 4D position of the light in object space, note that |
|---|
| 130 | for directional lights (which have no position), the w component |
|---|
| 131 | is 0 and the x/y/z position are the direction. |
|---|
| 132 | */ |
|---|
| 133 | void updateTriangleLightFacing(const Vector4& lightPos); |
|---|
| 134 | /** Updates the face normals for this edge list based on (changed) |
|---|
| 135 | position information, useful for animated objects. |
|---|
| 136 | @param vertexSet The vertex set we are updating |
|---|
| 137 | @param positionBuffer The updated position buffer, must contain ONLY xyz |
|---|
| 138 | */ |
|---|
| 139 | void updateFaceNormals(size_t vertexSet, const HardwareVertexBufferSharedPtr& positionBuffer); |
|---|
| 140 | |
|---|
| 141 | |
|---|
| 142 | |
|---|
| 143 | // Debugging method |
|---|
| 144 | void log(Log* log); |
|---|
| 145 | |
|---|
| 146 | }; |
|---|
| 147 | |
|---|
| 148 | /** General utility class for building edge lists for geometry. |
|---|
| 149 | @remarks |
|---|
| 150 | You can add multiple sets of vertex and index data to build and edge list. |
|---|
| 151 | Edges will be built between the various sets as well as within sets; this allows |
|---|
| 152 | you to use a model which is built from multiple SubMeshes each using |
|---|
| 153 | separate index and (optionally) vertex data and still get the same connectivity |
|---|
| 154 | information. It's important to note that the indexes for the edge will be constrained |
|---|
| 155 | to a single vertex buffer though (this is required in order to render the edge). |
|---|
| 156 | */ |
|---|
| 157 | class _OgreExport EdgeListBuilder |
|---|
| 158 | { |
|---|
| 159 | public: |
|---|
| 160 | |
|---|
| 161 | EdgeListBuilder(); |
|---|
| 162 | virtual ~EdgeListBuilder(); |
|---|
| 163 | /** Add a set of vertex geometry data to the edge builder. |
|---|
| 164 | @remarks |
|---|
| 165 | You must add at least one set of vertex data to the builder before invoking the |
|---|
| 166 | build method. |
|---|
| 167 | */ |
|---|
| 168 | void addVertexData(const VertexData* vertexData); |
|---|
| 169 | /** Add a set of index geometry data to the edge builder. |
|---|
| 170 | @remarks |
|---|
| 171 | You must add at least one set of index data to the builder before invoking the |
|---|
| 172 | build method. |
|---|
| 173 | @param indexData The index information which describes the triangles. |
|---|
| 174 | @param vertexSet The vertex data set this index data refers to; you only need to alter this |
|---|
| 175 | if you have added multiple sets of vertices |
|---|
| 176 | @param opType The operation type used to render these indexes. Only triangle types |
|---|
| 177 | are supported (no point or line types) |
|---|
| 178 | */ |
|---|
| 179 | void addIndexData(const IndexData* indexData, size_t vertexSet = 0, |
|---|
| 180 | RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST); |
|---|
| 181 | |
|---|
| 182 | /** Builds the edge information based on the information built up so far. |
|---|
| 183 | @remarks |
|---|
| 184 | The caller takes responsibility for deleting the returned structure. |
|---|
| 185 | */ |
|---|
| 186 | EdgeData* build(void); |
|---|
| 187 | |
|---|
| 188 | /// Debugging method |
|---|
| 189 | void log(Log* l); |
|---|
| 190 | protected: |
|---|
| 191 | |
|---|
| 192 | /** A vertex can actually represent several vertices in the final model, because |
|---|
| 193 | vertices along texture seams etc will have been duplicated. In order to properly |
|---|
| 194 | evaluate the surface properties, a single common vertex is used for these duplicates, |
|---|
| 195 | and the faces hold the detail of the duplicated vertices. |
|---|
| 196 | */ |
|---|
| 197 | struct CommonVertex { |
|---|
| 198 | Vector3 position; // location of point in euclidean space |
|---|
| 199 | size_t index; // place of vertex in common vertex list |
|---|
| 200 | size_t vertexSet; // The vertex set this came from |
|---|
| 201 | size_t indexSet; // The index set this was referenced (first) from |
|---|
| 202 | size_t originalIndex; // place of vertex in original vertex set |
|---|
| 203 | }; |
|---|
| 204 | /** A set of indexed geometry data */ |
|---|
| 205 | struct Geometry { |
|---|
| 206 | size_t vertexSet; // The vertex data set this geometry data refers to |
|---|
| 207 | size_t indexSet; // The index data set this geometry data refers to |
|---|
| 208 | const IndexData* indexData; // The index information which describes the triangles. |
|---|
| 209 | RenderOperation::OperationType opType; // The operation type used to render this geometry |
|---|
| 210 | }; |
|---|
| 211 | /** Comparator for sorting geometries by vertex set */ |
|---|
| 212 | struct geometryLess { |
|---|
| 213 | bool operator()(const Geometry& a, const Geometry& b) const |
|---|
| 214 | { |
|---|
| 215 | if (a.vertexSet < b.vertexSet) return true; |
|---|
| 216 | if (a.vertexSet > b.vertexSet) return false; |
|---|
| 217 | return a.indexSet < b.indexSet; |
|---|
| 218 | } |
|---|
| 219 | }; |
|---|
| 220 | /** Comparator for unique vertex list */ |
|---|
| 221 | struct vectorLess { |
|---|
| 222 | bool operator()(const Vector3& a, const Vector3& b) const |
|---|
| 223 | { |
|---|
| 224 | if (a.x < b.x) return true; |
|---|
| 225 | if (a.x > b.x) return false; |
|---|
| 226 | if (a.y < b.y) return true; |
|---|
| 227 | if (a.y > b.y) return false; |
|---|
| 228 | return a.z < b.z; |
|---|
| 229 | } |
|---|
| 230 | }; |
|---|
| 231 | |
|---|
| 232 | typedef std::vector<const VertexData*> VertexDataList; |
|---|
| 233 | typedef std::vector<Geometry> GeometryList; |
|---|
| 234 | typedef std::vector<CommonVertex> CommonVertexList; |
|---|
| 235 | |
|---|
| 236 | GeometryList mGeometryList; |
|---|
| 237 | VertexDataList mVertexDataList; |
|---|
| 238 | CommonVertexList mVertices; |
|---|
| 239 | EdgeData* mEdgeData; |
|---|
| 240 | /// Map for identifying common vertices |
|---|
| 241 | typedef std::map<Vector3, size_t, vectorLess> CommonVertexMap; |
|---|
| 242 | CommonVertexMap mCommonVertexMap; |
|---|
| 243 | /** Edge map, used to connect edges. Note we allow many triangles on an edge, |
|---|
| 244 | after connected an existing edge, we will remove it and never used again. |
|---|
| 245 | */ |
|---|
| 246 | typedef std::multimap< std::pair<size_t, size_t>, std::pair<size_t, size_t> > EdgeMap; |
|---|
| 247 | EdgeMap mEdgeMap; |
|---|
| 248 | |
|---|
| 249 | void buildTrianglesEdges(const Geometry &geometry); |
|---|
| 250 | |
|---|
| 251 | /// Finds an existing common vertex, or inserts a new one |
|---|
| 252 | size_t findOrCreateCommonVertex(const Vector3& vec, size_t vertexSet, |
|---|
| 253 | size_t indexSet, size_t originalIndex); |
|---|
| 254 | /// Connect existing edge or create a new edge - utility method during building |
|---|
| 255 | void connectOrCreateEdge(size_t vertexSet, size_t triangleIndex, size_t vertIndex0, size_t vertIndex1, |
|---|
| 256 | size_t sharedVertIndex0, size_t sharedVertIndex1); |
|---|
| 257 | }; |
|---|
| 258 | |
|---|
| 259 | } |
|---|
| 260 | #endif |
|---|
| 261 | |
|---|