pull/521/head
Kim Kulling 2015-03-28 20:47:17 +01:00
commit 20ad00b5e5
13 changed files with 273 additions and 59 deletions

View File

@ -1968,9 +1968,12 @@ private:
// strip AnimationStack:: prefix // strip AnimationStack:: prefix
std::string name = st.Name(); std::string name = st.Name();
if(name.substr(0,16) == "AnimationStack::") { if (name.substr(0, 16) == "AnimationStack::") {
name = name.substr(16); name = name.substr(16);
} }
else if (name.substr(0, 11) == "AnimStack::") {
name = name.substr(11);
}
anim->mName.Set(name); anim->mName.Set(name);
@ -2014,12 +2017,18 @@ private:
double min_time = 1e10; double min_time = 1e10;
double max_time = -1e10; double max_time = -1e10;
int64_t start_time = st.LocalStart();
int64_t stop_time = st.LocalStop();
double start_timeF = CONVERT_FBX_TIME(start_time);
double stop_timeF = CONVERT_FBX_TIME(stop_time);
try { try {
BOOST_FOREACH(const NodeMap::value_type& kv, node_map) { BOOST_FOREACH(const NodeMap::value_type& kv, node_map) {
GenerateNodeAnimations(node_anims, GenerateNodeAnimations(node_anims,
kv.first, kv.first,
kv.second, kv.second,
layer_map, layer_map,
start_time, stop_time,
max_time, max_time,
min_time); min_time);
} }
@ -2043,9 +2052,27 @@ private:
return; return;
} }
//adjust relative timing for animation
{
double start_fps = start_timeF * anim_fps;
for (unsigned int c = 0; c < anim->mNumChannels; c++)
{
aiNodeAnim* channel = anim->mChannels[c];
for (uint32_t i = 0; i < channel->mNumPositionKeys; i++)
channel->mPositionKeys[i].mTime -= start_fps;
for (uint32_t i = 0; i < channel->mNumRotationKeys; i++)
channel->mRotationKeys[i].mTime -= start_fps;
for (uint32_t i = 0; i < channel->mNumScalingKeys; i++)
channel->mScalingKeys[i].mTime -= start_fps;
}
max_time -= min_time;
}
// for some mysterious reason, mDuration is simply the maximum key -- the // for some mysterious reason, mDuration is simply the maximum key -- the
// validator always assumes animations to start at zero. // validator always assumes animations to start at zero.
anim->mDuration = max_time /*- min_time */; anim->mDuration = (stop_timeF - start_timeF) * anim_fps;
anim->mTicksPerSecond = anim_fps; anim->mTicksPerSecond = anim_fps;
} }
@ -2055,6 +2082,7 @@ private:
const std::string& fixed_name, const std::string& fixed_name,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
int64_t start, int64_t stop,
double& max_time, double& max_time,
double& min_time) double& min_time)
{ {
@ -2147,13 +2175,19 @@ private:
aiNodeAnim* const nd = GenerateSimpleNodeAnim(fixed_name, target, chain, aiNodeAnim* const nd = GenerateSimpleNodeAnim(fixed_name, target, chain,
node_property_map.end(), node_property_map.end(),
layer_map, layer_map,
start, stop,
max_time, max_time,
min_time, min_time,
true // input is TRS order, assimp is SRT true // input is TRS order, assimp is SRT
); );
ai_assert(nd); ai_assert(nd);
node_anims.push_back(nd); if (nd->mNumPositionKeys == 0 && nd->mNumRotationKeys == 0 && nd->mNumScalingKeys == 0) {
delete nd;
}
else {
node_anims.push_back(nd);
}
return; return;
} }
@ -2185,6 +2219,7 @@ private:
target, target,
(*chain[i]).second, (*chain[i]).second,
layer_map, layer_map,
start, stop,
max_time, max_time,
min_time); min_time);
@ -2200,6 +2235,7 @@ private:
target, target,
(*chain[i]).second, (*chain[i]).second,
layer_map, layer_map,
start, stop,
max_time, max_time,
min_time); min_time);
@ -2212,12 +2248,18 @@ private:
target, target,
(*chain[i]).second, (*chain[i]).second,
layer_map, layer_map,
start, stop,
max_time, max_time,
min_time, min_time,
true); true);
ai_assert(inv); ai_assert(inv);
node_anims.push_back(inv); if (inv->mNumPositionKeys == 0 && inv->mNumRotationKeys == 0 && inv->mNumScalingKeys == 0) {
delete inv;
}
else {
node_anims.push_back(inv);
}
ai_assert(TransformationComp_RotationPivotInverse > i); ai_assert(TransformationComp_RotationPivotInverse > i);
flags |= bit << (TransformationComp_RotationPivotInverse - i); flags |= bit << (TransformationComp_RotationPivotInverse - i);
@ -2230,12 +2272,18 @@ private:
target, target,
(*chain[i]).second, (*chain[i]).second,
layer_map, layer_map,
start, stop,
max_time, max_time,
min_time, min_time,
true); true);
ai_assert(inv); ai_assert(inv);
node_anims.push_back(inv); if (inv->mNumPositionKeys == 0 && inv->mNumRotationKeys == 0 && inv->mNumScalingKeys == 0) {
delete inv;
}
else {
node_anims.push_back(inv);
}
ai_assert(TransformationComp_RotationPivotInverse > i); ai_assert(TransformationComp_RotationPivotInverse > i);
flags |= bit << (TransformationComp_RotationPivotInverse - i); flags |= bit << (TransformationComp_RotationPivotInverse - i);
@ -2249,6 +2297,7 @@ private:
target, target,
(*chain[i]).second, (*chain[i]).second,
layer_map, layer_map,
start, stop,
max_time, max_time,
min_time); min_time);
@ -2259,7 +2308,12 @@ private:
} }
ai_assert(na); ai_assert(na);
node_anims.push_back(na); if (na->mNumPositionKeys == 0 && na->mNumRotationKeys == 0 && na->mNumScalingKeys == 0) {
delete na;
}
else {
node_anims.push_back(na);
}
continue; continue;
} }
} }
@ -2320,13 +2374,14 @@ private:
const Model& target, const Model& target,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
int64_t start, int64_t stop,
double& max_time, double& max_time,
double& min_time) double& min_time)
{ {
ScopeGuard<aiNodeAnim> na(new aiNodeAnim()); ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
na->mNodeName.Set(name); na->mNodeName.Set(name);
ConvertRotationKeys(na, curves, layer_map, max_time,min_time, target.RotationOrder()); ConvertRotationKeys(na, curves, layer_map, start, stop, max_time, min_time, target.RotationOrder());
// dummy scaling key // dummy scaling key
na->mScalingKeys = new aiVectorKey[1]; na->mScalingKeys = new aiVectorKey[1];
@ -2351,13 +2406,14 @@ private:
const Model& /*target*/, const Model& /*target*/,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
int64_t start, int64_t stop,
double& max_time, double& max_time,
double& min_time) double& min_time)
{ {
ScopeGuard<aiNodeAnim> na(new aiNodeAnim()); ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
na->mNodeName.Set(name); na->mNodeName.Set(name);
ConvertScaleKeys(na, curves, layer_map, max_time,min_time); ConvertScaleKeys(na, curves, layer_map, start, stop, max_time, min_time);
// dummy rotation key // dummy rotation key
na->mRotationKeys = new aiQuatKey[1]; na->mRotationKeys = new aiQuatKey[1];
@ -2382,6 +2438,7 @@ private:
const Model& /*target*/, const Model& /*target*/,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
int64_t start, int64_t stop,
double& max_time, double& max_time,
double& min_time, double& min_time,
bool inverse = false) bool inverse = false)
@ -2389,7 +2446,7 @@ private:
ScopeGuard<aiNodeAnim> na(new aiNodeAnim()); ScopeGuard<aiNodeAnim> na(new aiNodeAnim());
na->mNodeName.Set(name); na->mNodeName.Set(name);
ConvertTranslationKeys(na, curves, layer_map, max_time,min_time); ConvertTranslationKeys(na, curves, layer_map, start, stop, max_time, min_time);
if (inverse) { if (inverse) {
for (unsigned int i = 0; i < na->mNumPositionKeys; ++i) { for (unsigned int i = 0; i < na->mNumPositionKeys; ++i) {
@ -2422,6 +2479,7 @@ private:
NodeMap::const_iterator chain[TransformationComp_MAXIMUM], NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
NodeMap::const_iterator iter_end, NodeMap::const_iterator iter_end,
const LayerMap& layer_map, const LayerMap& layer_map,
int64_t start, int64_t stop,
double& max_time, double& max_time,
double& min_time, double& min_time,
bool reverse_order = false) bool reverse_order = false)
@ -2443,21 +2501,21 @@ private:
KeyFrameListList rotation; KeyFrameListList rotation;
if(chain[TransformationComp_Scaling] != iter_end) { if(chain[TransformationComp_Scaling] != iter_end) {
scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second); scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second, start, stop);
} }
else { else {
def_scale = PropertyGet(props,"Lcl Scaling",aiVector3D(1.f,1.f,1.f)); def_scale = PropertyGet(props,"Lcl Scaling",aiVector3D(1.f,1.f,1.f));
} }
if(chain[TransformationComp_Translation] != iter_end) { if(chain[TransformationComp_Translation] != iter_end) {
translation = GetKeyframeList((*chain[TransformationComp_Translation]).second); translation = GetKeyframeList((*chain[TransformationComp_Translation]).second, start, stop);
} }
else { else {
def_translate = PropertyGet(props,"Lcl Translation",aiVector3D(0.f,0.f,0.f)); def_translate = PropertyGet(props,"Lcl Translation",aiVector3D(0.f,0.f,0.f));
} }
if(chain[TransformationComp_Rotation] != iter_end) { if(chain[TransformationComp_Rotation] != iter_end) {
rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second); rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second, start, stop);
} }
else { else {
def_rot = EulerToQuaternion(PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)), def_rot = EulerToQuaternion(PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)),
@ -2475,17 +2533,20 @@ private:
aiVectorKey* out_scale = new aiVectorKey[times.size()]; aiVectorKey* out_scale = new aiVectorKey[times.size()];
aiVectorKey* out_translation = new aiVectorKey[times.size()]; aiVectorKey* out_translation = new aiVectorKey[times.size()];
ConvertTransformOrder_TRStoSRT(out_quat, out_scale, out_translation, if (times.size())
scaling, {
translation, ConvertTransformOrder_TRStoSRT(out_quat, out_scale, out_translation,
rotation, scaling,
times, translation,
max_time, rotation,
min_time, times,
target.RotationOrder(), max_time,
def_scale, min_time,
def_translate, target.RotationOrder(),
def_rot); def_scale,
def_translate,
def_rot);
}
// XXX remove duplicates / redundant keys which this operation did // XXX remove duplicates / redundant keys which this operation did
// likely produce if not all three channels were equally dense. // likely produce if not all three channels were equally dense.
@ -2507,6 +2568,7 @@ private:
if(chain[TransformationComp_Scaling] != iter_end) { if(chain[TransformationComp_Scaling] != iter_end) {
ConvertScaleKeys(na, (*chain[TransformationComp_Scaling]).second, ConvertScaleKeys(na, (*chain[TransformationComp_Scaling]).second,
layer_map, layer_map,
start, stop,
max_time, max_time,
min_time); min_time);
} }
@ -2522,6 +2584,7 @@ private:
if(chain[TransformationComp_Rotation] != iter_end) { if(chain[TransformationComp_Rotation] != iter_end) {
ConvertRotationKeys(na, (*chain[TransformationComp_Rotation]).second, ConvertRotationKeys(na, (*chain[TransformationComp_Rotation]).second,
layer_map, layer_map,
start, stop,
max_time, max_time,
min_time, min_time,
target.RotationOrder()); target.RotationOrder());
@ -2539,6 +2602,7 @@ private:
if(chain[TransformationComp_Translation] != iter_end) { if(chain[TransformationComp_Translation] != iter_end) {
ConvertTranslationKeys(na, (*chain[TransformationComp_Translation]).second, ConvertTranslationKeys(na, (*chain[TransformationComp_Translation]).second,
layer_map, layer_map,
start, stop,
max_time, max_time,
min_time); min_time);
} }
@ -2558,17 +2622,21 @@ private:
// key (time), value, mapto (component index) // key (time), value, mapto (component index)
typedef boost::tuple< const KeyTimeList*, const KeyValueList*, unsigned int > KeyFrameList; typedef boost::tuple<boost::shared_ptr<KeyTimeList>, boost::shared_ptr<KeyValueList>, unsigned int > KeyFrameList;
typedef std::vector<KeyFrameList> KeyFrameListList; typedef std::vector<KeyFrameList> KeyFrameListList;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
KeyFrameListList GetKeyframeList(const std::vector<const AnimationCurveNode*>& nodes) KeyFrameListList GetKeyframeList(const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop)
{ {
KeyFrameListList inputs; KeyFrameListList inputs;
inputs.reserve(nodes.size()*3); inputs.reserve(nodes.size()*3);
//give some breathing room for rounding errors
int64_t adj_start = start - 10000;
int64_t adj_stop = stop + 10000;
BOOST_FOREACH(const AnimationCurveNode* node, nodes) { BOOST_FOREACH(const AnimationCurveNode* node, nodes) {
ai_assert(node); ai_assert(node);
@ -2593,7 +2661,23 @@ private:
const AnimationCurve* const curve = kv.second; const AnimationCurve* const curve = kv.second;
ai_assert(curve->GetKeys().size() == curve->GetValues().size() && curve->GetKeys().size()); ai_assert(curve->GetKeys().size() == curve->GetValues().size() && curve->GetKeys().size());
inputs.push_back(boost::make_tuple(&curve->GetKeys(), &curve->GetValues(), mapto)); //get values within the start/stop time window
boost::shared_ptr<KeyTimeList> Keys(new KeyTimeList());
boost::shared_ptr<KeyValueList> Values(new KeyValueList());
const int count = curve->GetKeys().size();
Keys->reserve(count);
Values->reserve(count);
for (int n = 0; n < count; n++)
{
int64_t k = curve->GetKeys().at(n);
if (k >= adj_start && k <= adj_stop)
{
Keys->push_back(k);
Values->push_back(curve->GetValues().at(n));
}
}
inputs.push_back(boost::make_tuple(Keys, Values, mapto));
} }
} }
return inputs; // pray for NRVO :-) return inputs; // pray for NRVO :-)
@ -2623,7 +2707,7 @@ private:
const size_t count = inputs.size(); const size_t count = inputs.size();
while(true) { while(true) {
uint64_t min_tick = std::numeric_limits<uint64_t>::max(); int64_t min_tick = std::numeric_limits<int64_t>::max();
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
const KeyFrameList& kfl = inputs[i]; const KeyFrameList& kfl = inputs[i];
@ -2632,7 +2716,7 @@ private:
} }
} }
if (min_tick == std::numeric_limits<uint64_t>::max()) { if (min_tick == std::numeric_limits<int64_t>::max()) {
break; break;
} }
keys.push_back(min_tick); keys.push_back(min_tick);
@ -2832,6 +2916,7 @@ private:
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/, void ConvertScaleKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
int64_t start, int64_t stop,
double& maxTime, double& maxTime,
double& minTime) double& minTime)
{ {
@ -2841,36 +2926,40 @@ private:
// layers should be multiplied with each other). There is a FBX // layers should be multiplied with each other). There is a FBX
// property in the layer to specify the behaviour, though. // property in the layer to specify the behaviour, though.
const KeyFrameListList& inputs = GetKeyframeList(nodes); const KeyFrameListList& inputs = GetKeyframeList(nodes, start, stop);
const KeyTimeList& keys = GetKeyTimeList(inputs); const KeyTimeList& keys = GetKeyTimeList(inputs);
na->mNumScalingKeys = static_cast<unsigned int>(keys.size()); na->mNumScalingKeys = static_cast<unsigned int>(keys.size());
na->mScalingKeys = new aiVectorKey[keys.size()]; na->mScalingKeys = new aiVectorKey[keys.size()];
InterpolateKeys(na->mScalingKeys, keys, inputs, true, maxTime, minTime); if (keys.size() > 0)
InterpolateKeys(na->mScalingKeys, keys, inputs, true, maxTime, minTime);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, void ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
const LayerMap& /*layers*/, const LayerMap& /*layers*/,
int64_t start, int64_t stop,
double& maxTime, double& maxTime,
double& minTime) double& minTime)
{ {
ai_assert(nodes.size()); ai_assert(nodes.size());
// XXX see notes in ConvertScaleKeys() // XXX see notes in ConvertScaleKeys()
const KeyFrameListList& inputs = GetKeyframeList(nodes); const KeyFrameListList& inputs = GetKeyframeList(nodes, start, stop);
const KeyTimeList& keys = GetKeyTimeList(inputs); const KeyTimeList& keys = GetKeyTimeList(inputs);
na->mNumPositionKeys = static_cast<unsigned int>(keys.size()); na->mNumPositionKeys = static_cast<unsigned int>(keys.size());
na->mPositionKeys = new aiVectorKey[keys.size()]; na->mPositionKeys = new aiVectorKey[keys.size()];
InterpolateKeys(na->mPositionKeys, keys, inputs, false, maxTime, minTime); if (keys.size() > 0)
InterpolateKeys(na->mPositionKeys, keys, inputs, false, maxTime, minTime);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, void ConvertRotationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
const LayerMap& /*layers*/, const LayerMap& /*layers*/,
int64_t start, int64_t stop,
double& maxTime, double& maxTime,
double& minTime, double& minTime,
Model::RotOrder order) Model::RotOrder order)
@ -2878,12 +2967,13 @@ private:
ai_assert(nodes.size()); ai_assert(nodes.size());
// XXX see notes in ConvertScaleKeys() // XXX see notes in ConvertScaleKeys()
const std::vector< KeyFrameList >& inputs = GetKeyframeList(nodes); const std::vector< KeyFrameList >& inputs = GetKeyframeList(nodes, start, stop);
const KeyTimeList& keys = GetKeyTimeList(inputs); const KeyTimeList& keys = GetKeyTimeList(inputs);
na->mNumRotationKeys = static_cast<unsigned int>(keys.size()); na->mNumRotationKeys = static_cast<unsigned int>(keys.size());
na->mRotationKeys = new aiQuatKey[keys.size()]; na->mRotationKeys = new aiQuatKey[keys.size()];
InterpolateKeys(na->mRotationKeys, keys, inputs, false, maxTime, minTime, order); if (keys.size() > 0)
InterpolateKeys(na->mRotationKeys, keys, inputs, false, maxTime, minTime, order);
} }

