- fbx: initial code to read animations plus the accompanying DOM classes.
parent
ab93c6f38e
commit
67c55990cd
|
@ -414,6 +414,7 @@ SET(FBX_SRCS
|
||||||
FBXMeshGeometry.cpp
|
FBXMeshGeometry.cpp
|
||||||
FBXMaterial.cpp
|
FBXMaterial.cpp
|
||||||
FBXModel.cpp
|
FBXModel.cpp
|
||||||
|
FBXAnimation.cpp
|
||||||
)
|
)
|
||||||
SOURCE_GROUP( FBX FILES ${FBX_SRCS})
|
SOURCE_GROUP( FBX FILES ${FBX_SRCS})
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2012, assimp team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
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.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file FBXAnimation.cpp
|
||||||
|
* @brief Assimp::FBX::AnimationCurve, Assimp::FBX::AnimationCurveNode,
|
||||||
|
* Assimp::FBX::AnimationLayer, Assimp::FBX::AnimationStack
|
||||||
|
*/
|
||||||
|
#include "AssimpPCH.h"
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||||
|
|
||||||
|
#include "FBXParser.h"
|
||||||
|
#include "FBXDocument.h"
|
||||||
|
#include "FBXImporter.h"
|
||||||
|
#include "FBXImportSettings.h"
|
||||||
|
#include "FBXDocumentUtil.h"
|
||||||
|
#include "FBXProperties.h"
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
namespace FBX {
|
||||||
|
|
||||||
|
using namespace Util;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||||
|
: Object(id, element, name)
|
||||||
|
{
|
||||||
|
const Scope& sc = GetRequiredScope(element);
|
||||||
|
const Element& KeyTime = GetRequiredElement(sc,"KeyTime");
|
||||||
|
const Element& KeyValueFloat = GetRequiredElement(sc,"KeyValueFloat");
|
||||||
|
|
||||||
|
ReadVectorDataArray(keys, KeyTime);
|
||||||
|
ReadVectorDataArray(values, KeyValueFloat);
|
||||||
|
|
||||||
|
if(keys.size() != values.size()) {
|
||||||
|
DOMError("the number of key times does not match the number of keyframe values",&KeyTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Element* KeyAttrDataFloat = sc["KeyAttrDataFloat"];
|
||||||
|
if(KeyAttrDataFloat) {
|
||||||
|
ReadVectorDataArray(attributes, *KeyAttrDataFloat);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Element* KeyAttrFlags = sc["KeyAttrFlags"];
|
||||||
|
if(KeyAttrFlags) {
|
||||||
|
flags = ParseTokenAsInt(GetRequiredToken(*KeyAttrFlags,0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AnimationCurve::~AnimationCurve()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||||
|
: Object(id, element, name)
|
||||||
|
{
|
||||||
|
// resolve attached animation curves
|
||||||
|
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Connection* con, conns) {
|
||||||
|
|
||||||
|
// link should go for a property
|
||||||
|
if (con->PropertyName().length()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Object* const ob = con->SourceObject();
|
||||||
|
if(!ob) {
|
||||||
|
DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring",&element);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AnimationCurve* const anim = dynamic_cast<const AnimationCurve*>(ob);
|
||||||
|
if(!anim) {
|
||||||
|
DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve",&element);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
curves[con->PropertyName()] = anim;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AnimationCurveNode::~AnimationCurveNode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||||
|
: Object(id, element, name)
|
||||||
|
{
|
||||||
|
const Scope& sc = GetRequiredScope(element);
|
||||||
|
props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc);
|
||||||
|
|
||||||
|
// resolve attached animation nodes
|
||||||
|
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
|
||||||
|
nodes.reserve(conns.size());
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Connection* con, conns) {
|
||||||
|
|
||||||
|
// link should not go to a property
|
||||||
|
if (con->PropertyName().length()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Object* const ob = con->SourceObject();
|
||||||
|
if(!ob) {
|
||||||
|
DOMWarning("failed to read source object for AnimationCurveNode->AnimationLayer link, ignoring",&element);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AnimationCurveNode* const anim = dynamic_cast<const AnimationCurveNode*>(ob);
|
||||||
|
if(!anim) {
|
||||||
|
DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode",&element);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
nodes.push_back(anim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AnimationLayer::~AnimationLayer()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||||
|
: Object(id, element, name)
|
||||||
|
{
|
||||||
|
const Scope& sc = GetRequiredScope(element);
|
||||||
|
props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc);
|
||||||
|
|
||||||
|
// resolve attached animation layers
|
||||||
|
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
|
||||||
|
layers.reserve(conns.size());
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Connection* con, conns) {
|
||||||
|
|
||||||
|
// link should not go to a property
|
||||||
|
if (con->PropertyName().length()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Object* const ob = con->SourceObject();
|
||||||
|
if(!ob) {
|
||||||
|
DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring",&element);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AnimationLayer* const anim = dynamic_cast<const AnimationLayer*>(ob);
|
||||||
|
if(!anim) {
|
||||||
|
DOMWarning("source object for ->AnimationStack link is not an AnimationLayer",&element);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
layers.push_back(anim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AnimationStack::~AnimationStack()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} //!FBX
|
||||||
|
} //!Assimp
|
||||||
|
|
||||||
|
#endif
|
|
@ -307,6 +307,27 @@ void ReadVectorDataArray(std::vector<int>& out, const Element& el)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// read an array of floats
|
||||||
|
void ReadVectorDataArray(std::vector<float>& out, const Element& el)
|
||||||
|
{
|
||||||
|
out.clear();
|
||||||
|
const TokenList& tok = el.Tokens();
|
||||||
|
const size_t dim = ParseTokenAsDim(*tok[0]);
|
||||||
|
|
||||||
|
// see notes in ReadVectorDataArray()
|
||||||
|
out.reserve(dim);
|
||||||
|
|
||||||
|
const Scope& scope = GetRequiredScope(el);
|
||||||
|
const Element& a = GetRequiredElement(scope,"a",&el);
|
||||||
|
|
||||||
|
for (TokenList::const_iterator it = a.Tokens().begin(), end = a.Tokens().end(); it != end; ) {
|
||||||
|
const float ival = ParseTokenAsFloat(**it++);
|
||||||
|
out.push_back(ival);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// read an array of uints
|
// read an array of uints
|
||||||
void ReadVectorDataArray(std::vector<unsigned int>& out, const Element& el)
|
void ReadVectorDataArray(std::vector<unsigned int>& out, const Element& el)
|
||||||
|
@ -424,6 +445,18 @@ const Object* LazyObject::Get()
|
||||||
else if (!strncmp(obtype,"Texture",length)) {
|
else if (!strncmp(obtype,"Texture",length)) {
|
||||||
object.reset(new Texture(id,element,doc,name));
|
object.reset(new Texture(id,element,doc,name));
|
||||||
}
|
}
|
||||||
|
else if (!strncmp(obtype,"AnimationStack",length)) {
|
||||||
|
object.reset(new AnimationStack(id,element,name,doc));
|
||||||
|
}
|
||||||
|
else if (!strncmp(obtype,"AnimationLayer",length)) {
|
||||||
|
object.reset(new AnimationLayer(id,element,name,doc));
|
||||||
|
}
|
||||||
|
else if (!strncmp(obtype,"AnimationCurveNode",length)) {
|
||||||
|
object.reset(new AnimationCurveNode(id,element,name,doc));
|
||||||
|
}
|
||||||
|
else if (!strncmp(obtype,"AnimationCurve",length)) {
|
||||||
|
object.reset(new AnimationCurve(id,element,name,doc));
|
||||||
|
}
|
||||||
|
|
||||||
if (!object.get()) {
|
if (!object.get()) {
|
||||||
//DOMError("failed to convert element to DOM object, class: " + classtag + ", name: " + name,&element);
|
//DOMError("failed to convert element to DOM object, class: " + classtag + ", name: " + name,&element);
|
||||||
|
@ -553,6 +586,11 @@ void Document::ReadObjects()
|
||||||
}
|
}
|
||||||
|
|
||||||
objects[id] = new LazyObject(id, *el.second, *this);
|
objects[id] = new LazyObject(id, *el.second, *this);
|
||||||
|
|
||||||
|
// grab all animation stacks upfront since there is no listing of them
|
||||||
|
if(el.first == "AnimationStack") {
|
||||||
|
animationStacks.push_back(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,6 +697,26 @@ void Document::ReadConnections()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
const std::vector<const AnimationStack*>& Document::AnimationStacks() const
|
||||||
|
{
|
||||||
|
if (animationStacksResolved.empty() && animationStacks.size()) {
|
||||||
|
return animationStacksResolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
animationStacksResolved.reserve(animationStacks.size());
|
||||||
|
BOOST_FOREACH(uint64_t id, animationStacks) {
|
||||||
|
LazyObject* const lazy = GetObject(id);
|
||||||
|
const AnimationStack* stack;
|
||||||
|
if(!lazy || !(stack = lazy->Get<AnimationStack>())) {
|
||||||
|
DOMWarning("failed to read AnimationStack object");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
animationStacksResolved.push_back(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
return animationStacksResolved;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
LazyObject* Document::GetObject(uint64_t id) const
|
LazyObject* Document::GetObject(uint64_t id) const
|
||||||
|
|
|
@ -76,9 +76,9 @@ public:
|
||||||
const Object* Get();
|
const Object* Get();
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T* Get() {
|
const T* Get() {
|
||||||
const Object* const ob = Get();
|
const Object* const ob = Get();
|
||||||
return ob ? dynamic_cast<T*>(ob) : NULL;
|
return ob ? dynamic_cast<const T*>(ob) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ID() const {
|
uint64_t ID() const {
|
||||||
|
@ -125,7 +125,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** DOM base class for FBX models */
|
/** DOM base class for FBX models (even though its semantics are more "node" than "model" */
|
||||||
class Model : public Object
|
class Model : public Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -404,6 +404,144 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefor) */
|
||||||
|
class AnimationCurve : public Object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||||
|
~AnimationCurve();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** get list of keyframe positions (time).
|
||||||
|
* Invariant: |GetKeys()| > 0 */
|
||||||
|
const std::vector<float>& GetKeys() const {
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** get list of keyframe values.
|
||||||
|
* Invariant: |GetKeys()| == |GetValues()| && |GetKeys()| > 0*/
|
||||||
|
const std::vector<float>& GetValues() const {
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector<float>& GetAttributes() const {
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int GetFlags() const {
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::vector<float> keys;
|
||||||
|
std::vector<float> values;
|
||||||
|
std::vector<float> attributes;
|
||||||
|
unsigned int flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
// property-name -> animation curve
|
||||||
|
typedef std::map<std::string, const AnimationCurve*> AnimationCurveMap;
|
||||||
|
|
||||||
|
|
||||||
|
/** Represents a FBX animation curve (i.e. a mapping from single animation curves to nodes) */
|
||||||
|
class AnimationCurveNode : public Object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||||
|
~AnimationCurveNode();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
const PropertyTable& Props() const {
|
||||||
|
ai_assert(props.get());
|
||||||
|
return *props.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const AnimationCurveMap Curves() const {
|
||||||
|
return curves;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Model* TargetNode() const {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const Model* target;
|
||||||
|
boost::shared_ptr<const PropertyTable> props;
|
||||||
|
AnimationCurveMap curves;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<const AnimationCurveNode*> AnimationCurveNodeList;
|
||||||
|
|
||||||
|
|
||||||
|
/** Represents a FBX animation layer (i.e. a list of node animations) */
|
||||||
|
class AnimationLayer : public Object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||||
|
~AnimationLayer();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
const PropertyTable& Props() const {
|
||||||
|
ai_assert(props.get());
|
||||||
|
return *props.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
const AnimationCurveNodeList& Nodes() const {
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
boost::shared_ptr<const PropertyTable> props;
|
||||||
|
AnimationCurveNodeList nodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::vector<const AnimationLayer*> AnimationLayerList;
|
||||||
|
|
||||||
|
|
||||||
|
/** Represents a FBX animation stack (i.e. a list of animation layers) */
|
||||||
|
class AnimationStack : public Object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||||
|
~AnimationStack();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
const PropertyTable& Props() const {
|
||||||
|
ai_assert(props.get());
|
||||||
|
return *props.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const AnimationLayerList& Layers() const {
|
||||||
|
return layers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
boost::shared_ptr<const PropertyTable> props;
|
||||||
|
AnimationLayerList layers;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Represents a link between two FBX objects. */
|
/** Represents a link between two FBX objects. */
|
||||||
class Connection
|
class Connection
|
||||||
{
|
{
|
||||||
|
@ -514,6 +652,8 @@ public:
|
||||||
std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source) const;
|
std::vector<const Connection*> GetConnectionsBySourceSequenced(uint64_t source) const;
|
||||||
std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest) const;
|
std::vector<const Connection*> GetConnectionsByDestinationSequenced(uint64_t dest) const;
|
||||||
|
|
||||||
|
const std::vector<const AnimationStack*>& AnimationStacks() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void ReadHeader();
|
void ReadHeader();
|
||||||
|
@ -536,6 +676,8 @@ private:
|
||||||
std::string creator;
|
std::string creator;
|
||||||
unsigned int creationTimeStamp[7];
|
unsigned int creationTimeStamp[7];
|
||||||
|
|
||||||
|
std::vector<uint64_t> animationStacks;
|
||||||
|
mutable std::vector<const AnimationStack*> animationStacksResolved;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,9 @@ void ReadVectorDataArray(std::vector<aiVector2D>& out, const Element& el);
|
||||||
// read an array of ints
|
// read an array of ints
|
||||||
void ReadVectorDataArray(std::vector<int>& out, const Element& el);
|
void ReadVectorDataArray(std::vector<int>& out, const Element& el);
|
||||||
|
|
||||||
|
// read an array of floats
|
||||||
|
void ReadVectorDataArray(std::vector<float>& out, const Element& el);
|
||||||
|
|
||||||
// read an array of uints
|
// read an array of uints
|
||||||
void ReadVectorDataArray(std::vector<unsigned int>& out, const Element& el);
|
void ReadVectorDataArray(std::vector<unsigned int>& out, const Element& el);
|
||||||
|
|
||||||
|
|
|
@ -2055,6 +2055,10 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="fbx"
|
Name="fbx"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\FBXAnimation.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\code\FBXCompileConfig.h"
|
RelativePath="..\..\code\FBXCompileConfig.h"
|
||||||
>
|
>
|
||||||
|
|
Loading…
Reference in New Issue