1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-04-01 20:36:42 +00:00

Animation creatures

This commit is contained in:
Jason Hooks 2011-12-26 19:23:46 -05:00
parent 88c427543b
commit 653d999ac4
12 changed files with 102 additions and 24 deletions

View file

@ -135,6 +135,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
mEnvironment.mWorld->advanceTime ( mEnvironment.mWorld->advanceTime (
mEnvironment.mFrameDuration*mEnvironment.mWorld->getTimeScaleFactor()/3600); mEnvironment.mFrameDuration*mEnvironment.mWorld->getTimeScaleFactor()/3600);
if (changed) // keep change flag for another frame, if cell changed happend in local script if (changed) // keep change flag for another frame, if cell changed happend in local script
mEnvironment.mWorld->markCellAsUnchanged(); mEnvironment.mWorld->markCellAsUnchanged();

View file

@ -111,4 +111,18 @@ void Actors::removeCell(MWWorld::Ptr::CellStore* store){
} }
} }
} }
void Actors::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number){
mAllActors.find(ptr)->second->startScript(groupName, mode, number);
}
void Actors::skipAnimation (const MWWorld::Ptr& ptr){
}
void Actors::addTime(){
//std::cout << "Adding time in actors\n";
for(std::map<MWWorld::Ptr, Animation*>::iterator iter = mAllActors.begin(); iter != mAllActors.end(); iter++)
{
(iter->second)->runAnimation(mEnvironment.mFrameDuration);
}
}

View file

@ -38,6 +38,20 @@ namespace MWRender{
///< \return found? ///< \return found?
void removeCell(MWWorld::Ptr::CellStore* store); void removeCell(MWWorld::Ptr::CellStore* store);
void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode,
int number = 1);
///< Run animation for a MW-reference. Calls to this function for references that are currently not
/// in the rendered scene should be ignored.
///
/// \param mode: 0 normal, 1 immediate start, 2 immediate loop
/// \param number How offen the animation should be run
void skipAnimation (const MWWorld::Ptr& ptr);
///< Skip the animation for the given MW-reference for one frame. Calls to this function for
/// references that are currently not in the rendered scene should be ignored.
void addTime();
}; };
} }

View file

