mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 20:56:42 +00:00 
			
		
		
		
	Reintroducing animation
This commit is contained in:
		
							parent
							
								
									2236f69645
								
							
						
					
					
						commit
						d035441876
					
				
					 3 changed files with 388 additions and 19 deletions
				
			
		|  | @ -25,6 +25,8 @@ | |||
| #define _NIF_DATA_H_ | ||||
| 
 | ||||
| #include "controlled.hpp" | ||||
| #include <iostream> | ||||
| #include <Ogre.h> | ||||
| 
 | ||||
| namespace Nif | ||||
| { | ||||
|  | @ -433,20 +435,91 @@ public: | |||
| 
 | ||||
| class NiKeyframeData : public Record | ||||
| { | ||||
| 	 | ||||
| 	//Rotations
 | ||||
| 	std::vector<Ogre::Quaternion> quats; | ||||
| 	std::vector<Ogre::Vector3> tbc; | ||||
| 	std::vector<float> rottime; | ||||
| 	int rtype; | ||||
| 
 | ||||
| 	//Translations
 | ||||
| 	std::vector<Ogre::Vector3> translist1; | ||||
| 	std::vector<Ogre::Vector3> translist2; | ||||
| 	std::vector<Ogre::Vector3> translist3; | ||||
| 	std::vector<Ogre::Vector3> transtbc; | ||||
| 	std::vector<float> transtime; | ||||
| 	int ttype; | ||||
| 
 | ||||
| 	//Scalings
 | ||||
| 
 | ||||
| 	std::vector<float> scalefactor; | ||||
| 	std::vector<float> scaletime; | ||||
| 	std::vector<float> forwards; | ||||
| 	std::vector<float> backwards; | ||||
| 	std::vector<Ogre::Vector3> tbcscale; | ||||
| 	int stype; | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
|   void read(NIFFile *nif) | ||||
|   { | ||||
|     // Rotations first
 | ||||
|     int count = nif->getInt(); | ||||
| 	//std::vector<Ogre::Quaternion> quat(count);
 | ||||
| 	//std::vector<float> rottime(count);
 | ||||
| 	std::cout << "r"; | ||||
|     if(count) | ||||
|       { | ||||
|         int type = nif->getInt(); | ||||
| 
 | ||||
|         if(type == 1) | ||||
|           nif->skip(count*4*5); // time + quaternion
 | ||||
|         else if(type == 3) | ||||
|           nif->skip(count*4*8); // rot1 + tension+bias+continuity
 | ||||
|         else if(type == 4) | ||||
| 		//TYPE1  LINEAR_KEY
 | ||||
| 		//TYPE2  QUADRATIC_KEY
 | ||||
| 		//TYPE3  TBC_KEY
 | ||||
| 		//TYPE4  XYZ_ROTATION_KEY
 | ||||
| 		//TYPE5  UNKNOWN_KEY
 | ||||
|         rtype = nif->getInt(); | ||||
| 		    //std::cout << "Count: " << count << "Type: " << type << "\n";
 | ||||
| 
 | ||||
|         if(rtype == 1) | ||||
| 		{ | ||||
| 			//We need to actually read in these values instead of skipping them
 | ||||
| 			//nif->skip(count*4*5); // time + quaternion
 | ||||
| 			for (int i = 0; i < count; i++) { | ||||
| 			    float time = nif->getFloat(); | ||||
| 			    float w = nif->getFloat(); | ||||
| 			    float x = nif->getFloat(); | ||||
| 			    float y = nif->getFloat(); | ||||
| 			    float z = nif->getFloat(); | ||||
| 				Ogre::Quaternion quat = Ogre::Quaternion(Ogre::Real(w), Ogre::Real(x), Ogre::Real(y), Ogre::Real(z)); | ||||
| 				quats.push_back(quat); | ||||
| 				rottime.push_back(time); | ||||
| 				//if(time == 0.0 || time > 355.5) 
 | ||||
| 					// std::cout <<"Time:" << time << "W:" << w <<"X:" << x << "Y:" << y << "Z:" << z << "\n";
 | ||||
| 			} | ||||
| 		} | ||||
|         else if(rtype == 3) | ||||
| 		{                  //Example - node 116 in base_anim.nif
 | ||||
| 			for (int i = 0; i < count; i++) { | ||||
| 			    float time = nif->getFloat(); | ||||
| 			    float w = nif->getFloat(); | ||||
| 			    float x = nif->getFloat(); | ||||
| 			    float y = nif->getFloat(); | ||||
| 			    float z = nif->getFloat(); | ||||
| 
 | ||||
| 				float tbcx = nif->getFloat(); | ||||
| 				float tbcy = nif->getFloat(); | ||||
| 				float tbcz = nif->getFloat(); | ||||
| 				Ogre::Quaternion quat = Ogre::Quaternion(Ogre::Real(w), Ogre::Real(x), Ogre::Real(y), Ogre::Real(z)); | ||||
| 				Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz); | ||||
| 				quats.push_back(quat); | ||||
| 				rottime.push_back(time); | ||||
| 				tbc.push_back(vec); | ||||
| 				//if(time == 0.0 || time > 355.5) 
 | ||||
| 					// std::cout <<"Time:" << time << "W:" << w <<"X:" << x << "Y:" << y << "Z:" << z << "\n";
 | ||||
| 			} | ||||
| 
 | ||||
|           //nif->skip(count*4*8); // rot1 + tension+bias+continuity
 | ||||
| 		} | ||||
|         else if(rtype == 4) | ||||
|           { | ||||
|             for(int j=0;j<count;j++) | ||||
|               { | ||||
|  | @ -465,18 +538,69 @@ public: | |||
|           } | ||||
|         else nif->fail("Unknown rotation type in NiKeyframeData"); | ||||
|       } | ||||
| 	//first = false;
 | ||||
| 
 | ||||
|     // Then translation
 | ||||
|     count = nif->getInt(); | ||||
| 	 | ||||
|     if(count) | ||||
|       { | ||||
|         int type = nif->getInt(); | ||||
|        ttype = nif->getInt(); | ||||
| 
 | ||||
|         if(type == 1) nif->getFloatLen(count*4); // time + translation
 | ||||
|         else if(type == 2) | ||||
|           nif->getFloatLen(count*10); // trans1 + forward + backward
 | ||||
|         else if(type == 3) | ||||
|           nif->getFloatLen(count*7); // trans1 + tension,bias,continuity
 | ||||
| 		//std::cout << "TransCount:" << count << " Type: " << type << "\n";
 | ||||
|         if(ttype == 1) { | ||||
| 			for (int i = 0; i < count; i++) { | ||||
| 				float time = nif->getFloat(); | ||||
| 				float x = nif->getFloat(); | ||||
| 				float y = nif->getFloat(); | ||||
| 				float z = nif->getFloat(); | ||||
| 				Ogre::Vector3 trans = Ogre::Vector3(x, y, z); | ||||
| 				translist1.push_back(trans); | ||||
| 				transtime.push_back(time); | ||||
| 			} | ||||
| 			//nif->getFloatLen(count*4); // time + translation
 | ||||
| 		} | ||||
|         else if(ttype == 2) | ||||
| 		{                                        //Example - node 116 in base_anim.nif
 | ||||
| 			for (int i = 0; i < count; i++) { | ||||
| 				float time = nif->getFloat(); | ||||
| 				float x = nif->getFloat(); | ||||
| 				float y = nif->getFloat(); | ||||
| 				float z = nif->getFloat(); | ||||
| 				float x2 = nif->getFloat(); | ||||
| 				float y2 = nif->getFloat(); | ||||
| 				float z2 = nif->getFloat(); | ||||
| 				float x3 = nif->getFloat(); | ||||
| 				float y3 = nif->getFloat(); | ||||
| 				float z3 = nif->getFloat(); | ||||
| 				Ogre::Vector3 trans = Ogre::Vector3(x, y, z); | ||||
| 				Ogre::Vector3 trans2 = Ogre::Vector3(x2, y2, z2); | ||||
| 				Ogre::Vector3 trans3 = Ogre::Vector3(x3, y3, z3); | ||||
| 				transtime.push_back(time); | ||||
| 				translist1.push_back(trans); | ||||
| 				translist2.push_back(trans2); | ||||
| 				translist3.push_back(trans3); | ||||
| 			} | ||||
| 			 | ||||
| 			//nif->getFloatLen(count*10); // trans1 + forward + backward
 | ||||
| 		} | ||||
|         else if(ttype == 3){ | ||||
| 			for (int i = 0; i < count; i++) { | ||||
| 				float time = nif->getFloat(); | ||||
| 				float x = nif->getFloat(); | ||||
| 				float y = nif->getFloat(); | ||||
| 				float z = nif->getFloat(); | ||||
| 				float t = nif->getFloat(); | ||||
| 				float b = nif->getFloat(); | ||||
| 				float c = nif->getFloat(); | ||||
| 				Ogre::Vector3 trans = Ogre::Vector3(x, y, z); | ||||
| 				Ogre::Vector3 tbc = Ogre::Vector3(t, b, c); | ||||
| 				translist1.push_back(trans); | ||||
| 				transtbc.push_back(tbc); | ||||
| 				transtime.push_back(time); | ||||
| 			} | ||||
|           //nif->getFloatLen(count*7); // trans1 + tension,bias,continuity
 | ||||
| 		} | ||||
|         else nif->fail("Unknown translation type"); | ||||
|       } | ||||
| 
 | ||||
|  | @ -484,17 +608,93 @@ public: | |||
|     count = nif->getInt(); | ||||
|     if(count) | ||||
|       { | ||||
|         int type = nif->getInt(); | ||||
|         stype = nif->getInt(); | ||||
| 
 | ||||
|         int size = 0; | ||||
|         if(type == 1) size = 2; // time+scale
 | ||||
|         else if(type == 2) size = 4; // 1 + forward + backward (floats)
 | ||||
|         else if(type == 3) size = 5; // 1 + tbc
 | ||||
|         else nif->fail("Unknown scaling type"); | ||||
|         nif->getFloatLen(count*size); | ||||
| 		 | ||||
| 		for(int i = 0; i < count; i++){ | ||||
| 					 | ||||
| 				 | ||||
|         //int size = 0;
 | ||||
|         if(stype >= 1 && stype < 4)  | ||||
| 			{ | ||||
| 				float time = nif->getFloat(); | ||||
| 				float scale = nif->getFloat(); | ||||
| 				scaletime.push_back(time); | ||||
| 				scalefactor.push_back(scale); | ||||
| 				//size = 2; // time+scale
 | ||||
| 			} | ||||
| 		else nif->fail("Unknown scaling type"); | ||||
|          if(stype == 2){ | ||||
| 			//size = 4; // 1 + forward + backward (floats)
 | ||||
| 			float forward = nif->getFloat(); | ||||
| 			float backward = nif->getFloat(); | ||||
| 			forwards.push_back(forward); | ||||
| 			backwards.push_back(backward); | ||||
| 		} | ||||
| 		else if(stype == 3){ | ||||
| 			float tbcx = nif->getFloat(); | ||||
| 			float tbcy = nif->getFloat(); | ||||
| 			float tbcz = nif->getFloat(); | ||||
| 			Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz); | ||||
| 			tbcscale.push_back(vec); | ||||
| 
 | ||||
| 			//size = 5; // 1 + tbc
 | ||||
| 		} | ||||
|          | ||||
| 		} | ||||
|       } | ||||
| 	  else  | ||||
| 		  stype = 0; | ||||
|   } | ||||
|   	int getRtype(){ | ||||
| 		return rtype; | ||||
| 	} | ||||
| 	int getStype(){ | ||||
| 		return stype; | ||||
| 	} | ||||
| 	int getTtype(){ | ||||
| 		return ttype; | ||||
| 	} | ||||
| 	std::vector<Ogre::Quaternion> getQuat(){ | ||||
| 		return quats; | ||||
| 	} | ||||
| 	std::vector<Ogre::Vector3> getrTbc(){ | ||||
| 		return tbc; | ||||
| 	} | ||||
| 	std::vector<float> getrTime(){ | ||||
| 		return rottime; | ||||
| 	} | ||||
| 
 | ||||
| 	std::vector<Ogre::Vector3> getTranslist1(){ | ||||
| 		return translist1; | ||||
| 	} | ||||
| 	std::vector<Ogre::Vector3> getTranslist2(){ | ||||
| 		return translist2; | ||||
| 	} | ||||
| 	std::vector<Ogre::Vector3> getTranslist3(){ | ||||
| 		return translist3; | ||||
| 	} | ||||
| 	std::vector<float> gettTime(){ | ||||
| 		return transtime; | ||||
| 	} | ||||
| 	std::vector<float> getScalefactor(){ | ||||
| 		return scalefactor; | ||||
| 	} | ||||
| 	std::vector<float> getForwards(){ | ||||
| 		return forwards; | ||||
| 	} | ||||
| 	std::vector<float> getBackwards(){ | ||||
| 		return backwards; | ||||
| 	} | ||||
| 	std::vector<Ogre::Vector3> getScaleTbc(){ | ||||
| 		return tbcscale; | ||||
| 	} | ||||
| 
 | ||||
| 	std::vector<float> getsTime(){ | ||||
| 		return scaletime; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| } // Namespace
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -1068,6 +1068,11 @@ void NIFLoader::loadResource(Resource *resource) | |||
|     // Handle the node
 | ||||
|     handleNode(node, 0, NULL, bounds, 0); | ||||
| 
 | ||||
| 
 | ||||
| 	short handle = 0; | ||||
| 	//skel->setBlendMode(Ogre::SkeletonAnimationBlendMode::ANIMBLEND_CUMULATIVE);
 | ||||
| 	bool first = true; | ||||
| 	 | ||||
|     // set the bounding value.
 | ||||
|     if (bounds.isValid()) | ||||
|     { | ||||
|  | @ -1075,6 +1080,166 @@ void NIFLoader::loadResource(Resource *resource) | |||
|                                         bounds.maxX(), bounds.maxY(), bounds.maxZ())); | ||||
|         mesh->_setBoundingSphereRadius(bounds.getRadius()); | ||||
|     } | ||||
| 	for(int i = 0; i < nif.numRecords(); i++) | ||||
| 	{ | ||||
| 		 | ||||
| 	Nif::NiKeyframeController *f = dynamic_cast<Nif::NiKeyframeController*>(nif.getRecord(i)); | ||||
| 	Nif::Node *n = dynamic_cast<Nif::Node*>(nif.getRecord(i)); | ||||
| 	 | ||||
| 
 | ||||
| 	if(f != NULL) | ||||
| 	{ | ||||
| 		Nif::NiKeyframeDataPtr data = f->data; | ||||
| 		std::cout << "Controller's Rtype:" <<  data->getRtype() << "Stype: " << data->getStype() << "Ttype:" << data->getTtype() << "\n"; | ||||
| 		 | ||||
| 		if(first){ | ||||
| 
 | ||||
| 			float end = f->timeStop; | ||||
| 			//std::cout <<"Creating WholeThing" << end << "\n";
 | ||||
| 			 | ||||
| 			//TRANSLATION
 | ||||
| 			if(!mSkel.isNull()){ | ||||
| 			std::cout <<"Creating WholeThing" << end << "\n"; | ||||
| 			animcore = mSkel->createAnimation("WholeThing", end); | ||||
| 			//animcore->setInterpolationMode(Ogre::Animation::IM_SPLINE);
 | ||||
| 			//animcore->setRotationInterpolationMode(Ogre::Animation::RIM_SPHERICAL);
 | ||||
| 			//animcore2->setRotationInterpolationMode(Ogre::Animation::RIM_LINEAR);
 | ||||
| 
 | ||||
| 			//ROTATION
 | ||||
| 			animcore2 = mSkel->createAnimation("WholeThing2", end); | ||||
| 			//animcore2->setInterpolationMode(Ogre::Animation::IM_SPLINE);
 | ||||
| 			//animcore2->setRotationInterpolationMode(Ogre::Animation::RIM_SPHERICAL);
 | ||||
| 			} | ||||
| 			std::cout <<"AFTER"; | ||||
| 			first = false; | ||||
| 		} | ||||
| 		 if(animcore && animcore2){ | ||||
| 		Nif::Named *node = dynamic_cast<Nif::Named*> ( f->target.getPtr()); | ||||
| 			std::cout << "The target rec: " << node->name.toString() << "\n"; | ||||
| 			Ogre::NodeAnimationTrack* mTrack = animcore->createNodeTrack(handle, mSkel->getBone(node->name.toString())); | ||||
| 		Ogre::NodeAnimationTrack* mTrack2 = animcore2->createNodeTrack(handle++, mSkel->getBone(node->name.toString())); | ||||
| 			/* if (node->recType == RC_NiNode)
 | ||||
| 		{ | ||||
|         NodeList &list = ((NiNode*)node)->children; | ||||
|         int n = list.length(); | ||||
| 		 | ||||
|         for (int i = n; i<=n; i++) | ||||
|         { | ||||
| 			if(skel->hasBone((list[i]).name.toString())) | ||||
| 				mTrack3 = animcore2->createNodeTrack(handle++, skel->getBone((list[i]).name.toString())); | ||||
|              | ||||
|         } | ||||
|     }*/ | ||||
| 		 | ||||
| 		std::vector<Ogre::Quaternion> quats = data->getQuat(); | ||||
| 		std::vector<Ogre::Quaternion>::iterator quatIter = quats.begin(); | ||||
| 		std::vector<float> rtime = data->getrTime(); | ||||
| 		std::vector<float>::iterator rtimeiter = rtime.begin(); | ||||
| 
 | ||||
| 		std::vector<float> ttime = data->gettTime(); | ||||
| 		std::vector<float>::iterator ttimeiter = ttime.begin(); | ||||
| 		std::vector<Ogre::Vector3> translist1  = data->getTranslist1(); | ||||
| 		std::vector<Ogre::Vector3>::iterator transiter = translist1.begin(); | ||||
| 		std::vector<Ogre::Vector3> translist2  = data->getTranslist2(); | ||||
| 		std::vector<Ogre::Vector3>::iterator transiter2 = translist2.begin(); | ||||
| 		std::vector<Ogre::Vector3> translist3  = data->getTranslist3(); | ||||
| 		std::vector<Ogre::Vector3>::iterator transiter3 = translist3.begin(); | ||||
| 		 | ||||
| 
 | ||||
| 		float tleft = 0; | ||||
| 		float rleft = 0.0; | ||||
| 		float ttotal = 0.0; | ||||
| 		float rtotal = 0; | ||||
| 		Ogre::TransformKeyFrame* mKey; | ||||
| 		Ogre::TransformKeyFrame* mKey2; | ||||
| 		float tused = 0.0; | ||||
| 		float rused = 0.0; | ||||
| 		Ogre::Quaternion lastquat; | ||||
| 		Ogre::Vector3 lasttrans; | ||||
| 		bool rend = false; | ||||
| 		bool tend = false; | ||||
| 		Ogre::Quaternion test;// = (skel->getBone(node->name.toString()))->getOrientation();
 | ||||
| 		for (int j = 0 ; j < ttime.size(); j++) | ||||
| 		{ | ||||
| 			if(data->getTtype() >= 1 && data->getTtype() <= 5) | ||||
| 			{ | ||||
| 				 | ||||
| 			    Ogre::TransformKeyFrame* mKey = mTrack->createNodeKeyFrame(*ttimeiter); | ||||
| 				Ogre::Vector3 standard = *transiter; | ||||
| 				if(data->getTtype() == 2) | ||||
| 					standard = *transiter *  *transiter2  *  *transiter3; | ||||
| 
 | ||||
| 				mKey->setTranslate(standard);/*
 | ||||
| 				if(mTrack3) | ||||
| 				{ | ||||
| 					 Ogre::TransformKeyFrame* mKey3 = mTrack->createNodeKeyFrame(*ttimeiter); | ||||
| 					mKey3->setTranslate(standard); | ||||
| 				}*/ | ||||
| 				//mKey->setRotation(Quaternion::ZERO);
 | ||||
| 				//mKey->setScale(Ogre::Vector3(1,1,1));
 | ||||
| 				transiter++;               //START
 | ||||
| 				transiter2++; | ||||
| 				transiter3++; | ||||
| 			    ttimeiter++; | ||||
| 			} | ||||
| 		} | ||||
| 		for (int j = 0 ; j < rtime.size(); j++) | ||||
| 		{ | ||||
| 			if(data->getRtype() >= 1 && data->getRtype() <= 5) | ||||
| 			{ | ||||
| 			    Ogre::TransformKeyFrame* mKey2 = mTrack2->createNodeKeyFrame(*rtimeiter); | ||||
| 				test = *quatIter; | ||||
| 
 | ||||
| 				mKey2->setRotation(test); | ||||
| 				//mKey2->setTranslate(Ogre::Vector3(0,0,0));
 | ||||
| 				//mKey2->setScale(Ogre::Vector3(1,1,1));
 | ||||
| 				quatIter++; | ||||
| 			    rtimeiter++; | ||||
| 			} | ||||
| 		} | ||||
| 		 } | ||||
| 	 | ||||
| 			 | ||||
| 
 | ||||
| 		 | ||||
| 		/*
 | ||||
| 		//mTrack = animcore->createNodeTrack(handle++, skel->getBone(node->name.toString()));
 | ||||
| 
 | ||||
| 		std::vector<float> stime = data->getsTime(); | ||||
| 		std::vector<float>::iterator stimeiter = stime.begin(); | ||||
| 
 | ||||
| 		std::vector<float> sfactor = data->getScalefactor(); | ||||
| 		std::vector<float>::iterator sfactoriter = sfactor.begin(); | ||||
| 		for (int i = 0 ; i < stime.size(); i++) | ||||
| 		{ | ||||
| 			if(data->getStype() >= 1 && data->getStype() <= 5) | ||||
| 			{ | ||||
| 			    Ogre::TransformKeyFrame* mKey = mTrack->createNodeKeyFrame(*stimeiter); | ||||
| 			    mKey->setScale(Ogre::Vector3(*sfactoriter, *sfactoriter, *sfactoriter)); | ||||
| 
 | ||||
| 			    sfactoriter++; | ||||
| 			    stimeiter++; | ||||
| 			} | ||||
| 		} | ||||
| 		*/ | ||||
| 
 | ||||
| 	 | ||||
| 	} | ||||
| 	/*
 | ||||
| 	else if (n != NULL) | ||||
| 	{ | ||||
| 		std::cout << "handle" << handle << "\n"; | ||||
| 		//handle++;
 | ||||
| 	}*/ | ||||
| 	} | ||||
| 	 | ||||
| 
 | ||||
| 
 | ||||
|     // set skeleton
 | ||||
|   if (!mSkel.isNull()) | ||||
|   { | ||||
|         mesh->_notifySkeleton(mSkel); | ||||
|   } | ||||
| 
 | ||||
|     // set skeleton
 | ||||
| //     if (!skel.isNull())
 | ||||
|  |  | |||
|  | @ -131,6 +131,10 @@ class NIFLoader : Ogre::ManualResourceLoader | |||
|         int counter; | ||||
|         int numbers; | ||||
|         int stack; | ||||
| 		bool anim; | ||||
| 		int handle2; | ||||
| 		Ogre::Animation* animcore; | ||||
| 		Ogre::Animation* animcore2; | ||||
|          | ||||
| 
 | ||||
|         // pointer to the ogre mesh which is currently build
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue