Coverage Report

Created: 2025-06-22 07:30

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