diff --git a/NifImport/ImportAnimation.cpp b/NifImport/ImportAnimation.cpp index 73c14518ee861f2e4ac51cb76a67530dca37d8d2..695028bc00a6750a6dfebb790bbda74e9d7c9639 100644 --- a/NifImport/ImportAnimation.cpp +++ b/NifImport/ImportAnimation.cpp @@ -588,6 +588,29 @@ bool KFMImporter::ImportAnimation() } } } + else if (strmatch(type, "NiKeyframeController")) + { + Control *c = ai.GetTMController(name); + if (NULL == c) + continue; + + INode *n = gi->GetINodeByName(name.c_str()); + + if ((*lnk).priority_ != 0.0f) { + npSetProp(n, NP_ANM_PRI, (*lnk).priority_); + } + + NiKeyframeDataRef data; + Point3 p; Quat q; float s; + if (ai.GetTransformData(*lnk, name, data, p, q, s)) { + PosRotScaleNode(n, p, q, s, prsDefault, 0); + if (ai.AddValues(c, data, time)) { + minTime = min(minTime, start); + maxTime = max(maxTime, stop); + ok = true; + } + } + } } if (maxTime > minTime && maxTime > 0.0f) time += (maxTime-minTime) + FramesIncrement; diff --git a/NifImport/KFImporter.cpp b/NifImport/KFImporter.cpp index 43180a3545c7f778ca8857e2e40f8fd6ff4a3d6f..d3c34ac165a4ec65f2523980807867a8d6cfd899 100644 --- a/NifImport/KFImporter.cpp +++ b/NifImport/KFImporter.cpp @@ -2,6 +2,10 @@ #include "KFImporter.h" #include <kfm.h> #include "gen/ControllerLink.h" +#include "obj/NiSequenceStreamHelper.h" +#include "obj/NiTextKeyExtraData.h" +#include "obj/NiTimeController.h" +#include <float.h> using namespace Niflib; KFImporter::KFImporter(const TCHAR *Name,ImpInterface *I,Interface *GI, BOOL SuppressPrompts) @@ -18,8 +22,49 @@ void KFImporter::ReadBlocks() { try { - kf = DynamicCast<NiControllerSequence>(ReadNifList(name.c_str())); - BuildNodes(); + // Handle Freedom Force Animation Import + std::vector<NiObjectRef> roots = ReadNifList(name.c_str()); + kf = DynamicCast<NiControllerSequence>(roots); + if (kf.size() == 0) + { + std::vector<NiSequenceStreamHelperRef> helpers = DynamicCast<NiSequenceStreamHelper>(roots); + for (std::vector<NiSequenceStreamHelperRef>::iterator itr = helpers.begin(); itr != helpers.end(); ++itr) + { + NiSequenceStreamHelperRef helper = (*itr); + + list< Ref<NiExtraData> > data = helper->GetExtraData(); + NiTextKeyExtraDataRef textKey = DynamicCast<NiTextKeyExtraData>(data).front(); + list< NiStringExtraDataRef > keys = DynamicCast<NiStringExtraData>(data); + list< Ref<NiTimeController> > controllers = helper->GetControllers(); + + if (keys.size() == controllers.size()) + { + int nk = keys.size(); + + NiControllerSequenceRef seq = new NiControllerSequence(); + seq->SetName( helper->GetName() ); + seq->SetTextKey( textKey ); + + float start = FLT_MAX, stop = FLT_MIN; + vector< Key<string> > textKeys = textKey->GetKeys(); + for (vector< Key<string> >::iterator tItr = textKeys.begin(); tItr != textKeys.end(); ++tItr) { + start = min(start, tItr->time); + stop = max(stop, tItr->time); + } + seq->SetStartTime( start ); + seq->SetStopTime( stop ); + + list< NiStringExtraDataRef >::iterator keyItr = keys.begin(); + list< NiTimeControllerRef >::iterator ctrlItr = controllers.begin(); + for (int i=0; i<nk; ++i, ++keyItr, ++ctrlItr) { + seq->AddController( (*keyItr)->GetData(), (*ctrlItr) ); + } + kf.push_back( seq ); + } + } + } + + BuildNodes(); } catch (std::exception&) {