[692] | 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-2005 The OGRE Team
|
---|
| 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 | */
|
---|
| 25 | #ifndef __EdgeListBuilder_H__
|
---|
| 26 | #define __EdgeListBuilder_H__
|
---|
| 27 |
|
---|
| 28 | #include "OgrePrerequisites.h"
|
---|
| 29 | #include "OgreVector4.h"
|
---|
| 30 | #include "OgreHardwareVertexBuffer.h"
|
---|
| 31 | #include "OgreRenderOperation.h"
|
---|
| 32 |
|
---|
| 33 | namespace Ogre {
|
---|
| 34 |
|
---|
| 35 |
|
---|
| 36 | /** This class contains the information required to describe the edge connectivity of a
|
---|
| 37 | given set of vertices and indexes.
|
---|
| 38 | @remarks
|
---|
| 39 | This information is built using the EdgeListBuilder class. Note that for a given mesh,
|
---|
| 40 | which can be made up of multiple submeshes, there are separate edge lists for when
|
---|
| 41 | */
|
---|
| 42 | class _OgreExport EdgeData
|
---|
| 43 | {
|
---|
| 44 | public:
|
---|
| 45 | /** Basic triangle structure. */
|
---|
| 46 | struct Triangle {
|
---|
| 47 | /** The set of indexes this triangle came from (NB it is possible that the triangles on
|
---|
| 48 | one side of an edge are using a different vertex buffer from those on the other side.) */
|
---|
| 49 | size_t indexSet;
|
---|
| 50 | /** The vertex set these vertices came from. */
|
---|
| 51 | size_t vertexSet;
|
---|
| 52 | size_t vertIndex[3];/// Vertex indexes, relative to the original buffer
|
---|
| 53 | size_t sharedVertIndex[3]; /// Vertex indexes, relative to a shared vertex buffer with
|
---|
| 54 | // duplicates eliminated (this buffer is not exposed)
|
---|
| 55 | Vector4 normal; // unit vector othogonal to this face, plus distance from origin
|
---|
| 56 | bool lightFacing; // Working vector used when calculating the silhouette
|
---|
| 57 | };
|
---|
| 58 | /** Edge data. */
|
---|
| 59 | struct Edge {
|
---|
| 60 | /** The indexes of the 2 tris attached, note that tri 0 is the one where the
|
---|
| 61 | indexes run _anti_ clockwise along the edge. Indexes must be
|
---|
| 62 | reversed for tri 1. */
|
---|
| 63 | size_t triIndex[2];
|
---|
| 64 | /** The vertex indices for this edge. Note that both vertices will be in the vertex
|
---|
| 65 | set as specified in 'vertexSet', which will also be the same as tri 0 */
|
---|
| 66 | size_t vertIndex[2];
|
---|
| 67 | /** Vertex indices as used in the shared vertex list, not exposed. */
|
---|
| 68 | size_t sharedVertIndex[2];
|
---|
| 69 | /** Indicates if this is a degenerate edge, ie it does not have 2 triangles */
|
---|
| 70 | bool degenerate;
|
---|
| 71 | };
|
---|
| 72 |
|
---|
| 73 | typedef std::vector<Triangle> TriangleList;
|
---|
| 74 | typedef std::vector<Edge> EdgeList;
|
---|
| 75 |
|
---|
| 76 | /** A group of edges sharing the same vertex data. */
|
---|
| 77 | struct EdgeGroup
|
---|
| 78 | {
|
---|
| 79 | /** The vertex set index that contains the vertices for this edge group. */
|
---|
| 80 | size_t vertexSet;
|
---|
| 81 | /** Pointer to vertex data used by this edge group. */
|
---|
| 82 | const VertexData* vertexData;
|
---|
| 83 | /** The edges themselves. */
|
---|
| 84 | EdgeList edges;
|
---|
| 85 |
|
---|
| 86 | };
|
---|
| 87 |
|
---|
| 88 | typedef std::vector<EdgeGroup> EdgeGroupList;
|
---|
| 89 | TriangleList triangles;
|
---|
| 90 | EdgeGroupList edgeGroups;
|
---|
| 91 | // manifold? NB This value is not stored in the binary Mesh format yet so
|
---|
| 92 | // cannot be relied upon unless this has been calculated interactively.
|
---|
| 93 | //bool isClosed; // manifold?
|
---|
| 94 |
|
---|
| 95 |
|
---|
| 96 | /** Calculate the light facing state of the triangles in this edge list
|
---|
| 97 | @remarks
|
---|
| 98 | This is normally the first stage of calculating a silhouette, ie
|
---|
| 99 | establishing which tris are facing the light and which are facing
|
---|
| 100 | away. This state is stored in the 'lightFacing' flag in each
|
---|
| 101 | Triangle.
|
---|
| 102 | @param lightPos 4D position of the light in object space, note that
|
---|
| 103 | for directional lights (which have no position), the w component
|
---|
| 104 | is 0 and the x/y/z position are the direction.
|
---|
| 105 | */
|
---|
| 106 | void updateTriangleLightFacing(const Vector4& lightPos);
|
---|
| 107 | /** Updates the face normals for this edge list based on (changed)
|
---|
| 108 | position information, useful for animated objects.
|
---|
| 109 | @param vertexSet The vertex set we are updating
|
---|
| 110 | @param positionBuffer The updated position buffer, must contain ONLY xyz
|
---|
| 111 | */
|
---|
| 112 | void updateFaceNormals(size_t vertexSet, HardwareVertexBufferSharedPtr positionBuffer);
|
---|
| 113 |
|
---|
| 114 |
|
---|
| 115 |
|
---|
| 116 | // Debugging method
|
---|
| 117 | void log(Log* log);
|
---|
| 118 |
|
---|
| 119 | };
|
---|
| 120 |
|
---|
| 121 | /** General utility class for building edge lists for geometry.
|
---|
| 122 | @remarks
|
---|
| 123 | You can add multiple sets of vertex and index data to build and edge list.
|
---|
| 124 | Edges will be built between the various sets as well as within sets; this allows
|
---|
| 125 | you to use a model which is built from multiple SubMeshes each using
|
---|
| 126 | separate index and (optionally) vertex data and still get the same connectivity
|
---|
| 127 | information. It's important to note that the indexes for the edge will be constrained
|
---|
| 128 | to a single vertex buffer though (this is required in order to render the edge).
|
---|
| 129 | */
|
---|
| 130 | class _OgreExport EdgeListBuilder
|
---|
| 131 | {
|
---|
| 132 | public:
|
---|
| 133 |
|
---|
| 134 | EdgeListBuilder();
|
---|
| 135 | virtual ~EdgeListBuilder();
|
---|
| 136 | /** Add a set of vertex geometry data to the edge builder.
|
---|
| 137 | @remarks
|
---|
| 138 | You must add at least one set of vertex data to the builder before invoking the
|
---|
| 139 | build method.
|
---|
| 140 | */
|
---|
| 141 | void addVertexData(const VertexData* vertexData);
|
---|
| 142 | /** Add a set of index geometry data to the edge builder.
|
---|
| 143 | @remarks
|
---|
| 144 | You must add at least one set of index data to the builder before invoking the
|
---|
| 145 | build method.
|
---|
| 146 | @param indexData The index information which describes the triangles.
|
---|
| 147 | @param vertexSet The vertex data set this index data refers to; you only need to alter this
|
---|
| 148 | if you have added multiple sets of vertices
|
---|
| 149 | @param opType The operation type used to render these indexes. Only triangle types
|
---|
| 150 | are supported (no point or line types)
|
---|
| 151 | */
|
---|
| 152 | void addIndexData(const IndexData* indexData, size_t vertexSet = 0,
|
---|
| 153 | RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST);
|
---|
| 154 |
|
---|
| 155 | /** Builds the edge information based on the information built up so far.
|
---|
| 156 | @remarks
|
---|
| 157 | The caller takes responsibility for deleting the returned structure.
|
---|
| 158 | */
|
---|
| 159 | EdgeData* build(void);
|
---|
| 160 |
|
---|
| 161 | /// Debugging method
|
---|
| 162 | void log(Log* l);
|
---|
| 163 | protected:
|
---|
| 164 |
|
---|
| 165 | /** A vertex can actually represent several vertices in the final model, because
|
---|
| 166 | vertices along texture seams etc will have been duplicated. In order to properly
|
---|
| 167 | evaluate the surface properties, a single common vertex is used for these duplicates,
|
---|
| 168 | and the faces hold the detail of the duplicated vertices.
|
---|
| 169 | */
|
---|
| 170 | struct CommonVertex {
|
---|
| 171 | Vector3 position; // location of point in euclidean space
|
---|
| 172 | size_t index; // place of vertex in common vertex list
|
---|
| 173 | size_t vertexSet; // The vertex set this came from
|
---|
| 174 | size_t indexSet; // The index set this was referenced (first) from
|
---|
| 175 | size_t originalIndex; // place of vertex in original vertex set
|
---|
| 176 | };
|
---|
| 177 | /** A set of indexed geometry data */
|
---|
| 178 | struct Geometry {
|
---|
| 179 | size_t vertexSet; // The vertex data set this geometry data refers to
|
---|
| 180 | size_t indexSet; // The index data set this geometry data refers to
|
---|
| 181 | const IndexData* indexData; // The index information which describes the triangles.
|
---|
| 182 | RenderOperation::OperationType opType; // The operation type used to render this geometry
|
---|
| 183 | };
|
---|
| 184 | /** Comparator for sorting geometries by vertex set */
|
---|
| 185 | struct geometryLess {
|
---|
| 186 | bool operator()(const Geometry& a, const Geometry& b) const
|
---|
| 187 | {
|
---|
| 188 | if (a.vertexSet < b.vertexSet) return true;
|
---|
| 189 | if (a.vertexSet > b.vertexSet) return false;
|
---|
| 190 | return a.indexSet < b.indexSet;
|
---|
| 191 | }
|
---|
| 192 | };
|
---|
| 193 | /** Comparator for unique vertex list */
|
---|
| 194 | struct vectorLess {
|
---|
| 195 | bool operator()(const Vector3& a, const Vector3& b) const
|
---|
| 196 | {
|
---|
| 197 | if (a.x < b.x) return true;
|
---|
| 198 | if (a.x > b.x) return false;
|
---|
| 199 | if (a.y < b.y) return true;
|
---|
| 200 | if (a.y > b.y) return false;
|
---|
| 201 | return a.z < b.z;
|
---|
| 202 | }
|
---|
| 203 | };
|
---|
| 204 |
|
---|
| 205 | typedef std::vector<const VertexData*> VertexDataList;
|
---|
| 206 | typedef std::vector<Geometry> GeometryList;
|
---|
| 207 | typedef std::vector<CommonVertex> CommonVertexList;
|
---|
| 208 |
|
---|
| 209 | GeometryList mGeometryList;
|
---|
| 210 | VertexDataList mVertexDataList;
|
---|
| 211 | CommonVertexList mVertices;
|
---|
| 212 | EdgeData* mEdgeData;
|
---|
| 213 | /// Map for identifying common vertices
|
---|
| 214 | typedef std::map<Vector3, size_t, vectorLess> CommonVertexMap;
|
---|
| 215 | CommonVertexMap mCommonVertexMap;
|
---|
| 216 | /** Edge map, used to connect edges. Note we allow many triangles on an edge,
|
---|
| 217 | after connected an existing edge, we will remove it and never used again.
|
---|
| 218 | */
|
---|
| 219 | typedef std::multimap< std::pair<size_t, size_t>, std::pair<size_t, size_t> > EdgeMap;
|
---|
| 220 | EdgeMap mEdgeMap;
|
---|
| 221 |
|
---|
| 222 | void buildTrianglesEdges(const Geometry &geometry);
|
---|
| 223 |
|
---|
| 224 | /// Finds an existing common vertex, or inserts a new one
|
---|
| 225 | size_t findOrCreateCommonVertex(const Vector3& vec, size_t vertexSet,
|
---|
| 226 | size_t indexSet, size_t originalIndex);
|
---|
| 227 | /// Connect existing edge or create a new edge - utility method during building
|
---|
| 228 | void connectOrCreateEdge(size_t vertexSet, size_t triangleIndex, size_t vertIndex0, size_t vertIndex1,
|
---|
| 229 | size_t sharedVertIndex0, size_t sharedVertIndex1);
|
---|
| 230 | };
|
---|
| 231 |
|
---|
| 232 | }
|
---|
| 233 | #endif
|
---|
| 234 |
|
---|