source: OGRE/trunk/ogrenew/Tools/XSIExport/include/OgreXSIMeshExporter.h @ 692

Revision 692, 12.5 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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