vrshoot

view libs/assimp/FBXDocument.h @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line source
1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
5 Copyright (c) 2006-2012, assimp team
6 All rights reserved.
8 Redistribution and use of this software in source and binary forms,
9 with or without modification, are permitted provided that the
10 following conditions are met:
12 * Redistributions of source code must retain the above
13 copyright notice, this list of conditions and the
14 following disclaimer.
16 * Redistributions in binary form must reproduce the above
17 copyright notice, this list of conditions and the
18 following disclaimer in the documentation and/or other
19 materials provided with the distribution.
21 * Neither the name of the assimp team, nor the names of its
22 contributors may be used to endorse or promote products
23 derived from this software without specific prior
24 written permission of the assimp team.
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 ----------------------------------------------------------------------
39 */
41 /** @file FBXDocument.h
42 * @brief FBX DOM
43 */
44 #ifndef INCLUDED_AI_FBX_DOCUMENT_H
45 #define INCLUDED_AI_FBX_DOCUMENT_H
47 #include <vector>
48 #include <map>
49 #include <string>
51 #include "FBXProperties.h"
53 namespace Assimp {
54 namespace FBX {
56 class Parser;
57 class Object;
58 struct ImportSettings;
60 class PropertyTable;
61 class Document;
62 class Material;
63 class Geometry;
65 class AnimationCurve;
66 class AnimationCurveNode;
67 class AnimationLayer;
68 class AnimationStack;
70 class Skin;
71 class Cluster;
74 /** Represents a delay-parsed FBX objects. Many objects in the scene
75 * are not needed by assimp, so it makes no sense to parse them
76 * upfront. */
77 class LazyObject
78 {
79 public:
81 LazyObject(uint64_t id, const Element& element, const Document& doc);
82 ~LazyObject();
84 public:
86 const Object* Get(bool dieOnError = false);
88 template <typename T>
89 const T* Get(bool dieOnError = false) {
90 const Object* const ob = Get(dieOnError);
91 return ob ? dynamic_cast<const T*>(ob) : NULL;
92 }
94 uint64_t ID() const {
95 return id;
96 }
98 bool IsBeingConstructed() const {
99 return (flags & BEING_CONSTRUCTED) != 0;
100 }
102 bool FailedToConstruct() const {
103 return (flags & FAILED_TO_CONSTRUCT) != 0;
104 }
106 const Element& GetElement() const {
107 return element;
108 }
110 const Document& GetDocument() const {
111 return doc;
112 }
114 private:
116 const Document& doc;
117 const Element& element;
118 boost::scoped_ptr<const Object> object;
120 const uint64_t id;
122 enum Flags {
123 BEING_CONSTRUCTED = 0x1,
124 FAILED_TO_CONSTRUCT = 0x2
125 };
127 unsigned int flags;
128 };
132 /** Base class for in-memory (DOM) representations of FBX objects */
133 class Object
134 {
135 public:
137 Object(uint64_t id, const Element& element, const std::string& name);
138 virtual ~Object();
140 public:
142 const Element& SourceElement() const {
143 return element;
144 }
146 const std::string& Name() const {
147 return name;
148 }
150 uint64_t ID() const {
151 return id;
152 }
154 protected:
155 const Element& element;
156 const std::string name;
157 const uint64_t id;
158 };
162 /** DOM class for generic FBX NoteAttribute blocks. NoteAttribute's just hold a property table,
163 * fixed members are added by deriving classes. */
164 class NodeAttribute : public Object
165 {
166 public:
168 NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name);
169 ~NodeAttribute();
171 public:
173 const PropertyTable& Props() const {
174 ai_assert(props.get());
175 return *props.get();
176 }
178 private:
180 boost::shared_ptr<const PropertyTable> props;
181 };
184 /** DOM base class for FBX camera settings attached to a node */
185 class CameraSwitcher : public NodeAttribute
186 {
187 public:
189 CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name);
190 ~CameraSwitcher();
192 public:
194 int CameraID() const {
195 return cameraId;
196 }
198 const std::string& CameraName() const {
199 return cameraName;
200 }
203 const std::string& CameraIndexName() const {
204 return cameraIndexName;
205 }
207 private:
209 int cameraId;
210 std::string cameraName;
211 std::string cameraIndexName;
212 };
215 #define fbx_stringize(a) #a
217 #define fbx_simple_property(name, type, default_value) \
218 type name() const { \
219 return PropertyGet<type>(Props(), fbx_stringize(name), (default_value)); \
220 }
222 // XXX improve logging
223 #define fbx_simple_enum_property(name, type, default_value) \
224 type name() const { \
225 const int ival = PropertyGet<int>(Props(), fbx_stringize(name), static_cast<int>(default_value)); \
226 if (ival < 0 || ival >= AI_CONCAT(type, _MAX)) { \
227 ai_assert(static_cast<int>(default_value) >= 0 && static_cast<int>(default_value) < AI_CONCAT(type, _MAX)); \
228 return static_cast<type>(default_value); \
229 } \
230 return static_cast<type>(ival); \
231 }
235 /** DOM base class for FBX cameras attached to a node */
236 class Camera : public NodeAttribute
237 {
238 public:
240 Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name);
241 ~Camera();
243 public:
245 fbx_simple_property(Position, aiVector3D, aiVector3D(0,0,0));
246 fbx_simple_property(UpVector, aiVector3D, aiVector3D(0,1,0));
247 fbx_simple_property(InterestPosition, aiVector3D, aiVector3D(0,0,0));
249 fbx_simple_property(AspectWidth, float, 1.0f);
250 fbx_simple_property(AspectHeight, float, 1.0f);
251 fbx_simple_property(FilmWidth, float, 1.0f);
252 fbx_simple_property(FilmHeight, float, 1.0f);
254 fbx_simple_property(FilmAspectRatio, float, 1.0f);
255 fbx_simple_property(ApertureMode, int, 0);
257 fbx_simple_property(FieldOfView, float, 1.0f);
258 fbx_simple_property(FocalLength, float, 1.0f);
260 private:
261 };
264 /** DOM base class for FBX null markers attached to a node */
265 class Null : public NodeAttribute
266 {
267 public:
269 Null(uint64_t id, const Element& element, const Document& doc, const std::string& name);
270 ~Null();
271 };
274 /** DOM base class for FBX limb node markers attached to a node */
275 class LimbNode : public NodeAttribute
276 {
277 public:
279 LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name);
280 ~LimbNode();
281 };
284 /** DOM base class for FBX lights attached to a node */
285 class Light : public NodeAttribute
286 {
287 public:
289 Light(uint64_t id, const Element& element, const Document& doc, const std::string& name);
290 ~Light();
292 public:
294 enum Type
295 {
296 Type_Point,
297 Type_Directional,
298 Type_Spot,
299 Type_Area,
300 Type_Volume,
302 Type_MAX // end-of-enum sentinel
303 };
305 enum Decay
306 {
307 Decay_None,
308 Decay_Linear,
309 Decay_Quadratic,
310 Decay_Cubic,
312 Decay_MAX // end-of-enum sentinel
313 };
315 public:
317 fbx_simple_property(Color, aiVector3D, aiVector3D(1,1,1));
318 fbx_simple_enum_property(LightType, Type, 0);
319 fbx_simple_property(CastLightOnObject, bool, false);
320 fbx_simple_property(DrawVolumetricLight, bool, true);
321 fbx_simple_property(DrawGroundProjection, bool, true);
322 fbx_simple_property(DrawFrontFacingVolumetricLight, bool, false);
323 fbx_simple_property(Intensity, float, 1.0f);
324 fbx_simple_property(InnerAngle, float, 0.0f);
325 fbx_simple_property(OuterAngle, float, 45.0f);
326 fbx_simple_property(Fog, int, 50);
327 fbx_simple_enum_property(DecayType, Decay, 0);
328 fbx_simple_property(DecayStart, int, 0);
329 fbx_simple_property(FileName, std::string, "");
331 fbx_simple_property(EnableNearAttenuation, bool, false);
332 fbx_simple_property(NearAttenuationStart, float, 0.0f);
333 fbx_simple_property(NearAttenuationEnd, float, 0.0f);
334 fbx_simple_property(EnableFarAttenuation, bool, false);
335 fbx_simple_property(FarAttenuationStart, float, 0.0f);
336 fbx_simple_property(FarAttenuationEnd, float, 0.0f);
338 fbx_simple_property(CastShadows, bool, true);
339 fbx_simple_property(ShadowColor, aiVector3D, aiVector3D(0,0,0));
341 fbx_simple_property(AreaLightShape, int, 0);
343 fbx_simple_property(LeftBarnDoor, float, 20.0f);
344 fbx_simple_property(RightBarnDoor, float, 20.0f);
345 fbx_simple_property(TopBarnDoor, float, 20.0f);
346 fbx_simple_property(BottomBarnDoor, float, 20.0f);
347 fbx_simple_property(EnableBarnDoor, bool, true);
350 private:
351 };
354 /** DOM base class for FBX models (even though its semantics are more "node" than "model" */
355 class Model : public Object
356 {
357 public:
359 Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
360 ~Model();
362 public:
364 enum RotOrder
365 {
366 RotOrder_EulerXYZ = 0,
367 RotOrder_EulerXZY,
368 RotOrder_EulerYZX,
369 RotOrder_EulerYXZ,
370 RotOrder_EulerZXY,
371 RotOrder_EulerZYX,
373 RotOrder_SphericXYZ,
375 RotOrder_MAX // end-of-enum sentinel
376 };
379 enum TransformInheritance
380 {
381 TransformInheritance_RrSs = 0,
382 TransformInheritance_RSrs,
383 TransformInheritance_Rrs,
385 TransformInheritance_MAX // end-of-enum sentinel
386 };
388 public:
390 fbx_simple_property(QuaternionInterpolate, int, 0);
392 fbx_simple_property(RotationOffset, aiVector3D, aiVector3D());
393 fbx_simple_property(RotationPivot, aiVector3D, aiVector3D());
394 fbx_simple_property(ScalingOffset, aiVector3D, aiVector3D());
395 fbx_simple_property(ScalingPivot, aiVector3D, aiVector3D());
396 fbx_simple_property(TranslationActive, bool, false);
398 fbx_simple_property(TranslationMin, aiVector3D, aiVector3D());
399 fbx_simple_property(TranslationMax, aiVector3D, aiVector3D());
401 fbx_simple_property(TranslationMinX, bool, false);
402 fbx_simple_property(TranslationMaxX, bool, false);
403 fbx_simple_property(TranslationMinY, bool, false);
404 fbx_simple_property(TranslationMaxY, bool, false);
405 fbx_simple_property(TranslationMinZ, bool, false);
406 fbx_simple_property(TranslationMaxZ, bool, false);
408 fbx_simple_enum_property(RotationOrder, RotOrder, 0);
409 fbx_simple_property(RotationSpaceForLimitOnly, bool, false);
410 fbx_simple_property(RotationStiffnessX, float, 0.0f);
411 fbx_simple_property(RotationStiffnessY, float, 0.0f);
412 fbx_simple_property(RotationStiffnessZ, float, 0.0f);
413 fbx_simple_property(AxisLen, float, 0.0f);
415 fbx_simple_property(PreRotation, aiVector3D, aiVector3D());
416 fbx_simple_property(PostRotation, aiVector3D, aiVector3D());
417 fbx_simple_property(RotationActive, bool, false);
419 fbx_simple_property(RotationMin, aiVector3D, aiVector3D());
420 fbx_simple_property(RotationMax, aiVector3D, aiVector3D());
422 fbx_simple_property(RotationMinX, bool, false);
423 fbx_simple_property(RotationMaxX, bool, false);
424 fbx_simple_property(RotationMinY, bool, false);
425 fbx_simple_property(RotationMaxY, bool, false);
426 fbx_simple_property(RotationMinZ, bool, false);
427 fbx_simple_property(RotationMaxZ, bool, false);
428 fbx_simple_enum_property(InheritType, TransformInheritance, 0);
430 fbx_simple_property(ScalingActive, bool, false);
431 fbx_simple_property(ScalingMin, aiVector3D, aiVector3D());
432 fbx_simple_property(ScalingMax, aiVector3D, aiVector3D(1.f,1.f,1.f));
433 fbx_simple_property(ScalingMinX, bool, false);
434 fbx_simple_property(ScalingMaxX, bool, false);
435 fbx_simple_property(ScalingMinY, bool, false);
436 fbx_simple_property(ScalingMaxY, bool, false);
437 fbx_simple_property(ScalingMinZ, bool, false);
438 fbx_simple_property(ScalingMaxZ, bool, false);
440 fbx_simple_property(GeometricTranslation, aiVector3D, aiVector3D());
441 fbx_simple_property(GeometricRotation, aiVector3D, aiVector3D());
442 fbx_simple_property(GeometricScaling, aiVector3D, aiVector3D(1.f, 1.f, 1.f));
444 fbx_simple_property(MinDampRangeX, float, 0.0f);
445 fbx_simple_property(MinDampRangeY, float, 0.0f);
446 fbx_simple_property(MinDampRangeZ, float, 0.0f);
447 fbx_simple_property(MaxDampRangeX, float, 0.0f);
448 fbx_simple_property(MaxDampRangeY, float, 0.0f);
449 fbx_simple_property(MaxDampRangeZ, float, 0.0f);
451 fbx_simple_property(MinDampStrengthX, float, 0.0f);
452 fbx_simple_property(MinDampStrengthY, float, 0.0f);
453 fbx_simple_property(MinDampStrengthZ, float, 0.0f);
454 fbx_simple_property(MaxDampStrengthX, float, 0.0f);
455 fbx_simple_property(MaxDampStrengthY, float, 0.0f);
456 fbx_simple_property(MaxDampStrengthZ, float, 0.0f);
458 fbx_simple_property(PreferredAngleX, float, 0.0f);
459 fbx_simple_property(PreferredAngleY, float, 0.0f);
460 fbx_simple_property(PreferredAngleZ, float, 0.0f);
462 fbx_simple_property(Show, bool, true);
463 fbx_simple_property(LODBox, bool, false);
464 fbx_simple_property(Freeze, bool, false);
466 public:
468 const std::string& Shading() const {
469 return shading;
470 }
472 const std::string& Culling() const {
473 return culling;
474 }
476 const PropertyTable& Props() const {
477 ai_assert(props.get());
478 return *props.get();
479 }
481 /** Get material links */
482 const std::vector<const Material*>& GetMaterials() const {
483 return materials;
484 }
487 /** Get geometry links */
488 const std::vector<const Geometry*>& GetGeometry() const {
489 return geometry;
490 }
493 /** Get node attachments */
494 const std::vector<const NodeAttribute*>& GetAttributes() const {
495 return attributes;
496 }
498 public:
500 /** convenience method to check if the node has a Null node marker */
501 bool IsNull() const;
504 private:
506 void ResolveLinks(const Element& element, const Document& doc);
508 private:
510 std::vector<const Material*> materials;
511 std::vector<const Geometry*> geometry;
512 std::vector<const NodeAttribute*> attributes;
514 std::string shading;
515 std::string culling;
516 boost::shared_ptr<const PropertyTable> props;
517 };
521 /** DOM class for generic FBX textures */
522 class Texture : public Object
523 {
524 public:
526 Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name);
527 ~Texture();
529 public:
531 const std::string& Type() const {
532 return type;
533 }
535 const std::string& FileName() const {
536 return fileName;
537 }
539 const std::string& RelativeFilename() const {
540 return relativeFileName;
541 }
543 const std::string& AlphaSource() const {
544 return alphaSource;
545 }
547 const aiVector2D& UVTranslation() const {
548 return uvTrans;
549 }
551 const aiVector2D& UVScaling() const {
552 return uvScaling;
553 }
555 const PropertyTable& Props() const {
556 ai_assert(props.get());
557 return *props.get();
558 }
560 // return a 4-tuple
561 const unsigned int* Crop() const {
562 return crop;
563 }
565 private:
567 aiVector2D uvTrans;
568 aiVector2D uvScaling;
570 std::string type;
571 std::string relativeFileName;
572 std::string fileName;
573 std::string alphaSource;
574 boost::shared_ptr<const PropertyTable> props;
576 unsigned int crop[4];
577 };
580 typedef std::fbx_unordered_map<std::string, const Texture*> TextureMap;
583 /** DOM class for generic FBX materials */
584 class Material : public Object
585 {
586 public:
588 Material(uint64_t id, const Element& element, const Document& doc, const std::string& name);
589 ~Material();
591 public:
593 const std::string& GetShadingModel() const {
594 return shading;
595 }
597 bool IsMultilayer() const {
598 return multilayer;
599 }
601 const PropertyTable& Props() const {
602 ai_assert(props.get());
603 return *props.get();
604 }
606 const TextureMap& Textures() const {
607 return textures;
608 }
610 private:
612 std::string shading;
613 bool multilayer;
614 boost::shared_ptr<const PropertyTable> props;
616 TextureMap textures;
617 };
620 /** DOM base class for all kinds of FBX geometry */
621 class Geometry : public Object
622 {
623 public:
625 Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc);
626 ~Geometry();
628 public:
630 /** Get the Skin attached to this geometry or NULL */
631 const Skin* const DeformerSkin() const {
632 return skin;
633 }
635 private:
637 const Skin* skin;
638 };
641 typedef std::vector<int> MatIndexArray;
644 /** DOM class for FBX geometry of type "Mesh"*/
645 class MeshGeometry : public Geometry
646 {
648 public:
650 MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc);
651 ~MeshGeometry();
653 public:
655 /** Get a list of all vertex points, non-unique*/
656 const std::vector<aiVector3D>& GetVertices() const {
657 return vertices;
658 }
660 /** Get a list of all vertex normals or an empty array if
661 * no normals are specified. */
662 const std::vector<aiVector3D>& GetNormals() const {
663 return normals;
664 }
666 /** Get a list of all vertex tangents or an empty array
667 * if no tangents are specified */
668 const std::vector<aiVector3D>& GetTangents() const {
669 return tangents;
670 }
672 /** Get a list of all vertex binormals or an empty array
673 * if no binormals are specified */
674 const std::vector<aiVector3D>& GetBinormals() const {
675 return binormals;
676 }
678 /** Return list of faces - each entry denotes a face and specifies
679 * how many vertices it has. Vertices are taken from the
680 * vertex data arrays in sequential order. */
681 const std::vector<unsigned int>& GetFaceIndexCounts() const {
682 return faces;
683 }
685 /** Get a UV coordinate slot, returns an empty array if
686 * the requested slot does not exist. */
687 const std::vector<aiVector2D>& GetTextureCoords(unsigned int index) const {
688 static const std::vector<aiVector2D> empty;
689 return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : uvs[index];
690 }
693 /** Get a UV coordinate slot, returns an empty array if
694 * the requested slot does not exist. */
695 std::string GetTextureCoordChannelName(unsigned int index) const {
696 return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? "" : uvNames[index];
697 }
699 /** Get a vertex color coordinate slot, returns an empty array if
700 * the requested slot does not exist. */
701 const std::vector<aiColor4D>& GetVertexColors(unsigned int index) const {
702 static const std::vector<aiColor4D> empty;
703 return index >= AI_MAX_NUMBER_OF_COLOR_SETS ? empty : colors[index];
704 }
707 /** Get per-face-vertex material assignments */
708 const MatIndexArray& GetMaterialIndices() const {
709 return materials;
710 }
713 /** Convert from a fbx file vertex index (for example from a #Cluster weight) or NULL
714 * if the vertex index is not valid. */
715 const unsigned int* ToOutputVertexIndex(unsigned int in_index, unsigned int& count) const {
716 if(in_index >= mapping_counts.size()) {
717 return NULL;
718 }
720 ai_assert(mapping_counts.size() == mapping_offsets.size());
721 count = mapping_counts[in_index];
723 ai_assert(count != 0);
724 ai_assert(mapping_offsets[in_index] + count <= mappings.size());
726 return &mappings[mapping_offsets[in_index]];
727 }
730 /** Determine the face to which a particular output vertex index belongs.
731 * This mapping is always unique. */
732 unsigned int FaceForVertexIndex(unsigned int in_index) const {
733 ai_assert(in_index < vertices.size());
735 // in the current conversion pattern this will only be needed if
736 // weights are present, so no need to always pre-compute this table
737 if (facesVertexStartIndices.empty()) {
738 facesVertexStartIndices.resize(faces.size() + 1, 0);
740 std::partial_sum(faces.begin(), faces.end(), facesVertexStartIndices.begin() + 1);
741 facesVertexStartIndices.pop_back();
742 }
744 ai_assert(facesVertexStartIndices.size() == faces.size());
745 const std::vector<unsigned int>::iterator it = std::upper_bound(
746 facesVertexStartIndices.begin(),
747 facesVertexStartIndices.end(),
748 in_index
749 );
751 return static_cast<unsigned int>(std::distance(facesVertexStartIndices.begin(), it - 1));
752 }
754 public:
756 private:
758 void ReadLayer(const Scope& layer);
759 void ReadLayerElement(const Scope& layerElement);
760 void ReadVertexData(const std::string& type, int index, const Scope& source);
762 void ReadVertexDataUV(std::vector<aiVector2D>& uv_out, const Scope& source,
763 const std::string& MappingInformationType,
764 const std::string& ReferenceInformationType);
766 void ReadVertexDataNormals(std::vector<aiVector3D>& normals_out, const Scope& source,
767 const std::string& MappingInformationType,
768 const std::string& ReferenceInformationType);
770 void ReadVertexDataColors(std::vector<aiColor4D>& colors_out, const Scope& source,
771 const std::string& MappingInformationType,
772 const std::string& ReferenceInformationType);
774 void ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source,
775 const std::string& MappingInformationType,
776 const std::string& ReferenceInformationType);
778 void ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_out, const Scope& source,
779 const std::string& MappingInformationType,
780 const std::string& ReferenceInformationType);
782 void ReadVertexDataMaterials(MatIndexArray& materials_out, const Scope& source,
783 const std::string& MappingInformationType,
784 const std::string& ReferenceInformationType);
786 private:
788 // cached data arrays
789 MatIndexArray materials;
790 std::vector<aiVector3D> vertices;
791 std::vector<unsigned int> faces;
792 mutable std::vector<unsigned int> facesVertexStartIndices;
793 std::vector<aiVector3D> tangents;
794 std::vector<aiVector3D> binormals;
795 std::vector<aiVector3D> normals;
797 std::string uvNames[AI_MAX_NUMBER_OF_TEXTURECOORDS];
798 std::vector<aiVector2D> uvs[AI_MAX_NUMBER_OF_TEXTURECOORDS];
799 std::vector<aiColor4D> colors[AI_MAX_NUMBER_OF_COLOR_SETS];
801 std::vector<unsigned int> mapping_counts;
802 std::vector<unsigned int> mapping_offsets;
803 std::vector<unsigned int> mappings;
804 };
806 typedef std::vector<uint64_t> KeyTimeList;
807 typedef std::vector<float> KeyValueList;
809 /** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefor) */
810 class AnimationCurve : public Object
811 {
812 public:
814 AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc);
815 ~AnimationCurve();
817 public:
819 /** get list of keyframe positions (time).
820 * Invariant: |GetKeys()| > 0 */
821 const KeyTimeList& GetKeys() const {
822 return keys;
823 }
826 /** get list of keyframe values.
827 * Invariant: |GetKeys()| == |GetValues()| && |GetKeys()| > 0*/
828 const KeyValueList& GetValues() const {
829 return values;
830 }
833 const std::vector<float>& GetAttributes() const {
834 return attributes;
835 }
837 const std::vector<unsigned int>& GetFlags() const {
838 return flags;
839 }
841 private:
843 KeyTimeList keys;
844 KeyValueList values;
845 std::vector<float> attributes;
846 std::vector<unsigned int> flags;
847 };
849 // property-name -> animation curve
850 typedef std::map<std::string, const AnimationCurve*> AnimationCurveMap;
853 /** Represents a FBX animation curve (i.e. a mapping from single animation curves to nodes) */
854 class AnimationCurveNode : public Object
855 {
856 public:
858 /* the optional whitelist specifies a list of property names for which the caller
859 wants animations for. If the curve node does not match one of these, std::range_error
860 will be thrown. */
861 AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
862 const char* const * target_prop_whitelist = NULL, size_t whitelist_size = 0);
864 ~AnimationCurveNode();
866 public:
868 const PropertyTable& Props() const {
869 ai_assert(props.get());
870 return *props.get();
871 }
874 const AnimationCurveMap& Curves() const;
876 /** Object the curve is assigned to, this can be NULL if the
877 * target object has no DOM representation or could not
878 * be read for other reasons.*/
879 const Object* Target() const {
880 return target;
881 }
883 const Model* TargetAsModel() const {
884 return dynamic_cast<const Model*>(target);
885 }
887 const NodeAttribute* TargetAsNodeAttribute() const {
888 return dynamic_cast<const NodeAttribute*>(target);
889 }
891 /** Property of Target() that is being animated*/
892 const std::string& TargetProperty() const {
893 return prop;
894 }
896 private:
898 const Object* target;
899 boost::shared_ptr<const PropertyTable> props;
900 mutable AnimationCurveMap curves;
902 std::string prop;
903 const Document& doc;
904 };
906 typedef std::vector<const AnimationCurveNode*> AnimationCurveNodeList;
909 /** Represents a FBX animation layer (i.e. a list of node animations) */
910 class AnimationLayer : public Object
911 {
912 public:
915 AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc);
916 ~AnimationLayer();
918 public:
920 const PropertyTable& Props() const {
921 ai_assert(props.get());
922 return *props.get();
923 }
925 /* the optional whitelist specifies a list of property names for which the caller
926 wants animations for. Curves not matching this list will not be added to the
927 animation layer. */
928 AnimationCurveNodeList Nodes(const char* const * target_prop_whitelist = NULL, size_t whitelist_size = 0) const;
930 private:
932 boost::shared_ptr<const PropertyTable> props;
933 const Document& doc;
934 };
937 typedef std::vector<const AnimationLayer*> AnimationLayerList;
940 /** Represents a FBX animation stack (i.e. a list of animation layers) */
941 class AnimationStack : public Object
942 {
943 public:
945 AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
946 ~AnimationStack();
948 public:
950 fbx_simple_property(LocalStart, uint64_t, 0L);
951 fbx_simple_property(LocalStop, uint64_t, 0L);
952 fbx_simple_property(ReferenceStart, uint64_t, 0L);
953 fbx_simple_property(ReferenceStop, uint64_t, 0L);
957 const PropertyTable& Props() const {
958 ai_assert(props.get());
959 return *props.get();
960 }
963 const AnimationLayerList& Layers() const {
964 return layers;
965 }
967 private:
969 boost::shared_ptr<const PropertyTable> props;
970 AnimationLayerList layers;
971 };
974 /** DOM class for deformers */
975 class Deformer : public Object
976 {
977 public:
979 Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name);
980 ~Deformer();
982 public:
984 const PropertyTable& Props() const {
985 ai_assert(props.get());
986 return *props.get();
987 }
989 private:
991 boost::shared_ptr<const PropertyTable> props;
992 };
994 typedef std::vector<float> WeightArray;
995 typedef std::vector<unsigned int> WeightIndexArray;
998 /** DOM class for skin deformer clusters (aka subdeformers) */
999 class Cluster : public Deformer
1001 public:
1003 Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name);
1004 ~Cluster();
1006 public:
1008 /** get the list of deformer weights associated with this cluster.
1009 * Use #GetIndices() to get the associated vertices. Both arrays
1010 * have the same size (and may also be empty). */
1011 const WeightArray& GetWeights() const {
1012 return weights;
1015 /** get indices into the vertex data of the geometry associated
1016 * with this cluster. Use #GetWeights() to get the associated weights.
1017 * Both arrays have the same size (and may also be empty). */
1018 const WeightIndexArray& GetIndices() const {
1019 return indices;
1022 /** */
1023 const aiMatrix4x4& Transform() const {
1024 return transform;
1027 const aiMatrix4x4& TransformLink() const {
1028 return transformLink;
1031 const Model* const TargetNode() const {
1032 return node;
1035 private:
1037 WeightArray weights;
1038 WeightIndexArray indices;
1040 aiMatrix4x4 transform;
1041 aiMatrix4x4 transformLink;
1043 const Model* node;
1044 };
1048 /** DOM class for skin deformers */
1049 class Skin : public Deformer
1051 public:
1053 Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name);
1054 ~Skin();
1056 public:
1058 float DeformAccuracy() const {
1059 return accuracy;
1063 const std::vector<const Cluster*>& Clusters() const {
1064 return clusters;
1067 private:
1069 float accuracy;
1070 std::vector<const Cluster*> clusters;
1071 };
1075 /** Represents a link between two FBX objects. */
1076 class Connection
1078 public:
1080 Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string& prop, const Document& doc);
1081 ~Connection();
1083 // note: a connection ensures that the source and dest objects exist, but
1084 // not that they have DOM representations, so the return value of one of
1085 // these functions can still be NULL.
1086 const Object* SourceObject() const;
1087 const Object* DestinationObject() const;
1089 // these, however, are always guaranteed to be valid
1090 LazyObject& LazySourceObject() const;
1091 LazyObject& LazyDestinationObject() const;
1094 /** return the name of the property the connection is attached to.
1095 * this is an empty string for object to object (OO) connections. */
1096 const std::string& PropertyName() const {
1097 return prop;
1100 uint64_t InsertionOrder() const {
1101 return insertionOrder;
1104 int CompareTo(const Connection* c) const {
1105 // note: can't subtract because this would overflow uint64_t
1106 if(InsertionOrder() > c->InsertionOrder()) {
1107 return 1;
1109 else if(InsertionOrder() < c->InsertionOrder()) {
1110 return -1;
1112 return 0;
1115 bool Compare(const Connection* c) const {
1116 return InsertionOrder() < c->InsertionOrder();
1119 public:
1121 uint64_t insertionOrder;
1122 const std::string prop;
1124 uint64_t src, dest;
1125 const Document& doc;
1126 };
1129 // XXX again, unique_ptr would be useful. shared_ptr is too
1130 // bloated since the objects have a well-defined single owner
1131 // during their entire lifetime (Document). FBX files have
1132 // up to many thousands of objects (most of which we never use),
1133 // so the memory overhead for them should be kept at a minimum.
1134 typedef std::map<uint64_t, LazyObject*> ObjectMap;
1135 typedef std::fbx_unordered_map<std::string, boost::shared_ptr<const PropertyTable> > PropertyTemplateMap;
1138 typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
1141 /** DOM class for global document settings, a single instance per document can
1142 * be accessed via Document.Globals(). */
1143 class FileGlobalSettings
1145 public:
1147 FileGlobalSettings(const Document& doc, boost::shared_ptr<const PropertyTable> props);
1148 ~FileGlobalSettings();
1150 public:
1152 const PropertyTable& Props() const {
1153 ai_assert(props.get());
1154 return *props.get();
1157 const Document& GetDocument() const {
1158 return doc;
1162 fbx_simple_property(UpAxis, int, 1);
1163 fbx_simple_property(UpAxisSign, int, 1);
1164 fbx_simple_property(FrontAxis, int, 2);
1165 fbx_simple_property(FrontAxisSign, int, 1);
1166 fbx_simple_property(CoordAxis, int, 0);
1167 fbx_simple_property(CoordAxisSign, int, 1);
1168 fbx_simple_property(OriginalUpAxis, int, 0);
1169 fbx_simple_property(OriginalUpAxisSign, int, 1);
1170 fbx_simple_property(UnitScaleFactor, double, 1);
1171 fbx_simple_property(OriginalUnitScaleFactor, double, 1);
1172 fbx_simple_property(AmbientColor, aiVector3D, aiVector3D(0,0,0));
1173 fbx_simple_property(DefaultCamera, std::string, "");
1176 enum FrameRate {
1177 FrameRate_DEFAULT = 0,
1178 FrameRate_120 = 1,
1179 FrameRate_100 = 2,
1180 FrameRate_60 = 3,
1181 FrameRate_50 = 4,
1182 FrameRate_48 = 5,
1183 FrameRate_30 = 6,
1184 FrameRate_30_DROP = 7,
1185 FrameRate_NTSC_DROP_FRAME = 8,
1186 FrameRate_NTSC_FULL_FRAME = 9,
1187 FrameRate_PAL = 10,
1188 FrameRate_CINEMA = 11,
1189 FrameRate_1000 = 12,
1190 FrameRate_CINEMA_ND = 13,
1191 FrameRate_CUSTOM = 14,
1193 FrameRate_MAX// end-of-enum sentinel
1194 };
1196 fbx_simple_enum_property(TimeMode, FrameRate, FrameRate_DEFAULT);
1197 fbx_simple_property(TimeSpanStart, uint64_t, 0L);
1198 fbx_simple_property(TimeSpanStop, uint64_t, 0L);
1199 fbx_simple_property(CustomFrameRate, float, -1.0f);
1202 private:
1204 boost::shared_ptr<const PropertyTable> props;
1205 const Document& doc;
1206 };
1211 /** DOM root for a FBX file */
1212 class Document
1214 public:
1216 Document(const Parser& parser, const ImportSettings& settings);
1217 ~Document();
1219 public:
1221 LazyObject* GetObject(uint64_t id) const;
1223 bool IsBinary() const {
1224 return parser.IsBinary();
1227 unsigned int FBXVersion() const {
1228 return fbxVersion;
1231 const std::string& Creator() const {
1232 return creator;
1235 // elements (in this order): Uear, Month, Day, Hour, Second, Millisecond
1236 const unsigned int* CreationTimeStamp() const {
1237 return creationTimeStamp;
1240 const FileGlobalSettings& GlobalSettings() const {
1241 ai_assert(globals.get());
1242 return *globals.get();
1245 const PropertyTemplateMap& Templates() const {
1246 return templates;
1249 const ObjectMap& Objects() const {
1250 return objects;
1253 const ImportSettings& Settings() const {
1254 return settings;
1257 const ConnectionMap& ConnectionsBySource() const {
1258 return src_connections;
1261 const ConnectionMap& ConnectionsByDestination() const {
1262 return dest_connections;
1265 // note: the implicit rule in all DOM classes is to always resolve
1266 // from destination to source (since the FBX object hierarchy is,
1267 // with very few exceptions, a DAG, this avoids cycles). In all
1268 // cases that may involve back-facing edges in the object graph,
1269 // use LazyObject::IsBeingConstructed() to check.
1271 std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source) const;
1272 std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest) const;
1274 std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source, const char* classname) const;
1275 std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest, const char* classname) const;
1277 std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source,
1278 const char* const* classnames, size_t count) const;
1279 std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest,
1280 const char* const* classnames,
1281 size_t count) const;
1283 const std::vector<const AnimationStack*>& AnimationStacks() const;
1285 private:
1287 std::vector<const Connection*> GetConnectionsSequenced(uint64_t id, const ConnectionMap&) const;
1288 std::vector<const Connection*> GetConnectionsSequenced(uint64_t id, bool is_src,
1289 const ConnectionMap&,
1290 const char* const* classnames,
1291 size_t count) const;
1293 private:
1295 void ReadHeader();
1296 void ReadObjects();
1297 void ReadPropertyTemplates();
1298 void ReadConnections();
1299 void ReadGlobalSettings();
1301 private:
1303 const ImportSettings& settings;
1305 ObjectMap objects;
1306 const Parser& parser;
1308 PropertyTemplateMap templates;
1309 ConnectionMap src_connections;
1310 ConnectionMap dest_connections;
1312 unsigned int fbxVersion;
1313 std::string creator;
1314 unsigned int creationTimeStamp[7];
1316 std::vector<uint64_t> animationStacks;
1317 mutable std::vector<const AnimationStack*> animationStacksResolved;
1319 boost::scoped_ptr<FileGlobalSettings> globals;
1320 };
1325 #endif