1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252 |
- /*************************************************************************/
- /* FBXDocument.h */
- /*************************************************************************/
- /* This file is part of: */
- /* GODOT ENGINE */
- /* https://godotengine.org */
- /*************************************************************************/
- /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
- /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
- /* */
- /* Permission is hereby granted, free of charge, to any person obtaining */
- /* a copy of this software and associated documentation files (the */
- /* "Software"), to deal in the Software without restriction, including */
- /* without limitation the rights to use, copy, modify, merge, publish, */
- /* distribute, sublicense, and/or sell copies of the Software, and to */
- /* permit persons to whom the Software is furnished to do so, subject to */
- /* the following conditions: */
- /* */
- /* The above copyright notice and this permission notice shall be */
- /* included in all copies or substantial portions of the Software. */
- /* */
- /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
- /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
- /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
- /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
- /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
- /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
- /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- /*************************************************************************/
- /** @file FBXDocument.h
- * @brief FBX DOM
- */
- #ifndef FBX_DOCUMENT_H
- #define FBX_DOCUMENT_H
- #include "FBXCommon.h"
- #include "FBXParser.h"
- #include "FBXProperties.h"
- #include "core/math/transform_3d.h"
- #include "core/math/vector2.h"
- #include "core/math/vector3.h"
- #include "core/string/print_string.h"
- #include <stdint.h>
- #include <numeric>
- #define _AI_CONCAT(a, b) a##b
- #define AI_CONCAT(a, b) _AI_CONCAT(a, b)
- namespace FBXDocParser {
- class Parser;
- class Object;
- struct ImportSettings;
- class Connection;
- class PropertyTable;
- class Document;
- class Material;
- class ShapeGeometry;
- class LineGeometry;
- class Geometry;
- class Video;
- class AnimationCurve;
- class AnimationCurveNode;
- class AnimationLayer;
- class AnimationStack;
- class BlendShapeChannel;
- class BlendShape;
- class Skin;
- class Cluster;
- typedef Object *ObjectPtr;
- #define new_Object new Object
- /** Represents a delay-parsed FBX objects. Many objects in the scene
- * are not needed by assimp, so it makes no sense to parse them
- * upfront. */
- class LazyObject {
- public:
- LazyObject(uint64_t id, const ElementPtr element, const Document &doc);
- ~LazyObject();
- ObjectPtr LoadObject();
- /* Casting weak pointers to their templated type safely and preserving ref counting and safety
- * with lock() keyword to prevent leaking memory
- */
- template <typename T>
- const T *Get() {
- ObjectPtr ob = LoadObject();
- return dynamic_cast<const T *>(ob);
- }
- uint64_t ID() const {
- return id;
- }
- bool IsBeingConstructed() const {
- return (flags & BEING_CONSTRUCTED) != 0;
- }
- bool FailedToConstruct() const {
- return (flags & FAILED_TO_CONSTRUCT) != 0;
- }
- ElementPtr GetElement() const {
- return element;
- }
- const Document &GetDocument() const {
- return doc;
- }
- private:
- const Document &doc;
- ElementPtr element = nullptr;
- std::shared_ptr<Object> object = nullptr;
- const uint64_t id = 0;
- enum Flags {
- BEING_CONSTRUCTED = 0x1,
- FAILED_TO_CONSTRUCT = 0x2
- };
- unsigned int flags = 0;
- };
- /** Base class for in-memory (DOM) representations of FBX objects */
- class Object : public PropertyTable {
- public:
- Object(uint64_t id, const ElementPtr element, const std::string &name);
- virtual ~Object();
- ElementPtr SourceElement() const {
- return element;
- }
- const std::string &Name() const {
- return name;
- }
- uint64_t ID() const {
- return id;
- }
- protected:
- const ElementPtr element = nullptr;
- const std::string name;
- const uint64_t id;
- };
- /** DOM class for generic FBX NoteAttribute blocks. NoteAttribute's just hold a property table,
- * fixed members are added by deriving classes. */
- class NodeAttribute : public Object {
- public:
- NodeAttribute(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~NodeAttribute();
- };
- /** DOM base class for FBX camera settings attached to a node */
- class CameraSwitcher : public NodeAttribute {
- public:
- CameraSwitcher(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~CameraSwitcher();
- int CameraID() const {
- return cameraId;
- }
- const std::string &CameraName() const {
- return cameraName;
- }
- const std::string &CameraIndexName() const {
- return cameraIndexName;
- }
- private:
- int cameraId = 0;
- std::string cameraName;
- std::string cameraIndexName;
- };
- #define fbx_stringize(a) #a
- #define fbx_simple_property(name, type, default_value) \
- type name() const { \
- return PropertyGet<type>(this, fbx_stringize(name), (default_value)); \
- }
- // XXX improve logging
- #define fbx_simple_enum_property(name, type, default_value) \
- type name() const { \
- const int ival = PropertyGet<int>(this, fbx_stringize(name), static_cast<int>(default_value)); \
- if (ival < 0 || ival >= AI_CONCAT(type, _MAX)) { \
- return static_cast<type>(default_value); \
- } \
- return static_cast<type>(ival); \
- }
- class FbxPoseNode;
- class FbxPose : public Object {
- public:
- FbxPose(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- const std::vector<FbxPoseNode *> &GetBindPoses() const {
- return pose_nodes;
- }
- virtual ~FbxPose();
- private:
- std::vector<FbxPoseNode *> pose_nodes;
- };
- class FbxPoseNode {
- public:
- FbxPoseNode(const ElementPtr element, const Document &doc, const std::string &name) {
- const ScopePtr sc = GetRequiredScope(element);
- // get pose node transform
- const ElementPtr Transform = GetRequiredElement(sc, "Matrix", element);
- transform = ReadMatrix(Transform);
- // get node id this pose node is for
- const ElementPtr NodeId = sc->GetElement("Node3D");
- if (NodeId) {
- target_id = ParseTokenAsInt64(GetRequiredToken(NodeId, 0));
- }
- print_verbose("added posenode " + itos(target_id) + " transform: " + transform);
- }
- virtual ~FbxPoseNode() {
- }
- uint64_t GetNodeID() const {
- return target_id;
- }
- Transform3D GetBindPose() const {
- return transform;
- }
- private:
- uint64_t target_id = 0;
- Transform3D transform;
- };
- /** DOM base class for FBX cameras attached to a node */
- class Camera : public NodeAttribute {
- public:
- Camera(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~Camera();
- fbx_simple_property(Position, Vector3, Vector3(0, 0, 0));
- fbx_simple_property(UpVector, Vector3, Vector3(0, 1, 0));
- fbx_simple_property(InterestPosition, Vector3, Vector3(0, 0, 0));
- fbx_simple_property(AspectWidth, float, 1.0f);
- fbx_simple_property(AspectHeight, float, 1.0f);
- fbx_simple_property(FilmWidth, float, 1.0f);
- fbx_simple_property(FilmHeight, float, 1.0f);
- fbx_simple_property(NearPlane, float, 0.1f);
- fbx_simple_property(FarPlane, float, 100.0f);
- fbx_simple_property(FilmAspectRatio, float, 1.0f);
- fbx_simple_property(ApertureMode, int, 0);
- fbx_simple_property(FieldOfView, float, 1.0f);
- fbx_simple_property(FocalLength, float, 1.0f);
- };
- /** DOM base class for FBX null markers attached to a node */
- class Null : public NodeAttribute {
- public:
- Null(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~Null();
- };
- /** DOM base class for FBX limb node markers attached to a node */
- class LimbNode : public NodeAttribute {
- public:
- LimbNode(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~LimbNode();
- };
- /** DOM base class for FBX lights attached to a node */
- class Light : public NodeAttribute {
- public:
- Light(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~Light();
- enum Type {
- Type_Point,
- Type_Directional,
- Type_Spot,
- Type_Area,
- Type_Volume,
- Type_MAX // end-of-enum sentinel
- };
- enum Decay {
- Decay_None,
- Decay_Linear,
- Decay_Quadratic,
- Decay_Cubic,
- Decay_MAX // end-of-enum sentinel
- };
- fbx_simple_property(Color, Vector3, Vector3(1, 1, 1));
- fbx_simple_enum_property(LightType, Type, 0);
- fbx_simple_property(CastLightOnObject, bool, false);
- fbx_simple_property(DrawVolumetricLight, bool, true);
- fbx_simple_property(DrawGroundProjection, bool, true);
- fbx_simple_property(DrawFrontFacingVolumetricLight, bool, false);
- fbx_simple_property(Intensity, float, 100.0f);
- fbx_simple_property(InnerAngle, float, 0.0f);
- fbx_simple_property(OuterAngle, float, 45.0f);
- fbx_simple_property(Fog, int, 50);
- fbx_simple_enum_property(DecayType, Decay, 2);
- fbx_simple_property(DecayStart, float, 1.0f);
- fbx_simple_property(FileName, std::string, "");
- fbx_simple_property(EnableNearAttenuation, bool, false);
- fbx_simple_property(NearAttenuationStart, float, 0.0f);
- fbx_simple_property(NearAttenuationEnd, float, 0.0f);
- fbx_simple_property(EnableFarAttenuation, bool, false);
- fbx_simple_property(FarAttenuationStart, float, 0.0f);
- fbx_simple_property(FarAttenuationEnd, float, 0.0f);
- fbx_simple_property(CastShadows, bool, true);
- fbx_simple_property(ShadowColor, Vector3, Vector3(0, 0, 0));
- fbx_simple_property(AreaLightShape, int, 0);
- fbx_simple_property(LeftBarnDoor, float, 20.0f);
- fbx_simple_property(RightBarnDoor, float, 20.0f);
- fbx_simple_property(TopBarnDoor, float, 20.0f);
- fbx_simple_property(BottomBarnDoor, float, 20.0f);
- fbx_simple_property(EnableBarnDoor, bool, true);
- };
- class Model;
- typedef Model *ModelPtr;
- #define new_Model new Model
- /** DOM base class for FBX models (even though its semantics are more "node" than "model" */
- class Model : public Object {
- public:
- enum RotOrder {
- RotOrder_EulerXYZ = 0,
- RotOrder_EulerXZY,
- RotOrder_EulerYZX,
- RotOrder_EulerYXZ,
- RotOrder_EulerZXY,
- RotOrder_EulerZYX,
- RotOrder_SphericXYZ,
- RotOrder_MAX // end-of-enum sentinel
- };
- Model(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~Model();
- fbx_simple_property(QuaternionInterpolate, int, 0);
- fbx_simple_property(RotationOffset, Vector3, Vector3());
- fbx_simple_property(RotationPivot, Vector3, Vector3());
- fbx_simple_property(ScalingOffset, Vector3, Vector3());
- fbx_simple_property(ScalingPivot, Vector3, Vector3());
- fbx_simple_property(TranslationActive, bool, false);
- fbx_simple_property(TranslationMin, Vector3, Vector3());
- fbx_simple_property(TranslationMax, Vector3, Vector3());
- fbx_simple_property(TranslationMinX, bool, false);
- fbx_simple_property(TranslationMaxX, bool, false);
- fbx_simple_property(TranslationMinY, bool, false);
- fbx_simple_property(TranslationMaxY, bool, false);
- fbx_simple_property(TranslationMinZ, bool, false);
- fbx_simple_property(TranslationMaxZ, bool, false);
- fbx_simple_enum_property(RotationOrder, RotOrder, 0);
- fbx_simple_property(RotationSpaceForLimitOnly, bool, false);
- fbx_simple_property(RotationStiffnessX, float, 0.0f);
- fbx_simple_property(RotationStiffnessY, float, 0.0f);
- fbx_simple_property(RotationStiffnessZ, float, 0.0f);
- fbx_simple_property(AxisLen, float, 0.0f);
- fbx_simple_property(PreRotation, Vector3, Vector3());
- fbx_simple_property(PostRotation, Vector3, Vector3());
- fbx_simple_property(RotationActive, bool, false);
- fbx_simple_property(RotationMin, Vector3, Vector3());
- fbx_simple_property(RotationMax, Vector3, Vector3());
- fbx_simple_property(RotationMinX, bool, false);
- fbx_simple_property(RotationMaxX, bool, false);
- fbx_simple_property(RotationMinY, bool, false);
- fbx_simple_property(RotationMaxY, bool, false);
- fbx_simple_property(RotationMinZ, bool, false);
- fbx_simple_property(RotationMaxZ, bool, false);
- fbx_simple_enum_property(InheritType, TransformInheritance, 0);
- fbx_simple_property(ScalingActive, bool, false);
- fbx_simple_property(ScalingMin, Vector3, Vector3());
- fbx_simple_property(ScalingMax, Vector3, Vector3(1, 1, 1));
- fbx_simple_property(ScalingMinX, bool, false);
- fbx_simple_property(ScalingMaxX, bool, false);
- fbx_simple_property(ScalingMinY, bool, false);
- fbx_simple_property(ScalingMaxY, bool, false);
- fbx_simple_property(ScalingMinZ, bool, false);
- fbx_simple_property(ScalingMaxZ, bool, false);
- fbx_simple_property(GeometricTranslation, Vector3, Vector3());
- fbx_simple_property(GeometricRotation, Vector3, Vector3());
- fbx_simple_property(GeometricScaling, Vector3, Vector3(1, 1, 1));
- fbx_simple_property(MinDampRangeX, float, 0.0f);
- fbx_simple_property(MinDampRangeY, float, 0.0f);
- fbx_simple_property(MinDampRangeZ, float, 0.0f);
- fbx_simple_property(MaxDampRangeX, float, 0.0f);
- fbx_simple_property(MaxDampRangeY, float, 0.0f);
- fbx_simple_property(MaxDampRangeZ, float, 0.0f);
- fbx_simple_property(MinDampStrengthX, float, 0.0f);
- fbx_simple_property(MinDampStrengthY, float, 0.0f);
- fbx_simple_property(MinDampStrengthZ, float, 0.0f);
- fbx_simple_property(MaxDampStrengthX, float, 0.0f);
- fbx_simple_property(MaxDampStrengthY, float, 0.0f);
- fbx_simple_property(MaxDampStrengthZ, float, 0.0f);
- fbx_simple_property(PreferredAngleX, float, 0.0f);
- fbx_simple_property(PreferredAngleY, float, 0.0f);
- fbx_simple_property(PreferredAngleZ, float, 0.0f);
- fbx_simple_property(Show, bool, true);
- fbx_simple_property(LODBox, bool, false);
- fbx_simple_property(Freeze, bool, false);
- const std::string &Shading() const {
- return shading;
- }
- const std::string &Culling() const {
- return culling;
- }
- /** Get material links */
- const std::vector<const Material *> &GetMaterials() const {
- return materials;
- }
- /** Get geometry links */
- const std::vector<const Geometry *> &GetGeometry() const {
- return geometry;
- }
- /** Get node attachments */
- const std::vector<const NodeAttribute *> &GetAttributes() const {
- return attributes;
- }
- /** convenience method to check if the node has a Null node marker */
- bool IsNull() const;
- private:
- void ResolveLinks(const ElementPtr element, const Document &doc);
- private:
- std::vector<const Material *> materials;
- std::vector<const Geometry *> geometry;
- std::vector<const NodeAttribute *> attributes;
- std::string shading;
- std::string culling;
- };
- class ModelLimbNode : public Model {
- public:
- ModelLimbNode(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~ModelLimbNode();
- };
- /** DOM class for generic FBX textures */
- class Texture : public Object {
- public:
- Texture(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~Texture();
- const std::string &Type() const {
- return type;
- }
- const std::string &FileName() const {
- return fileName;
- }
- const std::string &RelativeFilename() const {
- return relativeFileName;
- }
- const std::string &AlphaSource() const {
- return alphaSource;
- }
- const Vector2 &UVTranslation() const {
- return uvTrans;
- }
- const Vector2 &UVScaling() const {
- return uvScaling;
- }
- // return a 4-tuple
- const unsigned int *Crop() const {
- return crop;
- }
- const Video *Media() const {
- return media;
- }
- private:
- Vector2 uvTrans;
- Vector2 uvScaling;
- std::string type;
- std::string relativeFileName;
- std::string fileName;
- std::string alphaSource;
- unsigned int crop[4] = { 0 };
- const Video *media = nullptr;
- };
- /** DOM class for layered FBX textures */
- class LayeredTexture : public Object {
- public:
- LayeredTexture(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~LayeredTexture();
- // Can only be called after construction of the layered texture object due to construction flag.
- void fillTexture(const Document &doc);
- enum BlendMode {
- BlendMode_Translucent,
- BlendMode_Additive,
- BlendMode_Modulate,
- BlendMode_Modulate2,
- BlendMode_Over,
- BlendMode_Normal,
- BlendMode_Dissolve,
- BlendMode_Darken,
- BlendMode_ColorBurn,
- BlendMode_LinearBurn,
- BlendMode_DarkerColor,
- BlendMode_Lighten,
- BlendMode_Screen,
- BlendMode_ColorDodge,
- BlendMode_LinearDodge,
- BlendMode_LighterColor,
- BlendMode_SoftLight,
- BlendMode_HardLight,
- BlendMode_VividLight,
- BlendMode_LinearLight,
- BlendMode_PinLight,
- BlendMode_HardMix,
- BlendMode_Difference,
- BlendMode_Exclusion,
- BlendMode_Subtract,
- BlendMode_Divide,
- BlendMode_Hue,
- BlendMode_Saturation,
- BlendMode_Color,
- BlendMode_Luminosity,
- BlendMode_Overlay,
- BlendMode_BlendModeCount
- };
- const Texture *getTexture(int index = 0) const {
- return textures[index];
- }
- int textureCount() const {
- return static_cast<int>(textures.size());
- }
- BlendMode GetBlendMode() const {
- return blendMode;
- }
- float Alpha() {
- return alpha;
- }
- private:
- std::vector<const Texture *> textures;
- BlendMode blendMode = BlendMode::BlendMode_Additive;
- float alpha = 0;
- };
- typedef std::map<std::string, const Texture *> TextureMap;
- typedef std::map<std::string, const LayeredTexture *> LayeredTextureMap;
- /** DOM class for generic FBX videos */
- class Video : public Object {
- public:
- Video(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~Video();
- const std::string &Type() const {
- return type;
- }
- bool IsEmbedded() const {
- return contentLength > 0;
- }
- const std::string &FileName() const {
- return fileName;
- }
- const std::string &RelativeFilename() const {
- return relativeFileName;
- }
- const uint8_t *Content() const {
- return content;
- }
- uint64_t ContentLength() const {
- return contentLength;
- }
- uint8_t *RelinquishContent() {
- uint8_t *ptr = content;
- content = nullptr;
- return ptr;
- }
- bool operator==(const Video &other) const {
- return (
- type == other.type && relativeFileName == other.relativeFileName && fileName == other.fileName);
- }
- bool operator<(const Video &other) const {
- return std::tie(type, relativeFileName, fileName) < std::tie(other.type, other.relativeFileName, other.fileName);
- }
- private:
- std::string type;
- std::string relativeFileName;
- std::string fileName;
- uint64_t contentLength = 0;
- uint8_t *content = nullptr;
- };
- /** DOM class for generic FBX materials */
- class Material : public Object {
- public:
- Material(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~Material();
- const std::string &GetShadingModel() const {
- return shading;
- }
- bool IsMultilayer() const {
- return multilayer;
- }
- const TextureMap &Textures() const {
- return textures;
- }
- const LayeredTextureMap &LayeredTextures() const {
- return layeredTextures;
- }
- private:
- std::string shading;
- bool multilayer = false;
- TextureMap textures;
- LayeredTextureMap layeredTextures;
- };
- // signed int keys (this can happen!)
- typedef std::vector<int64_t> KeyTimeList;
- typedef std::vector<float> KeyValueList;
- /** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefore) */
- class AnimationCurve : public Object {
- public:
- AnimationCurve(uint64_t id, const ElementPtr element, const std::string &name, const Document &doc);
- virtual ~AnimationCurve();
- /** get list of keyframe positions (time).
- * Invariant: |GetKeys()| > 0 */
- const KeyTimeList &GetKeys() const {
- return keys;
- }
- /** get list of keyframe values.
- * Invariant: |GetKeys()| == |GetValues()| && |GetKeys()| > 0*/
- const KeyValueList &GetValues() const {
- return values;
- }
- const std::map<int64_t, float> &GetValueTimeTrack() const {
- return keyvalues;
- }
- const std::vector<float> &GetAttributes() const {
- return attributes;
- }
- const std::vector<unsigned int> &GetFlags() const {
- return flags;
- }
- private:
- KeyTimeList keys;
- KeyValueList values;
- std::vector<float> attributes;
- std::map<int64_t, float> keyvalues;
- std::vector<unsigned int> flags;
- };
- /* Typedef for pointers for the animation handler */
- typedef std::shared_ptr<AnimationCurve> AnimationCurvePtr;
- typedef std::weak_ptr<AnimationCurve> AnimationCurveWeakPtr;
- typedef std::map<std::string, const AnimationCurve *> AnimationMap;
- /* Animation Curve node ptr */
- typedef std::shared_ptr<AnimationCurveNode> AnimationCurveNodePtr;
- typedef std::weak_ptr<AnimationCurveNode> AnimationCurveNodeWeakPtr;
- /** Represents a FBX animation curve (i.e. a mapping from single animation curves to nodes) */
- class AnimationCurveNode : public Object {
- public:
- /* the optional white list specifies a list of property names for which the caller
- wants animations for. If the curve node does not match one of these, std::range_error
- will be thrown. */
- AnimationCurveNode(uint64_t id, const ElementPtr element, const std::string &name, const Document &doc,
- const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0);
- virtual ~AnimationCurveNode();
- const AnimationMap &Curves() const;
- /** Object the curve is assigned to, this can be nullptr if the
- * target object has no DOM representation or could not
- * be read for other reasons.*/
- Object *Target() const {
- return target;
- }
- Model *TargetAsModel() const {
- return dynamic_cast<Model *>(target);
- }
- NodeAttribute *TargetAsNodeAttribute() const {
- return dynamic_cast<NodeAttribute *>(target);
- }
- /** Property of Target() that is being animated*/
- const std::string &TargetProperty() const {
- return prop;
- }
- private:
- Object *target = nullptr;
- mutable AnimationMap curves;
- std::string prop;
- const Document &doc;
- };
- typedef std::vector<const AnimationCurveNode *> AnimationCurveNodeList;
- typedef std::shared_ptr<AnimationLayer> AnimationLayerPtr;
- typedef std::weak_ptr<AnimationLayer> AnimationLayerWeakPtr;
- typedef std::vector<const AnimationLayer *> AnimationLayerList;
- /** Represents a FBX animation layer (i.e. a list of node animations) */
- class AnimationLayer : public Object {
- public:
- AnimationLayer(uint64_t id, const ElementPtr element, const std::string &name, const Document &doc);
- virtual ~AnimationLayer();
- /* the optional white list specifies a list of property names for which the caller
- wants animations for. Curves not matching this list will not be added to the
- animation layer. */
- const AnimationCurveNodeList Nodes(const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0) const;
- private:
- const Document &doc;
- };
- /** Represents a FBX animation stack (i.e. a list of animation layers) */
- class AnimationStack : public Object {
- public:
- AnimationStack(uint64_t id, const ElementPtr element, const std::string &name, const Document &doc);
- virtual ~AnimationStack();
- fbx_simple_property(LocalStart, int64_t, 0L);
- fbx_simple_property(LocalStop, int64_t, 0L);
- fbx_simple_property(ReferenceStart, int64_t, 0L);
- fbx_simple_property(ReferenceStop, int64_t, 0L);
- const AnimationLayerList &Layers() const {
- return layers;
- }
- private:
- AnimationLayerList layers;
- };
- /** DOM class for deformers */
- class Deformer : public Object {
- public:
- Deformer(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~Deformer();
- };
- /** Constraints are from Maya they can help us with BoneAttachments :) **/
- class Constraint : public Object {
- public:
- Constraint(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~Constraint();
- };
- typedef std::vector<float> WeightArray;
- typedef std::vector<unsigned int> WeightIndexArray;
- /** DOM class for BlendShapeChannel deformers */
- class BlendShapeChannel : public Deformer {
- public:
- BlendShapeChannel(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~BlendShapeChannel();
- float DeformPercent() const {
- return percent;
- }
- const WeightArray &GetFullWeights() const {
- return fullWeights;
- }
- const std::vector<const ShapeGeometry *> &GetShapeGeometries() const {
- return shapeGeometries;
- }
- private:
- float percent = 0;
- WeightArray fullWeights;
- std::vector<const ShapeGeometry *> shapeGeometries;
- };
- /** DOM class for BlendShape deformers */
- class BlendShape : public Deformer {
- public:
- BlendShape(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~BlendShape();
- const std::vector<const BlendShapeChannel *> &BlendShapeChannels() const {
- return blendShapeChannels;
- }
- private:
- std::vector<const BlendShapeChannel *> blendShapeChannels;
- };
- /** DOM class for skin deformer clusters (aka sub-deformers) */
- class Cluster : public Deformer {
- public:
- Cluster(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~Cluster();
- /** get the list of deformer weights associated with this cluster.
- * Use #GetIndices() to get the associated vertices. Both arrays
- * have the same size (and may also be empty). */
- const std::vector<float> &GetWeights() const {
- return weights;
- }
- /** get indices into the vertex data of the geometry associated
- * with this cluster. Use #GetWeights() to get the associated weights.
- * Both arrays have the same size (and may also be empty). */
- const std::vector<unsigned int> &GetIndices() const {
- return indices;
- }
- /** */
- const Transform3D &GetTransform() const {
- return transform;
- }
- const Transform3D &TransformLink() const {
- return transformLink;
- }
- const Model *TargetNode() const {
- return node;
- }
- const Transform3D &TransformAssociateModel() const {
- return transformAssociateModel;
- }
- bool TransformAssociateModelValid() const {
- return valid_transformAssociateModel;
- }
- // property is not in the fbx file
- // if the cluster has an associate model
- // we then have an additive type
- enum SkinLinkMode {
- SkinLinkMode_Normalized = 0,
- SkinLinkMode_Additive = 1
- };
- SkinLinkMode GetLinkMode() {
- return link_mode;
- }
- private:
- std::vector<float> weights;
- std::vector<unsigned int> indices;
- Transform3D transform;
- Transform3D transformLink;
- Transform3D transformAssociateModel;
- SkinLinkMode link_mode;
- bool valid_transformAssociateModel = false;
- const Model *node = nullptr;
- };
- /** DOM class for skin deformers */
- class Skin : public Deformer {
- public:
- Skin(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name);
- virtual ~Skin();
- float DeformAccuracy() const {
- return accuracy;
- }
- const std::vector<const Cluster *> &Clusters() const {
- return clusters;
- }
- enum SkinType {
- Skin_Rigid = 0,
- Skin_Linear,
- Skin_DualQuaternion,
- Skin_Blend
- };
- const SkinType &GetSkinType() const {
- return skinType;
- }
- private:
- float accuracy = 0;
- SkinType skinType = SkinType::Skin_Linear;
- std::vector<const Cluster *> clusters;
- };
- /** Represents a link between two FBX objects. */
- class Connection {
- public:
- Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string &prop, const Document &doc);
- ~Connection();
- // note: a connection ensures that the source and dest objects exist, but
- // not that they have DOM representations, so the return value of one of
- // these functions can still be nullptr.
- Object *SourceObject() const;
- Object *DestinationObject() const;
- // these, however, are always guaranteed to be valid
- LazyObject *LazySourceObject() const;
- LazyObject *LazyDestinationObject() const;
- /** return the name of the property the connection is attached to.
- * this is an empty string for object to object (OO) connections. */
- const std::string &PropertyName() const {
- return prop;
- }
- uint64_t InsertionOrder() const {
- return insertionOrder;
- }
- int CompareTo(const Connection *c) const {
- //ai_assert(nullptr != c);
- // note: can't subtract because this would overflow uint64_t
- if (InsertionOrder() > c->InsertionOrder()) {
- return 1;
- } else if (InsertionOrder() < c->InsertionOrder()) {
- return -1;
- }
- return 0;
- }
- bool Compare(const Connection *c) const {
- //ai_assert(nullptr != c);
- return InsertionOrder() < c->InsertionOrder();
- }
- public:
- uint64_t insertionOrder = 0;
- const std::string prop;
- uint64_t src = 0, dest = 0;
- const Document &doc;
- };
- // XXX again, unique_ptr would be useful. shared_ptr is too
- // bloated since the objects have a well-defined single owner
- // during their entire lifetime (Document). FBX files have
- // up to many thousands of objects (most of which we never use),
- // so the memory overhead for them should be kept at a minimum.
- typedef std::map<uint64_t, LazyObject *> ObjectMap;
- typedef std::map<std::string, const PropertyTable *> PropertyTemplateMap;
- typedef std::multimap<uint64_t, const Connection *> ConnectionMap;
- /** DOM class for global document settings, a single instance per document can
- * be accessed via Document.Globals(). */
- class FileGlobalSettings : public PropertyTable {
- public:
- FileGlobalSettings(const Document &doc);
- virtual ~FileGlobalSettings();
- const Document &GetDocument() const {
- return doc;
- }
- fbx_simple_property(UpAxis, int, 1);
- fbx_simple_property(UpAxisSign, int, 1);
- fbx_simple_property(FrontAxis, int, 2);
- fbx_simple_property(FrontAxisSign, int, 1);
- fbx_simple_property(CoordAxis, int, 0);
- fbx_simple_property(CoordAxisSign, int, 1);
- fbx_simple_property(OriginalUpAxis, int, 0);
- fbx_simple_property(OriginalUpAxisSign, int, 1);
- fbx_simple_property(UnitScaleFactor, float, 1);
- fbx_simple_property(OriginalUnitScaleFactor, float, 1);
- fbx_simple_property(AmbientColor, Vector3, Vector3(0, 0, 0));
- fbx_simple_property(DefaultCamera, std::string, "");
- enum FrameRate {
- FrameRate_DEFAULT = 0,
- FrameRate_120 = 1,
- FrameRate_100 = 2,
- FrameRate_60 = 3,
- FrameRate_50 = 4,
- FrameRate_48 = 5,
- FrameRate_30 = 6,
- FrameRate_30_DROP = 7,
- FrameRate_NTSC_DROP_FRAME = 8,
- FrameRate_NTSC_FULL_FRAME = 9,
- FrameRate_PAL = 10,
- FrameRate_CINEMA = 11,
- FrameRate_1000 = 12,
- FrameRate_CINEMA_ND = 13,
- FrameRate_CUSTOM = 14,
- FrameRate_MAX // end-of-enum sentinel
- };
- fbx_simple_enum_property(TimeMode, FrameRate, FrameRate_DEFAULT);
- fbx_simple_property(TimeSpanStart, uint64_t, 0L);
- fbx_simple_property(TimeSpanStop, uint64_t, 0L);
- fbx_simple_property(CustomFrameRate, float, -1.0f);
- private:
- const Document &doc;
- };
- /** DOM root for a FBX file */
- class Document {
- public:
- Document(const Parser &parser, const ImportSettings &settings);
- ~Document();
- LazyObject *GetObject(uint64_t id) const;
- bool IsSafeToImport() const {
- return SafeToImport;
- }
- bool IsBinary() const {
- return parser.IsBinary();
- }
- unsigned int FBXVersion() const {
- return fbxVersion;
- }
- const std::string &Creator() const {
- return creator;
- }
- // elements (in this order): Year, Month, Day, Hour, Second, Millisecond
- const unsigned int *CreationTimeStamp() const {
- return creationTimeStamp;
- }
- const FileGlobalSettings *GlobalSettingsPtr() const {
- return globals.get();
- }
- const PropertyTable &GetMetadataProperties() const {
- return metadata_properties;
- }
- const PropertyTemplateMap &Templates() const {
- return templates;
- }
- const ObjectMap &Objects() const {
- return objects;
- }
- const ImportSettings &Settings() const {
- return settings;
- }
- const ConnectionMap &ConnectionsBySource() const {
- return src_connections;
- }
- const ConnectionMap &ConnectionsByDestination() const {
- return dest_connections;
- }
- // note: the implicit rule in all DOM classes is to always resolve
- // from destination to source (since the FBX object hierarchy is,
- // with very few exceptions, a DAG, this avoids cycles). In all
- // cases that may involve back-facing edges in the object graph,
- // use LazyObject::IsBeingConstructed() to check.
- std::vector<const Connection *> GetConnectionsBySourceSequenced(uint64_t source) const;
- std::vector<const Connection *> GetConnectionsByDestinationSequenced(uint64_t dest) const;
- std::vector<const Connection *> GetConnectionsBySourceSequenced(uint64_t source, const char *classname) const;
- std::vector<const Connection *> GetConnectionsByDestinationSequenced(uint64_t dest, const char *classname) const;
- std::vector<const Connection *> GetConnectionsBySourceSequenced(uint64_t source,
- const char *const *classnames, size_t count) const;
- std::vector<const Connection *> GetConnectionsByDestinationSequenced(uint64_t dest,
- const char *const *classnames,
- size_t count) const;
- const std::vector<const AnimationStack *> &AnimationStacks() const;
- const std::vector<uint64_t> &GetAnimationStackIDs() const {
- return animationStacks;
- }
- const std::vector<uint64_t> &GetConstraintStackIDs() const {
- return constraints;
- }
- const std::vector<uint64_t> &GetBindPoseIDs() const {
- return bind_poses;
- };
- const std::vector<uint64_t> &GetMaterialIDs() const {
- return materials;
- };
- const std::vector<uint64_t> &GetSkinIDs() const {
- return skins;
- }
- private:
- std::vector<const Connection *> GetConnectionsSequenced(uint64_t id, const ConnectionMap &) const;
- std::vector<const Connection *> GetConnectionsSequenced(uint64_t id, bool is_src,
- const ConnectionMap &,
- const char *const *classnames,
- size_t count) const;
- bool ReadHeader();
- void ReadObjects();
- void ReadPropertyTemplates();
- void ReadConnections();
- void ReadGlobalSettings();
- private:
- const ImportSettings &settings;
- ObjectMap objects;
- const Parser &parser;
- bool SafeToImport = false;
- PropertyTemplateMap templates;
- ConnectionMap src_connections;
- ConnectionMap dest_connections;
- unsigned int fbxVersion = 0;
- std::string creator;
- unsigned int creationTimeStamp[7] = { 0 };
- std::vector<uint64_t> animationStacks;
- std::vector<uint64_t> bind_poses;
- // constraints aren't in the tree / at least they are not easy to access.
- std::vector<uint64_t> constraints;
- std::vector<uint64_t> materials;
- std::vector<uint64_t> skins;
- mutable std::vector<const AnimationStack *> animationStacksResolved;
- PropertyTable metadata_properties;
- std::shared_ptr<FileGlobalSettings> globals = nullptr;
- };
- } // namespace FBXDocParser
- namespace std {
- template <>
- struct hash<const FBXDocParser::Video> {
- std::size_t operator()(const FBXDocParser::Video &video) const {
- using std::hash;
- using std::size_t;
- using std::string;
- size_t res = 17;
- res = res * 31 + hash<string>()(video.Name());
- res = res * 31 + hash<string>()(video.RelativeFilename());
- res = res * 31 + hash<string>()(video.Type());
- return res;
- }
- };
- } // namespace std
- #endif // FBX_DOCUMENT_H
|