3DSHelper.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. /*
  2. Open Asset Import Library (ASSIMP)
  3. ----------------------------------------------------------------------
  4. Copyright (c) 2006-2008, ASSIMP Development Team
  5. All rights reserved.
  6. Redistribution and use of this software in source and binary forms,
  7. with or without modification, are permitted provided that the
  8. following conditions are met:
  9. * Redistributions of source code must retain the above
  10. copyright notice, this list of conditions and the
  11. following disclaimer.
  12. * Redistributions in binary form must reproduce the above
  13. copyright notice, this list of conditions and the
  14. following disclaimer in the documentation and/or other
  15. materials provided with the distribution.
  16. * Neither the name of the ASSIMP team, nor the names of its
  17. contributors may be used to endorse or promote products
  18. derived from this software without specific prior
  19. written permission of the ASSIMP Development Team.
  20. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. ----------------------------------------------------------------------
  32. */
  33. /** @file Defines the helper data structures for importing XFiles */
  34. #ifndef AI_3DSFILEHELPER_H_INC
  35. #define AI_3DSFILEHELPER_H_INC
  36. #include <string>
  37. #include <vector>
  38. #include <sstream>
  39. #include "../include/aiTypes.h"
  40. #include "../include/aiQuaternion.h"
  41. #include "../include/aiMesh.h"
  42. #include "../include/aiAnim.h"
  43. #include "SpatialSort.h"
  44. namespace Assimp
  45. {
  46. namespace Dot3DS
  47. {
  48. #if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
  49. # pragma pack(push,2)
  50. # define PACK_STRUCT
  51. #elif defined( __GNUC__ )
  52. # define PACK_STRUCT __attribute__((packed))
  53. #else
  54. # error Compiler not supported
  55. #endif
  56. // ---------------------------------------------------------------------------
  57. /** Dot3DSFile class: Helper class for loading 3ds files. Defines chunks
  58. * and data structures.
  59. */
  60. class Dot3DSFile
  61. {
  62. public:
  63. inline Dot3DSFile() {}
  64. //! data structure for a single chunk in a .3ds file
  65. struct Chunk
  66. {
  67. unsigned short Flag;
  68. long Size;
  69. } PACK_STRUCT;
  70. //! source for this used own structures,
  71. //! replaced it with out standard math helpers
  72. typedef aiMatrix3x3 MatTransform;
  73. typedef aiVector3D MatTranslate;
  74. //! Used for shading field in material3ds structure
  75. //! From AutoDesk 3ds SDK
  76. typedef enum
  77. {
  78. Wire = 0,
  79. Flat = 1,
  80. Gouraud = 2,
  81. Phong = 3,
  82. Metal = 4,
  83. // required by the ASE loader
  84. Blinn = 5
  85. } shadetype3ds;
  86. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  87. // enum for all chunks in 3ds files. Unused
  88. // ones are commented, list is not complete since
  89. // there are many undocumented chunks.
  90. //
  91. // Links: http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt
  92. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  93. enum
  94. {
  95. // **************************************************************
  96. // Base chunks which can be found everywhere in the file
  97. CHUNK_VERSION = 0x0002,
  98. CHUNK_RGBF = 0x0010, // float4 R; float4 G; float4 B
  99. CHUNK_RGBB = 0x0011, // int1 R; int1 G; int B
  100. // Linear color values (gamma = 2.2?)
  101. CHUNK_LINRGBF = 0x0013, // float4 R; float4 G; float4 B
  102. CHUNK_LINRGBB = 0x0012, // int1 R; int1 G; int B
  103. CHUNK_PERCENTW = 0x0030, // int2 percentage
  104. CHUNK_PERCENTF = 0x0031, // float4 percentage
  105. // **************************************************************
  106. // Unknown and ignored
  107. CHUNK_PRJ = 0xC23D,
  108. // Unknown. Possibly a reference to an external .mli file?
  109. CHUNK_MLI = 0x3DAA,
  110. // Primary main chunk of the .3ds file
  111. CHUNK_MAIN = 0x4D4D,
  112. // Mesh main chunk
  113. CHUNK_OBJMESH = 0x3D3D,
  114. // Specifies the background color of the .3ds file
  115. // This is passed through the material system for
  116. // viewing purposes.
  117. CHUNK_BKGCOLOR = 0x1200,
  118. // Specifies the ambient base color of the scene.
  119. // This is added to all materials in the file
  120. CHUNK_AMBCOLOR = 0x2100,
  121. // Specifies the background image for the whole scene
  122. // This value is passed through the material system
  123. // to the viewer
  124. CHUNK_BIT_MAP = 0x1100,
  125. CHUNK_BIT_MAP_EXISTS = 0x1101,
  126. // **************************************************************
  127. // Viewport related stuff. Ignored
  128. CHUNK_DEFAULT_VIEW = 0x3000,
  129. CHUNK_VIEW_TOP = 0x3010,
  130. CHUNK_VIEW_BOTTOM = 0x3020,
  131. CHUNK_VIEW_LEFT = 0x3030,
  132. CHUNK_VIEW_RIGHT = 0x3040,
  133. CHUNK_VIEW_FRONT = 0x3050,
  134. CHUNK_VIEW_BACK = 0x3060,
  135. CHUNK_VIEW_USER = 0x3070,
  136. CHUNK_VIEW_CAMERA = 0x3080,
  137. // **************************************************************
  138. // Mesh chunks
  139. CHUNK_OBJBLOCK = 0x4000,
  140. CHUNK_TRIMESH = 0x4100,
  141. CHUNK_VERTLIST = 0x4110,
  142. CHUNK_VERTFLAGS = 0x4111,
  143. CHUNK_FACELIST = 0x4120,
  144. CHUNK_FACEMAT = 0x4130,
  145. CHUNK_MAPLIST = 0x4140,
  146. CHUNK_SMOOLIST = 0x4150,
  147. CHUNK_TRMATRIX = 0x4160,
  148. CHUNK_MESHCOLOR = 0x4165,
  149. CHUNK_TXTINFO = 0x4170,
  150. CHUNK_LIGHT = 0x4600,
  151. CHUNK_SPOTLIGHT = 0x4610,
  152. CHUNK_CAMERA = 0x4700,
  153. CHUNK_HIERARCHY = 0x4F00,
  154. // Specifies the global scaling factor. This is applied
  155. // to the root node's transformation matrix
  156. CHUNK_MASTER_SCALE = 0x0100,
  157. // **************************************************************
  158. // Material chunks
  159. CHUNK_MAT_MATERIAL = 0xAFFF,
  160. // asciiz containing the name of the material
  161. CHUNK_MAT_MATNAME = 0xA000,
  162. CHUNK_MAT_AMBIENT = 0xA010, // followed by color chunk
  163. CHUNK_MAT_DIFFUSE = 0xA020, // followed by color chunk
  164. CHUNK_MAT_SPECULAR = 0xA030, // followed by color chunk
  165. // Specifies the shininess of the material
  166. // followed by percentage chunk
  167. CHUNK_MAT_SHININESS = 0xA040,
  168. CHUNK_MAT_SHININESS_PERCENT = 0xA041 ,
  169. // Specifies the shading mode to be used
  170. // followed by a short
  171. CHUNK_MAT_SHADING = 0xA100,
  172. // NOTE: Emissive color (self illumination) seems not
  173. // to be a color but a single value, type is unknown.
  174. // Make the parser accept both of them.
  175. // followed by percentage chunk (?)
  176. CHUNK_MAT_SELF_ILLUM = 0xA080,
  177. // Always followed by percentage chunk (?)
  178. CHUNK_MAT_SELF_ILPCT = 0xA084,
  179. // Always followed by percentage chunk
  180. CHUNK_MAT_TRANSPARENCY = 0xA050,
  181. // Diffuse texture channel 0
  182. CHUNK_MAT_TEXTURE = 0xA200,
  183. // Contains opacity information for each texel
  184. CHUNK_MAT_OPACMAP = 0xA210,
  185. // Contains a reflection map to be used to reflect
  186. // the environment. This is partially supported.
  187. CHUNK_MAT_REFLMAP = 0xA220,
  188. // Self Illumination map (emissive colors)
  189. CHUNK_MAT_SELFIMAP = 0xA33d,
  190. // Bumpmap. Not specified whether it is a heightmap
  191. // or a normal map. Assme it is a heightmap since
  192. // artist normally prefer this format.
  193. CHUNK_MAT_BUMPMAP = 0xA230,
  194. // Specular map. Seems to influence the specular color
  195. CHUNK_MAT_SPECMAP = 0xA204,
  196. // Holds shininess data. I assume the specular exponent is
  197. // calculated like this:
  198. //
  199. // s[x,y] = stex[x,y] * base_shininess;
  200. // I also assume the data in the texture must be renormalized
  201. // (normally by dividing / 255) after loading.
  202. CHUNK_MAT_MAT_SHINMAP = 0xA33C,
  203. // Scaling in U/V direction.
  204. // (need to gen separate UV coordinate set
  205. // and do this by hand)
  206. CHUNK_MAT_MAP_USCALE = 0xA354,
  207. CHUNK_MAT_MAP_VSCALE = 0xA356,
  208. // Translation in U/V direction.
  209. // (need to gen separate UV coordinate set
  210. // and do this by hand)
  211. CHUNK_MAT_MAP_UOFFSET = 0xA358,
  212. CHUNK_MAT_MAP_VOFFSET = 0xA35a,
  213. // UV-coordinates rotation around the z-axis
  214. // Assumed to be in radians.
  215. CHUNK_MAT_MAP_ANG = 0xA35C,
  216. // Specifies the file name of a texture
  217. CHUNK_MAPFILE = 0xA300,
  218. // **************************************************************
  219. // Main keyframer chunk. Contains translation/rotation/scaling data
  220. CHUNK_KEYFRAMER = 0xB000,
  221. // Supported sub chunks
  222. CHUNK_TRACKINFO = 0xB002,
  223. CHUNK_TRACKOBJNAME = 0xB010,
  224. CHUNK_TRACKPIVOT = 0xB013,
  225. CHUNK_TRACKPOS = 0xB020,
  226. CHUNK_TRACKROTATE = 0xB021,
  227. CHUNK_TRACKSCALE = 0xB022,
  228. // **************************************************************
  229. // Keyframes for various other stuff in the file
  230. // Ignored
  231. CHUNK_AMBIENTKEY = 0xB001,
  232. CHUNK_TRACKMORPH = 0xB026,
  233. CHUNK_TRACKHIDE = 0xB029,
  234. CHUNK_OBJNUMBER = 0xB030,
  235. CHUNK_TRACKCAMERA = 0xB003,
  236. CHUNK_TRACKFOV = 0xB023,
  237. CHUNK_TRACKROLL = 0xB024,
  238. CHUNK_TRACKCAMTGT = 0xB004,
  239. CHUNK_TRACKLIGHT = 0xB005,
  240. CHUNK_TRACKLIGTGT = 0xB006,
  241. CHUNK_TRACKSPOTL = 0xB007,
  242. CHUNK_FRAMES = 0xB008
  243. // **************************************************************
  244. };
  245. };
  246. #if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
  247. # pragma pack( pop )
  248. #endif
  249. #undef PACK_STRUCT
  250. // ---------------------------------------------------------------------------
  251. /** Helper structure representing a 3ds mesh face */
  252. struct Face
  253. {
  254. Face() : iSmoothGroup(0), bFlipped(false)
  255. {
  256. // let the rest uninitialized for performance
  257. this->mIndices[0] = 0;
  258. this->mIndices[1] = 0;
  259. this->mIndices[2] = 0;
  260. }
  261. //! Indices. .3ds is using uint16. However, after
  262. //! an unique vrtex set has been geneerated it might
  263. //! be an index becomes > 2^16
  264. uint32_t mIndices[3];
  265. //! specifies to which smoothing group the face belongs to
  266. uint32_t iSmoothGroup;
  267. //! Specifies that the face normal must be flipped
  268. bool bFlipped;
  269. };
  270. // ---------------------------------------------------------------------------
  271. /** Helper structure representing a texture */
  272. struct Texture
  273. {
  274. //! Default constructor
  275. Texture()
  276. :
  277. mScaleU(1.0f),
  278. mScaleV(1.0f),
  279. mOffsetU(0.0f),
  280. mOffsetV(0.0f),
  281. mRotation(0.0f),
  282. iUVSrc(0)
  283. {
  284. mTextureBlend = std::numeric_limits<float>::quiet_NaN();
  285. }
  286. //! Specifies the blending factor for the texture
  287. float mTextureBlend;
  288. //! Specifies the filename of the texture
  289. std::string mMapName;
  290. //! Specifies texture coordinate offsets/scaling/rotations
  291. float mScaleU;
  292. float mScaleV;
  293. float mOffsetU;
  294. float mOffsetV;
  295. float mRotation;
  296. //! Used internally
  297. bool bPrivate;
  298. int iUVSrc;
  299. };
  300. // ---------------------------------------------------------------------------
  301. /** Helper structure representing a 3ds material */
  302. struct Material
  303. {
  304. //! Default constructor. Builds a default name for the material
  305. Material()
  306. :
  307. mSpecularExponent (0.0f),
  308. mShading(Dot3DSFile::Gouraud),
  309. mTransparency (1.0f),
  310. mBumpHeight (1.0f),
  311. iBakeUVTransform (0),
  312. pcSingleTexture (NULL),
  313. mShininessStrength (1.0f)
  314. {
  315. static int iCnt = 0;
  316. std::stringstream ss(mName);
  317. ss << "$$_UNNAMED_" << iCnt++ << "_$$";
  318. }
  319. //! Name of the material
  320. std::string mName;
  321. //! Diffuse color of the material
  322. aiColor3D mDiffuse;
  323. //! Specular exponent
  324. float mSpecularExponent;
  325. //! Shininess strength, in percent
  326. float mShininessStrength;
  327. //! Specular color of the material
  328. aiColor3D mSpecular;
  329. //! Ambient color of the material
  330. aiColor3D mAmbient;
  331. //! Shading type to be used
  332. Dot3DSFile::shadetype3ds mShading;
  333. //! Opacity of the material
  334. float mTransparency;
  335. //! Diffuse texture channel
  336. Texture sTexDiffuse;
  337. //! Opacity texture channel
  338. Texture sTexOpacity;
  339. //! Specular texture channel
  340. Texture sTexSpecular;
  341. //! Bump texture channel
  342. Texture sTexBump;
  343. //! Emissive texture channel
  344. Texture sTexEmissive;
  345. //! Shininess texture channel
  346. Texture sTexShininess;
  347. /*
  348. float mReflectionTextureBlend;
  349. std::string mReflectionTexture;
  350. */
  351. float mBumpHeight;
  352. //! Emissive color
  353. aiColor3D mEmissive;
  354. //! Used internally
  355. unsigned int iBakeUVTransform;
  356. Texture* pcSingleTexture;
  357. };
  358. // ---------------------------------------------------------------------------
  359. /** Helper structure to represent a 3ds file mesh */
  360. struct Mesh
  361. {
  362. //! Default constructor
  363. Mesh()
  364. {
  365. static int iCnt = 0;
  366. std::stringstream ss(mName);
  367. ss << "$$_UNNAMED_" << iCnt++ << "_$$";
  368. }
  369. //! Name of the mesh
  370. std::string mName;
  371. //! Vertex positions
  372. std::vector<aiVector3D> mPositions;
  373. //! Face lists
  374. std::vector<Face> mFaces;
  375. //! Texture coordinates
  376. std::vector<aiVector2D> mTexCoords;
  377. //! Face materials
  378. std::vector<unsigned int> mFaceMaterials;
  379. //! Normal vectors
  380. std::vector<aiVector3D> mNormals;
  381. //! Local transformation matrix
  382. aiMatrix4x4 mMat;
  383. };
  384. // ---------------------------------------------------------------------------
  385. /** Helper structure to represent a 3ds file node */
  386. struct Node
  387. {
  388. Node()
  389. // (code for keyframe animation. however, this is currently not supported by Assimp)
  390. #if 0
  391. : vScaling(1.0f,1.0f,1.0f)
  392. #endif
  393. {
  394. static int iCnt = 0;
  395. std::stringstream ss(mName);
  396. ss << "$$_UNNAMED_" << iCnt++ << "_$$";
  397. mHierarchyPos = 0;
  398. mHierarchyIndex = 0;
  399. }
  400. //! Pointer to the parent node
  401. Node* mParent;
  402. //! Holds all child nodes
  403. std::vector<Node*> mChildren;
  404. //! Name of the node
  405. std::string mName;
  406. //! Position of the node in the hierarchy (tree depth)
  407. int16_t mHierarchyPos;
  408. //! Index of the node
  409. int16_t mHierarchyIndex;
  410. // (code for keyframe animation. however, this is currently not supported by Assimp)
  411. #if 0
  412. aiVector3D vPivot;
  413. aiVector3D vScaling;
  414. aiMatrix4x4 mRotation;
  415. aiVector3D vPosition;
  416. #endif
  417. //! Add a child node, setup the right parent node for it
  418. //! \param pc Node to be 'adopted'
  419. inline Node& push_back(Node* pc)
  420. {
  421. mChildren.push_back(pc);
  422. pc->mParent = this;
  423. //pc->mHierarchyPos = this->mHierarchyPos+1;
  424. return *this;
  425. }
  426. };
  427. // ---------------------------------------------------------------------------
  428. /** Helper structure analogue to aiScene */
  429. struct Scene
  430. {
  431. //! List of all materials loaded
  432. //! NOTE: 3ds references materials globally
  433. std::vector<Material> mMaterials;
  434. //! List of all meshes loaded
  435. std::vector<Mesh> mMeshes;
  436. //! Pointer to the root node of the scene
  437. Node* pcRootNode;
  438. };
  439. // ---------------------------------------------------------------------------
  440. inline bool is_qnan(float p_fIn)
  441. {
  442. // NOTE: Comparison against qnan is generally problematic
  443. // because qnan == qnan is false AFAIK
  444. union FTOINT
  445. {
  446. float fFloat;
  447. int32_t iInt;
  448. } one, two;
  449. one.fFloat = std::numeric_limits<float>::quiet_NaN();
  450. two.fFloat = p_fIn;
  451. return (one.iInt == two.iInt);
  452. }
  453. // ---------------------------------------------------------------------------
  454. inline bool is_not_qnan(float p_fIn)
  455. {
  456. return !is_qnan(p_fIn);
  457. }
  458. } // end of namespace Dot3DS
  459. } // end of namespace Assimp
  460. #endif // AI_XFILEHELPER_H_INC