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