From 0902a3db89fbc39456cefb9cc58bbbfe049fcb37 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 11 Dec 2011 22:40:00 -0500 Subject: [PATCH] Filled out NpcAnimation and CreatureAnimation classes --- apps/openmw/mwclass/creature.cpp | 9 +- apps/openmw/mwrender/actors.cpp | 165 +-------------------- apps/openmw/mwrender/actors.hpp | 7 +- apps/openmw/mwrender/animation.hpp | 16 ++ apps/openmw/mwrender/creatureanimation.cpp | 23 +++ apps/openmw/mwrender/creatureanimation.hpp | 12 +- apps/openmw/mwrender/npcanimation.cpp | 165 +++++++++++++++++++++ apps/openmw/mwrender/npcanimation.hpp | 11 +- components/nifogre/ogre_nif_loader.cpp | 5 +- 9 files changed, 240 insertions(+), 173 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index a58a851f2..e2f9ca6d8 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -25,18 +25,17 @@ namespace MWClass void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { - ESMS::LiveCellRef *ref = + /*ESMS::LiveCellRef *ref = ptr.get(); assert (ref->base != NULL); const std::string &model = ref->base->model; if (!model.empty()) - { + {*/ MWRender::Actors& actors = renderingInterface.getActors(); - actors.insertBegin(ptr, ptr.getRefData().isEnabled(), false); - actors.insertMesh(ptr, "meshes\\" + model); - } + actors.insertCreature(ptr); + } void Creature::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const diff --git a/apps/openmw/mwrender/actors.cpp b/apps/openmw/mwrender/actors.cpp index 6a3aeba23..2f605dd73 100644 --- a/apps/openmw/mwrender/actors.cpp +++ b/apps/openmw/mwrender/actors.cpp @@ -3,6 +3,7 @@ #include #include "../mwworld/world.hpp" + using namespace Ogre; using namespace MWRender; using namespace NifOgre; @@ -10,159 +11,11 @@ using namespace NifOgre; void Actors::setMwRoot(Ogre::SceneNode* root){ mMwRoot = root; } -Ogre::Entity* Actors::insertBoundedPart(const std::string &mesh, std::string bonename, Ogre::Entity* base){ - NIFLoader::load(mesh); - Entity* ent = mRend.getScene()->createEntity(mesh); - - base->attachObjectToBone(bonename, ent); - return ent; - -} void Actors::insertNPC(const MWWorld::Ptr& ptr){ - ESMS::LiveCellRef *ref = - ptr.get(); - assert (ref->base != NULL); - insertBegin(ptr, true, true); + MWRender::NpcAnimation(ptr, mEnvironment, mRend); - //Part selection on last character of the file string - // " Tri Chest - // * Tri Tail - // : Tri Left Foot - // < Tri Right Foot - // > Tri Left Hand - // ? Tri Right Hand - // | Normal - - //Mirroring Parts on second to last character - //suffix == '*' - // vector = Ogre::Vector3(-1,1,1); - // suffix == '?' - // vector = Ogre::Vector3(1,-1,1); - // suffix == '<' - // vector = Ogre::Vector3(1,1,-1); - - - - std::string hairID = ref->base->hair; - std::string headID = ref->base->head; - std::string npcName = ref->base->name; - - std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); - char secondtolast = bodyRaceID.at(bodyRaceID.length() - 2); - bool female = tolower(secondtolast) == 'f'; - bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_"; - - - std::string smodel = "meshes\\base_anim.nif"; - if(beast) - smodel = "meshes\\base_animkna.nif"; - - Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); - assert(insert); - - NifOgre::NIFLoader::load(smodel); - Entity *base = mRend.getScene()->createEntity(smodel); - insert->attachObject(base); - - std::string headModel = "meshes\\" + - mEnvironment.mWorld->getStore().bodyParts.find(headID)->model; - - std::string hairModel = "meshes\\" + - mEnvironment.mWorld->getStore().bodyParts.find(hairID)->model; - - const ESM::BodyPart *upperleg = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper leg"); - const ESM::BodyPart *groin = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "groin"); - const ESM::BodyPart *arml = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper arm"); //We need two - const ESM::BodyPart *neck = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "neck"); - const ESM::BodyPart *knee = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "knee"); - const ESM::BodyPart *ankle = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "ankle"); - const ESM::BodyPart *foot = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "foot"); - const ESM::BodyPart *feet = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "feet"); - const ESM::BodyPart *tail = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "tail"); - const ESM::BodyPart *wristl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); //We need two - const ESM::BodyPart *forearml = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); //We need two - const ESM::BodyPart *handl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand"); //We need two - const ESM::BodyPart *hair = mEnvironment.mWorld->getStore().bodyParts.search(hairID); - const ESM::BodyPart *head = mEnvironment.mWorld->getStore().bodyParts.search(headID); - if(!handl) - handl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands"); - //const ESM::BodyPart* claviclel = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "clavicle"); - //const ESM::BodyPart* clavicler = claviclel; - const ESM::BodyPart* handr = handl; - const ESM::BodyPart* forearmr = forearml; - const ESM::BodyPart* wristr = wristl; - const ESM::BodyPart* armr = arml; - if(upperleg){ - insertBoundedPart("meshes\\" + upperleg->model + "*|", "Left Upper Leg", base); - insertBoundedPart("meshes\\" + upperleg->model, "Right Upper Leg", base); - - } - if(foot){ - if(bodyRaceID.compare("b_n_khajiit_m_") == 0) - { - feet = foot; - } - else - { - insertBoundedPart("meshes\\" + foot->model, "Right Foot", base); - insertBoundedPart("meshes\\" + foot->model + "*|", "Left Foot", base); - } - } - if(groin){ - insertBoundedPart("meshes\\" + groin->model, "Groin", base); - } - if(knee) - { - insertBoundedPart("meshes\\" + knee->model + "*|", "Left Knee", base); //e - insertBoundedPart("meshes\\" + knee->model, "Right Knee", base); //e - - } - if(ankle){ - - insertBoundedPart("meshes\\" + ankle->model + "*|", "Left Ankle", base); //Ogre::Quaternion(Ogre::Radian(3.14 / 4), Ogre::Vector3(1, 0, 0)),blank); //1,0,0, blank); - insertBoundedPart("meshes\\" + ankle->model, "Right Ankle", base); - } - if (armr){ - insertBoundedPart("meshes\\" + armr->model, "Right Upper Arm", base); - } - if(arml){ - insertBoundedPart("meshes\\" + arml->model + "*|", "Left Upper Arm", base); - } - - if (forearmr) - { - insertBoundedPart("meshes\\" + forearmr->model, "Right Forearm", base); - } - if(forearml) - insertBoundedPart("meshes\\" + forearml->model + "*|", "Left Forearm", base); - - if (wristr) - { - insertBoundedPart("meshes\\" + wristr->model, "Right Wrist", base); - } - - if(wristl) - insertBoundedPart("meshes\\" + wristl->model + "*|", "Left Wrist", base); - - - - - /*if(claviclel) - insertBoundedPart("meshes\\" + claviclel->model + "*|", "Left Clavicle", base); - if(clavicler) - insertBoundedPart("meshes\\" + clavicler->model , "Right Clavicle", base);*/ - - - if(neck) - { - insertBoundedPart("meshes\\" + neck->model, "Neck", base); - } - if(head) - insertBoundedPart("meshes\\" + head->model, "Head", base); - if(hair) - insertBoundedPart("meshes\\" + hair->model, "Head", base); } void Actors::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){ Ogre::SceneNode* cellnode; @@ -202,18 +55,10 @@ void Actors::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){ } -void Actors::insertFreePart(const MWWorld::Ptr& ptr, const std::string& mesh){ - MeshPtr meshp = NIFLoader::load(mesh); - Entity *ent = mRend.getScene()->createEntity(mesh); - NIFLoader::getSingletonPtr()->addInMesh(ent->getMesh().getPointer()); -} -void Actors::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh){ - Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); - assert(insert); +void Actors::insertCreature (const MWWorld::Ptr& ptr){ + insertBegin(ptr, true, true); - NifOgre::NIFLoader::load(mesh); - Entity *ent = mRend.getScene()->createEntity(mesh); - insert->attachObject(ent); + MWRender::CreatureAnimation(ptr, mEnvironment, mRend); } bool Actors::deleteObject (const MWWorld::Ptr& ptr) diff --git a/apps/openmw/mwrender/actors.hpp b/apps/openmw/mwrender/actors.hpp index d533e77f9..1fe0c2e34 100644 --- a/apps/openmw/mwrender/actors.hpp +++ b/apps/openmw/mwrender/actors.hpp @@ -13,7 +13,8 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/actiontalk.hpp" #include "../mwworld/environment.hpp" - +#include "npcanimation.hpp" +#include "creatureanimation.hpp" namespace MWRender{ class Actors{ @@ -27,11 +28,9 @@ namespace MWRender{ public: Actors(OEngine::Render::OgreRenderer& _rend, MWWorld::Environment& _env): mRend(_rend), mEnvironment(_env){} ~Actors(){} - Ogre::Entity* Actors::insertBoundedPart(const std::string &mesh, std::string bonename, Ogre::Entity* base); void setMwRoot(Ogre::SceneNode* root); void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_); - void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh); - void insertFreePart(const MWWorld::Ptr& ptr, const std::string& mesh); + void insertCreature (const MWWorld::Ptr& ptr); void insertNPC(const MWWorld::Ptr& ptr); bool deleteObject (const MWWorld::Ptr& ptr); ///< \return found? diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index cb922d7f3..81938155f 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -1,10 +1,26 @@ #ifndef _GAME_RENDER_ANIMATION_H #define _GAME_RENDER_ANIMATION_H #include +#include +#include "../mwworld/refdata.hpp" +#include "../mwworld/ptr.hpp" +#include "../mwworld/actiontalk.hpp" +#include "../mwworld/environment.hpp" + namespace MWRender{ + class Animation{ + protected: + OEngine::Render::OgreRenderer &mRend; + MWWorld::Environment& mEnvironment; + + std::vector transformations; std::map textmappings; + Ogre::Entity* base; + public: + Animation(MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend): mRend(_rend), mEnvironment(_env){}; + }; } #endif \ No newline at end of file diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index e69de29bb..403f5da61 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -0,0 +1,23 @@ +#include "creatureanimation.hpp" + +#include "../mwworld/world.hpp" + +using namespace Ogre; +using namespace NifOgre; +namespace MWRender{ +CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend): Animation(_env,_rend){ + Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); + assert(insert); + ESMS::LiveCellRef *ref = + ptr.get(); + + assert (ref->base != NULL); + if(!ref->base->model.empty()){ + const std::string &mesh = "meshes\\" + ref->base->model; + + NifOgre::NIFLoader::load(mesh); + base = mRend.getScene()->createEntity(mesh); + insert->attachObject(base); + } +} +} \ No newline at end of file diff --git a/apps/openmw/mwrender/creatureanimation.hpp b/apps/openmw/mwrender/creatureanimation.hpp index 2bad5f769..26e4f33e0 100644 --- a/apps/openmw/mwrender/creatureanimation.hpp +++ b/apps/openmw/mwrender/creatureanimation.hpp @@ -3,10 +3,20 @@ #include "animation.hpp" #include + + +#include "../mwworld/refdata.hpp" +#include "../mwworld/ptr.hpp" +#include "../mwworld/environment.hpp" +#include "components/nifogre/ogre_nif_loader.hpp" + + namespace MWRender{ -class CreatureAnimation: Animation{ +class CreatureAnimation: public Animation{ std::vector shapes; //All the NiTriShapeData for this creature + public: + CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend); }; } #endif \ No newline at end of file diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index e69de29bb..b2a3d5825 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -0,0 +1,165 @@ +#include "npcanimation.hpp" +#include "../mwworld/world.hpp" + +using namespace Ogre; +using namespace NifOgre; +namespace MWRender{ + +NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend): Animation(_env,_rend){ + ESMS::LiveCellRef *ref = + ptr.get(); + //assert (ref->base != NULL); + + //insertBegin(ptr, true, true); + + //Part selection on last character of the file string + // " Tri Chest + // * Tri Tail + // : Tri Left Foot + // < Tri Right Foot + // > Tri Left Hand + // ? Tri Right Hand + // | Normal + + //Mirroring Parts on second to last character + //suffix == '*' + // vector = Ogre::Vector3(-1,1,1); + // suffix == '?' + // vector = Ogre::Vector3(1,-1,1); + // suffix == '<' + // vector = Ogre::Vector3(1,1,-1); + + + + std::string hairID = ref->base->hair; + std::string headID = ref->base->head; + std::string npcName = ref->base->name; + + std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); + char secondtolast = bodyRaceID.at(bodyRaceID.length() - 2); + bool female = tolower(secondtolast) == 'f'; + bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_"; + + + std::string smodel = "meshes\\base_anim.nif"; + if(beast) + smodel = "meshes\\base_animkna.nif"; + + Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); + assert(insert); + + NifOgre::NIFLoader::load(smodel); + + base = mRend.getScene()->createEntity(smodel); + insert->attachObject(base); + std::cout << "Nifloader\n"; + + std::string headModel = "meshes\\" + + mEnvironment.mWorld->getStore().bodyParts.find(headID)->model; + + std::string hairModel = "meshes\\" + + mEnvironment.mWorld->getStore().bodyParts.find(hairID)->model; + + const ESM::BodyPart *upperleg = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper leg"); + const ESM::BodyPart *groin = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "groin"); + const ESM::BodyPart *arml = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper arm"); //We need two + const ESM::BodyPart *neck = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "neck"); + const ESM::BodyPart *knee = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "knee"); + const ESM::BodyPart *ankle = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "ankle"); + const ESM::BodyPart *foot = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "foot"); + const ESM::BodyPart *feet = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "feet"); + const ESM::BodyPart *tail = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "tail"); + const ESM::BodyPart *wristl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); //We need two + const ESM::BodyPart *forearml = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); //We need two + const ESM::BodyPart *handl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand"); //We need two + const ESM::BodyPart *hair = mEnvironment.mWorld->getStore().bodyParts.search(hairID); + const ESM::BodyPart *head = mEnvironment.mWorld->getStore().bodyParts.search(headID); + if(!handl) + handl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands"); + //const ESM::BodyPart* claviclel = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "clavicle"); + //const ESM::BodyPart* clavicler = claviclel; + const ESM::BodyPart* handr = handl; + const ESM::BodyPart* forearmr = forearml; + const ESM::BodyPart* wristr = wristl; + const ESM::BodyPart* armr = arml; + std::cout << "upperleg"; + if(upperleg){ + insertBoundedPart("meshes\\" + upperleg->model + "*|", "Left Upper Leg"); + insertBoundedPart("meshes\\" + upperleg->model, "Right Upper Leg"); + + } + if(foot){ + if(bodyRaceID.compare("b_n_khajiit_m_") == 0) + { + feet = foot; + } + else + { + insertBoundedPart("meshes\\" + foot->model, "Right Foot"); + insertBoundedPart("meshes\\" + foot->model + "*|", "Left Foot"); + } + } + if(groin){ + insertBoundedPart("meshes\\" + groin->model, "Groin"); + } + if(knee) + { + insertBoundedPart("meshes\\" + knee->model + "*|", "Left Knee"); //e + insertBoundedPart("meshes\\" + knee->model, "Right Knee"); //e + + } + if(ankle){ + + insertBoundedPart("meshes\\" + ankle->model + "*|", "Left Ankle"); //Ogre::Quaternion(Ogre::Radian(3.14 / 4), Ogre::Vector3(1, 0, 0)),blank); //1,0,0, blank); + insertBoundedPart("meshes\\" + ankle->model, "Right Ankle"); + } + if (armr){ + insertBoundedPart("meshes\\" + armr->model, "Right Upper Arm"); + } + if(arml){ + insertBoundedPart("meshes\\" + arml->model + "*|", "Left Upper Arm"); + } + + if (forearmr) + { + insertBoundedPart("meshes\\" + forearmr->model, "Right Forearm"); + } + if(forearml) + insertBoundedPart("meshes\\" + forearml->model + "*|", "Left Forearm"); + + if (wristr) + { + insertBoundedPart("meshes\\" + wristr->model, "Right Wrist"); + } + + if(wristl) + insertBoundedPart("meshes\\" + wristl->model + "*|", "Left Wrist"); + + + + + + /*if(claviclel) + insertBoundedPart("meshes\\" + claviclel->model + "*|", "Left Clavicle", base); + if(clavicler) + insertBoundedPart("meshes\\" + clavicler->model , "Right Clavicle", base);*/ + + + if(neck) + { + insertBoundedPart("meshes\\" + neck->model, "Neck"); + } + if(head) + insertBoundedPart("meshes\\" + head->model, "Head"); + if(hair) + insertBoundedPart("meshes\\" + hair->model, "Head"); +} + +Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, std::string bonename){ + NIFLoader::load(mesh); + Entity* ent = mRend.getScene()->createEntity(mesh); + + base->attachObjectToBone(bonename, ent); + return ent; +} +} \ No newline at end of file diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 9358e2c0a..b9c55ff93 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -3,10 +3,19 @@ #include "animation.hpp" #include #include + +#include "../mwworld/refdata.hpp" +#include "../mwworld/ptr.hpp" +#include "../mwworld/environment.hpp" +#include "components/nifogre/ogre_nif_loader.hpp" + namespace MWRender{ -class NpcAnimation: Animation{ +class NpcAnimation: public Animation{ std::vector> 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); + Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename); }; } #endif \ No newline at end of file diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index eb658dd25..8f19be44c 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -474,6 +474,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std HardwareBuffer::HBU_STATIC_WRITE_ONLY, true); if(flip && mFlipVertexWinding && sub->indexData->indexCount % 3 == 0){ + sub->indexData->indexBuffer = ibuf; uint16 *datamod = new uint16[numFaces]; @@ -1109,10 +1110,10 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, { handleNiTriShape(dynamic_cast(node), flags, bounds, original, boneSequence); } - else if(name.length() >= triname.length()) + else if(nodename.length() >= triname.length()) { std::transform(nodename.begin(), nodename.end(), nodename.begin(), std::tolower); - if(triname == name.substr(0, triname.length())) + if(triname == nodename.substr(0, triname.length())) handleNiTriShape(dynamic_cast(node), flags, bounds, original, boneSequence); } }