1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-14 01:19:59 +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.mFrameDuration*mEnvironment.mWorld->getTimeScaleFactor()/3600);
if (changed) // keep change flag for another frame, if cell changed happend in local script
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?
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{
std::map<std::string, int> Animation::mUniqueIDs;
Animation::~Animation(){
}
std::string Animation::getUniqueID(std::string mesh){
int counter;
if(mUniqueIDs.find(mesh) == mUniqueIDs.end()){
@ -27,6 +29,11 @@ namespace MWRender{
//If groupname is recognized set animate to true
//Set the start time and stop time
//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){
@ -35,7 +42,7 @@ namespace MWRender{
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> allnormals = copy.normals;
@ -133,6 +140,7 @@ namespace MWRender{
*addr = absVertPos.x;
*(addr+1) = absVertPos.y;
*(addr+2) = absVertPos.z;
//std::cout << "Vertex" << vertices[verIndex] << "\n";
}
@ -147,6 +155,7 @@ namespace MWRender{
*addr = absVertPos.x;
*(addr+1) = absVertPos.y;
*(addr+2) = absVertPos.z;
std::cout << "We are actually 2\n";
//std::cout << "Vertex" << verIndex << "Weight: " << boneinfo.weights[i].weight << "was seen twice\n";
}
@ -194,8 +203,8 @@ namespace MWRender{
Ogre::Vector3 transmult;
Ogre::Quaternion rotmult;
float scale;
if(creaturemodel->getSkeleton()->hasBone(*boneSequenceIter)){
Ogre::Bone *bonePtr = creaturemodel->getSkeleton()->getBone(*boneSequenceIter);
if(skel->hasBone(*boneSequenceIter)){
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
@ -327,11 +336,7 @@ namespace MWRender{
}
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;
int slot = 0;

View File

@ -49,6 +49,19 @@ void CreatureAnimation::runAnimation(float timepassed){
//Handle the animation transforms dependent on time
//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)
insertBoundedPart("meshes\\" + hair->model, "Head");
if (chest){
/*if (chest){
insertFreePart("meshes\\" + chest->model, ">\"", insert);
@ -181,7 +181,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
if (handr){
insertFreePart("meshes\\" + handr->model , ">?", insert);
}
}*/
if (handl){
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;
NIFLoader::load(meshNumbered);
Entity* ent = mRend.getScene()->createEntity(meshNumbered);
insert->attachObject(ent);
entityparts.push_back(ent);
hand = mRend.getScene()->createEntity(meshNumbered);
insert->attachObject(hand);
//entityparts.push_back(ent);
std::vector<Nif::NiTriShapeCopy>* shapes = ((NIFLoader::getSingletonPtr())->getShapes(mesh + "0000" + suffix));
if(shapes){
shapeparts.push_back(shapes);
handleShapes(shapes, ent, skel);
handleShapes(shapes, hand, skel);
}
}
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){
//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{
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
public:
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)
{
std::cout<<"play animation " << groupName << ", " << mode << ", " << number << std::endl;
mActors.playAnimationGroup(ptr, groupName, mode, number);
}
void RenderingManager::skipAnimation (const MWWorld::Ptr& ptr)
{
std::cout<<"skip animation"<<std::endl;
}
void RenderingManager::addTime(float timepassed){
void RenderingManager::addTime(){
mActors.addTime();
//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
/// references that are currently not in the rendered scene should be ignored.
void addTime(float timepassed);
void addTime();
private:

View File

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

View File

@ -101,6 +101,7 @@ namespace MWWorld
void markCellAsUnchanged();
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)
{
hours += mGlobalVariables->getFloat ("gamehour");
setHour (hours);
int days = hours / 24;
if (days>0)
mGlobalVariables->setInt ("dayspassed", days + mGlobalVariables->getInt ("dayspassed"));
mWorldScene->advanceTime();
}
void World::setHour (double hour)