1/*
2Open Asset Import Library (assimp)
3----------------------------------------------------------------------
4
5Copyright (c) 2006-2017, assimp team
6
7All rights reserved.
8
9Redistribution and use of this software in source and binary forms,
10with or without modification, are permitted provided that the
11following 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
27THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39----------------------------------------------------------------------
40*/
41
42/** @file Defines helper data structures for the import of 3DS files */
43
44#ifndef AI_3DSFILEHELPER_H_INC
45#define AI_3DSFILEHELPER_H_INC
46
47#include "SpatialSort.h"
48#include "SmoothingGroups.h"
49#include "StringUtils.h"
50#include "qnan.h"
51#include <assimp/material.h>
52#include <assimp/camera.h>
53#include <assimp/light.h>
54#include <assimp/anim.h>
55#include <stdio.h> //sprintf
56
57namespace Assimp {
58namespace D3DS {
59
60#include "./../include/assimp/Compiler/pushpack1.h"
61
62// ---------------------------------------------------------------------------
63/** Discreet3DS class: Helper class for loading 3ds files. Defines chunks
64* and data structures.
65*/
66class Discreet3DS {
67private:
68 Discreet3DS() {
69 // empty
70 }
71
72 ~Discreet3DS() {
73 // empty
74 }
75
76public:
77 //! data structure for a single chunk in a .3ds file
78 struct Chunk {
79 uint16_t Flag;
80 uint32_t Size;
81 } PACK_STRUCT;
82
83
84 //! Used for shading field in material3ds structure
85 //! From AutoDesk 3ds SDK
86 typedef enum
87 {
88 // translated to gouraud shading with wireframe active
89 Wire = 0x0,
90
91 // if this material is set, no vertex normals will
92 // be calculated for the model. Face normals + gouraud
93 Flat = 0x1,
94
95 // standard gouraud shading
96 Gouraud = 0x2,
97
98 // phong shading
99 Phong = 0x3,
100
101 // cooktorrance or anistropic phong shading ...
102 // the exact meaning is unknown, if you know it
103 // feel free to tell me ;-)
104 Metal = 0x4,
105
106 // required by the ASE loader
107 Blinn = 0x5
108 } shadetype3ds;
109
110 // Flags for animated keys
111 enum
112 {
113 KEY_USE_TENS = 0x1,
114 KEY_USE_CONT = 0x2,
115 KEY_USE_BIAS = 0x4,
116 KEY_USE_EASE_TO = 0x8,
117 KEY_USE_EASE_FROM = 0x10
118 } ;
119
120 enum
121 {
122
123 // ********************************************************************
124 // Basic chunks which can be found everywhere in the file
125 CHUNK_VERSION = 0x0002,
126 CHUNK_RGBF = 0x0010, // float4 R; float4 G; float4 B
127 CHUNK_RGBB = 0x0011, // int1 R; int1 G; int B
128
129 // Linear color values (gamma = 2.2?)
130 CHUNK_LINRGBF = 0x0013, // float4 R; float4 G; float4 B
131 CHUNK_LINRGBB = 0x0012, // int1 R; int1 G; int B
132
133 CHUNK_PERCENTW = 0x0030, // int2 percentage
134 CHUNK_PERCENTF = 0x0031, // float4 percentage
135 CHUNK_PERCENTD = 0x0032, // float8 percentage
136 // ********************************************************************
137
138 // Prj master chunk
139 CHUNK_PRJ = 0xC23D,
140
141 // MDLI master chunk
142 CHUNK_MLI = 0x3DAA,
143
144 // Primary main chunk of the .3ds file
145 CHUNK_MAIN = 0x4D4D,
146
147 // Mesh main chunk
148 CHUNK_OBJMESH = 0x3D3D,
149
150 // Specifies the background color of the .3ds file
151 // This is passed through the material system for
152 // viewing purposes.
153 CHUNK_BKGCOLOR = 0x1200,
154
155 // Specifies the ambient base color of the scene.
156 // This is added to all materials in the file
157 CHUNK_AMBCOLOR = 0x2100,
158
159 // Specifies the background image for the whole scene
160 // This value is passed through the material system
161 // to the viewer
162 CHUNK_BIT_MAP = 0x1100,
163 CHUNK_BIT_MAP_EXISTS = 0x1101,
164
165 // ********************************************************************
166 // Viewport related stuff. Ignored
167 CHUNK_DEFAULT_VIEW = 0x3000,
168 CHUNK_VIEW_TOP = 0x3010,
169 CHUNK_VIEW_BOTTOM = 0x3020,
170 CHUNK_VIEW_LEFT = 0x3030,
171 CHUNK_VIEW_RIGHT = 0x3040,
172 CHUNK_VIEW_FRONT = 0x3050,
173 CHUNK_VIEW_BACK = 0x3060,
174 CHUNK_VIEW_USER = 0x3070,
175 CHUNK_VIEW_CAMERA = 0x3080,
176 // ********************************************************************
177
178 // Mesh chunks
179 CHUNK_OBJBLOCK = 0x4000,
180 CHUNK_TRIMESH = 0x4100,
181 CHUNK_VERTLIST = 0x4110,
182 CHUNK_VERTFLAGS = 0x4111,
183 CHUNK_FACELIST = 0x4120,
184 CHUNK_FACEMAT = 0x4130,
185 CHUNK_MAPLIST = 0x4140,
186 CHUNK_SMOOLIST = 0x4150,
187 CHUNK_TRMATRIX = 0x4160,
188 CHUNK_MESHCOLOR = 0x4165,
189 CHUNK_TXTINFO = 0x4170,
190 CHUNK_LIGHT = 0x4600,
191 CHUNK_CAMERA = 0x4700,
192 CHUNK_HIERARCHY = 0x4F00,
193
194 // Specifies the global scaling factor. This is applied
195 // to the root node's transformation matrix
196 CHUNK_MASTER_SCALE = 0x0100,
197
198 // ********************************************************************
199 // Material chunks
200 CHUNK_MAT_MATERIAL = 0xAFFF,
201
202 // asciiz containing the name of the material
203 CHUNK_MAT_MATNAME = 0xA000,
204 CHUNK_MAT_AMBIENT = 0xA010, // followed by color chunk
205 CHUNK_MAT_DIFFUSE = 0xA020, // followed by color chunk
206 CHUNK_MAT_SPECULAR = 0xA030, // followed by color chunk
207
208 // Specifies the shininess of the material
209 // followed by percentage chunk
210 CHUNK_MAT_SHININESS = 0xA040,
211 CHUNK_MAT_SHININESS_PERCENT = 0xA041 ,
212
213 // Specifies the shading mode to be used
214 // followed by a short
215 CHUNK_MAT_SHADING = 0xA100,
216
217 // NOTE: Emissive color (self illumination) seems not
218 // to be a color but a single value, type is unknown.
219 // Make the parser accept both of them.
220 // followed by percentage chunk (?)
221 CHUNK_MAT_SELF_ILLUM = 0xA080,
222
223 // Always followed by percentage chunk (?)
224 CHUNK_MAT_SELF_ILPCT = 0xA084,
225
226 // Always followed by percentage chunk
227 CHUNK_MAT_TRANSPARENCY = 0xA050,
228
229 // Diffuse texture channel 0
230 CHUNK_MAT_TEXTURE = 0xA200,
231
232 // Contains opacity information for each texel
233 CHUNK_MAT_OPACMAP = 0xA210,
234
235 // Contains a reflection map to be used to reflect
236 // the environment. This is partially supported.
237 CHUNK_MAT_REFLMAP = 0xA220,
238
239 // Self Illumination map (emissive colors)
240 CHUNK_MAT_SELFIMAP = 0xA33d,
241
242 // Bumpmap. Not specified whether it is a heightmap
243 // or a normal map. Assme it is a heightmap since
244 // artist normally prefer this format.
245 CHUNK_MAT_BUMPMAP = 0xA230,
246
247 // Specular map. Seems to influence the specular color
248 CHUNK_MAT_SPECMAP = 0xA204,
249
250 // Holds shininess data.
251 CHUNK_MAT_MAT_SHINMAP = 0xA33C,
252
253 // Scaling in U/V direction.
254 // (need to gen separate UV coordinate set
255 // and do this by hand)
256 CHUNK_MAT_MAP_USCALE = 0xA354,
257 CHUNK_MAT_MAP_VSCALE = 0xA356,
258
259 // Translation in U/V direction.
260 // (need to gen separate UV coordinate set
261 // and do this by hand)
262 CHUNK_MAT_MAP_UOFFSET = 0xA358,
263 CHUNK_MAT_MAP_VOFFSET = 0xA35a,
264
265 // UV-coordinates rotation around the z-axis
266 // Assumed to be in radians.
267 CHUNK_MAT_MAP_ANG = 0xA35C,
268
269 // Tiling flags for 3DS files
270 CHUNK_MAT_MAP_TILING = 0xa351,
271
272 // Specifies the file name of a texture
273 CHUNK_MAPFILE = 0xA300,
274
275 // Specifies whether a materail requires two-sided rendering
276 CHUNK_MAT_TWO_SIDE = 0xA081,
277 // ********************************************************************
278
279 // Main keyframer chunk. Contains translation/rotation/scaling data
280 CHUNK_KEYFRAMER = 0xB000,
281
282 // Supported sub chunks
283 CHUNK_TRACKINFO = 0xB002,
284 CHUNK_TRACKOBJNAME = 0xB010,
285 CHUNK_TRACKDUMMYOBJNAME = 0xB011,
286 CHUNK_TRACKPIVOT = 0xB013,
287 CHUNK_TRACKPOS = 0xB020,
288 CHUNK_TRACKROTATE = 0xB021,
289 CHUNK_TRACKSCALE = 0xB022,
290
291 // ********************************************************************
292 // Keyframes for various other stuff in the file
293 // Partially ignored
294 CHUNK_AMBIENTKEY = 0xB001,
295 CHUNK_TRACKMORPH = 0xB026,
296 CHUNK_TRACKHIDE = 0xB029,
297 CHUNK_OBJNUMBER = 0xB030,
298 CHUNK_TRACKCAMERA = 0xB003,
299 CHUNK_TRACKFOV = 0xB023,
300 CHUNK_TRACKROLL = 0xB024,
301 CHUNK_TRACKCAMTGT = 0xB004,
302 CHUNK_TRACKLIGHT = 0xB005,
303 CHUNK_TRACKLIGTGT = 0xB006,
304 CHUNK_TRACKSPOTL = 0xB007,
305 CHUNK_FRAMES = 0xB008,
306 // ********************************************************************
307
308 // light sub-chunks
309 CHUNK_DL_OFF = 0x4620,
310 CHUNK_DL_OUTER_RANGE = 0x465A,
311 CHUNK_DL_INNER_RANGE = 0x4659,
312 CHUNK_DL_MULTIPLIER = 0x465B,
313 CHUNK_DL_EXCLUDE = 0x4654,
314 CHUNK_DL_ATTENUATE = 0x4625,
315 CHUNK_DL_SPOTLIGHT = 0x4610,
316
317 // camera sub-chunks
318 CHUNK_CAM_RANGES = 0x4720
319 };
320};
321
322// ---------------------------------------------------------------------------
323/** Helper structure representing a 3ds mesh face */
324struct Face : public FaceWithSmoothingGroup
325{
326};
327
328// ---------------------------------------------------------------------------
329/** Helper structure representing a texture */
330struct Texture
331{
332 //! Default constructor
333 Texture()
334 : mOffsetU (0.0)
335 , mOffsetV (0.0)
336 , mScaleU (1.0)
337 , mScaleV (1.0)
338 , mRotation (0.0)
339 , mMapMode (aiTextureMapMode_Wrap)
340 , bPrivate()
341 , iUVSrc (0)
342 {
343 mTextureBlend = get_qnan();
344 }
345
346 //! Specifies the blend factor for the texture
347 ai_real mTextureBlend;
348
349 //! Specifies the filename of the texture
350 std::string mMapName;
351
352 //! Specifies texture coordinate offsets/scaling/rotations
353 ai_real mOffsetU;
354 ai_real mOffsetV;
355 ai_real mScaleU;
356 ai_real mScaleV;
357 ai_real mRotation;
358
359 //! Specifies the mapping mode to be used for the texture
360 aiTextureMapMode mMapMode;
361
362 //! Used internally
363 bool bPrivate;
364 int iUVSrc;
365};
366
367#include "./../include/assimp/Compiler/poppack1.h"
368
369// ---------------------------------------------------------------------------
370/** Helper structure representing a 3ds material */
371struct Material
372{
373 //! Default constructor. Builds a default name for the material
374 Material()
375 : mDiffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) // FIX ... we won't want object to be black
376 , mSpecularExponent ( ai_real( 0.0 ) )
377 , mShininessStrength ( ai_real( 1.0 ) )
378 , mShading(Discreet3DS::Gouraud)
379 , mTransparency ( ai_real( 1.0 ) )
380 , mBumpHeight ( ai_real( 1.0 ) )
381 , mTwoSided (false)
382 {
383 static int iCnt = 0;
384
385 char szTemp[128];
386 ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
387 mName = szTemp;
388 }
389
390 //! Name of the material
391 std::string mName;
392 //! Diffuse color of the material
393 aiColor3D mDiffuse;
394 //! Specular exponent
395 ai_real mSpecularExponent;
396 //! Shininess strength, in percent
397 ai_real mShininessStrength;
398 //! Specular color of the material
399 aiColor3D mSpecular;
400 //! Ambient color of the material
401 aiColor3D mAmbient;
402 //! Shading type to be used
403 Discreet3DS::shadetype3ds mShading;
404 //! Opacity of the material
405 ai_real mTransparency;
406 //! Diffuse texture channel
407 Texture sTexDiffuse;
408 //! Opacity texture channel
409 Texture sTexOpacity;
410 //! Specular texture channel
411 Texture sTexSpecular;
412 //! Reflective texture channel
413 Texture sTexReflective;
414 //! Bump texture channel
415 Texture sTexBump;
416 //! Emissive texture channel
417 Texture sTexEmissive;
418 //! Shininess texture channel
419 Texture sTexShininess;
420 //! Scaling factor for the bump values
421 ai_real mBumpHeight;
422 //! Emissive color
423 aiColor3D mEmissive;
424 //! Ambient texture channel
425 //! (used by the ASE format)
426 Texture sTexAmbient;
427 //! True if the material must be rendered from two sides
428 bool mTwoSided;
429};
430
431// ---------------------------------------------------------------------------
432/** Helper structure to represent a 3ds file mesh */
433struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
434{
435 //! Default constructor
436 Mesh()
437 {
438 static int iCnt = 0;
439
440 // Generate a default name for the mesh
441 char szTemp[128];
442 ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
443 mName = szTemp;
444 }
445
446 //! Name of the mesh
447 std::string mName;
448
449 //! Texture coordinates
450 std::vector<aiVector3D> mTexCoords;
451
452 //! Face materials
453 std::vector<unsigned int> mFaceMaterials;
454
455 //! Local transformation matrix
456 aiMatrix4x4 mMat;
457};
458
459// ---------------------------------------------------------------------------
460/** Float key - quite similar to aiVectorKey and aiQuatKey. Both are in the
461 C-API, so it would be difficult to make them a template. */
462struct aiFloatKey
463{
464 double mTime; ///< The time of this key
465 ai_real mValue; ///< The value of this key
466
467#ifdef __cplusplus
468
469 // time is not compared
470 bool operator == (const aiFloatKey& o) const
471 {return o.mValue == this->mValue;}
472
473 bool operator != (const aiFloatKey& o) const
474 {return o.mValue != this->mValue;}
475
476 // Only time is compared. This operator is defined
477 // for use with std::sort
478 bool operator < (const aiFloatKey& o) const
479 {return mTime < o.mTime;}
480
481 bool operator > (const aiFloatKey& o) const
482 {return mTime > o.mTime;}
483
484#endif
485};
486
487// ---------------------------------------------------------------------------
488/** Helper structure to represent a 3ds file node */
489struct Node
490{
491 Node():
492 mParent(NULL)
493 , mInstanceNumber(0)
494 , mHierarchyPos (0)
495 , mHierarchyIndex (0)
496 , mInstanceCount (1)
497 {
498 static int iCnt = 0;
499
500 // Generate a default name for the node
501 char szTemp[128];
502 ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
503 mName = szTemp;
504
505 aRotationKeys.reserve (20);
506 aPositionKeys.reserve (20);
507 aScalingKeys.reserve (20);
508 }
509
510 ~Node()
511 {
512 for (unsigned int i = 0; i < mChildren.size();++i)
513 delete mChildren[i];
514 }
515
516 //! Pointer to the parent node
517 Node* mParent;
518
519 //! Holds all child nodes
520 std::vector<Node*> mChildren;
521
522 //! Name of the node
523 std::string mName;
524
525 //! InstanceNumber of the node
526 int32_t mInstanceNumber;
527
528 //! Dummy nodes: real name to be combined with the $$$DUMMY
529 std::string mDummyName;
530
531 //! Position of the node in the hierarchy (tree depth)
532 int16_t mHierarchyPos;
533
534 //! Index of the node
535 int16_t mHierarchyIndex;
536
537 //! Rotation keys loaded from the file
538 std::vector<aiQuatKey> aRotationKeys;
539
540 //! Position keys loaded from the file
541 std::vector<aiVectorKey> aPositionKeys;
542
543 //! Scaling keys loaded from the file
544 std::vector<aiVectorKey> aScalingKeys;
545
546
547 // For target lights (spot lights and directional lights):
548 // The position of the target
549 std::vector< aiVectorKey > aTargetPositionKeys;
550
551 // For cameras: the camera roll angle
552 std::vector< aiFloatKey > aCameraRollKeys;
553
554 //! Pivot position loaded from the file
555 aiVector3D vPivot;
556
557 //instance count, will be kept only for the first node
558 int32_t mInstanceCount;
559
560 //! Add a child node, setup the right parent node for it
561 //! \param pc Node to be 'adopted'
562 inline Node& push_back(Node* pc)
563 {
564 mChildren.push_back(pc);
565 pc->mParent = this;
566 return *this;
567 }
568};
569// ---------------------------------------------------------------------------
570/** Helper structure analogue to aiScene */
571struct Scene
572{
573 //! List of all materials loaded
574 //! NOTE: 3ds references materials globally
575 std::vector<Material> mMaterials;
576
577 //! List of all meshes loaded
578 std::vector<Mesh> mMeshes;
579
580 //! List of all cameras loaded
581 std::vector<aiCamera*> mCameras;
582
583 //! List of all lights loaded
584 std::vector<aiLight*> mLights;
585
586 //! Pointer to the root node of the scene
587 // --- moved to main class
588 // Node* pcRootNode;
589};
590
591
592} // end of namespace D3DS
593} // end of namespace Assimp
594
595#endif // AI_XFILEHELPER_H_INC
596