mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-12 15:14:35 +00:00
update assimp to 6.0.5
This commit is contained in:
parent
2d2eb57e2e
commit
f5cf21cfeb
941 changed files with 22718 additions and 12240 deletions
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -143,31 +143,33 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element &element, cons
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const AnimationCurveMap &AnimationCurveNode::Curves() const {
|
||||
if (curves.empty()) {
|
||||
// resolve attached animation curves
|
||||
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "AnimationCurve");
|
||||
if (!curves.empty()) {
|
||||
return curves;
|
||||
}
|
||||
|
||||
for (const Connection *con : conns) {
|
||||
// resolve attached animation curves
|
||||
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "AnimationCurve");
|
||||
|
||||
// link should go for a property
|
||||
if (!con->PropertyName().length()) {
|
||||
continue;
|
||||
}
|
||||
for (const Connection *con : conns) {
|
||||
|
||||
const Object *const ob = con->SourceObject();
|
||||
if (nullptr == ob) {
|
||||
DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring", &element);
|
||||
continue;
|
||||
}
|
||||
|
||||
const AnimationCurve *const anim = dynamic_cast<const AnimationCurve *>(ob);
|
||||
if (nullptr == anim) {
|
||||
DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve", &element);
|
||||
continue;
|
||||
}
|
||||
|
||||
curves[con->PropertyName()] = anim;
|
||||
// link should go for a property
|
||||
if (!con->PropertyName().length()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const Object *const ob = con->SourceObject();
|
||||
if (nullptr == ob) {
|
||||
DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring", &element);
|
||||
continue;
|
||||
}
|
||||
|
||||
const AnimationCurve *const anim = dynamic_cast<const AnimationCurve *>(ob);
|
||||
if (nullptr == anim) {
|
||||
DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve", &element);
|
||||
continue;
|
||||
}
|
||||
|
||||
curves[con->PropertyName()] = anim;
|
||||
}
|
||||
|
||||
return curves;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -60,58 +59,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
||||
//enum Flag
|
||||
//{
|
||||
// e_unknown_0 = 1 << 0,
|
||||
// e_unknown_1 = 1 << 1,
|
||||
// e_unknown_2 = 1 << 2,
|
||||
// e_unknown_3 = 1 << 3,
|
||||
// e_unknown_4 = 1 << 4,
|
||||
// e_unknown_5 = 1 << 5,
|
||||
// e_unknown_6 = 1 << 6,
|
||||
// e_unknown_7 = 1 << 7,
|
||||
// e_unknown_8 = 1 << 8,
|
||||
// e_unknown_9 = 1 << 9,
|
||||
// e_unknown_10 = 1 << 10,
|
||||
// e_unknown_11 = 1 << 11,
|
||||
// e_unknown_12 = 1 << 12,
|
||||
// e_unknown_13 = 1 << 13,
|
||||
// e_unknown_14 = 1 << 14,
|
||||
// e_unknown_15 = 1 << 15,
|
||||
// e_unknown_16 = 1 << 16,
|
||||
// e_unknown_17 = 1 << 17,
|
||||
// e_unknown_18 = 1 << 18,
|
||||
// e_unknown_19 = 1 << 19,
|
||||
// e_unknown_20 = 1 << 20,
|
||||
// e_unknown_21 = 1 << 21,
|
||||
// e_unknown_22 = 1 << 22,
|
||||
// e_unknown_23 = 1 << 23,
|
||||
// e_flag_field_size_64_bit = 1 << 24, // Not sure what is
|
||||
// e_unknown_25 = 1 << 25,
|
||||
// e_unknown_26 = 1 << 26,
|
||||
// e_unknown_27 = 1 << 27,
|
||||
// e_unknown_28 = 1 << 28,
|
||||
// e_unknown_29 = 1 << 29,
|
||||
// e_unknown_30 = 1 << 30,
|
||||
// e_unknown_31 = 1 << 31
|
||||
//};
|
||||
//
|
||||
//bool check_flag(uint32_t flags, Flag to_check)
|
||||
//{
|
||||
// return (flags & to_check) != 0;
|
||||
//}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Token::Token(const char* sbegin, const char* send, TokenType type, size_t offset)
|
||||
:
|
||||
#ifdef DEBUG
|
||||
contents(sbegin, static_cast<size_t>(send-sbegin)),
|
||||
#endif
|
||||
sbegin(sbegin)
|
||||
, send(send)
|
||||
, type(type)
|
||||
, line(offset)
|
||||
, column(BINARY_MARKER)
|
||||
{
|
||||
Token::Token(const char* sbegin, const char* send, TokenType type, size_t offset) :
|
||||
#ifdef DEBUG
|
||||
contents(sbegin, static_cast<size_t>(send-sbegin)),
|
||||
#endif
|
||||
sbegin(sbegin),
|
||||
send(send),
|
||||
type(type),
|
||||
line(offset),
|
||||
column(BINARY_MARKER) {
|
||||
ai_assert(sbegin);
|
||||
ai_assert(send);
|
||||
|
||||
|
|
@ -134,7 +91,9 @@ AI_WONT_RETURN void TokenizeError(const std::string& message, size_t offset)
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
size_t Offset(const char* begin, const char* cursor) {
|
||||
ai_assert(begin <= cursor);
|
||||
if (begin > cursor) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cursor - begin;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -47,11 +47,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
namespace Assimp::FBX {
|
||||
|
||||
static constexpr size_t NumNullRecords = 25;
|
||||
const char NULL_RECORD[NumNullRecords] = { // 25 null bytes in 64-bit and 13 null bytes in 32-bit
|
||||
|
||||
constexpr char NULL_RECORD[NumNullRecords] = { // 25 null bytes in 64-bit and 13 null bytes in 32-bit
|
||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
|
||||
}; // who knows why, it looks like two integers 32/64 bit (compressed and uncompressed sizes?) + 1 byte (might be compression type?)
|
||||
|
|
@ -83,8 +83,7 @@ enum TransformInheritance {
|
|||
TransformInheritance_MAX // end-of-enum sentinel
|
||||
};
|
||||
|
||||
} // namespace FBX
|
||||
} // namespace Assimp
|
||||
} // namespace Assimp::FBX
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <set>
|
||||
|
||||
//
|
||||
#if _MSC_VER > 1500 || (defined __GNUC___)
|
||||
#if _MSC_VER > 1500 || (defined __GNUC__)
|
||||
# define ASSIMP_FBX_USE_UNORDERED_MULTIMAP
|
||||
# else
|
||||
# define fbx_unordered_map map
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ std::string FBXConverter::MakeUniqueNodeName(const Model *const model, const aiN
|
|||
/// When a node becomes a child of another node, that node becomes its owner and mOwnership should be released.
|
||||
struct FBXConverter::PotentialNode {
|
||||
PotentialNode() : mOwnership(new aiNode), mNode(mOwnership.get()) {}
|
||||
PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
|
||||
explicit PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
|
||||
aiNode* operator->() { return mNode; }
|
||||
std::unique_ptr<aiNode> mOwnership;
|
||||
aiNode* mNode;
|
||||
|
|
@ -438,7 +438,8 @@ void FBXConverter::ConvertLight(const Light &light, const std::string &orig_name
|
|||
out_light->mType = aiLightSource_UNDEFINED;
|
||||
break;
|
||||
default:
|
||||
ai_assert(false);
|
||||
FBXImporter::LogError("Not handled light type: ", light.LightType());
|
||||
break;
|
||||
}
|
||||
|
||||
float decay = light.DecayStart();
|
||||
|
|
@ -463,7 +464,7 @@ void FBXConverter::ConvertLight(const Light &light, const std::string &orig_name
|
|||
out_light->mAttenuationQuadratic = 1.0f;
|
||||
break;
|
||||
default:
|
||||
ai_assert(false);
|
||||
FBXImporter::LogError("Not handled light decay type: ", light.DecayType());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -601,7 +602,7 @@ const char *FBXConverter::NameTransformationCompProperty(TransformationComp comp
|
|||
return "GeometricRotationInverse";
|
||||
case TransformationComp_GeometricTranslationInverse:
|
||||
return "GeometricTranslationInverse";
|
||||
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
|
||||
case TransformationComp_MAXIMUM:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2957,7 +2958,7 @@ void FBXConverter::GenerateNodeAnimations(std::vector<aiNodeAnim *> &node_anims,
|
|||
// be invoked _later_ (animations come first). If this node has only rotation,
|
||||
// scaling and translation _and_ there are no animated other components either,
|
||||
// we can use a single node and also a single node animation channel.
|
||||
if( !has_complex && !NeedsComplexTransformationChain(target)) {
|
||||
if (!doc.Settings().preservePivots || (!has_complex && !NeedsComplexTransformationChain(target))) {
|
||||
aiNodeAnim* const nd = GenerateSimpleNodeAnim(fixed_name, target, chain,
|
||||
node_property_map.end(),
|
||||
start, stop,
|
||||
|
|
@ -3415,7 +3416,7 @@ FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std::
|
|||
KeyFrameListList inputs;
|
||||
inputs.reserve(nodes.size() * 3);
|
||||
|
||||
//give some breathing room for rounding errors
|
||||
// give some breathing room for rounding errors
|
||||
const int64_t adj_start = start - 10000;
|
||||
const int64_t adj_stop = stop + 10000;
|
||||
|
||||
|
|
@ -3441,7 +3442,7 @@ FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std::
|
|||
ai_assert(curve->GetKeys().size() == curve->GetValues().size());
|
||||
ai_assert(curve->GetKeys().size());
|
||||
|
||||
//get values within the start/stop time window
|
||||
// get values within the start/stop time window
|
||||
std::shared_ptr<KeyTimeList> Keys(new KeyTimeList());
|
||||
std::shared_ptr<KeyValueList> Values(new KeyValueList());
|
||||
const size_t count = curve->GetKeys().size();
|
||||
|
|
@ -3461,8 +3462,7 @@ FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std::
|
|||
if (tnew >= adj_start && tnew <= adj_stop) {
|
||||
Keys->push_back(tnew);
|
||||
Values->push_back(vnew);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Something broke
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -70,7 +69,7 @@ struct morphKeyData {
|
|||
std::vector<unsigned int> values;
|
||||
std::vector<float> weights;
|
||||
};
|
||||
typedef std::map<int64_t, morphKeyData*> morphAnimData;
|
||||
using morphAnimData = std::map<int64_t, morphKeyData*> ;
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -45,6 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "FBXParser.h"
|
||||
#include "FBXDocument.h"
|
||||
#include "FBXMeshGeometry.h"
|
||||
|
|
@ -65,9 +67,6 @@ Deformer::Deformer(uint64_t id, const Element& element, const Document& doc, con
|
|||
props = GetPropertyTable(doc,"Deformer.Fbx" + classname,element,sc,true);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Deformer::~Deformer() = default;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: Deformer(id,element,doc,name)
|
||||
|
|
@ -113,10 +112,6 @@ Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Cluster::~Cluster() = default;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Skin::Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: Deformer(id,element,doc,name)
|
||||
|
|
@ -142,9 +137,6 @@ Skin::Skin(uint64_t id, const Element& element, const Document& doc, const std::
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Skin::~Skin() = default;
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: Deformer(id, element, doc, name)
|
||||
|
|
@ -154,15 +146,16 @@ BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc,
|
|||
for (const Connection* con : conns) {
|
||||
const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element);
|
||||
if (bspc) {
|
||||
auto pr = blendShapeChannels.insert(bspc);
|
||||
if (!pr.second) {
|
||||
// Only add a channel if it doesn't exist already
|
||||
if (std::find(blendShapeChannels.begin(), blendShapeChannels.end(), bspc) == blendShapeChannels.end()) {
|
||||
blendShapeChannels.push_back(bspc);
|
||||
} else {
|
||||
FBXImporter::LogWarn("there is the same blendShapeChannel id ", bspc->ID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BlendShape::~BlendShape() = default;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: Deformer(id, element, doc, name)
|
||||
|
|
@ -181,17 +174,17 @@ BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const
|
|||
for (const Connection* con : conns) {
|
||||
const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element);
|
||||
if (sg) {
|
||||
auto pr = shapeGeometries.insert(sg);
|
||||
if (!pr.second) {
|
||||
// Only add a geometry if it doesn't exist already
|
||||
if (std::find(shapeGeometries.begin(), shapeGeometries.end(), sg) == shapeGeometries.end()) {
|
||||
shapeGeometries.push_back(sg);
|
||||
} else {
|
||||
FBXImporter::LogWarn("there is the same shapeGeometrie id ", sg->ID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BlendShapeChannel::~BlendShapeChannel() = default;
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace FBX
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -269,7 +269,7 @@ Document::~Document()
|
|||
{
|
||||
// The document does not own the memory for the following objects, but we need to call their d'tor
|
||||
// so they can properly free memory like string members:
|
||||
|
||||
|
||||
for (ObjectMap::value_type &v : objects) {
|
||||
delete_LazyObject(v.second);
|
||||
}
|
||||
|
|
@ -663,6 +663,10 @@ LazyObject& Connection::LazyDestinationObject() const {
|
|||
const Object* Connection::SourceObject() const {
|
||||
LazyObject* const lazy = doc.GetObject(src);
|
||||
ai_assert(lazy);
|
||||
if (lazy == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return lazy->Get();
|
||||
}
|
||||
|
||||
|
|
@ -670,6 +674,10 @@ const Object* Connection::SourceObject() const {
|
|||
const Object* Connection::DestinationObject() const {
|
||||
LazyObject* const lazy = doc.GetObject(dest);
|
||||
ai_assert(lazy);
|
||||
if (lazy == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return lazy->Get();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ class NodeAttribute : public Object {
|
|||
public:
|
||||
NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~NodeAttribute() = default;
|
||||
~NodeAttribute() override = default;
|
||||
|
||||
const PropertyTable& Props() const {
|
||||
ai_assert(props.get());
|
||||
|
|
@ -186,11 +186,11 @@ private:
|
|||
};
|
||||
|
||||
/** DOM base class for FBX camera settings attached to a node */
|
||||
class CameraSwitcher : public NodeAttribute {
|
||||
class CameraSwitcher final : public NodeAttribute {
|
||||
public:
|
||||
CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~CameraSwitcher() = default;
|
||||
~CameraSwitcher() override= default;
|
||||
|
||||
int CameraID() const {
|
||||
return cameraId;
|
||||
|
|
@ -231,11 +231,11 @@ private:
|
|||
|
||||
|
||||
/** DOM base class for FBX cameras attached to a node */
|
||||
class Camera : public NodeAttribute {
|
||||
class Camera final : public NodeAttribute {
|
||||
public:
|
||||
Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~Camera() = default;
|
||||
~Camera() override = default;
|
||||
|
||||
fbx_simple_property(Position, aiVector3D, aiVector3D(0,0,0))
|
||||
fbx_simple_property(UpVector, aiVector3D, aiVector3D(0,1,0))
|
||||
|
|
@ -257,24 +257,24 @@ public:
|
|||
};
|
||||
|
||||
/** DOM base class for FBX null markers attached to a node */
|
||||
class Null : public NodeAttribute {
|
||||
class Null final : public NodeAttribute {
|
||||
public:
|
||||
Null(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
virtual ~Null() = default;
|
||||
~Null() override = default;
|
||||
};
|
||||
|
||||
/** DOM base class for FBX limb node markers attached to a node */
|
||||
class LimbNode : public NodeAttribute {
|
||||
class LimbNode final : public NodeAttribute {
|
||||
public:
|
||||
LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
virtual ~LimbNode() = default;
|
||||
~LimbNode() override = default;
|
||||
};
|
||||
|
||||
/** DOM base class for FBX lights attached to a node */
|
||||
class Light : public NodeAttribute {
|
||||
class Light final : public NodeAttribute {
|
||||
public:
|
||||
Light(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
virtual ~Light() = default;
|
||||
~Light() override = default;
|
||||
|
||||
enum Type {
|
||||
Type_Point,
|
||||
|
|
@ -329,7 +329,7 @@ public:
|
|||
};
|
||||
|
||||
/** DOM base class for FBX models (even though its semantics are more "node" than "model" */
|
||||
class Model : public Object {
|
||||
class Model final : public Object {
|
||||
public:
|
||||
enum RotOrder {
|
||||
RotOrder_EulerXYZ = 0,
|
||||
|
|
@ -354,7 +354,7 @@ public:
|
|||
|
||||
Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~Model() = default;
|
||||
~Model() override = default;
|
||||
|
||||
fbx_simple_property(QuaternionInterpolate, int, 0)
|
||||
|
||||
|
|
@ -477,11 +477,11 @@ private:
|
|||
};
|
||||
|
||||
/** DOM class for generic FBX textures */
|
||||
class Texture : public Object {
|
||||
class Texture final : public Object {
|
||||
public:
|
||||
Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~Texture();
|
||||
~Texture() override;
|
||||
|
||||
const std::string& Type() const {
|
||||
return type;
|
||||
|
|
@ -542,10 +542,10 @@ private:
|
|||
};
|
||||
|
||||
/** DOM class for layered FBX textures */
|
||||
class LayeredTexture : public Object {
|
||||
class LayeredTexture final : public Object {
|
||||
public:
|
||||
LayeredTexture(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
virtual ~LayeredTexture();
|
||||
~LayeredTexture() override;
|
||||
|
||||
// Can only be called after construction of the layered texture object due to construction flag.
|
||||
void fillTexture(const Document& doc);
|
||||
|
|
@ -608,11 +608,11 @@ using TextureMap = std::fbx_unordered_map<std::string, const Texture*>;
|
|||
using LayeredTextureMap = std::fbx_unordered_map<std::string, const LayeredTexture*>;
|
||||
|
||||
/** DOM class for generic FBX videos */
|
||||
class Video : public Object {
|
||||
class Video final : public Object {
|
||||
public:
|
||||
Video(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~Video();
|
||||
~Video() override;
|
||||
|
||||
const std::string& Type() const {
|
||||
return type;
|
||||
|
|
@ -657,11 +657,11 @@ private:
|
|||
};
|
||||
|
||||
/** DOM class for generic FBX materials */
|
||||
class Material : public Object {
|
||||
class Material final : public Object {
|
||||
public:
|
||||
Material(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~Material();
|
||||
~Material() override = default;
|
||||
|
||||
const std::string& GetShadingModel() const {
|
||||
return shading;
|
||||
|
|
@ -697,10 +697,10 @@ using KeyTimeList = std::vector<int64_t>;
|
|||
using KeyValueList = std::vector<float>;
|
||||
|
||||
/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefore) */
|
||||
class AnimationCurve : public Object {
|
||||
class AnimationCurve final : public Object {
|
||||
public:
|
||||
AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||
virtual ~AnimationCurve() = default;
|
||||
~AnimationCurve() override = default;
|
||||
|
||||
/** get list of keyframe positions (time).
|
||||
* Invariant: |GetKeys()| > 0 */
|
||||
|
|
@ -733,7 +733,7 @@ private:
|
|||
using AnimationCurveMap = std::map<std::string, const AnimationCurve*>;
|
||||
|
||||
/** Represents a FBX animation curve (i.e. a mapping from single animation curves to nodes) */
|
||||
class AnimationCurveNode : public Object {
|
||||
class AnimationCurveNode final : 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
|
||||
|
|
@ -741,7 +741,7 @@ public:
|
|||
AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
|
||||
const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0);
|
||||
|
||||
virtual ~AnimationCurveNode() = default;
|
||||
~AnimationCurveNode() override = default;
|
||||
|
||||
const PropertyTable& Props() const {
|
||||
ai_assert(props.get());
|
||||
|
|
@ -783,7 +783,7 @@ private:
|
|||
using AnimationCurveNodeList = std::vector<const AnimationCurveNode*>;
|
||||
|
||||
/** Represents a FBX animation layer (i.e. a list of node animations) */
|
||||
class AnimationLayer : public Object {
|
||||
class AnimationLayer final : public Object {
|
||||
public:
|
||||
AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||
virtual ~AnimationLayer() = default;
|
||||
|
|
@ -806,7 +806,7 @@ private:
|
|||
using AnimationLayerList = std::vector<const AnimationLayer*>;
|
||||
|
||||
/** Represents a FBX animation stack (i.e. a list of animation layers) */
|
||||
class AnimationStack : public Object {
|
||||
class AnimationStack final : public Object {
|
||||
public:
|
||||
AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||
virtual ~AnimationStack() = default;
|
||||
|
|
@ -835,7 +835,7 @@ private:
|
|||
class Deformer : public Object {
|
||||
public:
|
||||
Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
virtual ~Deformer();
|
||||
virtual ~Deformer() = default;
|
||||
|
||||
const PropertyTable& Props() const {
|
||||
ai_assert(props.get());
|
||||
|
|
@ -851,11 +851,11 @@ using WeightIndexArray = std::vector<unsigned int>;
|
|||
|
||||
|
||||
/** DOM class for BlendShapeChannel deformers */
|
||||
class BlendShapeChannel : public Deformer {
|
||||
class BlendShapeChannel final : public Deformer {
|
||||
public:
|
||||
BlendShapeChannel(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~BlendShapeChannel();
|
||||
virtual ~BlendShapeChannel() = default;
|
||||
|
||||
float DeformPercent() const {
|
||||
return percent;
|
||||
|
|
@ -865,37 +865,37 @@ public:
|
|||
return fullWeights;
|
||||
}
|
||||
|
||||
const std::unordered_set<const ShapeGeometry*>& GetShapeGeometries() const {
|
||||
const std::vector<const ShapeGeometry*>& GetShapeGeometries() const {
|
||||
return shapeGeometries;
|
||||
}
|
||||
|
||||
private:
|
||||
float percent;
|
||||
WeightArray fullWeights;
|
||||
std::unordered_set<const ShapeGeometry*> shapeGeometries;
|
||||
std::vector<const ShapeGeometry*> shapeGeometries;
|
||||
};
|
||||
|
||||
/** DOM class for BlendShape deformers */
|
||||
class BlendShape : public Deformer {
|
||||
class BlendShape final : public Deformer {
|
||||
public:
|
||||
BlendShape(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~BlendShape();
|
||||
virtual ~BlendShape() = default;
|
||||
|
||||
const std::unordered_set<const BlendShapeChannel*>& BlendShapeChannels() const {
|
||||
const std::vector<const BlendShapeChannel*>& BlendShapeChannels() const {
|
||||
return blendShapeChannels;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_set<const BlendShapeChannel*> blendShapeChannels;
|
||||
std::vector<const BlendShapeChannel*> blendShapeChannels;
|
||||
};
|
||||
|
||||
/** DOM class for skin deformer clusters (aka sub-deformers) */
|
||||
class Cluster : public Deformer {
|
||||
class Cluster final : public Deformer {
|
||||
public:
|
||||
Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~Cluster();
|
||||
virtual ~Cluster() = default;
|
||||
|
||||
/** get the list of deformer weights associated with this cluster.
|
||||
* Use #GetIndices() to get the associated vertices. Both arrays
|
||||
|
|
@ -935,11 +935,11 @@ private:
|
|||
};
|
||||
|
||||
/** DOM class for skin deformers */
|
||||
class Skin : public Deformer {
|
||||
class Skin final : public Deformer {
|
||||
public:
|
||||
Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~Skin();
|
||||
virtual ~Skin() = default;
|
||||
|
||||
float DeformAccuracy() const {
|
||||
return accuracy;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -36,7 +35,6 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
|
@ -81,8 +79,7 @@ void DOMWarning(const std::string& message, const Token& token) {
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void DOMWarning(const std::string& message, const Element* element /*= nullptr*/)
|
||||
{
|
||||
void DOMWarning(const std::string& message, const Element* element /*= nullptr*/) {
|
||||
if(element) {
|
||||
DOMWarning(message,element->KeyToken());
|
||||
return;
|
||||
|
|
@ -92,41 +89,39 @@ void DOMWarning(const std::string& message, const Element* element /*= nullptr*/
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// fetch a property table and the corresponding property template
|
||||
std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
|
||||
const std::string& templateName,
|
||||
const Element &element,
|
||||
const Scope& sc,
|
||||
bool no_warn /*= false*/)
|
||||
{
|
||||
const std::string& templateName,
|
||||
const Element &element,
|
||||
const Scope& sc,
|
||||
bool no_warn /*= false*/) {
|
||||
const Element* const Properties70 = sc["Properties70"];
|
||||
std::shared_ptr<const PropertyTable> templateProps = std::shared_ptr<const PropertyTable>(
|
||||
static_cast<const PropertyTable *>(nullptr));
|
||||
|
||||
if(templateName.length()) {
|
||||
if (templateName.length()) {
|
||||
PropertyTemplateMap::const_iterator it = doc.Templates().find(templateName);
|
||||
if(it != doc.Templates().end()) {
|
||||
templateProps = (*it).second;
|
||||
}
|
||||
}
|
||||
|
||||
if(!Properties70 || !Properties70->Compound()) {
|
||||
if (!Properties70 || !Properties70->Compound()) {
|
||||
if(!no_warn) {
|
||||
DOMWarning("property table (Properties70) not found",&element);
|
||||
}
|
||||
if(templateProps) {
|
||||
return templateProps;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return std::make_shared<const PropertyTable>();
|
||||
}
|
||||
}
|
||||
return std::make_shared<const PropertyTable>(*Properties70,templateProps);
|
||||
}
|
||||
|
||||
} // !Util
|
||||
} // !FBX
|
||||
} // !Assimp
|
||||
|
||||
#endif
|
||||
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||
|
|
|
|||
|
|
@ -114,4 +114,4 @@ inline const T* ProcessSimpleConnection(const Connection& con,
|
|||
} //!FBX
|
||||
} //!Assimp
|
||||
|
||||
#endif
|
||||
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -35,7 +35,6 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
|
|
@ -55,37 +54,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <memory> // shared_ptr
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
// AddP70<type> helpers... there's no usable pattern here,
|
||||
// so all are defined as separate functions.
|
||||
// Even "animatable" properties are often completely different
|
||||
// from the standard (nonanimated) property definition,
|
||||
// so they are specified with an 'A' suffix.
|
||||
|
||||
void FBX::Node::AddP70int(
|
||||
const std::string& cur_name, int32_t value
|
||||
) {
|
||||
void FBX::Node::AddP70int(const std::string& cur_name, int32_t value) {
|
||||
FBX::Node n("P");
|
||||
n.AddProperties(cur_name, "int", "Integer", "", value);
|
||||
AddChild(n);
|
||||
}
|
||||
|
||||
void FBX::Node::AddP70bool(
|
||||
const std::string& cur_name, bool value
|
||||
) {
|
||||
void FBX::Node::AddP70bool(const std::string& cur_name, bool value) {
|
||||
FBX::Node n("P");
|
||||
n.AddProperties(cur_name, "bool", "", "", int32_t(value));
|
||||
AddChild(n);
|
||||
}
|
||||
|
||||
void FBX::Node::AddP70double(
|
||||
const std::string &cur_name, double value) {
|
||||
FBX::Node n("P");
|
||||
void FBX::Node::AddP70double(const std::string &cur_name, double value) { FBX::Node n("P");
|
||||
n.AddProperties(cur_name, "double", "Number", "", value);
|
||||
AddChild(n);
|
||||
}
|
||||
|
||||
void FBX::Node::AddP70numberA(
|
||||
const std::string &cur_name, double value) {
|
||||
void FBX::Node::AddP70numberA(const std::string &cur_name, double value) {
|
||||
FBX::Node n("P");
|
||||
n.AddProperties(cur_name, "Number", "", "A", value);
|
||||
AddChild(n);
|
||||
|
|
@ -405,8 +398,7 @@ void FBX::Node::DumpChildrenAscii(std::ostream& s, int indent)
|
|||
}
|
||||
}
|
||||
|
||||
void FBX::Node::EndAscii(std::ostream& s, int indent, bool has_children)
|
||||
{
|
||||
void FBX::Node::EndAscii(std::ostream& s, int indent, bool has_children) {
|
||||
if (!has_children) { return; } // nothing to do
|
||||
s << '\n';
|
||||
for (int i = 0; i < indent; ++i) { s << '\t'; }
|
||||
|
|
@ -417,11 +409,10 @@ void FBX::Node::EndAscii(std::ostream& s, int indent, bool has_children)
|
|||
|
||||
// ascii property node from vector of doubles
|
||||
void FBX::Node::WritePropertyNodeAscii(
|
||||
const std::string& name,
|
||||
const std::vector<double>& v,
|
||||
Assimp::StreamWriterLE& s,
|
||||
int indent
|
||||
){
|
||||
const std::string& name,
|
||||
const std::vector<double>& v,
|
||||
Assimp::StreamWriterLE& s,
|
||||
int indent){
|
||||
char buffer[32];
|
||||
FBX::Node node(name);
|
||||
node.Begin(s, false, indent);
|
||||
|
|
@ -556,6 +547,8 @@ void FBX::Node::WritePropertyNode(
|
|||
FBX::Node::WritePropertyNodeAscii(name, v, s, indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
|
||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -35,7 +35,6 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
|
@ -70,7 +69,6 @@ public:
|
|||
// some nodes always pretend they have children...
|
||||
bool force_has_children = false;
|
||||
|
||||
public: // constructors
|
||||
/// The default class constructor.
|
||||
Node() = default;
|
||||
|
||||
|
|
@ -89,7 +87,6 @@ public: // constructors
|
|||
AddProperties(std::forward<More>(more)...);
|
||||
}
|
||||
|
||||
public: // functions to add properties or children
|
||||
// add a single property to the node
|
||||
template <typename T>
|
||||
void AddProperty(T&& value) {
|
||||
|
|
@ -118,8 +115,6 @@ public: // functions to add properties or children
|
|||
children.push_back(std::move(c));
|
||||
}
|
||||
|
||||
public: // support specifically for dealing with Properties70 nodes
|
||||
|
||||
// it really is simpler to make these all separate functions.
|
||||
// the versions with 'A' suffixes are for animatable properties.
|
||||
// those often follow a completely different format internally in FBX.
|
||||
|
|
@ -150,8 +145,6 @@ public: // support specifically for dealing with Properties70 nodes
|
|||
AddChild(n);
|
||||
}
|
||||
|
||||
public: // member functions for writing data to a file or stream
|
||||
|
||||
// write the full node to the given file or stream
|
||||
void Dump(
|
||||
const std::shared_ptr<Assimp::IOStream> &outfile,
|
||||
|
|
@ -175,31 +168,6 @@ public: // member functions for writing data to a file or stream
|
|||
bool has_children
|
||||
);
|
||||
|
||||
private: // internal functions used for writing
|
||||
|
||||
void DumpBinary(Assimp::StreamWriterLE &s);
|
||||
void DumpAscii(Assimp::StreamWriterLE &s, int indent);
|
||||
void DumpAscii(std::ostream &s, int indent);
|
||||
|
||||
void BeginBinary(Assimp::StreamWriterLE &s);
|
||||
void DumpPropertiesBinary(Assimp::StreamWriterLE& s);
|
||||
void EndPropertiesBinary(Assimp::StreamWriterLE &s);
|
||||
void EndPropertiesBinary(Assimp::StreamWriterLE &s, size_t num_properties);
|
||||
void DumpChildrenBinary(Assimp::StreamWriterLE& s);
|
||||
void EndBinary(Assimp::StreamWriterLE &s, bool has_children);
|
||||
|
||||
void BeginAscii(std::ostream &s, int indent);
|
||||
void DumpPropertiesAscii(std::ostream &s, int indent);
|
||||
void BeginChildrenAscii(std::ostream &s, int indent);
|
||||
void DumpChildrenAscii(std::ostream &s, int indent);
|
||||
void EndAscii(std::ostream &s, int indent, bool has_children);
|
||||
|
||||
private: // data used for binary dumps
|
||||
size_t start_pos; // starting position in stream
|
||||
size_t end_pos; // ending position in stream
|
||||
size_t property_start; // starting position of property section
|
||||
|
||||
public: // static member functions
|
||||
|
||||
// convenience function to create a node with a single property,
|
||||
// and write it to the stream.
|
||||
|
|
@ -235,7 +203,26 @@ public: // static member functions
|
|||
bool binary, int indent
|
||||
);
|
||||
|
||||
private: // static helper functions
|
||||
private: // internal functions used for writing
|
||||
|
||||
void DumpBinary(Assimp::StreamWriterLE &s);
|
||||
void DumpAscii(Assimp::StreamWriterLE &s, int indent);
|
||||
void DumpAscii(std::ostream &s, int indent);
|
||||
|
||||
void BeginBinary(Assimp::StreamWriterLE &s);
|
||||
void DumpPropertiesBinary(Assimp::StreamWriterLE& s);
|
||||
void EndPropertiesBinary(Assimp::StreamWriterLE &s);
|
||||
void EndPropertiesBinary(Assimp::StreamWriterLE &s, size_t num_properties);
|
||||
void DumpChildrenBinary(Assimp::StreamWriterLE& s);
|
||||
void EndBinary(Assimp::StreamWriterLE &s, bool has_children);
|
||||
|
||||
void BeginAscii(std::ostream &s, int indent);
|
||||
void DumpPropertiesAscii(std::ostream &s, int indent);
|
||||
void BeginChildrenAscii(std::ostream &s, int indent);
|
||||
void DumpChildrenAscii(std::ostream &s, int indent);
|
||||
void EndAscii(std::ostream &s, int indent, bool has_children);
|
||||
|
||||
// static helper functions
|
||||
static void WritePropertyNodeAscii(
|
||||
const std::string& name,
|
||||
const std::vector<double>& v,
|
||||
|
|
@ -259,9 +246,13 @@ private: // static helper functions
|
|||
Assimp::StreamWriterLE& s
|
||||
);
|
||||
|
||||
private: // data used for binary dumps
|
||||
size_t start_pos; // starting position in stream
|
||||
size_t end_pos; // ending position in stream
|
||||
size_t property_start; // starting position of property section
|
||||
};
|
||||
}
|
||||
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
|
||||
|
||||
#endif // AI_FBXEXPORTNODE_H_INC
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -286,6 +286,8 @@ void FBXExportProperty::DumpAscii(std::ostream& s, int indent) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
// assimp issue #6112; fallthrough confirmed by @mesilliac
|
||||
[[fallthrough]];
|
||||
case 'R':
|
||||
s << '"';
|
||||
// we might as well check this now,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/IOSystem.hpp>
|
||||
#include <assimp/Exporter.hpp>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <assimp/Logger.hpp>
|
||||
#include <assimp/StreamWriter.h> // StreamWriterLE
|
||||
#include <assimp/Exceptional.h> // DeadlyExportError
|
||||
#include <assimp/material.h> // aiTextureType
|
||||
|
|
@ -370,12 +371,6 @@ void FBXExporter::WriteHeaderExtension ()
|
|||
"Creator", creator.str(), outstream, binary, indent
|
||||
);
|
||||
|
||||
//FBX::Node sceneinfo("SceneInfo");
|
||||
//sceneinfo.AddProperty("GlobalInfo" + FBX::SEPARATOR + "SceneInfo");
|
||||
// not sure if any of this is actually needed,
|
||||
// so just write an empty node for now.
|
||||
//sceneinfo.Dump(outstream, binary, indent);
|
||||
|
||||
indent = 0;
|
||||
|
||||
// finish node
|
||||
|
|
@ -459,11 +454,7 @@ void WritePropString(const aiScene* scene, FBX::Node& p, const std::string& key,
|
|||
}
|
||||
}
|
||||
|
||||
void FBXExporter::WriteGlobalSettings ()
|
||||
{
|
||||
if (!binary) {
|
||||
// no title, follows directly from the header extension
|
||||
}
|
||||
void FBXExporter::WriteGlobalSettings () {
|
||||
FBX::Node gs("GlobalSettings");
|
||||
gs.AddChild("Version", int32_t(1000));
|
||||
|
||||
|
|
@ -493,8 +484,7 @@ void FBXExporter::WriteGlobalSettings ()
|
|||
gs.Dump(outfile, binary, 0);
|
||||
}
|
||||
|
||||
void FBXExporter::WriteDocuments ()
|
||||
{
|
||||
void FBXExporter::WriteDocuments() {
|
||||
if (!binary) {
|
||||
WriteAsciiSectionHeader("Documents Description");
|
||||
}
|
||||
|
|
@ -523,8 +513,7 @@ void FBXExporter::WriteDocuments ()
|
|||
docs.Dump(outfile, binary, 0);
|
||||
}
|
||||
|
||||
void FBXExporter::WriteReferences ()
|
||||
{
|
||||
void FBXExporter::WriteReferences() {
|
||||
if (!binary) {
|
||||
WriteAsciiSectionHeader("Document References");
|
||||
}
|
||||
|
|
@ -540,7 +529,6 @@ void FBXExporter::WriteReferences ()
|
|||
// some internal helper functions used for writing the definitions
|
||||
// (before any actual data is written)
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
size_t count_nodes(const aiNode* n, const aiNode* root) {
|
||||
size_t count;
|
||||
if (n == root) {
|
||||
|
|
@ -556,8 +544,7 @@ size_t count_nodes(const aiNode* n, const aiNode* root) {
|
|||
return count;
|
||||
}
|
||||
|
||||
bool has_phong_mat(const aiScene* scene)
|
||||
{
|
||||
static bool has_phong_mat(const aiScene* scene) {
|
||||
// just search for any material with a shininess exponent
|
||||
for (size_t i = 0; i < scene->mNumMaterials; ++i) {
|
||||
aiMaterial* mat = scene->mMaterials[i];
|
||||
|
|
@ -570,16 +557,12 @@ bool has_phong_mat(const aiScene* scene)
|
|||
return false;
|
||||
}
|
||||
|
||||
size_t count_images(const aiScene* scene) {
|
||||
static size_t count_images(const aiScene* scene) {
|
||||
std::unordered_set<std::string> images;
|
||||
aiString texpath;
|
||||
for (size_t i = 0; i < scene->mNumMaterials; ++i) {
|
||||
aiMaterial* mat = scene->mMaterials[i];
|
||||
for (
|
||||
size_t tt = aiTextureType_DIFFUSE;
|
||||
tt < aiTextureType_UNKNOWN;
|
||||
++tt
|
||||
){
|
||||
aiMaterial *mat = scene->mMaterials[i];
|
||||
for (size_t tt = aiTextureType_DIFFUSE; tt < aiTextureType_UNKNOWN; ++tt) {
|
||||
const aiTextureType textype = static_cast<aiTextureType>(tt);
|
||||
const size_t texcount = mat->GetTextureCount(textype);
|
||||
for (unsigned int j = 0; j < texcount; ++j) {
|
||||
|
|
@ -588,10 +571,11 @@ size_t count_images(const aiScene* scene) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return images.size();
|
||||
}
|
||||
|
||||
size_t count_textures(const aiScene* scene) {
|
||||
static size_t count_textures(const aiScene* scene) {
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < scene->mNumMaterials; ++i) {
|
||||
aiMaterial* mat = scene->mMaterials[i];
|
||||
|
|
@ -609,7 +593,7 @@ size_t count_textures(const aiScene* scene) {
|
|||
return count;
|
||||
}
|
||||
|
||||
size_t count_deformers(const aiScene* scene) {
|
||||
static size_t count_deformers(const aiScene* scene) {
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < scene->mNumMeshes; ++i) {
|
||||
const size_t n = scene->mMeshes[i]->mNumBones;
|
||||
|
|
@ -621,8 +605,7 @@ size_t count_deformers(const aiScene* scene) {
|
|||
return count;
|
||||
}
|
||||
|
||||
void FBXExporter::WriteDefinitions ()
|
||||
{
|
||||
void FBXExporter::WriteDefinitions () {
|
||||
// basically this is just bookkeeping:
|
||||
// determining how many of each type of object there are
|
||||
// and specifying the base properties to use when otherwise unspecified.
|
||||
|
|
@ -1033,9 +1016,7 @@ void FBXExporter::WriteDefinitions ()
|
|||
// some internal helper functions used for writing the objects section
|
||||
// (which holds the actual data)
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
aiNode* get_node_for_mesh(unsigned int meshIndex, aiNode* node)
|
||||
{
|
||||
static aiNode* get_node_for_mesh(unsigned int meshIndex, aiNode* node) {
|
||||
for (size_t i = 0; i < node->mNumMeshes; ++i) {
|
||||
if (node->mMeshes[i] == meshIndex) {
|
||||
return node;
|
||||
|
|
@ -1048,8 +1029,7 @@ aiNode* get_node_for_mesh(unsigned int meshIndex, aiNode* node)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
aiMatrix4x4 get_world_transform(const aiNode* node, const aiScene* scene)
|
||||
{
|
||||
aiMatrix4x4 get_world_transform(const aiNode* node, const aiScene* scene) {
|
||||
std::vector<const aiNode*> node_chain;
|
||||
while (node != scene->mRootNode && node != nullptr) {
|
||||
node_chain.push_back(node);
|
||||
|
|
@ -1063,18 +1043,47 @@ aiMatrix4x4 get_world_transform(const aiNode* node, const aiScene* scene)
|
|||
}
|
||||
|
||||
inline int64_t to_ktime(double ticks, const aiAnimation* anim) {
|
||||
if (FP_ZERO == std::fpclassify(anim->mTicksPerSecond)) {
|
||||
return static_cast<int64_t>(ticks) * FBX::SECOND;
|
||||
if (FP_ZERO == std::fpclassify(anim->mTicksPerSecond)) {
|
||||
return static_cast<int64_t>(ticks * FBX::SECOND);
|
||||
}
|
||||
return (static_cast<int64_t>(ticks / anim->mTicksPerSecond)) * FBX::SECOND;
|
||||
|
||||
// Defensive: handle zero or near-zero mTicksPerSecond
|
||||
double tps = anim->mTicksPerSecond;
|
||||
double timeVal;
|
||||
if (FP_ZERO == std::fpclassify(tps)) {
|
||||
timeVal = ticks;
|
||||
} else {
|
||||
timeVal = ticks / tps;
|
||||
}
|
||||
|
||||
// Clamp to prevent overflow
|
||||
const double kMax = static_cast<double>(INT64_MAX) / static_cast<double>(FBX::SECOND);
|
||||
const double kMin = static_cast<double>(INT64_MIN) / static_cast<double>(FBX::SECOND);
|
||||
|
||||
if (timeVal > kMax) {
|
||||
return INT64_MAX;
|
||||
}
|
||||
if (timeVal < kMin) {
|
||||
return INT64_MIN;
|
||||
}
|
||||
return static_cast<int64_t>((ticks / anim->mTicksPerSecond) * FBX::SECOND);
|
||||
}
|
||||
|
||||
inline int64_t to_ktime(double time) {
|
||||
return (static_cast<int64_t>(time * FBX::SECOND));
|
||||
// Clamp to prevent overflow
|
||||
const double kMax = static_cast<double>(INT64_MAX) / static_cast<double>(FBX::SECOND);
|
||||
const double kMin = static_cast<double>(INT64_MIN) / static_cast<double>(FBX::SECOND);
|
||||
|
||||
if (time > kMax) {
|
||||
return INT64_MAX;
|
||||
}
|
||||
if (time < kMin) {
|
||||
return INT64_MIN;
|
||||
}
|
||||
return static_cast<int64_t>(time * FBX::SECOND);
|
||||
}
|
||||
|
||||
void FBXExporter::WriteObjects ()
|
||||
{
|
||||
void FBXExporter::WriteObjects () {
|
||||
if (!binary) {
|
||||
WriteAsciiSectionHeader("Object properties");
|
||||
}
|
||||
|
|
@ -1087,21 +1096,27 @@ void FBXExporter::WriteObjects ()
|
|||
object_node.BeginChildren(outstream, binary, indent);
|
||||
|
||||
bool bJoinIdenticalVertices = mProperties->GetPropertyBool("bJoinIdenticalVertices", true);
|
||||
std::vector<std::vector<int32_t>> vVertexIndice;//save vertex_indices as it is needed later
|
||||
// save vertex_indices as it is needed later
|
||||
std::vector<std::vector<int32_t>> vVertexIndice(mScene->mNumMeshes);
|
||||
std::vector<uint32_t> uniq_v_before_mi;
|
||||
|
||||
const auto bTransparencyFactorReferencedToOpacity = mProperties->GetPropertyBool(AI_CONFIG_EXPORT_FBX_TRANSPARENCY_FACTOR_REFER_TO_OPACITY, false);
|
||||
|
||||
// geometry (aiMesh)
|
||||
mesh_uids.clear();
|
||||
indent = 1;
|
||||
for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) {
|
||||
// it's all about this mesh
|
||||
aiMesh* m = mScene->mMeshes[mi];
|
||||
std::function<void(const aiNode*)> visit_node_geo = [&](const aiNode *node) {
|
||||
if (node->mNumMeshes == 0) {
|
||||
for (uint32_t ni = 0; ni < node->mNumChildren; ni++) {
|
||||
visit_node_geo(node->mChildren[ni]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// start the node record
|
||||
FBX::Node n("Geometry");
|
||||
int64_t uid = generate_uid();
|
||||
mesh_uids.push_back(uid);
|
||||
mesh_uids[node] = uid;
|
||||
n.AddProperty(uid);
|
||||
n.AddProperty(FBX::SEPARATOR + "Geometry");
|
||||
n.AddProperty("Mesh");
|
||||
|
|
@ -1109,159 +1124,113 @@ void FBXExporter::WriteObjects ()
|
|||
n.DumpProperties(outstream, binary, indent);
|
||||
n.EndProperties(outstream, binary, indent);
|
||||
n.BeginChildren(outstream, binary, indent);
|
||||
indent = 2;
|
||||
|
||||
// output vertex data - each vertex should be unique (probably)
|
||||
std::vector<double> flattened_vertices;
|
||||
// index of original vertex in vertex data vector
|
||||
std::vector<int32_t> vertex_indices;
|
||||
// map of vertex value to its index in the data vector
|
||||
std::map<aiVector3D,size_t> index_by_vertex_value;
|
||||
if(bJoinIdenticalVertices){
|
||||
int32_t index = 0;
|
||||
for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
|
||||
aiVector3D vtx = m->mVertices[vi];
|
||||
auto elem = index_by_vertex_value.find(vtx);
|
||||
if (elem == index_by_vertex_value.end()) {
|
||||
vertex_indices.push_back(index);
|
||||
index_by_vertex_value[vtx] = index;
|
||||
flattened_vertices.push_back(vtx[0]);
|
||||
flattened_vertices.push_back(vtx[1]);
|
||||
flattened_vertices.push_back(vtx[2]);
|
||||
++index;
|
||||
} else {
|
||||
vertex_indices.push_back(int32_t(elem->second));
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // do not join vertex, respect the export flag
|
||||
vertex_indices.resize(m->mNumVertices);
|
||||
std::iota(vertex_indices.begin(), vertex_indices.end(), 0);
|
||||
for(unsigned int v = 0; v < m->mNumVertices; ++ v) {
|
||||
aiVector3D vtx = m->mVertices[v];
|
||||
flattened_vertices.push_back(vtx.x);
|
||||
flattened_vertices.push_back(vtx.y);
|
||||
flattened_vertices.push_back(vtx.z);
|
||||
}
|
||||
}
|
||||
vVertexIndice.push_back(vertex_indices);
|
||||
|
||||
FBX::Node::WritePropertyNode(
|
||||
"Vertices", flattened_vertices, outstream, binary, indent
|
||||
);
|
||||
std::vector<double> normal_data;
|
||||
std::vector<double> color_data;
|
||||
|
||||
std::vector<int32_t> polygon_data;
|
||||
|
||||
std::vector<std::vector<double>> uv_data;
|
||||
std::vector<std::vector<int32_t>> uv_indices;
|
||||
|
||||
indent = 2;
|
||||
|
||||
for (uint32_t n_mi = 0; n_mi < node->mNumMeshes; n_mi++) {
|
||||
const auto mi = node->mMeshes[n_mi];
|
||||
const aiMesh *m = mScene->mMeshes[mi];
|
||||
|
||||
size_t v_offset = vertex_indices.size();
|
||||
size_t uniq_v_before = flattened_vertices.size() / 3;
|
||||
|
||||
// map of vertex value to its index in the data vector
|
||||
std::map<aiVector3D,size_t> index_by_vertex_value;
|
||||
if (bJoinIdenticalVertices) {
|
||||
int32_t index = 0;
|
||||
for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
|
||||
aiVector3D vtx = m->mVertices[vi];
|
||||
auto elem = index_by_vertex_value.find(vtx);
|
||||
if (elem == index_by_vertex_value.end()) {
|
||||
vertex_indices.push_back(index);
|
||||
index_by_vertex_value[vtx] = index;
|
||||
flattened_vertices.insert(flattened_vertices.end(), { vtx.x, vtx.y, vtx.z });
|
||||
++index;
|
||||
} else {
|
||||
vertex_indices.push_back(int32_t(elem->second));
|
||||
}
|
||||
}
|
||||
} else { // do not join vertex, respect the export flag
|
||||
vertex_indices.resize(v_offset + m->mNumVertices);
|
||||
std::iota(vertex_indices.begin() + v_offset, vertex_indices.end(), 0);
|
||||
for(unsigned int v = 0; v < m->mNumVertices; ++ v) {
|
||||
aiVector3D vtx = m->mVertices[v];
|
||||
flattened_vertices.insert(flattened_vertices.end(), {vtx.x, vtx.y, vtx.z});
|
||||
}
|
||||
}
|
||||
vVertexIndice[mi].insert(
|
||||
// TODO test whether this can be end or not
|
||||
vVertexIndice[mi].end(),
|
||||
vertex_indices.begin() + v_offset,
|
||||
vertex_indices.end()
|
||||
);
|
||||
|
||||
// here could be edges but they're insane.
|
||||
// it's optional anyway, so let's ignore it.
|
||||
|
||||
// output polygon data as a flattened array of vertex indices.
|
||||
// the last vertex index of each polygon is negated and - 1
|
||||
std::vector<int32_t> polygon_data;
|
||||
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
|
||||
for (size_t fi = 0; fi < m->mNumFaces; fi++) {
|
||||
const aiFace &f = m->mFaces[fi];
|
||||
for (size_t pvi = 0; pvi < f.mNumIndices - 1; ++pvi) {
|
||||
polygon_data.push_back(vertex_indices[f.mIndices[pvi]]);
|
||||
if (f.mNumIndices == 0) continue;
|
||||
size_t pvi = 0;
|
||||
for (; pvi < f.mNumIndices - 1; pvi++) {
|
||||
polygon_data.push_back(
|
||||
static_cast<int32_t>(uniq_v_before + vertex_indices[v_offset + f.mIndices[pvi]])
|
||||
);
|
||||
}
|
||||
polygon_data.push_back(
|
||||
-1 - vertex_indices[f.mIndices[f.mNumIndices-1]]
|
||||
static_cast<int32_t>(-1 ^ (uniq_v_before + vertex_indices[v_offset+f.mIndices[pvi]]))
|
||||
);
|
||||
}
|
||||
FBX::Node::WritePropertyNode(
|
||||
"PolygonVertexIndex", polygon_data, outstream, binary, indent
|
||||
);
|
||||
}
|
||||
|
||||
// here could be edges but they're insane.
|
||||
// it's optional anyway, so let's ignore it.
|
||||
uniq_v_before_mi.push_back(static_cast<uint32_t>(uniq_v_before));
|
||||
|
||||
FBX::Node::WritePropertyNode(
|
||||
"GeometryVersion", int32_t(124), outstream, binary, indent
|
||||
);
|
||||
|
||||
// normals, if any
|
||||
if (m->HasNormals()) {
|
||||
FBX::Node normals("LayerElementNormal", int32_t(0));
|
||||
normals.Begin(outstream, binary, indent);
|
||||
normals.DumpProperties(outstream, binary, indent);
|
||||
normals.EndProperties(outstream, binary, indent);
|
||||
normals.BeginChildren(outstream, binary, indent);
|
||||
indent = 3;
|
||||
FBX::Node::WritePropertyNode(
|
||||
"Version", int32_t(101), outstream, binary, indent
|
||||
);
|
||||
FBX::Node::WritePropertyNode(
|
||||
"Name", "", outstream, binary, indent
|
||||
);
|
||||
FBX::Node::WritePropertyNode(
|
||||
"MappingInformationType", "ByPolygonVertex",
|
||||
outstream, binary, indent
|
||||
);
|
||||
// TODO: vertex-normals or indexed normals when appropriate
|
||||
FBX::Node::WritePropertyNode(
|
||||
"ReferenceInformationType", "Direct",
|
||||
outstream, binary, indent
|
||||
);
|
||||
std::vector<double> normal_data;
|
||||
if (m->HasNormals()) {
|
||||
normal_data.reserve(3 * polygon_data.size());
|
||||
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
|
||||
const aiFace &f = m->mFaces[fi];
|
||||
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
|
||||
const aiVector3D &curN = m->mNormals[f.mIndices[pvi]];
|
||||
normal_data.push_back(curN.x);
|
||||
normal_data.push_back(curN.y);
|
||||
normal_data.push_back(curN.z);
|
||||
}
|
||||
for (size_t fi = 0; fi < m->mNumFaces; fi++) {
|
||||
const aiFace & f = m->mFaces[fi];
|
||||
for (size_t pvi = 0; pvi < f.mNumIndices; pvi++) {
|
||||
const aiVector3D &curN = m->mNormals[f.mIndices[pvi]];
|
||||
normal_data.insert(normal_data.end(), { curN.x, curN.y, curN.z });
|
||||
}
|
||||
}
|
||||
FBX::Node::WritePropertyNode(
|
||||
"Normals", normal_data, outstream, binary, indent
|
||||
);
|
||||
// note: version 102 has a NormalsW also... not sure what it is,
|
||||
// so we can stick with version 101 for now.
|
||||
indent = 2;
|
||||
normals.End(outstream, binary, indent, true);
|
||||
}
|
||||
}
|
||||
|
||||
// colors, if any
|
||||
for (size_t ci = 0; ci < m->GetNumColorChannels(); ++ci) {
|
||||
FBX::Node vertexcolors("LayerElementColor", int32_t(ci));
|
||||
vertexcolors.Begin(outstream, binary, indent);
|
||||
vertexcolors.DumpProperties(outstream, binary, indent);
|
||||
vertexcolors.EndProperties(outstream, binary, indent);
|
||||
vertexcolors.BeginChildren(outstream, binary, indent);
|
||||
indent = 3;
|
||||
FBX::Node::WritePropertyNode(
|
||||
"Version", int32_t(101), outstream, binary, indent
|
||||
);
|
||||
char layerName[8];
|
||||
snprintf(layerName, sizeof(layerName), "COLOR_%d", int32_t(ci));
|
||||
FBX::Node::WritePropertyNode(
|
||||
"Name", (const char*)layerName, outstream, binary, indent
|
||||
);
|
||||
FBX::Node::WritePropertyNode(
|
||||
"MappingInformationType", "ByPolygonVertex",
|
||||
outstream, binary, indent
|
||||
);
|
||||
FBX::Node::WritePropertyNode(
|
||||
"ReferenceInformationType", "Direct",
|
||||
outstream, binary, indent
|
||||
);
|
||||
std::vector<double> color_data;
|
||||
const int32_t colorChannelIndex = 0;
|
||||
if (m->HasVertexColors(colorChannelIndex)) {
|
||||
color_data.reserve(4 * polygon_data.size());
|
||||
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
|
||||
const aiFace &f = m->mFaces[fi];
|
||||
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
|
||||
const aiColor4D &c = m->mColors[ci][f.mIndices[pvi]];
|
||||
color_data.push_back(c.r);
|
||||
color_data.push_back(c.g);
|
||||
color_data.push_back(c.b);
|
||||
color_data.push_back(c.a);
|
||||
}
|
||||
for (size_t fi = 0; fi < m->mNumFaces; fi++) {
|
||||
const aiFace &f = m->mFaces[fi];
|
||||
for (size_t pvi = 0; pvi < f.mNumIndices; pvi++) {
|
||||
const aiColor4D &c = m->mColors[colorChannelIndex][f.mIndices[pvi]];
|
||||
color_data.insert(color_data.end(), { c.r, c.g, c.b, c.a });
|
||||
}
|
||||
}
|
||||
FBX::Node::WritePropertyNode(
|
||||
"Colors", color_data, outstream, binary, indent
|
||||
);
|
||||
indent = 2;
|
||||
vertexcolors.End(outstream, binary, indent, true);
|
||||
}
|
||||
}
|
||||
|
||||
// uvs, if any
|
||||
for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) {
|
||||
if (m->mNumUVComponents[uvi] > 2) {
|
||||
const auto num_uv = static_cast<size_t>(m->GetNumUVChannels());
|
||||
uv_indices.resize(std::max(num_uv, uv_indices.size()));
|
||||
uv_data.resize(std::max(num_uv, uv_data.size()));
|
||||
std::map<aiVector3D, int32_t> index_by_uv;
|
||||
|
||||
// uvs, if any
|
||||
for (size_t uvi = 0; uvi < m->GetNumUVChannels(); uvi++) {
|
||||
const auto nc = m->mNumUVComponents[uvi];
|
||||
if (nc > 2) {
|
||||
// FBX only supports 2-channel UV maps...
|
||||
// or at least i'm not sure how to indicate a different number
|
||||
std::stringstream err;
|
||||
|
|
@ -1276,71 +1245,112 @@ void FBXExporter::WriteObjects ()
|
|||
err << " but may be incorrectly interpreted on load.";
|
||||
ASSIMP_LOG_WARN(err.str());
|
||||
}
|
||||
FBX::Node uv("LayerElementUV", int32_t(uvi));
|
||||
uv.Begin(outstream, binary, indent);
|
||||
uv.DumpProperties(outstream, binary, indent);
|
||||
uv.EndProperties(outstream, binary, indent);
|
||||
uv.BeginChildren(outstream, binary, indent);
|
||||
indent = 3;
|
||||
FBX::Node::WritePropertyNode(
|
||||
"Version", int32_t(101), outstream, binary, indent
|
||||
);
|
||||
// it doesn't seem like assimp keeps the uv map name,
|
||||
// so just leave it blank.
|
||||
FBX::Node::WritePropertyNode(
|
||||
"Name", "", outstream, binary, indent
|
||||
);
|
||||
FBX::Node::WritePropertyNode(
|
||||
"MappingInformationType", "ByPolygonVertex",
|
||||
outstream, binary, indent
|
||||
);
|
||||
FBX::Node::WritePropertyNode(
|
||||
"ReferenceInformationType", "IndexToDirect",
|
||||
outstream, binary, indent
|
||||
);
|
||||
|
||||
std::vector<double> uv_data;
|
||||
std::vector<int32_t> uv_indices;
|
||||
std::map<aiVector3D,int32_t> index_by_uv;
|
||||
int32_t index = 0;
|
||||
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
|
||||
const aiFace &f = m->mFaces[fi];
|
||||
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
|
||||
const aiVector3D &curUv =
|
||||
m->mTextureCoords[uvi][f.mIndices[pvi]];
|
||||
auto elem = index_by_uv.find(curUv);
|
||||
if (elem == index_by_uv.end()) {
|
||||
index_by_uv[curUv] = index;
|
||||
uv_indices.push_back(index);
|
||||
for (unsigned int x = 0; x < m->mNumUVComponents[uvi]; ++x) {
|
||||
uv_data.push_back(curUv[x]);
|
||||
}
|
||||
++index;
|
||||
} else {
|
||||
uv_indices.push_back(elem->second);
|
||||
}
|
||||
int32_t index = static_cast<int32_t>(uv_data[uvi].size()) / nc;
|
||||
for (size_t fi = 0; fi < m->mNumFaces; fi++) {
|
||||
const aiFace &f = m->mFaces[fi];
|
||||
for (size_t pvi = 0; pvi < f.mNumIndices; pvi++) {
|
||||
const aiVector3D &curUv = m->mTextureCoords[uvi][f.mIndices[pvi]];
|
||||
auto elem = index_by_uv.find(curUv);
|
||||
if (elem == index_by_uv.end()) {
|
||||
index_by_uv[curUv] = index;
|
||||
uv_indices[uvi].push_back(index);
|
||||
for (uint32_t x = 0; x < nc; ++x) {
|
||||
uv_data[uvi].push_back(curUv[x]);
|
||||
}
|
||||
++index;
|
||||
} else {
|
||||
uv_indices[uvi].push_back(elem->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
FBX::Node::WritePropertyNode(
|
||||
"UV", uv_data, outstream, binary, indent
|
||||
);
|
||||
FBX::Node::WritePropertyNode(
|
||||
"UVIndex", uv_indices, outstream, binary, indent
|
||||
);
|
||||
indent = 2;
|
||||
uv.End(outstream, binary, indent, true);
|
||||
}
|
||||
}
|
||||
|
||||
// i'm not really sure why this material section exists,
|
||||
// as the material is linked via "Connections".
|
||||
// it seems to always have the same "0" value.
|
||||
|
||||
FBX::Node::WritePropertyNode("Vertices", flattened_vertices, outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("PolygonVertexIndex", polygon_data, outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("GeometryVersion", int32_t(124), outstream, binary, indent);
|
||||
|
||||
if (!normal_data.empty()) {
|
||||
FBX::Node normals("LayerElementNormal", int32_t(0));
|
||||
normals.Begin(outstream, binary, indent);
|
||||
normals.DumpProperties(outstream, binary, indent);
|
||||
normals.EndProperties(outstream, binary, indent);
|
||||
normals.BeginChildren(outstream, binary, indent);
|
||||
indent = 3;
|
||||
FBX::Node::WritePropertyNode("Version", int32_t(101), outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("Name", "", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("MappingInformationType", "ByPolygonVertex", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("ReferenceInformationType", "Direct", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("Normals", normal_data, outstream, binary, indent);
|
||||
// note: version 102 has a NormalsW also... not sure what it is,
|
||||
// so stick with version 101 for now.
|
||||
indent = 2;
|
||||
normals.End(outstream, binary, indent, true);
|
||||
}
|
||||
|
||||
if (!color_data.empty()) {
|
||||
const auto colorChannelIndex = 0;
|
||||
FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex));
|
||||
vertexcolors.Begin(outstream, binary, indent);
|
||||
vertexcolors.DumpProperties(outstream, binary, indent);
|
||||
vertexcolors.EndProperties(outstream, binary, indent);
|
||||
vertexcolors.BeginChildren(outstream, binary, indent);
|
||||
indent = 3;
|
||||
FBX::Node::WritePropertyNode("Version", int32_t(101), outstream, binary, indent);
|
||||
char layerName[8];
|
||||
snprintf(layerName, sizeof(layerName), "COLOR_%d", colorChannelIndex);
|
||||
FBX::Node::WritePropertyNode("Name", (const char *)layerName, outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("MappingInformationType", "ByPolygonVertex", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("ReferenceInformationType", "Direct", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("Colors", color_data, outstream, binary, indent);
|
||||
indent = 2;
|
||||
vertexcolors.End(outstream, binary, indent, true);
|
||||
}
|
||||
|
||||
for (uint32_t uvi = 0; uvi < uv_data.size(); uvi++) {
|
||||
FBX::Node uv("LayerElementUV", int32_t(uvi));
|
||||
uv.Begin(outstream, binary, indent);
|
||||
uv.DumpProperties(outstream, binary, indent);
|
||||
uv.EndProperties(outstream, binary, indent);
|
||||
uv.BeginChildren(outstream, binary, indent);
|
||||
indent = 3;
|
||||
FBX::Node::WritePropertyNode("Version", int32_t(101), outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("Name", "", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("MappingInformationType", "ByPolygonVertex", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("ReferenceInformationType", "IndexToDirect", outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("UV", uv_data[uvi], outstream, binary, indent);
|
||||
FBX::Node::WritePropertyNode("UVIndex", uv_indices[uvi], outstream, binary, indent);
|
||||
indent = 2;
|
||||
uv.End(outstream, binary, indent, true);
|
||||
}
|
||||
|
||||
|
||||
// When merging multiple meshes, we instead use by polygon so the correct material is
|
||||
// assigned to each face. Previously, this LayerElementMaterial always had 0 since it
|
||||
// assumed there was 1 material for each node for all meshes.
|
||||
FBX::Node mat("LayerElementMaterial", int32_t(0));
|
||||
mat.AddChild("Version", int32_t(101));
|
||||
mat.AddChild("Name", "");
|
||||
mat.AddChild("MappingInformationType", "AllSame");
|
||||
mat.AddChild("ReferenceInformationType", "IndexToDirect");
|
||||
std::vector<int32_t> mat_indices = {0};
|
||||
mat.AddChild("Materials", mat_indices);
|
||||
if (node->mNumMeshes == 1) {
|
||||
mat.AddChild("MappingInformationType", "AllSame");
|
||||
mat.AddChild("ReferenceInformationType", "IndexToDirect");
|
||||
std::vector<int32_t> mat_indices = {0};
|
||||
mat.AddChild("Materials", mat_indices);
|
||||
} else {
|
||||
mat.AddChild("MappingInformationType", "ByPolygon");
|
||||
mat.AddChild("ReferenceInformationType", "IndexToDirect");
|
||||
std::vector<int32_t> mat_indices;
|
||||
for (uint32_t n_mi = 0; n_mi < node->mNumMeshes; n_mi++) {
|
||||
const auto mi = node->mMeshes[n_mi];
|
||||
const auto *const m = mScene->mMeshes[mi];
|
||||
for (size_t fi = 0; fi < m->mNumFaces; fi++) {
|
||||
mat_indices.push_back(n_mi);
|
||||
}
|
||||
}
|
||||
mat.AddChild("Materials", mat_indices);
|
||||
}
|
||||
mat.Dump(outstream, binary, indent);
|
||||
|
||||
// finally we have the layer specifications,
|
||||
|
|
@ -1348,16 +1358,20 @@ void FBXExporter::WriteObjects ()
|
|||
// TODO: handle multiple uv sets correctly?
|
||||
FBX::Node layer("Layer", int32_t(0));
|
||||
layer.AddChild("Version", int32_t(100));
|
||||
FBX::Node le("LayerElement");
|
||||
le.AddChild("Type", "LayerElementNormal");
|
||||
le.AddChild("TypedIndex", int32_t(0));
|
||||
layer.AddChild(le);
|
||||
FBX::Node le;
|
||||
|
||||
for (size_t ci = 0; ci < m->GetNumColorChannels(); ++ci) {
|
||||
le = FBX::Node("LayerElement");
|
||||
le.AddChild("Type", "LayerElementColor");
|
||||
le.AddChild("TypedIndex", int32_t(ci));
|
||||
layer.AddChild(le);
|
||||
if (!normal_data.empty()) {
|
||||
le = FBX::Node("LayerElement");
|
||||
le.AddChild("Type", "LayerElementNormal");
|
||||
le.AddChild("TypedIndex", int32_t(0));
|
||||
layer.AddChild(le);
|
||||
}
|
||||
|
||||
if (!color_data.empty()) {
|
||||
le = FBX::Node("LayerElement");
|
||||
le.AddChild("Type", "LayerElementColor");
|
||||
le.AddChild("TypedIndex", int32_t(0));
|
||||
layer.AddChild(le);
|
||||
}
|
||||
|
||||
le = FBX::Node("LayerElement");
|
||||
|
|
@ -1370,8 +1384,7 @@ void FBXExporter::WriteObjects ()
|
|||
layer.AddChild(le);
|
||||
layer.Dump(outstream, binary, indent);
|
||||
|
||||
for(unsigned int lr = 1; lr < m->GetNumUVChannels(); ++ lr)
|
||||
{
|
||||
for(unsigned int lr = 1; lr < uv_data.size(); ++ lr) {
|
||||
FBX::Node layerExtra("Layer", int32_t(lr));
|
||||
layerExtra.AddChild("Version", int32_t(100));
|
||||
FBX::Node leExtra("LayerElement");
|
||||
|
|
@ -1383,7 +1396,14 @@ void FBXExporter::WriteObjects ()
|
|||
// finish the node record
|
||||
indent = 1;
|
||||
n.End(outstream, binary, indent, true);
|
||||
}
|
||||
|
||||
for (uint32_t ni = 0; ni < node->mNumChildren; ni++) {
|
||||
visit_node_geo(node->mChildren[ni]);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
visit_node_geo(mScene->mRootNode);
|
||||
|
||||
|
||||
// aiMaterial
|
||||
|
|
@ -1562,6 +1582,7 @@ void FBXExporter::WriteObjects ()
|
|||
}
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> tpath_by_image;
|
||||
// FbxVideo - stores images used by textures.
|
||||
for (const auto &it : uid_by_image) {
|
||||
FBX::Node n("Video");
|
||||
|
|
@ -1581,10 +1602,21 @@ void FBXExporter::WriteObjects ()
|
|||
std::stringstream newPath;
|
||||
if (embedded_texture->mFilename.length > 0) {
|
||||
newPath << embedded_texture->mFilename.C_Str();
|
||||
// If newPath doesn't end in an extension, add extension from embedded_texture->achFormatHint
|
||||
std::string np = newPath.str();
|
||||
size_t dot_pos = np.find_last_of('.');
|
||||
if (dot_pos == std::string::npos || dot_pos < np.find_last_of("/\\")) {
|
||||
// No extension found, add one
|
||||
newPath << "." << embedded_texture->achFormatHint;
|
||||
}
|
||||
} else if (embedded_texture->achFormatHint[0]) {
|
||||
int texture_index = std::stoi(path.substr(1, path.size() - 1));
|
||||
newPath << texture_index << "." << embedded_texture->achFormatHint;
|
||||
}
|
||||
auto elem = tpath_by_image.find(path);
|
||||
if (elem == tpath_by_image.end()) {
|
||||
tpath_by_image[path] = newPath.str();
|
||||
}
|
||||
path = newPath.str();
|
||||
// embed the texture
|
||||
size_t texture_size = static_cast<size_t>(embedded_texture->mWidth * std::max(embedded_texture->mHeight, 1u));
|
||||
|
|
@ -1703,6 +1735,17 @@ void FBXExporter::WriteObjects ()
|
|||
unsigned int max = sizeof(aiUVTransform);
|
||||
aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE, 0), (ai_real *)&trafo, &max);
|
||||
|
||||
auto tp_elem = tpath_by_image.find(texture_path);
|
||||
std::string tfile_path = texture_path;
|
||||
if (tp_elem != tpath_by_image.end()) {
|
||||
tfile_path = tp_elem->second;
|
||||
} else {
|
||||
std::stringstream err;
|
||||
err << "Texture path not found for texure " << texture_path;
|
||||
err << " on material " << i;
|
||||
ASSIMP_LOG_WARN(err.str());
|
||||
}
|
||||
|
||||
// now write the actual texture node
|
||||
FBX::Node tnode("Texture");
|
||||
// TODO: some way to determine texture name?
|
||||
|
|
@ -1723,8 +1766,8 @@ void FBXExporter::WriteObjects ()
|
|||
// can't easily determine which texture path will be correct,
|
||||
// so just store what we have in every field.
|
||||
// these being incorrect is a common problem with FBX anyway.
|
||||
tnode.AddChild("FileName", texture_path);
|
||||
tnode.AddChild("RelativeFilename", texture_path);
|
||||
tnode.AddChild("FileName", tfile_path);
|
||||
tnode.AddChild("RelativeFilename", tfile_path);
|
||||
tnode.AddChild("ModelUVTranslation", double(0.0), double(0.0));
|
||||
tnode.AddChild("ModelUVScaling", double(1.0), double(1.0));
|
||||
tnode.AddChild("Texture_Alpha_Source", "None");
|
||||
|
|
@ -1748,7 +1791,8 @@ void FBXExporter::WriteObjects ()
|
|||
dnode.AddChild("Version", int32_t(101));
|
||||
dnode.Dump(outstream, binary, indent);
|
||||
// connect it
|
||||
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]);
|
||||
const auto node = get_node_for_mesh((unsigned int)mi, mScene->mRootNode);
|
||||
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[node]);
|
||||
std::vector<int32_t> vertex_indices = vVertexIndice[mi];
|
||||
|
||||
for (unsigned int am = 0; am < m->mNumAnimMeshes; ++am) {
|
||||
|
|
@ -1758,7 +1802,7 @@ void FBXExporter::WriteObjects ()
|
|||
// start the node record
|
||||
FBX::Node bsnode("Geometry");
|
||||
int64_t blendshape_uid = generate_uid();
|
||||
mesh_uids.push_back(blendshape_uid);
|
||||
blendshape_uids.push_back(blendshape_uid);
|
||||
bsnode.AddProperty(blendshape_uid);
|
||||
bsnode.AddProperty(blendshape_name + FBX::SEPARATOR + "Geometry");
|
||||
bsnode.AddProperty("Shape");
|
||||
|
|
@ -1945,22 +1989,15 @@ void FBXExporter::WriteObjects ()
|
|||
// otherwise check if this is the root of the skeleton
|
||||
bool end = false;
|
||||
// is the mesh part of this node?
|
||||
for (size_t i = 0; i < parent->mNumMeshes; ++i) {
|
||||
if (parent->mMeshes[i] == mi) {
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
for (size_t i = 0; i < parent->mNumMeshes && !end; ++i) {
|
||||
end |= parent->mMeshes[i] == mi;
|
||||
}
|
||||
// is the mesh in one of the children of this node?
|
||||
for (size_t j = 0; j < parent->mNumChildren; ++j) {
|
||||
for (size_t j = 0; j < parent->mNumChildren && !end; ++j) {
|
||||
aiNode* child = parent->mChildren[j];
|
||||
for (size_t i = 0; i < child->mNumMeshes; ++i) {
|
||||
if (child->mMeshes[i] == mi) {
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
for (size_t i = 0; i < child->mNumMeshes && !end; ++i) {
|
||||
end |= child->mMeshes[i] == mi;
|
||||
}
|
||||
if (end) { break; }
|
||||
}
|
||||
|
||||
// if it was the skeleton root we can finish here
|
||||
|
|
@ -1974,8 +2011,7 @@ void FBXExporter::WriteObjects ()
|
|||
for (size_t i = 0; i < mScene->mNumMeshes; ++i) {
|
||||
auto &s = skeleton_by_mesh[i];
|
||||
for (const aiNode* n : s) {
|
||||
auto elem = node_uids.find(n);
|
||||
if (elem == node_uids.end()) {
|
||||
if (node_uids.find(n) == node_uids.end()) {
|
||||
node_uids[n] = generate_uid();
|
||||
}
|
||||
}
|
||||
|
|
@ -1991,6 +2027,8 @@ void FBXExporter::WriteObjects ()
|
|||
if (!m->HasBones()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const aiNode *mesh_node = get_node_for_mesh((uint32_t)mi, mScene->mRootNode);
|
||||
// make a deformer for this mesh
|
||||
int64_t deformer_uid = generate_uid();
|
||||
FBX::Node dnode("Deformer");
|
||||
|
|
@ -2002,10 +2040,7 @@ void FBXExporter::WriteObjects ()
|
|||
dnode.Dump(outstream, binary, indent);
|
||||
|
||||
// connect it
|
||||
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]);
|
||||
|
||||
//computed before
|
||||
std::vector<int32_t>& vertex_indices = vVertexIndice[mi];
|
||||
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mesh_node]);
|
||||
|
||||
// TODO, FIXME: this won't work if anything is not in the bind pose.
|
||||
// for now if such a situation is detected, we throw an exception.
|
||||
|
|
@ -2019,7 +2054,6 @@ void FBXExporter::WriteObjects ()
|
|||
// as it can be instanced to many nodes.
|
||||
// All we can do is assume no instancing,
|
||||
// and take the first node we find that contains the mesh.
|
||||
aiNode* mesh_node = get_node_for_mesh((unsigned int)mi, mScene->mRootNode);
|
||||
aiMatrix4x4 mesh_xform = get_world_transform(mesh_node, mScene);
|
||||
|
||||
// now make a subdeformer for each bone in the skeleton
|
||||
|
|
@ -2048,14 +2082,19 @@ void FBXExporter::WriteObjects ()
|
|||
sdnode.AddChild("Version", int32_t(100));
|
||||
sdnode.AddChild("UserData", "", "");
|
||||
|
||||
std::set<int32_t> setWeightedVertex;
|
||||
// add indices and weights, if any
|
||||
if (b) {
|
||||
std::set<int32_t> setWeightedVertex;
|
||||
std::vector<int32_t> subdef_indices;
|
||||
std::vector<double> subdef_weights;
|
||||
int32_t last_index = -1;
|
||||
for (size_t wi = 0; wi < b->mNumWeights; ++wi) {
|
||||
int32_t vi = vertex_indices[b->mWeights[wi].mVertexId];
|
||||
if (b->mWeights[wi].mVertexId >= vVertexIndice[mi].size()) {
|
||||
ASSIMP_LOG_ERROR("UNREAL: Skipping vertex index to prevent buffer overflow.");
|
||||
continue;
|
||||
}
|
||||
int32_t vi = vVertexIndice[mi][b->mWeights[wi].mVertexId]
|
||||
+ uniq_v_before_mi[mi];
|
||||
bool bIsWeightedAlready = (setWeightedVertex.find(vi) != setWeightedVertex.end());
|
||||
if (vi == last_index || bIsWeightedAlready) {
|
||||
// only for vertices we exported to fbx
|
||||
|
|
@ -2535,9 +2574,9 @@ void add_meta(FBX::Node& fbx_node, const aiNode* node){
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// write a single model node to the stream
|
||||
|
|
@ -2702,9 +2741,8 @@ void FBXExporter::WriteModelNodes(
|
|||
// handled later
|
||||
} else if (node->mNumMeshes == 1) {
|
||||
// connect to child mesh, which should have been written previously
|
||||
connections.emplace_back(
|
||||
"C", "OO", mesh_uids[node->mMeshes[0]], node_uid
|
||||
);
|
||||
// TODO double check this line
|
||||
connections.emplace_back("C", "OO", mesh_uids[node], node_uid);
|
||||
// also connect to the material for the child mesh
|
||||
connections.emplace_back(
|
||||
"C", "OO",
|
||||
|
|
@ -2729,6 +2767,16 @@ void FBXExporter::WriteModelNodes(
|
|||
na.Dump(outstream, binary, 1);
|
||||
// and connect them
|
||||
connections.emplace_back("C", "OO", node_attribute_uid, node_uid);
|
||||
} else if (node->mNumMeshes >= 1) {
|
||||
connections.emplace_back("C", "OO", mesh_uids[node], node_uid);
|
||||
for (size_t i = 0; i < node->mNumMeshes; i++) {
|
||||
connections.emplace_back(
|
||||
"C", "OO",
|
||||
material_uids[mScene->mMeshes[node->mMeshes[i]]->mMaterialIndex],
|
||||
node_uid
|
||||
);
|
||||
}
|
||||
WriteModelNode(outstream, binary, node, node_uid, "Mesh", transform_chain);
|
||||
} else {
|
||||
const auto& lightIt = lights_uids.find(node->mName.C_Str());
|
||||
if(lightIt != lights_uids.end()) {
|
||||
|
|
@ -2745,34 +2793,20 @@ void FBXExporter::WriteModelNodes(
|
|||
}
|
||||
}
|
||||
|
||||
// if more than one child mesh, make nodes for each mesh
|
||||
if (node->mNumMeshes > 1 || node == mScene->mRootNode) {
|
||||
for (size_t i = 0; i < node->mNumMeshes; ++i) {
|
||||
// make a new model node
|
||||
int64_t new_node_uid = generate_uid();
|
||||
// connect to parent node
|
||||
connections.emplace_back("C", "OO", new_node_uid, node_uid);
|
||||
// connect to child mesh, which should have been written previously
|
||||
connections.emplace_back(
|
||||
"C", "OO", mesh_uids[node->mMeshes[i]], new_node_uid
|
||||
);
|
||||
// also connect to the material for the child mesh
|
||||
connections.emplace_back(
|
||||
"C", "OO",
|
||||
material_uids[
|
||||
mScene->mMeshes[node->mMeshes[i]]->mMaterialIndex
|
||||
],
|
||||
new_node_uid
|
||||
);
|
||||
|
||||
aiNode new_node;
|
||||
// take name from mesh name, if it exists
|
||||
new_node.mName = mScene->mMeshes[node->mMeshes[i]]->mName;
|
||||
// write model node
|
||||
WriteModelNode(
|
||||
outstream, binary, &new_node, new_node_uid, "Mesh", std::vector<std::pair<std::string,aiVector3D>>()
|
||||
);
|
||||
}
|
||||
if (node == mScene->mRootNode && node->mNumMeshes > 0) {
|
||||
int64_t new_node_uid = generate_uid();
|
||||
connections.emplace_back("C", "OO", new_node_uid, node_uid);
|
||||
connections.emplace_back("C", "OO", mesh_uids[node], new_node_uid);
|
||||
for (size_t i = 0; i < node->mNumMeshes; ++i) {
|
||||
connections.emplace_back(
|
||||
"C", "OO",
|
||||
material_uids[mScene->mMeshes[node->mMeshes[i]]->mMaterialIndex],
|
||||
new_node_uid
|
||||
);
|
||||
}
|
||||
aiNode new_node;
|
||||
new_node.mName = mScene->mMeshes[0]->mName;
|
||||
WriteModelNode(outstream, binary, &new_node, new_node_uid, "Mesh", {});
|
||||
}
|
||||
|
||||
// now recurse into children
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "FBXCommon.h" // FBX::TransformInheritance
|
||||
|
||||
#include <assimp/types.h>
|
||||
//#include <assimp/material.h>
|
||||
#include <assimp/StreamWriter.h> // StreamWriterLE
|
||||
#include <assimp/Exceptional.h> // DeadlyExportError
|
||||
|
||||
|
|
@ -91,7 +90,8 @@ namespace Assimp {
|
|||
|
||||
std::vector<FBX::Node> connections; // connection storage
|
||||
|
||||
std::vector<int64_t> mesh_uids;
|
||||
std::map<const aiNode*, int64_t> mesh_uids;
|
||||
std::vector<int64_t> blendshape_uids;
|
||||
std::vector<int64_t> material_uids;
|
||||
std::map<const aiNode*,int64_t> node_uids;
|
||||
std::map<std::string,int64_t> lights_uids;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ namespace {
|
|||
// Returns whether the class can handle the format of the given file.
|
||||
bool FBXImporter::CanRead(const std::string & pFile, IOSystem * pIOHandler, bool /*checkSig*/) const {
|
||||
// at least ASCII-FBX files usually have a 'FBX' somewhere in their head
|
||||
static const char *tokens[] = { " \n\r\n " };
|
||||
static const char *tokens[] = { " \n\r\n ", "fbx" };
|
||||
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>
|
|||
///
|
||||
/// See http://en.wikipedia.org/wiki/FBX
|
||||
// -------------------------------------------------------------------------------------------
|
||||
class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> {
|
||||
class FBXImporter final : public BaseImporter, public LogFunctions<FBXImporter> {
|
||||
public:
|
||||
/// @brief The class constructor.
|
||||
FBXImporter() = default;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -134,10 +134,6 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Material::~Material() = default;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
|
||||
Object(id,element,name),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
#include "FBXMeshGeometry.h"
|
||||
|
|
@ -69,8 +70,10 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
|
|||
}
|
||||
const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element);
|
||||
if (bsp) {
|
||||
auto pr = blendShapes.insert(bsp);
|
||||
if (!pr.second) {
|
||||
// Only add a blendshape if it doesn't exist already
|
||||
if (std::find(blendShapes.begin(), blendShapes.end(), bsp) == blendShapes.end()) {
|
||||
blendShapes.push_back(bsp);
|
||||
} else {
|
||||
FBXImporter::LogWarn("there is the same blendShape id ", bsp->ID());
|
||||
}
|
||||
}
|
||||
|
|
@ -78,7 +81,7 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const std::unordered_set<const BlendShape*>& Geometry::GetBlendShapes() const {
|
||||
const std::vector<const BlendShape*>& Geometry::GetBlendShapes() const {
|
||||
return blendShapes;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -72,11 +72,11 @@ public:
|
|||
|
||||
/// @brief Get the BlendShape attached to this geometry or nullptr
|
||||
/// @return The blendshape arrays.
|
||||
const std::unordered_set<const BlendShape*>& GetBlendShapes() const;
|
||||
const std::vector<const BlendShape*>& GetBlendShapes() const;
|
||||
|
||||
private:
|
||||
const Skin* skin;
|
||||
std::unordered_set<const BlendShape*> blendShapes;
|
||||
std::vector<const BlendShape*> blendShapes;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -365,10 +365,14 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
|
|||
}
|
||||
|
||||
if (data[0] == 'F') {
|
||||
return SafeParse<float>(data+1, t.end());
|
||||
BE_NCONST float id = SafeParse<float>(data+1, t.end());
|
||||
AI_SWAP4(id);
|
||||
return id;
|
||||
}
|
||||
else {
|
||||
return static_cast<float>( SafeParse<double>(data+1, t.end()) );
|
||||
BE_NCONST double id = SafeParse<double>(data+1, t.end());
|
||||
AI_SWAP8(id);
|
||||
return static_cast<float>(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -637,9 +641,15 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
|
|||
if (type == 'd') {
|
||||
const double* d = reinterpret_cast<const double*>(&buff[0]);
|
||||
for (unsigned int i = 0; i < count3; ++i, d += 3) {
|
||||
out.emplace_back(static_cast<ai_real>(d[0]),
|
||||
static_cast<ai_real>(d[1]),
|
||||
static_cast<ai_real>(d[2]));
|
||||
BE_NCONST double val1 = d[0];
|
||||
BE_NCONST double val2 = d[1];
|
||||
BE_NCONST double val3 = d[2];
|
||||
AI_SWAP8(val1);
|
||||
AI_SWAP8(val2);
|
||||
AI_SWAP8(val3);
|
||||
out.emplace_back(static_cast<ai_real>(val1),
|
||||
static_cast<ai_real>(val2),
|
||||
static_cast<ai_real>(val3));
|
||||
}
|
||||
// for debugging
|
||||
/*for ( size_t i = 0; i < out.size(); i++ ) {
|
||||
|
|
@ -652,7 +662,13 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
|
|||
else if (type == 'f') {
|
||||
const float* f = reinterpret_cast<const float*>(&buff[0]);
|
||||
for (unsigned int i = 0; i < count3; ++i, f += 3) {
|
||||
out.emplace_back(f[0],f[1],f[2]);
|
||||
BE_NCONST float val1 = f[0];
|
||||
BE_NCONST float val2 = f[1];
|
||||
BE_NCONST float val3 = f[2];
|
||||
AI_SWAP4(val1);
|
||||
AI_SWAP4(val2);
|
||||
AI_SWAP4(val3);
|
||||
out.emplace_back(val1,val2,val3);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -726,16 +742,32 @@ void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
|
|||
if (type == 'd') {
|
||||
const double* d = reinterpret_cast<const double*>(&buff[0]);
|
||||
for (unsigned int i = 0; i < count4; ++i, d += 4) {
|
||||
out.emplace_back(static_cast<float>(d[0]),
|
||||
static_cast<float>(d[1]),
|
||||
static_cast<float>(d[2]),
|
||||
static_cast<float>(d[3]));
|
||||
BE_NCONST double val1 = d[0];
|
||||
BE_NCONST double val2 = d[1];
|
||||
BE_NCONST double val3 = d[2];
|
||||
BE_NCONST double val4 = d[3];
|
||||
AI_SWAP8(val1);
|
||||
AI_SWAP8(val2);
|
||||
AI_SWAP8(val3);
|
||||
AI_SWAP8(val4);
|
||||
out.emplace_back(static_cast<float>(val1),
|
||||
static_cast<float>(val2),
|
||||
static_cast<float>(val3),
|
||||
static_cast<float>(val4));
|
||||
}
|
||||
}
|
||||
else if (type == 'f') {
|
||||
const float* f = reinterpret_cast<const float*>(&buff[0]);
|
||||
for (unsigned int i = 0; i < count4; ++i, f += 4) {
|
||||
out.emplace_back(f[0],f[1],f[2],f[3]);
|
||||
BE_NCONST float val1 = f[0];
|
||||
BE_NCONST float val2 = f[1];
|
||||
BE_NCONST float val3 = f[2];
|
||||
BE_NCONST float val4 = f[3];
|
||||
AI_SWAP4(val1);
|
||||
AI_SWAP4(val2);
|
||||
AI_SWAP4(val3);
|
||||
AI_SWAP4(val4);
|
||||
out.emplace_back(val1,val2,val3,val4);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
@ -807,13 +839,21 @@ void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el) {
|
|||
if (type == 'd') {
|
||||
const double* d = reinterpret_cast<const double*>(&buff[0]);
|
||||
for (unsigned int i = 0; i < count2; ++i, d += 2) {
|
||||
out.emplace_back(static_cast<float>(d[0]),
|
||||
static_cast<float>(d[1]));
|
||||
BE_NCONST double val1 = d[0];
|
||||
BE_NCONST double val2 = d[1];
|
||||
AI_SWAP8(val1);
|
||||
AI_SWAP8(val2);
|
||||
out.emplace_back(static_cast<float>(val1),
|
||||
static_cast<float>(val2));
|
||||
}
|
||||
} else if (type == 'f') {
|
||||
const float* f = reinterpret_cast<const float*>(&buff[0]);
|
||||
for (unsigned int i = 0; i < count2; ++i, f += 2) {
|
||||
out.emplace_back(f[0],f[1]);
|
||||
BE_NCONST float val1 = f[0];
|
||||
BE_NCONST float val2 = f[1];
|
||||
AI_SWAP4(val1);
|
||||
AI_SWAP4(val2);
|
||||
out.emplace_back(val1,val2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -938,13 +978,17 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
|
|||
if (type == 'd') {
|
||||
const double* d = reinterpret_cast<const double*>(&buff[0]);
|
||||
for (unsigned int i = 0; i < count; ++i, ++d) {
|
||||
out.push_back(static_cast<float>(*d));
|
||||
BE_NCONST double val = *d;
|
||||
AI_SWAP8(val);
|
||||
out.push_back(static_cast<float>(val));
|
||||
}
|
||||
}
|
||||
else if (type == 'f') {
|
||||
const float* f = reinterpret_cast<const float*>(&buff[0]);
|
||||
for (unsigned int i = 0; i < count; ++i, ++f) {
|
||||
out.push_back(*f);
|
||||
BE_NCONST float val = *f;
|
||||
AI_SWAP4(val);
|
||||
out.push_back(val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ class Parser;
|
|||
class Element;
|
||||
|
||||
using ScopeList = std::vector<Scope*>;
|
||||
using ElementMap = std::fbx_unordered_multimap< std::string, Element*>;
|
||||
using ElementMap = std::multimap< std::string, Element*>;
|
||||
using ElementCollection = std::pair<ElementMap::const_iterator,ElementMap::const_iterator>;
|
||||
|
||||
#define new_Scope new (allocator.Allocate(sizeof(Scope))) Scope
|
||||
|
|
@ -82,10 +82,9 @@ using ElementCollection = std::pair<ElementMap::const_iterator,ElementMap::const
|
|||
* @endverbatim
|
||||
*
|
||||
* As can be seen in this sample, elements can contain nested #Scope
|
||||
* as their trailing member.
|
||||
* as their trailing member.
|
||||
**/
|
||||
class Element
|
||||
{
|
||||
class Element {
|
||||
public:
|
||||
Element(const Token& key_token, Parser& parser);
|
||||
~Element();
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -57,15 +56,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
||||
using namespace Util;
|
||||
using namespace Util;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Property::Property() = default;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Property::~Property() = default;
|
||||
|
||||
namespace {
|
||||
namespace {
|
||||
|
||||
void checkTokenCount(const TokenList &tok, unsigned int expectedCount) {
|
||||
ai_assert(expectedCount >= 2);
|
||||
|
|
@ -146,9 +141,9 @@ Property* ReadTypedProperty(const Element& element)
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// peek into an element and check if it contains a FBX property, if so return its name.
|
||||
std::string PeekPropertyName(const Element& element)
|
||||
{
|
||||
std::string PeekPropertyName(const Element& element) {
|
||||
ai_assert(element.KeyToken().StringContents() == "P");
|
||||
|
||||
const TokenList& tok = element.Tokens();
|
||||
if(tok.size() < 4) {
|
||||
return std::string();
|
||||
|
|
@ -160,13 +155,6 @@ std::string PeekPropertyName(const Element& element)
|
|||
} //! anon
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
PropertyTable::PropertyTable()
|
||||
: templateProps()
|
||||
, element()
|
||||
{
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
PropertyTable::PropertyTable(const Element &element, std::shared_ptr<const PropertyTable> templateProps) :
|
||||
templateProps(std::move(templateProps)), element(&element) {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -56,34 +55,33 @@ namespace FBX {
|
|||
// Forward declarations
|
||||
class Element;
|
||||
|
||||
/** Represents a dynamic property. Type info added by deriving classes,
|
||||
* see #TypedProperty.
|
||||
Example:
|
||||
@verbatim
|
||||
P: "ShininessExponent", "double", "Number", "",0.5
|
||||
@endvebatim
|
||||
*/
|
||||
/**
|
||||
* Represents a dynamic property. Type info added by deriving classes,
|
||||
* see #TypedProperty.
|
||||
* Example:
|
||||
*
|
||||
* @verbatim
|
||||
* P: "ShininessExponent", "double", "Number", "",0.5
|
||||
* @endvebatim
|
||||
*/
|
||||
class Property {
|
||||
protected:
|
||||
Property();
|
||||
|
||||
public:
|
||||
virtual ~Property();
|
||||
virtual ~Property() = default;
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
const T* As() const {
|
||||
return dynamic_cast<const T*>(this);
|
||||
}
|
||||
|
||||
protected:
|
||||
Property() = default;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class TypedProperty : public Property {
|
||||
public:
|
||||
explicit TypedProperty(const T& value)
|
||||
: value(value) {
|
||||
// empty
|
||||
}
|
||||
explicit TypedProperty(const T& value) : value(value) {}
|
||||
|
||||
const T& Value() const {
|
||||
return value;
|
||||
|
|
@ -93,10 +91,9 @@ private:
|
|||
T value;
|
||||
};
|
||||
|
||||
|
||||
typedef std::fbx_unordered_map<std::string,std::shared_ptr<Property> > DirectPropertyMap;
|
||||
typedef std::fbx_unordered_map<std::string,const Property*> PropertyMap;
|
||||
typedef std::fbx_unordered_map<std::string,const Element*> LazyPropertyMap;
|
||||
using DirectPropertyMap = std::fbx_unordered_map<std::string,std::shared_ptr<Property> >;
|
||||
using PropertyMap = std::fbx_unordered_map<std::string,const Property*>;
|
||||
using LazyPropertyMap = std::fbx_unordered_map<std::string,const Element*>;
|
||||
|
||||
/**
|
||||
* Represents a property table as can be found in the newer FBX files (Properties60, Properties70)
|
||||
|
|
@ -104,7 +101,7 @@ typedef std::fbx_unordered_map<std::string,const Element*> LazyPrope
|
|||
class PropertyTable {
|
||||
public:
|
||||
// in-memory property table with no source element
|
||||
PropertyTable();
|
||||
PropertyTable() : element() {}
|
||||
PropertyTable(const Element& element, std::shared_ptr<const PropertyTable> templateProps);
|
||||
~PropertyTable();
|
||||
|
||||
|
|
@ -130,8 +127,7 @@ private:
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline
|
||||
T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) {
|
||||
inline T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) {
|
||||
const Property* const prop = in.Get(name);
|
||||
if( nullptr == prop) {
|
||||
return defaultValue;
|
||||
|
|
@ -148,8 +144,7 @@ T PropertyGet(const PropertyTable& in, const std::string& name, const T& default
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline
|
||||
T PropertyGet(const PropertyTable& in, const std::string& name, bool& result, bool useTemplate=false ) {
|
||||
inline T PropertyGet(const PropertyTable& in, const std::string& name, bool& result, bool useTemplate=false ) {
|
||||
const Property* prop = in.Get(name);
|
||||
if( nullptr == prop) {
|
||||
if ( ! useTemplate ) {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -51,11 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
namespace Util {
|
||||
namespace Assimp::FBX::Util {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const char* TokenTypeString(TokenType t)
|
||||
|
|
@ -234,8 +229,5 @@ std::string EncodeBase64(const char* data, size_t length)
|
|||
return encoded_string;
|
||||
}
|
||||
|
||||
} // !Util
|
||||
} // !FBX
|
||||
} // !Assimp
|
||||
} // namespace Assimp::FBX::Util
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2024, assimp team
|
||||
|
||||
Copyright (c) 2006-2026, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
@ -50,12 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "FBXTokenizer.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
||||
|
||||
namespace Util {
|
||||
|
||||
namespace Assimp::FBX::Util {
|
||||
|
||||
/** helper for std::for_each to delete all heap-allocated items in a container */
|
||||
template<typename T>
|
||||
|
|
@ -76,19 +70,15 @@ struct destructor_fun {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/** Get a string representation for a #TokenType. */
|
||||
const char* TokenTypeString(TokenType t);
|
||||
|
||||
|
||||
|
||||
/** Format log/error messages using a given offset in the source binary file
|
||||
*
|
||||
* @param offset offset within the file
|
||||
* @return A string of the following format: " (offset 0x{offset}) "*/
|
||||
std::string GetOffsetText(size_t offset);
|
||||
|
||||
|
||||
/** Format log/error messages using a given line location in the source file.
|
||||
*
|
||||
* @param line Line index, 1-based
|
||||
|
|
@ -96,7 +86,6 @@ std::string GetOffsetText(size_t offset);
|
|||
* @return A string of the following format: " (line {line}, col {column}) "*/
|
||||
std::string GetLineAndColumnText(unsigned int line, unsigned int column);
|
||||
|
||||
|
||||
/** Format log/error messages using a given cursor token.
|
||||
*
|
||||
* @param tok Token where parsing/processing stopped
|
||||
|
|
@ -134,8 +123,6 @@ char EncodeBase64(char byte);
|
|||
* @return base64-encoded string*/
|
||||
std::string EncodeBase64(const char* data, size_t length);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ! INCLUDED_AI_FBX_UTIL_H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue