1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
4
5 Copyright (c) 2006-2017, assimp team
6
7 All rights reserved.
8
9 Redistribution and use of this software in source and binary forms,
10 with or without modification, are permitted provided that the
11 following conditions are met:
12
13 * Redistributions of source code must retain the above
14 copyright notice, this list of conditions and the
15 following disclaimer.
16
17 * Redistributions in binary form must reproduce the above
18 copyright notice, this list of conditions and the
19 following disclaimer in the documentation and/or other
20 materials provided with the distribution.
21
22 * Neither the name of the assimp team, nor the names of its
23 contributors may be used to endorse or promote products
24 derived from this software without specific prior
25 written permission of the assimp team.
26
27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39 ----------------------------------------------------------------------
40 */
41
42 /** @file Declaration of the LWO importer class. */
43 #ifndef AI_LWOLOADER_H_INCLUDED
44 #define AI_LWOLOADER_H_INCLUDED
45
46 #include <assimp/types.h>
47 #include <assimp/material.h>
48 #include <assimp/DefaultLogger.hpp>
49
50 #include "LWOFileData.h"
51 #include "BaseImporter.h"
52
53 #include <map>
54
55 struct aiTexture;
56 struct aiNode;
57 struct aiMaterial;
58
59 namespace Assimp {
60 using namespace LWO;
61
62 // ---------------------------------------------------------------------------
63 /** Class to load LWO files.
64 *
65 * @note Methods named "xxxLWO2[xxx]" are used with the newer LWO2 format.
66 * Methods named "xxxLWOB[xxx]" are used with the older LWOB format.
67 * Methods named "xxxLWO[xxx]" are used with both formats.
68 * Methods named "xxx" are used to preprocess the loaded data -
69 * they aren't specific to one format version
70 */
71 // ---------------------------------------------------------------------------
72 class LWOImporter : public BaseImporter
73 {
74 public:
75 LWOImporter();
76 ~LWOImporter();
77
78
79 public:
80
81 // -------------------------------------------------------------------
82 /** Returns whether the class can handle the format of the given file.
83 * See BaseImporter::CanRead() for details.
84 */
85 bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
86 bool checkSig) const;
87
88
89 // -------------------------------------------------------------------
90 /** Called prior to ReadFile().
91 * The function is a request to the importer to update its configuration
92 * basing on the Importer's configuration property list.
93 */
94 void SetupProperties(const Importer* pImp);
95
96 protected:
97
98 // -------------------------------------------------------------------
99 // Get list of supported extensions
100 const aiImporterDesc* GetInfo () const;
101
102 // -------------------------------------------------------------------
103 /** Imports the given file into the given scene structure.
104 * See BaseImporter::InternReadFile() for details
105 */
106 void InternReadFile( const std::string& pFile, aiScene* pScene,
107 IOSystem* pIOHandler);
108
109 private:
110
111 // -------------------------------------------------------------------
112 /** Loads a LWO file in the older LWOB format (LW < 6)
113 */
114 void LoadLWOBFile();
115
116 // -------------------------------------------------------------------
117 /** Loads a LWO file in the newer LWO2 format (LW >= 6)
118 */
119 void LoadLWO2File();
120
121
122 // -------------------------------------------------------------------
123 /** Parsing functions used for all file format versions
124 */
125 inline void GetS0(std::string& out,unsigned int max);
126 inline float GetF4();
127 inline uint32_t GetU4();
128 inline uint16_t GetU2();
129 inline uint8_t GetU1();
130
131
132 // -------------------------------------------------------------------
133 /** Loads a surface chunk from an LWOB file
134 * @param size Maximum size to be read, in bytes.
135 */
136 void LoadLWOBSurface(unsigned int size);
137
138 // -------------------------------------------------------------------
139 /** Loads a surface chunk from an LWO2 file
140 * @param size Maximum size to be read, in bytes.
141 */
142 void LoadLWO2Surface(unsigned int size);
143
144 // -------------------------------------------------------------------
145 /** Loads a texture block from a LWO2 file.
146 * @param size Maximum size to be read, in bytes.
147 * @param head Header of the SUF.BLOK header
148 */
149 void LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head,
150 unsigned int size );
151
152 // -------------------------------------------------------------------
153 /** Loads a shader block from a LWO2 file.
154 * @param size Maximum size to be read, in bytes.
155 * @param head Header of the SUF.BLOK header
156 */
157 void LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* head,
158 unsigned int size );
159
160 // -------------------------------------------------------------------
161 /** Loads an image map from a LWO2 file
162 * @param size Maximum size to be read, in bytes.
163 * @param tex Texture object to be filled
164 */
165 void LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex );
166 void LoadLWO2Gradient(unsigned int size, LWO::Texture& tex );
167 void LoadLWO2Procedural(unsigned int size, LWO::Texture& tex );
168
169 // loads the header - used by thethree functions above
170 void LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex );
171
172 // -------------------------------------------------------------------
173 /** Loads the LWO tag list from the file
174 * @param size Maximum size to be read, in bytes.
175 */
176 void LoadLWOTags(unsigned int size);
177
178 // -------------------------------------------------------------------
179 /** Load polygons from a POLS chunk
180 * @param length Size of the chunk
181 */
182 void LoadLWO2Polygons(unsigned int length);
183 void LoadLWOBPolygons(unsigned int length);
184
185 // -------------------------------------------------------------------
186 /** Load polygon tags from a PTAG chunk
187 * @param length Size of the chunk
188 */
189 void LoadLWO2PolygonTags(unsigned int length);
190
191 // -------------------------------------------------------------------
192 /** Load a vertex map from a VMAP/VMAD chunk
193 * @param length Size of the chunk
194 * @param perPoly Operate on per-polygon base?
195 */
196 void LoadLWO2VertexMap(unsigned int length, bool perPoly);
197
198 // -------------------------------------------------------------------
199 /** Load polygons from a PNTS chunk
200 * @param length Size of the chunk
201 */
202 void LoadLWOPoints(unsigned int length);
203
204 // -------------------------------------------------------------------
205 /** Load a clip from a CLIP chunk
206 * @param length Size of the chunk
207 */
208 void LoadLWO2Clip(unsigned int length);
209
210 // -------------------------------------------------------------------
211 /** Load an envelope from an EVL chunk
212 * @param length Size of the chunk
213 */
214 void LoadLWO2Envelope(unsigned int length);
215
216 // -------------------------------------------------------------------
217 /** Count vertices and faces in a LWOB/LWO2 file
218 */
219 void CountVertsAndFacesLWO2(unsigned int& verts,
220 unsigned int& faces,
221 uint16_t*& cursor,
222 const uint16_t* const end,
223 unsigned int max = UINT_MAX);
224
225 void CountVertsAndFacesLWOB(unsigned int& verts,
226 unsigned int& faces,
227 LE_NCONST uint16_t*& cursor,
228 const uint16_t* const end,
229 unsigned int max = UINT_MAX);
230
231 // -------------------------------------------------------------------
232 /** Read vertices and faces in a LWOB/LWO2 file
233 */
234 void CopyFaceIndicesLWO2(LWO::FaceList::iterator& it,
235 uint16_t*& cursor,
236 const uint16_t* const end);
237
238 // -------------------------------------------------------------------
239 void CopyFaceIndicesLWOB(LWO::FaceList::iterator& it,
240 LE_NCONST uint16_t*& cursor,
241 const uint16_t* const end,
242 unsigned int max = UINT_MAX);
243
244 // -------------------------------------------------------------------
245 /** Resolve the tag and surface lists that have been loaded.
246 * Generates the mMapping table.
247 */
248 void ResolveTags();
249
250 // -------------------------------------------------------------------
251 /** Resolve the clip list that has been loaded.
252 * Replaces clip references with real clips.
253 */
254 void ResolveClips();
255
256 // -------------------------------------------------------------------
257 /** Add a texture list to an output material description.
258 *
259 * @param pcMat Output material
260 * @param in Input texture list
261 * @param type Type identifier of the texture list
262 */
263 bool HandleTextures(aiMaterial* pcMat, const TextureList& in,
264 aiTextureType type);
265
266 // -------------------------------------------------------------------
267 /** Adjust a texture path
268 */
269 void AdjustTexturePath(std::string& out);
270
271 // -------------------------------------------------------------------
272 /** Convert a LWO surface description to an ASSIMP material
273 */
274 void ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat);
275
276
277 // -------------------------------------------------------------------
278 /** Get a list of all UV/VC channels required by a specific surface.
279 *
280 * @param surf Working surface
281 * @param layer Working layer
282 * @param out Output list. The members are indices into the
283 * UV/VC channel lists of the layer
284 */
285 void FindUVChannels(/*const*/ LWO::Surface& surf,
286 LWO::SortedRep& sorted,
287 /*const*/ LWO::Layer& layer,
288 unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS]);
289
290 // -------------------------------------------------------------------
291 char FindUVChannels(LWO::TextureList& list,
292 LWO::Layer& layer,LWO::UVChannel& uv, unsigned int next);
293
294 // -------------------------------------------------------------------
295 void FindVCChannels(const LWO::Surface& surf,
296 LWO::SortedRep& sorted,
297 const LWO::Layer& layer,
298 unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS]);
299
300 // -------------------------------------------------------------------
301 /** Generate the final node graph
302 * Unused nodes are deleted.
303 * @param apcNodes Flat list of nodes
304 */
305 void GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes);
306
307 // -------------------------------------------------------------------
308 /** Add children to a node
309 * @param node Node to become a father
310 * @param parent Index of the node
311 * @param apcNodes Flat list of nodes - used nodes are set to NULL.
312 */
313 void AddChildren(aiNode* node, uint16_t parent,
314 std::vector<aiNode*>& apcNodes);
315
316 // -------------------------------------------------------------------
317 /** Read a variable sized integer
318 * @param inout Input and output buffer
319 */
320 int ReadVSizedIntLWO2(uint8_t*& inout);
321
322 // -------------------------------------------------------------------
323 /** Assign a value from a VMAP to a vertex and all vertices
324 * attached to it.
325 * @param base VMAP destination data
326 * @param numRead Number of float's to be read
327 * @param idx Absolute index of the first vertex
328 * @param data Value of the VMAP to be assigned - read numRead
329 * floats from this array.
330 */
331 void DoRecursiveVMAPAssignment(VMapEntry* base, unsigned int numRead,
332 unsigned int idx, float* data);
333
334 // -------------------------------------------------------------------
335 /** Compute normal vectors for a mesh
336 * @param mesh Input mesh
337 * @param smoothingGroups Smoothing-groups-per-face array
338 * @param surface Surface for the mesh
339 */
340 void ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>& smoothingGroups,
341 const LWO::Surface& surface);
342
343
344 // -------------------------------------------------------------------
345 /** Setup a new texture after the corresponding chunk was
346 * encountered in the file.
347 * @param list Texture list
348 * @param size Maximum number of bytes to be read
349 * @return Pointer to new texture
350 */
351 LWO::Texture* SetupNewTextureLWOB(LWO::TextureList& list,
352 unsigned int size);
353
354 protected:
355
356 /** true if the file is a LWO2 file*/
357 bool mIsLWO2;
358
359 /** true if the file is a LXOB file*/
360 bool mIsLXOB;
361
362 /** Temporary list of layers from the file */
363 LayerList* mLayers;
364
365 /** Pointer to the current layer */
366 LWO::Layer* mCurLayer;
367
368 /** Temporary tag list from the file */
369 TagList* mTags;
370
371 /** Mapping table to convert from tag to surface indices.
372 UINT_MAX indicates that a no corresponding surface is available */
373 TagMappingTable* mMapping;
374
375 /** Temporary surface list from the file */
376 SurfaceList* mSurfaces;
377
378 /** Temporary clip list from the file */
379 ClipList mClips;
380
381 /** Temporary envelope list from the file */
382 EnvelopeList mEnvelopes;
383
384 /** file buffer */
385 uint8_t* mFileBuffer;
386
387 /** Size of the file, in bytes */
388 unsigned int fileSize;
389
390 /** Output scene */
391 aiScene* pScene;
392
393 /** Configuration option: speed flag set? */
394 bool configSpeedFlag;
395
396 /** Configuration option: index of layer to be loaded */
397 unsigned int configLayerIndex;
398
399 /** Configuration option: name of layer to be loaded */
400 std::string configLayerName;
401
402 /** True if we have a named layer */
403 bool hasNamedLayer;
404 };
405
406
407 // ------------------------------------------------------------------------------------------------
GetF4()408 inline float LWOImporter::GetF4()
409 {
410 float f;
411 ::memcpy(&f, mFileBuffer, 4);
412 mFileBuffer += 4;
413 AI_LSWAP4(f);
414 return f;
415 }
416
417 // ------------------------------------------------------------------------------------------------
GetU4()418 inline uint32_t LWOImporter::GetU4()
419 {
420 uint32_t f;
421 ::memcpy(&f, mFileBuffer, 4);
422 mFileBuffer += 4;
423 AI_LSWAP4(f);
424 return f;
425 }
426
427 // ------------------------------------------------------------------------------------------------
GetU2()428 inline uint16_t LWOImporter::GetU2()
429 {
430 uint16_t f;
431 ::memcpy(&f, mFileBuffer, 2);
432 mFileBuffer += 2;
433 AI_LSWAP2(f);
434 return f;
435 }
436
437 // ------------------------------------------------------------------------------------------------
GetU1()438 inline uint8_t LWOImporter::GetU1()
439 {
440 return *mFileBuffer++;
441 }
442
443 // ------------------------------------------------------------------------------------------------
ReadVSizedIntLWO2(uint8_t * & inout)444 inline int LWOImporter::ReadVSizedIntLWO2(uint8_t*& inout)
445 {
446 int i;
447 int c = *inout;inout++;
448 if(c != 0xFF)
449 {
450 i = c << 8;
451 c = *inout;inout++;
452 i |= c;
453 }
454 else
455 {
456 c = *inout;inout++;
457 i = c << 16;
458 c = *inout;inout++;
459 i |= c << 8;
460 c = *inout;inout++;
461 i |= c;
462 }
463 return i;
464 }
465
466 // ------------------------------------------------------------------------------------------------
GetS0(std::string & out,unsigned int max)467 inline void LWOImporter::GetS0(std::string& out,unsigned int max)
468 {
469 unsigned int iCursor = 0;
470 const char*sz = (const char*)mFileBuffer;
471 while (*mFileBuffer)
472 {
473 if (++iCursor > max)
474 {
475 DefaultLogger::get()->warn("LWO: Invalid file, string is is too long");
476 break;
477 }
478 ++mFileBuffer;
479 }
480 size_t len = (size_t) ((const char*)mFileBuffer-sz);
481 out = std::string(sz,len);
482 mFileBuffer += (len&0x1 ? 1 : 2);
483 }
484
485
486
487 } // end of namespace Assimp
488
489 #endif // AI_LWOIMPORTER_H_INCLUDED
490