- 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)
: Deformer(id,element,doc,name)
, node()
{
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(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));
}
const char* const arr[] = {"Deformer"};
// 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());
BOOST_FOREACH(const Connection* con, conns) {
// Cluster -> Skin links should be object-object connections
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);
const Cluster* const cluster = ProcessSimpleConnection<Cluster>(*con, false, "Cluster -> Skin", element);
if(cluster) {
clusters.push_back(cluster);
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)
: settings(settings)

View File

@ -60,6 +60,14 @@ namespace FBX {
class Material;
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
* are not needed by assimp, so it makes no sense to parse them
@ -363,8 +371,19 @@ class Geometry : public Object
{
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();
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;
}
const Model* const TargetNode() const {
return node;
}
private:
WeightList weights;
@ -702,6 +725,8 @@ private:
aiMatrix4x4 transform;
aiMatrix4x4 transformLink;
const Model* node;
};

View File

@ -108,6 +108,50 @@ boost::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
const Element &element,
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
} //!FBX
} //!Assimp

View File

@ -57,9 +57,34 @@ namespace FBX {
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)
: Geometry(id, element,name)
: Geometry(id, element,name, doc)
{
const Scope* sc = element.Compound();
if (!sc) {