Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/Tools/XSIExport/include/OgreXSIMeshExporter.h @ 6

Last change on this file since 6 was 6, checked in by anonymous, 17 years ago

=…

File size: 12.9 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#ifndef __XSIMESHEXPORTER_H__
30#define __XSIMESHEXPORTER_H__
31
32#include "OgrePrerequisites.h"
33#include "OgreVector2.h"
34#include "OgreVector3.h"
35#include "OgreColourValue.h"
36#include "OgreMesh.h"
37#include "OgreXSIHelper.h"
38#include <xsi_x3dobject.h>
39#include <xsi_string.h>
40#include <xsi_application.h>
41#include <xsi_geometry.h>
42#include <xsi_triangle.h>
43#include <xsi_polygonface.h>
44#include <xsi_facet.h>
45#include <xsi_point.h>
46#include <xsi_polygonmesh.h>
47#include <xsi_shapekey.h>
48#include <xsi_clip.h>
49#include <xsi_clipcontainer.h>
50
51
52namespace Ogre {
53
54    /** Class for performing a mesh export from XSI.
55    */
56    class XsiMeshExporter
57    {
58    public:
59        XsiMeshExporter();
60        virtual ~XsiMeshExporter();
61
62                struct LodData
63                {
64                        Mesh::LodDistanceList distances;
65                        ProgressiveMesh::VertexReductionQuota quota;
66                        Real reductionValue;
67                };
68
69               
70
71               
72                /** Build an OGRe mesh ready for export.
73        @remarks
74            Every PolygonMesh object is exported as a different SubMesh. Other
75            object types are ignored.
76                @param mergeSubMeshes Whether to merge submeshes with the same material
77                @param exportChildren Whether to cascade down each objects children
78        @param edgeLists Whether to calculate edge lists
79        @param tangents Whether to calculate tangents
80                @param animList List of animations in use (of any type)
81                @param materialPrefix Prefix to give all materials
82                @param lod LOD generation parameters (if required)
83                @param skeletonName Name of the skeleton to link to if animated
84                @returns List of deformers (bones) which were found whilst exporting (if
85                        skeletonName was provided) which can be used to determine the skeleton.
86        */
87        DeformerMap& buildMeshForExport(
88            bool mergeSubMeshes, bool exportChildren, bool edgeLists, 
89                        bool tangents, VertexElementSemantic tangentSemantic, bool vertexAnimation, 
90                        AnimationList& animList, Real fps, const String& materialPrefix = StringUtil::BLANK,
91                        LodData* lod = 0, const String& skeletonName = "");
92
93                /** Perform final export of built mesh.
94                @param fileName Target file name
95                @param skelAABB AABB of skeleton bones as found in animation, to pad
96                        final bounds of mesh.
97                */
98                void exportMesh(const String& fileName, const AxisAlignedBox& skelAABB);
99
100                /** Get a list of materials which were located during the last call
101                 *  to exportMesh.
102                 */
103                MaterialMap& getMaterials(void);
104
105                /** Get the map from texture projection names to uv indexes. */
106                TextureProjectionMap& getTextureProjectionMap(void);
107    protected:
108                MeshPtr mMesh;
109        // XSI Objects
110        XSI::Application mXsiApp;
111        /** This struct represents a unique vertex, identified from a unique
112        combination of components.
113        */
114        class UniqueVertex
115        {
116        public:
117            Vector3 position;
118            Vector3 normal;
119            Vector3 uv[OGRE_MAX_TEXTURE_COORD_SETS];
120            RGBA colour;
121            // The index of the next component with the same base details
122            // but with some variation
123            size_t nextIndex;
124
125            UniqueVertex();
126            bool operator==(const UniqueVertex& rhs) const;
127
128        };
129        typedef std::vector<UniqueVertex> UniqueVertexList;
130                // dynamic index list; 32-bit until we know the max vertex index
131                typedef std::vector<uint32> IndexList;
132
133                /** An entry for a PolygonMesh - need the parent X3DObject too */
134                class PolygonMeshEntry
135                {
136                public:
137                        XSI::PolygonMesh mesh;
138                        XSI::X3DObject obj;
139
140                        PolygonMeshEntry(XSI::PolygonMesh& themesh, XSI::X3DObject& theobj)
141                                :mesh(themesh), obj(theobj)
142                        {
143                        }
144
145                };
146                /// ordering function, required for set
147                struct PolygonMeshEntryLess
148                {
149                        bool operator()(PolygonMeshEntry* lhs, PolygonMeshEntry* rhs)
150                        {
151                                // can't name objects the same in XSI, so use that
152                                return XSItoOgre(lhs->obj.GetName()) < XSItoOgre(rhs->obj.GetName());
153                        }
154                };
155
156                /** Set of polygon mesh objects we're going to process
157                  * Use a set to avoid exporting the same object twice when manually selected
158                  * and as a child of a selected object.
159                  */
160                typedef std::set<PolygonMeshEntry*,PolygonMeshEntryLess> PolygonMeshList;
161                PolygonMeshList mXsiPolygonMeshList;
162
163
164       
165                /// List of deformers we've found whilst parsing the objects
166                DeformerMap mXsiDeformerMap;
167                /// LIst of materials we've found whilst parsing the objects
168                MaterialMap mXsiMaterialMap;
169                /// Map from texture projection names to uv index
170                TextureProjectionMap mTextureProjectionMap;
171                /// Material prefix
172                String mMaterialPrefix;
173
174
175                /// Build a list of PolygonMesh instances from selection
176                void buildPolygonMeshList(bool includeChildren);
177                /// Tidy up
178                void cleanupPolygonMeshList(void);
179                /// Recursive method to locate PolygonMeshes
180                void findPolygonMeshes(XSI::X3DObject& x3dObj, bool recurse);
181                /// Build the mesh
182                void buildMesh(Mesh* pMesh, bool mergeSubmeshes, bool lookForBoneAssignments, 
183                        bool vertexAnimation, AnimationList& animList, Real fps);
184                /// Process a single PolygonMesh into one or more ProtoSubMeshes
185                void processPolygonMesh(Mesh* pMesh, PolygonMeshEntry* pm, bool lookForBoneAssignments, unsigned short progressUpdates);
186                /// Find deformers and bone assignments
187                void processBoneAssignments(Mesh* pMesh, PolygonMeshEntry* pm);
188                /// Find shape keys for a given mesh
189                void processShapeKeys(Mesh* pMesh, PolygonMeshEntry* pm);
190               
191                /// Tidy up
192                void cleanupDeformerMap(void);
193                void cleanupMaterialMap(void);
194
195                typedef std::map<size_t, size_t> IndexRemap;
196                /** Working area which will become a submesh once we've finished figuring
197                        out what goes in there.
198                */
199                struct ProtoSubMesh
200                {
201                        // Name of the submesh (may be blank if we're merging)
202                        String name;
203                        // Material name
204                        String materialName;
205                        // unique vertex list
206                        UniqueVertexList uniqueVertices;
207                        // Defines number of texture coord sets and their dimensions
208                        std::vector<ushort> textureCoordDimensions;
209                        // Vertex colours?
210                        bool hasVertexColours;
211                        // Last polymesh entry added to this proto
212                        PolygonMeshEntry* lastMeshEntry;
213                        // Index offset for last polymesh entry
214                        size_t lastMeshIndexOffset;
215                        // index list
216                        IndexList indices;
217                        // map of polygon mesh -> position index offset (only > 0 when submeshes merged)
218                        typedef std::map<PolygonMeshEntry*, size_t> PolygonMeshOffsetMap;
219                        PolygonMeshOffsetMap polygonMeshOffsetMap;
220                        // map original position index (+any PM offset) -> first real instance in this one
221                        IndexRemap posIndexRemap;
222                        Mesh::VertexBoneAssignmentList boneAssignments;
223                        /// By-value pose list, build up ready for transfer later
224                        std::list<Pose> poseList;
225                        /// List of XSI shape keys which are being used in this proto
226                        XSI::CRefArray shapeKeys;
227
228                        ProtoSubMesh() : lastMeshEntry(0), lastMeshIndexOffset(0) {}
229
230                       
231                };
232
233                /// Global shape key to pose mapping
234                struct ShapeKeyToPoseEntry
235                {
236                        XSI::CRef shapeKey;
237                        size_t poseIndex;
238                        size_t targetHandle;
239
240                };
241                typedef std::list<ShapeKeyToPoseEntry> ShapeKeyMapping;
242                ShapeKeyMapping mShapeKeyMapping;
243
244                struct ShapeClipEntry
245                {
246                        XSI::Clip clip;
247                        ShapeKeyToPoseEntry* keytoPose;
248                        long startFrame;
249                        long endFrame;
250                        long originalStartFrame; // in case clamped
251                };
252                typedef std::list<ShapeClipEntry> ShapeClipList;
253
254
255                /// List of ProtoSubMeshes that use the same material but are not geometrically compatible
256                typedef std::list<ProtoSubMesh*> ProtoSubMeshList;
257
258                /// List of proto submeshes by material
259                typedef std::map<String, ProtoSubMeshList*> MaterialProtoSubMeshMap;
260                /// List of proto submeshes by material
261                MaterialProtoSubMeshMap mMaterialProtoSubmeshMap;
262                /// List of deviant proto submeshes by polygon index (clusters)
263                typedef std::map<size_t, ProtoSubMesh*> PolygonToProtoSubMeshList;
264                /// List of deviant proto submeshes by polygon index (clusters)
265                PolygonToProtoSubMeshList mPolygonToProtoSubMeshList;
266                /// Primary ProtoSubMesh (the one used by the PolygonMesh by default)
267                ProtoSubMesh* mMainProtoMesh;
268                // Current PolygonMesh texture coord information
269                typedef std::vector<ushort> TextureCoordDimensionList;
270                TextureCoordDimensionList mCurrentTextureCoordDimensions;
271                // Current PolygonMesh sampler-ordered UV information
272                typedef std::vector<Vector3*> SamplerSetList;
273                SamplerSetList mCurrentSamplerSets;
274                // Current PolygonMesh has Vertex colours?
275                bool mCurrentHasVertexColours;
276                // Current list of deformers as we discover them (will become bones)
277
278                /// Export the current list of proto submeshes, and clear list
279                void exportProtoSubMeshes(Mesh* pMesh);
280        /// Export a single ProtoSubMesh
281        void exportProtoSubMesh(Mesh* pMesh, ProtoSubMesh* proto);
282                /// Export vertex animations
283                void exportAnimations(Mesh* pMesh, AnimationList& animList, Real fps);
284                /// Build a list of all shape clips
285                void buildShapeClipList(ShapeClipList& listToPopulate);
286                /// Build a list of all shape clips in a container
287                void buildShapeClipList(XSI::ClipContainer& container, ShapeClipList& listToPopulate);
288                /// Build a derived clip list for just a specific submesh, and a list of keys to sample
289                void deriveShapeClipAndKeyframeList(ushort targetIndex, 
290                        AnimationEntry& animEntry, ShapeClipList& inClipList, 
291                        ShapeClipList& outClipList, std::set<long>& keyFrameList);
292                /// Retrieve a ProtoSubMesh for the given material name
293                /// (creates if required, validates if re-using)
294                ProtoSubMesh* createOrRetrieveProtoSubMesh(const String& materialName,
295                        const String& name, TextureCoordDimensionList& texCoordDims,
296                        bool hasVertexColours);
297                /// Method called at the start of processing a PolygonMesh
298                bool preprocessPolygonMesh(PolygonMeshEntry* mesh);
299                /// Method called at the end of processing a PolygonMesh
300                void postprocessPolygonMesh(PolygonMeshEntry* mesh);
301
302        /** Try to look up an existing vertex with the same information, or
303            create a new one.
304        @remarks
305                        Note that we buid up the list of unique position indexes that are
306                        actually used by each ProtoSubMesh as we go. When new positions
307                        are found, they are added and a remap entry created to take account
308                        of the fact that there may be extra vertices created in between, or
309                        there may be gaps due to clusters meaning not every position is
310                        used by every ProtoSubMesh. When an existing entry is found, we
311                        compare the vertex data, and if it differs, create a new vertex and
312                        'chain' it to the previous instances of this position index through
313                        nextIndex. This means that every position vertex has a single
314                        remapped starting point in the per-ProtoSubMesh vertex list, and a
315                        unidirectional linked list of variants of that vertex where other
316                        components differ.
317        @par
318            Note that this re-uses as many vertices as possible, and also places
319            every unique vertex in it's final index in one pass, so the return
320                        value from this method can be used as an adjusted vertex index.
321        @returns The index of the unique vertex
322        */
323        size_t createOrRetrieveUniqueVertex(ProtoSubMesh* proto, 
324                        size_t positionIndex, bool positionIndexIsOriginal,
325                        const UniqueVertex& vertex);
326
327        /** Templatised method for writing indexes */
328        template <typename T> void writeIndexes(T* buf, IndexList& indexes);
329
330        /** Create and fill a vertex buffer */
331        void createVertexBuffer(VertexData* vd, unsigned short bufIdx, 
332                        UniqueVertexList& uniqueVertexList);
333
334                /** Find out the sampler indices for the given triangle */
335                void deriveSamplerIndices(const XSI::Triangle& tri, const XSI::PolygonFace& face, 
336                        size_t* samplerIndices);
337                /** Get a single sampler index */
338                size_t getSamplerIndex(const XSI::Facet &f, const XSI::Point &p);
339
340                /** Register the use of a given XSI material. */
341                void registerMaterial(const String& name, XSI::Material mat);
342
343
344
345    };
346
347}
348#endif
349
Note: See TracBrowser for help on using the repository browser.