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:
parent
88c427543b
commit
653d999ac4
12 changed files with 102 additions and 24 deletions
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue