- fbx: resolve target node for node animations.
parent
ae3007b42b
commit
378bc93593
|
@ -97,6 +97,7 @@ AnimationCurve::~AnimationCurve()
|
||||||
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||||
: Object(id, element, name)
|
: Object(id, element, name)
|
||||||
, target()
|
, target()
|
||||||
|
{
|
||||||
{
|
{
|
||||||
// resolve attached animation curves
|
// resolve attached animation curves
|
||||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
|
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
|
||||||
|
@ -120,8 +121,48 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, cons
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curves[con->PropertyName()] = anim;
|
||||||
|
}
|
||||||
|
|
||||||
|
}{
|
||||||
|
|
||||||
|
// find target node
|
||||||
|
const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID());
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Connection* con, conns) {
|
||||||
|
|
||||||
|
// link should go for a property
|
||||||
|
if (con->PropertyName().length()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// note: the implicit rule in all DOM classes is to always resolve
|
||||||
|
// from destination to source (since the FBX object hierarchy is,
|
||||||
|
// with very few exceptions, a DAG, this avoids cycles). Since
|
||||||
|
// it goes the other way round, we have to cope with the case
|
||||||
|
// that the destination is not fully constructed yet.
|
||||||
|
LazyObject& lob = con->LazyDestinationObject();
|
||||||
|
if(lob.IsBeingConstructed()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Object* ob = lob.Get();
|
||||||
|
if(!ob) {
|
||||||
|
DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring",&element);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
target = dynamic_cast<const Model*>(ob);
|
||||||
|
if(!target) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
prop = con->PropertyName();
|
prop = con->PropertyName();
|
||||||
curves[prop] = anim;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!target) {
|
||||||
|
DOMError("failed to resolve target model for animation node",&element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -390,6 +390,7 @@ LazyObject::LazyObject(uint64_t id, const Element& element, const Document& doc)
|
||||||
: doc(doc)
|
: doc(doc)
|
||||||
, element(element)
|
, element(element)
|
||||||
, id(id)
|
, id(id)
|
||||||
|
, being_constructed()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -425,7 +426,8 @@ const Object* LazyObject::Get()
|
||||||
DOMError(err,&element);
|
DOMError(err,&element);
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX prevent recursive calls
|
// prevent recursive calls
|
||||||
|
being_constructed = true;
|
||||||
|
|
||||||
// this needs to be relatively fast since it happens a lot,
|
// this needs to be relatively fast since it happens a lot,
|
||||||
// so avoid constructing strings all the time.
|
// so avoid constructing strings all the time.
|
||||||
|
@ -462,6 +464,7 @@ const Object* LazyObject::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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
being_constructed = false;
|
||||||
return object.get();
|
return object.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,6 +700,7 @@ void Document::ReadConnections()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const std::vector<const AnimationStack*>& Document::AnimationStacks() const
|
const std::vector<const AnimationStack*>& Document::AnimationStacks() const
|
||||||
{
|
{
|
||||||
|
@ -718,6 +722,7 @@ const std::vector<const AnimationStack*>& Document::AnimationStacks() const
|
||||||
return animationStacksResolved;
|
return animationStacksResolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
LazyObject* Document::GetObject(uint64_t id) const
|
LazyObject* Document::GetObject(uint64_t id) const
|
||||||
{
|
{
|
||||||
|
@ -725,6 +730,7 @@ LazyObject* Document::GetObject(uint64_t id) const
|
||||||
return it == objects.end() ? NULL : (*it).second;
|
return it == objects.end() ? NULL : (*it).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source) const
|
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source) const
|
||||||
{
|
{
|
||||||
|
@ -762,6 +768,7 @@ std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(ui
|
||||||
return temp; // NRVO should handle this
|
return temp; // NRVO should handle this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Connection::Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string& prop, const Document& doc)
|
Connection::Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string& prop, const Document& doc)
|
||||||
: insertionOrder(insertionOrder)
|
: insertionOrder(insertionOrder)
|
||||||
|
@ -783,6 +790,24 @@ Connection::~Connection()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
LazyObject& Connection::LazySourceObject() const
|
||||||
|
{
|
||||||
|
LazyObject* const lazy = doc.GetObject(src);
|
||||||
|
ai_assert(lazy);
|
||||||
|
return *lazy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
LazyObject& Connection::LazyDestinationObject() const
|
||||||
|
{
|
||||||
|
LazyObject* const lazy = doc.GetObject(dest);
|
||||||
|
ai_assert(lazy);
|
||||||
|
return *lazy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const Object* Connection::SourceObject() const
|
const Object* Connection::SourceObject() const
|
||||||
{
|
{
|
||||||
|
@ -791,6 +816,7 @@ const Object* Connection::SourceObject() const
|
||||||
return lazy->Get();
|
return lazy->Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const Object* Connection::DestinationObject() const
|
const Object* Connection::DestinationObject() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -85,6 +85,10 @@ public:
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsBeingConstructed() const {
|
||||||
|
return being_constructed;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const Document& doc;
|
const Document& doc;
|
||||||
|
@ -92,6 +96,7 @@ private:
|
||||||
boost::scoped_ptr<const Object> object;
|
boost::scoped_ptr<const Object> object;
|
||||||
|
|
||||||
const uint64_t id;
|
const uint64_t id;
|
||||||
|
bool being_constructed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -469,11 +474,12 @@ public:
|
||||||
return curves;
|
return curves;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Model instance the curve is assigned to, this is always non-NULL */
|
||||||
const Model* TargetNode() const {
|
const Model* TargetNode() const {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Property of TargetNode() that is being animated*/
|
||||||
const std::string& TargetProperty() const {
|
const std::string& TargetProperty() const {
|
||||||
return prop;
|
return prop;
|
||||||
}
|
}
|
||||||
|
@ -562,8 +568,13 @@ public:
|
||||||
const Object* SourceObject() const;
|
const Object* SourceObject() const;
|
||||||
const Object* DestinationObject() const;
|
const Object* DestinationObject() const;
|
||||||
|
|
||||||
// return the name of the property the connection is attached to.
|
// these, however, are always guaranteed to be valid
|
||||||
// this is an empty string for object to object (OO) connections.
|
LazyObject& LazySourceObject() const;
|
||||||
|
LazyObject& LazyDestinationObject() const;
|
||||||
|
|
||||||
|
|
||||||
|
/** return the name of the property the connection is attached to.
|
||||||
|
* this is an empty string for object to object (OO) connections. */
|
||||||
const std::string& PropertyName() const {
|
const std::string& PropertyName() const {
|
||||||
return prop;
|
return prop;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue