3DSHelper.h 12 KB

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