Revision: 50232
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=50232
Author: aramis_acg
Date: 2012-08-26 23:34:38 +0000 (Sun, 26 Aug 2012)
Log Message:
-----------
*POST-GSOC-FROM-HERE!-TAG* - ext_assimp: merge
https://github.com/acgessler/assimp-gsoc2012-fbx proper framerate conversion,
fixes crash when assigning animations to root node, keep Null node info,
support scenes with no geometry in them, massive logging cleanup (fewer but
more concise warnings), performance improvements.
Modified Paths:
--------------
branches/soc-2012-bratwurst/extern/assimp/code/FBXAnimation.cpp
branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp
branches/soc-2012-bratwurst/extern/assimp/code/FBXDeformer.cpp
branches/soc-2012-bratwurst/extern/assimp/code/FBXDocument.cpp
branches/soc-2012-bratwurst/extern/assimp/code/FBXDocument.h
branches/soc-2012-bratwurst/extern/assimp/code/FBXDocumentUtil.cpp
branches/soc-2012-bratwurst/extern/assimp/code/FBXDocumentUtil.h
branches/soc-2012-bratwurst/extern/assimp/code/FBXModel.cpp
branches/soc-2012-bratwurst/extern/assimp/code/FBXNodeAttribute.cpp
branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.cpp
branches/soc-2012-bratwurst/source/blender/assimp/AnimationImporter.h
Modified: branches/soc-2012-bratwurst/extern/assimp/code/FBXAnimation.cpp
===================================================================
--- branches/soc-2012-bratwurst/extern/assimp/code/FBXAnimation.cpp
2012-08-26 23:17:50 UTC (rev 50231)
+++ branches/soc-2012-bratwurst/extern/assimp/code/FBXAnimation.cpp
2012-08-26 23:34:38 UTC (rev 50232)
@@ -98,17 +98,18 @@
//
------------------------------------------------------------------------------------------------
-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,
+ const char* const * target_prop_whitelist /*= NULL*/, size_t
whitelist_size /*= 0*/)
: Object(id, element, name)
, target()
+, doc(doc)
{
const Scope& sc = GetRequiredScope(element);
- props =
GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc);
+
+ // find target node
+ const char* whitelist[] = {"Model","NodeAttribute"};
+ const std::vector<const Connection*>& conns =
doc.GetConnectionsBySourceSequenced(ID(),whitelist,2);
- {
- // resolve attached animation curves
- const std::vector<const Connection*>& conns =
doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
-
BOOST_FOREACH(const Connection* con, conns) {
// link should go for a property
@@ -116,34 +117,21 @@
continue;
}
- const Object* const ob = con->SourceObject();
- if(!ob) {
- DOMWarning("failed to read source object for
AnimationCurve->AnimationCurveNode link, ignoring",&element);
- continue;
- }
+ if(target_prop_whitelist) {
+ const char* const s = con->PropertyName().c_str();
+ bool ok = false;
+ for (size_t i = 0; i < whitelist_size; ++i) {
+ if (!strcmp(s, target_prop_whitelist[i])) {
+ ok = true;
+ break;
+ }
+ }
- const AnimationCurve* const anim = dynamic_cast<const
AnimationCurve*>(ob);
- if(!anim) {
- DOMWarning("source object for ->AnimationCurveNode link
is not an AnimationCurve",&element);
- continue;
+ if (!ok) {
+ throw std::range_error("AnimationCurveNode
target property is not in whitelist");
+ }
}
-
- curves[con->PropertyName()] = anim;
- }
- }{
-
- // find target node
- const char* whitelist[] = {"Model","NodeAttribute"};
- const std::vector<const Connection*>& conns =
doc.GetConnectionsBySourceSequenced(ID(),whitelist,2);
-
- BOOST_FOREACH(const Connection* con, conns) {
-
- // link should go for a property
- if (!con->PropertyName().length()) {
- continue;
- }
-
const Object* const ob = con->DestinationObject();
if(!ob) {
DOMWarning("failed to read destination object for
AnimationCurveNode->Model link, ignoring",&element);
@@ -160,10 +148,12 @@
prop = con->PropertyName();
break;
}
- }
+
if(!target) {
DOMWarning("failed to resolve target
Model/NodeAttribute/Constraint for AnimationCurveNode",&element);
}
+
+ props =
GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false);
}
@@ -175,12 +165,64 @@
//
------------------------------------------------------------------------------------------------
+const AnimationCurveMap& AnimationCurveNode::Curves() const
+{
+ if(curves.empty()) {
+ // resolve attached animation curves
+ const std::vector<const Connection*>& conns =
doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
+
+ 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;
+ }
+ }
+
+ return curves;
+}
+
+
+//
------------------------------------------------------------------------------------------------
AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const
std::string& name, const Document& doc)
: Object(id, element, name)
+, doc(doc)
{
const Scope& sc = GetRequiredScope(element);
- props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc);
+ // note: the props table here bears little importance and is usually
absent
+ props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc,
true);
+}
+
+
+//
------------------------------------------------------------------------------------------------
+AnimationLayer::~AnimationLayer()
+{
+
+}
+
+
+//
------------------------------------------------------------------------------------------------
+AnimationCurveNodeList AnimationLayer::Nodes(const char* const *
target_prop_whitelist /*= NULL*/,
+ size_t whitelist_size /*= 0*/) const
+{
+ AnimationCurveNodeList nodes;
+
// resolve attached animation nodes
const std::vector<const Connection*>& conns =
doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurveNode");
nodes.reserve(conns.size());
@@ -203,15 +245,24 @@
DOMWarning("source object for ->AnimationLayer link is
not an AnimationCurveNode",&element);
continue;
}
+
+ if(target_prop_whitelist) {
+ const char* s = anim->TargetProperty().c_str();
+ bool ok = false;
+ for (size_t i = 0; i < whitelist_size; ++i) {
+ if (!strcmp(s, target_prop_whitelist[i])) {
+ ok = true;
+ break;
+ }
+ }
+ if(!ok) {
+ continue;
+ }
+ }
nodes.push_back(anim);
}
-}
-
-//
------------------------------------------------------------------------------------------------
-AnimationLayer::~AnimationLayer()
-{
-
+ return nodes; // pray for NRVO
}
//
------------------------------------------------------------------------------------------------
@@ -219,8 +270,10 @@
: Object(id, element, name)
{
const Scope& sc = GetRequiredScope(element);
- props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc);
+ // note: we don't currently use any of these properties so we shouldn't
bother if it is missing
+ props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc,
true);
+
// resolve attached animation layers
const std::vector<const Connection*>& conns =
doc.GetConnectionsByDestinationSequenced(ID(),"AnimationLayer");
layers.reserve(conns.size());
Modified: branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp
===================================================================
--- branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp
2012-08-26 23:17:50 UTC (rev 50231)
+++ branches/soc-2012-bratwurst/extern/assimp/code/FBXConverter.cpp
2012-08-26 23:34:38 UTC (rev 50232)
@@ -61,8 +61,10 @@
#define MAGIC_NODE_TAG "_$AssimpFbx$"
-#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158
+#define MAGIC_NULL_TAG "_$AssimpFbxNull$"
+#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
+
// XXX vc9's debugger won't step into anonymous namespaces
//namespace {
@@ -124,6 +126,13 @@
}
TransferDataToScene();
+
+ // if we didn't read any meshes set the
AI_SCENE_FLAGS_INCOMPLETE
+ // to make sure the scene passes assimp's validation. FBX files
+ // need not contain geometry (i.e. camera animations, raw
armatures).
+ if (out->mNumMeshes == 0) {
+ out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
+ }
}
@@ -197,16 +206,17 @@
// is supposed to have. If there is
none, add another node to
// preserve the name - people might
have scripts etc. that rely
// on specific node names.
- bool has_name = false;
+ aiNode* name_carrier = NULL;
BOOST_FOREACH(aiNode* prenode,
nodes_chain) {
if (
!strcmp(prenode->mName.C_Str(), original_name.c_str()) ) {
- has_name = true;
+ name_carrier = prenode;
break;
}
}
- if(!has_name) {
+ if(!name_carrier) {
nodes_chain.push_back(new
aiNode(original_name));
+ name_carrier =
nodes_chain.back();
}
// link all nodes in a row
@@ -240,6 +250,14 @@
ConvertCameras(*model);
}
+ // preserve the info that a node was
marked as Null node
+ // in the original file.
+ if(model->IsNull()) {
+ const std::string& new_name =
original_name + MAGIC_NULL_TAG;
+ RenameNode(original_name,
new_name);
+ name_carrier->mName.Set(
new_name.c_str() );
+ }
+
nodes.push_back(nodes_chain.front());
nodes_chain.clear();
}
@@ -1545,9 +1563,66 @@
//
------------------------------------------------------------------------------------------------
+ // get the number of fps for a FrameRate enumerated value
+ static double FrameRateToDouble(FileGlobalSettings::FrameRate fp,
double customFPSVal = -1.0)
+ {
+ switch(fp) {
+ case FileGlobalSettings::FrameRate_DEFAULT:
+ return 1.0;
+
+ case FileGlobalSettings::FrameRate_120:
+ return 120.0;
+
+ case FileGlobalSettings::FrameRate_100:
+ return 100.0;
+
+ case FileGlobalSettings::FrameRate_60:
+ return 60.0;
+
+ case FileGlobalSettings::FrameRate_50:
+ return 50.0;
+
+ case FileGlobalSettings::FrameRate_48:
+ return 48.0;
+
+ case FileGlobalSettings::FrameRate_30:
+ case FileGlobalSettings::FrameRate_30_DROP:
+ return 30.0;
+
+ case FileGlobalSettings::FrameRate_NTSC_DROP_FRAME:
+ case FileGlobalSettings::FrameRate_NTSC_FULL_FRAME:
+ return 29.9700262;
+
+ case FileGlobalSettings::FrameRate_PAL:
+ return 25.0;
+
+ case FileGlobalSettings::FrameRate_CINEMA:
+ return 24.0;
+
+ case FileGlobalSettings::FrameRate_1000:
+ return 1000.0;
+
+ case FileGlobalSettings::FrameRate_CINEMA_ND:
+ return 23.976;
+
+ case FileGlobalSettings::FrameRate_CUSTOM:
+ return customFPSVal;
+ }
+
+ ai_assert(false);
+ return -1.0f;
+ }
+
+
+ //
------------------------------------------------------------------------------------------------
// convert animation data to aiAnimation et al
void ConvertAnimations()
{
+ // first of all determine framerate
+ const FileGlobalSettings::FrameRate fps =
doc.GlobalSettings().TimeMode();
+ const float custom = doc.GlobalSettings().CustomFrameRate();
+ anim_fps = FrameRateToDouble(fps, custom);
+
const std::vector<const AnimationStack*>& animations =
doc.AnimationStacks();
BOOST_FOREACH(const AnimationStack* stack, animations) {
@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs