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