@ -3,8 +3,10 @@
namespace MWRender{ namespace MWRender{
std::map<std::string, int> Animation::mUniqueIDs; std::map<std::string, int> Animation::mUniqueIDs;
Animation::~Animation(){ Animation::~Animation(){
} }
std::string Animation::getUniqueID(std::string mesh){ std::string Animation::getUniqueID(std::string mesh){
int counter; int counter;
if(mUniqueIDs.find(mesh) == mUniqueIDs.end()){ if(mUniqueIDs.find(mesh) == mUniqueIDs.end()){
@ -27,6 +29,11 @@ namespace MWRender{
//If groupname is recognized set animate to true //If groupname is recognized set animate to true
//Set the start time and stop time //Set the start time and stop time
//How many times to loop //How many times to loop
if(groupname == "all"){
animate = true;
time = startTime;
}
} }
void Animation::handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel){ void Animation::handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel){
@ -35,7 +42,7 @@ namespace MWRender{
for(allshapesiter = allshapes->begin(); allshapesiter != allshapes->end(); allshapesiter++) for(allshapesiter = allshapes->begin(); allshapesiter != allshapes->end(); allshapesiter++)
{ {
Nif::NiTriShapeCopy copy = *allshapesiter; Nif::NiTriShapeCopy& copy = *allshapesiter;
std::vector<Ogre::Vector3> allvertices = copy.vertices; std::vector<Ogre::Vector3> allvertices = copy.vertices;
std::vector<Ogre::Vector3> allnormals = copy.normals; std::vector<Ogre::Vector3> allnormals = copy.normals;
@ -133,6 +140,7 @@ namespace MWRender{
*addr = absVertPos.x; *addr = absVertPos.x;
*(addr+1) = absVertPos.y; *(addr+1) = absVertPos.y;
*(addr+2) = absVertPos.z; *(addr+2) = absVertPos.z;
//std::cout << "Vertex" << vertices[verIndex] << "\n"; //std::cout << "Vertex" << vertices[verIndex] << "\n";
} }
@ -147,6 +155,7 @@ namespace MWRender{
*addr = absVertPos.x; *addr = absVertPos.x;
*(addr+1) = absVertPos.y; *(addr+1) = absVertPos.y;
*(addr+2) = absVertPos.z; *(addr+2) = absVertPos.z;
std::cout << "We are actually 2\n";
//std::cout << "Vertex" << verIndex << "Weight: " << boneinfo.weights[i].weight << "was seen twice\n"; //std::cout << "Vertex" << verIndex << "Weight: " << boneinfo.weights[i].weight << "was seen twice\n";
} }
@ -194,8 +203,8 @@ namespace MWRender{
Ogre::Vector3 transmult; Ogre::Vector3 transmult;
Ogre::Quaternion rotmult; Ogre::Quaternion rotmult;
float scale; float scale;
if(creaturemodel->getSkeleton()->hasBone(*boneSequenceIter)){ if(skel->hasBone(*boneSequenceIter)){
Ogre::Bone *bonePtr = creaturemodel->getSkeleton()->getBone(*boneSequenceIter); Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
@ -327,11 +336,7 @@ namespace MWRender{
} }
void Animation::handleAnimationTransforms(){ void Animation::handleAnimationTransforms(){
Ogre::Bone* b = skel->getRootBone();
b->setOrientation(.3,.3,.3,.3); //This is a trick
skel->getManualBonesDirty();
skel->_updateTransforms();
skel->_notifyManualBonesDirty();
std::vector<Nif::NiKeyframeData>::iterator iter; std::vector<Nif::NiKeyframeData>::iterator iter;
int slot = 0; int slot = 0;

View file

@ -49,6 +49,19 @@ void CreatureAnimation::runAnimation(float timepassed){
//Handle the animation transforms dependent on time //Handle the animation transforms dependent on time
//Handle the shapes dependent on animation transforms //Handle the shapes dependent on animation transforms
time += timepassed;
Ogre::Bone* b = skel->getRootBone();
b->setOrientation(.3,.3,.3,.3); //This is a trick
skel->getManualBonesDirty();
skel->_updateTransforms();
skel->_notifyManualBonesDirty();
base->getAllAnimationStates()->_notifyDirty();
base->_updateAnimation();
base->_notifyMoved();
handleAnimationTransforms();
handleShapes(shapes, base, skel);
} }
} }

View file

@ -173,7 +173,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
if(hair) if(hair)
insertBoundedPart("meshes\\" + hair->model, "Head"); insertBoundedPart("meshes\\" + hair->model, "Head");
if (chest){ /*if (chest){
insertFreePart("meshes\\" + chest->model, ">\"", insert); insertFreePart("meshes\\" + chest->model, ">\"", insert);
@ -181,7 +181,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
if (handr){ if (handr){
insertFreePart("meshes\\" + handr->model , ">?", insert); insertFreePart("meshes\\" + handr->model , ">?", insert);
} }*/
if (handl){ if (handl){
insertFreePart("meshes\\" + handl->model, ">>", insert); insertFreePart("meshes\\" + handl->model, ">>", insert);
@ -207,25 +207,50 @@ void NpcAnimation::insertFreePart(const std::string &mesh, const std::string suf
std::string meshNumbered = mesh + getUniqueID(mesh + suffix) + suffix; std::string meshNumbered = mesh + getUniqueID(mesh + suffix) + suffix;
NIFLoader::load(meshNumbered); NIFLoader::load(meshNumbered);
Entity* ent = mRend.getScene()->createEntity(meshNumbered); hand = mRend.getScene()->createEntity(meshNumbered);
insert->attachObject(ent); insert->attachObject(hand);
entityparts.push_back(ent); //entityparts.push_back(ent);
std::vector<Nif::NiTriShapeCopy>* shapes = ((NIFLoader::getSingletonPtr())->getShapes(mesh + "0000" + suffix)); std::vector<Nif::NiTriShapeCopy>* shapes = ((NIFLoader::getSingletonPtr())->getShapes(mesh + "0000" + suffix));
if(shapes){ if(shapes){
shapeparts.push_back(shapes); shapeparts.push_back(shapes);
handleShapes(shapes, ent, skel); handleShapes(shapes, hand, skel);
} }
} }
void NpcAnimation::runAnimation(float timepassed){ void NpcAnimation::runAnimation(float timepassed){
//Add the amount of time passed to time
//Handle the animation transforms dependent on time
//Handle the shapes dependent on animation transforms
if(animate){ if(animate){
//Add the amount of time passed to time time += timepassed;
Ogre::Bone* b = skel->getRootBone();
b->setOrientation(.3,.3,.3,.3); //This is a trick
skel->getManualBonesDirty();
skel->_updateTransforms();
skel->_notifyManualBonesDirty();
//Handle the animation transforms dependent on time base->getAllAnimationStates()->_notifyDirty();
base->_updateAnimation();
base->_notifyMoved();
//Handle the shapes dependent on animation transforms
} handleAnimationTransforms();
std::vector<std::vector<Nif::NiTriShapeCopy>*>::iterator shapepartsiter = shapeparts.begin();
std::vector<Ogre::Entity*>::iterator entitypartsiter = entityparts.begin();
int i = 0;
while(shapepartsiter != shapeparts.end() && entitypartsiter != entityparts.end())
{
std::vector<Nif::NiTriShapeCopy>* shapes = *shapepartsiter;
handleShapes(shapes, *entitypartsiter, skel);
//std::cout << "Shape part size" << shapes->size() << "\n";
shapepartsiter++;
entitypartsiter++;
}
}
} }
} }

View file

@ -16,7 +16,7 @@ namespace MWRender{
class NpcAnimation: public Animation{ class NpcAnimation: public Animation{
std::vector<Ogre::Entity*> entityparts; std::vector<Ogre::Entity*> entityparts;
Ogre::Entity* hand;
std::vector<std::vector<Nif::NiTriShapeCopy>*> shapeparts; //All the NiTriShape data that we need for animating this particular npc std::vector<std::vector<Nif::NiTriShapeCopy>*> shapeparts; //All the NiTriShape data that we need for animating this particular npc
public: public:
NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend); NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend);

View file

@ -234,13 +234,15 @@ void RenderingManager::playAnimationGroup (const MWWorld::Ptr& ptr, const std::s
int mode, int number) int mode, int number)
{ {
std::cout<<"play animation " << groupName << ", " << mode << ", " << number << std::endl; std::cout<<"play animation " << groupName << ", " << mode << ", " << number << std::endl;
mActors.playAnimationGroup(ptr, groupName, mode, number);
} }
void RenderingManager::skipAnimation (const MWWorld::Ptr& ptr) void RenderingManager::skipAnimation (const MWWorld::Ptr& ptr)
{ {
std::cout<<"skip animation"<<std::endl; std::cout<<"skip animation"<<std::endl;
} }
void RenderingManager::addTime(float timepassed){ void RenderingManager::addTime(){
mActors.addTime();
//Notify each animation that time has passed //Notify each animation that time has passed
} }

View file

@ -105,7 +105,7 @@ class RenderingManager: private RenderingInterface {
///< Skip the animation for the given MW-reference for one frame. Calls to this function for ///< Skip the animation for the given MW-reference for one frame. Calls to this function for
/// references that are currently not in the rendered scene should be ignored. /// references that are currently not in the rendered scene should be ignored.
void addTime(float timepassed); void addTime();
private: private:

View file

@ -52,7 +52,9 @@ void insertCellRefList(MWRender::RenderingManager& rendering, MWWorld::Environme
namespace MWWorld namespace MWWorld
{ {
void Scene::advanceTime(){
mRendering.addTime();
}
void Scene::unloadCell (CellStoreCollection::iterator iter) void Scene::unloadCell (CellStoreCollection::iterator iter)
{ {
std::cout << "Unloading cell\n"; std::cout << "Unloading cell\n";

View file

@ -101,6 +101,7 @@ namespace MWWorld
void markCellAsUnchanged(); void markCellAsUnchanged();
void insertCell(ESMS::CellStore<MWWorld::RefData> &cell, MWWorld::Environment& environment); void insertCell(ESMS::CellStore<MWWorld::RefData> &cell, MWWorld::Environment& environment);
void advanceTime();
}; };
} }

View file

@ -348,13 +348,14 @@ namespace MWWorld
void World::advanceTime (double hours) void World::advanceTime (double hours)
{ {
hours += mGlobalVariables->getFloat ("gamehour"); hours += mGlobalVariables->getFloat ("gamehour");
setHour (hours); setHour (hours);
int days = hours / 24; int days = hours / 24;
if (days>0) if (days>0)
mGlobalVariables->setInt ("dayspassed", days + mGlobalVariables->getInt ("dayspassed")); mGlobalVariables->setInt ("dayspassed", days + mGlobalVariables->getInt ("dayspassed"));
mWorldScene->advanceTime();
} }
void World::setHour (double hour) void World::setHour (double hour)