From 6d346933db21946c68ab96b1105b1ea6f61f9b8e Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 10 Mar 2012 17:45:34 -0500 Subject: [PATCH 01/20] gus's changes --- apps/openmw/mwworld/weather.cpp | 8 ++++++++ apps/openmw/mwworld/weather.hpp | 16 ++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 059b0ec1e2..90afc4e78b 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -21,6 +21,14 @@ const std::string WeatherGlobals::mThunderSoundID0 = "Thunder0"; const std::string WeatherGlobals::mThunderSoundID1 = "Thunder1"; const std::string WeatherGlobals::mThunderSoundID2 = "Thunder2"; const std::string WeatherGlobals::mThunderSoundID3 = "Thunder3"; +const float WeatherGlobals::mSunriseTime = 8; +const float WeatherGlobals::mSunsetTime = 18; +const float WeatherGlobals::mSunriseDuration = 2; +const float WeatherGlobals::mSunsetDuration = 2; +const float WeatherGlobals::mWeatherUpdateTime = 20.f; +const float WeatherGlobals::mThunderFrequency = .4; +const float WeatherGlobals::mThunderThreshold = 0.6; +const float WeatherGlobals::mThunderSoundDelay = 0.25; WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environment* env) : mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0), diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index 7a719252b0..9353f7cd1d 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -95,18 +95,18 @@ namespace MWWorld Script Color=255,20,20 */ - static const float mSunriseTime = 8; - static const float mSunsetTime = 18; - static const float mSunriseDuration = 2; - static const float mSunsetDuration = 2; + static const float mSunriseTime; + static const float mSunsetTime; + static const float mSunriseDuration; + static const float mSunsetDuration; - static const float mWeatherUpdateTime = 20.f; + static const float mWeatherUpdateTime; // morrowind sets these per-weather, but since they are only used by 'thunderstorm' // weather setting anyway, we can just as well set them globally - static const float mThunderFrequency = .4; - static const float mThunderThreshold = 0.6; - static const float mThunderSoundDelay = 0.25; + static const float mThunderFrequency; + static const float mThunderThreshold; + static const float mThunderSoundDelay; static const std::string mThunderSoundID0; static const std::string mThunderSoundID1; static const std::string mThunderSoundID2; From 2b3e75718c1bbe8f4408dfa85fb9c07faac15eac Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 19 Mar 2012 20:03:48 -0400 Subject: [PATCH 02/20] Updating everything --- apps/openmw/mwworld/physicssystem.cpp | 56 ++++++++++++++++++++++----- apps/openmw/mwworld/physicssystem.hpp | 2 + libs/openengine/bullet/trace.cpp | 4 +- 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index bb2f9f8a92..11a43c7d30 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -13,6 +13,7 @@ #include "OgreTextureManager.h" + using namespace Ogre; namespace MWWorld { @@ -20,9 +21,11 @@ namespace MWWorld PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) : mRender(_rend), mEngine(0), mFreeFly (true) { + playerphysics = new playerMove; // Create physics. shapeLoader is deleted by the physic engine NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader(); mEngine = new OEngine::Physic::PhysicEngine(shapeLoader); + playerphysics->mEngine = mEngine; } PhysicsSystem::~PhysicsSystem() @@ -68,55 +71,90 @@ namespace MWWorld { //set the DebugRenderingMode. To disable it,set it to 0 //eng->setDebugRenderingMode(1); - + + //set the walkdirection to 0 (no movement) for every actor) for(std::map::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) { OEngine::Physic::PhysicActor* act = it->second; act->setWalkDirection(btVector3(0,0,0)); } - + playerMove::playercmd& pm_ref = playerphysics->cmd; + + pm_ref.rightmove = 0; + pm_ref.forwardmove = 0; + pm_ref.upmove = 0; + //playerphysics->ps.move_type = PM_NOCLIP; for (std::vector >::const_iterator iter (actors.begin()); iter!=actors.end(); ++iter) { OEngine::Physic::PhysicActor* act = mEngine->getCharacter(iter->first); - + //if(iter->first == "player") + // std::cout << "This is player\n"; //dirty stuff to get the camera orientation. Must be changed! Ogre::SceneNode *sceneNode = mRender.getScene()->getSceneNode (iter->first); Ogre::Vector3 dir; Ogre::Node* yawNode = sceneNode->getChildIterator().getNext(); Ogre::Node* pitchNode = yawNode->getChildIterator().getNext(); + Ogre::Quaternion yawQuat = yawNode->getOrientation(); + Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); + Ogre::Quaternion both = yawQuat * pitchQuat; + + playerphysics->ps.viewangles.x = 0; + playerphysics->ps.viewangles.z = 0; + playerphysics->ps.viewangles.y = both.getYaw().valueDegrees() *-1 + 90; + //playerphysics->ps.viewangles.z = both.getPitch().valueDegrees(); + + if(mFreeFly) { - Ogre::Quaternion yawQuat = yawNode->getOrientation(); - Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); + Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); + pm_ref.rightmove = -dir1.x; + pm_ref.forwardmove = dir1.z; + + + + //std::cout << "Current angle" << yawQuat.getYaw().valueDegrees() - 90<< "\n"; + //playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees(); + //std::cout << "Pitch: " << yawQuat.getPitch() << "Yaw:" << yawQuat.getYaw() << "Roll: " << yawQuat.getRoll() << "\n"; dir = 0.07*(yawQuat*pitchQuat*dir1); } else { Ogre::Quaternion quat = yawNode->getOrientation(); Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); + pm_ref.rightmove = -dir1.x; + pm_ref.forwardmove = dir1.z; + dir = 0.025*(quat*dir1); } + Pmove(playerphysics); //set the walk direction act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y)); } - mEngine->stepSimulation(duration); - + //mEngine->stepSimulation(duration); + Pmove(playerphysics); std::vector< std::pair > response; for(std::map::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) { btVector3 newPos = it->second->getPosition(); + Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z()); - + if(it->first == "player"){ + + coord = playerphysics->ps.origin; + //std::cout << "Coord" << coord << "\n"; + coord = Ogre::Vector3(coord.x, coord.z, coord.y); //x, z, -y + + } response.push_back(std::pair(it->first, coord)); } + return response; } - void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh, const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position) { diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index 78cbde0837..4fc8bee36a 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -5,6 +5,7 @@ #include #include #include "ptr.hpp" +#include namespace MWWorld { @@ -49,6 +50,7 @@ namespace MWWorld OEngine::Render::OgreRenderer &mRender; OEngine::Physic::PhysicEngine* mEngine; bool mFreeFly; + playerMove* playerphysics; PhysicsSystem (const PhysicsSystem&); PhysicsSystem& operator= (const PhysicsSystem&); diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 6baec8c83a..49e12064ee 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -32,7 +32,7 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr Ogre::Vector3 endReplace = startReplace; endReplace.y -= .25; - const bool hasHit = NewPhysicsTrace(&out, startReplace, endReplace, BBHalfExtents, Ogre::Vector3(0.0f, rotation, 0.0f), isInterior, enginePass); + const bool hasHit = NewPhysicsTrace(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, rotation, 0.0f), isInterior, enginePass); if(hasHit) std::cout << "Has hit\n"; if (out.fraction < 0.001f) @@ -102,7 +102,7 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& const btVector3 btend(end.x, end.y, end.z); const btQuaternion btrot(rotation.y, rotation.x, rotation.z); - const btBoxShape newshape(btVector3(1000, 1000, 1000) ); + const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z)); const btTransform from(btrot, btstart); const btTransform to(btrot, btend); float x = from.getOrigin().getX(); From 57299571d5a1d76ce8666e1d7df6f7721d0c0d15 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 2 Apr 2012 22:08:46 -0400 Subject: [PATCH 03/20] Preparing for clothes/armor --- apps/openmw/mwclass/npc.cpp | 2 + apps/openmw/mwrender/npcanimation.cpp | 19 +- apps/openmw/mwrender/occlusionquery.cpp | 46 +- apps/openmw/mwrender/occlusionquery.hpp | 8 + apps/openmw/mwworld/physicssystem.cpp | 34 +- apps/openmw/mwworld/physicssystem.hpp | 3 +- apps/openmw/mwworld/weather.cpp | 34 +- apps/openmw/mwworld/world.cpp | 60 +- apps/openmw/mwworld/world.hpp | 18 +- components/bsa/bsa_archive.cpp | 6 +- components/nifogre/ogre_nif_loader.cpp | 14 +- libs/openengine/bullet/pmove.cpp | 2042 ----------------------- libs/openengine/bullet/pmove.h | 197 --- libs/openengine/bullet/trace.cpp | 188 --- 14 files changed, 169 insertions(+), 2502 deletions(-) delete mode 100644 libs/openengine/bullet/pmove.cpp delete mode 100644 libs/openengine/bullet/pmove.h delete mode 100644 libs/openengine/bullet/trace.cpp diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 83a94d27d1..94bcbb31f9 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -93,7 +93,9 @@ namespace MWClass void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { + std::cout << "Inserting NPC\n"; renderingInterface.getActors().insertNPC(ptr); + } void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index c6fe023d69..a4fd15b745 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -14,6 +14,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O ESMS::LiveCellRef *ref = ptr.get(); + //Part selection on last character of the file string // " Tri Chest // * Tri Tail @@ -65,6 +66,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O NifOgre::NIFLoader::load(smodel); base = mRend.getScene()->createEntity(smodel); + base->setSkipAnimationStateUpdate(true); //Magical line of code, this makes the bones //stay in the same place when we skipanim, or open a gui window @@ -82,6 +84,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O } textmappings = NIFLoader::getSingletonPtr()->getTextIndices(smodel); insert->attachObject(base); + if(female) insert->scale(race->data.height.female, race->data.height.female, race->data.height.female); @@ -124,6 +127,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O insertBoundedPart("meshes\\" + upperleg->model, "Right Upper Leg"); } + if(foot){ if(bodyRaceID.compare("b_n_khajiit_m_") == 0) { @@ -190,28 +194,29 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O insertBoundedPart("meshes\\" + hair->model, "Head"); if (chest){ - insertFreePart("meshes\\" + chest->model, ">\"", insert); + insertFreePart("meshes\\" + chest->model, ":\"", insert); } if (handr){ - insertFreePart("meshes\\" + handr->model , ">?", insert); + insertFreePart("meshes\\" + handr->model , ":?", insert); } if (handl){ - insertFreePart("meshes\\" + handl->model, ">>", insert); + insertFreePart("meshes\\" + handl->model, ":>", insert); } if(tail){ - insertFreePart("meshes\\" + tail->model, ">*", insert); + insertFreePart("meshes\\" + tail->model, ":*", insert); } if(feet){ std::string num = getUniqueID(feet->model); - insertFreePart("meshes\\" + feet->model,"><", insert); - insertFreePart("meshes\\" + feet->model,">:", insert); + insertFreePart("meshes\\" + feet->model,":<", insert); + insertFreePart("meshes\\" + feet->model,"::", insert); } //originalpos = insert->_getWorldAABB().getCenter(); //originalscenenode = insert->getPosition(); + } Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, std::string bonename){ @@ -262,7 +267,7 @@ void NpcAnimation::runAnimation(float timepassed){ time = startTime + (time - stopTime); } - handleAnimationTransforms(); + handleAnimationTransforms(); std::vector*>::iterator shapepartsiter = shapeparts.begin(); std::vector::iterator entitypartsiter = entityparts.begin(); diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index 29cfe33fe3..781b522b63 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -5,13 +5,14 @@ #include #include #include +#include using namespace MWRender; using namespace Ogre; OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) : mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0), - mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false), + mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false), mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false), mBBNode(0) { @@ -84,7 +85,6 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod mRendering->getScene()->addRenderObjectListener(this); mRendering->getScene()->addRenderQueueListener(this); mDoQuery = true; - mDoQuery2 = true; } OcclusionQuery::~OcclusionQuery() @@ -100,7 +100,7 @@ bool OcclusionQuery::supported() return mSupported; } -void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source, +void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source, const LightList* pLightList, bool suppressRenderStateChanges) { // The following code activates and deactivates the occlusion queries @@ -134,7 +134,7 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass mActiveQuery = mSingleObjectQuery; mObjectWasVisible = true; } - + if (mActiveQuery != NULL) mActiveQuery->beginOcclusionQuery(); } @@ -195,7 +195,6 @@ void OcclusionQuery::update(float duration) // Stop occlusion queries until we get their information // (may not happen on the same frame they are requested in) mDoQuery = false; - mDoQuery2 = false; if (!mSunTotalAreaQuery->isStillOutstanding() && !mSunVisibleAreaQuery->isStillOutstanding() @@ -264,3 +263,40 @@ bool OcclusionQuery::getTestResult() return mTestResult; } + +bool OcclusionQuery::isPotentialOccluder(Ogre::SceneNode* node) +{ + bool result = false; + for (unsigned int i=0; i < node->numAttachedObjects(); ++i) + { + MovableObject* ob = node->getAttachedObject(i); + std::string type = ob->getMovableType(); + if (type == "Entity") + { + Entity* ent = static_cast(ob); + for (unsigned int j=0; j < ent->getNumSubEntities(); ++j) + { + // if any sub entity has a material with depth write off, + // consider the object as not an occluder + MaterialPtr mat = ent->getSubEntity(j)->getMaterial(); + + Material::TechniqueIterator techIt = mat->getTechniqueIterator(); + while (techIt.hasMoreElements()) + { + Technique* tech = techIt.getNext(); + Technique::PassIterator passIt = tech->getPassIterator(); + while (passIt.hasMoreElements()) + { + Pass* pass = passIt.getNext(); + + if (pass->getDepthWriteEnabled() == false) + return false; + else + result = true; + } + } + } + } + } + return result; +} diff --git a/apps/openmw/mwrender/occlusionquery.hpp b/apps/openmw/mwrender/occlusionquery.hpp index b655c8e46b..c76fcccd08 100644 --- a/apps/openmw/mwrender/occlusionquery.hpp +++ b/apps/openmw/mwrender/occlusionquery.hpp @@ -46,6 +46,14 @@ namespace MWRender */ bool occlusionTestPending(); + /** + * Checks if the objects held by this scenenode + * can be considered as potential occluders + * (which might not be the case when transparency is involved) + * @param Scene node + */ + bool isPotentialOccluder(Ogre::SceneNode* node); + /** * @return true if the object tested in the last request was occluded */ diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 71e12e3695..ed96f47d62 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -21,11 +21,11 @@ namespace MWWorld PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) : mRender(_rend), mEngine(0), mFreeFly (true) { - playerphysics = new playerMove; + // Create physics. shapeLoader is deleted by the physic engine NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader(); mEngine = new OEngine::Physic::PhysicEngine(shapeLoader); - playerphysics->mEngine = mEngine; + } PhysicsSystem::~PhysicsSystem() @@ -101,11 +101,9 @@ namespace MWWorld OEngine::Physic::PhysicActor* act = it->second; act->setWalkDirection(btVector3(0,0,0)); } - playerMove::playercmd& pm_ref = playerphysics->cmd; - pm_ref.rightmove = 0; - pm_ref.forwardmove = 0; - pm_ref.upmove = 0; + + //playerphysics->ps.move_type = PM_NOCLIP; for (std::vector >::const_iterator iter (actors.begin()); iter!=actors.end(); ++iter) @@ -123,9 +121,7 @@ namespace MWWorld Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); Ogre::Quaternion both = yawQuat * pitchQuat; - playerphysics->ps.viewangles.x = 0; - playerphysics->ps.viewangles.z = 0; - playerphysics->ps.viewangles.y = both.getYaw().valueDegrees() *-1 + 90; + //playerphysics->ps.viewangles.z = both.getPitch().valueDegrees(); @@ -133,8 +129,7 @@ namespace MWWorld { Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); - pm_ref.rightmove = -dir1.x; - pm_ref.forwardmove = dir1.z; + @@ -147,31 +142,24 @@ namespace MWWorld { Ogre::Quaternion quat = yawNode->getOrientation(); Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); - pm_ref.rightmove = -dir1.x; - pm_ref.forwardmove = dir1.z; + dir = 0.025*(quat*dir1); } - Pmove(playerphysics); + //set the walk direction act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y)); } - //mEngine->stepSimulation(duration); - Pmove(playerphysics); + mEngine->stepSimulation(duration); + std::vector< std::pair > response; for(std::map::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) { btVector3 newPos = it->second->getPosition(); Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z()); - if(it->first == "player"){ - - coord = playerphysics->ps.origin; - //std::cout << "Coord" << coord << "\n"; - coord = Ogre::Vector3(coord.x, coord.z, coord.y); //x, z, -y - - } + response.push_back(std::pair(it->first, coord)); } diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index a2dea24925..b88ff23b16 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -5,7 +5,6 @@ #include #include #include "ptr.hpp" -#include namespace MWWorld { @@ -54,7 +53,7 @@ namespace MWWorld OEngine::Render::OgreRenderer &mRender; OEngine::Physic::PhysicEngine* mEngine; bool mFreeFly; - playerMove* playerphysics; + PhysicsSystem (const PhysicsSystem&); PhysicsSystem& operator= (const PhysicsSystem&); diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 37b97dd276..1972d8d5bc 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -31,7 +31,7 @@ const float WeatherGlobals::mThunderFrequency = .4; const float WeatherGlobals::mThunderThreshold = 0.6; const float WeatherGlobals::mThunderSoundDelay = 0.25; -WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environment* env) : +WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, MWWorld::Environment* env) : mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0) { @@ -268,8 +268,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environmen blight.mGlareView = 0; blight.mAmbientLoopSoundID = "blight"; mWeatherSettings["blight"] = blight; - - /* + Weather snow; snow.mCloudTexture = "tx_bm_sky_snow.dds"; snow.mCloudsMaximumPercent = 1.0; @@ -326,7 +325,6 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environmen blizzard.mGlareView = 0; blizzard.mAmbientLoopSoundID = "BM Blizzard"; mWeatherSettings["blizzard"] = blizzard; - */ } void WeatherManager::setWeather(const String& weather, bool instant) @@ -508,32 +506,32 @@ void WeatherManager::update(float duration) float thunder = region->data.thunder/255.f; float ash = region->data.ash/255.f; float blight = region->data.blight/255.f; - //float snow = region->data.a/255.f; - //float blizzard = region->data.b/255.f; + float snow = region->data.a/255.f; + float blizzard = region->data.b/255.f; // re-scale to 100 percent - const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight;//+snow+blizzard; + const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight+snow+blizzard; srand(time(NULL)); float random = ((rand()%100)/100.f) * total; - //if (random > snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear) - // weather = "blizzard"; - //else if (random > blight+ash+thunder+rain+overcast+foggy+cloudy+clear) - // weather = "snow"; - /*else*/ if (random > ash+thunder+rain+overcast+foggy+cloudy+clear) + if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear) + weather = "blizzard"; + else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear) + weather = "snow"; + else if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear) weather = "blight"; - else if (random > thunder+rain+overcast+foggy+cloudy+clear) + else if (random >= thunder+rain+overcast+foggy+cloudy+clear) weather = "ashstorm"; - else if (random > rain+overcast+foggy+cloudy+clear) + else if (random >= rain+overcast+foggy+cloudy+clear) weather = "thunderstorm"; - else if (random > overcast+foggy+cloudy+clear) + else if (random >= overcast+foggy+cloudy+clear) weather = "rain"; - else if (random > foggy+cloudy+clear) + else if (random >= foggy+cloudy+clear) weather = "overcast"; - else if (random > cloudy+clear) + else if (random >= cloudy+clear) weather = "foggy"; - else if (random > clear) + else if (random >= clear) weather = "cloudy"; else weather = "clear"; diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index a48cc7e722..a7252353dd 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -543,7 +543,7 @@ namespace MWWorld if (ptr==mPlayer->getPlayer()) { //std::cout << "X:" << ptr.getRefData().getPosition().pos[0] << " Z: " << ptr.getRefData().getPosition().pos[1] << "\n"; - + Ptr::CellStore *currentCell = mWorldScene->getCurrentCell(); if (currentCell) { @@ -750,15 +750,16 @@ namespace MWWorld // figure out which object we want to test against std::vector < std::pair < float, std::string > > results = mPhysics->getFacedObjects(); - // ignore the player - for (std::vector < std::pair < float, std::string > >::iterator it = results.begin(); - it != results.end(); ++it) + // ignore the player and other things we're not interested in + std::vector < std::pair < float, std::string > >::iterator it = results.begin(); + while (it != results.end()) { - if ( (*it).second == mPlayer->getPlayer().getRefData().getHandle() ) + if ( getPtrViaHandle((*it).second) == mPlayer->getPlayer() ) { - results.erase(it); - break; + it = results.erase(it); } + else + ++it; } if (results.size() == 0) @@ -774,6 +775,10 @@ namespace MWWorld btVector3 p = mPhysics->getRayPoint(results.front().first); Ogre::Vector3 pos(p.x(), p.z(), -p.y()); Ogre::SceneNode* node = mFaced1.getRefData().getBaseNode(); + + //std::cout << "Num facing 1 : " << mFaced1Name << std::endl; + //std::cout << "Type 1 " << mFaced1.getTypeName() << std::endl; + query->occlusionTest(pos, node); } else @@ -786,8 +791,33 @@ namespace MWWorld btVector3 p = mPhysics->getRayPoint(results[1].first); Ogre::Vector3 pos(p.x(), p.z(), -p.y()); - Ogre::SceneNode* node = mFaced2.getRefData().getBaseNode(); - query->occlusionTest(pos, node); + Ogre::SceneNode* node1 = mFaced1.getRefData().getBaseNode(); + Ogre::SceneNode* node2 = mFaced2.getRefData().getBaseNode(); + + // no need to test if the first node is not occluder + if (!query->isPotentialOccluder(node1) && (mFaced1.getTypeName().find("Static") == std::string::npos)) + { + mFacedHandle = mFaced1Name; + //std::cout << "node1 Not an occluder" << std::endl; + return; + } + + // no need to test if the second object is static (thus cannot be activated) + if (mFaced2.getTypeName().find("Static") != std::string::npos) + { + mFacedHandle = mFaced1Name; + return; + } + + // work around door problems + if (mFaced1.getTypeName().find("Static") != std::string::npos + && mFaced2.getTypeName().find("Door") != std::string::npos) + { + mFacedHandle = mFaced2Name; + return; + } + + query->occlusionTest(pos, node2); } } } @@ -834,6 +864,18 @@ namespace MWWorld return mRendering->getFader(); } + Ogre::Vector2 World::getNorthVector(Ptr::CellStore* cell) + { + ESMS::CellRefList statics = cell->statics; + ESMS::LiveCellRef* ref = statics.find("northmarker"); + if (!ref) + return Vector2(0, 1); + Ogre::SceneNode* node = ref->mData.getBaseNode(); + Vector3 dir = node->_getDerivedOrientation().yAxis(); + Vector2 d = Vector2(dir.x, dir.z); + return d; + } + void World::setWaterHeight(const float height) { mRendering->setWaterHeight(height); diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 7f8b7e861b..92540f82b7 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -63,13 +63,14 @@ namespace MWWorld enum RenderMode { Render_CollisionDebug, - Render_Wireframe + Render_Wireframe, + Render_Pathgrid }; private: MWRender::RenderingManager* mRendering; - + MWWorld::WeatherManager* mWeatherManager; MWWorld::Scene *mWorldScene; @@ -112,7 +113,7 @@ namespace MWWorld Environment& environment, const std::string& encoding); ~World(); - + OEngine::Render::Fader* getFader(); Ptr::CellStore *getExterior (int x, int y); @@ -121,7 +122,7 @@ namespace MWWorld void setWaterHeight(const float height); void toggleWater(); - + void adjustSky(); MWWorld::Player& getPlayer(); @@ -134,10 +135,13 @@ namespace MWWorld bool hasCellChanged() const; ///< Has the player moved to a different cell, since the last frame? - + bool isCellExterior() const; bool isCellQuasiExterior() const; + Ogre::Vector2 getNorthVector(Ptr::CellStore* cell); + ///< get north vector (OGRE coordinates) for given interior cell + Globals::Data& getGlobalVariable (const std::string& name); Globals::Data getGlobalVariable (const std::string& name) const; @@ -172,9 +176,9 @@ namespace MWWorld bool toggleSky(); ///< \return Resulting mode - + void changeWeather(const std::string& region, const unsigned int id); - + int getCurrentWeather() const; int getMasserPhase() const; diff --git a/components/bsa/bsa_archive.cpp b/components/bsa/bsa_archive.cpp index 0e3563b261..fa197d9605 100644 --- a/components/bsa/bsa_archive.cpp +++ b/components/bsa/bsa_archive.cpp @@ -79,7 +79,7 @@ class DirArchive: public Ogre::FileSystemArchive { passed = filename.substr(0, filename.length() - 2); } - if(filename.at(filename.length() - 2) == '>') + if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':') passed = filename.substr(0, filename.length() - 6); copy = passed; } @@ -232,7 +232,7 @@ public: { passed = filename.substr(0, filename.length() - 2); } - if(filename.at(filename.length() - 2) == '>') + if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':') passed = filename.substr(0, filename.length() - 6); // Open the file StreamPtr strm = narc->getFile(passed.c_str()); @@ -254,7 +254,7 @@ bool exists(const String& filename) { { passed = filename.substr(0, filename.length() - 2); } - if(filename.at(filename.length() - 2) == '>') + if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':') passed = filename.substr(0, filename.length() - 6); return arc.exists(passed.c_str()); diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 2ab6ae6211..616dd1daf9 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -1296,6 +1296,7 @@ void NIFLoader::loadResource(Resource *resource) char suffix = name.at(name.length() - 2); bool addAnim = true; bool hasAnim = false; + bool linkSkeleton = true; //bool baddin = false; bNiTri = true; if(name == "meshes\\base_anim.nif" || name == "meshes\\base_animkna.nif") @@ -1326,6 +1327,17 @@ void NIFLoader::loadResource(Resource *resource) addAnim = false; } + else if(suffix == ':') + { + //baddin = true; + linkSkeleton = false; + bNiTri = true; + std::string sub = name.substr(name.length() - 6, 4); + + if(sub.compare("0000") != 0) + addAnim = false; + + } switch(name.at(name.length() - 1)) { @@ -1464,7 +1476,7 @@ void NIFLoader::loadResource(Resource *resource) } //Don't link on npc parts to eliminate redundant skeletons //Will have to be changed later slightly for robes/skirts - if(triname == "") + if(linkSkeleton) mesh->_notifySkeleton(mSkel); } } diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp deleted file mode 100644 index 45fe84f4fc..0000000000 --- a/libs/openengine/bullet/pmove.cpp +++ /dev/null @@ -1,2042 +0,0 @@ -/* -This source file is a *modified* version of bg_pmove.c from the Quake 3 Arena source code, -which was released under the GNU GPL (v2) in 2005. -Quake 3 Arena is copyright (C) 1999-2005 Id Software, Inc. -*/ - - -#include "pmove.h" - - - -//#include "bprintf.h" - -//#include "..\..\ESMParser\ESMParser\CELL.h" - -//#include "GameTime.h" - -//#include "Object.h" - -//#include "Sound.h" - -//#include "..\..\ESMParser\ESMParser\SNDG.h" -//#include "..\..\ESMParser\ESMParser\SOUN.h" - -#include - -//SceneInstance* global_lastscene = NULL; - -// Forward declaration: -void PM_AirMove(); - -static playerMove* pm = NULL; - -//extern std::map ExtCellLookup; - -static struct playermoveLocal -{ - playermoveLocal() : frametime(1.0f / 20.0f), groundPlane(true), walking(true), msec(50) - { - forward = Ogre::Vector3(0.0f, 0.0f, 0.0f); - right = Ogre::Vector3(0.0f, 0.0f, 0.0f); - up = Ogre::Vector3(0.0f, 0.0f, 0.0f); - - previous_origin = Ogre::Vector3(0.0f, 0.0f, 0.0f); - previous_velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); - } - - traceResults groundTrace; - - //SceneInstance* scene; - - float frametime; // in seconds (usually something like 0.01f) - float impactSpeed; - - Ogre::Vector3 forward; - Ogre::Vector3 right; - Ogre::Vector3 up; - - int msec; - - Ogre::Vector3 previous_origin, previous_velocity; - - int previous_waterlevel; // the waterlevel before this pmove - - bool groundPlane; // if we're standing on a groundplane this frame - - bool walking; - int waterHeight; - bool hasWater; - bool isInterior; - //Object* traceObj; - -} pml; - -static inline void PM_ClipVelocity(const Ogre::Vector3& in, const Ogre::Vector3& normal, Ogre::Vector3& out, const float overbounce) -{ - float backoff; - //float change; - //int i; - - // backoff = in dot normal - //backoff = DotProduct (in, normal); - backoff = in.dotProduct(normal); - - if ( backoff < 0 ) - backoff *= overbounce; - else - backoff /= overbounce; - - // change = normal * backoff - // out = in - change - /*for ( i=0 ; i<3 ; i++ ) - { - change = normal[i]*backoff; - out[i] = in[i] - change; - }*/ - float changex = normal.x * backoff; - out.x = in.x - changex; - float changey = normal.y * backoff; - out.y = in.y - changey; - float changez = normal.z * backoff; - out.z = in.z - changez; -} - -float VectorNormalize2( const Ogre::Vector3& v, Ogre::Vector3& out) -{ - float length, ilength; - - length = v.x * v.x+ v.y * v.y + v.z * v.z; - length = sqrt(length); - - if (length) - { -#ifndef Q3_VM // bk0101022 - FPE related -// assert( ((Q_fabs(v[0])!=0.0f) || (Q_fabs(v[1])!=0.0f) || (Q_fabs(v[2])!=0.0f)) ); -#endif - ilength = 1 / length; - out.x= v.x * ilength; - out.y = v.y * ilength; - out.z = v.z * ilength; - } else - { -#ifndef Q3_VM // bk0101022 - FPE related -// assert( ((Q_fabs(v[0])==0.0f) && (Q_fabs(v[1])==0.0f) && (Q_fabs(v[2])==0.0f)) ); -#endif - //VectorClear( out ); - out.x = 0; out.y = 0; out.z = 0; - } - - return length; - -} - - -float VectorNormalize(Ogre::Vector3& out) -{ - float length, ilength; - - length = out.x * out.x + out.y * out.y + out.z * out.z; - length = sqrt(length); - - if (length) - { -#ifndef Q3_VM // bk0101022 - FPE related -// assert( ((Q_fabs(v[0])!=0.0f) || (Q_fabs(v[1])!=0.0f) || (Q_fabs(v[2])!=0.0f)) ); -#endif - ilength = 1 / length; - out.x = out.x * ilength; - out.y = out.y * ilength; - out.z = out.z * ilength; - } - - return length; - -} - -/* -================== -PM_SlideMove - -Returns qtrue if the velocity was clipped in some way -================== -*/ - -bool PM_SlideMove( bool gravity ) -{ - int bumpcount, numbumps; - Ogre::Vector3 dir; - float d; - int numplanes; - Ogre::Vector3 planes[MAX_CLIP_PLANES]; - Ogre::Vector3 primal_velocity; - Ogre::Vector3 clipVelocity; - int i, j, k; - struct traceResults trace; - Ogre::Vector3 end; - float time_left; - float into; - Ogre::Vector3 endVelocity; - Ogre::Vector3 endClipVelocity; - - numbumps = 4; - - // primal_velocity = pm->ps->velocity - //VectorCopy (pm->ps->velocity, primal_velocity); - primal_velocity = pm->ps.velocity; - - if ( gravity ) - { - // endVelocity = pm->ps->velocity - vec3(0, 0, pm->ps->gravity * pml.frametime) - //VectorCopy( pm->ps->velocity, endVelocity ); - endVelocity = pm->ps.velocity; - //endVelocity[2] -= pm->ps->gravity * pml.frametime; - endVelocity.y -= pm->ps.gravity * pml.frametime; - - // pm->ps->velocity = avg(pm->ps->velocity.z, endVelocity.z) - //pm->ps->velocity[2] = ( pm->ps->velocity[2] + endVelocity[2] ) * 0.5; - pm->ps.velocity.y= (pm->ps.velocity.y + endVelocity.y) * 0.5f; - - //primal_velocity[2] = endVelocity[2]; - primal_velocity.y = endVelocity.y; - - if ( pml.groundPlane ) - // slide along the ground plane - //PM_ClipVelocity (pm->ps->velocity, pml.groundTrace.plane.normal, pm->ps->velocity, OVERCLIP ); - PM_ClipVelocity(pm->ps.velocity, pml.groundTrace.planenormal, pm->ps.velocity, OVERCLIP); - } - - time_left = pml.frametime; - - // never turn against the ground plane - if ( pml.groundPlane ) - { - numplanes = 1; - - // planes[0] = pml.groundTrace.plane.normal - //VectorCopy( pml.groundTrace.plane.normal, planes[0] ); - planes[0] = pml.groundTrace.planenormal; - } else - numplanes = 0; - - // never turn against original velocity - VectorNormalize2( pm->ps.velocity, planes[numplanes] ); - numplanes++; - - for ( bumpcount = 0; bumpcount < numbumps; bumpcount++ ) - { - - // calculate position we are trying to move to - //VectorMA( pm->ps->origin, time_left, pm->ps->velocity, end ); - end = pm->ps.origin + pm->ps.velocity * time_left; - - // see if we can make it there - //pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemask); - //tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&(end), *(const D3DXVECTOR3* const)&(pm->ps.velocity), 0, pml.traceObj); - newtrace(&trace, pm->ps.origin, end, halfExtents, Ogre::Math::DegreesToRadians (pm->ps.viewangles.y), pm->isInterior, pm->mEngine); - - if (trace.allsolid) - { - // entity is completely trapped in another solid - //pm->ps->velocity[2] = 0; // don't build up falling damage, but allow sideways acceleration - pm->ps.velocity.y = 0; - return true; - } - - if (trace.fraction > 0) - // actually covered some distance - //VectorCopy (trace.endpos, pm->ps->origin); - pm->ps.origin = trace.endpos; - - if (trace.fraction == 1) - break; // moved the entire distance - - // save entity for contact8 - //PM_AddTouchEnt( trace.entityNum ); - - time_left -= time_left * trace.fraction; - - if (numplanes >= MAX_CLIP_PLANES) - { - // this shouldn't really happen - //VectorClear( pm->ps->velocity ); - pm->ps.velocity = Ogre::Vector3(0,0,0); - return true; - } - - // - // if this is the same plane we hit before, nudge velocity - // out along it, which fixes some epsilon issues with - // non-axial planes - // - for ( i = 0 ; i < numplanes ; i++ ) - { - if (trace.planenormal.dotProduct(planes[i]) > 0.99) //OGRE::VECTOR3 ? - //if ( DotProduct( trace.plane.normal, planes[i] ) > 0.99 ) - { - // pm->ps->velocity += (trace.plane.normal + pm->ps->velocity) - //VectorAdd( trace.plane.normal, pm->ps->velocity, pm->ps->velocity ); - pm->ps.velocity = (trace.planenormal + pm->ps.velocity); - break; - } - } - - if ( i < numplanes ) - continue; - - //VectorCopy (trace.plane.normal, planes[numplanes]); - planes[numplanes] = trace.planenormal; - numplanes++; - - // - // modify velocity so it parallels all of the clip planes - // - - // find a plane that it enters - for ( i = 0 ; i < numplanes ; i++ ) - { - //into = DotProduct( pm->ps->velocity, planes[i] ); - into = pm->ps.velocity.dotProduct(planes[i]); - if ( into >= 0.1 ) - continue; // move doesn't interact with the plane - - // see how hard we are hitting things - if ( -into > pml.impactSpeed ) - pml.impactSpeed = -into; - - // slide along the plane - //PM_ClipVelocity (pm->ps->velocity, planes[i], clipVelocity, OVERCLIP ); - PM_ClipVelocity(pm->ps.velocity, planes[i], clipVelocity, OVERCLIP); - - // slide along the plane - PM_ClipVelocity (endVelocity, planes[i], endClipVelocity, OVERCLIP ); - - // see if there is a second plane that the new move enters - for ( j = 0 ; j < numplanes ; j++ ) - { - if ( j == i ) - continue; - - if (clipVelocity.dotProduct(planes[j]) >= 0.1) - //if ( DotProduct( clipVelocity, planes[j] ) >= 0.1 ) - continue; // move doesn't interact with the plane - - // try clipping the move to the plane - PM_ClipVelocity( clipVelocity, planes[j], clipVelocity, OVERCLIP ); - PM_ClipVelocity( endClipVelocity, planes[j], endClipVelocity, OVERCLIP ); - - // see if it goes back into the first clip plane - if (clipVelocity.dotProduct(planes[i]) >= 0) - //if ( DotProduct( clipVelocity, planes[i] ) >= 0 ) - continue; - - - // slide the original velocity along the crease - //dProduct (planes[i], planes[j], dir); - dir = planes[i].crossProduct(planes[j]) ; - - //VectorNormalize( dir ); - //D3DXVec3Normalize( (D3DXVECTOR3* const)&dir, (const D3DXVECTOR3* const)&dir); - VectorNormalize(dir); - - //d = DotProduct( dir, pm->ps->velocity ); - d = dir.dotProduct(pm->ps.velocity); - - //VectorScale( dir, d, clipVelocity ); - clipVelocity = dir * d; - - //CrossProduct (planes[i], planes[j], dir); - dir = planes[i].crossProduct(planes[j]) ; - - - //VectorNormalize( dir ); - //D3DXVec3Normalize( (D3DXVECTOR3* const)&dir, (const D3DXVECTOR3* const)&dir); - VectorNormalize(dir); - - //d = DotProduct( dir, endVelocity ); - d = dir.dotProduct(endVelocity); - - //VectorScale( dir, d, endClipVelocity ); - endClipVelocity = dir * d; - - // see if there is a third plane the the new move enters - for ( k = 0 ; k < numplanes ; k++ ) - { - if ( k == i || k == j ) - continue; - - if (clipVelocity.dotProduct(planes[k]) >= 0.1) - //if ( DotProduct( clipVelocity, planes[k] ) >= 0.1 ) - continue; // move doesn't interact with the plane - - // stop dead at a tripple plane interaction - //VectorClear( pm->ps->velocity ); - printf("Stop dead at a triple plane interaction\n"); - pm->ps.velocity = Ogre::Vector3(0,0,0); - return true; - } - } - - // if we have fixed all interactions, try another move - //VectorCopy( clipVelocity, pm->ps->velocity ); - pm->ps.velocity = clipVelocity; - - //VectorCopy( endClipVelocity, endVelocity ); - endVelocity = endClipVelocity; - break; - } - } - - if ( gravity ) - //VectorCopy( endVelocity, pm->ps->velocity ); - pm->ps.velocity = endVelocity; - - // don't change velocity if in a timer (FIXME: is this correct?) - if ( pm->ps.pm_time ) - //VectorCopy( primal_velocity, pm->ps->velocity ); - pm->ps.velocity = primal_velocity; - - //return ( (qboolean)(bumpcount != 0) ); - return bumpcount != 0; -} - -/* -================== -PM_StepSlideMove - -================== -*/ -int PM_StepSlideMove( bool gravity ) -{ - Ogre::Vector3 start_o, start_v; - Ogre::Vector3 down_o, down_v; - traceResults trace; -// float down_dist, up_dist; -// vec3_t delta, delta2; - Ogre::Vector3 up, down; - float stepSize; - - // start_o = pm->ps->origin - //VectorCopy (pm->ps->origin, start_o); - start_o = pm->ps.origin; - - // start_v = pm->ps->velocity - //VectorCopy (pm->ps->velocity, start_v); - start_v = pm->ps.velocity; - - if ( PM_SlideMove( gravity ) == false ) - return 1; // we got exactly where we wanted to go first try - - // down = start_o - vec3(0, 0, STEPSIZE) - //VectorCopy(start_o, down); - down = start_o; - down.y -= STEPSIZE; - - //pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask); - //tracefunc(&trace, start_o, down, , 0, pml.scene); - //tracefunc(&trace, *(const D3DXVECTOR3* const)&start_o, *(const D3DXVECTOR3* const)&down, D3DXVECTOR3(0.0f, -STEPSIZE, 0.0f), 0, pml.traceObj); - newtrace(&trace, start_o, down, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); - - // up = vec3(0, 0, 1) - //VectorSet(up, 0, 0, 1); - up = Ogre::Vector3(0.0f, 1.0f, 0.0f); - - // never step up when you still have up velocity - //if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 || DotProduct(trace.plane.normal, up) < 0.7)) - if (pm->ps.velocity.y > 0 && ( - trace.fraction == 1.0 || trace.planenormal.dotProduct(up) < 0.7 - ) ) - return 2; - - // down_o = pm->ps->origin - //VectorCopy (pm->ps->origin, down_o); - down_o = pm->ps.origin; - - // down_v = pm->ps->velocity - //VectorCopy (pm->ps->velocity, down_v); - down_v = pm->ps.velocity; - - // up = start_o + vec3(0, 0, STEPSIZE) - //VectorCopy (start_o, up); - up = start_o; - //up[2] += STEPSIZE; - up.y += STEPSIZE; - - // test the player position if they were a stepheight higher - //pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask); - //tracefunc(&trace, *(const D3DXVECTOR3* const)&start_o, *(const D3DXVECTOR3* const)&up, D3DXVECTOR3(0.0f, STEPSIZE, 0.0f), 0, pml.traceObj); - newtrace(&trace, start_o, up, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); - if ( trace.allsolid ) - { - //if ( pm->debugLevel ) - //Com_Printf("%i:bend can't step\n", c_pmove); - //bprintf("bend can't step\n"); - return 3; // can't step up - } - - //stepSize = trace.endpos[2] - start_o[2]; - stepSize = trace.endpos.y - start_o.y; - - // try slidemove from this position - //VectorCopy (trace.endpos, pm->ps->origin); // pm->ps->origin = trace.endpos - pm->ps.origin = trace.endpos; - //VectorCopy (start_v, pm->ps->velocity); // pm->ps->velocity = start_v - pm->ps.velocity = start_v; - - PM_SlideMove( gravity ); - - // push down the final amount - - // down = pm->ps->origin - vec3(0, 0, stepSize) - //VectorCopy (pm->ps->origin, down); - down = pm->ps.origin; - //down[2] -= stepSize; - down.y -= stepSize; - - - //pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask); - //tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&down, D3DXVECTOR3(0.0f, -STEPSIZE, 0.0f), 0, pml.traceObj); - newtrace(&trace, pm->ps.origin, down, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); - if ( !trace.allsolid ) - //VectorCopy (trace.endpos, pm->ps->origin); - pm->ps.origin = trace.endpos; - - if ( trace.fraction < 1.0 ) - //PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP ); - PM_ClipVelocity(pm->ps.velocity, trace.planenormal, pm->ps.velocity, OVERCLIP); - - { - // use the step move - float delta; - - //delta = pm->ps->origin[2] - start_o[2]; - delta = pm->ps.origin.y - start_o.y; - if ( delta > 2 ) - { - if (gravity) - printf("g on: %f ", delta); - else - printf("g off: %f ", delta); - - if ( delta < 7 ) - printf("stepped 3 < x < 7\n"); - //PM_AddEvent( EV_STEP_4 ); - else if ( delta < 11 ) - printf("stepped 7 < x < 11\n"); - //PM_AddEvent( EV_STEP_8 ); - else if ( delta < 15 ) - printf("stepped 11 < x < 15\n"); - //PM_AddEvent( EV_STEP_12 ); - else - printf("stepped 15+\n"); - //PM_AddEvent( EV_STEP_16 ); - - } - /*if ( pm->debugLevel ) - Com_Printf("%i:stepped\n", c_pmove);*/ - } - - return 4; -} - -void PM_Friction(void) -{ - Ogre::Vector3 vec; - float* vel; - float speed, newspeed, control; - float drop; - - vel = &(pm->ps.velocity.x); - - // vec = vel - //VectorCopy( vel, vec ); - vec = pm->ps.velocity; - - if ( pml.walking ) - //vec[2] = 0; // ignore slope movement - vec.y = 0; - - //speed = VectorLength(vec); - speed = vec.length(); - if (speed < 1) - { - vel[0] = 0; - vel[2] = 0; // allow sinking underwater - // FIXME: still have z friction underwater? - //bprintf("Static friction (vec = [%f, %f, %f]) (vec.length = %f)\n", vec.x, vec.y, vec.z, speed); - return; - } - - drop = 0; - - // apply ground friction - if ( pm->ps.waterlevel <= 1 ) - { - if ( pml.walking )//&& !(pml.groundTrace.surfaceFlags & SURF_SLICK) ) - { - // if getting knocked back, no friction - //if ( ! (pm->ps->pm_flags & PMF_TIME_KNOCKBACK) ) - { - control = (speed < pm_stopspeed) ? pm_stopspeed : speed; - drop += control * pm_friction * pml.frametime; - } - } - } - - // apply water friction even if just wading - if ( pm->ps.waterlevel ) - drop += speed * pm_waterfriction * pm->ps.waterlevel * pml.frametime; - - // apply flying friction - /*if ( pm->ps->powerups[PW_FLIGHT]) - drop += speed * pm_flightfriction * pml.frametime; - - if ( pm->ps->pm_type == PM_SPECTATOR) - drop += speed * pm_spectatorfriction * pml.frametime;*/ - if (pm->ps.move_type == PM_SPECTATOR) - drop += speed * pm_flightfriction * pml.frametime; - - // scale the velocity - newspeed = speed - drop; - if (newspeed < 0) - newspeed = 0; - - newspeed /= speed; - - // vel *= newspeed - vel[0] = vel[0] * newspeed; - vel[1] = vel[1] * newspeed; - vel[2] = vel[2] * newspeed; -} - -float PM_CmdScale(playerMove::playercmd* const cmd) -{ - int max; - float total; - float scale; - - max = abs( cmd->forwardmove ); - if ( abs( cmd->rightmove ) > max ) - max = abs( cmd->rightmove ); - - if ( abs( cmd->upmove ) > max ) - max = abs( cmd->upmove ); - - if ( !max ) - return 0; - - total = sqrtf( (const float)(cmd->forwardmove * cmd->forwardmove - + cmd->rightmove * cmd->rightmove + cmd->upmove * cmd->upmove) ); - scale = (float)pm->ps.speed * max / ( 127.0f * total ); - - return scale; -} - -static void PM_Accelerate( Ogre::Vector3& wishdir, float wishspeed, float accel ) -{ -// int i; - float addspeed, accelspeed, currentspeed; - - // currentspeed = pm->ps->velocity dot wishdir - //currentspeed = DotProduct (pm->ps->velocity, wishdir); - currentspeed = pm->ps.velocity.dotProduct(wishdir); - - addspeed = wishspeed - currentspeed; - if (addspeed <= 0) - return; - - accelspeed = accel * pml.frametime * wishspeed; - - // Clamp accelspeed at addspeed - if (accelspeed > addspeed) - accelspeed = addspeed; - - // pm->ps->velocity += accelspeed * wishdir - //for (i=0 ; i<3 ; i++) - //pm->ps->velocity[i] += accelspeed * wishdir[i]; - pm->ps.velocity += (wishdir * accelspeed); -} - -static bool PM_CheckJump(void) -{ - //if ( pm->ps->pm_flags & PMF_RESPAWNED ) - //return qfalse; // don't allow jump until all buttons are up - - if ( pm->cmd.upmove < 10 ) - // not holding jump - return false; - - pm->cmd.upmove = 0; - - // must wait for jump to be released - /*if ( pm->ps->pm_flags & PMF_JUMP_HELD ) - { - // clear upmove so cmdscale doesn't lower running speed - pm->cmd.upmove = 0; - return false; - }*/ - - pml.groundPlane = false; // jumping away - pml.walking = false; - //pm->ps->pm_flags |= PMF_JUMP_HELD; - - pm->ps.groundEntityNum = ENTITYNUM_NONE; - pm->ps.velocity.y = JUMP_VELOCITY; - //PM_AddEvent( EV_JUMP ); - - /*if ( pm->cmd.forwardmove >= 0 ) - { - PM_ForceLegsAnim( LEGS_JUMP ); - pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP; - } - else - { - PM_ForceLegsAnim( LEGS_JUMPB ); - pm->ps->pm_flags |= PMF_BACKWARDS_JUMP; - }*/ - - return true; -} - -static void PM_WaterMove( playerMove* const pm ) -{ - //int i; - //vec3_t wishvel; - Ogre::Vector3 wishvel; - float wishspeed; - //vec3_t wishdir; - Ogre::Vector3 wishdir; - float scale; - float vel; - - /*if ( PM_CheckWaterJump() ) - { - PM_WaterJumpMove(); - return; - }*/ -#if 0 - // jump = head for surface - if ( pm->cmd.upmove >= 10 ) { - if (pm->ps->velocity[2] > -300) { - if ( pm->watertype == CONTENTS_WATER ) { - pm->ps->velocity[2] = 100; - } else if (pm->watertype == CONTENTS_SLIME) { - pm->ps->velocity[2] = 80; - } else { - pm->ps->velocity[2] = 50; - } - } - } -#endif - PM_Friction (); - - if (pm->cmd.forwardmove || pm->cmd.rightmove) - { - //NEEDS TO BE REWRITTEN FOR OGRE TIME--------------------------------------------------- - /* - static const TimeTicks footstep_duration = GetTimeFreq(); // make each splash last 1.0s - static TimeTicks lastStepTime = 0; - const TimeTicks thisStepTime = GetTimeQPC(); - static bool lastWasLeft = false; - if (thisStepTime > lastStepTime) - { - if (pm->cmd.ducking) - lastStepTime = thisStepTime + footstep_duration * 2; // splashes while ducking are twice as slow - else - lastStepTime = thisStepTime + footstep_duration; - - lastWasLeft = !lastWasLeft; - */ - //-----------------jhooks1 - - /* - namestruct defaultCreature; - const SNDG* const sndg = SNDG::GetFromMap(defaultCreature, lastWasLeft ? SNDG::r_swim : SNDG::l_swim); - if (sndg) - { - const namestruct& SOUNID = sndg->soundID; - const SOUN* const soun = SOUN::GetSound(SOUNID); - if (soun) - { - PlaySound2D(soun->soundFilename, soun->soundData->GetVolumeFloat() ); - } - }*/ - //Sound, ignore for now -- jhooks1 - //} - } - - scale = PM_CmdScale( &pm->cmd ); - // - // user intentions - // - if ( !scale ) - { - /*wishvel[0] = 0; - wishvel[1] = 0; - wishvel[2] = -60; // sink towards bottom - */ - wishvel.x = 0; - wishvel.y = -60; - wishvel.z = 0; - } - else - { - /*for (i=0 ; i<3 ; i++) - wishvel[i] = scale * pml.forward[i]*pm->cmd.forwardmove + scale * pml.right[i]*pm->cmd.rightmove;*/ - wishvel = pml.forward * scale * pm->cmd.forwardmove + pml.right * scale * pm->cmd.rightmove; - - //wishvel[2] += scale * pm->cmd.upmove; - wishvel.y += pm->cmd.upmove * scale; - } - - //VectorCopy (wishvel, wishdir); - wishdir = wishvel; - wishspeed = VectorNormalize(wishdir); - - if ( wishspeed > pm->ps.speed * pm_swimScale ) - wishspeed = pm->ps.speed * pm_swimScale; - - PM_Accelerate (wishdir, wishspeed, pm_wateraccelerate); - - // make sure we can go up slopes easily under water - //if ( pml.groundPlane && DotProduct( pm->ps->velocity, pml.groundTrace.plane.normal ) < 0 ) - if (pml.groundPlane && pm->ps.velocity.dotProduct(pml.groundTrace.planenormal) < 0.0f) - { - //vel = VectorLength(pm->ps->velocity); - vel = pm->ps.velocity.length(); - - // slide along the ground plane - //PM_ClipVelocity (pm->ps->velocity, pml.groundTrace.plane.normal, pm->ps->velocity, OVERCLIP ); - PM_ClipVelocity(pm->ps.velocity, pml.groundTrace.planenormal, pm->ps.velocity, OVERCLIP); - - VectorNormalize(pm->ps.velocity); - //VectorScale(pm->ps->velocity, vel, pm->ps->velocity); - pm->ps.velocity = pm->ps.velocity * vel; - } - - PM_SlideMove( false ); -} - -/* -=================== -PM_WalkMove - -=================== -*/ -static void PM_WalkMove( playerMove* const pmove ) -{ -// int i; - Ogre::Vector3 wishvel; - float fmove, smove; - Ogre::Vector3 wishdir; - float wishspeed; - float scale; - playerMove::playercmd cmd; - float accelerate; - float vel; - - if ( pm->ps.waterlevel > 2 && //DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) - pml.forward.dotProduct(pml.groundTrace.planenormal) > 0.0f) - { - // begin swimming - PM_WaterMove(pmove); - return; - } - - - if ( PM_CheckJump () ) - { - // jumped away - if ( pm->ps.waterlevel > 1 ) - PM_WaterMove(pmove); - else - PM_AirMove(); - printf("Jumped away\n"); - return; - } - - // Footsteps time - if (pmove->cmd.forwardmove || pmove->cmd.rightmove) - { - bool step_underwater = false; - //if (pmove->traceObj) - //{ - - - //jhooks1 - Water handling, deal with later - - - - if (pmove->hasWater) - { - if (pmove->hasWater ) - { - const float waterHeight = pmove->waterHeight; - const float waterSoundStepHeight = waterHeight + halfExtents.y; - if (pmove->ps.origin.y < waterSoundStepHeight) - step_underwater = true; - } - } - //} - - /* - static const TimeTicks footstep_duration = GetTimeFreq() / 2; // make each footstep last 500ms - static TimeTicks lastStepTime = 0; - const TimeTicks thisStepTime = GetTimeQPC(); - static bool lastWasLeft = false; - if (thisStepTime > lastStepTime) - { - if (pmove->cmd.ducking) - lastStepTime = thisStepTime + footstep_duration * 2; // footsteps while ducking are twice as slow - else - lastStepTime = thisStepTime + footstep_duration; - - lastWasLeft = !lastWasLeft; - */ - - if (step_underwater) - { - /* - const namestruct ns(lastWasLeft ? "FootWaterRight" : "FootWaterLeft"); - const SOUN* const soun = SOUN::GetSound(ns); - if (soun) - { - PlaySound2D(soun->soundFilename, soun->soundData->GetVolumeFloat() ); - }*/ - } - else - { - /* - namestruct defaultCreature; - const SNDG* const sndg = SNDG::GetFromMap(defaultCreature, lastWasLeft ? SNDG::r_foot : SNDG::l_foot); - if (sndg) - { - const namestruct& SOUNID = sndg->soundID; - const SOUN* const soun = SOUN::GetSound(SOUNID); - if (soun) - { - PlaySound2D(soun->soundFilename, soun->soundData->GetVolumeFloat() ); - } - }*/ - } - } - - - PM_Friction (); - - //bprintf("vel: (%f, %f, %f)\n", pm->ps.velocity.x, pm->ps.velocity.y, pm->ps.velocity.z); - - fmove = pm->cmd.forwardmove; - smove = pm->cmd.rightmove; - - cmd = pm->cmd; - scale = PM_CmdScale( &cmd ); - - // set the movementDir so clients can rotate the legs for strafing - //PM_SetMovementDir(); - - // project moves down to flat plane - //pml.forward[2] = 0; - pml.forward.y = 0; - - //pml.right[2] = 0; - pml.right.y = 0; - - // project the forward and right directions onto the ground plane - PM_ClipVelocity (pml.forward, pml.groundTrace.planenormal, pml.forward, OVERCLIP ); - PM_ClipVelocity (pml.right, pml.groundTrace.planenormal, pml.right, OVERCLIP ); - // - //VectorNormalize (pml.forward); - pml.forward = pml.forward.normalise(); - pml.right = pml.right.normalise(); - - - // wishvel = (pml.forward * fmove) + (pml.right * smove); - //for ( i = 0 ; i < 3 ; i++ ) - //wishvel[i] = pml.forward[i] * fmove + pml.right[i] * smove; - wishvel = pml.forward * fmove + pml.right * smove; - //bprintf("f: (%f, %f, %f), s: (%f, %f, %f)\n", fmove, smove); - - - // when going up or down slopes the wish velocity should Not be zero -// wishvel[2] = 0; - - // wishdir = wishvel - //VectorCopy (wishvel, wishdir); - //wishvel = wishdir; - wishdir = wishvel; - - wishspeed = VectorNormalize(wishdir); - wishspeed *= scale; - - // clamp the speed lower if ducking - if ( pm->cmd.ducking ) - if ( wishspeed > pm->ps.speed * pm_duckScale ) - wishspeed = pm->ps.speed * pm_duckScale; - - // clamp the speed lower if wading or walking on the bottom - if ( pm->ps.waterlevel ) - { - float waterScale; - - waterScale = pm->ps.waterlevel / 3.0f; - waterScale = 1.0f - ( 1.0f - pm_swimScale ) * waterScale; - if ( wishspeed > pm->ps.speed * waterScale ) - wishspeed = pm->ps.speed * waterScale; - } - - // when a player gets hit, they temporarily lose - // full control, which allows them to be moved a bit - //if ( ( pml.groundTrace.surfaceFlags & SURF_SLICK ) || pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) - //accelerate = pm_airaccelerate; - //else - accelerate = pm_accelerate; - - - PM_Accelerate (wishdir, wishspeed, accelerate); - - //Com_Printf("velocity = %1.1f %1.1f %1.1f\n", pm->ps->velocity[0], pm->ps->velocity[1], pm->ps->velocity[2]); - //Com_Printf("velocity1 = %1.1f\n", VectorLength(pm->ps->velocity)); - - //if ( ( pml.groundTrace.surfaceFlags & SURF_SLICK ) || pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) - //pm->ps->velocity[2] -= pm->ps->gravity * pml.frametime; - //else - //{ - // don't reset the z velocity for slopes -// pm->ps->velocity[2] = 0; - //} - - //vel = VectorLength(pm->ps->velocity); - vel = pm->ps.velocity.length(); - - // slide along the ground plane - PM_ClipVelocity (pm->ps.velocity, pml.groundTrace.planenormal, - pm->ps.velocity, OVERCLIP ); - - // don't decrease velocity when going up or down a slope - //VectorNormalize(pm->ps->velocity); - pm->ps.velocity = pm->ps.velocity.normalise(); - - //VectorScale(pm->ps->velocity, vel, pm->ps->velocity); - pm->ps.velocity = pm->ps.velocity * vel; - - // don't do anything if standing still - //if (!pm->ps->velocity[0] && !pm->ps->velocity[1]) - if (!pm->ps.velocity.x && !pm->ps.velocity.z) - return; - - PM_StepSlideMove( false ); - - //Com_Printf("velocity2 = %1.1f\n", VectorLength(pm->ps->velocity)); - -} - -void PM_UpdateViewAngles( playerMove::playerStruct* const ps, playerMove::playercmd* const cmd ) -{ - short temp; - int i; - - //while(1); - - //if ( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPINTERMISSION) - //return; // no view changes at all - - //if ( ps->pm_type != PM_SPECTATOR && ps->stats[STAT_HEALTH] <= 0 ) - //return; // no view changes at all - - // circularly clamp the angles with deltas - //bprintf("View angles: %i, %i, %i\n", cmd->angles[0], cmd->angles[1], cmd->angles[2]); - for (i = 0 ; i < 3 ; i++) - { - temp = cmd->angles[i];// + ps->delta_angles[i]; - //if ( i == PITCH ) - { - // don't let the player look up or down more than 90 degrees - /*if ( temp > 16000 ) - { - ps->delta_angles[i] = 16000 - cmd->angles[i]; - temp = 16000; - } - else if ( temp < -16000 ) - { - ps->delta_angles[i] = -16000 - cmd->angles[i]; - temp = -16000; - }*/ - } - (&(ps->viewangles.x) )[i] = SHORT2ANGLE(temp); - //cmd->angles[i] += ps->delta_angles[i]; - } - //ps->delta_angles[0] = ps->delta_angles[1] = ps->delta_angles[2] = 0; - -} - -void AngleVectors( const Ogre::Vector3& angles, Ogre::Vector3* const forward, Ogre::Vector3* const right, Ogre::Vector3* const up) -{ - float angle; - static float sr, sp, sy, cr, cp, cy; - // static to help MS compiler fp bugs - - //angle = angles[YAW] * (M_PI*2 / 360); - angle = angles.x * (M_PI * 2.0f / 360.0f); - sp = sinf(angle); - cp = cosf(angle); - - //angle = angles[PITCH] * (M_PI*2 / 360); - angle = angles.y * (-M_PI * 2.0f / 360.0f); - sy = sinf(angle); - cy = cosf(angle); - - //angle = angles[ROLL] * (M_PI*2 / 360); - angle = angles.z * (M_PI * 2.0f / 360.0f); - sr = sinf(angle); - cr = cosf(angle); - - if (forward) - { - forward->x = cp * cy; - forward->z = cp * sy; - forward->y = -sp; - } - if (right) - { - right->x = (-1 * sr * sp * cy + -1 * cr * -sy); - right->z = (-1 * sr * sp * sy + -1 * cr * cy); - right->y = 0.0f;//-1 * sp * cp; - } - if (up) - { - up->x = (cr * sp * cy + -sr * -sy); - up->z = (cr * sp * sy + -sr * cy); - up->y = cr * cp; - } -} - -void PM_GroundTraceMissed() -{ - traceResults trace; - Ogre::Vector3 point; - - if ( pm->ps.groundEntityNum != ENTITYNUM_NONE ) - { - // we just transitioned into freefall - //if ( pm->debugLevel ) - //Com_Printf("%i:lift\n", c_pmove); - - // if they aren't in a jumping animation and the ground is a ways away, force into it - // if we didn't do the trace, the player would be backflipping down staircases - //VectorCopy( pm->ps->origin, point ); - point = pm->ps.origin; - //point[2] -= 64; - point.y -= 64; - - //pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask); - //tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -64.0f, 0.0f), 0, pml.traceObj); - newtrace(&trace, pm->ps.origin, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); - if ( trace.fraction == 1.0 ) - { - if ( pm->cmd.forwardmove >= 0 ) - { - //PM_ForceLegsAnim( LEGS_JUMP ); - //pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP; - } - else - { - //PM_ForceLegsAnim( LEGS_JUMPB ); - //pm->ps->pm_flags |= PMF_BACKWARDS_JUMP; - } - } - } - - pm->ps.groundEntityNum = ENTITYNUM_NONE; - pml.groundPlane = false; - pml.walking = false; -} - -static bool PM_CorrectAllSolid(traceResults* const trace) -{ - int i, j, k; - Ogre::Vector3 point; - std::cout << "Correct all solid\n"; - - //if ( pm->debugLevel ) - //Com_Printf("%i:allsolid\n", c_pmove); - //bprintf("allsolid\n"); - - // jitter around - for (i = -1; i <= 1; i++) - { - for (j = -1; j <= 1; j++) - { - for (k = -1; k <= 1; k++) - { - //VectorCopy(pm->ps->origin, point); - point = pm->ps.origin; - - /*point[0] += (float) i; - point[1] += (float) j; - point[2] += (float) k;*/ - point += Ogre::Vector3( (const float)i, (const float)j, (const float)k); - - //pm->trace (trace, point, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask); - //tracefunc(trace, *(const D3DXVECTOR3* const)&point, *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, 0.0f, 0.0f), 0, pml.traceObj); - newtrace(trace, point, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); - - if ( !trace->allsolid ) - { - /*point[0] = pm->ps->origin[0]; - point[1] = pm->ps->origin[1]; - point[2] = pm->ps->origin[2] - 0.25;*/ - point = pm->ps.origin; - point.y -= 0.25f; - - //pm->trace (trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask); - //tracefunc(trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj); - newtrace(trace, pm->ps.origin, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); - pml.groundTrace = *trace; - return true; - } - } - } - } - - //pm->ps->groundEntityNum = ENTITYNUM_NONE; - pm->ps.groundEntityNum = ENTITYNUM_NONE; - pml.groundPlane = false; - pml.walking = false; - - return false; -} - -static void PM_CrashLand( void ) -{ - float delta; - float dist ; - float vel, acc; - float t; - float a, b, c, den; - - // decide which landing animation to use - /*if ( pm->ps->pm_flags & PMF_BACKWARDS_JUMP ) - PM_ForceLegsAnim( LEGS_LANDB ); - else - PM_ForceLegsAnim( LEGS_LAND ); - - pm->ps->legsTimer = TIMER_LAND;*/ - - // calculate the exact velocity on landing - //dist = pm->ps->origin[2] - pml.previous_origin[2]; - - dist = pm->ps.origin.y - pml.previous_origin.y; - - //vel = pml.previous_velocity[2]; - vel = pml.previous_velocity.y; - - //acc = -pm->ps->gravity; - acc = -pm->ps.gravity; - - a = acc / 2; - b = vel; - c = -dist; - - den = b * b - 4 * a * c; - if ( den < 0 ) - return; - - t = (-b - sqrtf( den ) ) / ( 2 * a ); - - delta = vel + t * acc; - delta = delta * delta * 0.0001f; - - // ducking while falling doubles damage - /*if ( pm->ps->pm_flags & PMF_DUCKED ) - delta *= 2;*/ - if (pm->cmd.upmove < -20) - delta *= 2; - - // never take falling damage if completely underwater - if ( pm->ps.waterlevel == 3 ) - return; - - // reduce falling damage if there is standing water - if ( pm->ps.waterlevel == 2 ) - delta *= 0.25; - if ( pm->ps.waterlevel == 1 ) - delta *= 0.5; - - if ( delta < 1 ) - return; - - if (delta > 60) - printf("Far crashland: %f\n", delta); - else if (delta > 40) - printf("Medium crashland: %f\n", delta); - else if (delta > 4) - printf("Short crashland: %f\n", delta); - - if (delta > 60) - { - /* - static const namestruct healthDamage("Health Damage"); - const SOUN* const soun = SOUN::GetSound(healthDamage); - if (soun) - { - PlaySound2D(soun->soundFilename, soun->soundData->GetVolumeFloat() ); - }*/ - } - - if (delta > 3) // We need at least a short crashland to proc the sound effects: - { - bool splashSound = false; - - if (pm->hasWater) - { - - const float waterHeight = pm->waterHeight; - const float waterHeightSplash = waterHeight + halfExtents.y; - if (pm->ps.origin.y < waterHeightSplash) - { - splashSound = true; - } - - } - - - if (splashSound) - { - //Change this later----------------------------------- - /* - const namestruct ns("DefaultLandWater"); - const SOUN* const soun = SOUN::GetSound(ns); - if (soun) - { - PlaySound2D(soun->soundFilename, soun->soundDatga->GetVolumeFloat() ); - }*/ - } - else - { - //Change this later--------------------------------- - /* - namestruct defaultCreature; - const SNDG* const sndg = SNDG::GetFromMap(defaultCreature, SNDG::land); - if (sndg) - { - const namestruct& SOUNID = sndg->soundID; - const SOUN* const soun = SOUN::GetSound(SOUNID); - if (soun) - { - PlaySound2D(soun->soundFilename, soun->soundData->GetVolumeFloat() ); - } - }*/ - } - } - - // create a local entity event to play the sound - - // SURF_NODAMAGE is used for bounce pads where you don't ever - // want to take damage or play a crunch sound - //if ( !(pml.groundTrace.surfaceFlags & SURF_NODAMAGE) ) - { - /*if ( delta > 60 ) - PM_AddEvent( EV_FALL_FAR ); - else if ( delta > 40 ) - { - // this is a pain grunt, so don't play it if dead - if ( pm->ps->stats[STAT_HEALTH] > 0 ) - PM_AddEvent( EV_FALL_MEDIUM ); - } - else if ( delta > 7 ) - PM_AddEvent( EV_FALL_SHORT ); - else - PM_AddEvent( PM_FootstepForSurface() );*/ - } - - // start footstep cycle over - //pm->ps->bobCycle = 0; -} - -static void PM_GroundTrace( void ) -{ - std::cout << "Ground trace\n"; - Ogre::Vector3 point; - traceResults trace; - - /*point[0] = pm->ps->origin[0]; - point[1] = pm->ps->origin[1]; - point[2] = pm->ps->origin[2] - 0.25;*/ - point = pm->ps.origin; - point.y -= 0.25f; - - //pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask); - //tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj); - newtrace(&trace, pm->ps.origin, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); - pml.groundTrace = trace; - - // do something corrective if the trace starts in a solid... - if ( trace.allsolid ) { - //std::cout << "ALL SOLID\n"; - if ( !PM_CorrectAllSolid(&trace) ){ - //std::cout << "Returning after correct all solid\n"; - return; - } - } - - // if the trace didn't hit anything, we are in free fall - if ( trace.fraction == 1.0 ) - { - PM_GroundTraceMissed(); - pml.groundPlane = false; - pml.walking = false; - return; - } - - // check if getting thrown off the ground - //if ( pm->ps->velocity[2] > 0 && DotProduct( pm->ps->velocity, trace.plane.normal ) > 10 ) - if (pm->ps.velocity.y > 0 && pm->ps.velocity.dotProduct(trace.planenormal) > 10.0f) - { - //if ( pm->debugLevel ) - //Com_Printf("%i:kickoff\n", c_pmove); - - // go into jump animation - /*if ( pm->cmd.forwardmove >= 0 ) - { - PM_ForceLegsAnim( LEGS_JUMP ); - pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP; - } - else - { - PM_ForceLegsAnim( LEGS_JUMPB ); - pm->ps->pm_flags |= PMF_BACKWARDS_JUMP; - }*/ - - pm->ps.groundEntityNum = ENTITYNUM_NONE; - pml.groundPlane = false; - pml.walking = false; - return; - } - - // slopes that are too steep will not be considered onground - //if ( trace.plane.normal[2] < MIN_WALK_NORMAL ) - if (trace.planenormal.y < MIN_WALK_NORMAL) - { - //if ( pm->debugLevel ) - //Com_Printf("%i:steep\n", c_pmove); - - // FIXME: if they can't slide down the slope, let them - // walk (sharp crevices) - pm->ps.groundEntityNum = ENTITYNUM_NONE; - pml.groundPlane = true; - pml.walking = false; - return; - } - - pml.groundPlane = true; - pml.walking = true; - - // hitting solid ground will end a waterjump - /*if (pm->ps.pm_flags & PMF_TIME_WATERJUMP) - { - pm->ps->pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND); - pm->ps->pm_time = 0; - }*/ - - if ( pm->ps.groundEntityNum == ENTITYNUM_NONE ) - { - // just hit the ground - /*if ( pm->debugLevel ) - Com_Printf("%i:Land\n", c_pmove);*/ - //bprintf("Land\n"); - - PM_CrashLand(); - - // don't do landing time if we were just going down a slope - //if ( pml.previous_velocity[2] < -200 ) - if (pml.previous_velocity.y < -200) - { - // don't allow another jump for a little while - //pm->ps->pm_flags |= PMF_TIME_LAND; - pm->ps.pm_time = 250; - } - } - - pm->ps.groundEntityNum = trace.entityNum; - - // don't reset the z velocity for slopes -// pm->ps->velocity[2] = 0; - - //PM_AddTouchEnt( trace.entityNum ); -} - -static void PM_AirMove() -{ - //int i; - Ogre::Vector3 wishvel; - float fmove, smove; - Ogre::Vector3 wishdir; - float wishspeed; - float scale; - playerMove::playercmd cmd; - - PM_Friction(); - - fmove = pm->cmd.forwardmove; - smove = pm->cmd.rightmove; - - cmd = pm->cmd; - scale = PM_CmdScale( &cmd ); - - // set the movementDir so clients can rotate the legs for strafing - //PM_SetMovementDir(); - - // project moves down to flat plane - //pml.forward[2] = 0; - pml.forward.y = 0; - //pml.right[2] = 0; - pml.right.y = 0; - //VectorNormalize (pml.forward); - pml.forward = Ogre::Vector3(pml.forward.normalise()); - pml.right = Ogre::Vector3(pml.right.normalise()); - //VectorNormalize (pml.right); - - //for ( i = 0 ; i < 2 ; i++ ) - //wishvel[i] = pml.forward[i] * fmove + pml.right[i] * smove; - wishvel = pml.forward * fmove + pml.right * smove; - - //wishvel[2] = 0; - wishvel.y = 0; - - //VectorCopy (wishvel, wishdir); - wishdir = wishvel; - //wishspeed = VectorNormalize(wishdir); - wishspeed = VectorNormalize(wishdir); - - wishspeed *= scale; - - // not on ground, so little effect on velocity - PM_Accelerate (wishdir, wishspeed, pm_airaccelerate); - - // we may have a ground plane that is very steep, even - // though we don't have a groundentity - // slide along the steep plane - if ( pml.groundPlane ) - PM_ClipVelocity (pm->ps.velocity, pml.groundTrace.planenormal, pm->ps.velocity, OVERCLIP ); - -/*#if 0 - //ZOID: If we are on the grapple, try stair-stepping - //this allows a player to use the grapple to pull himself - //over a ledge - if (pm->ps->pm_flags & PMF_GRAPPLE_PULL) - PM_StepSlideMove ( qtrue ); - else - PM_SlideMove ( qtrue ); -#endif*/ - - /*bprintf("%i ", */PM_StepSlideMove ( true )/* )*/; -} - -static void PM_NoclipMove( void ) -{ - float speed, drop, friction, control, newspeed; -// int i; - Ogre::Vector3 wishvel; - float fmove, smove; - Ogre::Vector3 wishdir; - float wishspeed; - float scale; - - //pm->ps->viewheight = DEFAULT_VIEWHEIGHT; - - // friction - - //speed = VectorLength (pm->ps->velocity); - speed = pm->ps.velocity.length(); - if (speed < 1) - //VectorCopy (vec3_origin, pm->ps->velocity); - pm->ps.velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); - else - { - drop = 0; - - friction = pm_friction * 1.5f; // extra friction - control = speed < pm_stopspeed ? pm_stopspeed : speed; - drop += control * friction * pml.frametime; - - // scale the velocity - newspeed = speed - drop; - if (newspeed < 0) - newspeed = 0; - newspeed /= speed; - - //VectorScale (pm->ps->velocity, newspeed, pm->ps->velocity); - pm->ps.velocity = pm->ps.velocity * newspeed; - } - - // accelerate - scale = PM_CmdScale( &pm->cmd ); - - fmove = pm->cmd.forwardmove; - smove = pm->cmd.rightmove; - - //for (i=0 ; i<3 ; i++) - //wishvel[i] = pml.forward[i] * fmove + pml.right[i] * smove; - wishvel = pml.forward * fmove + pml.right * smove; - //wishvel[2] += pm->cmd.upmove; - wishvel.y += pm->cmd.upmove; - - //VectorCopy (wishvel, wishdir); - wishdir = wishvel; - wishspeed = VectorNormalize(wishdir); - wishspeed *= scale; - - PM_Accelerate( wishdir, wishspeed, pm_accelerate ); - - // move - //VectorMA (pm->ps->origin, pml.frametime, pm->ps->velocity, pm->ps->origin); - pm->ps.origin = pm->ps.origin + pm->ps.velocity * pml.frametime; -} - -static void PM_DropTimers( void ) -{ - // drop misc timing counter - if ( pm->ps.pm_time ) - { - if ( pml.msec >= pm->ps.pm_time ) - { - //pm->ps->pm_flags &= ~PMF_ALL_TIMES; - pm->ps.pm_time = 0; - } - else - pm->ps.pm_time -= pml.msec; - } - - //bprintf("Time: %i\n", pm->ps.pm_time); - - // drop animation counter - /*if ( pm->ps->legsTimer > 0 ) - { - pm->ps->legsTimer -= pml.msec; - if ( pm->ps->legsTimer < 0 ) - pm->ps->legsTimer = 0; - } - - if ( pm->ps->torsoTimer > 0 ) - { - pm->ps->torsoTimer -= pml.msec; - if ( pm->ps->torsoTimer < 0 ) - pm->ps->torsoTimer = 0; - }*/ -} - -static void PM_FlyMove( void ) -{ - //int i; - Ogre::Vector3 wishvel; - float wishspeed; - Ogre::Vector3 wishdir; - float scale; - - // normal slowdown - PM_Friction (); - - scale = PM_CmdScale( &pm->cmd ); - // - // user intentions - // - if ( !scale ) - { - /*wishvel[0] = 0; - wishvel[1] = 0; - wishvel[2] = 0;*/ - wishvel = Ogre::Vector3(0,0,0); - } - else - { - //for (i=0 ; i<3 ; i++) - //wishvel[i] = scale * pml.forward[i]*pm->cmd.forwardmove + scale * pml.right[i]*pm->cmd.rightmove; - wishvel = pml.forward * scale * pm->cmd.forwardmove + pml.right * scale * pm->cmd.rightmove; - - //wishvel[2] += scale * pm->cmd.upmove; - wishvel.y += /*6.35f * */pm->cmd.upmove * scale; - } - - //VectorCopy (wishvel, wishdir); - wishdir = wishvel; - - //wishspeed = VectorNormalize(wishdir); - wishspeed = VectorNormalize(wishdir); - - PM_Accelerate (wishdir, wishspeed, pm_flyaccelerate); - - PM_StepSlideMove( false ); -} - - -void PM_SetWaterLevel( playerMove* const pm ) -{ - Ogre::Vector3 point; - //int cont; - int sample1; - int sample2; - - // - // get waterlevel, accounting for ducking - // - - pm->ps.waterlevel = WL_DRYLAND; - pm->ps.watertype = 0; - - /*point[0] = pm->ps->origin[0]; - point[1] = pm->ps->origin[1]; - point[2] = pm->ps->origin[2] + MINS_Z + 1; */ - point.x = pm->ps.origin.x; - point.y = pm->ps.origin.y + MINS_Z + 1; - point.z = pm->ps.origin.z; - - //cont = pm->pointcontents( point, pm->ps->clientNum ); - bool checkWater = (pml.hasWater && pml.waterHeight > point.y); - //if ( cont & MASK_WATER ) - if ( checkWater) - { - sample2 = /*pm->ps.viewheight*/DEFAULT_VIEWHEIGHT - MINS_Z; - sample1 = sample2 / 2; - - pm->ps.watertype = CONTENTS_WATER;//cont; - pm->ps.waterlevel = WL_ANKLE; - //point[2] = pm->ps->origin[2] + MINS_Z + sample1; - point.y = pm->ps.origin.y + MINS_Z + sample1; - //cont = pm->pointcontents (point, pm->ps->clientNum ); - //if ( cont & MASK_WATER ) - if (checkWater) - { - pm->ps.waterlevel = WL_WAIST; - //point[2] = pm->ps->origin[2] + MINS_Z + sample2; - point.y = pm->ps.origin.y + MINS_Z + sample2; - //cont = pm->pointcontents (point, pm->ps->clientNum ); - //if ( cont & MASK_WATER ) - if (checkWater ) - pm->ps.waterlevel = WL_UNDERWATER; - } - } -} - -void PmoveSingle (playerMove* const pmove) -{ - std::cout << "Pmove single\n"; - //pm = pmove; - - // Aedra doesn't support Q3-style VM traps D: //while(1); - - // this counter lets us debug movement problems with a journal - // by setting a conditional breakpoint fot the previous frame - //c_pmove++; - - // clear results - //pm->numtouch = 0; - pm->ps.watertype = 0; - pm->ps.waterlevel = WL_DRYLAND; - - //if ( pm->ps->stats[STAT_HEALTH] <= 0 ) - //pm->tracemask &= ~CONTENTS_BODY; // corpses can fly through bodies - - - // make sure walking button is clear if they are running, to avoid - // proxy no-footsteps cheats - //if ( abs( pm->cmd.forwardmove ) > 64 || abs( pm->cmd.rightmove ) > 64 ) - //pm->cmd.buttons &= ~BUTTON_WALKING; - - - // set the talk balloon flag - //if ( pm->cmd.buttons & BUTTON_TALK ) - //pm->ps->eFlags |= EF_TALK; - //else - //pm->ps->eFlags &= ~EF_TALK; - - // set the firing flag for continuous beam weapons - /*if ( !(pm->ps->pm_flags & PMF_RESPAWNED) && pm->ps->pm_type != PM_INTERMISSION - && ( pm->cmd.buttons & BUTTON_ATTACK ) && pm->ps->ammo[ pm->ps->weapon ] ) - pm->ps->eFlags |= EF_FIRING; - else - pm->ps->eFlags &= ~EF_FIRING;*/ - - // clear the respawned flag if attack and use are cleared - /*if ( pm->ps->stats[STAT_HEALTH] > 0 && - !( pm->cmd.buttons & (BUTTON_ATTACK | BUTTON_USE_HOLDABLE) ) ) - pm->ps->pm_flags &= ~PMF_RESPAWNED;*/ - - // if talk button is down, dissallow all other input - // this is to prevent any possible intercept proxy from - // adding fake talk balloons - /*if ( pmove->cmd.buttons & BUTTON_TALK ) - { - // keep the talk button set tho for when the cmd.serverTime > 66 msec - // and the same cmd is used multiple times in Pmove - pmove->cmd.buttons = BUTTON_TALK; - pmove->cmd.forwardmove = 0; - pmove->cmd.rightmove = 0; - pmove->cmd.upmove = 0; - }*/ - - // clear all pmove local vars - memset (&pml, 0, sizeof(pml) ); - - // Aedra-specific code: - //pml.scene = global_lastscene; - - - // End Aedra-specific code - pml.hasWater = pmove->hasWater; - pml.isInterior = pmove->isInterior; - pml.waterHeight = pmove->waterHeight; -#ifdef _DEBUG - if (!pml.traceObj) - __debugbreak(); - - if (!pml.traceObj->incellptr) - __debugbreak(); -#endif - - // determine the time - pml.msec = pmove->cmd.serverTime - pm->ps.commandTime; - if ( pml.msec < 1 ) - pml.msec = 1; - else if ( pml.msec > 200 ) - pml.msec = 200; - - //pm->ps->commandTime = pmove->cmd.serverTime; - - // Commented out as a hack - pm->ps.commandTime = pmove->cmd.serverTime; - - // Handle state change procs: - if (pm->cmd.activating != pm->cmd.lastActivatingState) - { - if (!pm->cmd.lastActivatingState && pm->cmd.activating) - pm->cmd.procActivating = playerMove::playercmd::KEYDOWN; - else - pm->cmd.procActivating = playerMove::playercmd::KEYUP; - } - else - { - pm->cmd.procActivating = playerMove::playercmd::NO_CHANGE; - } - pm->cmd.lastActivatingState = pm->cmd.activating; - - if (pm->cmd.dropping != pm->cmd.lastDroppingState) - { - if (!pm->cmd.lastDroppingState && pm->cmd.dropping) - pm->cmd.procDropping = playerMove::playercmd::KEYDOWN; - else - pm->cmd.procDropping = playerMove::playercmd::KEYUP; - } - else - { - pm->cmd.procDropping = playerMove::playercmd::NO_CHANGE; - } - pm->cmd.lastDroppingState = pm->cmd.dropping; - - // save old org in case we get stuck - //VectorCopy (pm->ps->origin, pml.previous_origin); - pml.previous_origin = pm->ps.origin; - - // Copy over the lastframe origin - pmove->ps.lastframe_origin = pmove->ps.origin; - - //pmove->ps.lastframe_origin = pmove->ps.origin; - - // save old velocity for crashlanding - //VectorCopy (pm->ps->velocity, pml.previous_velocity); - pml.previous_velocity = pm->ps.velocity; - - pml.frametime = pml.msec * 0.001f; - - // update the viewangles - //PM_UpdateViewAngles( &(pm->ps), &(pm->cmd) ); - - AngleVectors (pm->ps.viewangles, &(pml.forward), &(pml.right), &(pml.up) ); - - //if ( pm->cmd.upmove < 10 ) - // not holding jump - //pm->ps->pm_flags &= ~PMF_JUMP_HELD; - - // decide if backpedaling animations should be used - /*if ( pm->cmd.forwardmove < 0 ) - pm->ps->pm_flags |= PMF_BACKWARDS_RUN; - else if ( pm->cmd.forwardmove > 0 || ( pm->cmd.forwardmove == 0 && pm->cmd.rightmove ) ) - pm->ps->pm_flags &= ~PMF_BACKWARDS_RUN;*/ - - /*if ( pm->ps->pm_type >= PM_DEAD ) - { - pm->cmd.forwardmove = 0; - pm->cmd.rightmove = 0; - pm->cmd.upmove = 0; - }*/ - - if ( pm->ps.move_type == PM_SPECTATOR ) - { - std::cout << "SPECTATOR\n"; - //PM_CheckDuck (); - PM_FlyMove (); - PM_DropTimers (); - return; - } - - if ( pm->ps.move_type == PM_NOCLIP ) - { - std::cout << "NOCLIP\n"; - PM_NoclipMove (); - PM_DropTimers (); - return; - } - - if (pm->ps.move_type == PM_FREEZE){ - std::cout << "FREEZE\n"; - return; // no movement at all - - } - - if ( pm->ps.move_type == PM_INTERMISSION || pm->ps.move_type == PM_SPINTERMISSION){ - std::cout << "INTERMISSION\n"; - return; // no movement at all - } - - // set watertype, and waterlevel - PM_SetWaterLevel(pmove); - pml.previous_waterlevel = pmove->ps.waterlevel; - - // set mins, maxs, and viewheight - //PM_CheckDuck (); - - // set groundentity - PM_GroundTrace(); - - /*if ( pm->ps->pm_type == PM_DEAD ) - PM_DeadMove (); - - PM_DropTimers();*/ - - PM_DropTimers(); - -/*#ifdef MISSIONPACK - if ( pm->ps->powerups[PW_INVULNERABILITY] ) { - PM_InvulnerabilityMove(); - } else -#endif*/ - /*if ( pm->ps->powerups[PW_FLIGHT] ) - // flight powerup doesn't allow jump and has different friction - PM_FlyMove(); - else if (pm->ps->pm_flags & PMF_GRAPPLE_PULL) - { - PM_GrappleMove(); - // We can wiggle a bit - PM_AirMove(); - } - else if (pm->ps->pm_flags & PMF_TIME_WATERJUMP) - PM_WaterJumpMove();*/ - if ( pmove->ps.waterlevel > 1 ) - // swimming - PM_WaterMove(pmove); - else if ( pml.walking ) - { - std::cout << "WALKING\n"; - // walking on ground - PM_WalkMove(pmove); - //bprintf("WalkMove\n"); - } - else - { - // airborne - std::cout << "AIRMOVE\n"; - PM_AirMove(); - //bprintf("AirMove\n"); - } - - //PM_Animate(); - - // set groundentity, watertype, and waterlevel - PM_GroundTrace(); - PM_SetWaterLevel(pmove); - - // weapons - /*PM_Weapon(); - - // torso animation - PM_TorsoAnimation(); - - // footstep events / legs animations - PM_Footsteps(); - - // entering / leaving water splashes - PM_WaterEvents(); - - // snap some parts of playerstate to save network bandwidth - trap_SnapVector( pm->ps->velocity );*/ -} - -void Ext_UpdateViewAngles(playerMove* const pm) -{ - playerMove::playerStruct* const ps = &(pm->ps); - playerMove::playercmd* const cmd = &(pm->cmd); - PM_UpdateViewAngles(ps, cmd); -} - -void Pmove (playerMove* const pmove) -{ - pm = pmove; - - int finalTime; - - finalTime = pmove->cmd.serverTime; - - pmove->ps.commandTime = 40; - - if ( finalTime < pmove->ps.commandTime ) - return; // should not happen - - if ( finalTime > pmove->ps.commandTime + 1000 ) - pmove->ps.commandTime = finalTime - 1000; - - pmove->ps.pmove_framecount = (pmove->ps.pmove_framecount + 1) & ( (1 << PS_PMOVEFRAMECOUNTBITS) - 1); - - // chop the move up if it is too long, to prevent framerate - // dependent behavior - while ( pmove->ps.commandTime != finalTime ) - { - int msec; - - msec = finalTime - pmove->ps.commandTime; - - if ( pmove->pmove_fixed ) - if ( msec > pmove->pmove_msec ) - msec = pmove->pmove_msec; - else - if ( msec > 66 ) - msec = 66; - - pmove->cmd.serverTime = pmove->ps.commandTime + msec; - - if (pmove->isInterior) - { - PmoveSingle( pmove ); - } - else - { - PmoveSingle( pmove ); - /* - std::map::const_iterator it = ExtCellLookup.find(PositionToCell(pmove->ps.origin) ); - if (it != ExtCellLookup.end() ) - { - pmove->traceObj->incellptr = it->second; - }*/ - } - - //if ( pmove->ps->pm_flags & PMF_JUMP_HELD ) - //pmove->cmd.upmove = 20; - } - - //pmove->ps.last_compute_time = GetTimeQPC(); - //pmove->ps.lerp_multiplier = (pmove->ps.origin - pmove->ps.lastframe_origin);// * (1.000 / 31.0); - - //PM_CheckStuck(); - -} - - diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h deleted file mode 100644 index e90cc3b35d..0000000000 --- a/libs/openengine/bullet/pmove.h +++ /dev/null @@ -1,197 +0,0 @@ -#ifndef OENGINE_BULLET_PMOVE_H -#define OENGINE_BULLET_PMOVE_H -/* -This source file is a *modified* version of various header files from the Quake 3 Arena source code, -which was released under the GNU GPL (v2) in 2005. -Quake 3 Arena is copyright (C) 1999-2005 Id Software, Inc. -*/ - -#include -#include -#include -#include "trace.h" -#include "physic.hpp" - - -//#include "GameMath.h" -//#include "GameTime.h" - -// Forwards-declare it! - -/*#ifndef COMPILING_PMOVE -#include "Scene.h" -extern SceneInstance* global_lastscene; -#endif*/ - -static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2); - -#define MAX_CLIP_PLANES 5 -#define OVERCLIP 1.001f -//#define STEPSIZE 18 // 18 is way too much -#define STEPSIZE (18 / 2) -#ifndef M_PI - #define M_PI 3.14159265358979323846f -#endif -#define YAW 0 -#define PITCH /*1*/2 -#define ROLL /*2*/1 -#define SHORT2ANGLE(x) ( (x) * (360.0f / 65536.0f) ) -#define ANGLE2SHORT(x) ( (const short)( (x) / (360.0f / 65536.0f) ) ) -#define GENTITYNUM_BITS 10 // don't need to send any more -#define MAX_GENTITIES (1 << GENTITYNUM_BITS) -#define ENTITYNUM_NONE (MAX_GENTITIES - 1) -#define ENTITYNUM_WORLD (MAX_GENTITIES - 2) -#define MIN_WALK_NORMAL 0.7f // can't walk on very steep slopes -#define JUMP_VELOCITY (270 * 1) -#define PS_PMOVEFRAMECOUNTBITS 6 -#define MINS_Z -24 -#define DEFAULT_VIEWHEIGHT 26 -#define CROUCH_VIEWHEIGHT 12 -#define DEAD_VIEWHEIGHT (-16) -#define CONTENTS_SOLID 1 // an eye is never valid in a solid -#define CONTENTS_LAVA 8 -#define CONTENTS_SLIME 16 -#define CONTENTS_WATER 32 -#define CONTENTS_FOG 64 -static const float pm_accelerate = 10.0f; -static const float pm_stopspeed = 100.0f; -static const float pm_friction = 6.0f; -static const float pm_flightfriction = 3.0f; -static const float pm_waterfriction = 1.0f; -static const float pm_airaccelerate = 1.0f; -static const float pm_swimScale = 0.50f; -static const float pm_duckScale = 0.25f; -static const float pm_flyaccelerate = 8.0f; -static const float pm_wateraccelerate = 4.0f; - -enum pmtype_t : unsigned char -{ - PM_NORMAL, // can accelerate and turn - PM_NOCLIP, // noclip movement - PM_SPECTATOR, // still run into walls - PM_DEAD, // no acceleration or turning, but free falling - PM_FREEZE, // stuck in place with no control - PM_INTERMISSION, // no movement or status bar - PM_SPINTERMISSION // no movement or status bar -}; - -enum waterlevel_t : unsigned char -{ - WL_DRYLAND = 0, - WL_ANKLE, - WL_WAIST, - WL_UNDERWATER -}; - - -//#include "bprintf.h" - -struct playerMove -{ - struct playerStruct - { - playerStruct() : gravity(50.0f), speed(320.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NORMAL), pm_time(0) - { - origin = Ogre::Vector3(733.164f,1000.0f, 839.432f); - velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); - - viewangles = Ogre::Vector3(0.0f, 0.0f, 0.0f); - - delta_angles[0] = delta_angles[1] = delta_angles[2] = 0; - - lastframe_origin.x = lastframe_origin.y = lastframe_origin.z = 0; - lerp_multiplier.x = lerp_multiplier.y = lerp_multiplier.z = 0; - } - - inline void SpeedUp(void) - { - printf("speed up to: %f\n", speed); - speed *= 1.25f; - } - - inline void SpeedDown(void) - { - printf("speed down to %f\n", speed); - speed /= 1.25f; - } - - Ogre::Vector3 velocity; - Ogre::Vector3 origin; - float gravity; // default = 800 - float speed; // default = 320 - - int commandTime; // the time at which this command was issued (in milliseconds) - - int pm_time; - - Ogre::Vector3 viewangles; - - int groundEntityNum; - - int pmove_framecount; - - int watertype; - waterlevel_t waterlevel; - - signed short delta_angles[3]; - - pmtype_t move_type; - - float last_compute_time; - Ogre::Vector3 lastframe_origin; - Ogre::Vector3 lerp_multiplier; - } ps; - - struct playercmd - { - enum CMDstateChange - { - NO_CHANGE, - KEYDOWN, - KEYUP - }; - - playercmd() : forwardmove(0), rightmove(0), upmove(0), serverTime(50), ducking(false), - activating(false), lastActivatingState(false), procActivating(NO_CHANGE), - dropping(false), lastDroppingState(false), procDropping(NO_CHANGE) - { - angles[0] = angles[1] = angles[2] = 0; - } - - int serverTime; - - short angles[3]; - - signed char forwardmove; - signed char rightmove; - signed char upmove; - - bool ducking; - bool activating; // if the user is holding down the activate button - bool dropping; // if the user is dropping an item - - bool lastActivatingState; - bool lastDroppingState; - - CMDstateChange procActivating; - CMDstateChange procDropping; - } cmd; - - playerMove() : msec(50), pmove_fixed(false), pmove_msec(50), waterHeight(0), isInterior(true), hasWater(false) - { - } - - int msec; - int pmove_msec; - bool pmove_fixed; - int waterHeight; - bool hasWater; - bool isInterior; - //Object* traceObj; - OEngine::Physic::PhysicEngine* mEngine; -}; - -void Pmove (playerMove* const pmove); -void Ext_UpdateViewAngles(playerMove* const pm); -void AngleVectors( const Ogre::Vector3& angles, Ogre::Vector3* const forward, Ogre::Vector3* const right, Ogre::Vector3* const up) ; -#endif diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp deleted file mode 100644 index 49e12064ee..0000000000 --- a/libs/openengine/bullet/trace.cpp +++ /dev/null @@ -1,188 +0,0 @@ - -#include "trace.h" - - - -#include - - - - - - - -void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBHalfExtents, const float rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass) //Traceobj was a Aedra Object -{ - - //if (!traceobj) - // return; - - //if (!traceobj->incellptr) - // return; - - const Ogre::Vector3 rayDir = end - start; - - // Nudge starting point backwards - //const Position3D nudgestart = start + (rayDir * -0.1f); // by 10% (isn't that too much?) - //const Position3D nudgestart = start; - - NewPhysTraceResults out; - //std::cout << "Starting trace\n"; - Ogre::Vector3 startReplace = Ogre::Vector3(650,950, 45); - Ogre::Vector3 endReplace = startReplace; - endReplace.y -= .25; - - const bool hasHit = NewPhysicsTrace(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, rotation, 0.0f), isInterior, enginePass); - if(hasHit) - std::cout << "Has hit\n"; - if (out.fraction < 0.001f) - results->startsolid = true; - else - results->startsolid = false; - - - //results->allsolid = out.startSolid; - - // If outside and underground, we're solid - /*if (isInterior) - { - const Ogre::Vector3 height = GetGroundPosition(start, CellCoords(traceCell->data->gridX, traceCell->data->gridY) ); - if (start.yPos - height.yPos < (-2.0f * BBHalfExtents.yPos) ) - { - results->allsolid = true; - } - else - results->allsolid = false; - }*/ - - // If inside and out of the tree, we're solid - //else - //{ - results->allsolid = out.startSolid; - //std::cout << "allsolid" << results->allsolid << "\n"; - //} - - if (!hasHit) - { - results->endpos = end; - results->planenormal = Ogre::Vector3(0.0f, 1.0f, 0.0f); - results->entityNum = ENTITYNUM_NONE; - results->fraction = 1.0f; - } - else - { - results->fraction = out.fraction; - results->planenormal = out.hitNormal; - results->endpos = rayDir * results->fraction + start; - results->entityNum = ENTITYNUM_WORLD; - /*bprintf("Start: (%f, %f, %f) End: (%f, %f, %f) TraceDir: (%f, %f, %f) HitNormal: (%f, %f, %f) Fraction: %f Hitpos: (%f, %f, %f) CompensatedHitpos: (%f, %f, %f)\n", - start.xPos, start.yPos, start.zPos, - end.xPos, end.yPos, end.zPos, - rayDir.xPos, rayDir.yPos, rayDir.zPos, - results->planenormal.xPos, results->planenormal.yPos, results->planenormal.zPos, results->fraction, - out.endPos.xPos, out.endPos.yPos, out.endPos.zPos, - results->endpos.xPos, results->endpos.yPos, results->endpos.zPos);*/ - } -} - - - -template -const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, - const Ogre::Vector3& BBHalfExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass) -{ - //if (!traceobj->incellptr) - // return false; - //if(enginePass->dynamicsWorld->getCollisionObjectArray().at(60)->getCollisionShape()->isConvex()) - // std::cout << "It's convex\n"; - - - - const btVector3 btstart(start.x, start.y, start.z); - const btVector3 btend(end.x, end.y, end.z); - const btQuaternion btrot(rotation.y, rotation.x, rotation.z); - - const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z)); - const btTransform from(btrot, btstart); - const btTransform to(btrot, btend); - float x = from.getOrigin().getX(); - float y = from.getOrigin().getY(); - float z = from.getOrigin().getZ(); - float x2 = to.getOrigin().getX(); - float y2 = to.getOrigin().getY(); - float z2 = to.getOrigin().getZ(); - - std::cout << "BtFrom: " << x << "," << y << "," << z << "\n"; - std::cout << "BtTo: " << x2 << "," << y2 << "," << z2 << "\n"; - //std::cout << "BtTo: " << to.getOrigin().getX() << "," << to.getOrigin().getY() << "," << to.getOrigin().getZ() << "\n"; - - - btCollisionWorld::ClosestConvexResultCallback - newTraceCallback(btstart, btend); - - newTraceCallback.m_collisionFilterMask = (traceType == collisionWorldTrace) ? Only_Collision : Only_Pickup; - - - enginePass->dynamicsWorld->convexSweepTest(&newshape, from, to, newTraceCallback); - //newTraceCallback. - - - //std::cout << "NUM: " << enginePass->dynamicsWorld->getNumCollisionObjects() << "\n"; - - // Copy the hit data over to our trace results struct: - out->fraction = newTraceCallback.m_closestHitFraction; - - Ogre::Vector3& outhitnormal = out->hitNormal; - const btVector3& tracehitnormal = newTraceCallback.m_hitNormalWorld; - - outhitnormal.x = tracehitnormal.x(); - outhitnormal.y = tracehitnormal.y(); - outhitnormal.z = tracehitnormal.z(); - - Ogre::Vector3& outhitpos = out->endPos; - const btVector3& tracehitpos = newTraceCallback.m_hitPointWorld; - - outhitpos.x = tracehitpos.x(); - outhitpos.y = tracehitpos.y(); - outhitpos.z= tracehitpos.z(); - - // StartSolid test: - { - out->startSolid = false; - //btCollisionObject collision; - //collision.setCollisionShape(const_cast(&newshape) ); - - //CustomContactCallback crb; - - //world.world->contactTest(&collision, crb); - //out->startSolid = crb.hit; - - // If outside and underground, we're solid - if (!isInterior) //Check if we are interior - { - } - - // If inside and out of the tree, we're solid - else - { - btVector3 aabbMin, aabbMax; - enginePass->broadphase->getBroadphaseAabb(aabbMin, aabbMax); - //std::cout << "AABBMIN" << aabbMin.getX() <<"," <startSolid = false; - } - } - } - - const bool hasHit = newTraceCallback.hasHit(); - - if(hasHit) - std::cout << "HIT\n"; - - - return hasHit; -} From ca4de0606ea0a4b57b8b718229768d33019cd7e5 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 4 Apr 2012 23:23:24 -0400 Subject: [PATCH 04/20] Some planning --- apps/openmw/mwrender/npcanimation.hpp | 34 ++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index e2071957c0..e524878ccd 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -15,7 +15,39 @@ namespace MWRender{ class NpcAnimation: public Animation{ - +private: + + int mStateID; + //Free Parts + Ogre::Entity* chest; std::vector* chestShapes; + Ogre::Entity* skirt; std::vector* skirtShapes; + Ogre::Entity* rhand; std::vector* rhandShapes; + Ogre::Entity* lhand; std::vector* lhandShapes; + Ogre::Entity* tail; std::vector* tailShapes; + Ogre::Entity* lBeastFoot; std::vector* lBeastFootShapes; + Ogre::Entity* rBeastFoot; std::vector* rBeastFootShapes; + + //Bounded Parts + Ogre::Entity* lclavicle; + Ogre::Entity* rclavicle; + Ogre::Entity* rupperArm; + Ogre::Entity* lupperArm; + Ogre::Entity* rUpperLeg; + Ogre::Entity* lUpperLeg; + Ogre::Entity* lForearm; + Ogre::Entity* rForearm; + Ogre::Entity* lWrist; + Ogre::Entity* rWrist; + Ogre::Entity* rKnee; + Ogre::Entity* lKnee; + Ogre::Entity* neck; + Ogre::Entity* rAnkle; + Ogre::Entity* lAnkle; + Ogre::Entity* groin; + Ogre::Entity* lfoot; + Ogre::Entity* rfoot; + Ogre::Entity* hair; + Ogre::Entity* head; public: From ebab98a8a0f919049a6fd7c2997387c29f580be0 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 7 Apr 2012 22:02:20 -0400 Subject: [PATCH 05/20] Restructuring things --- CMakeLists.txt | 5 +- apps/openmw/mwclass/npc.cpp | 5 +- apps/openmw/mwrender/actors.cpp | 4 +- apps/openmw/mwrender/actors.hpp | 2 +- apps/openmw/mwrender/animation.cpp | 11 +- apps/openmw/mwrender/animation.hpp | 4 +- apps/openmw/mwrender/npcanimation.cpp | 182 ++++++++++++++------------ apps/openmw/mwrender/npcanimation.hpp | 21 ++- 8 files changed, 121 insertions(+), 113 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ce5d846848..60eadc49a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,10 +114,7 @@ set(OENGINE_BULLET ${LIBDIR}/openengine/bullet/physic.hpp ${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp ${LIBDIR}/openengine/bullet/BulletShapeLoader.h - ${LIBDIR}/openengine/bullet/pmove.h - ${LIBDIR}/openengine/bullet/pmove.cpp - ${LIBDIR}/openengine/bullet/trace.h - ${LIBDIR}/openengine/bullet/trace.cpp + ) set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI} ${OENGINE_BULLET}) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 94bcbb31f9..c78a7501f2 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -93,8 +93,9 @@ namespace MWClass void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { - std::cout << "Inserting NPC\n"; - renderingInterface.getActors().insertNPC(ptr); + + + renderingInterface.getActors().insertNPC(ptr, getInventoryStore(ptr)); } diff --git a/apps/openmw/mwrender/actors.cpp b/apps/openmw/mwrender/actors.cpp index 6eb4a182bd..5034e72b32 100644 --- a/apps/openmw/mwrender/actors.cpp +++ b/apps/openmw/mwrender/actors.cpp @@ -20,10 +20,10 @@ Actors::~Actors(){ void Actors::setMwRoot(Ogre::SceneNode* root){ mMwRoot = root; } -void Actors::insertNPC(const MWWorld::Ptr& ptr){ +void Actors::insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv){ insertBegin(ptr, true, true); - NpcAnimation* anim = new MWRender::NpcAnimation(ptr, mEnvironment, mRend); + NpcAnimation* anim = new MWRender::NpcAnimation(ptr, mEnvironment, mRend, inv); mAllActors[ptr] = anim; } diff --git a/apps/openmw/mwrender/actors.hpp b/apps/openmw/mwrender/actors.hpp index d49c6e0f8d..66c98c541c 100644 --- a/apps/openmw/mwrender/actors.hpp +++ b/apps/openmw/mwrender/actors.hpp @@ -34,7 +34,7 @@ namespace MWRender{ void setMwRoot(Ogre::SceneNode* root); void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_); void insertCreature (const MWWorld::Ptr& ptr); - void insertNPC(const MWWorld::Ptr& ptr); + void insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv); bool deleteObject (const MWWorld::Ptr& ptr); ///< \return found? diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index fb710443b6..d0019154e8 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -9,7 +9,6 @@ namespace MWRender{ , mRend(_rend) , mEnvironment(_env) , vecRotPos() - , shapeparts() , time(0.0f) , startTime(0.0f) , stopTime(0.0f) @@ -19,7 +18,6 @@ namespace MWRender{ , shapeNumber(0) , shapeIndexI() , shapes(NULL) - , entityparts() , transformations(NULL) , textmappings(NULL) , base(NULL) @@ -430,14 +428,7 @@ namespace MWRender{ //base->_updateAnimation(); //base->_notifyMoved(); - for(unsigned int i = 0; i < entityparts.size(); i++){ - //Ogre::SkeletonInstance* skel = entityparts[i]->getSkeleton(); - - //Ogre::Bone* b = skel->getRootBone(); - //b->setOrientation(Ogre::Real(.3),Ogre::Real(.3),Ogre::Real(.3), Ogre::Real(.3));//This is a trick - - //entityparts[i]->getAllAnimationStates()->_notifyDirty(); - } + std::vector::iterator iter; diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 7692c71283..98f0e74879 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -31,7 +31,7 @@ class Animation{ - std::vector* > shapeparts; //All the NiTriShape data that we need for animating an npc + float time; float startTime; @@ -48,7 +48,7 @@ class Animation{ //Ogre::SkeletonInstance* skel; std::vector* shapes; //All the NiTriShapeData for a creature - std::vector entityparts; + std::vector* transformations; diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index a4fd15b745..30c28bb795 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -2,6 +2,7 @@ #include "../mwworld/world.hpp" + using namespace Ogre; using namespace NifOgre; namespace MWRender{ @@ -10,11 +11,12 @@ NpcAnimation::~NpcAnimation(){ } -NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend): Animation(_env,_rend){ +NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv){ ESMS::LiveCellRef *ref = ptr.get(); - - + Ogre::Entity* blank = 0; + std::vector* blankshape = 0; + chest = std::make_pair(blank, blankshape); //Part selection on last character of the file string // " Tri Chest // * Tri Tail @@ -95,85 +97,85 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O std::string hairModel = "meshes\\" + mEnvironment.mWorld->getStore().bodyParts.find(hairID)->model; - const ESM::BodyPart *chest = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest"); + const ESM::BodyPart *chestPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest"); 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 *groinpart = 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 *neckpart = 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); + const ESM::BodyPart *feetpart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "feet"); + const ESM::BodyPart *tailpart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "tail"); + const ESM::BodyPart *wristlpart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); //We need two + const ESM::BodyPart *forearmlpart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); //We need two + const ESM::BodyPart *handlpart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand"); //We need two + const ESM::BodyPart *hairpart = mEnvironment.mWorld->getStore().bodyParts.search(hairID); + const ESM::BodyPart *headpart = mEnvironment.mWorld->getStore().bodyParts.search(headID); if(bodyRaceID == "b_n_argonian_f_") - forearml = mEnvironment.mWorld->getStore().bodyParts.search ("b_n_argonian_m_forearm"); //We need two - if(!handl) - handl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands"); + forearmlpart = mEnvironment.mWorld->getStore().bodyParts.search ("b_n_argonian_m_forearm"); //We need two + if(!handlpart) + handlpart = 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* handrpart = handlpart; + const ESM::BodyPart* forearmr = forearmlpart; + const ESM::BodyPart* wristrpart = wristlpart; const ESM::BodyPart* armr = arml; if(upperleg){ - insertBoundedPart("meshes\\" + upperleg->model + "*|", "Left Upper Leg"); - insertBoundedPart("meshes\\" + upperleg->model, "Right Upper Leg"); + lUpperLeg = insertBoundedPart("meshes\\" + upperleg->model + "*|", "Left Upper Leg"); + rUpperLeg = insertBoundedPart("meshes\\" + upperleg->model, "Right Upper Leg"); } if(foot){ if(bodyRaceID.compare("b_n_khajiit_m_") == 0) { - feet = foot; + feetpart = foot; } else { - insertBoundedPart("meshes\\" + foot->model, "Right Foot"); - insertBoundedPart("meshes\\" + foot->model + "*|", "Left Foot"); + rfoot = insertBoundedPart("meshes\\" + foot->model, "Right Foot"); + lfoot = insertBoundedPart("meshes\\" + foot->model + "*|", "Left Foot"); } } - if(groin){ - insertBoundedPart("meshes\\" + groin->model, "Groin"); + if(groinpart){ + groin = insertBoundedPart("meshes\\" + groinpart->model, "Groin"); } if(knee) { - insertBoundedPart("meshes\\" + knee->model + "*|", "Left Knee"); //e - insertBoundedPart("meshes\\" + knee->model, "Right Knee"); //e + lKnee = insertBoundedPart("meshes\\" + knee->model + "*|", "Left Knee"); //e + rKnee = 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"); + lAnkle = insertBoundedPart("meshes\\" + ankle->model + "*|", "Left Ankle"); //Ogre::Quaternion(Ogre::Radian(3.14 / 4), Ogre::Vector3(1, 0, 0)),blank); //1,0,0, blank); + rAnkle = insertBoundedPart("meshes\\" + ankle->model, "Right Ankle"); } if (armr){ - insertBoundedPart("meshes\\" + armr->model, "Right Upper Arm"); + rupperArm = insertBoundedPart("meshes\\" + armr->model, "Right Upper Arm"); } if(arml){ - insertBoundedPart("meshes\\" + arml->model + "*|", "Left Upper Arm"); + lupperArm = insertBoundedPart("meshes\\" + arml->model + "*|", "Left Upper Arm"); } if (forearmr) { - insertBoundedPart("meshes\\" + forearmr->model, "Right Forearm"); + rForearm = insertBoundedPart("meshes\\" + forearmr->model, "Right Forearm"); } - if(forearml) - insertBoundedPart("meshes\\" + forearml->model + "*|", "Left Forearm"); + if(forearmlpart) + lForearm = insertBoundedPart("meshes\\" + forearmlpart->model + "*|", "Left Forearm"); - if (wristr) + if (wristrpart) { - insertBoundedPart("meshes\\" + wristr->model, "Right Wrist"); + rWrist = insertBoundedPart("meshes\\" + wristrpart->model, "Right Wrist"); } - if(wristl) - insertBoundedPart("meshes\\" + wristl->model + "*|", "Left Wrist"); + if(wristlpart) + lWrist = insertBoundedPart("meshes\\" + wristlpart->model + "*|", "Left Wrist"); @@ -184,35 +186,35 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O if(clavicler) insertBoundedPart("meshes\\" + clavicler->model , "Right Clavicle", base);*/ - if(neck) + if(neckpart) { - insertBoundedPart("meshes\\" + neck->model, "Neck"); + neck = insertBoundedPart("meshes\\" + neckpart->model, "Neck"); } - if(head) - insertBoundedPart("meshes\\" + head->model, "Head"); - if(hair) - insertBoundedPart("meshes\\" + hair->model, "Head"); + if(headpart) + head = insertBoundedPart("meshes\\" + headpart->model, "Head"); + if(hairpart) + hair = insertBoundedPart("meshes\\" + hairpart->model, "Head"); - if (chest){ - insertFreePart("meshes\\" + chest->model, ":\"", insert); + if (chestPart){ + chest = insertFreePart("meshes\\" + chestPart->model, ":\""); } - if (handr){ - insertFreePart("meshes\\" + handr->model , ":?", insert); + if (handrpart){ + rhand = insertFreePart("meshes\\" + handrpart->model , ":?"); } - if (handl){ - insertFreePart("meshes\\" + handl->model, ":>", insert); + if (handlpart){ + lhand = insertFreePart("meshes\\" + handlpart->model, ":>"); } - if(tail){ - insertFreePart("meshes\\" + tail->model, ":*", insert); + if(tailpart){ + tail = insertFreePart("meshes\\" + tailpart->model, ":*"); } - if(feet){ - std::string num = getUniqueID(feet->model); - insertFreePart("meshes\\" + feet->model,":<", insert); - insertFreePart("meshes\\" + feet->model,"::", insert); + if(feetpart){ + + lBeastFoot = insertFreePart("meshes\\" + feetpart->model,"::"); + rBeastFoot = insertFreePart("meshes\\" + feetpart->model,":<"); } //originalpos = insert->_getWorldAABB().getCenter(); //originalscenenode = insert->getPosition(); @@ -222,34 +224,38 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, std::string bonename){ NIFLoader::load(mesh); - Entity* ent = mRend.getScene()->createEntity(mesh); + Ogre::Entity* part = mRend.getScene()->createEntity(mesh); - base->attachObjectToBone(bonename, ent); - return ent; + base->attachObjectToBone(bonename, part); + return part; } -void NpcAnimation::insertFreePart(const std::string &mesh, const std::string suffix, Ogre::SceneNode* insert){ +std::pair*> NpcAnimation::insertFreePart(const std::string &mesh, const std::string suffix){ + std::string meshNumbered = mesh + getUniqueID(mesh + suffix) + suffix; NIFLoader::load(meshNumbered); - Ogre::Entity* ent = mRend.getScene()->createEntity(meshNumbered); + Ogre::Entity* part = mRend.getScene()->createEntity(meshNumbered); - insert->attachObject(ent); - entityparts.push_back(ent); - shapes = ((NIFLoader::getSingletonPtr())->getShapes(mesh + "0000" + suffix)); - if(shapes){ - shapeparts.push_back(shapes); - handleShapes(shapes, ent, base->getSkeleton()); + insert->attachObject(part); + + std::vector* shape = ((NIFLoader::getSingletonPtr())->getShapes(mesh + "0000" + suffix)); + if(shape){ + + handleShapes(shape, part, base->getSkeleton()); } - - + std::pair*> pair = std::make_pair(part, shape); + return pair; } void NpcAnimation::runAnimation(float timepassed){ - + + mStateID = inv.getStateId(); + + //1. Add the amount of time passed to time //2. Handle the animation transforms dependent on time @@ -269,21 +275,25 @@ void NpcAnimation::runAnimation(float timepassed){ handleAnimationTransforms(); - std::vector*>::iterator shapepartsiter = shapeparts.begin(); - std::vector::iterator entitypartsiter = entityparts.begin(); - while(shapepartsiter != shapeparts.end()) - { + vecRotPos.clear(); - std::vector* shapes = *shapepartsiter; - Ogre::Entity* theentity = *entitypartsiter; - - - handleShapes(shapes, theentity, base->getSkeleton()); - shapepartsiter++; - entitypartsiter++; - } - - } - + + /* + if(lBeastFoot) + handleShapes(lBeastFootShapes, lBeastFoot, base->getSkeleton()); + if(rBeastFoot) + handleShapes(rBeastFootShapes, rBeastFoot, base->getSkeleton()); + if(chest) + handleShapes(chestShapes, chest, base->getSkeleton()); + if(tail) + handleShapes(tailShapes, tail, base->getSkeleton()); + if(skirt) + handleShapes(skirtShapes, skirt, base->getSkeleton()); + if(lhand) + handleShapes(lhandShapes, lhand, base->getSkeleton()); + if(rhand) + handleShapes(rhandShapes, rhand, base->getSkeleton()); + */ } } +} \ No newline at end of file diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index e524878ccd..a95ce8526f 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -6,26 +6,34 @@ #include #include #include +#include #include "../mwworld/refdata.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/environment.hpp" #include "components/nifogre/ogre_nif_loader.hpp" +#include "../mwworld/inventorystore.hpp" namespace MWRender{ class NpcAnimation: public Animation{ private: - + MWWorld::InventoryStore& inv; int mStateID; //Free Parts - Ogre::Entity* chest; std::vector* chestShapes; - Ogre::Entity* skirt; std::vector* skirtShapes; + std::pair*> chest; + std::pair*> skirt; + std::pair*> lhand; + std::pair*> rhand; + std::pair*> tail; + std::pair*> lBeastFoot; + std::pair*> rBeastFoot; + /*Ogre::Entity* skirt; std::vector* skirtShapes; Ogre::Entity* rhand; std::vector* rhandShapes; Ogre::Entity* lhand; std::vector* lhandShapes; Ogre::Entity* tail; std::vector* tailShapes; Ogre::Entity* lBeastFoot; std::vector* lBeastFootShapes; - Ogre::Entity* rBeastFoot; std::vector* rBeastFootShapes; + Ogre::Entity* rBeastFoot; std::vector* rBeastFootShapes;*/ //Bounded Parts Ogre::Entity* lclavicle; @@ -48,13 +56,14 @@ private: Ogre::Entity* rfoot; Ogre::Entity* hair; Ogre::Entity* head; + Ogre::SceneNode* insert; 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, MWWorld::InventoryStore& _inv); virtual ~NpcAnimation(); Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename); - void insertFreePart(const std::string &mesh, const std::string suffix, Ogre::SceneNode* insert); + std::pair*> insertFreePart(const std::string &mesh, const std::string suffix); virtual void runAnimation(float timepassed); }; From 6bdfdf379b46c7d2d009c5f1fb691d094597357f Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 8 Apr 2012 17:27:56 -0400 Subject: [PATCH 06/20] Trying iterators --- apps/openmw/mwrender/npcanimation.cpp | 79 +++++++++++++++++---------- apps/openmw/mwrender/npcanimation.hpp | 10 +++- 2 files changed, 59 insertions(+), 30 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 30c28bb795..ea00919c69 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -11,12 +11,18 @@ NpcAnimation::~NpcAnimation(){ } -NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv){ +NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv), robe(inv.getSlot(MWWorld::InventoryStore::Slot_Robe)){ ESMS::LiveCellRef *ref = ptr.get(); Ogre::Entity* blank = 0; std::vector* blankshape = 0; chest = std::make_pair(blank, blankshape); + tail = std::make_pair(blank, blankshape); + lBeastFoot = std::make_pair(blank, blankshape); + rBeastFoot = std::make_pair(blank, blankshape); + rhand = std::make_pair(blank, blankshape); + lhand = std::make_pair(blank, blankshape); + skirt = std::make_pair(blank, blankshape); //Part selection on last character of the file string // " Tri Chest // * Tri Tail @@ -35,18 +41,18 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O // vector = Ogre::Vector3(1,1,-1); - std::string hairID = ref->base->hair; - std::string headID = ref->base->head; - std::string npcName = ref->base->name; + hairID = ref->base->hair; + headID = ref->base->head; + npcName = ref->base->name; //ESMStore::Races r = const ESM::Race* race = mEnvironment.mWorld->getStore().races.find(ref->base->race); - std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); + bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); char secondtolast = bodyRaceID.at(bodyRaceID.length() - 2); bool female = tolower(secondtolast) == 'f'; std::transform(bodyRaceID.begin(), bodyRaceID.end(), bodyRaceID.begin(), ::tolower); - bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_"; + isBeast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_"; /*std::cout << "Race: " << ref->base->race ; if(female){ @@ -59,7 +65,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O std::string smodel = "meshes\\base_anim.nif"; - if(beast) + if(isBeast) smodel = "meshes\\base_animkna.nif"; insert = ptr.getRefData().getBaseNode(); @@ -92,11 +98,26 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O insert->scale(race->data.height.female, race->data.height.female, race->data.height.female); else insert->scale(race->data.height.male, race->data.height.male, race->data.height.male); - std::string headModel = "meshes\\" + + updateParts(); + +} + +void NpcAnimation::updateParts(){ + std::string headModel = "meshes\\" + mEnvironment.mWorld->getStore().bodyParts.find(headID)->model; std::string hairModel = "meshes\\" + mEnvironment.mWorld->getStore().bodyParts.find(hairID)->model; + + //inv.getSlot(MWWorld::InventoryStore::Slot_Robe); + + robe = inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass); + if(robe == inv.end()) + std::cout << "No part\n"; + else + std::cout << "yes part\n"; + + const ESM::BodyPart *chestPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest"); const ESM::BodyPart *upperleg = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper leg"); const ESM::BodyPart *groinpart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "groin"); @@ -216,9 +237,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O lBeastFoot = insertFreePart("meshes\\" + feetpart->model,"::"); rBeastFoot = insertFreePart("meshes\\" + feetpart->model,":<"); } - //originalpos = insert->_getWorldAABB().getCenter(); - //originalscenenode = insert->getPosition(); - + //originalpos = insert->_getWorl } Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, std::string bonename){ @@ -252,8 +271,10 @@ std::pair*> NpcAnimation::insert void NpcAnimation::runAnimation(float timepassed){ - - mStateID = inv.getStateId(); + if(mStateID != inv.getStateId()){ + mStateID = inv.getStateId(); + updateParts(); + } //1. Add the amount of time passed to time @@ -278,22 +299,22 @@ void NpcAnimation::runAnimation(float timepassed){ vecRotPos.clear(); - /* - if(lBeastFoot) - handleShapes(lBeastFootShapes, lBeastFoot, base->getSkeleton()); - if(rBeastFoot) - handleShapes(rBeastFootShapes, rBeastFoot, base->getSkeleton()); - if(chest) - handleShapes(chestShapes, chest, base->getSkeleton()); - if(tail) - handleShapes(tailShapes, tail, base->getSkeleton()); - if(skirt) - handleShapes(skirtShapes, skirt, base->getSkeleton()); - if(lhand) - handleShapes(lhandShapes, lhand, base->getSkeleton()); - if(rhand) - handleShapes(rhandShapes, rhand, base->getSkeleton()); - */ + + if(lBeastFoot.first) + handleShapes(lBeastFoot.second, lBeastFoot.first, base->getSkeleton()); + if(rBeastFoot.first) + handleShapes(rBeastFoot.second, rBeastFoot.first, base->getSkeleton()); + if(chest.first) + handleShapes(chest.second, chest.first, base->getSkeleton()); + if(tail.first) + handleShapes(tail.second, tail.first, base->getSkeleton()); + if(skirt.first) + handleShapes(skirt.second, skirt.first, base->getSkeleton()); + if(lhand.first) + handleShapes(lhand.second, lhand.first, base->getSkeleton()); + if(rhand.first) + handleShapes(rhand.second, rhand.first, base->getSkeleton()); + } } } \ No newline at end of file diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index a95ce8526f..aae97db2a6 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -13,6 +13,8 @@ #include "../mwworld/environment.hpp" #include "components/nifogre/ogre_nif_loader.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwclass/npc.hpp" +#include "../mwworld/containerstore.hpp" namespace MWRender{ @@ -57,7 +59,12 @@ private: Ogre::Entity* hair; Ogre::Entity* head; Ogre::SceneNode* insert; - + bool isBeast; + std::string headID; + std::string hairID; + std::string npcName; + std::string bodyRaceID; + MWWorld::ContainerStoreIterator robe; public: NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); @@ -65,6 +72,7 @@ private: Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename); std::pair*> insertFreePart(const std::string &mesh, const std::string suffix); virtual void runAnimation(float timepassed); + void updateParts(); }; } From 80afcb2eac55b8c9b13c660c858cadbe6b7e8586 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 8 Apr 2012 20:44:44 -0400 Subject: [PATCH 07/20] small change --- apps/openmw/mwrender/npcanimation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index f7877d2ad0..4b3c23e64b 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -295,7 +295,7 @@ void NpcAnimation::runAnimation(float timepassed){ if(mStateID != inv.getStateId()){ std::cout << "StateID" < Date: Mon, 9 Apr 2012 00:51:10 -0400 Subject: [PATCH 08/20] one more change --- apps/openmw/mwrender/npcanimation.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 4b3c23e64b..8097afdbf6 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -134,8 +134,10 @@ void NpcAnimation::updateParts(){ //inv.getSlot(MWWorld::InventoryStore::Slot_Robe); - //MWWorld::ContainerStoreIterator robe = inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass); - //if(robe == inv.end()) + MWWorld::ContainerStoreIterator robe = inv.getSlot(MWWorld::InventoryStore::Slot_Robe); + + + // ; @@ -295,6 +297,7 @@ void NpcAnimation::runAnimation(float timepassed){ if(mStateID != inv.getStateId()){ std::cout << "StateID" < Date: Wed, 11 Apr 2012 20:16:22 -0400 Subject: [PATCH 09/20] Getting started with a new branch --- apps/openmw/mwrender/npcanimation.cpp | 167 ++++++------------------- apps/openmw/mwrender/npcanimation.hpp | 15 +-- apps/openmw/mwworld/inventorystore.cpp | 2 +- components/esm/loadarmo.cpp | 1 + components/esm/loadclot.cpp | 1 + 5 files changed, 50 insertions(+), 136 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 8097afdbf6..f04ac76092 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -12,7 +12,7 @@ NpcAnimation::~NpcAnimation(){ } -NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv){ +NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv), timeToChange(0), robe(inv.getSlot(MWWorld::InventoryStore::Slot_Robe)){ ESMS::LiveCellRef *ref = ptr.get(); Ogre::Entity* blank = 0; @@ -121,6 +121,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O insert->scale(race->data.height.female, race->data.height.female, race->data.height.female); else insert->scale(race->data.height.male, race->data.height.male, race->data.height.male); + std::cout << "Inv" << inv.getStateId() << "\n"; updateParts(); } @@ -133,134 +134,43 @@ void NpcAnimation::updateParts(){ mEnvironment.mWorld->getStore().bodyParts.find(hairID)->model; //inv.getSlot(MWWorld::InventoryStore::Slot_Robe); + if(robe != inv.getSlot(MWWorld::InventoryStore::Slot_Robe)){ + //A robe was added or removed + if(chest.first) + { + insert->detachObject(chest.first); chest.first = 0; + } + robe = inv.getSlot(MWWorld::InventoryStore::Slot_Robe); + if(robe != inv.end()) + { + MWWorld::Ptr ptr = *robe; + + const ESM::Clothing *clothes = (ptr.get())->base; + std::vector parts = clothes->parts.parts; + for(int i = 0; i < parts.size(); i++) + { + ESM::PartReference part = parts[i]; + if(part.part == ESM::PRT_Cuirass) + { + const ESM::BodyPart *bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.male); + chest = insertFreePart("meshes\\" + bodypart->model, ":\""); + } + } + } - MWWorld::ContainerStoreIterator robe = inv.getSlot(MWWorld::InventoryStore::Slot_Robe); - - + } + if(robe == inv.end() ){ + //if(inv.getSlot(MWWorld::InventoryStore::Cuirass) != inv.end()) + if(chest.first == 0){ + const ESM::BodyPart *chestPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest"); + chest = insertFreePart("meshes\\" + chestPart->model, ":\""); + } + + } - // ; - const ESM::BodyPart *chestPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest"); - const ESM::BodyPart *upperleg = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper leg"); - const ESM::BodyPart *groinpart = 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 *neckpart = 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 *feetpart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "feet"); - const ESM::BodyPart *tailpart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "tail"); - const ESM::BodyPart *wristlpart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); //We need two - const ESM::BodyPart *forearmlpart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); //We need two - const ESM::BodyPart *handlpart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand"); //We need two - const ESM::BodyPart *hairpart = mEnvironment.mWorld->getStore().bodyParts.search(hairID); - const ESM::BodyPart *headpart = mEnvironment.mWorld->getStore().bodyParts.search(headID); - if(bodyRaceID == "b_n_argonian_f_") - forearmlpart = mEnvironment.mWorld->getStore().bodyParts.search ("b_n_argonian_m_forearm"); //We need two - if(!handlpart) - handlpart = 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* handrpart = handlpart; - const ESM::BodyPart* forearmr = forearmlpart; - const ESM::BodyPart* wristrpart = wristlpart; - const ESM::BodyPart* armr = arml; - - - if(upperleg){ - lUpperLeg = insertBoundedPart("meshes\\" + upperleg->model + "*|", "Left Upper Leg"); - rUpperLeg = insertBoundedPart("meshes\\" + upperleg->model, "Right Upper Leg"); - - } - if(foot){ - if(bodyRaceID.compare("b_n_khajiit_m_") == 0) - { - feetpart = foot; - } - else - { - rfoot = insertBoundedPart("meshes\\" + foot->model, "Right Foot"); - lfoot = insertBoundedPart("meshes\\" + foot->model + "*|", "Left Foot"); - } - } - if(groinpart){ - groin = insertBoundedPart("meshes\\" + groinpart->model, "Groin"); - } - if(knee) - { - lKnee = insertBoundedPart("meshes\\" + knee->model + "*|", "Left Knee"); //e - rKnee = insertBoundedPart("meshes\\" + knee->model, "Right Knee"); //e - - } - if(ankle){ - - lAnkle = insertBoundedPart("meshes\\" + ankle->model + "*|", "Left Ankle"); //Ogre::Quaternion(Ogre::Radian(3.14 / 4), Ogre::Vector3(1, 0, 0)),blank); //1,0,0, blank); - rAnkle = insertBoundedPart("meshes\\" + ankle->model, "Right Ankle"); - } - if (armr){ - rupperArm = insertBoundedPart("meshes\\" + armr->model, "Right Upper Arm"); - } - if(arml){ - lupperArm = insertBoundedPart("meshes\\" + arml->model + "*|", "Left Upper Arm"); - } - - if (forearmr) - { - rForearm = insertBoundedPart("meshes\\" + forearmr->model, "Right Forearm"); - } - if(forearmlpart) - lForearm = insertBoundedPart("meshes\\" + forearmlpart->model + "*|", "Left Forearm"); - - if (wristrpart) - { - rWrist = insertBoundedPart("meshes\\" + wristrpart->model, "Right Wrist"); - } - - if(wristlpart) - lWrist = insertBoundedPart("meshes\\" + wristlpart->model + "*|", "Left Wrist"); - - - - - - /*if(claviclel) - insertBoundedPart("meshes\\" + claviclel->model + "*|", "Left Clavicle", base); - if(clavicler) - insertBoundedPart("meshes\\" + clavicler->model , "Right Clavicle", base);*/ - - if(neckpart) - { - neck = insertBoundedPart("meshes\\" + neckpart->model, "Neck"); - } - if(headpart) - head = insertBoundedPart("meshes\\" + headpart->model, "Head"); - if(hairpart) - hair = insertBoundedPart("meshes\\" + hairpart->model, "Head"); - - if (chestPart){ - chest = insertFreePart("meshes\\" + chestPart->model, ":\""); - - - } - if (handrpart){ - rhand = insertFreePart("meshes\\" + handrpart->model , ":?"); - - } - if (handlpart){ - lhand = insertFreePart("meshes\\" + handlpart->model, ":>"); - - } - if(tailpart){ - tail = insertFreePart("meshes\\" + tailpart->model, ":*"); - } - if(feetpart){ - - lBeastFoot = insertFreePart("meshes\\" + feetpart->model,"::"); - rBeastFoot = insertFreePart("meshes\\" + feetpart->model,":<"); - } - //originalpos = insert->_getWorl } Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, std::string bonename){ @@ -295,13 +205,14 @@ std::pair*> NpcAnimation::insert void NpcAnimation::runAnimation(float timepassed){ - if(mStateID != inv.getStateId()){ - std::cout << "StateID" < .2){ + timeToChange = 0; + + updateParts(); } - + timeToChange += timepassed; //1. Add the amount of time passed to time diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index e90bea5c9f..02b161b994 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -15,6 +15,7 @@ #include "../mwworld/inventorystore.hpp" #include "../mwclass/npc.hpp" #include "../mwworld/containerstore.hpp" +#include "components/esm/loadarmo.hpp" namespace MWRender{ @@ -30,12 +31,11 @@ private: std::pair*> tail; std::pair*> lBeastFoot; std::pair*> rBeastFoot; - /*Ogre::Entity* skirt; std::vector* skirtShapes; - Ogre::Entity* rhand; std::vector* rhandShapes; - Ogre::Entity* lhand; std::vector* lhandShapes; - Ogre::Entity* tail; std::vector* tailShapes; - Ogre::Entity* lBeastFoot; std::vector* lBeastFootShapes; - Ogre::Entity* rBeastFoot; std::vector* rBeastFootShapes;*/ + + int partslots[27]; //Each part slot is taken by clothing, armor, or is empty + + + //Bounded Parts Ogre::Entity* lclavicle; @@ -64,7 +64,8 @@ private: std::string hairID; std::string npcName; std::string bodyRaceID; - + float timeToChange; + MWWorld::ContainerStoreIterator robe; public: NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 650418201b..230f7d69a0 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -72,7 +72,7 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite /// \todo restack item previously in this slot (if required) /// \todo unstack item pointed to by iterator if required) - + mSlots[slot] = iterator; flagAsModified(); diff --git a/components/esm/loadarmo.cpp b/components/esm/loadarmo.cpp index ddc25e176f..8b559b10fc 100644 --- a/components/esm/loadarmo.cpp +++ b/components/esm/loadarmo.cpp @@ -11,6 +11,7 @@ void PartReferenceList::load(ESMReader &esm) esm.getHT(pr.part); // The INDX byte pr.male = esm.getHNOString("BNAM"); pr.female = esm.getHNOString("CNAM"); + parts.push_back(pr); } } diff --git a/components/esm/loadclot.cpp b/components/esm/loadclot.cpp index 1d6c9d4a1e..16fd0598cc 100644 --- a/components/esm/loadclot.cpp +++ b/components/esm/loadclot.cpp @@ -13,6 +13,7 @@ void Clothing::load(ESMReader &esm) icon = esm.getHNOString("ITEX"); parts.load(esm); + enchant = esm.getHNOString("ENAM"); } From a885f3e9422646e1212d0b0344ed4205918b63ed Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Thu, 12 Apr 2012 20:40:11 -0400 Subject: [PATCH 10/20] Remove part function --- apps/openmw/mwrender/npcanimation.cpp | 158 +++++++++++++++++++++++++- apps/openmw/mwrender/npcanimation.hpp | 5 +- 2 files changed, 161 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index f04ac76092..520cc12bbd 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -12,11 +12,32 @@ NpcAnimation::~NpcAnimation(){ } -NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv), timeToChange(0), robe(inv.getSlot(MWWorld::InventoryStore::Slot_Robe)){ +NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv), timeToChange(0), + robe(inv.getSlot(MWWorld::InventoryStore::Slot_Robe)), + lclavicle(0), + rclavicle(0), + rupperArm(0), + lupperArm(0), + rUpperLeg(0), + lUpperLeg(0), + lForearm(0), + rForearm(0), + lWrist(0), + rWrist(0), + rKnee(0), + lKnee(0), + neck(0), + rAnkle(0), + lAnkle(0), + groin(0), + lfoot(0), + rfoot(0) + { ESMS::LiveCellRef *ref = ptr.get(); Ogre::Entity* blank = 0; std::vector* blankshape = 0; + zero = std::make_pair(blank, blankshape); chest = std::make_pair(blank, blankshape); tail = std::make_pair(blank, blankshape); lBeastFoot = std::make_pair(blank, blankshape); @@ -24,6 +45,12 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O rhand = std::make_pair(blank, blankshape); lhand = std::make_pair(blank, blankshape); skirt = std::make_pair(blank, blankshape); + for (int init = 0; init < 27; init++){ + partslots[init] = -1; //each slot is empty + partpriorities[init] = 0; + } + + //Part selection on last character of the file string // " Tri Chest // * Tri Tail @@ -254,4 +281,133 @@ void NpcAnimation::runAnimation(float timepassed){ } } + +void NpcAnimation::removeIndividualPart(int type){ + partpriorities[type] = 0; + partslots[type] = -1; + + if(type == ESM::PRT_Head && head){ //0 + base->detachObjectFromBone(head); + head = 0; + } + else if(type == ESM::PRT_Hair && hair){//1 + base->detachObjectFromBone(hair); + hair = 0; + } + else if(type == ESM::PRT_Neck && neck){//2 + base->detachObjectFromBone(neck); + neck = 0; + } + else if(type == ESM::PRT_Cuirass && chest.first){//3 + insert->detachObject(chest.first); + chest = zero; + } + else if(type == ESM::PRT_Groin && groin){//4 + base->detachObjectFromBone(groin); + groin = 0; + } + else if(type == ESM::PRT_Skirt && skirt.first){//5 + insert->detachObject(skirt.first); + skirt = zero; + } + else if(type == ESM::PRT_RHand && rhand.first){//6 + insert->detachObject(rhand.first); + rhand = zero; + } + else if(type == ESM::PRT_LHand && lhand.first){//7 + insert->detachObject(lhand.first); + lhand = zero; + } + else if(type == ESM::PRT_RWrist && rWrist){//8 + base->detachObjectFromBone(rWrist); + rWrist = 0; + } + else if(type == ESM::PRT_LWrist && lWrist){//9 + base->detachObjectFromBone(lWrist); + lWrist = 0; + } + else if(type == ESM::PRT_Shield){//10 + + } + else if(type == ESM::PRT_RForearm && rForearm){//11 + base->detachObjectFromBone(rForearm); + rForearm = 0; + } + else if(type == ESM::PRT_LForearm && lForearm){//12 + base->detachObjectFromBone(lForearm); + lForearm = 0; + } + else if(type == ESM::PRT_RUpperarm && rupperArm){//13 + base->detachObjectFromBone(rupperArm); + rupperArm = 0; + } + else if(type == ESM::PRT_LUpperarm && lupperArm){//14 + base->detachObjectFromBone(lupperArm); + lupperArm = 0; + } + else if(type == ESM::PRT_RFoot){ //15 + if(rfoot){ + base->detachObjectFromBone(rfoot); + rfoot = 0; + } + else if(rBeastFoot.first){ + insert->detachObject(rBeastFoot.first); + rBeastFoot = zero; + } + } + else if(type == ESM::PRT_LFoot){ //16 + if(lfoot){ + base->detachObjectFromBone(lfoot); + lfoot = 0; + } + else if(lBeastFoot.first){ + insert->detachObject(lBeastFoot.first); + lBeastFoot = zero; + } + } + else if(type == ESM::PRT_RAnkle && rAnkle){ //17 + base->detachObjectFromBone(rAnkle); + rAnkle = 0; + } + else if(type == ESM::PRT_LAnkle && lAnkle){ //18 + base->detachObjectFromBone(lAnkle); + lAnkle = 0; + } + else if(type == ESM::PRT_RKnee && rKnee){ //19 + base->detachObjectFromBone(rKnee); + rKnee = 0; + } + else if(type == ESM::PRT_LKnee && lKnee){ //20 + base->detachObjectFromBone(lKnee); + lKnee = 0; + } + else if(type == ESM::PRT_RLeg && rUpperLeg){ //21 + base->detachObjectFromBone(rAnkle); + rUpperLeg = 0; + } + else if(type == ESM::PRT_LLeg && lUpperLeg){ //22 + base->detachObjectFromBone(lUpperLeg); + lUpperLeg = 0; + } + else if(type == ESM::PRT_RPauldron && rclavicle){ //23 + base->detachObjectFromBone(rclavicle); + rclavicle = 0; + } + else if(type == ESM::PRT_LPauldron && lclavicle){ //24 + base->detachObjectFromBone(lclavicle); + lclavicle = 0; + } + else if(type == ESM::PRT_Weapon){ //25 + + } + else if(type == ESM::PRT_Tail && tail.first){ //26 + insert->detachObject(tail.first); + tail = zero; + } + + + + + } + } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 02b161b994..eecb598dff 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -33,7 +33,8 @@ private: std::pair*> rBeastFoot; int partslots[27]; //Each part slot is taken by clothing, armor, or is empty - + int partpriorities[27]; + std::pair*> zero; @@ -58,6 +59,7 @@ private: Ogre::Entity* rfoot; Ogre::Entity* hair; Ogre::Entity* head; + Ogre::SceneNode* insert; bool isBeast; std::string headID; @@ -74,6 +76,7 @@ private: std::pair*> insertFreePart(const std::string &mesh, const std::string suffix); virtual void runAnimation(float timepassed); void updateParts(); + void removeIndividualPart(int type); }; } From 1f566fc93a66e1cfc7b2516e9937dd88c53c3e40 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Thu, 12 Apr 2012 20:59:30 -0400 Subject: [PATCH 11/20] Another remove function --- apps/openmw/mwrender/npcanimation.cpp | 9 +++++++++ apps/openmw/mwrender/npcanimation.hpp | 1 + 2 files changed, 10 insertions(+) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 520cc12bbd..0b546bf134 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -410,4 +410,13 @@ void NpcAnimation::removeIndividualPart(int type){ } + void NpcAnimation::removePartGroup(int group){ + for(int i = 0; i < 27; i++){ + if(partslots[i] == group){ + removeIndividualPart(i); + } + } + } } + + diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index eecb598dff..0b4442e3ac 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -77,6 +77,7 @@ private: virtual void runAnimation(float timepassed); void updateParts(); void removeIndividualPart(int type); + void removePartGroup(int group); }; } From e869433b07c0e30cbd73affeb64b8d551484d7b6 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Thu, 12 Apr 2012 22:16:02 -0400 Subject: [PATCH 12/20] Add or replace individual parts --- apps/openmw/mwrender/npcanimation.cpp | 100 +++++++++++++++++++++++++- apps/openmw/mwrender/npcanimation.hpp | 1 + 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 0b546bf134..37e3573f8a 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -382,7 +382,7 @@ void NpcAnimation::removeIndividualPart(int type){ lKnee = 0; } else if(type == ESM::PRT_RLeg && rUpperLeg){ //21 - base->detachObjectFromBone(rAnkle); + base->detachObjectFromBone(rUpperLeg); rUpperLeg = 0; } else if(type == ESM::PRT_LLeg && lUpperLeg){ //22 @@ -417,6 +417,104 @@ void NpcAnimation::removeIndividualPart(int type){ } } } + bool NpcAnimation::addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh){ + if(priority >= partpriorities[type]){ + removeIndividualPart(type); + partslots[type] = group; + switch(type){ + case ESM::PRT_Head: //0 + head = insertBoundedPart(mesh, "Head"); + break; + case ESM::PRT_Hair: //1 + hair = insertBoundedPart(mesh, "Head"); + break; + case ESM::PRT_Neck: //2 + neck = insertBoundedPart(mesh, "Neck"); + break; + case ESM::PRT_Cuirass: //3 + chest = insertFreePart(mesh, ":\""); + break; + case ESM::PRT_Groin: //4 + neck = insertBoundedPart(mesh, "Groin"); + break; + case ESM::PRT_Skirt: //5 + skirt = insertFreePart(mesh, ":|"); + break; + case ESM::PRT_RHand: //6 + rhand = insertFreePart(mesh, ":?"); + break; + case ESM::PRT_LHand: //7 + lhand = insertFreePart(mesh, ":>"); + break; + case ESM::PRT_RWrist: //8 + rWrist = insertBoundedPart(mesh, "Right Wrist"); + break; + case ESM::PRT_LWrist: //9 + lWrist = insertBoundedPart(mesh + "*|", "Left Wrist"); + break; + case ESM::PRT_Shield: //10 + break; + case ESM::PRT_RForearm: //11 + rForearm = insertBoundedPart(mesh, "Right Forearm"); + break; + case ESM::PRT_LForearm: //12 + lForearm = insertBoundedPart(mesh + "*|", "Left Forearm"); + break; + case ESM::PRT_RUpperarm: //13 + rupperArm = insertBoundedPart(mesh, "Right Upper Arm"); + break; + case ESM::PRT_LUpperarm: //14 + lupperArm = insertBoundedPart(mesh + "*|", "Left Upper Arm"); + break; + case ESM::PRT_RFoot: //15 + if(isBeast) + rBeastFoot = insertFreePart(mesh, ":<"); + else + rfoot = insertBoundedPart(mesh, "Right Foot"); + break; + case ESM::PRT_LFoot: //16 + if(isBeast) + lBeastFoot = insertFreePart(mesh, "::"); + else + lfoot = insertBoundedPart(mesh + "*|", "Left Foot"); + break; + + case ESM::PRT_RAnkle: //17 + rAnkle = insertBoundedPart(mesh , "Right Ankle"); + break; + case ESM::PRT_LAnkle: //18 + lAnkle = insertBoundedPart(mesh + "*|", "Left Ankle"); + break; + case ESM::PRT_RKnee: //19 + rKnee = insertBoundedPart(mesh , "Right Knee"); + break; + case ESM::PRT_LKnee: //20 + lKnee = insertBoundedPart(mesh + "*|", "Left Knee"); + break; + case ESM::PRT_RLeg: //21 + rUpperLeg = insertBoundedPart(mesh, "Right Upper Leg"); + break; + case ESM::PRT_LLeg: //22 + lUpperLeg = insertBoundedPart(mesh + "*|", "Left Upper Leg"); + break; + case ESM::PRT_RPauldron: //23 + rclavicle = insertBoundedPart(mesh , "Right Clavicle"); + break; + case ESM::PRT_LPauldron: //24 + lclavicle = insertBoundedPart(mesh + "*|", "Left Clavicle"); + break; + case ESM::PRT_Weapon: //25 + break; + case ESM::PRT_Tail: //26 + tail = insertFreePart(mesh, ":*"); + break; + + + } + return true; + } + return false; + } } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 0b4442e3ac..e5858e38c0 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -78,6 +78,7 @@ private: void updateParts(); void removeIndividualPart(int type); void removePartGroup(int group); + bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh); }; } From 7551926afd698109527cd76888bbb8a8f567750e Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Fri, 13 Apr 2012 23:25:15 -0400 Subject: [PATCH 13/20] Adding helmets --- apps/openmw/mwrender/npcanimation.cpp | 56 +++++++++++++++++++-------- apps/openmw/mwrender/npcanimation.hpp | 1 + 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 37e3573f8a..34dbb08621 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -13,7 +13,7 @@ NpcAnimation::~NpcAnimation(){ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv), timeToChange(0), - robe(inv.getSlot(MWWorld::InventoryStore::Slot_Robe)), + robe(inv.getSlot(MWWorld::InventoryStore::Slot_Robe)), helmet(inv.getSlot(MWWorld::InventoryStore::Slot_Helmet)), lclavicle(0), rclavicle(0), rupperArm(0), @@ -160,13 +160,12 @@ void NpcAnimation::updateParts(){ std::string hairModel = "meshes\\" + mEnvironment.mWorld->getStore().bodyParts.find(hairID)->model; + + //inv.getSlot(MWWorld::InventoryStore::Slot_Robe); if(robe != inv.getSlot(MWWorld::InventoryStore::Slot_Robe)){ //A robe was added or removed - if(chest.first) - { - insert->detachObject(chest.first); chest.first = 0; - } + removePartGroup(MWWorld::InventoryStore::Slot_Robe); robe = inv.getSlot(MWWorld::InventoryStore::Slot_Robe); if(robe != inv.end()) { @@ -177,23 +176,47 @@ void NpcAnimation::updateParts(){ for(int i = 0; i < parts.size(); i++) { ESM::PartReference part = parts[i]; - if(part.part == ESM::PRT_Cuirass) - { + const ESM::BodyPart *bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.male); - chest = insertFreePart("meshes\\" + bodypart->model, ":\""); - } + if(bodypart) + addOrReplaceIndividualPart(part.part, MWWorld::InventoryStore::Slot_Robe,5,"meshes\\" + bodypart->model); + } } } - if(robe == inv.end() ){ - //if(inv.getSlot(MWWorld::InventoryStore::Cuirass) != inv.end()) - if(chest.first == 0){ - const ESM::BodyPart *chestPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest"); - chest = insertFreePart("meshes\\" + chestPart->model, ":\""); + if(helmet != inv.getSlot(MWWorld::InventoryStore::Slot_Helmet)){ + helmet = inv.getSlot(MWWorld::InventoryStore::Slot_Helmet); + removePartGroup(MWWorld::InventoryStore::Slot_Helmet); + removeIndividualPart(ESM::PRT_Hair); + if(helmet != inv.end()){ + const ESM::Armor *armor = (helmet->get())->base; + std::vector parts = armor->parts.parts; + for(int i = 0; i < parts.size(); i++) + { + ESM::PartReference part = parts[i]; + + const ESM::BodyPart *bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.male); + if(bodypart) + addOrReplaceIndividualPart(part.part, MWWorld::InventoryStore::Slot_Helmet,3,"meshes\\" + bodypart->model); + + } } - + } + + if(partpriorities[ESM::PRT_Cuirass] < 1){ + const ESM::BodyPart *chestPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest"); + if(chestPart) + addOrReplaceIndividualPart(ESM::PRT_Cuirass, -1,1,"meshes\\" + chestPart->model); + } + if(partpriorities[ESM::PRT_Head] < 1){ + addOrReplaceIndividualPart(ESM::PRT_Head, -1,1,headModel); + } + if(partpriorities[ESM::PRT_Hair] < 1 && partpriorities[ESM::PRT_Head] <= 1){ + addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1,hairModel); + } + @@ -418,9 +441,10 @@ void NpcAnimation::removeIndividualPart(int type){ } } bool NpcAnimation::addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh){ - if(priority >= partpriorities[type]){ + if(priority > partpriorities[type]){ removeIndividualPart(type); partslots[type] = group; + partpriorities[type] = priority; switch(type){ case ESM::PRT_Head: //0 head = insertBoundedPart(mesh, "Head"); diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index e5858e38c0..b3d9b3c4a2 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -68,6 +68,7 @@ private: std::string bodyRaceID; float timeToChange; MWWorld::ContainerStoreIterator robe; + MWWorld::ContainerStoreIterator helmet; public: NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); From 5d4ad4cd810501e09f2b6550fb4e28204ebe8223 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 14 Apr 2012 16:44:46 -0400 Subject: [PATCH 14/20] Shirts and Cuirasses --- apps/openmw/mwclass/clothing.cpp | 2 +- apps/openmw/mwrender/npcanimation.cpp | 68 ++++++++++++++++++++++----- apps/openmw/mwrender/npcanimation.hpp | 2 + 3 files changed, 60 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 1fbc11c631..672a2b60a0 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -89,7 +89,7 @@ namespace MWClass static const int sMapping[size][2] = { - { ESM::Clothing::Shirt, MWWorld::InventoryStore::Slot_Cuirass }, + { ESM::Clothing::Shirt, MWWorld::InventoryStore::Slot_Shirt }, { ESM::Clothing::Belt, MWWorld::InventoryStore::Slot_Belt }, { ESM::Clothing::Robe, MWWorld::InventoryStore::Slot_Robe }, { ESM::Clothing::Pants, MWWorld::InventoryStore::Slot_Pants }, diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 34dbb08621..08c53f39da 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -13,7 +13,8 @@ NpcAnimation::~NpcAnimation(){ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv), timeToChange(0), - robe(inv.getSlot(MWWorld::InventoryStore::Slot_Robe)), helmet(inv.getSlot(MWWorld::InventoryStore::Slot_Helmet)), + robe(inv.getSlot(MWWorld::InventoryStore::Slot_Robe)), helmet(inv.getSlot(MWWorld::InventoryStore::Slot_Helmet)), shirt(inv.getSlot(MWWorld::InventoryStore::Slot_Shirt)), + cuirass(inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass)), lclavicle(0), rclavicle(0), rupperArm(0), @@ -159,7 +160,7 @@ void NpcAnimation::updateParts(){ std::string hairModel = "meshes\\" + mEnvironment.mWorld->getStore().bodyParts.find(hairID)->model; - + bool apparelChanged = false; //inv.getSlot(MWWorld::InventoryStore::Slot_Robe); @@ -167,7 +168,31 @@ void NpcAnimation::updateParts(){ //A robe was added or removed removePartGroup(MWWorld::InventoryStore::Slot_Robe); robe = inv.getSlot(MWWorld::InventoryStore::Slot_Robe); - if(robe != inv.end()) + apparelChanged = true; + + + } + if(helmet != inv.getSlot(MWWorld::InventoryStore::Slot_Helmet)){ + apparelChanged = true; + helmet = inv.getSlot(MWWorld::InventoryStore::Slot_Helmet); + removePartGroup(MWWorld::InventoryStore::Slot_Helmet); + + } + if(cuirass != inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass)){ + cuirass = inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass); + removePartGroup(MWWorld::InventoryStore::Slot_Cuirass); + apparelChanged = true; + + } + if(shirt != inv.getSlot(MWWorld::InventoryStore::Slot_Shirt)){ + shirt = inv.getSlot(MWWorld::InventoryStore::Slot_Shirt); + removePartGroup(MWWorld::InventoryStore::Slot_Shirt); + apparelChanged = true; + + } + + if(apparelChanged){ + if(robe != inv.end()) { MWWorld::Ptr ptr = *robe; @@ -183,13 +208,9 @@ void NpcAnimation::updateParts(){ } } - - } - if(helmet != inv.getSlot(MWWorld::InventoryStore::Slot_Helmet)){ - helmet = inv.getSlot(MWWorld::InventoryStore::Slot_Helmet); - removePartGroup(MWWorld::InventoryStore::Slot_Helmet); - removeIndividualPart(ESM::PRT_Hair); - if(helmet != inv.end()){ + + if(helmet != inv.end()){ + removeIndividualPart(ESM::PRT_Hair); const ESM::Armor *armor = (helmet->get())->base; std::vector parts = armor->parts.parts; for(int i = 0; i < parts.size(); i++) @@ -202,7 +223,32 @@ void NpcAnimation::updateParts(){ } } - + if(cuirass != inv.end()){ + const ESM::Armor *armor = (cuirass->get())->base; + std::vector parts = armor->parts.parts; + for(int i = 0; i < parts.size(); i++) + { + ESM::PartReference part = parts[i]; + + const ESM::BodyPart *bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.male); + if(bodypart) + addOrReplaceIndividualPart(part.part, MWWorld::InventoryStore::Slot_Cuirass,3,"meshes\\" + bodypart->model); + + } + } + if(shirt != inv.end()){ + const ESM::Clothing *clothes = (shirt->get())->base; + std::vector parts = clothes->parts.parts; + for(int i = 0; i < parts.size(); i++) + { + ESM::PartReference part = parts[i]; + + const ESM::BodyPart *bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.male); + if(bodypart) + addOrReplaceIndividualPart(part.part, MWWorld::InventoryStore::Slot_Shirt,2,"meshes\\" + bodypart->model); + + } + } } if(partpriorities[ESM::PRT_Cuirass] < 1){ diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index b3d9b3c4a2..3775602226 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -69,6 +69,8 @@ private: float timeToChange; MWWorld::ContainerStoreIterator robe; MWWorld::ContainerStoreIterator helmet; + MWWorld::ContainerStoreIterator shirt; + MWWorld::ContainerStoreIterator cuirass; public: NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); From e5becb1f50dc79b14a5f587629516ee216ab6f95 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 14 Apr 2012 18:58:52 -0400 Subject: [PATCH 15/20] Group add function;Greaves --- apps/openmw/mwrender/npcanimation.cpp | 81 ++++++++++++++------------- apps/openmw/mwrender/npcanimation.hpp | 6 +- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 08c53f39da..bacee7f2db 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -14,7 +14,7 @@ NpcAnimation::~NpcAnimation(){ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv), timeToChange(0), robe(inv.getSlot(MWWorld::InventoryStore::Slot_Robe)), helmet(inv.getSlot(MWWorld::InventoryStore::Slot_Helmet)), shirt(inv.getSlot(MWWorld::InventoryStore::Slot_Shirt)), - cuirass(inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass)), + cuirass(inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass)), greaves(inv.getSlot(MWWorld::InventoryStore::Slot_Greaves)), lclavicle(0), rclavicle(0), rupperArm(0), @@ -79,7 +79,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); char secondtolast = bodyRaceID.at(bodyRaceID.length() - 2); - bool female = tolower(secondtolast) == 'f'; + isFemale = tolower(secondtolast) == 'f'; std::transform(bodyRaceID.begin(), bodyRaceID.end(), bodyRaceID.begin(), ::tolower); isBeast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_"; @@ -145,7 +145,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O insert->attachObject(base); - if(female) + if(isFemale) insert->scale(race->data.height.female, race->data.height.female, race->data.height.female); else insert->scale(race->data.height.male, race->data.height.male, race->data.height.male); @@ -183,6 +183,12 @@ void NpcAnimation::updateParts(){ removePartGroup(MWWorld::InventoryStore::Slot_Cuirass); apparelChanged = true; + } + if(greaves != inv.getSlot(MWWorld::InventoryStore::Slot_Greaves)){ + cuirass = inv.getSlot(MWWorld::InventoryStore::Slot_Greaves); + removePartGroup(MWWorld::InventoryStore::Slot_Greaves); + apparelChanged = true; + } if(shirt != inv.getSlot(MWWorld::InventoryStore::Slot_Shirt)){ shirt = inv.getSlot(MWWorld::InventoryStore::Slot_Shirt); @@ -198,56 +204,32 @@ void NpcAnimation::updateParts(){ const ESM::Clothing *clothes = (ptr.get())->base; std::vector parts = clothes->parts.parts; - for(int i = 0; i < parts.size(); i++) - { - ESM::PartReference part = parts[i]; - - const ESM::BodyPart *bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.male); - if(bodypart) - addOrReplaceIndividualPart(part.part, MWWorld::InventoryStore::Slot_Robe,5,"meshes\\" + bodypart->model); - - } + addPartGroup(MWWorld::InventoryStore::Slot_Robe, 5, parts); } if(helmet != inv.end()){ removeIndividualPart(ESM::PRT_Hair); const ESM::Armor *armor = (helmet->get())->base; std::vector parts = armor->parts.parts; - for(int i = 0; i < parts.size(); i++) - { - ESM::PartReference part = parts[i]; - - const ESM::BodyPart *bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.male); - if(bodypart) - addOrReplaceIndividualPart(part.part, MWWorld::InventoryStore::Slot_Helmet,3,"meshes\\" + bodypart->model); - - } + addPartGroup(MWWorld::InventoryStore::Slot_Helmet, 3, parts); + } if(cuirass != inv.end()){ const ESM::Armor *armor = (cuirass->get())->base; std::vector parts = armor->parts.parts; - for(int i = 0; i < parts.size(); i++) - { - ESM::PartReference part = parts[i]; - - const ESM::BodyPart *bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.male); - if(bodypart) - addOrReplaceIndividualPart(part.part, MWWorld::InventoryStore::Slot_Cuirass,3,"meshes\\" + bodypart->model); - - } + addPartGroup(MWWorld::InventoryStore::Slot_Cuirass, 3, parts); + + } + if(greaves != inv.end()){ + const ESM::Armor *armor = (greaves->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Greaves, 3, parts); + } if(shirt != inv.end()){ const ESM::Clothing *clothes = (shirt->get())->base; std::vector parts = clothes->parts.parts; - for(int i = 0; i < parts.size(); i++) - { - ESM::PartReference part = parts[i]; - - const ESM::BodyPart *bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.male); - if(bodypart) - addOrReplaceIndividualPart(part.part, MWWorld::InventoryStore::Slot_Shirt,2,"meshes\\" + bodypart->model); - - } + addPartGroup(MWWorld::InventoryStore::Slot_Shirt, 2, parts); } } @@ -299,6 +281,8 @@ std::pair*> NpcAnimation::insert } + + void NpcAnimation::runAnimation(float timepassed){ if(timeToChange > .2){ @@ -585,6 +569,25 @@ void NpcAnimation::removeIndividualPart(int type){ } return false; } + + void NpcAnimation::addPartGroup(int group, int priority, std::vector& parts){ + for(int i = 0; i < parts.size(); i++) + { + ESM::PartReference part = parts[i]; + + + const ESM::BodyPart *bodypart = 0; + + if(isFemale) + bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.female); + if(!bodypart) + bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.male); + + if(bodypart) + addOrReplaceIndividualPart(part.part, group,priority,"meshes\\" + bodypart->model); + + } + } } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 3775602226..545634e1fe 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -62,6 +62,7 @@ private: Ogre::SceneNode* insert; bool isBeast; + bool isFemale; std::string headID; std::string hairID; std::string npcName; @@ -71,6 +72,7 @@ private: MWWorld::ContainerStoreIterator helmet; MWWorld::ContainerStoreIterator shirt; MWWorld::ContainerStoreIterator cuirass; + MWWorld::ContainerStoreIterator greaves; public: NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); @@ -80,8 +82,10 @@ private: virtual void runAnimation(float timepassed); void updateParts(); void removeIndividualPart(int type); - void removePartGroup(int group); + bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh); + void removePartGroup(int group); + void addPartGroup(int group, int priority, std::vector& parts); }; } From 940a90e3baac2f924bcd1fba0de672c9b74a2717 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 14 Apr 2012 19:21:14 -0400 Subject: [PATCH 16/20] Pauldrons --- apps/openmw/mwrender/npcanimation.cpp | 26 +++++++++++++++++++++++++- apps/openmw/mwrender/npcanimation.hpp | 2 ++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index bacee7f2db..5adb9914dd 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -15,6 +15,7 @@ NpcAnimation::~NpcAnimation(){ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv), timeToChange(0), robe(inv.getSlot(MWWorld::InventoryStore::Slot_Robe)), helmet(inv.getSlot(MWWorld::InventoryStore::Slot_Helmet)), shirt(inv.getSlot(MWWorld::InventoryStore::Slot_Shirt)), cuirass(inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass)), greaves(inv.getSlot(MWWorld::InventoryStore::Slot_Greaves)), + leftpauldron(inv.getSlot(MWWorld::InventoryStore::Slot_LeftPauldron)), rightpauldron(inv.getSlot(MWWorld::InventoryStore::Slot_RightPauldron)), lclavicle(0), rclavicle(0), rupperArm(0), @@ -185,9 +186,20 @@ void NpcAnimation::updateParts(){ } if(greaves != inv.getSlot(MWWorld::InventoryStore::Slot_Greaves)){ - cuirass = inv.getSlot(MWWorld::InventoryStore::Slot_Greaves); + greaves = inv.getSlot(MWWorld::InventoryStore::Slot_Greaves); removePartGroup(MWWorld::InventoryStore::Slot_Greaves); apparelChanged = true; + } + if(leftpauldron != inv.getSlot(MWWorld::InventoryStore::Slot_LeftPauldron)){ + leftpauldron = inv.getSlot(MWWorld::InventoryStore::Slot_LeftPauldron); + removePartGroup(MWWorld::InventoryStore::Slot_LeftPauldron); + apparelChanged = true; + + } + if(rightpauldron != inv.getSlot(MWWorld::InventoryStore::Slot_RightPauldron)){ + leftpauldron = inv.getSlot(MWWorld::InventoryStore::Slot_RightPauldron); + removePartGroup(MWWorld::InventoryStore::Slot_RightPauldron); + apparelChanged = true; } if(shirt != inv.getSlot(MWWorld::InventoryStore::Slot_Shirt)){ @@ -225,6 +237,18 @@ void NpcAnimation::updateParts(){ std::vector parts = armor->parts.parts; addPartGroup(MWWorld::InventoryStore::Slot_Greaves, 3, parts); + } + if(leftpauldron != inv.end()){ + const ESM::Armor *armor = (leftpauldron->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_LeftPauldron, 3, parts); + + } + if(rightpauldron != inv.end()){ + const ESM::Armor *armor = (rightpauldron->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_RightPauldron, 3, parts); + } if(shirt != inv.end()){ const ESM::Clothing *clothes = (shirt->get())->base; diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 545634e1fe..7785ffc1a0 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -73,6 +73,8 @@ private: MWWorld::ContainerStoreIterator shirt; MWWorld::ContainerStoreIterator cuirass; MWWorld::ContainerStoreIterator greaves; + MWWorld::ContainerStoreIterator leftpauldron; + MWWorld::ContainerStoreIterator rightpauldron; public: NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); From 5e1ac0cca1c8a20095da079065b2fad0aa443fbe Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 14 Apr 2012 20:32:46 -0400 Subject: [PATCH 17/20] Gloves, Gauntlets, Boots, Shoes --- apps/openmw/mwrender/npcanimation.cpp | 71 ++++++++++++++++++++++++++- apps/openmw/mwrender/npcanimation.hpp | 4 ++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 5adb9914dd..3a9525949c 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -16,6 +16,9 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O robe(inv.getSlot(MWWorld::InventoryStore::Slot_Robe)), helmet(inv.getSlot(MWWorld::InventoryStore::Slot_Helmet)), shirt(inv.getSlot(MWWorld::InventoryStore::Slot_Shirt)), cuirass(inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass)), greaves(inv.getSlot(MWWorld::InventoryStore::Slot_Greaves)), leftpauldron(inv.getSlot(MWWorld::InventoryStore::Slot_LeftPauldron)), rightpauldron(inv.getSlot(MWWorld::InventoryStore::Slot_RightPauldron)), + boots(inv.getSlot(MWWorld::InventoryStore::Slot_Boots)), + leftglove(inv.getSlot(MWWorld::InventoryStore::Slot_LeftGauntlet)), rightglove(inv.getSlot(MWWorld::InventoryStore::Slot_RightGauntlet)), + pants(inv.getSlot(MWWorld::InventoryStore::Slot_Pants)), lclavicle(0), rclavicle(0), rupperArm(0), @@ -197,10 +200,28 @@ void NpcAnimation::updateParts(){ } if(rightpauldron != inv.getSlot(MWWorld::InventoryStore::Slot_RightPauldron)){ - leftpauldron = inv.getSlot(MWWorld::InventoryStore::Slot_RightPauldron); + rightpauldron = inv.getSlot(MWWorld::InventoryStore::Slot_RightPauldron); removePartGroup(MWWorld::InventoryStore::Slot_RightPauldron); apparelChanged = true; + } + if(boots != inv.getSlot(MWWorld::InventoryStore::Slot_Boots)){ + boots = inv.getSlot(MWWorld::InventoryStore::Slot_Boots); + removePartGroup(MWWorld::InventoryStore::Slot_Boots); + apparelChanged = true; + + } + if(leftglove != inv.getSlot(MWWorld::InventoryStore::Slot_LeftGauntlet)){ + leftglove = inv.getSlot(MWWorld::InventoryStore::Slot_LeftGauntlet); + removePartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet); + apparelChanged = true; + + } + if(rightglove != inv.getSlot(MWWorld::InventoryStore::Slot_RightGauntlet)){ + rightglove = inv.getSlot(MWWorld::InventoryStore::Slot_RightGauntlet); + removePartGroup(MWWorld::InventoryStore::Slot_RightGauntlet); + apparelChanged = true; + } if(shirt != inv.getSlot(MWWorld::InventoryStore::Slot_Shirt)){ shirt = inv.getSlot(MWWorld::InventoryStore::Slot_Shirt); @@ -210,6 +231,7 @@ void NpcAnimation::updateParts(){ } if(apparelChanged){ + std::cout << "Modifying stuff\n"; if(robe != inv.end()) { MWWorld::Ptr ptr = *robe; @@ -238,6 +260,7 @@ void NpcAnimation::updateParts(){ addPartGroup(MWWorld::InventoryStore::Slot_Greaves, 3, parts); } + if(leftpauldron != inv.end()){ const ESM::Armor *armor = (leftpauldron->get())->base; std::vector parts = armor->parts.parts; @@ -250,6 +273,52 @@ void NpcAnimation::updateParts(){ addPartGroup(MWWorld::InventoryStore::Slot_RightPauldron, 3, parts); } + if(boots != inv.end()){ + + if(boots->getTypeName() == "struct ESM::Clothing"){ + const ESM::Clothing *clothes = (boots->get())->base; + std::vector parts = clothes->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Boots, 2, parts); + } + else + { + const ESM::Armor *armor = (boots->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Boots, 3, parts); + } + + } + if(leftglove != inv.end()){ + + if(leftglove->getTypeName() == "struct ESM::Clothing"){ + const ESM::Clothing *clothes = (leftglove->get())->base; + std::vector parts = clothes->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet, 2, parts); + } + else + { + const ESM::Armor *armor = (leftglove->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet, 3, parts); + } + + } + if(rightglove != inv.end()){ + + if(rightglove->getTypeName() == "struct ESM::Clothing"){ + const ESM::Clothing *clothes = (rightglove->get())->base; + std::vector parts = clothes->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_RightGauntlet, 2, parts); + } + else + { + const ESM::Armor *armor = (rightglove->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_RightGauntlet, 3, parts); + } + + } + if(shirt != inv.end()){ const ESM::Clothing *clothes = (shirt->get())->base; std::vector parts = clothes->parts.parts; diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 7785ffc1a0..255989d286 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -75,6 +75,10 @@ private: MWWorld::ContainerStoreIterator greaves; MWWorld::ContainerStoreIterator leftpauldron; MWWorld::ContainerStoreIterator rightpauldron; + MWWorld::ContainerStoreIterator boots; + MWWorld::ContainerStoreIterator pants; + MWWorld::ContainerStoreIterator leftglove; + MWWorld::ContainerStoreIterator rightglove; public: NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); From 85ac658cacb03ef53455e57ea7b97f41bbab5c36 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 14 Apr 2012 22:52:05 -0400 Subject: [PATCH 18/20] Adding tons of skin body parts --- apps/openmw/mwrender/npcanimation.cpp | 135 ++++++++++++++++++++++++-- 1 file changed, 129 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 3a9525949c..bc134581d8 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -205,7 +205,7 @@ void NpcAnimation::updateParts(){ apparelChanged = true; } - if(boots != inv.getSlot(MWWorld::InventoryStore::Slot_Boots)){ + if(!isBeast && boots != inv.getSlot(MWWorld::InventoryStore::Slot_Boots)){ boots = inv.getSlot(MWWorld::InventoryStore::Slot_Boots); removePartGroup(MWWorld::InventoryStore::Slot_Boots); apparelChanged = true; @@ -228,6 +228,12 @@ void NpcAnimation::updateParts(){ removePartGroup(MWWorld::InventoryStore::Slot_Shirt); apparelChanged = true; + } + if(pants != inv.getSlot(MWWorld::InventoryStore::Slot_Pants)){ + pants = inv.getSlot(MWWorld::InventoryStore::Slot_Pants); + removePartGroup(MWWorld::InventoryStore::Slot_Pants); + apparelChanged = true; + } if(apparelChanged){ @@ -273,7 +279,7 @@ void NpcAnimation::updateParts(){ addPartGroup(MWWorld::InventoryStore::Slot_RightPauldron, 3, parts); } - if(boots != inv.end()){ + if(!isBeast && boots != inv.end()){ if(boots->getTypeName() == "struct ESM::Clothing"){ const ESM::Clothing *clothes = (boots->get())->base; @@ -324,19 +330,136 @@ void NpcAnimation::updateParts(){ std::vector parts = clothes->parts.parts; addPartGroup(MWWorld::InventoryStore::Slot_Shirt, 2, parts); } + if(pants != inv.end()){ + const ESM::Clothing *clothes = (pants->get())->base; + std::vector parts = clothes->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Pants, 2, parts); + } } + if(partpriorities[ESM::PRT_Head] < 1){ + addOrReplaceIndividualPart(ESM::PRT_Head, -1,1,headModel); + } + if(partpriorities[ESM::PRT_Hair] < 1 && partpriorities[ESM::PRT_Head] <= 1){ + addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1,hairModel); + } + if(partpriorities[ESM::PRT_Neck] < 1){ + const ESM::BodyPart *neckPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "neck"); + if(neckPart) + addOrReplaceIndividualPart(ESM::PRT_Neck, -1,1,"meshes\\" + neckPart->model); + } if(partpriorities[ESM::PRT_Cuirass] < 1){ const ESM::BodyPart *chestPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest"); if(chestPart) addOrReplaceIndividualPart(ESM::PRT_Cuirass, -1,1,"meshes\\" + chestPart->model); } - if(partpriorities[ESM::PRT_Head] < 1){ - addOrReplaceIndividualPart(ESM::PRT_Head, -1,1,headModel); + + if(partpriorities[ESM::PRT_Groin] < 1){ + const ESM::BodyPart *groinPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "groin"); + if(groinPart) + addOrReplaceIndividualPart(ESM::PRT_Groin, -1,1,"meshes\\" + groinPart->model); } - if(partpriorities[ESM::PRT_Hair] < 1 && partpriorities[ESM::PRT_Head] <= 1){ - addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1,hairModel); + if(partpriorities[ESM::PRT_RHand] < 1){ + const ESM::BodyPart *handPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand"); + if(!handPart) + handPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands"); + if(handPart) + addOrReplaceIndividualPart(ESM::PRT_RHand, -1,1,"meshes\\" + handPart->model); + } + if(partpriorities[ESM::PRT_LHand] < 1){ + const ESM::BodyPart *handPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand"); + if(!handPart) + handPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands"); + if(handPart) + addOrReplaceIndividualPart(ESM::PRT_LHand, -1,1,"meshes\\" + handPart->model); } + + if(partpriorities[ESM::PRT_RWrist] < 1){ + const ESM::BodyPart *wristPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); + if(wristPart) + addOrReplaceIndividualPart(ESM::PRT_RWrist, -1,1,"meshes\\" + wristPart->model); + } + if(partpriorities[ESM::PRT_LWrist] < 1){ + const ESM::BodyPart *wristPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); + if(wristPart) + addOrReplaceIndividualPart(ESM::PRT_LWrist, -1,1,"meshes\\" + wristPart->model); + } + if(partpriorities[ESM::PRT_RForearm] < 1){ + const ESM::BodyPart *forearmPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); + if(bodyRaceID == "b_n_argonian_f_") + forearmPart = mEnvironment.mWorld->getStore().bodyParts.search ("b_n_argonian_m_forearm"); + if(forearmPart) + addOrReplaceIndividualPart(ESM::PRT_RForearm, -1,1,"meshes\\" + forearmPart->model); + } + if(partpriorities[ESM::PRT_LForearm] < 1){ + const ESM::BodyPart *forearmPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); + if(bodyRaceID == "b_n_argonian_f_") + forearmPart = mEnvironment.mWorld->getStore().bodyParts.search ("b_n_argonian_m_forearm"); + if(forearmPart) + addOrReplaceIndividualPart(ESM::PRT_LForearm, -1,1,"meshes\\" + forearmPart->model); + } + if(partpriorities[ESM::PRT_RUpperarm] < 1){ + const ESM::BodyPart *armPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper arm"); + if(armPart) + addOrReplaceIndividualPart(ESM::PRT_RUpperarm, -1,1,"meshes\\" + armPart->model); + } + if(partpriorities[ESM::PRT_LUpperarm] < 1){ + const ESM::BodyPart *armPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper arm"); + if(armPart) + addOrReplaceIndividualPart(ESM::PRT_LUpperarm, -1,1,"meshes\\" + armPart->model); + } + if(partpriorities[ESM::PRT_RFoot] < 1){ + const ESM::BodyPart *footPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "foot"); + if(isBeast) + footPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "feet"); + if(footPart) + addOrReplaceIndividualPart(ESM::PRT_RFoot, -1,1,"meshes\\" + footPart->model); + } + if(partpriorities[ESM::PRT_LFoot] < 1){ + const ESM::BodyPart *footPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "foot"); + if(isBeast) + footPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "feet"); + if(footPart) + addOrReplaceIndividualPart(ESM::PRT_LFoot, -1,1,"meshes\\" + footPart->model); + } + if(partpriorities[ESM::PRT_RAnkle] < 1){ + const ESM::BodyPart *anklePart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "ankle"); + if(anklePart) + addOrReplaceIndividualPart(ESM::PRT_RAnkle, -1,1,"meshes\\" + anklePart->model); + } + if(partpriorities[ESM::PRT_LAnkle] < 1){ + const ESM::BodyPart *anklePart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "ankle"); + if(anklePart) + addOrReplaceIndividualPart(ESM::PRT_LAnkle, -1,1,"meshes\\" + anklePart->model); + } + if(partpriorities[ESM::PRT_RKnee] < 1){ + const ESM::BodyPart *kneePart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "knee"); + if(kneePart) + addOrReplaceIndividualPart(ESM::PRT_RKnee, -1,1,"meshes\\" + kneePart->model); + } + if(partpriorities[ESM::PRT_LKnee] < 1){ + const ESM::BodyPart *kneePart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "knee"); + if(kneePart) + addOrReplaceIndividualPart(ESM::PRT_LKnee, -1,1,"meshes\\" + kneePart->model); + } + if(partpriorities[ESM::PRT_RLeg] < 1){ + const ESM::BodyPart *legPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper leg"); + if(legPart) + addOrReplaceIndividualPart(ESM::PRT_RLeg, -1,1,"meshes\\" + legPart->model); + } + if(partpriorities[ESM::PRT_LLeg] < 1){ + const ESM::BodyPart *legPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper leg"); + if(legPart) + addOrReplaceIndividualPart(ESM::PRT_LLeg, -1,1,"meshes\\" + legPart->model); + } + if(partpriorities[ESM::PRT_Tail] < 1){ + const ESM::BodyPart *tailPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "tail"); + if(tailPart) + addOrReplaceIndividualPart(ESM::PRT_Tail, -1,1,"meshes\\" + tailPart->model); + } + + + From bc8bb9c57ead538e4568f629b68b40863804c0be Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 15 Apr 2012 14:22:55 -0400 Subject: [PATCH 19/20] Reserve; skirts --- apps/openmw/mwrender/animation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index d0019154e8..5755418e2d 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -303,8 +303,8 @@ namespace MWRender{ for(; boneSequenceIter != boneSequence.end(); boneSequenceIter++) { - if(creaturemodel->getSkeleton()->hasBone(*boneSequenceIter)){ - Ogre::Bone *bonePtr = creaturemodel->getSkeleton()->getBone(*boneSequenceIter); + if(skel->hasBone(*boneSequenceIter)){ + Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter); // Computes C = B + AxC*scale transmult = transmult + rotmult * bonePtr->getPosition(); rotmult = rotmult * bonePtr->getOrientation(); From 65c9cf565c70c4c49cbe484df96811c6e214fb28 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 15 Apr 2012 15:16:48 -0400 Subject: [PATCH 20/20] Skirt and robe part blanking --- apps/openmw/mwrender/npcanimation.cpp | 78 +++++++++++++++++++-------- apps/openmw/mwrender/npcanimation.hpp | 7 ++- 2 files changed, 61 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index bc134581d8..2f87635494 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -13,12 +13,12 @@ NpcAnimation::~NpcAnimation(){ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv), timeToChange(0), - robe(inv.getSlot(MWWorld::InventoryStore::Slot_Robe)), helmet(inv.getSlot(MWWorld::InventoryStore::Slot_Helmet)), shirt(inv.getSlot(MWWorld::InventoryStore::Slot_Shirt)), - cuirass(inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass)), greaves(inv.getSlot(MWWorld::InventoryStore::Slot_Greaves)), - leftpauldron(inv.getSlot(MWWorld::InventoryStore::Slot_LeftPauldron)), rightpauldron(inv.getSlot(MWWorld::InventoryStore::Slot_RightPauldron)), - boots(inv.getSlot(MWWorld::InventoryStore::Slot_Boots)), - leftglove(inv.getSlot(MWWorld::InventoryStore::Slot_LeftGauntlet)), rightglove(inv.getSlot(MWWorld::InventoryStore::Slot_RightGauntlet)), - pants(inv.getSlot(MWWorld::InventoryStore::Slot_Pants)), + robe(inv.end()), helmet(inv.end()), shirt(inv.end()), + cuirass(inv.end()), greaves(inv.end()), + leftpauldron(inv.end()), rightpauldron(inv.end()), + boots(inv.end()), + leftglove(inv.end()), rightglove(inv.end()), skirtiter(inv.end()), + pants(inv.end()), lclavicle(0), rclavicle(0), rupperArm(0), @@ -74,8 +74,13 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O // vector = Ogre::Vector3(1,1,-1); - hairID = ref->base->hair; - headID = ref->base->head; + std::string hairID = ref->base->hair; + std::string headID = ref->base->head; + headModel = "meshes\\" + + mEnvironment.mWorld->getStore().bodyParts.find(headID)->model; + + hairModel = "meshes\\" + + mEnvironment.mWorld->getStore().bodyParts.find(hairID)->model; npcName = ref->base->name; //ESMStore::Races r = const ESM::Race* race = mEnvironment.mWorld->getStore().races.find(ref->base->race); @@ -159,11 +164,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O } void NpcAnimation::updateParts(){ - std::string headModel = "meshes\\" + - mEnvironment.mWorld->getStore().bodyParts.find(headID)->model; - - std::string hairModel = "meshes\\" + - mEnvironment.mWorld->getStore().bodyParts.find(hairID)->model; + bool apparelChanged = false; @@ -173,8 +174,12 @@ void NpcAnimation::updateParts(){ removePartGroup(MWWorld::InventoryStore::Slot_Robe); robe = inv.getSlot(MWWorld::InventoryStore::Slot_Robe); apparelChanged = true; - - + } + if(skirtiter != inv.getSlot(MWWorld::InventoryStore::Slot_Skirt)){ + //A robe was added or removed + removePartGroup(MWWorld::InventoryStore::Slot_Skirt); + skirtiter = inv.getSlot(MWWorld::InventoryStore::Slot_Skirt); + apparelChanged = true; } if(helmet != inv.getSlot(MWWorld::InventoryStore::Slot_Helmet)){ apparelChanged = true; @@ -237,7 +242,6 @@ void NpcAnimation::updateParts(){ } if(apparelChanged){ - std::cout << "Modifying stuff\n"; if(robe != inv.end()) { MWWorld::Ptr ptr = *robe; @@ -245,6 +249,29 @@ void NpcAnimation::updateParts(){ const ESM::Clothing *clothes = (ptr.get())->base; std::vector parts = clothes->parts.parts; addPartGroup(MWWorld::InventoryStore::Slot_Robe, 5, parts); + reserveIndividualPart(ESM::PRT_Groin, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_Skirt, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_RLeg, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_LLeg, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_RUpperarm, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_LUpperarm, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_RKnee, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_LKnee, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_RForearm, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_LForearm, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_RPauldron, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_LPauldron, MWWorld::InventoryStore::Slot_Robe, 5); + } + if(skirtiter != inv.end()) + { + MWWorld::Ptr ptr = *skirtiter; + + const ESM::Clothing *clothes = (ptr.get())->base; + std::vector parts = clothes->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Skirt, 4, parts); + reserveIndividualPart(ESM::PRT_Groin, MWWorld::InventoryStore::Slot_Skirt, 4); + reserveIndividualPart(ESM::PRT_RLeg, MWWorld::InventoryStore::Slot_Skirt, 4); + reserveIndividualPart(ESM::PRT_LLeg, MWWorld::InventoryStore::Slot_Skirt, 4); } if(helmet != inv.end()){ @@ -489,7 +516,6 @@ std::pair*> NpcAnimation::insert std::vector* shape = ((NIFLoader::getSingletonPtr())->getShapes(mesh + "0000" + suffix)); if(shape){ - handleShapes(shape, part, base->getSkeleton()); } std::pair*> pair = std::make_pair(part, shape); @@ -541,8 +567,9 @@ void NpcAnimation::runAnimation(float timepassed){ handleShapes(chest.second, chest.first, base->getSkeleton()); if(tail.first) handleShapes(tail.second, tail.first, base->getSkeleton()); - if(skirt.first) + if(skirt.first){ handleShapes(skirt.second, skirt.first, base->getSkeleton()); + } if(lhand.first) handleShapes(lhand.second, lhand.first, base->getSkeleton()); if(rhand.first) @@ -677,6 +704,14 @@ void NpcAnimation::removeIndividualPart(int type){ + } + + void NpcAnimation::reserveIndividualPart(int type, int group, int priority){ + if(priority > partpriorities[type]){ + removeIndividualPart(type); + partpriorities[type] = priority; + partslots[type] = group; + } } void NpcAnimation::removePartGroup(int group){ @@ -705,7 +740,7 @@ void NpcAnimation::removeIndividualPart(int type){ chest = insertFreePart(mesh, ":\""); break; case ESM::PRT_Groin: //4 - neck = insertBoundedPart(mesh, "Groin"); + groin = insertBoundedPart(mesh, "Groin"); break; case ESM::PRT_Skirt: //5 skirt = insertFreePart(mesh, ":|"); @@ -791,16 +826,15 @@ void NpcAnimation::removeIndividualPart(int type){ { ESM::PartReference part = parts[i]; - const ESM::BodyPart *bodypart = 0; - if(isFemale) bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.female); if(!bodypart) bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.male); - if(bodypart) addOrReplaceIndividualPart(part.part, group,priority,"meshes\\" + bodypart->model); + else + reserveIndividualPart(part.part, group, priority); } } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 255989d286..c7c22ad550 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -63,8 +63,8 @@ private: Ogre::SceneNode* insert; bool isBeast; bool isFemale; - std::string headID; - std::string hairID; + std::string headModel; + std::string hairModel; std::string npcName; std::string bodyRaceID; float timeToChange; @@ -79,6 +79,7 @@ private: MWWorld::ContainerStoreIterator pants; MWWorld::ContainerStoreIterator leftglove; MWWorld::ContainerStoreIterator rightglove; + MWWorld::ContainerStoreIterator skirtiter; public: NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); @@ -88,10 +89,12 @@ private: virtual void runAnimation(float timepassed); void updateParts(); void removeIndividualPart(int type); + void reserveIndividualPart(int type, int group, int priority); bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh); void removePartGroup(int group); void addPartGroup(int group, int priority, std::vector& parts); + }; }