FBXDocument.h 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322
  1. /**************************************************************************/
  2. /* FBXDocument.h */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. /** @file FBXDocument.h
  31. * @brief FBX DOM
  32. */
  33. #ifndef FBXDOCUMENT_H
  34. #define FBXDOCUMENT_H
  35. #include "FBXCommon.h"
  36. #include "FBXParser.h"
  37. #include "FBXProperties.h"
  38. #include "core/math/transform.h"
  39. #include "core/math/vector2.h"
  40. #include "core/math/vector3.h"
  41. #include "core/print_string.h"
  42. #include <stdint.h>
  43. #include <numeric>
  44. #define _AI_CONCAT(a, b) a##b
  45. #define AI_CONCAT(a, b) _AI_CONCAT(a, b)
  46. namespace FBXDocParser {
  47. class Parser;
  48. class Object;
  49. struct ImportSettings;
  50. class Connection;
  51. class PropertyTable;
  52. class Document;
  53. class Material;
  54. class ShapeGeometry;
  55. class LineGeometry;
  56. class Geometry;
  57. class Video;
  58. class AnimationCurve;
  59. class AnimationCurveNode;
  60. class AnimationLayer;
  61. class AnimationStack;
  62. class BlendShapeChannel;
  63. class BlendShape;
  64. class Skin;
  65. class Cluster;
  66. typedef Object *ObjectPtr;
  67. #define new_Object new Object
  68. /** Represents a delay-parsed FBX objects. Many objects in the scene
  69. * are not needed by assimp, so it makes no sense to parse them
  70. * upfront. */
  71. class LazyObject {
  72. public:
  73. LazyObject(uint64_t id, const ElementPtr element, const Document &doc);
  74. ~LazyObject();
  75. ObjectPtr LoadObject();
  76. /* Casting weak pointers to their templated type safely and preserving ref counting and safety
  77. * with lock() keyword to prevent leaking memory
  78. */
  79. template <typename T>
  80. const T *Get() {
  81. ObjectPtr ob = LoadObject();
  82. return dynamic_cast<const T *>(ob);
  83. }
  84. uint64_t ID() const {
  85. return id;
  86. }
  87. bool IsBeingConstructed() const {
  88. return (flags & BEING_CONSTRUCTED) != 0;
  89. }
  90. bool FailedToConstruct() const {
  91. return (flags & FAILED_TO_CONSTRUCT) != 0;
  92. }
  93. ElementPtr GetElement() const {
  94. return element;
  95. }
  96. const Document &GetDocument() const {
  97. return doc;
  98. }
  99. private:
  100. const Document &doc;
  101. ElementPtr element = nullptr;
  102. std::shared_ptr<Object> object = nullptr;
  103. const uint64_t id = 0;
  104. enum Flags {
  105. BEING_CONSTRUCTED = 0x1,
  106. FAILED_TO_CONSTRUCT = 0x2
  107. };
  108. unsigned int flags = 0;
  109. };
  110. /** Base class for in-memory (DOM) representations of FBX objects */
  111. class Object {
  112. public:
  113. Object(uint64_t id, const ElementPtr element, const std::string &name);
  114. virtual ~Object();
  115. ElementPtr SourceElement() const {
  116. return element;
  117. }
  118. const std::string &Name() const {
  119. return name;
  120. }
  121. uint64_t ID() const {
  122. return id;
  123. }
  124. protected:
  125. const ElementPtr element;
  126. const std::string name;
  127. const uint64_t id = 0;
  128. };
  129. /** DOM class for generic FBX NoteAttribute blocks. NoteAttribute's just hold a property table,
  130. * fixed members are added by deriving classes. */
  131. class NodeAttribute : public Object {
  132. public:
  133. NodeAttribute(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  134. virtual ~NodeAttribute();
  135. const PropertyTable *Props() const {
  136. return props;
  137. }
  138. private:
  139. const PropertyTable *props;
  140. };
  141. /** DOM base class for FBX camera settings attached to a node */
  142. class CameraSwitcher : public NodeAttribute {
  143. public:
  144. CameraSwitcher(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  145. virtual ~CameraSwitcher();
  146. int CameraID() const {
  147. return cameraId;
  148. }
  149. const std::string &CameraName() const {
  150. return cameraName;
  151. }
  152. const std::string &CameraIndexName() const {
  153. return cameraIndexName;
  154. }
  155. private:
  156. int cameraId;
  157. std::string cameraName;
  158. std::string cameraIndexName;
  159. };
  160. #define fbx_stringize(a) #a
  161. #define fbx_simple_property(name, type, default_value) \
  162. type name() const { \
  163. return PropertyGet<type>(Props(), fbx_stringize(name), (default_value)); \
  164. }
  165. // XXX improve logging
  166. #define fbx_simple_enum_property(name, type, default_value) \
  167. type name() const { \
  168. const int ival = PropertyGet<int>(Props(), fbx_stringize(name), static_cast<int>(default_value)); \
  169. if (ival < 0 || ival >= AI_CONCAT(type, _MAX)) { \
  170. return static_cast<type>(default_value); \
  171. } \
  172. return static_cast<type>(ival); \
  173. }
  174. class FbxPoseNode;
  175. class FbxPose : public Object {
  176. public:
  177. FbxPose(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  178. const std::vector<FbxPoseNode *> &GetBindPoses() const {
  179. return pose_nodes;
  180. }
  181. virtual ~FbxPose();
  182. private:
  183. std::vector<FbxPoseNode *> pose_nodes;
  184. };
  185. class FbxPoseNode {
  186. public:
  187. FbxPoseNode(const ElementPtr element, const Document &doc, const std::string &name) {
  188. const ScopePtr sc = GetRequiredScope(element);
  189. // get pose node transform
  190. const ElementPtr Transform = GetRequiredElement(sc, "Matrix", element);
  191. transform = ReadMatrix(Transform);
  192. // get node id this pose node is for
  193. const ElementPtr NodeId = sc->GetElement("Node");
  194. if (NodeId) {
  195. target_id = ParseTokenAsInt64(GetRequiredToken(NodeId, 0));
  196. }
  197. print_verbose("added posenode " + itos(target_id) + " transform: " + transform);
  198. }
  199. virtual ~FbxPoseNode() {
  200. }
  201. uint64_t GetNodeID() const {
  202. return target_id;
  203. }
  204. Transform GetBindPose() const {
  205. return transform;
  206. }
  207. private:
  208. uint64_t target_id;
  209. Transform transform;
  210. };
  211. /** DOM base class for FBX cameras attached to a node */
  212. class Camera : public NodeAttribute {
  213. public:
  214. Camera(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  215. virtual ~Camera();
  216. fbx_simple_property(Position, Vector3, Vector3(0, 0, 0));
  217. fbx_simple_property(UpVector, Vector3, Vector3(0, 1, 0));
  218. fbx_simple_property(InterestPosition, Vector3, Vector3(0, 0, 0));
  219. fbx_simple_property(AspectWidth, float, 1.0f);
  220. fbx_simple_property(AspectHeight, float, 1.0f);
  221. fbx_simple_property(FilmWidth, float, 1.0f);
  222. fbx_simple_property(FilmHeight, float, 1.0f);
  223. fbx_simple_property(NearPlane, float, 0.1f);
  224. fbx_simple_property(FarPlane, float, 100.0f);
  225. fbx_simple_property(FilmAspectRatio, float, 1.0f);
  226. fbx_simple_property(ApertureMode, int, 0);
  227. fbx_simple_property(FieldOfView, float, 1.0f);
  228. fbx_simple_property(FocalLength, float, 1.0f);
  229. };
  230. /** DOM base class for FBX null markers attached to a node */
  231. class Null : public NodeAttribute {
  232. public:
  233. Null(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  234. virtual ~Null();
  235. };
  236. /** DOM base class for FBX limb node markers attached to a node */
  237. class LimbNode : public NodeAttribute {
  238. public:
  239. LimbNode(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  240. virtual ~LimbNode();
  241. };
  242. /** DOM base class for FBX lights attached to a node */
  243. class Light : public NodeAttribute {
  244. public:
  245. Light(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  246. virtual ~Light();
  247. enum Type {
  248. Type_Point,
  249. Type_Directional,
  250. Type_Spot,
  251. Type_Area,
  252. Type_Volume,
  253. Type_MAX // end-of-enum sentinel
  254. };
  255. enum Decay {
  256. Decay_None,
  257. Decay_Linear,
  258. Decay_Quadratic,
  259. Decay_Cubic,
  260. Decay_MAX // end-of-enum sentinel
  261. };
  262. fbx_simple_property(Color, Vector3, Vector3(1, 1, 1));
  263. fbx_simple_enum_property(LightType, Type, 0);
  264. fbx_simple_property(CastLightOnObject, bool, false);
  265. fbx_simple_property(DrawVolumetricLight, bool, true);
  266. fbx_simple_property(DrawGroundProjection, bool, true);
  267. fbx_simple_property(DrawFrontFacingVolumetricLight, bool, false);
  268. fbx_simple_property(Intensity, float, 100.0f);
  269. fbx_simple_property(InnerAngle, float, 0.0f);
  270. fbx_simple_property(OuterAngle, float, 45.0f);
  271. fbx_simple_property(Fog, int, 50);
  272. fbx_simple_enum_property(DecayType, Decay, 2);
  273. fbx_simple_property(DecayStart, float, 1.0f);
  274. fbx_simple_property(FileName, std::string, "");
  275. fbx_simple_property(EnableNearAttenuation, bool, false);
  276. fbx_simple_property(NearAttenuationStart, float, 0.0f);
  277. fbx_simple_property(NearAttenuationEnd, float, 0.0f);
  278. fbx_simple_property(EnableFarAttenuation, bool, false);
  279. fbx_simple_property(FarAttenuationStart, float, 0.0f);
  280. fbx_simple_property(FarAttenuationEnd, float, 0.0f);
  281. fbx_simple_property(CastShadows, bool, true);
  282. fbx_simple_property(ShadowColor, Vector3, Vector3(0, 0, 0));
  283. fbx_simple_property(AreaLightShape, int, 0);
  284. fbx_simple_property(LeftBarnDoor, float, 20.0f);
  285. fbx_simple_property(RightBarnDoor, float, 20.0f);
  286. fbx_simple_property(TopBarnDoor, float, 20.0f);
  287. fbx_simple_property(BottomBarnDoor, float, 20.0f);
  288. fbx_simple_property(EnableBarnDoor, bool, true);
  289. };
  290. class Model;
  291. typedef Model *ModelPtr;
  292. #define new_Model new Model
  293. /** DOM base class for FBX models (even though its semantics are more "node" than "model" */
  294. class Model : public Object {
  295. public:
  296. enum RotOrder {
  297. RotOrder_EulerXYZ = 0,
  298. RotOrder_EulerXZY,
  299. RotOrder_EulerYZX,
  300. RotOrder_EulerYXZ,
  301. RotOrder_EulerZXY,
  302. RotOrder_EulerZYX,
  303. RotOrder_SphericXYZ,
  304. RotOrder_MAX // end-of-enum sentinel
  305. };
  306. Model(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  307. virtual ~Model();
  308. fbx_simple_property(QuaternionInterpolate, int, 0);
  309. fbx_simple_property(RotationOffset, Vector3, Vector3());
  310. fbx_simple_property(RotationPivot, Vector3, Vector3());
  311. fbx_simple_property(ScalingOffset, Vector3, Vector3());
  312. fbx_simple_property(ScalingPivot, Vector3, Vector3());
  313. fbx_simple_property(TranslationActive, bool, false);
  314. fbx_simple_property(TranslationMin, Vector3, Vector3());
  315. fbx_simple_property(TranslationMax, Vector3, Vector3());
  316. fbx_simple_property(TranslationMinX, bool, false);
  317. fbx_simple_property(TranslationMaxX, bool, false);
  318. fbx_simple_property(TranslationMinY, bool, false);
  319. fbx_simple_property(TranslationMaxY, bool, false);
  320. fbx_simple_property(TranslationMinZ, bool, false);
  321. fbx_simple_property(TranslationMaxZ, bool, false);
  322. fbx_simple_enum_property(RotationOrder, RotOrder, 0);
  323. fbx_simple_property(RotationSpaceForLimitOnly, bool, false);
  324. fbx_simple_property(RotationStiffnessX, float, 0.0f);
  325. fbx_simple_property(RotationStiffnessY, float, 0.0f);
  326. fbx_simple_property(RotationStiffnessZ, float, 0.0f);
  327. fbx_simple_property(AxisLen, float, 0.0f);
  328. fbx_simple_property(PreRotation, Vector3, Vector3());
  329. fbx_simple_property(PostRotation, Vector3, Vector3());
  330. fbx_simple_property(RotationActive, bool, false);
  331. fbx_simple_property(RotationMin, Vector3, Vector3());
  332. fbx_simple_property(RotationMax, Vector3, Vector3());
  333. fbx_simple_property(RotationMinX, bool, false);
  334. fbx_simple_property(RotationMaxX, bool, false);
  335. fbx_simple_property(RotationMinY, bool, false);
  336. fbx_simple_property(RotationMaxY, bool, false);
  337. fbx_simple_property(RotationMinZ, bool, false);
  338. fbx_simple_property(RotationMaxZ, bool, false);
  339. fbx_simple_enum_property(InheritType, TransformInheritance, 0);
  340. fbx_simple_property(ScalingActive, bool, false);
  341. fbx_simple_property(ScalingMin, Vector3, Vector3());
  342. fbx_simple_property(ScalingMax, Vector3, Vector3(1, 1, 1));
  343. fbx_simple_property(ScalingMinX, bool, false);
  344. fbx_simple_property(ScalingMaxX, bool, false);
  345. fbx_simple_property(ScalingMinY, bool, false);
  346. fbx_simple_property(ScalingMaxY, bool, false);
  347. fbx_simple_property(ScalingMinZ, bool, false);
  348. fbx_simple_property(ScalingMaxZ, bool, false);
  349. fbx_simple_property(GeometricTranslation, Vector3, Vector3());
  350. fbx_simple_property(GeometricRotation, Vector3, Vector3());
  351. fbx_simple_property(GeometricScaling, Vector3, Vector3(1, 1, 1));
  352. fbx_simple_property(MinDampRangeX, float, 0.0f);
  353. fbx_simple_property(MinDampRangeY, float, 0.0f);
  354. fbx_simple_property(MinDampRangeZ, float, 0.0f);
  355. fbx_simple_property(MaxDampRangeX, float, 0.0f);
  356. fbx_simple_property(MaxDampRangeY, float, 0.0f);
  357. fbx_simple_property(MaxDampRangeZ, float, 0.0f);
  358. fbx_simple_property(MinDampStrengthX, float, 0.0f);
  359. fbx_simple_property(MinDampStrengthY, float, 0.0f);
  360. fbx_simple_property(MinDampStrengthZ, float, 0.0f);
  361. fbx_simple_property(MaxDampStrengthX, float, 0.0f);
  362. fbx_simple_property(MaxDampStrengthY, float, 0.0f);
  363. fbx_simple_property(MaxDampStrengthZ, float, 0.0f);
  364. fbx_simple_property(PreferredAngleX, float, 0.0f);
  365. fbx_simple_property(PreferredAngleY, float, 0.0f);
  366. fbx_simple_property(PreferredAngleZ, float, 0.0f);
  367. fbx_simple_property(Show, bool, true);
  368. fbx_simple_property(LODBox, bool, false);
  369. fbx_simple_property(Freeze, bool, false);
  370. const std::string &Shading() const {
  371. return shading;
  372. }
  373. const std::string &Culling() const {
  374. return culling;
  375. }
  376. const PropertyTable *Props() const {
  377. return props;
  378. }
  379. /** Get material links */
  380. const std::vector<const Material *> &GetMaterials() const {
  381. return materials;
  382. }
  383. /** Get geometry links */
  384. const std::vector<const Geometry *> &GetGeometry() const {
  385. return geometry;
  386. }
  387. /** Get node attachments */
  388. const std::vector<const NodeAttribute *> &GetAttributes() const {
  389. return attributes;
  390. }
  391. /** convenience method to check if the node has a Null node marker */
  392. bool IsNull() const;
  393. private:
  394. void ResolveLinks(const ElementPtr element, const Document &doc);
  395. private:
  396. std::vector<const Material *> materials;
  397. std::vector<const Geometry *> geometry;
  398. std::vector<const NodeAttribute *> attributes;
  399. std::string shading;
  400. std::string culling;
  401. const PropertyTable *props = nullptr;
  402. };
  403. class ModelLimbNode : public Model {
  404. public:
  405. ModelLimbNode(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  406. virtual ~ModelLimbNode();
  407. };
  408. /** DOM class for generic FBX textures */
  409. class Texture : public Object {
  410. public:
  411. Texture(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  412. virtual ~Texture();
  413. const std::string &Type() const {
  414. return type;
  415. }
  416. const std::string &FileName() const {
  417. return fileName;
  418. }
  419. const std::string &RelativeFilename() const {
  420. return relativeFileName;
  421. }
  422. const std::string &AlphaSource() const {
  423. return alphaSource;
  424. }
  425. const Vector2 &UVTranslation() const {
  426. return uvTrans;
  427. }
  428. const Vector2 &UVScaling() const {
  429. return uvScaling;
  430. }
  431. const PropertyTable *Props() const {
  432. return props;
  433. }
  434. // return a 4-tuple
  435. const unsigned int *Crop() const {
  436. return crop;
  437. }
  438. const Video *Media() const {
  439. return media;
  440. }
  441. private:
  442. Vector2 uvTrans;
  443. Vector2 uvScaling;
  444. std::string type;
  445. std::string relativeFileName;
  446. std::string fileName;
  447. std::string alphaSource;
  448. const PropertyTable *props = nullptr;
  449. unsigned int crop[4] = { 0 };
  450. const Video *media = nullptr;
  451. };
  452. /** DOM class for layered FBX textures */
  453. class LayeredTexture : public Object {
  454. public:
  455. LayeredTexture(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  456. virtual ~LayeredTexture();
  457. // Can only be called after construction of the layered texture object due to construction flag.
  458. void fillTexture(const Document &doc);
  459. enum BlendMode {
  460. BlendMode_Translucent,
  461. BlendMode_Additive,
  462. BlendMode_Modulate,
  463. BlendMode_Modulate2,
  464. BlendMode_Over,
  465. BlendMode_Normal,
  466. BlendMode_Dissolve,
  467. BlendMode_Darken,
  468. BlendMode_ColorBurn,
  469. BlendMode_LinearBurn,
  470. BlendMode_DarkerColor,
  471. BlendMode_Lighten,
  472. BlendMode_Screen,
  473. BlendMode_ColorDodge,
  474. BlendMode_LinearDodge,
  475. BlendMode_LighterColor,
  476. BlendMode_SoftLight,
  477. BlendMode_HardLight,
  478. BlendMode_VividLight,
  479. BlendMode_LinearLight,
  480. BlendMode_PinLight,
  481. BlendMode_HardMix,
  482. BlendMode_Difference,
  483. BlendMode_Exclusion,
  484. BlendMode_Subtract,
  485. BlendMode_Divide,
  486. BlendMode_Hue,
  487. BlendMode_Saturation,
  488. BlendMode_Color,
  489. BlendMode_Luminosity,
  490. BlendMode_Overlay,
  491. BlendMode_BlendModeCount
  492. };
  493. const Texture *getTexture(int index = 0) const {
  494. return textures[index];
  495. }
  496. int textureCount() const {
  497. return static_cast<int>(textures.size());
  498. }
  499. BlendMode GetBlendMode() const {
  500. return blendMode;
  501. }
  502. float Alpha() {
  503. return alpha;
  504. }
  505. private:
  506. std::vector<const Texture *> textures;
  507. BlendMode blendMode;
  508. float alpha;
  509. };
  510. typedef std::map<std::string, const Texture *> TextureMap;
  511. typedef std::map<std::string, const LayeredTexture *> LayeredTextureMap;
  512. /** DOM class for generic FBX videos */
  513. class Video : public Object {
  514. public:
  515. Video(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  516. virtual ~Video();
  517. const std::string &Type() const {
  518. return type;
  519. }
  520. bool IsEmbedded() const {
  521. return contentLength > 0;
  522. }
  523. const std::string &FileName() const {
  524. return fileName;
  525. }
  526. const std::string &RelativeFilename() const {
  527. return relativeFileName;
  528. }
  529. const PropertyTable *Props() const {
  530. return props;
  531. }
  532. const uint8_t *Content() const {
  533. return content;
  534. }
  535. uint64_t ContentLength() const {
  536. return contentLength;
  537. }
  538. uint8_t *RelinquishContent() {
  539. uint8_t *ptr = content;
  540. content = nullptr;
  541. return ptr;
  542. }
  543. bool operator==(const Video &other) const {
  544. return (
  545. type == other.type && relativeFileName == other.relativeFileName && fileName == other.fileName);
  546. }
  547. bool operator<(const Video &other) const {
  548. return std::tie(type, relativeFileName, fileName) < std::tie(other.type, other.relativeFileName, other.fileName);
  549. }
  550. private:
  551. std::string type;
  552. std::string relativeFileName;
  553. std::string fileName;
  554. const PropertyTable *props = nullptr;
  555. uint64_t contentLength;
  556. uint8_t *content;
  557. };
  558. /** DOM class for generic FBX materials */
  559. class Material : public Object {
  560. public:
  561. Material(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  562. virtual ~Material();
  563. const std::string &GetShadingModel() const {
  564. return shading;
  565. }
  566. bool IsMultilayer() const {
  567. return multilayer;
  568. }
  569. const PropertyTable *Props() const {
  570. return props;
  571. }
  572. const TextureMap &Textures() const {
  573. return textures;
  574. }
  575. const LayeredTextureMap &LayeredTextures() const {
  576. return layeredTextures;
  577. }
  578. private:
  579. std::string shading;
  580. bool multilayer;
  581. const PropertyTable *props;
  582. TextureMap textures;
  583. LayeredTextureMap layeredTextures;
  584. };
  585. // signed int keys (this can happen!)
  586. typedef std::vector<int64_t> KeyTimeList;
  587. typedef std::vector<float> KeyValueList;
  588. /** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefore) */
  589. class AnimationCurve : public Object {
  590. public:
  591. AnimationCurve(uint64_t id, const ElementPtr element, const std::string &name, const Document &doc);
  592. virtual ~AnimationCurve();
  593. /** get list of keyframe positions (time).
  594. * Invariant: |GetKeys()| > 0 */
  595. const KeyTimeList &GetKeys() const {
  596. return keys;
  597. }
  598. /** get list of keyframe values.
  599. * Invariant: |GetKeys()| == |GetValues()| && |GetKeys()| > 0*/
  600. const KeyValueList &GetValues() const {
  601. return values;
  602. }
  603. const std::map<int64_t, float> &GetValueTimeTrack() const {
  604. return keyvalues;
  605. }
  606. const std::vector<float> &GetAttributes() const {
  607. return attributes;
  608. }
  609. const std::vector<unsigned int> &GetFlags() const {
  610. return flags;
  611. }
  612. private:
  613. KeyTimeList keys;
  614. KeyValueList values;
  615. std::vector<float> attributes;
  616. std::map<int64_t, float> keyvalues;
  617. std::vector<unsigned int> flags;
  618. };
  619. /* Typedef for pointers for the animation handler */
  620. typedef std::shared_ptr<AnimationCurve> AnimationCurvePtr;
  621. typedef std::weak_ptr<AnimationCurve> AnimationCurveWeakPtr;
  622. typedef std::map<std::string, const AnimationCurve *> AnimationMap;
  623. /* Animation Curve node ptr */
  624. typedef std::shared_ptr<AnimationCurveNode> AnimationCurveNodePtr;
  625. typedef std::weak_ptr<AnimationCurveNode> AnimationCurveNodeWeakPtr;
  626. /** Represents a FBX animation curve (i.e. a mapping from single animation curves to nodes) */
  627. class AnimationCurveNode : public Object {
  628. public:
  629. /* the optional white list specifies a list of property names for which the caller
  630. wants animations for. If the curve node does not match one of these, std::range_error
  631. will be thrown. */
  632. AnimationCurveNode(uint64_t id, const ElementPtr element, const std::string &name, const Document &doc,
  633. const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0);
  634. virtual ~AnimationCurveNode();
  635. const PropertyTable *Props() const {
  636. return props;
  637. }
  638. const AnimationMap &Curves() const;
  639. /** Object the curve is assigned to, this can be NULL if the
  640. * target object has no DOM representation or could not
  641. * be read for other reasons.*/
  642. Object *Target() const {
  643. return target;
  644. }
  645. Model *TargetAsModel() const {
  646. return dynamic_cast<Model *>(target);
  647. }
  648. NodeAttribute *TargetAsNodeAttribute() const {
  649. return dynamic_cast<NodeAttribute *>(target);
  650. }
  651. /** Property of Target() that is being animated*/
  652. const std::string &TargetProperty() const {
  653. return prop;
  654. }
  655. private:
  656. Object *target = nullptr;
  657. const PropertyTable *props;
  658. mutable AnimationMap curves;
  659. std::string prop;
  660. const Document &doc;
  661. };
  662. typedef std::vector<const AnimationCurveNode *> AnimationCurveNodeList;
  663. typedef std::shared_ptr<AnimationLayer> AnimationLayerPtr;
  664. typedef std::weak_ptr<AnimationLayer> AnimationLayerWeakPtr;
  665. typedef std::vector<const AnimationLayer *> AnimationLayerList;
  666. /** Represents a FBX animation layer (i.e. a list of node animations) */
  667. class AnimationLayer : public Object {
  668. public:
  669. AnimationLayer(uint64_t id, const ElementPtr element, const std::string &name, const Document &doc);
  670. virtual ~AnimationLayer();
  671. const PropertyTable *Props() const {
  672. //ai_assert(props.get());
  673. return props;
  674. }
  675. /* the optional white list specifies a list of property names for which the caller
  676. wants animations for. Curves not matching this list will not be added to the
  677. animation layer. */
  678. const AnimationCurveNodeList Nodes(const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0) const;
  679. private:
  680. const PropertyTable *props;
  681. const Document &doc;
  682. };
  683. /** Represents a FBX animation stack (i.e. a list of animation layers) */
  684. class AnimationStack : public Object {
  685. public:
  686. AnimationStack(uint64_t id, const ElementPtr element, const std::string &name, const Document &doc);
  687. virtual ~AnimationStack();
  688. fbx_simple_property(LocalStart, int64_t, 0L);
  689. fbx_simple_property(LocalStop, int64_t, 0L);
  690. fbx_simple_property(ReferenceStart, int64_t, 0L);
  691. fbx_simple_property(ReferenceStop, int64_t, 0L);
  692. const PropertyTable *Props() const {
  693. return props;
  694. }
  695. const AnimationLayerList &Layers() const {
  696. return layers;
  697. }
  698. private:
  699. const PropertyTable *props = nullptr;
  700. AnimationLayerList layers;
  701. };
  702. /** DOM class for deformers */
  703. class Deformer : public Object {
  704. public:
  705. Deformer(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  706. virtual ~Deformer();
  707. const PropertyTable *Props() const {
  708. //ai_assert(props.get());
  709. return props;
  710. }
  711. private:
  712. const PropertyTable *props;
  713. };
  714. /** Constraints are from Maya they can help us with BoneAttachments :) **/
  715. class Constraint : public Object {
  716. public:
  717. Constraint(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  718. virtual ~Constraint();
  719. private:
  720. const PropertyTable *props;
  721. };
  722. typedef std::vector<float> WeightArray;
  723. typedef std::vector<unsigned int> WeightIndexArray;
  724. /** DOM class for BlendShapeChannel deformers */
  725. class BlendShapeChannel : public Deformer {
  726. public:
  727. BlendShapeChannel(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  728. virtual ~BlendShapeChannel();
  729. float DeformPercent() const {
  730. return percent;
  731. }
  732. const WeightArray &GetFullWeights() const {
  733. return fullWeights;
  734. }
  735. const std::vector<const ShapeGeometry *> &GetShapeGeometries() const {
  736. return shapeGeometries;
  737. }
  738. private:
  739. float percent;
  740. WeightArray fullWeights;
  741. std::vector<const ShapeGeometry *> shapeGeometries;
  742. };
  743. /** DOM class for BlendShape deformers */
  744. class BlendShape : public Deformer {
  745. public:
  746. BlendShape(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  747. virtual ~BlendShape();
  748. const std::vector<const BlendShapeChannel *> &BlendShapeChannels() const {
  749. return blendShapeChannels;
  750. }
  751. private:
  752. std::vector<const BlendShapeChannel *> blendShapeChannels;
  753. };
  754. /** DOM class for skin deformer clusters (aka sub-deformers) */
  755. class Cluster : public Deformer {
  756. public:
  757. Cluster(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  758. virtual ~Cluster();
  759. /** get the list of deformer weights associated with this cluster.
  760. * Use #GetIndices() to get the associated vertices. Both arrays
  761. * have the same size (and may also be empty). */
  762. const std::vector<float> &GetWeights() const {
  763. return weights;
  764. }
  765. /** get indices into the vertex data of the geometry associated
  766. * with this cluster. Use #GetWeights() to get the associated weights.
  767. * Both arrays have the same size (and may also be empty). */
  768. const std::vector<unsigned int> &GetIndices() const {
  769. return indices;
  770. }
  771. /** */
  772. const Transform &GetTransform() const {
  773. return transform;
  774. }
  775. const Transform &TransformLink() const {
  776. return transformLink;
  777. }
  778. const Model *TargetNode() const {
  779. return node;
  780. }
  781. const Transform &TransformAssociateModel() const {
  782. return transformAssociateModel;
  783. }
  784. bool TransformAssociateModelValid() const {
  785. return valid_transformAssociateModel;
  786. }
  787. // property is not in the fbx file
  788. // if the cluster has an associate model
  789. // we then have an additive type
  790. enum SkinLinkMode {
  791. SkinLinkMode_Normalized = 0,
  792. SkinLinkMode_Additive = 1
  793. };
  794. SkinLinkMode GetLinkMode() {
  795. return link_mode;
  796. }
  797. private:
  798. std::vector<float> weights;
  799. std::vector<unsigned int> indices;
  800. Transform transform;
  801. Transform transformLink;
  802. Transform transformAssociateModel;
  803. SkinLinkMode link_mode;
  804. bool valid_transformAssociateModel;
  805. const Model *node = nullptr;
  806. };
  807. /** DOM class for skin deformers */
  808. class Skin : public Deformer {
  809. public:
  810. Skin(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
  811. virtual ~Skin();
  812. float DeformAccuracy() const {
  813. return accuracy;
  814. }
  815. const std::vector<const Cluster *> &Clusters() const {
  816. return clusters;
  817. }
  818. enum SkinType {
  819. Skin_Rigid = 0,
  820. Skin_Linear,
  821. Skin_DualQuaternion,
  822. Skin_Blend
  823. };
  824. const SkinType &GetSkinType() const {
  825. return skinType;
  826. }
  827. private:
  828. float accuracy;
  829. SkinType skinType;
  830. std::vector<const Cluster *> clusters;
  831. };
  832. /** Represents a link between two FBX objects. */
  833. class Connection {
  834. public:
  835. Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string &prop, const Document &doc);
  836. ~Connection();
  837. // note: a connection ensures that the source and dest objects exist, but
  838. // not that they have DOM representations, so the return value of one of
  839. // these functions can still be NULL.
  840. Object *SourceObject() const;
  841. Object *DestinationObject() const;
  842. // these, however, are always guaranteed to be valid
  843. LazyObject *LazySourceObject() const;
  844. LazyObject *LazyDestinationObject() const;
  845. /** return the name of the property the connection is attached to.
  846. * this is an empty string for object to object (OO) connections. */
  847. const std::string &PropertyName() const {
  848. return prop;
  849. }
  850. uint64_t InsertionOrder() const {
  851. return insertionOrder;
  852. }
  853. int CompareTo(const Connection *c) const {
  854. //ai_assert(nullptr != c);
  855. // note: can't subtract because this would overflow uint64_t
  856. if (InsertionOrder() > c->InsertionOrder()) {
  857. return 1;
  858. } else if (InsertionOrder() < c->InsertionOrder()) {
  859. return -1;
  860. }
  861. return 0;
  862. }
  863. bool Compare(const Connection *c) const {
  864. //ai_assert(nullptr != c);
  865. return InsertionOrder() < c->InsertionOrder();
  866. }
  867. public:
  868. uint64_t insertionOrder;
  869. const std::string prop;
  870. uint64_t src, dest;
  871. const Document &doc;
  872. };
  873. // XXX again, unique_ptr would be useful. shared_ptr is too
  874. // bloated since the objects have a well-defined single owner
  875. // during their entire lifetime (Document). FBX files have
  876. // up to many thousands of objects (most of which we never use),
  877. // so the memory overhead for them should be kept at a minimum.
  878. typedef std::map<uint64_t, LazyObject *> ObjectMap;
  879. typedef std::map<std::string, const PropertyTable *> PropertyTemplateMap;
  880. typedef std::multimap<uint64_t, const Connection *> ConnectionMap;
  881. /** DOM class for global document settings, a single instance per document can
  882. * be accessed via Document.Globals(). */
  883. class FileGlobalSettings {
  884. public:
  885. FileGlobalSettings(const Document &doc, const PropertyTable *props);
  886. ~FileGlobalSettings();
  887. const PropertyTable *Props() const {
  888. return props;
  889. }
  890. const Document &GetDocument() const {
  891. return doc;
  892. }
  893. fbx_simple_property(UpAxis, int, 1);
  894. fbx_simple_property(UpAxisSign, int, 1);
  895. fbx_simple_property(FrontAxis, int, 2);
  896. fbx_simple_property(FrontAxisSign, int, 1);
  897. fbx_simple_property(CoordAxis, int, 0);
  898. fbx_simple_property(CoordAxisSign, int, 1);
  899. fbx_simple_property(OriginalUpAxis, int, 0);
  900. fbx_simple_property(OriginalUpAxisSign, int, 1);
  901. fbx_simple_property(UnitScaleFactor, float, 1);
  902. fbx_simple_property(OriginalUnitScaleFactor, float, 1);
  903. fbx_simple_property(AmbientColor, Vector3, Vector3(0, 0, 0));
  904. fbx_simple_property(DefaultCamera, std::string, "");
  905. enum FrameRate {
  906. FrameRate_DEFAULT = 0,
  907. FrameRate_120 = 1,
  908. FrameRate_100 = 2,
  909. FrameRate_60 = 3,
  910. FrameRate_50 = 4,
  911. FrameRate_48 = 5,
  912. FrameRate_30 = 6,
  913. FrameRate_30_DROP = 7,
  914. FrameRate_NTSC_DROP_FRAME = 8,
  915. FrameRate_NTSC_FULL_FRAME = 9,
  916. FrameRate_PAL = 10,
  917. FrameRate_CINEMA = 11,
  918. FrameRate_1000 = 12,
  919. FrameRate_CINEMA_ND = 13,
  920. FrameRate_CUSTOM = 14,
  921. FrameRate_MAX // end-of-enum sentinel
  922. };
  923. fbx_simple_enum_property(TimeMode, FrameRate, FrameRate_DEFAULT);
  924. fbx_simple_property(TimeSpanStart, uint64_t, 0L);
  925. fbx_simple_property(TimeSpanStop, uint64_t, 0L);
  926. fbx_simple_property(CustomFrameRate, float, -1.0f);
  927. private:
  928. const PropertyTable *props = nullptr;
  929. const Document &doc;
  930. };
  931. /** DOM root for a FBX file */
  932. class Document {
  933. public:
  934. Document(const Parser &parser, const ImportSettings &settings);
  935. ~Document();
  936. LazyObject *GetObject(uint64_t id) const;
  937. bool IsSafeToImport() const {
  938. return SafeToImport;
  939. }
  940. bool IsBinary() const {
  941. return parser.IsBinary();
  942. }
  943. unsigned int FBXVersion() const {
  944. return fbxVersion;
  945. }
  946. const std::string &Creator() const {
  947. return creator;
  948. }
  949. // elements (in this order): Year, Month, Day, Hour, Second, Millisecond
  950. const unsigned int *CreationTimeStamp() const {
  951. return creationTimeStamp;
  952. }
  953. const FileGlobalSettings *GlobalSettingsPtr() const {
  954. return globals.get();
  955. }
  956. const PropertyTable *GetMetadataProperties() const {
  957. return metadata_properties;
  958. }
  959. const PropertyTemplateMap &Templates() const {
  960. return templates;
  961. }
  962. const ObjectMap &Objects() const {
  963. return objects;
  964. }
  965. const ImportSettings &Settings() const {
  966. return settings;
  967. }
  968. const ConnectionMap &ConnectionsBySource() const {
  969. return src_connections;
  970. }
  971. const ConnectionMap &ConnectionsByDestination() const {
  972. return dest_connections;
  973. }
  974. // note: the implicit rule in all DOM classes is to always resolve
  975. // from destination to source (since the FBX object hierarchy is,
  976. // with very few exceptions, a DAG, this avoids cycles). In all
  977. // cases that may involve back-facing edges in the object graph,
  978. // use LazyObject::IsBeingConstructed() to check.
  979. std::vector<const Connection *> GetConnectionsBySourceSequenced(uint64_t source) const;
  980. std::vector<const Connection *> GetConnectionsByDestinationSequenced(uint64_t dest) const;
  981. std::vector<const Connection *> GetConnectionsBySourceSequenced(uint64_t source, const char *classname) const;
  982. std::vector<const Connection *> GetConnectionsByDestinationSequenced(uint64_t dest, const char *classname) const;
  983. std::vector<const Connection *> GetConnectionsBySourceSequenced(uint64_t source,
  984. const char *const *classnames, size_t count) const;
  985. std::vector<const Connection *> GetConnectionsByDestinationSequenced(uint64_t dest,
  986. const char *const *classnames,
  987. size_t count) const;
  988. const std::vector<const AnimationStack *> &AnimationStacks() const;
  989. const std::vector<uint64_t> &GetAnimationStackIDs() const {
  990. return animationStacks;
  991. }
  992. const std::vector<uint64_t> &GetConstraintStackIDs() const {
  993. return constraints;
  994. }
  995. const std::vector<uint64_t> &GetBindPoseIDs() const {
  996. return bind_poses;
  997. };
  998. const std::vector<uint64_t> &GetMaterialIDs() const {
  999. return materials;
  1000. };
  1001. const std::vector<uint64_t> &GetSkinIDs() const {
  1002. return skins;
  1003. }
  1004. private:
  1005. std::vector<const Connection *> GetConnectionsSequenced(uint64_t id, const ConnectionMap &) const;
  1006. std::vector<const Connection *> GetConnectionsSequenced(uint64_t id, bool is_src,
  1007. const ConnectionMap &,
  1008. const char *const *classnames,
  1009. size_t count) const;
  1010. bool ReadHeader();
  1011. void ReadObjects();
  1012. void ReadPropertyTemplates();
  1013. void ReadConnections();
  1014. void ReadGlobalSettings();
  1015. private:
  1016. const ImportSettings &settings;
  1017. ObjectMap objects;
  1018. const Parser &parser;
  1019. bool SafeToImport = false;
  1020. PropertyTemplateMap templates;
  1021. ConnectionMap src_connections;
  1022. ConnectionMap dest_connections;
  1023. unsigned int fbxVersion = 0;
  1024. std::string creator;
  1025. unsigned int creationTimeStamp[7] = { 0 };
  1026. std::vector<uint64_t> animationStacks;
  1027. std::vector<uint64_t> bind_poses;
  1028. // constraints aren't in the tree / at least they are not easy to access.
  1029. std::vector<uint64_t> constraints;
  1030. std::vector<uint64_t> materials;
  1031. std::vector<uint64_t> skins;
  1032. mutable std::vector<const AnimationStack *> animationStacksResolved;
  1033. PropertyTable *metadata_properties = nullptr;
  1034. std::shared_ptr<FileGlobalSettings> globals = nullptr;
  1035. };
  1036. } // namespace FBXDocParser
  1037. namespace std {
  1038. template <>
  1039. struct hash<const FBXDocParser::Video> {
  1040. std::size_t operator()(const FBXDocParser::Video &video) const {
  1041. using std::hash;
  1042. using std::size_t;
  1043. using std::string;
  1044. size_t res = 17;
  1045. res = res * 31 + hash<string>()(video.Name());
  1046. res = res * 31 + hash<string>()(video.RelativeFilename());
  1047. res = res * 31 + hash<string>()(video.Type());
  1048. return res;
  1049. }
  1050. };
  1051. } // namespace std
  1052. #endif // FBXDOCUMENT_H