Coverage Report

Created: 2024-08-02 07:04

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