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