From 14f77735db46e273cf9d7a359e2b5b8040e90168 Mon Sep 17 00:00:00 2001
From: Tazpn <tazpn@users.sourceforge.net>
Date: Mon, 24 Sep 2007 04:17:56 +0000
Subject: [PATCH] Add support for Freedom Force Animation

---
 NifImport/ImportAnimation.cpp | 23 ++++++++++++++++
 NifImport/KFImporter.cpp      | 49 +++++++++++++++++++++++++++++++++--
 2 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/NifImport/ImportAnimation.cpp b/NifImport/ImportAnimation.cpp
index 73c1451..695028b 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 43180a3..d3c34ac 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&)
    {
-- 
GitLab