View File

@ -871,7 +871,7 @@ private:
std::vector<unsigned int> mappings; std::vector<unsigned int> mappings;
}; };
typedef std::vector<uint64_t> KeyTimeList; typedef std::vector<int64_t> KeyTimeList;
typedef std::vector<float> KeyValueList; typedef std::vector<float> KeyValueList;
/** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefor) */ /** Represents a FBX animation curve (i.e. a 1-dimensional set of keyframes and values therefor) */
@ -1015,10 +1015,10 @@ public:
public: public:
fbx_simple_property(LocalStart, uint64_t, 0L) fbx_simple_property(LocalStart, int64_t, 0L)
fbx_simple_property(LocalStop, uint64_t, 0L) fbx_simple_property(LocalStop, int64_t, 0L)
fbx_simple_property(ReferenceStart, uint64_t, 0L) fbx_simple_property(ReferenceStart, int64_t, 0L)
fbx_simple_property(ReferenceStop, uint64_t, 0L) fbx_simple_property(ReferenceStop, int64_t, 0L)

View File

@ -431,6 +431,43 @@ int ParseTokenAsInt(const Token& t, const char*& err_out)
} }
// ------------------------------------------------------------------------------------------------
int64_t ParseTokenAsInt64(const Token& t, const char*& err_out)
{
err_out = NULL;
if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token";
return 0L;
}
if (t.IsBinary())
{
const char* data = t.begin();
if (data[0] != 'L') {
err_out = "failed to parse Int64, unexpected data type";
return 0L;
}
BE_NCONST int64_t id = SafeParse<int64_t>(data + 1, t.end());
AI_SWAP8(id);
return id;
}
// XXX: should use size_t here
unsigned int length = static_cast<unsigned int>(t.end() - t.begin());
ai_assert(length > 0);
const char* out;
const int64_t id = strtoul10_64(t.begin(), &out, &length);
if (out > t.end()) {
err_out = "failed to parse Int64 (text)";
return 0L;
}
return id;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::string ParseTokenAsString(const Token& t, const char*& err_out) std::string ParseTokenAsString(const Token& t, const char*& err_out)
{ {
@ -1062,6 +1099,63 @@ void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& el)
} }
} }
// ------------------------------------------------------------------------------------------------
// read an array of int64_ts
void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el)
{
out.clear();
const TokenList& tok = el.Tokens();
if (tok.empty()) {
ParseError("unexpected empty element", &el);
}
if (tok[0]->IsBinary()) {
const char* data = tok[0]->begin(), *end = tok[0]->end();
char type;
uint32_t count;
ReadBinaryDataArrayHead(data, end, type, count, el);
if (!count) {
return;
}
if (type != 'l') {
ParseError("expected long array (binary)", &el);
}
std::vector<char> buff;
ReadBinaryDataArray(type, count, data, end, buff, el);
ai_assert(data == end);
ai_assert(buff.size() == count * 8);
out.reserve(count);
const int64_t* ip = reinterpret_cast<const int64_t*>(&buff[0]);
for (unsigned int i = 0; i < count; ++i, ++ip) {
BE_NCONST int64_t val = *ip;
AI_SWAP8(val);
out.push_back(val);
}
return;
}
const size_t dim = ParseTokenAsDim(*tok[0]);
// see notes in ParseVectorDataArray()
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 int64_t ival = ParseTokenAsInt64(**it++);
out.push_back(ival);
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiMatrix4x4 ReadMatrix(const Element& element) aiMatrix4x4 ReadMatrix(const Element& element)
@ -1205,6 +1299,18 @@ int ParseTokenAsInt(const Token& t)
// ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsInt64() with ParseError handling
int64_t ParseTokenAsInt64(const Token& t)
{
const char* err;
const int64_t i = ParseTokenAsInt64(t, err);
if (err) {
ParseError(err, t);
}
return i;
}
} // !FBX } // !FBX
} // !Assimp } // !Assimp

