1 
2 /*
3 Open Asset Import Library (assimp)
4 ----------------------------------------------------------------------
5 
6 Copyright (c) 2006-2021, assimp team
7 
8 
9 All rights reserved.
10 
11 Redistribution and use of this software in source and binary forms,
12 with or without modification, are permitted provided that the
13 following conditions are met:
14 
15 * Redistributions of source code must retain the above
16   copyright notice, this list of conditions and the
17   following disclaimer.
18 
19 * Redistributions in binary form must reproduce the above
20   copyright notice, this list of conditions and the
21   following disclaimer in the documentation and/or other
22   materials provided with the distribution.
23 
24 * Neither the name of the assimp team, nor the names of its
25   contributors may be used to endorse or promote products
26   derived from this software without specific prior
27   written permission of the assimp team.
28 
29 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 
41 ----------------------------------------------------------------------
42 */
43 
44 /** @file  3DSLoader.h
45  *  @brief 3DS File format loader
46  */
47 #ifndef AI_3DSIMPORTER_H_INC
48 #define AI_3DSIMPORTER_H_INC
49 #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
50 
51 #include <assimp/BaseImporter.h>
52 #include <assimp/types.h>
53 
54 
55 #include "3DSHelper.h"
56 #include <assimp/StreamReader.h>
57 
58 struct aiNode;
59 
60 namespace Assimp    {
61 
62 
63 using namespace D3DS;
64 
65 // ---------------------------------------------------------------------------------
66 /** Importer class for 3D Studio r3 and r4 3DS files
67  */
68 class Discreet3DSImporter : public BaseImporter {
69 public:
70     Discreet3DSImporter();
71     ~Discreet3DSImporter();
72 
73     // -------------------------------------------------------------------
74     /** Returns whether the class can handle the format of the given file.
75      * See BaseImporter::CanRead() for details.
76      */
77     bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
78         bool checkSig) const override;
79 
80     // -------------------------------------------------------------------
81     /** Called prior to ReadFile().
82      * The function is a request to the importer to update its configuration
83      * basing on the Importer's configuration property list.
84      */
85     void SetupProperties(const Importer* pImp) override;
86 
87 protected:
88 
89     // -------------------------------------------------------------------
90     /** Return importer meta information.
91      * See #BaseImporter::GetInfo for the details
92      */
93     const aiImporterDesc* GetInfo () const override;
94 
95     // -------------------------------------------------------------------
96     /** Imports the given file into the given scene structure.
97      * See BaseImporter::InternReadFile() for details
98      */
99     void InternReadFile( const std::string& pFile, aiScene* pScene,
100         IOSystem* pIOHandler) override;
101 
102     // -------------------------------------------------------------------
103     /** Converts a temporary material to the outer representation
104      */
105     void ConvertMaterial(D3DS::Material& p_cMat,
106         aiMaterial& p_pcOut);
107 
108     // -------------------------------------------------------------------
109     /** Read a chunk
110      *
111      *  @param pcOut Receives the current chunk
112      */
113     void ReadChunk(Discreet3DS::Chunk* pcOut);
114 
115     // -------------------------------------------------------------------
116     /** Parse a percentage chunk. mCurrent will point to the next
117     * chunk behind afterwards. If no percentage chunk is found
118     * QNAN is returned.
119     */
120     ai_real ParsePercentageChunk();
121 
122     // -------------------------------------------------------------------
123     /** Parse a color chunk. mCurrent will point to the next
124     * chunk behind afterwards. If no color chunk is found
125     * QNAN is returned in all members.
126     */
127     void ParseColorChunk(aiColor3D* p_pcOut,
128         bool p_bAcceptPercent = true);
129 
130 
131     // -------------------------------------------------------------------
132     /** Skip a chunk in the file
133     */
134     void SkipChunk();
135 
136     // -------------------------------------------------------------------
137     /** Generate the nodegraph
138     */
139     void GenerateNodeGraph(aiScene* pcOut);
140 
141     // -------------------------------------------------------------------
142     /** Parse a main top-level chunk in the file
143     */
144     void ParseMainChunk();
145 
146     // -------------------------------------------------------------------
147     /** Parse a top-level chunk in the file
148     */
149     void ParseChunk(const char* name, unsigned int num);
150 
151     // -------------------------------------------------------------------
152     /** Parse a top-level editor chunk in the file
153     */
154     void ParseEditorChunk();
155 
156     // -------------------------------------------------------------------
157     /** Parse a top-level object chunk in the file
158     */
159     void ParseObjectChunk();
160 
161     // -------------------------------------------------------------------
162     /** Parse a material chunk in the file
163     */
164     void ParseMaterialChunk();
165 
166     // -------------------------------------------------------------------
167     /** Parse a mesh chunk in the file
168     */
169     void ParseMeshChunk();
170 
171     // -------------------------------------------------------------------
172     /** Parse a light chunk in the file
173     */
174     void ParseLightChunk();
175 
176     // -------------------------------------------------------------------
177     /** Parse a camera chunk in the file
178     */
179     void ParseCameraChunk();
180 
181     // -------------------------------------------------------------------
182     /** Parse a face list chunk in the file
183     */
184     void ParseFaceChunk();
185 
186     // -------------------------------------------------------------------
187     /** Parse a keyframe chunk in the file
188     */
189     void ParseKeyframeChunk();
190 
191     // -------------------------------------------------------------------
192     /** Parse a hierarchy chunk in the file
193     */
194     void ParseHierarchyChunk(uint16_t parent);
195 
196     // -------------------------------------------------------------------
197     /** Parse a texture chunk in the file
198     */
199     void ParseTextureChunk(D3DS::Texture* pcOut);
200 
201     // -------------------------------------------------------------------
202     /** Convert the meshes in the file
203     */
204     void ConvertMeshes(aiScene* pcOut);
205 
206     // -------------------------------------------------------------------
207     /** Replace the default material in the scene
208     */
209     void ReplaceDefaultMaterial();
210 
ContainsTextures(unsigned int i)211     bool ContainsTextures(unsigned int i) const {
212         return !mScene->mMaterials[i].sTexDiffuse.mMapName.empty() ||
213                !mScene->mMaterials[i].sTexBump.mMapName.empty() ||
214                !mScene->mMaterials[i].sTexOpacity.mMapName.empty() ||
215                !mScene->mMaterials[i].sTexEmissive.mMapName.empty() ||
216                !mScene->mMaterials[i].sTexSpecular.mMapName.empty() ||
217                !mScene->mMaterials[i].sTexShininess.mMapName.empty() ;
218     }
219 
220     // -------------------------------------------------------------------
221     /** Convert the whole scene
222     */
223     void ConvertScene(aiScene* pcOut);
224 
225     // -------------------------------------------------------------------
226     /** generate unique vertices for a mesh
227     */
228     void MakeUnique(D3DS::Mesh& sMesh);
229 
230     // -------------------------------------------------------------------
231     /** Add a node to the node graph
232     */
233     void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
234         aiMatrix4x4& absTrafo);
235 
236     // -------------------------------------------------------------------
237     /** Search for a node in the graph.
238     * Called recursively
239     */
240     void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent);
241 
242     // -------------------------------------------------------------------
243     /** Apply the master scaling factor to the mesh
244     */
245     void ApplyMasterScale(aiScene* pScene);
246 
247     // -------------------------------------------------------------------
248     /** Clamp all indices in the file to a valid range
249     */
250     void CheckIndices(D3DS::Mesh& sMesh);
251 
252     // -------------------------------------------------------------------
253     /** Skip the TCB info in a track key
254     */
255     void SkipTCBInfo();
256 
257 protected:
258 
259     /** Stream to read from */
260     StreamReaderLE* stream;
261 
262     /** Last touched node index */
263     short mLastNodeIndex;
264 
265     /** Current node, root node */
266     D3DS::Node* mCurrentNode, *mRootNode;
267 
268     /** Scene under construction */
269     D3DS::Scene* mScene;
270 
271     /** Ambient base color of the scene */
272     aiColor3D mClrAmbient;
273 
274     /** Master scaling factor of the scene */
275     ai_real mMasterScale;
276 
277     /** Path to the background image of the scene */
278     std::string mBackgroundImage;
279     bool bHasBG;
280 
281     /** true if PRJ file */
282     bool bIsPrj;
283 };
284 
285 } // end of namespace Assimp
286 
287 #endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
288 
289 #endif // AI_3DSIMPORTER_H_INC
290