- fbx: read Geometry -> Skin and Model -> Cluster connections. Improve logging, some refactoring.

pull/14/head
Alexander Gessler 2012-07-26 19:13:19 +02:00
parent 06acead438
commit 05ec3c2e90
5 changed files with 113 additions and 33 deletions

View File

@ -78,6 +78,7 @@ Deformer::~Deformer()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name) Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name)
: Deformer(id,element,doc,name) : Deformer(id,element,doc,name)
, node()
{ {
const Scope& sc = GetRequiredScope(element); const Scope& sc = GetRequiredScope(element);
@ -91,6 +92,20 @@ Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const
ReadVectorDataArray(indices,Indexes); ReadVectorDataArray(indices,Indexes);
ReadVectorDataArray(weights,Weights); ReadVectorDataArray(weights,Weights);
// read assigned node
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer");
BOOST_FOREACH(const Connection* con, conns) {
const Model* const mod = ProcessSimpleConnection<Model>(*con, false, "Model -> Cluster", element);
if(mod) {
node = mod;
break;
}
}
if (!node) {
DOMError("failed to read target Node for Cluster",&element);
}
} }
@ -112,31 +127,17 @@ Skin::Skin(uint64_t id, const Element& element, const Document& doc, const std::
accuracy = ParseTokenAsFloat(GetRequiredToken(*Link_DeformAcuracy,0)); accuracy = ParseTokenAsFloat(GetRequiredToken(*Link_DeformAcuracy,0));
} }
const char* const arr[] = {"Deformer"};
// resolve assigned clusters // resolve assigned clusters
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),arr, 1); const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer");
clusters.reserve(conns.size()); clusters.reserve(conns.size());
BOOST_FOREACH(const Connection* con, conns) { BOOST_FOREACH(const Connection* con, conns) {
// Cluster -> Skin links should be object-object connections const Cluster* const cluster = ProcessSimpleConnection<Cluster>(*con, false, "Cluster -> Skin", element);
if (con->PropertyName().length()) {
continue;
}
const Object* const ob = con->SourceObject();
if(!ob) {
DOMWarning("failed to read source object for incoming Skin link, ignoring",&element);
continue;
}
const Cluster* const cluster = dynamic_cast<const Cluster*>(ob);
if(cluster) { if(cluster) {
clusters.push_back(cluster); clusters.push_back(cluster);
continue; continue;
} }
} }
} }

View File

@ -579,21 +579,6 @@ Object::~Object()
} }
// ------------------------------------------------------------------------------------------------
Geometry::Geometry(uint64_t id, const Element& element, const std::string& name)
: Object(id, element,name)
{
}
// ------------------------------------------------------------------------------------------------
Geometry::~Geometry()
{
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Document::Document(const Parser& parser, const ImportSettings& settings) Document::Document(const Parser& parser, const ImportSettings& settings)
: settings(settings) : settings(settings)

View File

@ -60,6 +60,14 @@ namespace FBX {
class Material; class Material;
class Geometry; class Geometry;
class AnimationCurve;
class AnimationCurveNode;
class AnimationLayer;
class AnimationStack;
class Skin;
class Cluster;
/** Represents a delay-parsed FBX objects. Many objects in the scene /** Represents a delay-parsed FBX objects. Many objects in the scene
* are not needed by assimp, so it makes no sense to parse them * are not needed by assimp, so it makes no sense to parse them
@ -363,8 +371,19 @@ class Geometry : public Object
{ {
public: public:
Geometry(uint64_t id, const Element& element, const std::string& name); Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc);
~Geometry(); ~Geometry();
public:
/** Get the Skin attached to this geometry or NULL */
const Skin* const DeformerSkin() const {
return skin;
}
private:
const Skin* skin;
}; };
@ -695,6 +714,10 @@ public:
return transformLink; return transformLink;
} }
const Model* const TargetNode() const {
return node;
}
private: private:
WeightList weights; WeightList weights;
@ -702,6 +725,8 @@ private:
aiMatrix4x4 transform; aiMatrix4x4 transform;
aiMatrix4x4 transformLink; aiMatrix4x4 transformLink;
const Model* node;
}; };

View File

@ -108,6 +108,50 @@ boost::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
const Element &element, const Element &element,
const Scope& sc); const Scope& sc);
// ------------------------------------------------------------------------------------------------
template <typename T>
inline const T* ProcessSimpleConnection(const Connection& con,
bool is_object_property_conn,
const char* name,
const Element& element,
const char** propNameOut = NULL)
{
if (is_object_property_conn && con.PropertyName().length()) {
DOMWarning("expected incoming " + std::string(name) +
" link to be an object-object connection, ignoring",
&element
);
return NULL;
}
else if (!is_object_property_conn && !con.PropertyName().length()) {
DOMWarning("expected incoming " + std::string(name) +
" link to be an object-property connection, ignoring",
&element
);
return NULL;
}
if(is_object_property_conn && propNameOut) {
// note: this is ok, the return value of PropertyValue() is guaranteed to
// remain valid and unchanged as long as the document exists.
*propNameOut = con.PropertyName().c_str();
}
const Object* const ob = con.SourceObject();
if(!ob) {
DOMWarning("failed to read source object for incoming" + std::string(name) +
" link, ignoring",
&element);
return NULL;
}
return dynamic_cast<const T*>(ob);
}
} //!Util } //!Util
} //!FBX } //!FBX
} //!Assimp } //!Assimp

View File

@ -57,9 +57,34 @@ namespace FBX {
using namespace Util; using namespace Util;
// ------------------------------------------------------------------------------------------------
Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
: Object(id, element,name)
, skin()
{
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer");
BOOST_FOREACH(const Connection* con, conns) {
const Skin* const sk = ProcessSimpleConnection<Skin>(*con, false, "Skin -> Geometry", element);
if(sk) {
skin = sk;
break;
}
}
}
// ------------------------------------------------------------------------------------------------
Geometry::~Geometry()
{
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
: Geometry(id, element,name) : Geometry(id, element,name, doc)
{ {
const Scope* sc = element.Compound(); const Scope* sc = element.Compound();
if (!sc) { if (!sc) {