View File

@ -206,6 +206,7 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out);
float ParseTokenAsFloat(const Token& t, const char*& err_out); float ParseTokenAsFloat(const Token& t, const char*& err_out);
int ParseTokenAsInt(const Token& t, const char*& err_out); int ParseTokenAsInt(const Token& t, const char*& err_out);
int64_t ParseTokenAsInt64(const Token& t, const char*& err_out);
std::string ParseTokenAsString(const Token& t, const char*& err_out); std::string ParseTokenAsString(const Token& t, const char*& err_out);
@ -214,6 +215,7 @@ uint64_t ParseTokenAsID(const Token& t);
size_t ParseTokenAsDim(const Token& t); size_t ParseTokenAsDim(const Token& t);
float ParseTokenAsFloat(const Token& t); float ParseTokenAsFloat(const Token& t);
int ParseTokenAsInt(const Token& t); int ParseTokenAsInt(const Token& t);
int64_t ParseTokenAsInt64(const Token& t);
std::string ParseTokenAsString(const Token& t); std::string ParseTokenAsString(const Token& t);
/* read data arrays */ /* read data arrays */
@ -224,6 +226,7 @@ void ParseVectorDataArray(std::vector<int>& out, const Element& el);
void ParseVectorDataArray(std::vector<float>& out, const Element& el); void ParseVectorDataArray(std::vector<float>& out, const Element& el);
void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el); void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el);
void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& e); void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& e);
void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el);

View File

@ -88,9 +88,12 @@ Property* ReadTypedProperty(const Element& element)
else if (!strcmp(cs, "int") || !strcmp(cs, "Int") || !strcmp(cs, "enum") || !strcmp(cs, "Enum")) { else if (!strcmp(cs, "int") || !strcmp(cs, "Int") || !strcmp(cs, "enum") || !strcmp(cs, "Enum")) {
return new TypedProperty<int>(ParseTokenAsInt(*tok[4])); return new TypedProperty<int>(ParseTokenAsInt(*tok[4]));
} }
else if (!strcmp(cs,"ULongLong")) { else if (!strcmp(cs, "ULongLong")) {
return new TypedProperty<uint64_t>(ParseTokenAsID(*tok[4])); return new TypedProperty<uint64_t>(ParseTokenAsID(*tok[4]));
} }
else if (!strcmp(cs, "KTime")) {
return new TypedProperty<int64_t>(ParseTokenAsInt64(*tok[4]));
}
else if (!strcmp(cs,"Vector3D") || else if (!strcmp(cs,"Vector3D") ||
!strcmp(cs,"ColorRGB") || !strcmp(cs,"ColorRGB") ||
!strcmp(cs,"Vector") || !strcmp(cs,"Vector") ||
@ -105,7 +108,7 @@ Property* ReadTypedProperty(const Element& element)
ParseTokenAsFloat(*tok[6])) ParseTokenAsFloat(*tok[6]))
); );
} }
else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"KTime") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView")) { else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView")) {
return new TypedProperty<float>(ParseTokenAsFloat(*tok[4])); return new TypedProperty<float>(ParseTokenAsFloat(*tok[4]));
} }
return NULL; return NULL;

View File

@ -87,7 +87,7 @@ static const aiImporterDesc desc = {
"", "",
"", "",
"", "",
aiImporterFlags_SupportTextFlavour, aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportCompressedFlavour,
0, 0,
0, 0,
0, 0,

Binary file not shown.

View File

@ -164,7 +164,7 @@ def gen_db(ext_list,outfile):
num = 0 num = 0
for tp in settings.model_directories: for tp in settings.model_directories:
num += process_dir(tp, outfile, num += process_dir(tp, outfile,
lambda x: os.path.splitext(x)[1] in ext_list) lambda x: os.path.splitext(x)[1].lower() in ext_list and not x in settings.files_to_ignore)
print("="*60) print("="*60)
print("Updated {0} entries".format(num)) print("Updated {0} entries".format(num))
@ -201,7 +201,7 @@ if __name__ == "__main__":
if ext_list is None: if ext_list is None:
(ext_list, err) = subprocess.Popen([assimp_bin_path, "listext"], (ext_list, err) = subprocess.Popen([assimp_bin_path, "listext"],
stdout=subprocess.PIPE).communicate() stdout=subprocess.PIPE).communicate()
ext_list = str(ext_list).lower().split(";") ext_list = str(ext_list.strip()).lower().split(";")
# todo: Fix for multi dot extensions like .skeleton.xml # todo: Fix for multi dot extensions like .skeleton.xml
ext_list = list(filter(lambda f: not f in settings.exclude_extensions, ext_list = list(filter(lambda f: not f in settings.exclude_extensions,

View File

@ -65,7 +65,7 @@ import utils
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
EXPECTED_FAILURE_NOT_MET, DATABASE_LENGTH_MISMATCH, \ EXPECTED_FAILURE_NOT_MET, DATABASE_LENGTH_MISMATCH, \
DATABASE_VALUE_MISMATCH, IMPORT_FAILURE, \ DATABASE_VALUE_MISMATCH, IMPORT_FAILURE, \
FILE_NOT_READABLE, COMPARE_SUCCESS = range(6) FILE_NOT_READABLE, COMPARE_SUCCESS, EXPECTED_FAILURE = range(7)
messages = collections.defaultdict(lambda: "<unknown", { messages = collections.defaultdict(lambda: "<unknown", {
EXPECTED_FAILURE_NOT_MET: EXPECTED_FAILURE_NOT_MET:
@ -88,7 +88,10 @@ messages = collections.defaultdict(lambda: "<unknown", {
COMPARE_SUCCESS: COMPARE_SUCCESS:
"""Results match archived reference dump in database\n\ """Results match archived reference dump in database\n\
\tNumber of bytes compared: {0}""" \tNumber of bytes compared: {0}""",
EXPECTED_FAILURE:
"""Expected failure was met.""",
}) })
outfilename_output = "run_regression_suite_output.txt" outfilename_output = "run_regression_suite_output.txt"
@ -211,6 +214,10 @@ def process_dir(d, outfile_results, zipin, result):
result.fail(fullpath, outfile_expect, pppreset, EXPECTED_FAILURE_NOT_MET) result.fail(fullpath, outfile_expect, pppreset, EXPECTED_FAILURE_NOT_MET)
outfile_results.write("Expected import to fail\n") outfile_results.write("Expected import to fail\n")
continue continue
elif failure and r:
result.ok(fullpath, pppreset, EXPECTED_FAILURE)
outfile_results.write("Failed as expected, skipping.\n")
continue
with open(outfile_expect, "wb") as s: with open(outfile_expect, "wb") as s:
s.write(input_expected) s.write(input_expected)

View File

@ -60,9 +60,9 @@ files_to_ignore = ["pond.0.ply"]
# File extensions are case insensitive # File extensions are case insensitive
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
exclude_extensions = [ exclude_extensions = [
".lws", ".assbin", ".assxml", ".txt", ".md", ".assbin", ".assxml", ".txt", ".md",
".jpeg", ".jpg", ".png", ".gif", ".tga", ".bmp", ".jpeg", ".jpg", ".png", ".gif", ".tga", ".bmp",
".skeleton", ".skeleton.xml", ".license" ".skeleton", ".skeleton.xml", ".license", ".mtl", ".material"
] ]
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------

View File

@ -50,15 +50,13 @@ def hashing(file,pp):
needs to be persistent across different python implementations needs to be persistent across different python implementations
and platforms, so we implement the hashing manually. and platforms, so we implement the hashing manually.
""" """
file = file.lower()
file = file.replace('\\','/')+":"+pp file = file.replace('\\','/')+":"+pp
# SDBM hash # SDBM hash
res = 0 res = 0
for t in file: for t in file:
res = (ord(t) + (res<<6) + (res<<16) - res) % 2**32 res = (ord(t) + (res<<6) + (res<<16) - res) % 2**32
return '{:x}'.format(res)
# Python 2.7 normalization: strip 'L' suffix.
return hex(res).rstrip('L')
# vim: ai ts=4 sts=4 et sw=4 # vim: ai ts=4 sts=4 et sw=4

View File

@ -134,15 +134,16 @@ public:
if(it != history.back().second.end()) { if(it != history.back().second.end()) {
++history.back().second[s]; ++history.back().second[s];
} }
else history.back().second[s] = 1; else history.back().second[s] = 0;
history.push_back(HistoryEntry(s,PerChunkCounter())); history.push_back(HistoryEntry(s,PerChunkCounter()));
debug_trace.push_back("PUSH " + s);
} }
/* leave current scope */ /* leave current scope */
void pop_elem() { void pop_elem() {
ai_assert(history.size()); ai_assert(history.size());
debug_trace.push_back("POP "+ history.back().first);
history.pop_back(); history.pop_back();
} }
@ -243,18 +244,22 @@ private:
const char* last = history.back().first.c_str(); const char* last = history.back().first.c_str();
std::string pad; std::string pad;
for(ChunkHistory::reverse_iterator rev = ++history.rbegin(), for(ChunkHistory::reverse_iterator rev = history.rbegin(),
end = history.rend(); rev < end; ++rev, pad += " ") end = history.rend(); rev != end; ++rev, pad += " ")
{ {
ss << pad << (*rev).first << "(Index: " << (*rev).second[last]-1 << ")" << std::endl; ss << pad << (*rev).first << "(Index: " << (*rev).second[last] << ")" << std::endl;
last = (*rev).first.c_str(); last = (*rev).first.c_str();
} }
ss << std::endl << "Debug trace: "<< std::endl;
for (std::vector<std::string>::const_iterator it = debug_trace.begin(); it != debug_trace.end(); ++it) {
ss << *it << std::endl;
}
return ss.str(); return ss.str();
} }
/* read from both streams simult.*/ /* read from both streams at the same time */
template <typename T> void read(T& filla,T& fille) { template <typename T> void read(T& filla,T& fille) {
if(1 != fread(&filla,sizeof(T),1,actual)) { if(1 != fread(&filla,sizeof(T),1,actual)) {
EOFActual(); EOFActual();
@ -291,6 +296,8 @@ private:
typedef std::deque<HistoryEntry> ChunkHistory; typedef std::deque<HistoryEntry> ChunkHistory;
ChunkHistory history; ChunkHistory history;
std::vector<std::string> debug_trace;
typedef std::stack<std::pair<uint32_t,uint32_t> > LengthStack; typedef std::stack<std::pair<uint32_t,uint32_t> > LengthStack;
LengthStack lengths; LengthStack lengths;
@ -739,7 +746,7 @@ void CompareOnTheFlyLight(comparer_context& comp) {
const aiLightSourceType type = static_cast<aiLightSourceType>( const aiLightSourceType type = static_cast<aiLightSourceType>(
comp.cmp<uint32_t>("mType")); comp.cmp<uint32_t>("mType"));
if(type==aiLightSource_DIRECTIONAL) { if(type!=aiLightSource_DIRECTIONAL) {
comp.cmp<float>("mAttenuationConstant"); comp.cmp<float>("mAttenuationConstant");
comp.cmp<float>("mAttenuationLinear"); comp.cmp<float>("mAttenuationLinear");
comp.cmp<float>("mAttenuationQuadratic"); comp.cmp<float>("mAttenuationQuadratic");