From 6d346933db21946c68ab96b1105b1ea6f61f9b8e Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 10 Mar 2012 17:45:34 -0500 Subject: [PATCH 01/74] 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 059b0ec1e..90afc4e78 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 7a719252b..9353f7cd1 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/74] 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 bb2f9f8a9..11a43c7d3 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 78cbde083..4fc8bee36 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 6baec8c83..49e12064e 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 f9bb19fcdc8111ab405cbc8673dbf9c5800b1986 Mon Sep 17 00:00:00 2001 From: gugus Date: Fri, 23 Mar 2012 15:18:09 +0100 Subject: [PATCH 03/74] begining factions --- apps/openmw/mwworld/player.cpp | 53 ++++++++++++++++++++++++++++++++++ apps/openmw/mwworld/player.hpp | 21 ++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 5bfb82138..270ffa55c 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -89,4 +89,57 @@ namespace MWWorld MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Run, !running); } + + Player::Faction Player::getFaction(std::string faction) + { + for(std::list::iterator it = mFactions.begin(); it != mFactions.end();it++) + { + if(it->name == faction) return *it; + } + //faction was not found->dummy faction + Player::Faction fact; + fact.id = "not found"; + fact.name = "not found"; + fact.rank = -10; + fact.expelled = false; + return fact; + } + + void Player::addFaction(std::string faction) + { + if(getFaction(faction).name == "not found") + { + Player::Faction fact; + const ESM::Faction* eFact = mWorld.getStore().factions.find(faction); + fact.expelled = false; + fact.rank = 0; + fact.name = faction; + fact.id = eFact->id; + mFactions.push_back(fact); + } + } + + int Player::getRank(std::string faction) + { + Player::Faction fact = getFaction(faction); + return fact.rank; + } + + void Player::setRank(std::string faction,int rank) + { + Player::Faction fact = getFaction(faction); + fact.rank = rank; + } + + bool Player::isExpelled(std::string faction) + { + Player::Faction fact = getFaction(faction); + return fact.expelled; + } + + void Player::setExpelled(std::string faction,bool expelled) + { + Player::Faction fact = getFaction(faction); + fact.expelled = expelled; + } } diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index 01c71da43..8129c4d8e 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -4,6 +4,7 @@ #include "OgreCamera.h" #include +#include #include "../mwworld/refdata.hpp" #include "../mwworld/ptr.hpp" @@ -20,6 +21,13 @@ namespace MWWorld /// \brief NPC object representing the player and additional player data class Player { + struct Faction + { + std::string id,name; + int rank; + bool expelled; + }; + ESMS::LiveCellRef mPlayer; MWWorld::Ptr::CellStore *mCellStore; MWRender::Player *mRenderer; @@ -29,9 +37,12 @@ namespace MWWorld std::string mRace; std::string mBirthsign; ESM::Class *mClass; + std::list mFactions; bool mAutoMove; int mForwardBackward; + Faction getFaction(std::string faction); + public: Player(MWRender::Player *renderer, const ESM::NPC *player, MWWorld::World& world); @@ -108,6 +119,16 @@ namespace MWWorld void setAutoMove (bool enable); + void addFaction(std::string faction); + + int getRank(std::string faction); + + void setRank(std::string faction,int rank); + + bool isExpelled(std::string faction); + + void setExpelled(std::string faction,bool expelled); + void setLeftRight (int value); void setForwardBackward (int value); From 0c61f0d2942036d52a5703f9c17c968484d08dca Mon Sep 17 00:00:00 2001 From: gugus Date: Wed, 28 Mar 2012 11:45:46 +0200 Subject: [PATCH 04/74] test stuff --- apps/openmw/mwscript/docs/vmformat.txt | 3 +- apps/openmw/mwscript/statsextensions.cpp | 39 +++++++++++++++++ apps/openmw/mwworld/player.cpp | 53 +++++++++++++++++------- apps/openmw/mwworld/player.hpp | 14 ++++--- 4 files changed, 89 insertions(+), 20 deletions(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index eab5bf846..713ac43b0 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -123,4 +123,5 @@ op 0x200013d: FadeOut op 0x200013e: FadeTo op 0x200013f: GetCurrentWeather op 0x2000140: ChangeWeather -opcodes 0x2000141-0x3ffffff unused +op 0x2000141: OpPCJoinFaction +opcodes 0x2000142-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 0e97a39cf..85ac54348 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -8,6 +8,8 @@ #include #include "../mwworld/class.hpp" +#include "../mwworld/environment.hpp" +#include "../mwworld/player.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" @@ -280,6 +282,36 @@ namespace MWScript } }; + class OpPCJoinFaction : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string factionID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + context.getEnvironment().mWorld->getPlayer().addFaction(factionID); + } + }; + + class OpPCRaiseRank : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string factionID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + context.getEnvironment().mWorld->getPlayer().raiseRank(factionID); + } + }; + const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; @@ -310,6 +342,8 @@ namespace MWScript const int opcodeSetSkillExplicit = 0x20000df; const int opcodeModSkill = 0x20000fa; const int opcodeModSkillExplicit = 0x2000115; + const int opcodePCJoinFaction = 0x2000141; + const int opcodePCRaiseRank = 0x2000142; void registerExtensions (Compiler::Extensions& extensions) { @@ -381,6 +415,8 @@ namespace MWScript extensions.registerInstruction (mod + skills[i], "l", opcodeModSkill+i, opcodeModSkillExplicit+i); } + extensions.registerInstruction("PCJoinFaction","S",opcodePCJoinFaction); + extensions.registerInstruction("PCRaiseRank","S",opcodePCRaiseRank); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -436,6 +472,9 @@ namespace MWScript interpreter.installSegment5 (opcodeModSkill+i, new OpModSkill (i)); interpreter.installSegment5 (opcodeModSkillExplicit+i, new OpModSkill (i)); } + + interpreter.installSegment5(opcodePCJoinFaction,new OpPCJoinFaction); + interpreter.installSegment5(opcodePCRaiseRank,new OpPCRaiseRank); } } } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 270ffa55c..518b1d519 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -90,11 +90,11 @@ namespace MWWorld MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Run, !running); } - Player::Faction Player::getFaction(std::string faction) + Player::Faction Player::getFaction(std::string factionID) { for(std::list::iterator it = mFactions.begin(); it != mFactions.end();it++) { - if(it->name == faction) return *it; + if(it->name == factionID) return *it; } //faction was not found->dummy faction Player::Faction fact; @@ -105,41 +105,66 @@ namespace MWWorld return fact; } - void Player::addFaction(std::string faction) + void Player::addFaction(std::string factionID) { - if(getFaction(faction).name == "not found") + if(getFaction(factionID).name == "not found") { Player::Faction fact; - const ESM::Faction* eFact = mWorld.getStore().factions.find(faction); + const ESM::Faction* eFact = mWorld.getStore().factions.find(factionID); fact.expelled = false; fact.rank = 0; - fact.name = faction; + fact.name = eFact->name; fact.id = eFact->id; mFactions.push_back(fact); } } - int Player::getRank(std::string faction) + int Player::getRank(std::string factionID) { - Player::Faction fact = getFaction(faction); + Player::Faction fact = getFaction(factionID); return fact.rank; } - void Player::setRank(std::string faction,int rank) + void Player::setRank(std::string factionID,int rank) { - Player::Faction fact = getFaction(faction); + Player::Faction fact = getFaction(factionID); fact.rank = rank; } - bool Player::isExpelled(std::string faction) + void Player::raiseRank(std::string factionID) { - Player::Faction fact = getFaction(faction); + if(getFaction(factionID).name == "not found") + { + addFaction(factionID); + setRank(factionID,1); + } + else + { + setRank(factionID,getRank(factionID) + 1); + } + } + + void Player::lowerRank(std::string factionID) + { + if(getFaction(factionID).name == "not found") + { + std::cout << "cannot lower the rank of the player: faction no found. Faction: "<< factionID << std::endl; + } + else + { + setRank(factionID,getRank(factionID) - 1); + } + } + + bool Player::isExpelled(std::string factionID) + { + Player::Faction fact = getFaction(factionID); return fact.expelled; } - void Player::setExpelled(std::string faction,bool expelled) + void Player::setExpelled(std::string factionID,bool expelled) { - Player::Faction fact = getFaction(faction); + Player::Faction fact = getFaction(factionID); fact.expelled = expelled; } } diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index 8129c4d8e..628a23826 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -119,15 +119,19 @@ namespace MWWorld void setAutoMove (bool enable); - void addFaction(std::string faction); + void addFaction(std::string factionID); - int getRank(std::string faction); + int getRank(std::string factionID); - void setRank(std::string faction,int rank); + void setRank(std::string factionID,int rank); - bool isExpelled(std::string faction); + void raiseRank(std::string factionID); - void setExpelled(std::string faction,bool expelled); + void lowerRank(std::string factionID); + + bool isExpelled(std::string factionID); + + void setExpelled(std::string factionID,bool expelled); void setLeftRight (int value); From 57299571d5a1d76ce8666e1d7df6f7721d0c0d15 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 2 Apr 2012 22:08:46 -0400 Subject: [PATCH 05/74] 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 83a94d27d..94bcbb31f 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 c6fe023d6..a4fd15b74 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 29cfe33fe..781b522b6 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 b655c8e46..c76fcccd0 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 71e12e369..ed96f47d6 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 a2dea2492..b88ff23b1 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 37b97dd27..1972d8d5b 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 a48cc7e72..a7252353d 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 7f8b7e861..92540f82b 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 0e3563b26..fa197d960 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 2ab6ae621..616dd1daf 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 45fe84f4f..000000000 --- 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 e90cc3b35..000000000 --- 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 49e12064e..000000000 --- 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 be4af711af3ee7668110b7d838c275432b969bfb Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 3 Apr 2012 17:30:19 +0200 Subject: [PATCH 06/74] NPC rank was not loaded. Not sure if it's the right way, but it seems to work. --- apps/openmw/mwclass/npc.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 83a94d27d..b98df79ef 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -53,9 +53,14 @@ namespace MWClass // NPC stats if (!ref->base->faction.empty()) { - // TODO research how initial rank is stored. The information in loadnpc.hpp are at - // best very unclear. - data->mNpcStats.mFactionRank[ref->base->faction] = 0; + if(ref->base->npdt52.gold != -10) + { + data->mNpcStats.mFactionRank[ref->base->faction] = ref->base->npdt52.rank; + } + else + { + data->mNpcStats.mFactionRank[ref->base->faction] = ref->base->npdt52.rank; + } } for (int i=0; i<27; ++i) @@ -281,7 +286,7 @@ namespace MWClass void Npc::registerSelf() { boost::shared_ptr instance (new Npc); - + std::cout << "class npc:" << typeid (ESM::NPC).name(); registerClass (typeid (ESM::NPC).name(), instance); } } From a268b89239742ce05f164f0706c8c765aa01ab6e Mon Sep 17 00:00:00 2001 From: gugus Date: Tue, 3 Apr 2012 17:31:41 +0200 Subject: [PATCH 07/74] changed the way NPC faction is checked. Should be the same way for the player. --- apps/openmw/mwdialogue/dialoguemanager.cpp | 23 +++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index 50549f4a5..1e6faf292 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -39,6 +39,9 @@ #include "../mwscript/interpretercontext.hpp" #include +#include "../mwclass/npc.hpp" +#include "../mwmechanics/npcstats.hpp" + namespace { std::string toLower (const std::string& name) @@ -474,22 +477,18 @@ namespace MWDialogue //NPC faction if (!info.npcFaction.empty()) { - ESMS::LiveCellRef *cellRef = actor.get(); - - if (!cellRef) - return false; - - if (toLower (info.npcFaction)!=toLower (cellRef->base->faction)) - return false; - - //check NPC rank - if(cellRef->base->npdt52.gold != -10) + //MWWorld::Class npcClass = MWWorld::Class::get(actor); + MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor); + std::map::iterator it = stats.mFactionRank.find(info.npcFaction); + if(it!=stats.mFactionRank.end()) { - if(cellRef->base->npdt52.rank < info.data.rank) return false; + //check rank + if(it->second < info.data.rank) return false; } else { - if(cellRef->base->npdt12.rank < info.data.rank) return false; + //not in the faction + return false; } } From 2c7c945208789b2ea29a8755608fc212721f3462 Mon Sep 17 00:00:00 2001 From: gugus Date: Wed, 4 Apr 2012 22:13:57 +0200 Subject: [PATCH 08/74] check playerfaction during dialogue --- apps/openmw/mwdialogue/dialoguemanager.cpp | 31 ++++++++++++++++++++++ apps/openmw/mwdialogue/dialoguemanager.hpp | 3 +++ 2 files changed, 34 insertions(+) diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index 1e6faf292..cd7be5031 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -493,6 +493,21 @@ namespace MWDialogue } // TODO check player faction + if(!info.pcFaction.empty()) + { + MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(mEnvironment.mWorld->getPlayer().getPlayer()); + std::map::iterator it = stats.mFactionRank.find(info.npcFaction); + if(it!=stats.mFactionRank.end()) + { + //check rank + if(it->second < info.data.rank) return false; + } + else + { + //not in the faction + return false; + } + } //check gender ESMS::LiveCellRef* npc = actor.get(); @@ -655,6 +670,7 @@ namespace MWDialogue void DialogueManager::executeScript(std::string script) { + std::cout << script; std::vector code; if(compile(script,code)) { @@ -796,4 +812,19 @@ namespace MWDialogue mChoiceMap[question] = choice; mIsInChoice = true; } + + std::string DialogueManager::getFaction() + { + std::string factionID(""); + MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mEnvironment.mWorld->getPlayer().getPlayer()); + if(stats.mFactionRank.empty()) + { + std::cout << "No faction for this actor!"; + } + else + { + factionID = stats.mFactionRank.begin()->first; + } + return factionID; + } } diff --git a/apps/openmw/mwdialogue/dialoguemanager.hpp b/apps/openmw/mwdialogue/dialoguemanager.hpp index 260d8e339..d0380fa71 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.hpp +++ b/apps/openmw/mwdialogue/dialoguemanager.hpp @@ -63,6 +63,9 @@ namespace MWDialogue void askQuestion(std::string question,int choice); + ///get the faction of the actor you are talking with + std::string getFaction(); + //calbacks for the GUI void keywordSelected(std::string keyword); void goodbyeSelected(); From aaa5368fe927b093b239862bb7d069c83099f140 Mon Sep 17 00:00:00 2001 From: gugus Date: Wed, 4 Apr 2012 22:14:38 +0200 Subject: [PATCH 09/74] added script instruction pcraiserank. Does not work yet. --- apps/openmw/mwscript/docs/vmformat.txt | 3 ++- apps/openmw/mwscript/statsextensions.cpp | 27 ++++++++++++++++-------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 7ff60a203..27b426d0e 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -127,4 +127,5 @@ op 0x2000141: GetWaterLevel op 0x2000142: SetWaterLevel op 0x2000143: ModWaterLevel op 0x2000144: ToggleWater, twa -opcodes 0x2000145-0x3ffffff unused +op 0x2000145: PCRaiseRank +opcodes 0x2000146-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 85ac54348..be31321e9 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -17,6 +17,8 @@ #include "interpretercontext.hpp" #include "ref.hpp" +#include "../mwdialogue/dialoguemanager.hpp" + namespace MWScript { namespace Stats @@ -303,12 +305,18 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { + std::cout << "try to rais rank..."; MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - - std::string factionID = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - context.getEnvironment().mWorld->getPlayer().raiseRank(factionID); + + std::string factionID = context.getEnvironment().mDialogueManager->getFaction(); + if(factionID != "") + { + std::cout << "raiserank!!!!!"; + MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 1; + } + std::cout << std::endl; } }; @@ -342,8 +350,8 @@ namespace MWScript const int opcodeSetSkillExplicit = 0x20000df; const int opcodeModSkill = 0x20000fa; const int opcodeModSkillExplicit = 0x2000115; - const int opcodePCJoinFaction = 0x2000141; - const int opcodePCRaiseRank = 0x2000142; + //const int opcodePCJoinFaction = 0x2000141; + const int opcodePCRaiseRank = 0x2000145; void registerExtensions (Compiler::Extensions& extensions) { @@ -415,8 +423,9 @@ namespace MWScript extensions.registerInstruction (mod + skills[i], "l", opcodeModSkill+i, opcodeModSkillExplicit+i); } - extensions.registerInstruction("PCJoinFaction","S",opcodePCJoinFaction); - extensions.registerInstruction("PCRaiseRank","S",opcodePCRaiseRank); + //extensions.registerInstruction("PCJoinFaction","S",opcodePCJoinFaction); + std::cout << "rgister raiserank"; + extensions.registerInstruction("pcraiserank","",opcodePCRaiseRank); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -473,7 +482,7 @@ namespace MWScript interpreter.installSegment5 (opcodeModSkillExplicit+i, new OpModSkill (i)); } - interpreter.installSegment5(opcodePCJoinFaction,new OpPCJoinFaction); + //interpreter.installSegment5(opcodePCJoinFaction,new OpPCJoinFaction); interpreter.installSegment5(opcodePCRaiseRank,new OpPCRaiseRank); } } From ca4de0606ea0a4b57b8b718229768d33019cd7e5 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 4 Apr 2012 23:23:24 -0400 Subject: [PATCH 10/74] 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 e2071957c..e524878cc 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 12f7bae526b89aecb024b5f61d2cd77528e5c602 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 7 Apr 2012 18:37:41 +0200 Subject: [PATCH 11/74] added known spells and selected spell to NpcStats --- apps/openmw/mwmechanics/npcstats.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index aeb5f56d5..59bfa2ac0 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -2,6 +2,7 @@ #define GAME_MWMECHANICS_NPCSTATS_H #include +#include #include "stat.hpp" @@ -25,6 +26,9 @@ namespace MWMechanics bool mSneak; bool mCombat; + std::set mKnownSpells; + std::string mSelectedSpell; // can be an empty string (no spell selected) + NpcStats() : mForceRun (false), mForceSneak (false), mRun (false), mSneak (false), mCombat (false) {} }; From c94d6830145dcad282e8c3ac412308746c8692a2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 7 Apr 2012 18:46:50 +0200 Subject: [PATCH 12/74] fill in initial spell list from NPC record --- apps/openmw/mwclass/npc.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 83a94d27d..2cf4cf41c 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -61,6 +61,10 @@ namespace MWClass for (int i=0; i<27; ++i) data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]); + for (std::vector::const_iterator iter (ref->base->spells.list.begin()); + iter!=ref->base->spells.list.end(); ++iter) + data->mNpcStats.mKnownSpells.insert (*iter); + // creature stats data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength); data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence); From ebab98a8a0f919049a6fd7c2997387c29f580be0 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 7 Apr 2012 22:02:20 -0400 Subject: [PATCH 13/74] 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 ce5d84684..60eadc49a 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 94bcbb31f..c78a7501f 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 6eb4a182b..5034e72b3 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 d49c6e0f8..66c98c541 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 fb710443b..d0019154e 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 7692c7128..98f0e7487 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 a4fd15b74..30c28bb79 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 e524878cc..a95ce8526 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 14/74] 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 30c28bb79..ea00919c6 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 a95ce8526..aae97db2a 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 15/74] 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 f7877d2ad..4b3c23e64 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 16/74] 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 4b3c23e64..8097afdbf 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: Mon, 9 Apr 2012 13:24:19 +0200 Subject: [PATCH 17/74] pcRaiseRank works. Player can now join factions. --- apps/openmw/mwdialogue/dialoguemanager.cpp | 22 ++++++---- apps/openmw/mwscript/docs/vmformat.txt | 5 ++- apps/openmw/mwscript/statsextensions.cpp | 47 +++++++++++++++++----- 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index cd7be5031..b36c9d998 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -181,7 +181,17 @@ namespace MWDialogue break; case 46://Same faction - if(!selectCompare(comp,0,select.i)) return false; + { + MWMechanics::NpcStats PCstats = MWWorld::Class::get(mEnvironment.mWorld->getPlayer().getPlayer()).getNpcStats(mEnvironment.mWorld->getPlayer().getPlayer()); + MWMechanics::NpcStats NPCstats = MWWorld::Class::get(actor).getNpcStats(actor); + int sameFaction = 0; + if(!NPCstats.mFactionRank.empty()) + { + std::string NPCFaction = NPCstats.mFactionRank.begin()->first; + if(PCstats.mFactionRank.find(NPCFaction) != PCstats.mFactionRank.end()) sameFaction = 1; + } + if(!selectCompare(comp,sameFaction,select.i)) return false; + } break; case 48://Detected @@ -193,7 +203,6 @@ namespace MWDialogue break; case 50://choice - if(choice) { if(!selectCompare(comp,mChoice,select.i)) return false; @@ -447,9 +456,6 @@ namespace MWDialogue if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor)) return false; - //PC Faction - if(!info.pcFaction.empty()) return false; - //NPC race if (!info.race.empty()) { @@ -495,8 +501,8 @@ namespace MWDialogue // TODO check player faction if(!info.pcFaction.empty()) { - MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(mEnvironment.mWorld->getPlayer().getPlayer()); - std::map::iterator it = stats.mFactionRank.find(info.npcFaction); + MWMechanics::NpcStats stats = MWWorld::Class::get(mEnvironment.mWorld->getPlayer().getPlayer()).getNpcStats(mEnvironment.mWorld->getPlayer().getPlayer()); + std::map::iterator it = stats.mFactionRank.find(info.pcFaction); if(it!=stats.mFactionRank.end()) { //check rank @@ -816,7 +822,7 @@ namespace MWDialogue std::string DialogueManager::getFaction() { std::string factionID(""); - MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mEnvironment.mWorld->getPlayer().getPlayer()); + MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mActor); if(stats.mFactionRank.empty()) { std::cout << "No faction for this actor!"; diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 27b426d0e..2b20b973c 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -24,7 +24,8 @@ op 0x20007: PlayAnim, explicit reference op 0x20008: LoopAnim op 0x20009: LoopAnim, explicit reference op 0x2000a: Choice -opcodes 0x2000b-0x3ffff unused +op 0x2000b: PCRaiseRank +opcodes 0x2000c-0x3ffff unused Segment 4: (not implemented yet) @@ -127,5 +128,5 @@ op 0x2000141: GetWaterLevel op 0x2000142: SetWaterLevel op 0x2000143: ModWaterLevel op 0x2000144: ToggleWater, twa -op 0x2000145: PCRaiseRank +op 0x2000145: ModDisposition opcodes 0x2000146-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index be31321e9..05db10301 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -299,27 +299,54 @@ namespace MWScript } }; - class OpPCRaiseRank : public Interpreter::Opcode0 + class OpPCRaiseRank : public Interpreter::Opcode1 { public: - virtual void execute (Interpreter::Runtime& runtime) + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { + std::cout << "arg0:" << arg0<< std::endl; std::cout << "try to rais rank..."; + std::string factionID = ""; MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - - std::string factionID = context.getEnvironment().mDialogueManager->getFaction(); + if(arg0==0) + { + std::cout << "slurpppp"; + factionID = context.getEnvironment().mDialogueManager->getFaction(); + } + else + { + factionID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + } if(factionID != "") { std::cout << "raiserank!!!!!"; MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); - MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 1; + if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) == MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) + { + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 1; + } + else + { + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] +1; + } } std::cout << std::endl; } }; + class OpModDisposition : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + + } + }; + const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; @@ -351,7 +378,8 @@ namespace MWScript const int opcodeModSkill = 0x20000fa; const int opcodeModSkillExplicit = 0x2000115; //const int opcodePCJoinFaction = 0x2000141; - const int opcodePCRaiseRank = 0x2000145; + const int opcodePCRaiseRank = 0x2000b; + const int opcodeModDisposition = 0x2000145; void registerExtensions (Compiler::Extensions& extensions) { @@ -424,8 +452,8 @@ namespace MWScript opcodeModSkill+i, opcodeModSkillExplicit+i); } //extensions.registerInstruction("PCJoinFaction","S",opcodePCJoinFaction); - std::cout << "rgister raiserank"; - extensions.registerInstruction("pcraiserank","",opcodePCRaiseRank); + extensions.registerInstruction("pcraiserank","/S",opcodePCRaiseRank); + extensions.registerInstruction("moddisposition","l",opcodeModDisposition); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -483,7 +511,8 @@ namespace MWScript } //interpreter.installSegment5(opcodePCJoinFaction,new OpPCJoinFaction); - interpreter.installSegment5(opcodePCRaiseRank,new OpPCRaiseRank); + interpreter.installSegment3(opcodePCRaiseRank,new OpPCRaiseRank); + interpreter.installSegment5(opcodeModDisposition,new OpModDisposition); } } } From 45d11eaf144a160d8a3b3a2fb83e0a1b491a2324 Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 9 Apr 2012 14:23:12 +0200 Subject: [PATCH 18/74] fixed a bug in the dialogue manager. --- apps/openmw/mwdialogue/dialoguemanager.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index b36c9d998..5dded07b0 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -112,16 +112,15 @@ namespace switch (world.getGlobalVariableType (name)) { case 's': - - return selectCompare (comp, value, world.getGlobalVariable (name).mShort); + return selectCompare (comp, world.getGlobalVariable (name).mShort, value); case 'l': - return selectCompare (comp, value, world.getGlobalVariable (name).mLong); + return selectCompare (comp, world.getGlobalVariable (name).mLong, value); case 'f': - return selectCompare (comp, value, world.getGlobalVariable (name).mFloat); + return selectCompare (comp, world.getGlobalVariable (name).mFloat, value); case ' ': @@ -282,7 +281,7 @@ namespace MWDialogue { case '1': // function - return true; // TODO implement functions + return true; // Done elsewhere. case '2': // global From aa8418634f8f776a09e19bf141e322505b26ad1f Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 9 Apr 2012 14:26:53 +0200 Subject: [PATCH 19/74] add PCLowerRank script instruction --- apps/openmw/mwscript/docs/vmformat.txt | 3 +- apps/openmw/mwscript/statsextensions.cpp | 43 +++++++++++++++++++++--- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 2b20b973c..9a5cf8525 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -25,7 +25,8 @@ op 0x20008: LoopAnim op 0x20009: LoopAnim, explicit reference op 0x2000a: Choice op 0x2000b: PCRaiseRank -opcodes 0x2000c-0x3ffff unused +op 0x2000c: PCLowerRank +opcodes 0x2000d-0x3ffff unused Segment 4: (not implemented yet) diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 05db10301..176f139aa 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -305,14 +305,11 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { - std::cout << "arg0:" << arg0<< std::endl; - std::cout << "try to rais rank..."; std::string factionID = ""; MWScript::InterpreterContext& context = static_cast (runtime.getContext()); if(arg0==0) { - std::cout << "slurpppp"; factionID = context.getEnvironment().mDialogueManager->getFaction(); } else @@ -322,7 +319,6 @@ namespace MWScript } if(factionID != "") { - std::cout << "raiserank!!!!!"; MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) == MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) { @@ -336,7 +332,41 @@ namespace MWScript std::cout << std::endl; } }; - + + class OpPCLowerRank : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + std::string factionID = ""; + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + if(arg0==0) + { + factionID = context.getEnvironment().mDialogueManager->getFaction(); + } + else + { + factionID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + } + if(factionID != "") + { + MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) == MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) + { + //do nothing, the player is not in the faction... Throw an exeption? + } + else + { + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] -1; + } + } + std::cout << std::endl; + } + }; + class OpModDisposition : public Interpreter::Opcode0 { public: @@ -379,6 +409,7 @@ namespace MWScript const int opcodeModSkillExplicit = 0x2000115; //const int opcodePCJoinFaction = 0x2000141; const int opcodePCRaiseRank = 0x2000b; + const int opcodePCLowerRank = 0x2000c; const int opcodeModDisposition = 0x2000145; void registerExtensions (Compiler::Extensions& extensions) @@ -453,6 +484,7 @@ namespace MWScript } //extensions.registerInstruction("PCJoinFaction","S",opcodePCJoinFaction); extensions.registerInstruction("pcraiserank","/S",opcodePCRaiseRank); + extensions.registerInstruction("pclowerrank","/S",opcodePCLowerRank); extensions.registerInstruction("moddisposition","l",opcodeModDisposition); } @@ -512,6 +544,7 @@ namespace MWScript //interpreter.installSegment5(opcodePCJoinFaction,new OpPCJoinFaction); interpreter.installSegment3(opcodePCRaiseRank,new OpPCRaiseRank); + interpreter.installSegment3(opcodePCLowerRank,new OpPCLowerRank); interpreter.installSegment5(opcodeModDisposition,new OpModDisposition); } } From 6ca212b9e96280cbb671d22b44795ecdc64a6198 Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 9 Apr 2012 14:30:42 +0200 Subject: [PATCH 20/74] script instruction: PCJoinFaction --- apps/openmw/mwscript/docs/vmformat.txt | 3 +- apps/openmw/mwscript/statsextensions.cpp | 35 ++++++++++++++++++------ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 9a5cf8525..30b9f97e7 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -26,7 +26,8 @@ op 0x20009: LoopAnim, explicit reference op 0x2000a: Choice op 0x2000b: PCRaiseRank op 0x2000c: PCLowerRank -opcodes 0x2000d-0x3ffff unused +op x20000d: PCJoinFaction +opcodes 0x2000e-0x3ffff unused Segment 4: (not implemented yet) diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 176f139aa..5b64ee239 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -284,18 +284,36 @@ namespace MWScript } }; - class OpPCJoinFaction : public Interpreter::Opcode0 + class OpPCJoinFaction : public Interpreter::Opcode1 { public: - virtual void execute (Interpreter::Runtime& runtime) + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { + std::string factionID = ""; MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - - std::string factionID = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - context.getEnvironment().mWorld->getPlayer().addFaction(factionID); + if(arg0==0) + { + factionID = context.getEnvironment().mDialogueManager->getFaction(); + } + else + { + factionID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + } + if(factionID != "") + { + MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) == MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) + { + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 1; + } + else + { + //the player is already in the faction... Throw an exeption? + } + } } }; @@ -329,7 +347,6 @@ namespace MWScript MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] +1; } } - std::cout << std::endl; } }; @@ -363,7 +380,6 @@ namespace MWScript MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] -1; } } - std::cout << std::endl; } }; @@ -410,6 +426,7 @@ namespace MWScript //const int opcodePCJoinFaction = 0x2000141; const int opcodePCRaiseRank = 0x2000b; const int opcodePCLowerRank = 0x2000c; + const int opcodePCJoinFaction = 0x2000d; const int opcodeModDisposition = 0x2000145; void registerExtensions (Compiler::Extensions& extensions) @@ -485,6 +502,7 @@ namespace MWScript //extensions.registerInstruction("PCJoinFaction","S",opcodePCJoinFaction); extensions.registerInstruction("pcraiserank","/S",opcodePCRaiseRank); extensions.registerInstruction("pclowerrank","/S",opcodePCLowerRank); + extensions.registerInstruction("pcjoinfaction","/S",opcodePCJoinFaction); extensions.registerInstruction("moddisposition","l",opcodeModDisposition); } @@ -545,6 +563,7 @@ namespace MWScript //interpreter.installSegment5(opcodePCJoinFaction,new OpPCJoinFaction); interpreter.installSegment3(opcodePCRaiseRank,new OpPCRaiseRank); interpreter.installSegment3(opcodePCLowerRank,new OpPCLowerRank); + interpreter.installSegment3(opcodePCJoinFaction,new OpPCJoinFaction); interpreter.installSegment5(opcodeModDisposition,new OpModDisposition); } } From dd9a88cee266f4e91bd77312b3b083c9c9a47ad7 Mon Sep 17 00:00:00 2001 From: gugus Date: Mon, 9 Apr 2012 14:32:07 +0200 Subject: [PATCH 21/74] clean up --- apps/openmw/mwscript/statsextensions.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 5b64ee239..27983eca8 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -423,7 +423,7 @@ namespace MWScript const int opcodeSetSkillExplicit = 0x20000df; const int opcodeModSkill = 0x20000fa; const int opcodeModSkillExplicit = 0x2000115; - //const int opcodePCJoinFaction = 0x2000141; + const int opcodePCRaiseRank = 0x2000b; const int opcodePCLowerRank = 0x2000c; const int opcodePCJoinFaction = 0x2000d; @@ -499,7 +499,6 @@ namespace MWScript extensions.registerInstruction (mod + skills[i], "l", opcodeModSkill+i, opcodeModSkillExplicit+i); } - //extensions.registerInstruction("PCJoinFaction","S",opcodePCJoinFaction); extensions.registerInstruction("pcraiserank","/S",opcodePCRaiseRank); extensions.registerInstruction("pclowerrank","/S",opcodePCLowerRank); extensions.registerInstruction("pcjoinfaction","/S",opcodePCJoinFaction); @@ -560,7 +559,6 @@ namespace MWScript interpreter.installSegment5 (opcodeModSkillExplicit+i, new OpModSkill (i)); } - //interpreter.installSegment5(opcodePCJoinFaction,new OpPCJoinFaction); interpreter.installSegment3(opcodePCRaiseRank,new OpPCRaiseRank); interpreter.installSegment3(opcodePCLowerRank,new OpPCLowerRank); interpreter.installSegment3(opcodePCJoinFaction,new OpPCJoinFaction); From 944654f2637c68231583c636f064c6308067aa7a Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 9 Apr 2012 15:20:57 +0200 Subject: [PATCH 22/74] image rotating function --- CMakeLists.txt | 1 + libs/openengine/ogre/imagerotate.cpp | 74 ++++++++++++++++++++++++++++ libs/openengine/ogre/imagerotate.hpp | 27 ++++++++++ 3 files changed, 102 insertions(+) create mode 100644 libs/openengine/ogre/imagerotate.cpp create mode 100644 libs/openengine/ogre/imagerotate.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b87e3544..148386432 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,7 @@ set(OENGINE_OGRE ${LIBDIR}/openengine/ogre/renderer.cpp ${LIBDIR}/openengine/ogre/mouselook.cpp ${LIBDIR}/openengine/ogre/fader.cpp + ${LIBDIR}/openengine/ogre/imagerotate.cpp ) set(OENGINE_GUI ${LIBDIR}/openengine/gui/events.cpp diff --git a/libs/openengine/ogre/imagerotate.cpp b/libs/openengine/ogre/imagerotate.cpp new file mode 100644 index 000000000..a6304277e --- /dev/null +++ b/libs/openengine/ogre/imagerotate.cpp @@ -0,0 +1,74 @@ +#include "imagerotate.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Ogre; +using namespace OEngine::Render; + +void ImageRotate::rotate(const std::string& sourceImage, const std::string& destImage, const float angle) +{ + Root* root = Ogre::Root::getSingletonPtr(); + + SceneManager* sceneMgr = root->createSceneManager(ST_GENERIC); + Camera* camera = sceneMgr->createCamera("ImageRotateCamera"); + + MaterialPtr material = MaterialManager::getSingleton().create("ImageRotateMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + material->getTechnique(0)->getPass(0)->setLightingEnabled(false); + material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); + TextureUnitState* tus = material->getTechnique(0)->getPass(0)->createTextureUnitState(sourceImage); + Degree deg(angle); + tus->setTextureRotate(Radian(deg.valueRadians())); + tus->setTextureAddressingMode(TextureUnitState::TAM_BORDER); + tus->setTextureBorderColour(ColourValue(0, 0, 0, 0)); + + Rectangle2D* rect = new Rectangle2D(true); + rect->setCorners(-1.0, 1.0, 1.0, -1.0); + rect->setMaterial("ImageRotateMaterial"); + // Render the background before everything else + rect->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND); + + // Use infinite AAB to always stay visible + AxisAlignedBox aabInf; + aabInf.setInfinite(); + rect->setBoundingBox(aabInf); + + // Attach background to the scene + SceneNode* node = sceneMgr->getRootSceneNode()->createChildSceneNode(); + node->attachObject(rect); + + // retrieve image width and height + TexturePtr sourceTexture = TextureManager::getSingleton().getByName(sourceImage); + unsigned int width = sourceTexture->getWidth(); + unsigned int height = sourceTexture->getHeight(); + + TexturePtr destTexture = TextureManager::getSingleton().createManual( + "ImageRotateDestTexture", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + TEX_TYPE_2D, + width, height, + 0, + PF_R8G8B8, + TU_RENDERTARGET); + + RenderTarget* rtt = destTexture->getBuffer()->getRenderTarget(); + rtt->setAutoUpdated(false); + Viewport* vp = rtt->addViewport(camera); + vp->setOverlaysEnabled(false); + vp->setShadowsEnabled(false); + + rtt->update(); + rtt->writeContentsToFile(destImage); + + // remove all the junk we've created + TextureManager::getSingleton().remove("ImageRotateDestTexture"); + MaterialManager::getSingleton().remove("ImageRotateMaterial"); + root->destroySceneManager(sceneMgr); + delete rect; +} diff --git a/libs/openengine/ogre/imagerotate.hpp b/libs/openengine/ogre/imagerotate.hpp new file mode 100644 index 000000000..85363d71f --- /dev/null +++ b/libs/openengine/ogre/imagerotate.hpp @@ -0,0 +1,27 @@ +#ifndef OENGINE_OGRE_IMAGEROTATE_HPP +#define OENGINE_OGRE_IMAGEROTATE_HPP + +#include + +namespace OEngine +{ +namespace Render +{ + + /// Rotate an image by certain degrees and save as file, uses the GPU + /// Make sure Ogre Root is initialised before calling + class ImageRotate + { + public: + /** + * @param source image (file name - has to exist in an resource group) + * @param destination image (absolute file path) + * @param angle in degrees to turn + */ + static void rotate(const std::string& sourceImage, const std::string& destImage, const float angle); + }; + +} +} + +#endif From 33f360f52f363e67a65b1432a33442d9bfc0a303 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 9 Apr 2012 15:36:51 +0200 Subject: [PATCH 23/74] transparency fix --- libs/openengine/ogre/imagerotate.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/openengine/ogre/imagerotate.cpp b/libs/openengine/ogre/imagerotate.cpp index a6304277e..166a1d3c6 100644 --- a/libs/openengine/ogre/imagerotate.cpp +++ b/libs/openengine/ogre/imagerotate.cpp @@ -54,7 +54,7 @@ void ImageRotate::rotate(const std::string& sourceImage, const std::string& dest TEX_TYPE_2D, width, height, 0, - PF_R8G8B8, + PF_A8R8G8B8, TU_RENDERTARGET); RenderTarget* rtt = destTexture->getBuffer()->getRenderTarget(); @@ -62,6 +62,8 @@ void ImageRotate::rotate(const std::string& sourceImage, const std::string& dest Viewport* vp = rtt->addViewport(camera); vp->setOverlaysEnabled(false); vp->setShadowsEnabled(false); + vp->setBackgroundColour(ColourValue(0,0,0,0)); + vp->setClearEveryFrame(true, FBT_DEPTH); rtt->update(); rtt->writeContentsToFile(destImage); From 344641e5748d5cb12bcddebd4706a585c73ebbd8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 11 Apr 2012 13:38:17 +0200 Subject: [PATCH 24/74] updated developer list in readme file --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index 17806172f..e1c24ab52 100644 --- a/readme.txt +++ b/readme.txt @@ -95,6 +95,7 @@ Allowed options: CREDITS Current Developers: +Aleksandar Jovanov Alexander “Ace” Olofsson athile BrotherBrick From 2a4fcf42a3a8af3314a0c87deb2d719944482a73 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 11 Apr 2012 18:53:13 +0200 Subject: [PATCH 25/74] basic shadows --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/engine.cpp | 1 + apps/openmw/mwrender/localmap.cpp | 4 +- apps/openmw/mwrender/objects.cpp | 2 + apps/openmw/mwrender/occlusionquery.cpp | 3 + apps/openmw/mwrender/renderingmanager.cpp | 33 ++- apps/openmw/mwrender/renderingmanager.hpp | 15 +- apps/openmw/mwrender/shaderhelper.cpp | 308 ++++++++++++++++++++++ apps/openmw/mwrender/shaderhelper.hpp | 29 ++ apps/openmw/mwrender/shadows.cpp | 175 ++++++++++++ apps/openmw/mwrender/shadows.hpp | 39 +++ apps/openmw/mwrender/sky.cpp | 10 + apps/openmw/mwrender/terrain.cpp | 21 +- apps/openmw/mwrender/terrain.hpp | 3 +- apps/openmw/mwrender/terrainmaterial.cpp | 110 ++++---- apps/openmw/mwrender/terrainmaterial.hpp | 5 + apps/openmw/mwrender/water.cpp | 75 +++++- apps/openmw/mwrender/water.hpp | 2 + components/nifogre/ogre_nif_loader.cpp | 181 +++---------- files/CMakeLists.txt | 3 + files/settings-default.cfg | 31 ++- files/shadows/depthshadowcaster.cg | 51 ++++ files/shadows/depthshadowcaster.material | 67 +++++ files/water/water.material | 2 +- 24 files changed, 953 insertions(+), 219 deletions(-) create mode 100644 apps/openmw/mwrender/shaderhelper.cpp create mode 100644 apps/openmw/mwrender/shaderhelper.hpp create mode 100644 apps/openmw/mwrender/shadows.cpp create mode 100644 apps/openmw/mwrender/shadows.hpp create mode 100644 files/shadows/depthshadowcaster.cg create mode 100644 files/shadows/depthshadowcaster.material diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index a8ae0bd49..6a65c0e14 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -15,7 +15,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER}) add_openmw_dir (mwrender renderingmanager debugging sky player animation npcanimation creatureanimation actors objects - renderinginterface localmap occlusionquery terrain terrainmaterial water + renderinginterface localmap occlusionquery terrain terrainmaterial water shadows shaderhelper ) add_openmw_dir (mwinput diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 259733600..1adcf8dca 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -362,6 +362,7 @@ void OMW::Engine::go() addResourcesDirectory(mResDir / "mygui"); addResourcesDirectory(mResDir / "water"); addResourcesDirectory(mResDir / "gbuffer"); + addResourcesDirectory(mResDir / "shadows"); // Create the window mOgre->createWindow("OpenMW"); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index cb3c0a204..2cc233a01 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -225,7 +225,9 @@ void LocalMap::render(const float x, const float y, vp->setShadowsEnabled(false); vp->setBackgroundColour(ColourValue(0, 0, 0)); vp->setVisibilityMask(RV_Map); - vp->setMaterialScheme("Map"); + + // use fallback techniques without shadows and without mrt + vp->setMaterialScheme("Fallback"); rtt->update(); diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index b633330fa..eb7e440cb 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -193,6 +193,8 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics); + sg->setCastShadows(true); + sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); mRenderer.getScene()->destroyEntity(ent); diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index d789b8c4e..80b804dce 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -60,6 +60,7 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod mBBNodeReal = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); mBBQueryTotal = mRendering->getScene()->createBillboardSet(1); + mBBQueryTotal->setCastShadows(false); mBBQueryTotal->setDefaultDimensions(150, 150); mBBQueryTotal->createBillboard(Vector3::ZERO); mBBQueryTotal->setMaterialName("QueryTotalPixels"); @@ -67,6 +68,7 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod mBBNodeReal->attachObject(mBBQueryTotal); mBBQueryVisible = mRendering->getScene()->createBillboardSet(1); + mBBQueryVisible->setCastShadows(false); mBBQueryVisible->setDefaultDimensions(150, 150); mBBQueryVisible->createBillboard(Vector3::ZERO); mBBQueryVisible->setMaterialName("QueryVisiblePixels"); @@ -75,6 +77,7 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod mBBQuerySingleObject = mRendering->getScene()->createBillboardSet(1); /// \todo ideally this should occupy exactly 1 pixel on the screen + mBBQuerySingleObject->setCastShadows(false); mBBQuerySingleObject->setDefaultDimensions(0.003, 0.003); mBBQuerySingleObject->createBillboard(Vector3::ZERO); mBBQuerySingleObject->setMaterialName("QueryVisiblePixels"); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index aadc92369..ee60407b2 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -14,6 +14,10 @@ #include #include +#include "shadows.hpp" +#include "shaderhelper.hpp" +#include "localmap.hpp" +#include "water.hpp" using namespace MWRender; using namespace Ogre; @@ -21,11 +25,9 @@ using namespace Ogre; namespace MWRender { RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Environment& environment) - :mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0) + :mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mAmbientMode(0), mSunEnabled(0) { mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); - mTerrainManager = new TerrainManager(mRendering.getScene(), - environment); mWater = 0; @@ -86,6 +88,12 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const Ogre::SceneNode *cameraPitchNode = cameraYawNode->createChildSceneNode(); cameraPitchNode->attachObject(mRendering.getCamera()); + mShadows = new Shadows(&mRendering); + mShaderHelper = new ShaderHelper(this); + + mTerrainManager = new TerrainManager(mRendering.getScene(), this, + environment); + //mSkyManager = 0; mSkyManager = new SkyManager(mMwRoot, mRendering.getCamera(), &environment); @@ -412,6 +420,7 @@ void RenderingManager::skipAnimation (const MWWorld::Ptr& ptr) void RenderingManager::setSunColour(const Ogre::ColourValue& colour) { + if (!mSunEnabled) return; mSun->setDiffuseColour(colour); mSun->setSpecularColour(colour); mTerrainManager->setDiffuse(colour); @@ -425,12 +434,21 @@ void RenderingManager::setAmbientColour(const Ogre::ColourValue& colour) void RenderingManager::sunEnable() { - if (mSun) mSun->setVisible(true); + // Don't disable the light, as the shaders assume the first light to be directional. + //if (mSun) mSun->setVisible(true); + mSunEnabled = true; } void RenderingManager::sunDisable() { - if (mSun) mSun->setVisible(false); + // Don't disable the light, as the shaders assume the first light to be directional. + //if (mSun) mSun->setVisible(false); + mSunEnabled = false; + if (mSun) + { + mSun->setDiffuseColour(ColourValue(0,0,0)); + mSun->setSpecularColour(ColourValue(0,0,0)); + } } void RenderingManager::setSunDirection(const Ogre::Vector3& direction) @@ -475,4 +493,9 @@ const bool RenderingManager::useMRT() return Settings::Manager::getBool("shader", "Water"); } +Shadows* RenderingManager::getShadows() +{ + return mShadows; +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index da9c55cb5..a563d78c6 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -25,8 +25,6 @@ #include "objects.hpp" #include "actors.hpp" #include "player.hpp" -#include "water.hpp" -#include "localmap.hpp" #include "occlusionquery.hpp" namespace Ogre @@ -45,7 +43,10 @@ namespace MWWorld namespace MWRender { - + class Shadows; + class ShaderHelper; + class LocalMap; + class Water; class RenderingManager: private RenderingInterface { @@ -114,6 +115,8 @@ class RenderingManager: private RenderingInterface { bool occlusionQuerySupported() { return mOcclusionQuery->supported(); }; OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; }; + Shadows* getShadows(); + void setGlare(bool glare); void skyEnable (); void skyDisable (); @@ -149,6 +152,8 @@ class RenderingManager: private RenderingInterface { void setAmbientMode(); + bool mSunEnabled; + SkyManager* mSkyManager; OcclusionQuery* mOcclusionQuery; @@ -180,6 +185,10 @@ class RenderingManager: private RenderingInterface { MWRender::Debugging *mDebugging; MWRender::LocalMap* mLocalMap; + + MWRender::Shadows* mShadows; + + MWRender::ShaderHelper* mShaderHelper; }; } diff --git a/apps/openmw/mwrender/shaderhelper.cpp b/apps/openmw/mwrender/shaderhelper.cpp new file mode 100644 index 000000000..93f960dc4 --- /dev/null +++ b/apps/openmw/mwrender/shaderhelper.cpp @@ -0,0 +1,308 @@ +#include "shaderhelper.hpp" +#include "renderingmanager.hpp" +#include "shadows.hpp" + +#include +#include +#include + +#include + +using namespace Ogre; +using namespace MWRender; + +ShaderHelper::ShaderHelper(RenderingManager* rend) +{ + mRendering = rend; + applyShaders(); +} + +void ShaderHelper::applyShaders() +{ + if (!Settings::Manager::getBool("shaders", "Objects")) return; + + bool mrt = RenderingManager::useMRT(); + bool shadows = Settings::Manager::getBool("enabled", "Shadows"); + bool split = Settings::Manager::getBool("split", "Shadows"); + + // shader for normal rendering + createShader(mrt, shadows, split, "main"); + + // fallback shader without mrt and without shadows + // (useful for reflection and for minimap) + createShader(false, false, false, "main_fallback"); +} + +void ShaderHelper::createShader(const bool mrt, const bool shadows, const bool split, const std::string& name) +{ + HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); + + const int numsplits = 3; + + // the number of lights to support. + // when rendering an object, OGRE automatically picks the lights that are + // closest to the object being rendered. unfortunately this mechanism does + // not work perfectly for objects batched together (they will all use the same + // lights). to work around this, we are simply pushing the maximum number + // of lights here in order to minimize disappearing lights. + int num_lights = Settings::Manager::getInt("num lights", "Objects"); + + { + // vertex + HighLevelGpuProgramPtr vertex; + if (!mgr.getByName(name+"_vp").isNull()) + mgr.remove(name+"_vp"); + + vertex = mgr.createProgram(name+"_vp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + "cg", GPT_VERTEX_PROGRAM); + vertex->setParameter("profiles", "vs_4_0 vs_2_x vp40 arbvp1"); + vertex->setParameter("entry_point", "main_vp"); + StringUtil::StrStreamType outStream; + outStream << + "void main_vp( \n" + " float4 position : POSITION, \n" + " float4 normal : NORMAL, \n" + " float4 colour : COLOR, \n" + " in float2 uv : TEXCOORD0, \n" + " out float2 oUV : TEXCOORD0, \n" + " out float4 oPosition : POSITION, \n" + " out float4 oPositionObjSpace : TEXCOORD1, \n" + " out float4 oNormal : TEXCOORD2, \n" + " out float oDepth : TEXCOORD3, \n" + " out float4 oVertexColour : TEXCOORD4, \n"; + if (shadows && !split) outStream << + " out float4 oLightSpacePos0 : TEXCOORD5, \n" + " uniform float4x4 worldMatrix, \n" + " uniform float4x4 texViewProjMatrix0, \n"; + else + { + for (int i=0; isetSource(outStream.str()); + vertex->load(); + vertex->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); + if (shadows) + { + vertex->getDefaultParameters()->setNamedAutoConstant("worldMatrix", GpuProgramParameters::ACT_WORLD_MATRIX); + if (!split) + vertex->getDefaultParameters()->setNamedAutoConstant("texViewProjMatrix0", GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, 0); + else + { + for (int i=0; igetDefaultParameters()->setNamedAutoConstant("texViewProjMatrix"+StringConverter::toString(i), GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, i); + } + } + } + } + + { + // fragment + HighLevelGpuProgramPtr fragment; + if (!mgr.getByName(name+"_fp").isNull()) + mgr.remove(name+"_fp"); + + fragment = mgr.createProgram(name+"_fp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + "cg", GPT_FRAGMENT_PROGRAM); + fragment->setParameter("profiles", "ps_4_0 ps_2_x fp40 arbfp1"); + fragment->setParameter("entry_point", "main_fp"); + StringUtil::StrStreamType outStream; + + if (shadows) outStream << + "float depthShadow(sampler2D shadowMap, float4 shadowMapPos, float2 offset) \n" + "{ \n" + " shadowMapPos /= shadowMapPos.w; \n" + " float3 o = float3(offset.xy, -offset.x) * 0.3f; \n" + " float c = (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy - o.xy).r) ? 1 : 0; // top left \n" + " c += (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy + o.xy).r) ? 1 : 0; // bottom right \n" + " c += (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy + o.zy).r) ? 1 : 0; // bottom left \n" + " c += (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy - o.zy).r) ? 1 : 0; // top right \n" + " return c / 4; \n" + "} \n"; + + outStream << + "void main_fp( \n" + " in float2 uv : TEXCOORD0, \n" + " out float4 oColor : COLOR, \n" + " uniform sampler2D texture : register(s0), \n" + " float4 positionObjSpace : TEXCOORD1, \n" + " float4 normal : TEXCOORD2, \n" + " float iDepth : TEXCOORD3, \n" + " float4 vertexColour : TEXCOORD4, \n" + " uniform float4 fogColour, \n" + " uniform float4 fogParams, \n"; + + if (shadows) outStream << + " uniform float4 shadowFar_fadeStart, \n"; + + if (shadows && !split) outStream << + " uniform sampler2D shadowMap : register(s1), \n" + " float4 lightSpacePos0 : TEXCOORD5, \n" + " uniform float4 invShadowmapSize0, \n"; + else + { + outStream << + " uniform float4 pssmSplitPoints, \n"; + for (int i=0; i shadowFar_fadeStart.x) ? 1 : ((iDepth > shadowFar_fadeStart.y) ? 1-((1-shadow)*fade) : shadow); \n" + " lightColour.xyz += shadow * lit(dot(normalize(lightDir), normalize(normal)), 0, 0).y * lightDiffuse"<setSource(outStream.str()); + fragment->load(); + + for (int i=0; igetDefaultParameters()->setNamedAutoConstant("lightPositionObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i); + fragment->getDefaultParameters()->setNamedAutoConstant("lightDiffuse"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i); + fragment->getDefaultParameters()->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i); + } + fragment->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR); + fragment->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR); + fragment->getDefaultParameters()->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR); + fragment->getDefaultParameters()->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR); + fragment->getDefaultParameters()->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR); + fragment->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); + + if (shadows) + { + fragment->getDefaultParameters()->setNamedConstant("shadowFar_fadeStart", Vector4(mRendering->getShadows()->getShadowFar(), mRendering->getShadows()->getFadeStart()*mRendering->getShadows()->getShadowFar(), 0, 0)); + for (int i=0; i < (split ? numsplits : 1); ++i) + { + fragment->getDefaultParameters()->setNamedAutoConstant("invShadowmapSize" + StringConverter::toString(i), GpuProgramParameters::ACT_INVERSE_TEXTURE_SIZE, i+1); + } + if (split) + { + Vector4 splitPoints; + const PSSMShadowCameraSetup::SplitPointList& splitPointList = mRendering->getShadows()->getPSSMSetup()->getSplitPoints(); + // Populate from split point 1, not 0, since split 0 isn't useful (usually 0) + for (int i = 1; i < numsplits; ++i) + { + splitPoints[i-1] = splitPointList[i]; + } + fragment->getDefaultParameters()->setNamedConstant("pssmSplitPoints", splitPoints); + } + } + + if (mrt) + fragment->getDefaultParameters()->setNamedAutoConstant("far", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE); + } +} diff --git a/apps/openmw/mwrender/shaderhelper.hpp b/apps/openmw/mwrender/shaderhelper.hpp new file mode 100644 index 000000000..356d345de --- /dev/null +++ b/apps/openmw/mwrender/shaderhelper.hpp @@ -0,0 +1,29 @@ +#ifndef GAME_SHADERHELPER_H +#define GAME_SHADERHELPER_H + +#include + +namespace MWRender +{ + class RenderingManager; + + /// + /// \brief manages the main shader + /// + class ShaderHelper + { + public: + ShaderHelper(RenderingManager* rend); + + void applyShaders(); + ///< apply new settings + + private: + RenderingManager* mRendering; + + void createShader(const bool mrt, const bool shadows, const bool split, const std::string& name); + }; + +} + +#endif diff --git a/apps/openmw/mwrender/shadows.cpp b/apps/openmw/mwrender/shadows.cpp new file mode 100644 index 000000000..9c150f0c6 --- /dev/null +++ b/apps/openmw/mwrender/shadows.cpp @@ -0,0 +1,175 @@ +#include "shadows.hpp" + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "renderconst.hpp" + +using namespace Ogre; +using namespace MWRender; + +Shadows::Shadows(OEngine::Render::OgreRenderer* rend) : + mShadowFar(1000), mFadeStart(0.9) +{ + mRendering = rend; + mSceneMgr = mRendering->getScene(); + recreate(); +} + +void Shadows::recreate() +{ + bool enabled = Settings::Manager::getBool("enabled", "Shadows"); + + // Split shadow maps are currently disabled because the terrain cannot cope with them + // (Too many texture units) Solution would be a multi-pass terrain material + bool split = Settings::Manager::getBool("split", "Shadows"); + //const bool split = false; + + if (!enabled) + { + mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE); + return; + } + + int texsize = Settings::Manager::getInt("texture size", "Shadows"); + mSceneMgr->setShadowTextureSize(texsize); + + mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED); + + // no point light shadows, i'm afraid. might revisit this with Deferred Shading + mSceneMgr->setShadowTextureCountPerLightType(Light::LT_POINT, 0); + + mSceneMgr->setShadowTextureCountPerLightType(Light::LT_DIRECTIONAL, split ? 3 : 1); + mSceneMgr->setShadowTextureCount(split ? 3 : 1); + + mSceneMgr->setShadowTextureSelfShadow(true); + mSceneMgr->setShadowCasterRenderBackFaces(true); + mSceneMgr->setShadowTextureCasterMaterial("depth_shadow_caster"); + mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT32_R); + mSceneMgr->setShadowDirLightTextureOffset(0.9); + mSceneMgr->setShadowDirectionalLightExtrusionDistance(1000000); + mSceneMgr->setShowDebugShadows(true); + + mShadowFar = split ? Settings::Manager::getInt("split shadow distance", "Shadows") : Settings::Manager::getInt("shadow distance", "Shadows"); + mSceneMgr->setShadowFarDistance(mShadowFar); + + mFadeStart = Settings::Manager::getFloat("fade start", "Shadows"); + + ShadowCameraSetupPtr shadowCameraSetup; + if (split) + { + mPSSMSetup = new PSSMShadowCameraSetup(); + mPSSMSetup->setSplitPadding(5); + mPSSMSetup->calculateSplitPoints(3, mRendering->getCamera()->getNearClipDistance(), mShadowFar); + + const Real adjustFactors[3] = {64, 64, 64}; + for (int i=0; i < 3; ++i) + { + mPSSMSetup->setOptimalAdjustFactor(i, adjustFactors[i]); + /*if (i==0) + mSceneMgr->setShadowTextureConfig(i, texsize, texsize, Ogre::PF_FLOAT32_R); + else if (i ==1) + mSceneMgr->setShadowTextureConfig(i, texsize/2, texsize/2, Ogre::PF_FLOAT32_R); + else if (i ==2) + mSceneMgr->setShadowTextureConfig(i, texsize/4, texsize/4, Ogre::PF_FLOAT32_R);*/ + } + + shadowCameraSetup = ShadowCameraSetupPtr(mPSSMSetup); + } + else + { + LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup(); + lispsmSetup->setOptimalAdjustFactor(2); + //lispsmSetup->setCameraLightDirectionThreshold(Degree(0)); + //lispsmSetup->setUseAggressiveFocusRegion(false); + shadowCameraSetup = ShadowCameraSetupPtr(lispsmSetup); + } + mSceneMgr->setShadowCameraSetup(shadowCameraSetup); + + // Set visibility mask for the shadow render textures + int visibilityMask = RV_Actors * Settings::Manager::getBool("actor shadows", "Shadows") + + (RV_Statics + RV_StaticsSmall) * Settings::Manager::getBool("statics shadows", "Shadows") + + RV_Misc * Settings::Manager::getBool("misc shadows", "Shadows"); + + for (int i = 0; i < (split ? 3 : 1); ++i) + { + TexturePtr shadowTexture = mSceneMgr->getShadowTexture(i); + Viewport* vp = shadowTexture->getBuffer()->getRenderTarget()->getViewport(0); + vp->setVisibilityMask(visibilityMask); + } + + // -------------------------------------------------------------------------------------------------------------------- + // --------------------------- Debug overlays to display the content of shadow maps ----------------------------------- + // -------------------------------------------------------------------------------------------------------------------- + /* + OverlayManager& mgr = OverlayManager::getSingleton(); + Overlay* overlay; + + // destroy if already exists + if (overlay = mgr.getByName("DebugOverlay")) + mgr.destroy(overlay); + + overlay = mgr.create("DebugOverlay"); + for (size_t i = 0; i < (split ? 3 : 1); ++i) { + TexturePtr tex = mRendering->getScene()->getShadowTexture(i); + + // Set up a debug panel to display the shadow + + if (MaterialManager::getSingleton().resourceExists("Ogre/DebugTexture" + StringConverter::toString(i))) + MaterialManager::getSingleton().remove("Ogre/DebugTexture" + StringConverter::toString(i)); + MaterialPtr debugMat = MaterialManager::getSingleton().create( + "Ogre/DebugTexture" + StringConverter::toString(i), + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); + TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName()); + t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); + + OverlayContainer* debugPanel; + + // destroy container if exists + try + { + if (debugPanel = + static_cast( + mgr.getOverlayElement("Ogre/DebugTexPanel" + StringConverter::toString(i) + ))) + mgr.destroyOverlayElement(debugPanel); + } + catch (Ogre::Exception&) {} + + debugPanel = (OverlayContainer*) + (OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i))); + debugPanel->_setPosition(0.8, i*0.25); + debugPanel->_setDimensions(0.2, 0.24); + debugPanel->setMaterialName(debugMat->getName()); + debugPanel->show(); + overlay->add2D(debugPanel); + overlay->show(); + } + */ +} + +PSSMShadowCameraSetup* Shadows::getPSSMSetup() +{ + return mPSSMSetup; +} + +float Shadows::getShadowFar() const +{ + return mShadowFar; +} + +float Shadows::getFadeStart() const +{ + return mFadeStart; +} diff --git a/apps/openmw/mwrender/shadows.hpp b/apps/openmw/mwrender/shadows.hpp new file mode 100644 index 000000000..bc2b141f7 --- /dev/null +++ b/apps/openmw/mwrender/shadows.hpp @@ -0,0 +1,39 @@ +#ifndef GAME_SHADOWS_H +#define GAME_SHADOWS_H + +// forward declares +namespace Ogre +{ + class SceneManager; + class PSSMShadowCameraSetup; +} +namespace OEngine{ + namespace Render{ + class OgreRenderer; + } +} + +namespace MWRender +{ + class Shadows + { + public: + Shadows(OEngine::Render::OgreRenderer* rend); + + void recreate(); + + Ogre::PSSMShadowCameraSetup* getPSSMSetup(); + float getShadowFar() const; + float getFadeStart() const; + + protected: + OEngine::Render::OgreRenderer* mRendering; + Ogre::SceneManager* mSceneMgr; + + Ogre::PSSMShadowCameraSetup* mPSSMSetup; + float mShadowFar; + float mFadeStart; + }; +} + +#endif diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 188ec3b83..859da2dc1 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -102,6 +102,7 @@ void BillboardObject::init(const String& textureName, mNode->setPosition(finalPosition); mNode->attachObject(mBBSet); mBBSet->createBillboard(0,0,0); + mBBSet->setCastShadows(false); mMaterial = MaterialManager::getSingleton().create("BillboardMaterial"+StringConverter::toString(bodyCount), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); mMaterial->removeAllTechniques(); @@ -450,6 +451,7 @@ void SkyManager::create() Entity* night1_ent = mSceneMgr->createEntity("meshes\\sky_night_01.nif"); night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1); night1_ent->setVisibilityFlags(RV_Sky); + night1_ent->setCastShadows(false); mAtmosphereNight = mRootNode->createChildSceneNode(); mAtmosphereNight->attachObject(night1_ent); @@ -525,6 +527,7 @@ void SkyManager::create() // Atmosphere (day) mesh = NifOgre::NIFLoader::load("meshes\\sky_atmosphere.nif"); Entity* atmosphere_ent = mSceneMgr->createEntity("meshes\\sky_atmosphere.nif"); + atmosphere_ent->setCastShadows(false); ModVertexAlpha(atmosphere_ent, 0); @@ -596,6 +599,7 @@ void SkyManager::create() SceneNode* clouds_node = mRootNode->createChildSceneNode(); clouds_node->attachObject(clouds_ent); mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial(); + clouds_ent->setCastShadows(false); // Clouds vertex shader HighLevelGpuProgramPtr vshader2 = mgr.createProgram("Clouds_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, @@ -677,6 +681,8 @@ void SkyManager::create() mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); mCloudMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA); + mCloudMaterial->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); + mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("textures\\tx_sky_cloudy.dds"); mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState(""); mCreated = true; @@ -766,12 +772,14 @@ void SkyManager::disable() void SkyManager::setMoonColour (bool red) { + if (!mCreated) return; mSecunda->setColour( red ? ColourValue(1.0, 0.0784, 0.0784) : ColourValue(1.0, 1.0, 1.0)); } void SkyManager::setCloudsOpacity(float opacity) { + if (!mCreated) return; mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("opacity", Real(opacity)); } @@ -927,11 +935,13 @@ void SkyManager::setThunder(const float factor) void SkyManager::setMasserFade(const float fade) { + if (!mCreated) return; mMasser->setVisibility(fade); } void SkyManager::setSecundaFade(const float fade) { + if (!mCreated) return; mSecunda->setVisibility(fade); } diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index 67dd4e0b0..f9b43655b 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -7,7 +7,8 @@ #include "terrainmaterial.hpp" #include "terrain.hpp" #include "renderconst.hpp" - +#include "shadows.hpp" +#include using namespace Ogre; @@ -16,8 +17,8 @@ namespace MWRender //---------------------------------------------------------------------------------------------- - TerrainManager::TerrainManager(Ogre::SceneManager* mgr, const MWWorld::Environment& evn) : - mEnvironment(evn), mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)) + TerrainManager::TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend, const MWWorld::Environment& evn) : + mEnvironment(evn), mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)), mRendering(rend) { TerrainMaterialGeneratorPtr matGen; @@ -48,9 +49,19 @@ namespace MWRender mActiveProfile->setLayerSpecularMappingEnabled(false); mActiveProfile->setLayerNormalMappingEnabled(false); mActiveProfile->setLayerParallaxMappingEnabled(false); - mActiveProfile->setReceiveDynamicShadowsEnabled(false); - //composite maps lead to a drastic reduction in loading time so are + bool shadows = Settings::Manager::getBool("enabled", "Shadows"); + mActiveProfile->setReceiveDynamicShadowsEnabled(shadows); + mActiveProfile->setReceiveDynamicShadowsDepth(shadows); + if (Settings::Manager::getBool("split", "Shadows")) + mActiveProfile->setReceiveDynamicShadowsPSSM(mRendering->getShadows()->getPSSMSetup()); + else + mActiveProfile->setReceiveDynamicShadowsPSSM(0); + + mActiveProfile->setShadowFar(mRendering->getShadows()->getShadowFar()); + mActiveProfile->setShadowFadeStart(mRendering->getShadows()->getFadeStart()); + + //composite maps lead to a drastic increase in loading time so are //disabled mActiveProfile->setCompositeMapEnabled(false); diff --git a/apps/openmw/mwrender/terrain.hpp b/apps/openmw/mwrender/terrain.hpp index 29a4ba36b..dc4a2388c 100644 --- a/apps/openmw/mwrender/terrain.hpp +++ b/apps/openmw/mwrender/terrain.hpp @@ -24,7 +24,7 @@ namespace MWRender{ */ class TerrainManager{ public: - TerrainManager(Ogre::SceneManager* mgr, const MWWorld::Environment& env); + TerrainManager(Ogre::SceneManager* mgr, RenderingManager* rend, const MWWorld::Environment& env); virtual ~TerrainManager(); void setDiffuse(const Ogre::ColourValue& diffuse); @@ -37,6 +37,7 @@ namespace MWRender{ Ogre::TerrainGroup mTerrainGroup; const MWWorld::Environment& mEnvironment; + RenderingManager* mRendering; Ogre::TerrainMaterialGeneratorB::SM2Profile* mActiveProfile; diff --git a/apps/openmw/mwrender/terrainmaterial.cpp b/apps/openmw/mwrender/terrainmaterial.cpp index 87798006c..57bea5388 100644 --- a/apps/openmw/mwrender/terrainmaterial.cpp +++ b/apps/openmw/mwrender/terrainmaterial.cpp @@ -86,6 +86,7 @@ namespace Ogre , mPSSM(0) , mDepthShadows(false) , mLowLodShadows(false) + , mShadowFar(1300) { } @@ -102,6 +103,24 @@ namespace Ogre terrain->_setLightMapRequired(mLightmapEnabled, true); terrain->_setCompositeMapRequired(mCompositeMapEnabled); } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorB::SM2Profile::setShadowFar(float far) + { + if (mShadowFar != far) + { + mShadowFar = far; + mParent->_markChanged(); + } + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorB::SM2Profile::setShadowFadeStart(float fadestart) + { + if (mShadowFadeStart != fadestart) + { + mShadowFadeStart = fadestart; + mParent->_markChanged(); + } + } //--------------------------------------------------------------------- void TerrainMaterialGeneratorB::SM2Profile::setLayerNormalMappingEnabled(bool enabled) { @@ -462,6 +481,7 @@ namespace Ogre StringUtil::StrStreamType sourceStr; generateFragmentProgramSource(prof, terrain, tt, sourceStr); + ret->setSource(sourceStr.str()); ret->load(); defaultFpParams(prof, terrain, tt, ret); @@ -533,8 +553,8 @@ namespace Ogre GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, i); if (prof->getReceiveDynamicShadowsDepth()) { - params->setNamedAutoConstant("depthRange" + StringConverter::toString(i), - GpuProgramParameters::ACT_SHADOW_SCENE_DEPTH_RANGE, i); + //params->setNamedAutoConstant("depthRange" + StringConverter::toString(i), + //GpuProgramParameters::ACT_SHADOW_SCENE_DEPTH_RANGE, i); } } } @@ -567,6 +587,7 @@ namespace Ogre if (prof->isShadowingEnabled(tt, terrain)) { + params->setNamedConstant("shadowFar_fadeStart", Vector4(prof->mShadowFar, prof->mShadowFadeStart * prof->mShadowFar, 0, 0)); uint numTextures = 1; if (prof->getReceiveDynamicShadowsPSSM()) { @@ -732,7 +753,7 @@ namespace Ogre ret->unload(); } - ret->setParameter("profiles", "vs_3_0 vs_2_0 arbvp1"); + ret->setParameter("profiles", "vs_3_0 vs_2_0 vp40 arbvp1"); ret->setParameter("entry_point", "main_vp"); return ret; @@ -790,9 +811,9 @@ namespace Ogre outStream << "out float4 oPos : POSITION,\n" - "out float4 oPosObj : TEXCOORD0 \n"; + "out float4 oPosObj : COLOR \n"; - uint texCoordSet = 1; + uint texCoordSet = 0; outStream << ", out float4 oUVMisc : TEXCOORD" << texCoordSet++ <<" // xy = uv, z = camDepth\n"; @@ -818,8 +839,8 @@ namespace Ogre if (fog) { outStream << - ", uniform float4 fogParams\n" - ", out float fogVal : COLOR\n"; + ", uniform float4 fogParams\n"; + //", out float fogVal : COLOR\n"; } if (prof->isShadowingEnabled(tt, terrain)) @@ -831,7 +852,7 @@ namespace Ogre if (texCoordSet > 8) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Requested options require too many texture coordinate sets! Try reducing the number of layers.", + "Requested options require too many texture coordinate sets! Try reducing the number of layers. requested: " + StringConverter::toString(texCoordSet), __FUNCTION__); } @@ -917,9 +938,9 @@ namespace Ogre outStream << "void main_fp(\n" - "float4 position : TEXCOORD0,\n"; + "float4 position : COLOR,\n"; - uint texCoordSet = 1; + uint texCoordSet = 0; outStream << "float4 uvMisc : TEXCOORD" << texCoordSet++ << ",\n"; @@ -948,8 +969,8 @@ namespace Ogre if (fog) { outStream << - "uniform float3 fogColour, \n" - "float fogVal : COLOR,\n"; + "uniform float3 fogColour, \n"; + //"float fogVal : COLOR,\n"; } uint currentSamplerIdx = 0; @@ -1046,6 +1067,7 @@ namespace Ogre " float4 outputCol;\n" " float shadow = 1.0;\n" " float2 uv = uvMisc.xy;\n" + " float fogVal = position.w; \n" // base colour " outputCol = float4(0,0,0,1);\n"; @@ -1257,13 +1279,15 @@ namespace Ogre if (terrain->getSceneManager()->getFogMode() == FOG_LINEAR) { outStream << - " fogVal = saturate((oPos.z - fogParams.y) * fogParams.w);\n"; + " float fogVal = saturate((oPos.z - fogParams.y) * fogParams.w);\n"; } else { outStream << - " fogVal = saturate(1 / (exp(oPos.z * fogParams.x)));\n"; + " float fogVal = saturate(1 / (exp(oPos.z * fogParams.x)));\n"; } + outStream << + " oPosObj.w = fogVal; \n"; } if (prof->isShadowingEnabled(tt, terrain)) @@ -1364,7 +1388,7 @@ namespace Ogre outStream << "// Simple PCF \n" "// Number of samples in one dimension (square for total samples) \n" - "#define NUM_SHADOW_SAMPLES_1D 2.0 \n" + "#define NUM_SHADOW_SAMPLES_1D 1.0 \n" "#define SHADOW_FILTER_SCALE 1 \n" "#define SHADOW_SAMPLES NUM_SHADOW_SAMPLES_1D*NUM_SHADOW_SAMPLES_1D \n" @@ -1377,28 +1401,18 @@ namespace Ogre if (prof->getReceiveDynamicShadowsDepth()) { outStream << - "float calcDepthShadow(sampler2D shadowMap, float4 uv, float invShadowMapSize) \n" - "{ \n" - " // 4-sample PCF \n" - - " float shadow = 0.0; \n" - " float offset = (NUM_SHADOW_SAMPLES_1D/2 - 0.5) * SHADOW_FILTER_SCALE; \n" - " for (float y = -offset; y <= offset; y += SHADOW_FILTER_SCALE) \n" - " for (float x = -offset; x <= offset; x += SHADOW_FILTER_SCALE) \n" - " { \n" - " float4 newUV = offsetSample(uv, float2(x, y), invShadowMapSize);\n" - " // manually project and assign derivatives \n" - " // to avoid gradient issues inside loops \n" - " newUV = newUV / newUV.w; \n" - " float depth = tex2D(shadowMap, newUV.xy, 1, 1).x; \n" - " if (depth >= 1 || depth >= uv.z)\n" - " shadow += 1.0;\n" - " } \n" - - " shadow /= SHADOW_SAMPLES; \n" - - " return shadow; \n" - "} \n"; + "float calcDepthShadow(sampler2D shadowMap, float4 shadowMapPos, float2 offset) \n" + " { \n" + " shadowMapPos = shadowMapPos / shadowMapPos.w; \n" + " float2 uv = shadowMapPos.xy; \n" + " float3 o = float3(offset, -offset.x) * 0.3f; \n" + " // Note: We using 2x2 PCF. Good enough and is alot faster. \n" + " float c = (shadowMapPos.z <= tex2D(shadowMap, uv.xy - o.xy).r) ? 1 : 0; // top left \n" + " c += (shadowMapPos.z <= tex2D(shadowMap, uv.xy + o.xy).r) ? 1 : 0; // bottom right \n" + " c += (shadowMapPos.z <= tex2D(shadowMap, uv.xy + o.zy).r) ? 1 : 0; // bottom left \n" + " c += (shadowMapPos.z <= tex2D(shadowMap, uv.xy - o.zy).r) ? 1 : 0; // top right \n" + " return c / 4; \n" + " } \n"; } else { @@ -1436,7 +1450,7 @@ namespace Ogre { outStream << "\n "; for (uint i = 0; i < numTextures; ++i) - outStream << "float invShadowmapSize" << i << ", "; + outStream << "float2 invShadowmapSize" << i << ", "; } outStream << "\n" " float4 pssmSplitPoints, float camDepth) \n" @@ -1458,7 +1472,7 @@ namespace Ogre if (prof->getReceiveDynamicShadowsDepth()) { outStream << - " shadow = calcDepthShadow(shadowMap" << i << ", lsPos" << i << ", invShadowmapSize" << i << "); \n"; + " shadow = calcDepthShadow(shadowMap" << i << ", lsPos" << i << ", invShadowmapSize" << i << ".xy); \n"; } else { @@ -1520,8 +1534,8 @@ namespace Ogre if (prof->getReceiveDynamicShadowsDepth()) { // make linear - outStream << - "oLightSpacePos" << i << ".z = (oLightSpacePos" << i << ".z - depthRange" << i << ".x) * depthRange" << i << ".w;\n"; + //outStream << + // "oLightSpacePos" << i << ".z = (oLightSpacePos" << i << ".z - depthRange" << i << ".x) * depthRange" << i << ".w;\n"; } } @@ -1538,6 +1552,8 @@ namespace Ogre // in semantics & params uint numTextures = 1; + outStream << + ", uniform float4 shadowFar_fadeStart \n"; if (prof->getReceiveDynamicShadowsPSSM()) { numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); @@ -1554,7 +1570,7 @@ namespace Ogre if (prof->getReceiveDynamicShadowsDepth()) { outStream << - ", uniform float inverseShadowmapSize" << i << " \n"; + ", uniform float4 inverseShadowmapSize" << i << " \n"; } } @@ -1589,7 +1605,7 @@ namespace Ogre { outStream << "\n "; for (uint i = 0; i < numTextures; ++i) - outStream << "inverseShadowmapSize" << i << ", "; + outStream << "inverseShadowmapSize" << i << ".xy, "; } outStream << "\n" << " pssmSplitPoints, camDepth);\n"; @@ -1600,7 +1616,7 @@ namespace Ogre if (prof->getReceiveDynamicShadowsDepth()) { outStream << - " float rtshadow = calcDepthShadow(shadowMap0, lightSpacePos0, inverseShadowmapSize0);"; + " float rtshadow = calcDepthShadow(shadowMap0, lightSpacePos0, inverseShadowmapSize0.xy);"; } else { @@ -1609,7 +1625,11 @@ namespace Ogre } } - outStream << + outStream << + " float fadeRange = shadowFar_fadeStart.x - shadowFar_fadeStart.y; \n" + " float fade = 1-((uvMisc.z - shadowFar_fadeStart.y) / fadeRange); \n" + " rtshadow = (uvMisc.z > shadowFar_fadeStart.x) ? 1 : ((uvMisc.z > shadowFar_fadeStart.y) ? 1-((1-rtshadow)*fade) : rtshadow); \n" + " rtshadow = (1-(1-rtshadow)*0.6); \n" // make the shadow a little less intensive " shadow = min(shadow, rtshadow);\n"; } diff --git a/apps/openmw/mwrender/terrainmaterial.hpp b/apps/openmw/mwrender/terrainmaterial.hpp index 3cb316347..db916bf25 100644 --- a/apps/openmw/mwrender/terrainmaterial.hpp +++ b/apps/openmw/mwrender/terrainmaterial.hpp @@ -73,6 +73,9 @@ namespace Ogre void updateParamsForCompositeMap(const MaterialPtr& mat, const Terrain* terrain); void requestOptions(Terrain* terrain); + void setShadowFar(float far); + void setShadowFadeStart(float fadestart); + /** Whether to support normal mapping per layer in the shader (default true). */ bool isLayerNormalMappingEnabled() const { return mLayerNormalMappingEnabled; } @@ -245,6 +248,8 @@ namespace Ogre bool mDepthShadows; bool mLowLodShadows; bool mSM3Available; + float mShadowFar; + float mShadowFadeStart; bool isShadowingEnabled(TechniqueType tt, const Terrain* terrain) const; diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 7981def0b..85fb2ee99 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -31,6 +31,7 @@ Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : mWater = mSceneManager->createEntity("water"); mWater->setVisibilityFlags(RV_Water); mWater->setRenderQueueGroup(RQG_Water); + mWater->setCastShadows(false); mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water") + RV_Statics * Settings::Manager::getBool("reflect statics", "Water") @@ -42,6 +43,8 @@ Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode(); mWaterNode->setPosition(0, mTop, 0); + mReflectionCamera = mSceneManager->createCamera("ReflectionCamera"); + if(!(cell->data.flags & cell->Interior)) { mWaterNode->setPosition(getSceneNodeCoordinates(cell->data.gridX, cell->data.gridY)); @@ -51,17 +54,20 @@ Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : // Create rendertarget for reflection int rttsize = Settings::Manager::getInt("rtt size", "Water"); + TexturePtr tex; if (Settings::Manager::getBool("shader", "Water")) { - TexturePtr tex = TextureManager::getSingleton().createManual("WaterReflection", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, rttsize, rttsize, 0, PF_R8G8B8, TU_RENDERTARGET); + tex = TextureManager::getSingleton().createManual("WaterReflection", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, rttsize, rttsize, 0, PF_FLOAT16_RGBA, TU_RENDERTARGET); RenderTarget* rtt = tex->getBuffer()->getRenderTarget(); - Viewport* vp = rtt->addViewport(mCamera); + Viewport* vp = rtt->addViewport(mReflectionCamera); vp->setOverlaysEnabled(false); vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f)); vp->setShadowsEnabled(false); vp->setVisibilityMask( mVisibilityFlags ); + // use fallback techniques without shadows and without mrt (currently not implemented for sky and terrain) + //vp->setMaterialScheme("Fallback"); rtt->addListener(this); rtt->setActive(true); @@ -74,6 +80,55 @@ Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : mWater->setMaterial(mMaterial); mUnderwaterEffect = Settings::Manager::getBool("underwater effect", "Water"); + + + // ---------------------------------------------------------------------------------------------- + // ---------------------------------- reflection debug overlay ---------------------------------- + // ---------------------------------------------------------------------------------------------- + /* + if (Settings::Manager::getBool("shader", "Water")) + { + OverlayManager& mgr = OverlayManager::getSingleton(); + Overlay* overlay; + // destroy if already exists + if (overlay = mgr.getByName("ReflectionDebugOverlay")) + mgr.destroy(overlay); + + overlay = mgr.create("ReflectionDebugOverlay"); + + if (MaterialManager::getSingleton().resourceExists("Ogre/ReflectionDebugTexture")) + MaterialManager::getSingleton().remove("Ogre/ReflectionDebugTexture"); + MaterialPtr debugMat = MaterialManager::getSingleton().create( + "Ogre/ReflectionDebugTexture", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); + TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName()); + t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); + + OverlayContainer* debugPanel; + + // destroy container if exists + try + { + if (debugPanel = + static_cast( + mgr.getOverlayElement("Ogre/ReflectionDebugTexPanel" + ))) + mgr.destroyOverlayElement(debugPanel); + } + catch (Ogre::Exception&) {} + + debugPanel = (OverlayContainer*) + (OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/ReflectionDebugTexPanel")); + debugPanel->_setPosition(0, 0.55); + debugPanel->_setDimensions(0.3, 0.3); + debugPanel->setMaterialName(debugMat->getName()); + debugPanel->show(); + overlay->add2D(debugPanel); + overlay->show(); + } + */ } void Water::setActive(bool active) @@ -162,6 +217,12 @@ Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY) void Water::preRenderTargetUpdate(const RenderTargetEvent& evt) { + mReflectionCamera->setOrientation(mCamera->getDerivedOrientation()); + mReflectionCamera->setPosition(mCamera->getDerivedPosition()); + mReflectionCamera->setNearClipDistance(mCamera->getNearClipDistance()); + mReflectionCamera->setFarClipDistance(mCamera->getFarClipDistance()); + mReflectionCamera->setAspectRatio(mCamera->getAspectRatio()); + mReflectionCamera->setFOVy(mCamera->getFOVy()); if (evt.source == mReflectionTarget) { mWater->setVisible(false); @@ -174,8 +235,8 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt) mSky->setSkyPosition(pos); mSky->scaleSky(mCamera->getFarClipDistance() / 1000.f); - mCamera->enableCustomNearClipPlane(Plane(Vector3::UNIT_Y, mTop)); - mCamera->enableReflection(Plane(Vector3::UNIT_Y, mTop)); + mReflectionCamera->enableCustomNearClipPlane(Plane(Vector3::UNIT_Y, mTop)); + mReflectionCamera->enableReflection(Plane(Vector3::UNIT_Y, mTop)); } } @@ -187,8 +248,8 @@ void Water::postRenderTargetUpdate(const RenderTargetEvent& evt) { mSky->resetSkyPosition(); mSky->scaleSky(1); - mCamera->disableReflection(); - mCamera->disableCustomNearClipPlane(); + mReflectionCamera->disableCustomNearClipPlane(); + mReflectionCamera->disableReflection(); } } diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 0e23f5b0c..3fb1b07b7 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -39,6 +39,8 @@ namespace MWRender { void createMaterial(); Ogre::MaterialPtr mMaterial; + Ogre::Camera* mReflectionCamera; + Ogre::RenderTarget* mReflectionTarget; bool mUnderwaterEffect; diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 835534eff..02e4e5447 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -291,6 +291,42 @@ void NIFLoader::createMaterial(const String &name, else warn("Unhandled alpha setting for texture " + texName); } + else + { + material->getTechnique(0)->setShadowCasterMaterial("depth_shadow_caster_noalpha"); + } + } + + if (Settings::Manager::getBool("enabled", "Shadows")) + { + bool split = Settings::Manager::getBool("split", "Shadows"); + const int numsplits = 3; + for (int i = 0; i < (split ? numsplits : 1); ++i) + { + TextureUnitState* tu = material->getTechnique(0)->getPass(0)->createTextureUnitState(); + tu->setName("shadowMap" + StringConverter::toString(i)); + tu->setContentType(TextureUnitState::CONTENT_SHADOW); + tu->setTextureAddressingMode(TextureUnitState::TAM_BORDER); + tu->setTextureBorderColour(ColourValue::White); + } + } + + if (Settings::Manager::getBool("shaders", "Objects")) + { + material->getTechnique(0)->getPass(0)->setVertexProgram("main_vp"); + material->getTechnique(0)->getPass(0)->setFragmentProgram("main_fp"); + } + + // Create a fallback technique without shadows and without mrt + Technique* tech2 = material->createTechnique(); + tech2->setSchemeName("Fallback"); + Pass* pass2 = tech2->createPass(); + pass2->createTextureUnitState(texName); + pass2->setVertexColourTracking(TVC_DIFFUSE); + if (Settings::Manager::getBool("shaders", "Objects")) + { + pass2->setVertexProgram("main_fallback_vp"); + pass2->setFragmentProgram("main_fallback_fp"); } // Add material bells and whistles @@ -299,151 +335,6 @@ void NIFLoader::createMaterial(const String &name, material->setSpecular(specular.array[0], specular.array[1], specular.array[2], alpha); material->setSelfIllumination(emissive.array[0], emissive.array[1], emissive.array[2]); material->setShininess(glossiness); - - if (Settings::Manager::getBool("shaders", "Objects")) - { - bool mrt = Settings::Manager::getBool("shader", "Water"); - - // Create shader for the material - // vertex - HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); - - HighLevelGpuProgramPtr vertex; - if (mgr.getByName("main_vp").isNull()) - { - vertex = mgr.createProgram("main_vp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - "cg", GPT_VERTEX_PROGRAM); - vertex->setParameter("profiles", "vs_4_0 vs_2_x vp40 arbvp1"); - vertex->setParameter("entry_point", "main_vp"); - StringUtil::StrStreamType outStream; - outStream << - "void main_vp( \n" - " float4 position : POSITION, \n" - " float4 normal : NORMAL, \n" - " float4 colour : COLOR, \n" - " in float2 uv : TEXCOORD0, \n" - " out float2 oUV : TEXCOORD0, \n" - " out float4 oPosition : POSITION, \n" - " out float4 oPositionObjSpace : TEXCOORD1, \n" - " out float4 oNormal : TEXCOORD2, \n" - " out float oDepth : TEXCOORD3, \n" - " out float4 oVertexColour : TEXCOORD4, \n" - " uniform float4x4 worldViewProj \n" - ") \n" - "{ \n" - " oVertexColour = colour; \n" - " oUV = uv; \n" - " oNormal = normal; \n" - " oPosition = mul( worldViewProj, position ); \n" - " oDepth = oPosition.z; \n" - " oPositionObjSpace = position; \n" - "}"; - vertex->setSource(outStream.str()); - vertex->load(); - vertex->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); - } - else - vertex = mgr.getByName("main_vp"); - material->getTechnique(0)->getPass(0)->setVertexProgram(vertex->getName()); - - // the number of lights to support. - // when rendering an object, OGRE automatically picks the lights that are - // closest to the object being rendered. unfortunately this mechanism does - // not work perfectly for objects batched together (they will all use the same - // lights). to work around this, we are simply pushing the maximum number - // of lights here in order to minimize disappearing lights. - int num_lights = Settings::Manager::getInt("num lights", "Objects"); - - // fragment - HighLevelGpuProgramPtr fragment; - if (mgr.getByName("main_fp").isNull()) - { - fragment = mgr.createProgram("main_fp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - "cg", GPT_FRAGMENT_PROGRAM); - fragment->setParameter("profiles", "ps_4_0 ps_2_x fp40 arbfp1"); - fragment->setParameter("entry_point", "main_fp"); - StringUtil::StrStreamType outStream; - outStream << - "void main_fp( \n" - " in float2 uv : TEXCOORD0, \n" - " out float4 oColor : COLOR, \n" - " uniform sampler2D texture : TEXUNIT0, \n" - " float4 positionObjSpace : TEXCOORD1, \n" - " float4 normal : TEXCOORD2, \n" - " float iDepth : TEXCOORD3, \n" - " float4 vertexColour : TEXCOORD4, \n" - " uniform float4 fogColour, \n" - " uniform float4 fogParams, \n"; - - if (mrt) outStream << - " out float4 oColor1 : COLOR1, \n" - " uniform float far, \n"; - - for (int i=0; isetSource(outStream.str()); - fragment->load(); - - for (int i=0; igetDefaultParameters()->setNamedAutoConstant("lightPositionObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i); - fragment->getDefaultParameters()->setNamedAutoConstant("lightDiffuse"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i); - fragment->getDefaultParameters()->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i); - } - fragment->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR); - fragment->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR); - fragment->getDefaultParameters()->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR); - fragment->getDefaultParameters()->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR); - fragment->getDefaultParameters()->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR); - fragment->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); - if (mrt) - fragment->getDefaultParameters()->setNamedAutoConstant("far", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE); - } - else - fragment = mgr.getByName("main_fp"); - material->getTechnique(0)->getPass(0)->setFragmentProgram(fragment->getName()); - } } // Takes a name and adds a unique part to it. This is just used to diff --git a/files/CMakeLists.txt b/files/CMakeLists.txt index 507f82c1a..8ab3d5b51 100644 --- a/files/CMakeLists.txt +++ b/files/CMakeLists.txt @@ -11,3 +11,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/water.cg "${OpenMW_BINARY_DIR}/ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.cg "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.cg" COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.material "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.material" COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.compositor "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.compositor" COPYONLY) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/shadows/depthshadowcaster.material "${OpenMW_BINARY_DIR}/resources/shadows/depthshadowcaster.material" COPYONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/shadows/depthshadowcaster.cg "${OpenMW_BINARY_DIR}/resources/shadows/depthshadowcaster.cg" COPYONLY) diff --git a/files/settings-default.cfg b/files/settings-default.cfg index d5a8bdfd4..4d2d46fca 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -18,6 +18,32 @@ anisotropy = 4 # Number of texture mipmaps to generate num mipmaps = 5 +[Shadows] +# Shadows are only supported when object shaders are on! +enabled = false + +# Split the shadow maps, allows for a larger shadow distance +# Warning: enabling this will cause some terrain textures to disappear due to +# hitting the texture unit limit of the terrain material +split = false + +# Increasing shadow distance will lower the shadow quality. +# Uses "shadow distance" or "split shadow distance" depending on "split" setting. +shadow distance = 1300 +# This one shouldn't be too low, otherwise you'll see artifacts. Use at least 2x max viewing distance. +split shadow distance = 14000 + +# Size of the shadow textures, higher means higher quality +texture size = 1024 + +# Turn on/off various shadow casters +actor shadows = true +misc shadows = true +statics shadows = true + +# Fraction of the total shadow distance after which the shadow starts to fade out +fade start = 0.8 + [HUD] # FPS counter # 0: not visible @@ -64,15 +90,10 @@ num lights = 8 shader = true rtt size = 512 - reflect terrain = true - reflect statics = false - reflect small statics = false - reflect actors = true - reflect misc = false # Enable underwater effect. It is not resource intensive, so only disable it if you have problems. diff --git a/files/shadows/depthshadowcaster.cg b/files/shadows/depthshadowcaster.cg new file mode 100644 index 000000000..3457a4f8d --- /dev/null +++ b/files/shadows/depthshadowcaster.cg @@ -0,0 +1,51 @@ +void main_vp( + float4 position : POSITION, + float2 uv : TEXCOORD0, + + out float4 oPosition : POSITION, + out float2 oDepth : TEXCOORD0, + out float2 oUv : TEXCOORD1, + + uniform float4x4 wvpMat) +{ + // this is the view space position + oPosition = mul(wvpMat, position); + + // depth info for the fragment. + oDepth.x = oPosition.z; + oDepth.y = oPosition.w; + + // clamp z to zero. seem to do the trick. :-/ + oPosition.z = max(oPosition.z, 0); + + oUv = uv; +} + +void main_fp( + float2 depth : TEXCOORD0, + float2 uv : TEXCOORD1, + uniform sampler2D texture1 : register(s0), + + out float4 oColour : COLOR) +{ + float finalDepth = depth.x / depth.y; + + // use alpha channel of the first texture + float alpha = tex2D(texture1, uv).a; + + // discard if alpha is less than 0.5 + clip((alpha >= 0.5) ? 1 : -1); + + oColour = float4(finalDepth, finalDepth, finalDepth, 1); +} + +void main_fp_noalpha( + float2 depth : TEXCOORD0, + float2 uv : TEXCOORD1, + + out float4 oColour : COLOR) +{ + float finalDepth = depth.x / depth.y; + + oColour = float4(finalDepth, finalDepth, finalDepth, 1); +} diff --git a/files/shadows/depthshadowcaster.material b/files/shadows/depthshadowcaster.material new file mode 100644 index 000000000..9ff51c5b1 --- /dev/null +++ b/files/shadows/depthshadowcaster.material @@ -0,0 +1,67 @@ +vertex_program depth_shadow_caster_vs cg +{ + source depthshadowcaster.cg + profiles vs_1_1 arbvp1 + entry_point main_vp + + default_params + { + param_named_auto wvpMat worldviewproj_matrix + } +} + +fragment_program depth_shadow_caster_ps cg +{ + source depthshadowcaster.cg + profiles ps_2_0 arbfp1 + entry_point main_fp + + default_params + { + } +} + +fragment_program depth_shadow_caster_ps_noalpha cg +{ + source depthshadowcaster.cg + profiles ps_2_0 arbfp1 + entry_point main_fp_noalpha + + default_params + { + } +} + +material depth_shadow_caster +{ + technique + { + pass + { + vertex_program_ref depth_shadow_caster_vs + { + } + + fragment_program_ref depth_shadow_caster_ps + { + } + } + } +} + +material depth_shadow_caster_noalpha +{ + technique + { + pass + { + vertex_program_ref depth_shadow_caster_vs + { + } + + fragment_program_ref depth_shadow_caster_ps_noalpha + { + } + } + } +} diff --git a/files/water/water.material b/files/water/water.material index 7ce6e7ba2..8b4ff96f5 100644 --- a/files/water/water.material +++ b/files/water/water.material @@ -92,7 +92,7 @@ material Water } technique { - scheme Map + scheme Fallback pass { cull_hardware none From 750d79eaf032ca8bd21f33899853e5a3595e311c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 11 Apr 2012 18:29:36 +0200 Subject: [PATCH 26/74] added spell container class --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwmechanics/spells.cpp | 77 ++++++++++++++++++++++++++++++ apps/openmw/mwmechanics/spells.hpp | 55 +++++++++++++++++++++ 3 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 apps/openmw/mwmechanics/spells.cpp create mode 100644 apps/openmw/mwmechanics/spells.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index c31a9d8fd..79f0948f9 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -55,7 +55,7 @@ add_openmw_dir (mwclass ) add_openmw_dir (mwmechanics - mechanicsmanager stat creaturestats magiceffects movement + mechanicsmanager stat creaturestats magiceffects movement spells ) # Main executable diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp new file mode 100644 index 000000000..2b28f0c2f --- /dev/null +++ b/apps/openmw/mwmechanics/spells.cpp @@ -0,0 +1,77 @@ + +#include "spells.hpp" + +#include + +#include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" + +#include "magiceffects.hpp" + +namespace MWMechanics +{ + void Spells::addSpell (const ESM::Spell *spell, MagicEffects& effects) const + { + for (std::vector::const_iterator iter = spell->effects.list.begin(); + iter!=spell->effects.list.end(); ++iter) + { + EffectParam param; + param.mMagnitude = iter->magnMax; /// \todo calculate magnitude + effects.add (EffectKey (*iter), param); + } + } + + Spells::TIterator Spells::begin (ESM::Spell::SpellType type) const + { + assert (type>=0 && type=0 && typegetStore().spells.find (spellId); + + int type = spell->data.type; + + assert (type>=0 && typegetStore().spells.find (spellId); + + int type = spell->data.type; + + TContainer::iterator iter = std::find (mSpells[type].begin(), mSpells[type].end(), spell); + + if (iter!=mSpells[type].end()) + mSpells[type].erase (iter); + } + + MagicEffects Spells::getMagicEffects (MWWorld::Environment& environment) const + { + MagicEffects effects; + + for (int i=ESM::Spell::ST_Ability; i<=ESM::Spell::ST_Curse; ++i) + for (TIterator iter (begin (static_cast (i))); + iter!=end(static_cast (i)); ++iter) + addSpell (*iter, effects); + + return effects; + } + + void Spells::clear() + { + for (int i=0; i + +#include + +namespace MWWorld +{ + struct Environment; +} + +namespace MWMechanics +{ + class MagicEffects; + + /// \brief Spell list + /// + /// This class manages known spells as well as abilities, powers and permanent negative effects like + /// diseaes. + class Spells + { + public: + + typedef std::vector TContainer; + typedef TContainer::const_iterator TIterator; + + private: + + static const int sTypes = 6; + + std::vector mSpells[sTypes]; + + void addSpell (const ESM::Spell *, MagicEffects& effects) const; + + public: + + TIterator begin (ESM::Spell::SpellType type) const; + + TIterator end (ESM::Spell::SpellType type) const; + + void add (const std::string& spell, MWWorld::Environment& environment); + /// \note Adding a spell that is already listed in *this is a no-op. + + void remove (const std::string& spell, MWWorld::Environment& environment); + + MagicEffects getMagicEffects (MWWorld::Environment& environment) const; + ///< Return sum of magic effects resulting from abilities, blights, deseases and curses. + + void clear(); + ///< Remove all spells of al types. + }; +} + +#endif From e04ccfced0867c27f8ab049096abad91f9a65b09 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 11 Apr 2012 19:03:36 +0200 Subject: [PATCH 27/74] replaced old abilities container in CreatureStats with a Spells object --- apps/openmw/mwmechanics/creaturestats.hpp | 3 +- apps/openmw/mwmechanics/mechanicsmanager.cpp | 55 ++------------------ apps/openmw/mwmechanics/mechanicsmanager.hpp | 2 - 3 files changed, 7 insertions(+), 53 deletions(-) diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index d2edc031d..ab008da9e 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -6,6 +6,7 @@ #include "stat.hpp" #include "magiceffects.hpp" +#include "spells.hpp" namespace MWMechanics { @@ -14,7 +15,7 @@ namespace MWMechanics Stat mAttributes[8]; DynamicStat mDynamic[3]; // health, magicka, fatigue int mLevel; - std::set mAbilities; + Spells mSpells; MagicEffects mMagicEffects; }; } diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index 7ed81f785..00453eee5 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -23,7 +23,7 @@ namespace MWMechanics // reset creatureStats.mLevel = player->npdt52.level; - creatureStats.mAbilities.clear(); + creatureStats.mSpells.clear(); creatureStats.mMagicEffects = MagicEffects(); for (int i=0; i<27; ++i) @@ -71,7 +71,7 @@ namespace MWMechanics for (std::vector::const_iterator iter (race->powers.list.begin()); iter!=race->powers.list.end(); ++iter) { - insertSpell (*iter, ptr); + creatureStats.mSpells.add (*iter, mEnvironment); } } @@ -85,7 +85,7 @@ namespace MWMechanics for (std::vector::const_iterator iter (sign->powers.list.begin()); iter!=sign->powers.list.end(); ++iter) { - insertSpell (*iter, ptr); + creatureStats.mSpells.add (*iter, mEnvironment); } } @@ -159,59 +159,14 @@ namespace MWMechanics creatureStats.mDynamic[i].setCurrent (creatureStats.mDynamic[i].getModified()); } - void MechanicsManager::insertSpell (const std::string& id, MWWorld::Ptr& creature) - { - MWMechanics::CreatureStats& creatureStats = - MWWorld::Class::get (creature).getCreatureStats (creature); - - const ESM::Spell *spell = mEnvironment.mWorld->getStore().spells.find (id); - - switch (spell->data.type) - { - case ESM::Spell::ST_Ability: - - if (creatureStats.mAbilities.find (id)==creatureStats.mAbilities.end()) - { - creatureStats.mAbilities.insert (id); - } - - break; - - // TODO ST_SPELL, ST_Blight, ST_Disease, ST_Curse, ST_Power - - default: - - std::cout - << "adding unsupported spell type (" << spell->data.type - << ") to creature: " << id << std::endl; - } - } - void MechanicsManager::adjustMagicEffects (MWWorld::Ptr& creature) { MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (creature).getCreatureStats (creature); - MagicEffects now; + MagicEffects now = creatureStats.mSpells.getMagicEffects (mEnvironment); - for (std::set::const_iterator iter (creatureStats.mAbilities.begin()); - iter!=creatureStats.mAbilities.end(); ++iter) - { - const ESM::Spell *spell = mEnvironment.mWorld->getStore().spells.find (*iter); - - for (std::vector::const_iterator iter = spell->effects.list.begin(); - iter!=spell->effects.list.end(); ++iter) - { - if (iter->range==0) // self - { - EffectParam param; - param.mMagnitude = iter->magnMax; // TODO calculate magnitude - now.add (EffectKey (*iter), param); - } - } - } - - // TODO add effects from other spell types, active spells and equipment + /// \todo add effects from active spells and equipment MagicEffects diff = MagicEffects::diff (creatureStats.mMagicEffects, now); diff --git a/apps/openmw/mwmechanics/mechanicsmanager.hpp b/apps/openmw/mwmechanics/mechanicsmanager.hpp index 2e2192638..8975329dd 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.hpp @@ -37,8 +37,6 @@ namespace MWMechanics ///< build player according to stored class/race/birthsign information. Will /// default to the values of the ESM::NPC object, if no explicit information is given. - void insertSpell (const std::string& id, MWWorld::Ptr& creature); - void adjustMagicEffects (MWWorld::Ptr& creature); public: From 77065390d7de2c09a9972e3fda90c9ed73255644 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 11 Apr 2012 19:40:42 +0200 Subject: [PATCH 28/74] simplifying Spells class --- apps/openmw/mwmechanics/mechanicsmanager.cpp | 4 +- apps/openmw/mwmechanics/spells.cpp | 53 ++++++++------------ apps/openmw/mwmechanics/spells.hpp | 24 +++++---- 3 files changed, 37 insertions(+), 44 deletions(-) diff --git a/apps/openmw/mwmechanics/mechanicsmanager.cpp b/apps/openmw/mwmechanics/mechanicsmanager.cpp index 00453eee5..414faa414 100644 --- a/apps/openmw/mwmechanics/mechanicsmanager.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanager.cpp @@ -71,7 +71,7 @@ namespace MWMechanics for (std::vector::const_iterator iter (race->powers.list.begin()); iter!=race->powers.list.end(); ++iter) { - creatureStats.mSpells.add (*iter, mEnvironment); + creatureStats.mSpells.add (*iter); } } @@ -85,7 +85,7 @@ namespace MWMechanics for (std::vector::const_iterator iter (sign->powers.list.begin()); iter!=sign->powers.list.end(); ++iter) { - creatureStats.mSpells.add (*iter, mEnvironment); + creatureStats.mSpells.add (*iter); } } diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index 2b28f0c2f..4e8c6fa5a 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -1,7 +1,7 @@ #include "spells.hpp" -#include +#include #include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" @@ -21,57 +21,48 @@ namespace MWMechanics } } - Spells::TIterator Spells::begin (ESM::Spell::SpellType type) const + Spells::TIterator Spells::begin() const { - assert (type>=0 && type=0 && typegetStore().spells.find (spellId); - - int type = spell->data.type; - - assert (type>=0 && typegetStore().spells.find (spellId); + TContainer::iterator iter = std::find (mSpells.begin(), mSpells.end(), spellId); - int type = spell->data.type; - - TContainer::iterator iter = std::find (mSpells[type].begin(), mSpells[type].end(), spell); - - if (iter!=mSpells[type].end()) - mSpells[type].erase (iter); + if (iter!=mSpells.end()) + mSpells.erase (iter); } - MagicEffects Spells::getMagicEffects (MWWorld::Environment& environment) const + MagicEffects Spells::getMagicEffects (const MWWorld::Environment& environment) const { MagicEffects effects; - for (int i=ESM::Spell::ST_Ability; i<=ESM::Spell::ST_Curse; ++i) - for (TIterator iter (begin (static_cast (i))); - iter!=end(static_cast (i)); ++iter) - addSpell (*iter, effects); + for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter) + { + const ESM::Spell *spell = environment.mWorld->getStore().spells.find (*iter); + + if (spell->data.type==ESM::Spell::ST_Ability || spell->data.type==ESM::Spell::ST_Blight || + spell->data.type==ESM::Spell::ST_Disease || spell->data.type==ESM::Spell::ST_Curse) + addSpell (spell, effects); + } return effects; } void Spells::clear() { - for (int i=0; i - #include +#include + +namespace ESM +{ + struct Spell; +} namespace MWWorld { @@ -22,29 +26,27 @@ namespace MWMechanics { public: - typedef std::vector TContainer; + typedef std::vector TContainer; typedef TContainer::const_iterator TIterator; private: - static const int sTypes = 6; - - std::vector mSpells[sTypes]; + std::vector mSpells; void addSpell (const ESM::Spell *, MagicEffects& effects) const; public: - TIterator begin (ESM::Spell::SpellType type) const; + TIterator begin() const; - TIterator end (ESM::Spell::SpellType type) const; + TIterator end() const; - void add (const std::string& spell, MWWorld::Environment& environment); + void add (const std::string& spell); /// \note Adding a spell that is already listed in *this is a no-op. - void remove (const std::string& spell, MWWorld::Environment& environment); + void remove (const std::string& spell); - MagicEffects getMagicEffects (MWWorld::Environment& environment) const; + MagicEffects getMagicEffects (const MWWorld::Environment& environment) const; ///< Return sum of magic effects resulting from abilities, blights, deseases and curses. void clear(); From 26a529111c760e639321b87a6659e0875be0fe67 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 11 Apr 2012 19:45:56 +0200 Subject: [PATCH 29/74] removed old known spell list from NpcStats --- apps/openmw/mwclass/npc.cpp | 2 +- apps/openmw/mwmechanics/npcstats.hpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 2cf4cf41c..57cc3560a 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -63,7 +63,7 @@ namespace MWClass for (std::vector::const_iterator iter (ref->base->spells.list.begin()); iter!=ref->base->spells.list.end(); ++iter) - data->mNpcStats.mKnownSpells.insert (*iter); + data->mCreatureStats.mSpells.add (*iter); // creature stats data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength); diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 59bfa2ac0..ece85f893 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -11,6 +11,8 @@ namespace MWMechanics /// \brief Additional stats for NPCs /// /// For non-NPC-specific stats, see the CreatureStats struct. + /// + /// \note For technical reasons the spell list is also handled by CreatureStats. struct NpcStats { @@ -26,7 +28,6 @@ namespace MWMechanics bool mSneak; bool mCombat; - std::set mKnownSpells; std::string mSelectedSpell; // can be an empty string (no spell selected) NpcStats() : mForceRun (false), mForceSneak (false), mRun (false), mSneak (false), From a727bcd4a405c1d9007b00d609114cb39b7c98cd Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 11 Apr 2012 20:13:15 +0200 Subject: [PATCH 30/74] override nif transparency settings (part 1) --- CMakeLists.txt | 4 ++ apps/openmw/engine.cpp | 8 +++ components/CMakeLists.txt | 4 ++ components/nifogre/ogre_nif_loader.cpp | 19 ++++-- components/nifoverrides/nifoverrides.cpp | 37 ++++++++++ components/nifoverrides/nifoverrides.hpp | 23 +++++++ files/transparency-overrides.cfg | 86 ++++++++++++++++++++++++ 7 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 components/nifoverrides/nifoverrides.cpp create mode 100644 components/nifoverrides/nifoverrides.hpp create mode 100644 files/transparency-overrides.cfg diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b87e3544..21de30bac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,6 +227,9 @@ endif (APPLE) configure_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg "${OpenMW_BINARY_DIR}/settings-default.cfg") +configure_file(${OpenMW_SOURCE_DIR}/files/transparency-overrides.cfg + "${OpenMW_BINARY_DIR}/transparency-overrides.cfg") + configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local "${OpenMW_BINARY_DIR}/openmw.cfg") configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg @@ -308,6 +311,7 @@ if(DPKG_PROGRAM) #Install global configuration files INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") + INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "../etc/openmw/" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 1adcf8dca..d5ff165f8 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -349,6 +350,13 @@ void OMW::Engine::go() mFpsLevel = settings.getInt("fps", "HUD"); + // load nif overrides + NifOverrides::Overrides nifOverrides; + if (boost::filesystem::exists(mCfgMgr.getLocalPath().string() + "/transparency-overrides.cfg")) + nifOverrides.loadTransparencyOverrides(mCfgMgr.getLocalPath().string() + "/transparency-overrides.cfg"); + else if (boost::filesystem::exists(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg")) + nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"); + mOgre->configure(!boost::filesystem::is_regular_file(mCfgMgr.getOgreConfigPath()), mCfgMgr.getOgreConfigPath().string(), mCfgMgr.getLogPath().string(), diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index b48c50640..8a1875d0f 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -6,6 +6,10 @@ add_component_dir (settings settings ) +add_component_dir (nifoverrides + nifoverrides + ) + add_component_dir (bsa bsa_archive bsa_file ) diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 02e4e5447..6f5142796 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -26,6 +26,7 @@ #include "ogre_nif_loader.hpp" #include +#include typedef unsigned char ubyte; @@ -282,11 +283,21 @@ void NIFLoader::createMaterial(const String &name, // other values. 237 basically means normal transparencly. if (alphaFlags == 237) { - // Enable transparency - pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); + NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName); + if (result.first) + { + pass->setAlphaRejectFunction(CMPF_GREATER_EQUAL); + pass->setAlphaRejectValue(result.second); + } + else + { + // Enable transparency + pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); - //pass->setDepthCheckEnabled(false); - pass->setDepthWriteEnabled(false); + //pass->setDepthCheckEnabled(false); + pass->setDepthWriteEnabled(false); + std::cout << "alpha 237; material: " << name << " texName: " << texName << std::endl; + } } else warn("Unhandled alpha setting for texture " + texName); diff --git a/components/nifoverrides/nifoverrides.cpp b/components/nifoverrides/nifoverrides.cpp new file mode 100644 index 000000000..1c8fefd24 --- /dev/null +++ b/components/nifoverrides/nifoverrides.cpp @@ -0,0 +1,37 @@ +#include "nifoverrides.hpp" + +#include + +#include + +using namespace NifOverrides; + +Ogre::ConfigFile Overrides::mTransparencyOverrides = Ogre::ConfigFile(); + +void Overrides::loadTransparencyOverrides (const std::string& file) +{ + mTransparencyOverrides.load(file); +} + +TransparencyResult Overrides::getTransparencyOverride(const std::string& texture) +{ + TransparencyResult result; + result.first = false; + + std::string tex = texture; + boost::to_lower(tex); + + Ogre::ConfigFile::SectionIterator seci = mTransparencyOverrides.getSectionIterator(); + while (seci.hasMoreElements()) + { + Ogre::String sectionName = seci.peekNextKey(); + if (sectionName == tex) + { + result.first = true; + result.second = Ogre::StringConverter::parseInt(mTransparencyOverrides.getSetting("alphaRejectValue", sectionName)); + break; + } + seci.getNext(); + } + return result; +} diff --git a/components/nifoverrides/nifoverrides.hpp b/components/nifoverrides/nifoverrides.hpp new file mode 100644 index 000000000..c9b711df6 --- /dev/null +++ b/components/nifoverrides/nifoverrides.hpp @@ -0,0 +1,23 @@ +#ifndef COMPONENTS_NIFOVERRIDES_H +#define COMPONENTS_NIFOVERRIDES_H + +#include + +namespace NifOverrides +{ + + typedef std::pair TransparencyResult; + + /// \brief provide overrides for some model / texture properties that bethesda has chosen poorly + class Overrides + { + public: + static Ogre::ConfigFile mTransparencyOverrides; + void loadTransparencyOverrides (const std::string& file); + + static TransparencyResult getTransparencyOverride(const std::string& texture); + }; + +} + +#endif diff --git a/files/transparency-overrides.cfg b/files/transparency-overrides.cfg new file mode 100644 index 000000000..7750e9834 --- /dev/null +++ b/files/transparency-overrides.cfg @@ -0,0 +1,86 @@ +# Bethesda has used wrong transparency settings for many textures +# (who would have guessed) +# This is very unfortunate because objects with real transparency: +# - cannot cast shadows +# - cannot receive advanced framebuffer effects like depth of field or ambient occlusion +# - cannot cover lens flare effects (the lens flare will just shine through) + +# This file lists textures that should be using alpha rejection instead of transparency +# basically these are textures that are not translucent (i.e. at one spot on the texture, either transparent or opaque) + +# Note: all the texture names here have to be lowercase + +[textures\tx_flag_imp_01.dds] + alphaRejectValue = 128 + +[textures\tx_ivy_02.dds] + alphaRejectValue = 128 + +[textures\tx_ivy_01.dds] + alphaRejectValue = 128 + +[textures\tx_sail.dds] + alphaRejectValue = 128 + +[textures\tx_saltrice_04.dds] + alphaRejectValue = 128 + +[textures\tx_black_lichen_01.dds] + alphaRejectValue = 128 + +[textures\tx_leaves_01.dds] + alphaRejectValue = 128 + +[textures\tx_leaves_02.dds] + alphaRejectValue = 128 + +[textures\tx_leaves_03.dds] + alphaRejectValue = 128 + +[textures\tx_ai_heather_01.dds] + alphaRejectValue = 96 + +[textures\tx_goldkanet_01.dds] + alphaRejectValue = 128 + +[textures\tx_goldkanet_02.dds] + alphaRejectValue = 128 + +[textures\tx_plant_tails00.dds] + alphaRejectValue = 128 + +[textures\tx_vine_01.dds] + alphaRejectValue = 128 + +[textures\tx_comberry_01.dds] + alphaRejectValue = 128 + +[textures\tx_willow_flower_02.dds] + alphaRejectValue = 128 + +[textures\tx_cork_bulb_02.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_telvanni_01.dds] + alphaRejectValue = 128 + +[textures\tx_green_lichen_01.dds] + alphaRejectValue = 128 + +[textures\tx_roobrush_01.dds] + alphaRejectValue = 128 + +[textures\tx_bittergreen_02.dds] + alphaRejectValue = 128 + +[textures\tx_chokeweed_01.dds] + alphaRejectValue = 128 + +[textures\tx_de_banner_book_01.dds] + alphaRejectValue = 128 + +[textures\tx_bannerd_w_a_shop_01.dds] + alphaRejectValue = 128 + +[textures\tx_banner_temple_02.dds] + alphaRejectValue = 128 From 7fce57f335133735760262849e431adacfc6aba2 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 11 Apr 2012 20:16:22 -0400 Subject: [PATCH 31/74] Getting started with a new branch --- apps/openmw/mwrender/npcanimation.cpp | 173 ++++++------------------- 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, 53 insertions(+), 139 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 8097afdbf..f04ac7609 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); - - MWWorld::ContainerStoreIterator robe = inv.getSlot(MWWorld::InventoryStore::Slot_Robe); - - - - // ; - - - 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){ + 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; - lBeastFoot = insertFreePart("meshes\\" + feetpart->model,"::"); - rBeastFoot = insertFreePart("meshes\\" + feetpart->model,":<"); + 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, ":\""); + } + } + } + + } + 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, ":\""); + } + } - //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 e90bea5c9..02b161b99 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 650418201..230f7d69a 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 ddc25e176..8b559b10f 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 1d6c9d4a1..16fd0598c 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 800df7376ccc1b88c56c286af5e7a1fe1e12c091 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 12 Apr 2012 14:26:21 +0200 Subject: [PATCH 32/74] use the cursors from morrowind.bsa and remove mwpointer.png --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/engine.cpp | 4 ++++ apps/openmw/mwgui/cursorreplace.cpp | 16 ++++++++++++++++ apps/openmw/mwgui/cursorreplace.hpp | 16 ++++++++++++++++ files/mygui/CMakeLists.txt | 1 - files/mygui/mwpointer.png | Bin 4810 -> 0 bytes files/mygui/openmw_images.xml | 18 +++++++++--------- libs/openengine/ogre/imagerotate.cpp | 3 +-- libs/openengine/ogre/imagerotate.hpp | 2 +- 9 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 apps/openmw/mwgui/cursorreplace.cpp create mode 100644 apps/openmw/mwgui/cursorreplace.hpp delete mode 100644 files/mygui/mwpointer.png diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index a8ae0bd49..b417c764d 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,7 +25,7 @@ add_openmw_dir (mwinput add_openmw_dir (mwgui layouts text_input widgets race class birth review window_manager console dialogue dialogue_history window_base stats_window messagebox journalwindow charactercreation - map_window window_pinnable_base + map_window window_pinnable_base cursorreplace ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 259733600..8fe6963a9 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -28,6 +28,7 @@ #include "mwinput/inputmanager.hpp" #include "mwgui/window_manager.hpp" +#include "mwgui/cursorreplace.hpp" #include "mwscript/scriptmanager.hpp" #include "mwscript/compilercontext.hpp" @@ -368,6 +369,9 @@ void OMW::Engine::go() loadBSA(); + // cursor replacer (converts the cursor from the bsa so they can be used by mygui) + MWGui::CursorReplace replacer; + // Create the world mEnvironment.mWorld = new MWWorld::World (*mOgre, mFileCollections, mMaster, mResDir, mNewGame, mEnvironment, mEncoding, mFallbackMap); diff --git a/apps/openmw/mwgui/cursorreplace.cpp b/apps/openmw/mwgui/cursorreplace.cpp new file mode 100644 index 000000000..2079538fc --- /dev/null +++ b/apps/openmw/mwgui/cursorreplace.cpp @@ -0,0 +1,16 @@ +#include "cursorreplace.hpp" + +#include +#include + +#include +#include + +using namespace MWGui; + +CursorReplace::CursorReplace() +{ + OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_vresize.png", 90); + OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize1.png", -45); + OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize2.png", 45); +} diff --git a/apps/openmw/mwgui/cursorreplace.hpp b/apps/openmw/mwgui/cursorreplace.hpp new file mode 100644 index 000000000..06fe28e39 --- /dev/null +++ b/apps/openmw/mwgui/cursorreplace.hpp @@ -0,0 +1,16 @@ +#ifndef GAME_CURSORREPLACE_H +#define GAME_CURSORREPLACE_H + +#include + +namespace MWGui +{ + /// \brief MyGUI does not support rotating cursors, so we have to do it manually + class CursorReplace + { + public: + CursorReplace(); + }; +} + +#endif diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index dbc20f3f8..e3a7b9999 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -8,7 +8,6 @@ configure_file("${SDIR}/bigbars.png" "${DDIR}/bigbars.png" COPYONLY) configure_file("${SDIR}/black.png" "${DDIR}/black.png" COPYONLY) configure_file("${SDIR}/core.skin" "${DDIR}/core.skin" COPYONLY) configure_file("${SDIR}/core.xml" "${DDIR}/core.xml" COPYONLY) -configure_file("${SDIR}/mwpointer.png" "${DDIR}/mwpointer.png" COPYONLY) configure_file("${SDIR}/mwgui.png" "${DDIR}/mwgui.png" COPYONLY) configure_file("${SDIR}/openmw_images.xml" "${DDIR}/openmw_images.xml" COPYONLY) configure_file("${SDIR}/openmw_settings.xml" "${DDIR}/openmw_settings.xml" COPYONLY) diff --git a/files/mygui/mwpointer.png b/files/mygui/mwpointer.png deleted file mode 100644 index 90bc19b5e2c7ea4f30b895cc5b8cde00ce460e98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4810 zcmV;*5;g6KP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXDv z4ipCV%8V!g000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}000stNklY!DT!(TT8(ATxmF9B$tA>HJFd$UG{4+JUXc=`2B zNY%$dM-iE8vvfryFk_PL1_Ops^?eoAzp@@F3sV3<1KNr4LYr5?kiPD$&*6 zg}DpoV(!AZ;Cp;7AU1}|Opc+Fs+&#a04y`4oB{>}3V2(1HW~_*0vvFlP${5|CXxN9 z4&VUq?mV8PQE1W?M^h*8<89-fh<-9zKDP}MGewQ!{X&h z6V>54odz=)p!hEQXX*VEiQUu(nC-4n=S{8V(d&fV3_OyNh?A#kq{}mswvxd6egaK8 zNCLSefwB!*>Y^KrAzhuWE?cuwf57jj?jI){6DTw(fwbE?=*UAvHJhIofDa^WRM?4 zz?zkM>ArVf%-i?Qi)CvUk<*$HH}wHZsbEWVL?{A;1Zay5LOu_*E!~g?OTcB^fESR3 zk{|>G2mygrkLpo!p%rai)<9LLBu5o0iEQf|D83z=t(Fl|QpDe~>Y+J*-~HzLrCE!$ zfmEmj*1iFRgh=r2XO))52GcJ0_4f=+N>u;4$J`M}MW{eUsE{~E6S(@RpXrn1RL}D{ z&@?u*b-IDh>BIoe%^Gz|F{?|6f}E0La9|Js;Nb@V0J1W4h*49ZD00*_C1nQGT{fcd zu+JZx`t2tSX4`83%5OFn!G{#U<~3PKd9QBFx+>vfAu+07R2+rEBb8UrJ)_+eY<314 z)~_COjKU)&mi=FyEhs!zzHPchZ8v2=ww7cm6$LpZ|8athZ^kid3K}(q%E~6BEr|b- zAn-A$@NhBeE*qg$kuaET&8KSGw*lBS2H`aTGSgGzHveJcDh)ZBpQ9KMHJiFVd2+2D z5ELq_>Yz)}j=j2f(NudV28gHHqOb^t(SlNlz9y`1q$eZegxO%Gr*Ngz{6ky1HHz)UlclLX-5Vbl6l z06_k}QrKNil-8NAb;uR~Ql(6cb(wMauG)lG*XmGQZNkwKgYQ0m7~1G&Ll3jduZ@;z z?*mfPQhW|sL885jhPk_URG&Bvg_!6tG`04k`AQ$kFBxF6*vkRzV#Y8zw?HOUk`<$&j#CKlb+>Qn#4aR5hCkrPSpH}3as%p{}NK2 zl4Ro|NR|LtVx~Ohu0x|Hh%%B7c7_x)n86HYFoPM)UhZL~lUwk;~_TaeHT~ z_|vafv001bn*0ydXKSS=k& zfJ5*>PKJrRpMAjA7!|2kM+G51CKQ%lTat~o?V<ihp&v zJpV}d+sg-soL8>x&%eWQ^5i5THPg(f@{uK}F?oh#HIwn|b;$1Uo_Wg#@5D`p2mY;*Zyw=B|d5}*{=X-_s_$9k7=)n*TzZW6rvZNShYAsED4Le(?mTw3&Rbq-XzA{;Ro5G>gak=4UoT#j7 z#@9vPfeZ<+5Az zk61gJ4FA6EV9WNqVRyPLLvEE^R4HJY>@LetSVdJmG_%zRl8C_L@em*gz$XPK@Yxq9 z5h&!t>Gpo!Yju1!8S8*dHAU!sgpb6cxsk})7LZOm!qBN0bw}08X?QVM8lNFscrz=fAzfjX&Z8BTY*mMP# zYU(k_IAAum!g#qFL81T*Fdp+|qqX8@zV>!BAXlrBER}_dJA3*EEyuoZ1wn8F`&?YC z&e0(xOo9!seAsNNs8&gJoP%zbwBb@ie2`v!Ck zIFOvEL`R2Z&ZEn;{fCOGOU5!6U6!FKiH^+uj-HpEO^;o=Ab#=kWjcIUT8qj{4Ji5M z6snv1FfinS!|85xd)VI(IXsiHr%gKI0DRTO?Ald2mNDeB`*&<$iP7zom73T{3i!;D zga~%^gBtdik0p5*Co0$_^P|~)Z$Hm6hJ5z$-}2Z!+t>YeL#erSb6- z8GKnvc*Ix|y!+4VUOlw?CDw5{pWXTTTK2J}YW9^UQ`p6c;cV)ha5hyN?h*<4f4Wtm zb2}!;GU5QnDC=fMw@*%Xl!NnxNKhXv79cJ2jU9Bj&);f&!kwT-OnnNP#Rao%u&J%5AB}Cj zHd4(0;{fA+2EYsFtBm%y_ngKj1!c%ymH>q;X!{$#f8woKvmy?V5vsTaX~_ZE8Hw}! z{^WMS2k^`@&t@gh*QvMu?&r~)0btJ?&uj{pOWs_OnSgy?mSM-oXHZ$&X6v&#_B6Fy zTbyn$7R(7ph(vG}!1?hEG9k0%^7usm+O0y92sa0uj{x@)t9@|a$%?LFhuaQ7SXyO# z&;9pP@Or&??#VO=0{Fi%wwn+n;Ui;VJnREQ$s(a3ebC`NbGzflM+NIcWx>SaN9TIW zS_)r#=kf5tcMd(P*{fdK0b{LHEjT}3BaL;=S46^^S~j-;e5EK-(~>NJ=F}b z08^iac6->1KN#&Bs|*7NNBlep;4=Wu3pH)|@9sSl74)E{mtz%Kp8FzN=}TUz;UzO-@LpcM4^)Auq=yDKQF~QdrqUY%4i4h&j1br zu&0>CSNA-I~UHFVhxt=)KzWyf#l#vO(((vn*#8EF9^Ev++OC;4l#bxj^S z4Q(`ux>mZm@T_6MWN888^p5GwHm*)&zP-@-NQ^QV>hK^83^))UHyd0o7aorXGI=Q0 ztXrFM=;B9``nrbkGJw-*vOl&mUCWgQ1%h$7;PH6Ta@mOb(#!BN3?u}z#ic^SQXsp8)FEAc&#Xhkjaj{$` z7TD}V2;lQUDP^$t+dzhjk*Joj0s%jn6!V|_viSN%;CP9Dy9+Uf9&iV8fJ|fe0EUmv z|MV)^=3F- zEG#w#l^3c}-PjF*K!`|%6w0V@&d{KP{<5g-O90Ms43WM%E8$o3lA=hL#{-F2i00;Q z)L&}E>C#qMtPE#vY&g$iV-_l9LPblb{UiYIoy_HSo$#*WYE#~lWJ&`7uddaN+K;PC z(E@H7UmUF{z!dHm7?!Y0Edy@^ciW9Era^W8fHOUs3gUFr48O-Zh%*81YT>8S;XcjC?W-A(6y7BJrZ^7|$;PQ9@aNuy7Ic+`t z!GL=`pU3%*&*L1tk(r!K23X+Row5}GimOe?zNW+H$I30A`!+yNd0x!pWs58}_JqaO z9}XaGV91pgs|?EF^SP0vL?ACZSq!iMm&am7rZ)KW`8iZwW5=!TD>wBGtqCLq0D$fu z8{XP^62T%KJYF6Id>&hQxywn21odXyU=s(NkK7*i;urzKq?@3tdHP@xKQ~CkmtJh_ zfkG~WHePkLar+;)@2zfQ_Tuis4xrxU@t$>i*iV`}Y%PR<*J`F6-gaY~w104j&kNx3 z>HZ<1SVa6!V@uZ!pD$~ar0BUPm;7Fr5H0=hBc(We{30AqH{2eW>Wp-UsmFe}-{Jmn zz~Oq2_2O+Wi&_Bmo&NDVSqE5Z40J(;j@mqO12o`&7efiX4fhW2UaNx!uuoF2BsJNWp`+OSJ2tV5VL!_l_OokOEqWi*6G8x7S*Ro(K*)_c`AcCo%R-3u zKtk{dfL{Pey_%JpX4pKE0sD7s>LVucMNRht{(7YO0H~WWYBDjAWZW)88{N!!?O@zA z_J4J@fVsshX{I~+7_f{R6#z^C`lmYsEdG~X_+I~VcOswr4ihc?s|7fDbq$?+>l!-? kX2^MOka;&UqW3HQ4@_ElhBC1j1ONa407*qoM6N<$f{)=HO8@`> diff --git a/files/mygui/openmw_images.xml b/files/mygui/openmw_images.xml index 6487742c3..e149273e2 100644 --- a/files/mygui/openmw_images.xml +++ b/files/mygui/openmw_images.xml @@ -2,37 +2,37 @@ - + - + - + - + - + - + - + - + - + diff --git a/libs/openengine/ogre/imagerotate.cpp b/libs/openengine/ogre/imagerotate.cpp index 166a1d3c6..b7522c100 100644 --- a/libs/openengine/ogre/imagerotate.cpp +++ b/libs/openengine/ogre/imagerotate.cpp @@ -49,7 +49,7 @@ void ImageRotate::rotate(const std::string& sourceImage, const std::string& dest unsigned int height = sourceTexture->getHeight(); TexturePtr destTexture = TextureManager::getSingleton().createManual( - "ImageRotateDestTexture", + destImage, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, width, height, @@ -69,7 +69,6 @@ void ImageRotate::rotate(const std::string& sourceImage, const std::string& dest rtt->writeContentsToFile(destImage); // remove all the junk we've created - TextureManager::getSingleton().remove("ImageRotateDestTexture"); MaterialManager::getSingleton().remove("ImageRotateMaterial"); root->destroySceneManager(sceneMgr); delete rect; diff --git a/libs/openengine/ogre/imagerotate.hpp b/libs/openengine/ogre/imagerotate.hpp index 85363d71f..a3f6d662f 100644 --- a/libs/openengine/ogre/imagerotate.hpp +++ b/libs/openengine/ogre/imagerotate.hpp @@ -15,7 +15,7 @@ namespace Render public: /** * @param source image (file name - has to exist in an resource group) - * @param destination image (absolute file path) + * @param name of the destination texture to save to (in memory) * @param angle in degrees to turn */ static void rotate(const std::string& sourceImage, const std::string& destImage, const float angle); From 4a6a8e5420eb24f203d6645b157e3aba63a21342 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 12 Apr 2012 14:28:35 +0200 Subject: [PATCH 33/74] don't write to disk --- libs/openengine/ogre/imagerotate.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/openengine/ogre/imagerotate.cpp b/libs/openengine/ogre/imagerotate.cpp index b7522c100..1147559d6 100644 --- a/libs/openengine/ogre/imagerotate.cpp +++ b/libs/openengine/ogre/imagerotate.cpp @@ -66,7 +66,6 @@ void ImageRotate::rotate(const std::string& sourceImage, const std::string& dest vp->setClearEveryFrame(true, FBT_DEPTH); rtt->update(); - rtt->writeContentsToFile(destImage); // remove all the junk we've created MaterialManager::getSingleton().remove("ImageRotateMaterial"); From 2b8c81e7795a01c00a6e014714d31206abaa0af4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 12 Apr 2012 14:31:12 +0200 Subject: [PATCH 34/74] removed test.skin file --- files/mygui/test.skin | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 files/mygui/test.skin diff --git a/files/mygui/test.skin b/files/mygui/test.skin deleted file mode 100644 index 5f198ab4a..000000000 --- a/files/mygui/test.skin +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - From 95f87a8abf437e7cc0e35c77c785ca619f02b6dc Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 12 Apr 2012 16:33:36 +0200 Subject: [PATCH 35/74] more or less complete list for morrowind.bsa (thanks to artorius) --- components/nifogre/ogre_nif_loader.cpp | 2 +- files/transparency-overrides.cfg | 502 ++++++++++++++++++++++++- 2 files changed, 496 insertions(+), 8 deletions(-) diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 6f5142796..ab6a708c0 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -296,7 +296,7 @@ void NIFLoader::createMaterial(const String &name, //pass->setDepthCheckEnabled(false); pass->setDepthWriteEnabled(false); - std::cout << "alpha 237; material: " << name << " texName: " << texName << std::endl; + //std::cout << "alpha 237; material: " << name << " texName: " << texName << std::endl; } } else diff --git a/files/transparency-overrides.cfg b/files/transparency-overrides.cfg index 7750e9834..299792be1 100644 --- a/files/transparency-overrides.cfg +++ b/files/transparency-overrides.cfg @@ -10,7 +10,17 @@ # Note: all the texture names here have to be lowercase -[textures\tx_flag_imp_01.dds] +# fauna +[textures\tx_wickwheat_01.dds] + alphaRejectValue = 128 + +[textures\tx_wickwheat_03.dds] + alphaRejectValue = 128 + +[textures\tx_red_lichen_01.dds] + alphaRejectValue = 128 + +[textures\tx_stone_flower_01.dds] alphaRejectValue = 128 [textures\tx_ivy_02.dds] @@ -19,9 +29,6 @@ [textures\tx_ivy_01.dds] alphaRejectValue = 128 -[textures\tx_sail.dds] - alphaRejectValue = 128 - [textures\tx_saltrice_04.dds] alphaRejectValue = 128 @@ -37,6 +44,15 @@ [textures\tx_leaves_03.dds] alphaRejectValue = 128 +[textures\tx_leaves_04.dds] + alphaRejectValue = 128 + +[textures\tx_leaves_06.dds] + alphaRejectValue = 128 + +[textures\tx_leaves_07.dds] + alphaRejectValue = 128 + [textures\tx_ai_heather_01.dds] alphaRejectValue = 96 @@ -61,9 +77,6 @@ [textures\tx_cork_bulb_02.dds] alphaRejectValue = 128 -[textures\tx_v_b_telvanni_01.dds] - alphaRejectValue = 128 - [textures\tx_green_lichen_01.dds] alphaRejectValue = 128 @@ -76,11 +89,486 @@ [textures\tx_chokeweed_01.dds] alphaRejectValue = 128 +[textures\tx_branches_01.dds] + alphaRejectValue = 128 + +[textures\tx_branches_02.dds] + alphaRejectValue = 128 + +[textures\tx_guarskin_hut_03.dds] + alphaRejectValue = 128 + +[textures\tx_hackle-lo_02.dds] + alphaRejectValue = 128 + +[textures\tx_bc_fern_01.dds] + alphaRejectValue = 128 + +[textures\tx_bc_fern_02.dds] + alphaRejectValue = 128 + +[textures\tx_bc_leaves_02.dds] + alphaRejectValue = 128 + +[textures\tx_marshmerrow_03.dds] + alphaRejectValue = 128 + +[textures\tx_bc_moss_01.dds] + alphaRejectValue = 128 + +[textures\tx_bc_moss_02.dds] + alphaRejectValue = 128 + +[textures\tx_bc_lilypad_01.dds] + alphaRejectValue = 128 + +[textures\tx_bc_lilypad_02.dds] + alphaRejectValue = 128 + +[textures\tx_bc_lilypad_03.dds] + alphaRejectValue = 128 + +[textures\tx_fire_fern_01.dds] + alphaRejectValue = 128 + +# banners and flags +[textures\tx_flag_imp_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_arena_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_comfort_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_child_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_count_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_faith_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_walk_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_imp_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_redoran_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_avs_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_serving_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_speak_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_stdeyln_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_stolms_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_thin_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_vivec_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_vivec_02.dds] + alphaRejectValue = 128 + +[textures\tx_ashl_banner_01.dds] + alphaRejectValue = 128 + +[textures\tx_ashl_banner_02.dds] + alphaRejectValue = 128 + +[textures\tx_ashl_banner_04.dds] + alphaRejectValue = 128 + +[textures\tx_ashl_banner_05.dds] + alphaRejectValue = 128 + +[textures\tx_ashl_banner_06.dds] + alphaRejectValue = 128 + +[textures\tx_ashl_banner_07.dds] + alphaRejectValue = 128 + +[textures\tx_ashl_a_banner.dds] + alphaRejectValue = 128 + +[textures\tx_ashl_e_banner.dds] + alphaRejectValue = 128 + +[textures\tx_ashl_u_banner.dds] + alphaRejectValue = 128 + +[textures\tx_ashl_z_banner.dds] + alphaRejectValue = 128 + +[textures\tx_banner_6th.dds] + alphaRejectValue = 128 + +[textures\tx_banner_6th_tall.dds] + alphaRejectValue = 128 + +[textures\tx_banner_gnisis_01.dds] + alphaRejectValue = 128 + +[textures\tx_banner_gnisis_02.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_bhm_01.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_02.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_03.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_04.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_05.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_06.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_07.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_08.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_08.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_09.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_10.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_11.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_12.dds] + alphaRejectValue = 128 + +[textures\tx_de_tapestry_13.dds] + alphaRejectValue = 128 + +[textures\tx_de_lutestrings_01.dds] + alphaRejectValue = 128 + +[textures\tx_fabric_imp_altar_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_akatosh_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_apprentice_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_arkay_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_dibella_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_golem_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_julianos_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_kynareth_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_lady_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_lord_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_lover_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_mara_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_ritual_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_shadow_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_steed_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_stendarr_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_thief_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_tower_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_warrior_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_wizard_01.dds] + alphaRejectValue = 128 + +[textures\tx_c_t_zenithar_01.dds] + alphaRejectValue = 128 + +[textures\tx_banner_dagoth_01.dds] + alphaRejectValue = 128 + +[textures\tx_bannerd_tavern_01.dds] + alphaRejectValue = 128 + +[textures\tx_bannerd_goods_01.dds] + alphaRejectValue = 128 + +[textures\tx_bannerd_danger_01.dds] + alphaRejectValue = 128 + +[textures\tx_bannerd_welcome_01.dds] + alphaRejectValue = 128 + +[textures\tx_bannerd_clothing_01.dds] + alphaRejectValue = 128 + +[textures\tx_bannerd_alchemy_01.dds] + alphaRejectValue = 128 + +[textures\tx_banner_hlaalu_01.dds] + alphaRejectValue = 128 + +[textures\tx_banner_redoran_01.dds] + alphaRejectValue = 128 + +[textures\tx_banner_temple_01.dds] + alphaRejectValue = 128 + +[textures\tx_banner_temple_03.dds] + alphaRejectValue = 128 + [textures\tx_de_banner_book_01.dds] alphaRejectValue = 128 +[textures\tx_de_banner_ald_velothi.dds] + alphaRejectValue = 128 + +[textures\tx_de_banner_gnaar_mok.dds] + alphaRejectValue = 128 + +[textures\tx_de_banner_hla_oad.dds] + alphaRejectValue = 128 + +[textures\tx_de_banner_khull.dds] + alphaRejectValue = 128 + +[textures\tx_de_banner_pawn_01.dds] + alphaRejectValue = 128 + +[textures\tx_de_banner_sadrith_mora.dds] + alphaRejectValue = 128 + +[textures\tx_de_banner_tel_aruhn.dds] + alphaRejectValue = 128 + +[textures\tx_de_banner_tel_branora.dds] + alphaRejectValue = 128 + +[textures\tx_de_banner_tel_fyr.dds] + alphaRejectValue = 128 + +[textures\tx_de_banner_tel_mora.dds] + alphaRejectValue = 128 + +[textures\tx_de_banner_telvani_01.dds] + alphaRejectValue = 128 + +[textures\tx_de_banner_tel_vos.dds] + alphaRejectValue = 128 + +[textures\tx_de_banner_vos.dds] + alphaRejectValue = 128 + [textures\tx_bannerd_w_a_shop_01.dds] alphaRejectValue = 128 [textures\tx_banner_temple_02.dds] alphaRejectValue = 128 + +[textures\tx_mural1_00.dds] + alphaRejectValue = 128 + +[textures\tx_mural1_01.dds] + alphaRejectValue = 128 + +[textures\tx_mural4_00.dds] + alphaRejectValue = 128 + +[textures\tx_mural4_01.dds] + alphaRejectValue = 128 + +[textures\tx_mural5_00.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_telvanni_01.dds] + alphaRejectValue = 128 + +[textures\tx_v_b_hlaalu_01.dds] + alphaRejectValue = 128 + +[textures\tx_fabric_tapestry.dds] + alphaRejectValue = 128 + +[textures\tx_fabric_tapestry_01.dds] + alphaRejectValue = 128 + +[textures\tx_fabric_tapestry_02.dds] + alphaRejectValue = 128 + +[textures\tx_fabric_tapestry_03.dds] + alphaRejectValue = 128 + +[textures\tx_fabric_tapestry_04.dds] + alphaRejectValue = 128 + +# characters +[textures\tx_netchgod00.dds] + alphaRejectValue = 128 + +[textures\tx_b_n_argonian_f_hair02.dds] + alphaRejectValue = 128 + +[textures\tx_b_n_argonian_f_hair03.dds] + alphaRejectValue = 128 + +[textures\tx_b_n_argonian_m_hair01.dds] + alphaRejectValue = 128 + +[textures\tx_b_n_argonian_m_hair04.dds] + alphaRejectValue = 128 + +[textures\tx_b_n_argonian_m_hair05.dds] + alphaRejectValue = 128 + +[textures\tx_b_n_khajiit_f_hair01.dds] + alphaRejectValue = 128 + +[textures\tx_b_n_khajiit_f_hair02.dds] + alphaRejectValue = 128 + +[textures\tx_b_n_khajiit_m_hair01.dds] + alphaRejectValue = 128 + +[textures\tx_corprus_stalker12.dds] + alphaRejectValue = 128 + +[textures\tx_a_clavicus02.dds] + alphaRejectValue = 128 + +[textures\tx_b_n_dark elf_m_hair11.dds] + alphaRejectValue = 128 + +[textures\tx_b_n_dark elf_f_hair10.dds] + alphaRejectValue = 128 + +# misc items +[textures\tx_sail.dds] + alphaRejectValue = 128 + +[textures\tx_longboatsail01.dds] + alphaRejectValue = 128 + +[textures\tx_longboatsail01a.dds] + alphaRejectValue = 128 + +[textures\tx_longboatsail01b.dds] + alphaRejectValue = 128 + +[textures\tx_longboatsail02.dds] + alphaRejectValue = 128 + +[textures\tx_quill.dds] + alphaRejectValue = 128 + +[textures\tx_note_01.dds] + alphaRejectValue = 128 + +[textures\tx_note_02.dds] + alphaRejectValue = 128 + +[textures\tx_parchment_02.dds] + alphaRejectValue = 128 + +[textures\tx_parchment_03.dds] + alphaRejectValue = 128 + +[textures\tx_scroll_01.dds] + alphaRejectValue = 128 + +[textures\tx_scroll_02.dds] + alphaRejectValue = 128 + +[textures\tx_scroll_03.dds] + alphaRejectValue = 128 + +[textures\tx_alpha_small_edge.dds] + alphaRejectValue = 128 + +[textures\tx_alpha_shadow_circular.dds] + alphaRejectValue = 128 + +# building materials +[textures\tx_shack_thatch_strip.dds] + alphaRejectValue = 128 + +[textures\tx_rug00.dds] + alphaRejectValue = 128 + +[textures\tx_rug_02.dds] + alphaRejectValue = 128 + +[textures\tx_rug_edge_01.dds] + alphaRejectValue = 128 + +[textures\tx_awning_thatch_02.dds] + alphaRejectValue = 128 + +[textures\tx_awning_woven_01.dds] + alphaRejectValue = 128 + +[textures\tx_bridgeropes.dds] + alphaRejectValue = 128 + +[textures\tx_rope_woven_01.dds] + alphaRejectValue = 128 + +[textures\tx_rope_woven_02.dds] + alphaRejectValue = 128 + +[textures\tx_ashl_tent_06.dds] + alphaRejectValue = 128 + +[textures\tx_guar_tarp.dds] + alphaRejectValue = 128 + +[textures\tx_velothi_glyph00.dds] + alphaRejectValue = 128 From a96ad7fb8295df3470dd0b008d978d234317edd6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 12 Apr 2012 16:46:56 +0200 Subject: [PATCH 36/74] restored toggleWater --- apps/openmw/mwrender/water.cpp | 55 +++++++++++++++++----------------- apps/openmw/mwrender/water.hpp | 2 ++ 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 85fb2ee99..71cf56dfd 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -11,7 +11,7 @@ namespace MWRender Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()), mIsUnderwater(false), mVisibilityFlags(0), - mReflectionTarget(0), mActive(1) + mReflectionTarget(0), mActive(1), mToggled(1) { mSky = sky; @@ -93,32 +93,32 @@ Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : // destroy if already exists if (overlay = mgr.getByName("ReflectionDebugOverlay")) mgr.destroy(overlay); - + overlay = mgr.create("ReflectionDebugOverlay"); - + if (MaterialManager::getSingleton().resourceExists("Ogre/ReflectionDebugTexture")) MaterialManager::getSingleton().remove("Ogre/ReflectionDebugTexture"); MaterialPtr debugMat = MaterialManager::getSingleton().create( - "Ogre/ReflectionDebugTexture", + "Ogre/ReflectionDebugTexture", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - + debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName()); t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); OverlayContainer* debugPanel; - + // destroy container if exists try { - if (debugPanel = + if (debugPanel = static_cast( mgr.getOverlayElement("Ogre/ReflectionDebugTexPanel" ))) mgr.destroyOverlayElement(debugPanel); } catch (Ogre::Exception&) {} - + debugPanel = (OverlayContainer*) (OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/ReflectionDebugTexPanel")); debugPanel->_setPosition(0, 0.55); @@ -134,8 +134,7 @@ Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) : void Water::setActive(bool active) { mActive = active; - if (mReflectionTarget) mReflectionTarget->setActive(active && !mIsUnderwater); - mWater->setVisible(active); + updateVisible(); } Water::~Water() @@ -167,8 +166,8 @@ void Water::setHeight(const float height) void Water::toggle() { - if (mActive) - mWater->setVisible(!mWater->getVisible()); + mToggled = !mToggled; + updateVisible(); } void Water::checkUnderwater(float y) @@ -183,13 +182,10 @@ void Water::checkUnderwater(float y) if (pass->hasFragmentProgram() && pass->getFragmentProgramParameters()->_findNamedConstantDefinition("isUnderwater", false)) pass->getFragmentProgramParameters()->setNamedConstant("isUnderwater", Real(0)); - if (mReflectionTarget) - mReflectionTarget->setActive(mActive); - mWater->setRenderQueueGroup(RQG_Water); mIsUnderwater = false; - } + } if (!mIsUnderwater && y < mTop && mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID) { @@ -201,13 +197,12 @@ void Water::checkUnderwater(float y) if (pass->hasFragmentProgram() && pass->getFragmentProgramParameters()->_findNamedConstantDefinition("isUnderwater", false)) pass->getFragmentProgramParameters()->setNamedConstant("isUnderwater", Real(1)); - if (mReflectionTarget) - mReflectionTarget->setActive(false); - mWater->setRenderQueueGroup(RQG_UnderWater); mIsUnderwater = true; } + + updateVisible(); } Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY) @@ -217,15 +212,14 @@ Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY) void Water::preRenderTargetUpdate(const RenderTargetEvent& evt) { - mReflectionCamera->setOrientation(mCamera->getDerivedOrientation()); - mReflectionCamera->setPosition(mCamera->getDerivedPosition()); - mReflectionCamera->setNearClipDistance(mCamera->getNearClipDistance()); - mReflectionCamera->setFarClipDistance(mCamera->getFarClipDistance()); - mReflectionCamera->setAspectRatio(mCamera->getAspectRatio()); - mReflectionCamera->setFOVy(mCamera->getFOVy()); if (evt.source == mReflectionTarget) { - mWater->setVisible(false); + mReflectionCamera->setOrientation(mCamera->getDerivedOrientation()); + mReflectionCamera->setPosition(mCamera->getDerivedPosition()); + mReflectionCamera->setNearClipDistance(mCamera->getNearClipDistance()); + mReflectionCamera->setFarClipDistance(mCamera->getFarClipDistance()); + mReflectionCamera->setAspectRatio(mCamera->getAspectRatio()); + mReflectionCamera->setFOVy(mCamera->getFOVy()); // Some messy code to get the skybox to show up at all // The problem here is that it gets clipped by the water plane @@ -242,8 +236,6 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt) void Water::postRenderTargetUpdate(const RenderTargetEvent& evt) { - mWater->setVisible(true); - if (evt.source == mReflectionTarget) { mSky->resetSkyPosition(); @@ -291,4 +283,11 @@ void Water::setViewportBackground(const ColourValue& bg) mReflectionTarget->getViewport(0)->setBackgroundColour(bg); } +void Water::updateVisible() +{ + mWater->setVisible(mToggled && mActive); + if (mReflectionTarget) + mReflectionTarget->setActive(mToggled && mActive && !mIsUnderwater); +} + } // namespace diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 3fb1b07b7..f14482e2b 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -24,6 +24,7 @@ namespace MWRender { bool mIsUnderwater; bool mActive; + bool mToggled; int mTop; Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY); @@ -31,6 +32,7 @@ namespace MWRender { protected: void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + void updateVisible(); SkyManager* mSky; From 03d6d1fb82faf7dcdd808facfcefb7e2716b8cfc Mon Sep 17 00:00:00 2001 From: gugus Date: Thu, 12 Apr 2012 17:08:57 +0200 Subject: [PATCH 37/74] NPC rank is correctly loaded now. Also corrected a potential bug (i think). --- apps/openmw/mwclass/npc.cpp | 41 ++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index b98df79ef..43e04ab52 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -55,31 +55,38 @@ namespace MWClass { if(ref->base->npdt52.gold != -10) { - data->mNpcStats.mFactionRank[ref->base->faction] = ref->base->npdt52.rank; + data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt52.rank; } else { - data->mNpcStats.mFactionRank[ref->base->faction] = ref->base->npdt52.rank; + data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt12.rank; } } - for (int i=0; i<27; ++i) - data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]); + if(ref->base->npdt52.gold != -10) + { + for (int i=0; i<27; ++i) + data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]); - // creature stats - data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength); - data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence); - data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower); - data->mCreatureStats.mAttributes[3].set (ref->base->npdt52.agility); - data->mCreatureStats.mAttributes[4].set (ref->base->npdt52.speed); - data->mCreatureStats.mAttributes[5].set (ref->base->npdt52.endurance); - data->mCreatureStats.mAttributes[6].set (ref->base->npdt52.personality); - data->mCreatureStats.mAttributes[7].set (ref->base->npdt52.luck); - data->mCreatureStats.mDynamic[0].set (ref->base->npdt52.health); - data->mCreatureStats.mDynamic[1].set (ref->base->npdt52.mana); - data->mCreatureStats.mDynamic[2].set (ref->base->npdt52.fatigue); + // creature stats + data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength); + data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence); + data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower); + data->mCreatureStats.mAttributes[3].set (ref->base->npdt52.agility); + data->mCreatureStats.mAttributes[4].set (ref->base->npdt52.speed); + data->mCreatureStats.mAttributes[5].set (ref->base->npdt52.endurance); + data->mCreatureStats.mAttributes[6].set (ref->base->npdt52.personality); + data->mCreatureStats.mAttributes[7].set (ref->base->npdt52.luck); + data->mCreatureStats.mDynamic[0].set (ref->base->npdt52.health); + data->mCreatureStats.mDynamic[1].set (ref->base->npdt52.mana); + data->mCreatureStats.mDynamic[2].set (ref->base->npdt52.fatigue); - data->mCreatureStats.mLevel = ref->base->npdt52.level; + data->mCreatureStats.mLevel = ref->base->npdt52.level; + } + else + { + //TODO: do something with npdt12 maybe:p + } // \todo add initial container content From 7edc5c733ca0f52bcba0025a5dc5244c8e1dff09 Mon Sep 17 00:00:00 2001 From: gugus Date: Thu, 12 Apr 2012 17:29:05 +0200 Subject: [PATCH 38/74] corrected a bug about rank. --- apps/openmw/mwdialogue/dialoguemanager.cpp | 4 ++-- apps/openmw/mwscript/statsextensions.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index 140522499..90f0c0231 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -488,7 +488,7 @@ namespace MWDialogue if(it!=stats.mFactionRank.end()) { //check rank - if(it->second < info.data.rank) return false; + if(it->second < (int)info.data.rank) return false; } else { @@ -505,7 +505,7 @@ namespace MWDialogue if(it!=stats.mFactionRank.end()) { //check rank - if(it->second < info.data.rank) return false; + if(it->second < (int)info.data.PCrank) return false; } else { diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index a3c517f8c..47ae9d13d 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -307,7 +307,7 @@ namespace MWScript MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) == MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) { - MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 1; + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 0; } else { @@ -340,7 +340,7 @@ namespace MWScript MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) == MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) { - MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 1; + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 0; } else { From e2ec889d1008bd721a945330b136a53a0950a6b0 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 12 Apr 2012 17:40:26 +0200 Subject: [PATCH 39/74] fixed a warning "implicit cast to float3" --- apps/openmw/mwrender/shaderhelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/shaderhelper.cpp b/apps/openmw/mwrender/shaderhelper.cpp index 93f960dc4..5354251f8 100644 --- a/apps/openmw/mwrender/shaderhelper.cpp +++ b/apps/openmw/mwrender/shaderhelper.cpp @@ -258,7 +258,7 @@ void ShaderHelper::createShader(const bool mrt, const bool shadows, const bool s outStream << " float3 lightingFinal = lightColour.xyz * diffuse.xyz * vertexColour.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n" " float fogValue = saturate((iDepth - fogParams.y) * fogParams.w); \n" - " oColor.xyz = lerp(lightingFinal * tex.xyz, fogColour, fogValue); \n" + " oColor.xyz = lerp(lightingFinal * tex.xyz, fogColour.xyz, fogValue); \n" " oColor.a = tex.a * diffuse.a * vertexColour.a; \n"; if (mrt) outStream << From fb78e853d41f07158705936213f21dd1804d0b16 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 12 Apr 2012 19:18:38 +0200 Subject: [PATCH 40/74] removed 2 unneeded lines --- apps/openmw/mwrender/shadows.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/openmw/mwrender/shadows.cpp b/apps/openmw/mwrender/shadows.cpp index 9c150f0c6..bf5602f43 100644 --- a/apps/openmw/mwrender/shadows.cpp +++ b/apps/openmw/mwrender/shadows.cpp @@ -55,9 +55,7 @@ void Shadows::recreate() mSceneMgr->setShadowCasterRenderBackFaces(true); mSceneMgr->setShadowTextureCasterMaterial("depth_shadow_caster"); mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT32_R); - mSceneMgr->setShadowDirLightTextureOffset(0.9); mSceneMgr->setShadowDirectionalLightExtrusionDistance(1000000); - mSceneMgr->setShowDebugShadows(true); mShadowFar = split ? Settings::Manager::getInt("split shadow distance", "Shadows") : Settings::Manager::getInt("shadow distance", "Shadows"); mSceneMgr->setShadowFarDistance(mShadowFar); From a885f3e9422646e1212d0b0344ed4205918b63ed Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Thu, 12 Apr 2012 20:40:11 -0400 Subject: [PATCH 41/74] 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 f04ac7609..520cc12bb 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 02b161b99..eecb598df 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 42/74] 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 520cc12bb..0b546bf13 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 eecb598df..0b4442e3a 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 43/74] 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 0b546bf13..37e3573f8 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 0b4442e3a..e5858e38c 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 52c7ee3b6ae8a9738289a1728cb02ad8d9a49e1f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 13 Apr 2012 10:49:45 +0200 Subject: [PATCH 44/74] moved selected spell from NpcStats to Spells --- apps/openmw/mwmechanics/npcstats.hpp | 5 ++--- apps/openmw/mwmechanics/spells.cpp | 13 +++++++++++++ apps/openmw/mwmechanics/spells.hpp | 11 ++++++++++- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index ece85f893..b9c672722 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -12,7 +12,8 @@ namespace MWMechanics /// /// For non-NPC-specific stats, see the CreatureStats struct. /// - /// \note For technical reasons the spell list is also handled by CreatureStats. + /// \note For technical reasons the spell list and the currently selected spell is also handled by + /// CreatureStats, even though they are actually NPC stats. struct NpcStats { @@ -28,8 +29,6 @@ namespace MWMechanics bool mSneak; bool mCombat; - std::string mSelectedSpell; // can be an empty string (no spell selected) - NpcStats() : mForceRun (false), mForceSneak (false), mRun (false), mSneak (false), mCombat (false) {} }; diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index 4e8c6fa5a..916239a84 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -43,6 +43,9 @@ namespace MWMechanics if (iter!=mSpells.end()) mSpells.erase (iter); + + if (spellId==mSelectedSpell) + mSelectedSpell.clear(); } MagicEffects Spells::getMagicEffects (const MWWorld::Environment& environment) const @@ -65,4 +68,14 @@ namespace MWMechanics { mSpells.clear(); } + + void Spells::setSelectedSpell (const std::string& spellId) + { + mSelectedSpell = spellId; + } + + const std::string Spells::getSelectedSpell() const + { + return mSelectedSpell; + } } diff --git a/apps/openmw/mwmechanics/spells.hpp b/apps/openmw/mwmechanics/spells.hpp index 4c5f21d35..f7606c4ac 100644 --- a/apps/openmw/mwmechanics/spells.hpp +++ b/apps/openmw/mwmechanics/spells.hpp @@ -32,6 +32,7 @@ namespace MWMechanics private: std::vector mSpells; + std::string mSelectedSpell; void addSpell (const ESM::Spell *, MagicEffects& effects) const; @@ -42,15 +43,23 @@ namespace MWMechanics TIterator end() const; void add (const std::string& spell); - /// \note Adding a spell that is already listed in *this is a no-op. + ///< Adding a spell that is already listed in *this is a no-op. void remove (const std::string& spell); + ///< If the spell to be removed is the selected spell, the selected spell will be changed to + /// no spell (empty string). MagicEffects getMagicEffects (const MWWorld::Environment& environment) const; ///< Return sum of magic effects resulting from abilities, blights, deseases and curses. void clear(); ///< Remove all spells of al types. + + void setSelectedSpell (const std::string& spellId); + ///< This function does not verify, if the spell is available. + + const std::string getSelectedSpell() const; + ///< May return an empty string. }; } From b099e1baf583202cbaed50697011d09d50a72dc0 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 13 Apr 2012 11:12:53 +0200 Subject: [PATCH 45/74] added addspell and removespell script instructions --- apps/openmw/mwscript/docs/vmformat.txt | 6 ++- apps/openmw/mwscript/statsextensions.cpp | 47 ++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index df955ec19..705d65814 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -129,4 +129,8 @@ op 0x2000143: ModWaterLevel op 0x2000144: ToggleWater, twa op 0x2000145: ToggleFogOfWar (tfow) op 0x2000146: TogglePathgrid -opcodes 0x2000147-0x3ffffff unused +op 0x2000147: AddSpell +op 0x2000148: AddSpell, explicit reference +op 0x2000149: RemoveSpell +op 0x200014a: RemoveSpell, explicit reference +opcodes 0x200014b-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 0e97a39cf..10641903e 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -280,6 +280,38 @@ namespace MWScript } }; + template + class OpAddSpell : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + MWWorld::Class::get (ptr).getCreatureStats (ptr).mSpells.add (id); + } + }; + + template + class OpRemoveSpell : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + MWWorld::Class::get (ptr).getCreatureStats (ptr).mSpells.remove (id); + } + }; + const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; @@ -311,6 +343,11 @@ namespace MWScript const int opcodeModSkill = 0x20000fa; const int opcodeModSkillExplicit = 0x2000115; + const int opcodeAddSpell = 0x2000147; + const int opcodeAddSpellExplicit = 0x2000148; + const int opcodeRemoveSpell = 0x2000149; + const int opcodeRemoveSpellExplicit = 0x200014a; + void registerExtensions (Compiler::Extensions& extensions) { static const char *attributes[numberOfAttributes] = @@ -381,6 +418,10 @@ namespace MWScript extensions.registerInstruction (mod + skills[i], "l", opcodeModSkill+i, opcodeModSkillExplicit+i); } + + extensions.registerInstruction ("addspell", "c", opcodeAddSpell, opcodeAddSpellExplicit); + extensions.registerInstruction ("removespell", "c", opcodeRemoveSpell, + opcodeRemoveSpellExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -436,6 +477,12 @@ namespace MWScript interpreter.installSegment5 (opcodeModSkill+i, new OpModSkill (i)); interpreter.installSegment5 (opcodeModSkillExplicit+i, new OpModSkill (i)); } + + interpreter.installSegment5 (opcodeAddSpell, new OpAddSpell); + interpreter.installSegment5 (opcodeAddSpellExplicit, new OpAddSpell); + interpreter.installSegment5 (opcodeRemoveSpell, new OpRemoveSpell); + interpreter.installSegment5 (opcodeRemoveSpellExplicit, + new OpRemoveSpell); } } } From e3486931aef62a4d10eff259a6fb1fd71e488d7d Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 13 Apr 2012 13:17:50 +0200 Subject: [PATCH 46/74] F10 hotkey toggle FPS --- apps/openmw/mwgui/layouts.cpp | 35 +++++++++++++++++++--------- apps/openmw/mwgui/layouts.hpp | 1 + apps/openmw/mwgui/window_manager.cpp | 10 ++++++++ apps/openmw/mwgui/window_manager.hpp | 5 +++- apps/openmw/mwinput/inputmanager.cpp | 10 ++++++++ 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index 6d8aa901b..21302d7c1 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -67,17 +67,8 @@ HUD::HUD(int width, int height, int fpsLevel) getWidget(crosshair, "Crosshair"); - if ( fpsLevel == 2 ){ - getWidget(fpsbox, "FPSBoxAdv"); - fpsbox->setVisible(true); - getWidget(fpscounter, "FPSCounterAdv"); - }else if ( fpsLevel == 1 ){ - getWidget(fpsbox, "FPSBox"); - fpsbox->setVisible(true); - getWidget(fpscounter, "FPSCounter"); - }else{ - getWidget(fpscounter, "FPSCounter"); - } + setFpsLevel(fpsLevel); + getWidget(trianglecounter, "TriangleCounter"); getWidget(batchcounter, "BatchCounter"); @@ -95,6 +86,28 @@ HUD::HUD(int width, int height, int fpsLevel) LocalMapBase::init(minimap, this); } +void HUD::setFpsLevel(int level) +{ + MyGUI::Widget* fps; + getWidget(fps, "FPSBoxAdv"); + fps->setVisible(false); + getWidget(fps, "FPSBox"); + fps->setVisible(false); + + if (level == 2) + { + getWidget(fpsbox, "FPSBoxAdv"); + fpsbox->setVisible(true); + getWidget(fpscounter, "FPSCounterAdv"); + } + else if (level == 1) + { + getWidget(fpsbox, "FPSBox"); + fpsbox->setVisible(true); + getWidget(fpscounter, "FPSCounter"); + } +} + void HUD::setFPS(float fps) { fpscounter->setCaption(boost::lexical_cast((int)fps)); diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 0614708cf..19d96d2ef 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -78,6 +78,7 @@ namespace MWGui void setPlayerPos(const float x, const float y); void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible); void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible); + void setFpsLevel(const int level); MyGUI::ProgressPtr health, magicka, stamina; MyGUI::Widget *weapBox, *spellBox; diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 13b6fab31..34d62ba08 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -15,6 +15,8 @@ #include "journalwindow.hpp" #include "charactercreation.hpp" +#include + #include #include #include @@ -472,3 +474,11 @@ void WindowManager::toggleFogOfWar() map->toggleFogOfWar(); hud->toggleFogOfWar(); } + +int WindowManager::toggleFps() +{ + showFPSLevel = (showFPSLevel+1)%3; + hud->setFpsLevel(showFPSLevel); + Settings::Manager::setInt("fps", "HUD", showFPSLevel); + return showFPSLevel; +} diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index f1db11731..2b53560ba 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -158,7 +158,10 @@ namespace MWGui void setPlayerDir(const float x, const float y); ///< set player view direction in map space void toggleFogOfWar(); - + + int toggleFps(); + ///< toggle fps display @return resulting fps level + void setInteriorMapTexture(const int x, const int y); ///< set the index of the map texture that should be used (for interiors) diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index bd27de029..9b5a9ae30 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -68,6 +68,8 @@ namespace MWInput A_ToggleWeapon, A_ToggleSpell, + A_ToggleFps, // Toggle FPS display (this is temporary) + A_LAST // Marker for the last item }; @@ -88,6 +90,11 @@ namespace MWInput /* InputImpl Methods */ + void toggleFps() + { + windows.toggleFps(); + } + void toggleSpell() { DrawState state = player.getDrawState(); @@ -235,6 +242,8 @@ namespace MWInput "Draw Weapon"); disp->funcs.bind(A_ToggleSpell,boost::bind(&InputImpl::toggleSpell,this), "Ready hands"); + disp->funcs.bind(A_ToggleFps, boost::bind(&InputImpl::toggleFps, this), + "Toggle FPS display"); // Add the exit listener ogre.getRoot()->addFrameListener(&exit); @@ -281,6 +290,7 @@ namespace MWInput disp->bind(A_ToggleWalk, KC_C); disp->bind(A_ToggleWeapon,KC_F); disp->bind(A_ToggleSpell,KC_R); + disp->bind(A_ToggleFps, KC_F10); // Key bindings for polled keys // NOTE: These keys are constantly being polled. Only add keys that must be checked each frame. From e16daeed238c140754642388ffa6d7988884382e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 13 Apr 2012 13:17:57 +0200 Subject: [PATCH 47/74] added GetSpell script function --- apps/openmw/mwscript/docs/vmformat.txt | 4 ++- apps/openmw/mwscript/statsextensions.cpp | 32 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 705d65814..1317794fa 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -133,4 +133,6 @@ op 0x2000147: AddSpell op 0x2000148: AddSpell, explicit reference op 0x2000149: RemoveSpell op 0x200014a: RemoveSpell, explicit reference -opcodes 0x200014b-0x3ffffff unused +op 0x200014b: GetSpell +op 0x200014c: GetSpell, explicit reference +opcodes 0x200014d-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 10641903e..011b8b010 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -312,6 +312,33 @@ namespace MWScript } }; + template + class OpGetSpell : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string id = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Integer value = 0; + + for (MWMechanics::Spells::TIterator iter ( + MWWorld::Class::get (ptr).getCreatureStats (ptr).mSpells.begin()); + iter!=MWWorld::Class::get (ptr).getCreatureStats (ptr).mSpells.end(); ++iter) + if (*iter==id) + { + value = 1; + break; + } + + runtime.push (value); + } + }; + const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; @@ -347,6 +374,8 @@ namespace MWScript const int opcodeAddSpellExplicit = 0x2000148; const int opcodeRemoveSpell = 0x2000149; const int opcodeRemoveSpellExplicit = 0x200014a; + const int opcodeGetSpell = 0x200014b; + const int opcodeGetSpellExplicit = 0x200014c; void registerExtensions (Compiler::Extensions& extensions) { @@ -422,6 +451,7 @@ namespace MWScript extensions.registerInstruction ("addspell", "c", opcodeAddSpell, opcodeAddSpellExplicit); extensions.registerInstruction ("removespell", "c", opcodeRemoveSpell, opcodeRemoveSpellExplicit); + extensions.registerFunction ("getspell", 'l', "c", opcodeGetSpell, opcodeGetSpellExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -483,6 +513,8 @@ namespace MWScript interpreter.installSegment5 (opcodeRemoveSpell, new OpRemoveSpell); interpreter.installSegment5 (opcodeRemoveSpellExplicit, new OpRemoveSpell); + interpreter.installSegment5 (opcodeGetSpell, new OpGetSpell); + interpreter.installSegment5 (opcodeGetSpellExplicit, new OpGetSpell); } } } From a33ae35e9487913454e87797425307375dc8aefb Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 13 Apr 2012 13:28:31 +0200 Subject: [PATCH 48/74] some fixes --- apps/openmw/mwrender/renderingmanager.cpp | 3 ++- apps/openmw/mwrender/terrainmaterial.cpp | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index ee60407b2..984b7ddc9 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -56,6 +56,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); if (caps->getNumMultiRenderTargets() < 2) Settings::Manager::setBool("shader", "Water", false); + if (!caps->isShaderProfileSupported("fp40") && !caps->isShaderProfileSupported("ps_4_0")) + Settings::Manager::setBool("enabled", "Shadows", false); // note that the order is important here if (useMRT()) @@ -108,7 +110,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const RenderingManager::~RenderingManager () { - //TODO: destroy mSun? delete mPlayer; delete mSkyManager; delete mDebugging; diff --git a/apps/openmw/mwrender/terrainmaterial.cpp b/apps/openmw/mwrender/terrainmaterial.cpp index 57bea5388..c69ed3a61 100644 --- a/apps/openmw/mwrender/terrainmaterial.cpp +++ b/apps/openmw/mwrender/terrainmaterial.cpp @@ -1339,7 +1339,13 @@ namespace Ogre // diffuse lighting for (int i=0; igetNumberOfLightsSupported(); ++i) + { + // shadows only for first light (directional) + if (i==0) outStream << " outputCol.rgb += litRes"<isLayerSpecularMappingEnabled()) From 3442ef17a8ee4dc37d74f63dcd0c95843179ab2b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 13 Apr 2012 14:54:13 +0200 Subject: [PATCH 49/74] fixed ModDisposition --- apps/openmw/mwscript/docs/vmformat.txt | 3 ++- apps/openmw/mwscript/statsextensions.cpp | 13 +++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 17f11d3a9..fda8d1954 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -139,4 +139,5 @@ op 0x200014a: RemoveSpell, explicit reference op 0x200014b: GetSpell op 0x200014c: GetSpell, explicit reference op 0x200014d: ModDisposition -opcodes 0x200014e-0x3ffffff unused +op 0x200014e: ModDisposition, explicit reference +opcodes 0x200014f-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index f7a4e5d86..9d3009870 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -435,13 +435,19 @@ namespace MWScript } }; + template class OpModDisposition : public Interpreter::Opcode0 { public: virtual void execute (Interpreter::Runtime& runtime) { + MWWorld::Ptr ptr = R()(runtime); +// Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); + + /// \todo modify disposition towards the player } }; @@ -487,6 +493,7 @@ namespace MWScript const int opcodePCLowerRank = 0x2000c; const int opcodePCJoinFaction = 0x2000d; const int opcodeModDisposition = 0x200014d; + const int opcodeModDispositionExplicit = 0x200014e; void registerExtensions (Compiler::Extensions& extensions) { @@ -567,7 +574,8 @@ namespace MWScript extensions.registerInstruction("pcraiserank","/S",opcodePCRaiseRank); extensions.registerInstruction("pclowerrank","/S",opcodePCLowerRank); extensions.registerInstruction("pcjoinfaction","/S",opcodePCJoinFaction); - extensions.registerInstruction("moddisposition","l",opcodeModDisposition); + extensions.registerInstruction("moddisposition","l",opcodeModDisposition, + opcodeModDispositionExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -635,7 +643,8 @@ namespace MWScript interpreter.installSegment3(opcodePCRaiseRank,new OpPCRaiseRank); interpreter.installSegment3(opcodePCLowerRank,new OpPCLowerRank); interpreter.installSegment3(opcodePCJoinFaction,new OpPCJoinFaction); - interpreter.installSegment5(opcodeModDisposition,new OpModDisposition); + interpreter.installSegment5(opcodeModDisposition,new OpModDisposition); + interpreter.installSegment5(opcodeModDispositionExplicit,new OpModDisposition); } } } From 0c6862e3e6469ade34ed6d994ffa92e2bcc90ff3 Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Fri, 13 Apr 2012 15:09:38 +0200 Subject: [PATCH 50/74] Undefining some windows defines --- apps/openmw/mwmechanics/drawstate.hpp | 2 ++ apps/openmw/mwrender/terrainmaterial.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/apps/openmw/mwmechanics/drawstate.hpp b/apps/openmw/mwmechanics/drawstate.hpp index ded25f8d5..772086d90 100644 --- a/apps/openmw/mwmechanics/drawstate.hpp +++ b/apps/openmw/mwmechanics/drawstate.hpp @@ -1,6 +1,8 @@ #ifndef GAME_MWMECHANICS_DRAWSTATE_H #define GAME_MWMECHANICS_DRAWSTATE_H +#undef DrawState + enum DrawState { DrawState_Weapon = 0, diff --git a/apps/openmw/mwrender/terrainmaterial.cpp b/apps/openmw/mwrender/terrainmaterial.cpp index 57bea5388..331bb47e3 100644 --- a/apps/openmw/mwrender/terrainmaterial.cpp +++ b/apps/openmw/mwrender/terrainmaterial.cpp @@ -39,6 +39,8 @@ THE SOFTWARE. #include #include "renderingmanager.hpp" +#undef far + namespace Ogre { //--------------------------------------------------------------------- From 226f312163593db2d46dce2c1886b8b365e03650 Mon Sep 17 00:00:00 2001 From: k1ll Date: Fri, 13 Apr 2012 17:36:31 +0200 Subject: [PATCH 51/74] Set the version in the openmw.desktop file via CMake --- CMakeLists.txt | 3 +++ files/openmw.desktop | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f3ca740af..286d0f743 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -244,6 +244,9 @@ endif (WIN32) if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.linux "${OpenMW_BINARY_DIR}/plugins.cfg") + + configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop + "${OpenMW_BINARY_DIR}/openmw.desktop") endif() if (APPLE) diff --git a/files/openmw.desktop b/files/openmw.desktop index 8643d4b13..234f660c6 100644 --- a/files/openmw.desktop +++ b/files/openmw.desktop @@ -1,5 +1,5 @@ [Desktop Entry] -Version=0.11 +Version=${OPENMW_VERSION} Type=Application Name=OpenMW Launcher GenericName=Role Playing Game From dc2751f4ec40cec649797e76c7e002a371d965fb Mon Sep 17 00:00:00 2001 From: k1ll Date: Fri, 13 Apr 2012 17:39:46 +0200 Subject: [PATCH 52/74] Moved Build options to the top. I need this for my tar.gz packages but i think this is a good idea in general. --- CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 286d0f743..d67d3eb5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,11 @@ configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_ option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE) option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE) +# Apps and tools +option(BUILD_ESMTOOL "build ESM inspector" ON) +option(BUILD_LAUNCHER "build Launcher" ON) +option(BUILD_MWINIIMPORTER "build MWiniImporter" ON) + # Sound source selection option(USE_FFMPEG "use ffmpeg for sound" OFF) option(USE_AUDIERE "use audiere for sound" OFF) @@ -416,17 +421,14 @@ add_subdirectory (components) # Apps and tools add_subdirectory( apps/openmw ) -option(BUILD_ESMTOOL "build ESM inspector" ON) if (BUILD_ESMTOOL) add_subdirectory( apps/esmtool ) endif() -option(BUILD_LAUNCHER "build Launcher inspector" ON) if (BUILD_LAUNCHER) add_subdirectory( apps/launcher ) endif() -option(BUILD_MWINIIMPORTER "build MWiniImporter inspector" ON) if (BUILD_MWINIIMPORTER) add_subdirectory( apps/mwiniimporter ) endif() From 2d6cd162966f69501ebc8c5f428f8ca4fa382400 Mon Sep 17 00:00:00 2001 From: k1ll Date: Fri, 13 Apr 2012 17:53:01 +0200 Subject: [PATCH 53/74] Now Debian Packages install the configured openmw.desktop file. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d67d3eb5f..9969747d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -315,7 +315,7 @@ if(DPKG_PROGRAM) endif() #Install icon and desktop file - INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/openmw.desktop" DESTINATION "share/applications/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") + INSTALL(FILES "${OpenMW_BINARY_DIR}/files/openmw.desktop" DESTINATION "share/applications/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "share/pixmaps/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") #Install global configuration files From 8156e9e5c4022db029213f04e5e62eb8958dac8a Mon Sep 17 00:00:00 2001 From: k1ll Date: Fri, 13 Apr 2012 18:20:49 +0200 Subject: [PATCH 54/74] Fixed install search path for openmw.desktop. It's directly in the binary dir. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9969747d3..442710a02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -315,7 +315,7 @@ if(DPKG_PROGRAM) endif() #Install icon and desktop file - INSTALL(FILES "${OpenMW_BINARY_DIR}/files/openmw.desktop" DESTINATION "share/applications/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") + INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "share/applications/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "share/pixmaps/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") #Install global configuration files From 52b0b28c78f1423c463cfbb390bb1a1f3f6d2161 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 13 Apr 2012 19:20:59 +0200 Subject: [PATCH 55/74] fixed the mygui output on console --- libs/openengine/gui/manager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/openengine/gui/manager.cpp b/libs/openengine/gui/manager.cpp index 2d84ac804..1bf8ec325 100644 --- a/libs/openengine/gui/manager.cpp +++ b/libs/openengine/gui/manager.cpp @@ -18,7 +18,6 @@ void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool // manager before the main gui system itself, otherwise the main // object will get the chance to spit out a few messages before we // can able to disable it. - /// \todo - can't avoid this with MyGUI 3.2? std::string theLogFile = std::string(MYGUI_PLATFORM_LOG_FILENAME); if(!logDir.empty()) @@ -26,9 +25,9 @@ void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool // Set up OGRE platform. We might make this more generic later. mPlatform = new OgrePlatform(); + LogManager::getInstance().setSTDOutputEnabled(logging); mPlatform->initialise(wnd, mgr, "General", theLogFile); - LogManager::getInstance().setSTDOutputEnabled(logging); // Create GUI mGui = new Gui(); From 7551926afd698109527cd76888bbb8a8f567750e Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Fri, 13 Apr 2012 23:25:15 -0400 Subject: [PATCH 56/74] 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 37e3573f8..34dbb0862 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 e5858e38c..b3d9b3c4a 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 e04d127f30817dfbe02eebe9cc65f358515cfe59 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 14 Apr 2012 15:10:26 +0200 Subject: [PATCH 57/74] terrain shader fixes --- apps/openmw/mwrender/terrainmaterial.cpp | 68 +++++++++--------------- 1 file changed, 26 insertions(+), 42 deletions(-) diff --git a/apps/openmw/mwrender/terrainmaterial.cpp b/apps/openmw/mwrender/terrainmaterial.cpp index 331bb47e3..7ed2a703b 100644 --- a/apps/openmw/mwrender/terrainmaterial.cpp +++ b/apps/openmw/mwrender/terrainmaterial.cpp @@ -540,7 +540,6 @@ namespace Ogre params->setNamedAutoConstant("viewProjMatrix", GpuProgramParameters::ACT_VIEWPROJ_MATRIX); params->setNamedAutoConstant("lodMorph", GpuProgramParameters::ACT_CUSTOM, Terrain::LOD_MORPH_CUSTOM_PARAM); - params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); if (prof->isShadowingEnabled(tt, terrain)) { @@ -576,7 +575,7 @@ namespace Ogre { params->setNamedAutoConstant("lightPosObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i); params->setNamedAutoConstant("lightDiffuseColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i); - if (prof->getNumberOfLightsSupported() > 1) + if (i > 0) params->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i); //params->setNamedAutoConstant("lightSpecularColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, i); } @@ -586,6 +585,7 @@ namespace Ogre params->setNamedAutoConstant("eyePosObjSpace", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE); params->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR); + params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); if (prof->isShadowingEnabled(tt, terrain)) { @@ -813,11 +813,11 @@ namespace Ogre outStream << "out float4 oPos : POSITION,\n" - "out float4 oPosObj : COLOR \n"; + "out float4 oPosObj : TEXCOORD0 \n"; - uint texCoordSet = 0; + uint texCoordSet = 1; outStream << - ", out float4 oUVMisc : TEXCOORD" << texCoordSet++ <<" // xy = uv, z = camDepth\n"; + ", out float4 oUVMisc : COLOR0 // xy = uv, z = camDepth\n"; // layer UV's premultiplied, packed as xy/zw uint numUVSets = numLayers / 2; @@ -837,14 +837,6 @@ namespace Ogre outStream << ", out float2 lodInfo : TEXCOORD" << texCoordSet++ << "\n"; } - bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - outStream << - ", uniform float4 fogParams\n"; - //", out float fogVal : COLOR\n"; - } - if (prof->isShadowingEnabled(tt, terrain)) { texCoordSet = generateVpDynamicShadowsParams(texCoordSet, prof, terrain, tt, outStream); @@ -940,11 +932,11 @@ namespace Ogre outStream << "void main_fp(\n" - "float4 position : COLOR,\n"; + "float4 position : TEXCOORD0,\n"; - uint texCoordSet = 0; + uint texCoordSet = 1; outStream << - "float4 uvMisc : TEXCOORD" << texCoordSet++ << ",\n"; + "float4 uvMisc : COLOR0,\n"; // UV's premultiplied, packed as xy/zw uint maxLayers = prof->getMaxLayers(terrain); @@ -971,8 +963,8 @@ namespace Ogre if (fog) { outStream << + "uniform float4 fogParams, \n" "uniform float3 fogColour, \n"; - //"float fogVal : COLOR,\n"; } uint currentSamplerIdx = 0; @@ -991,7 +983,7 @@ namespace Ogre //"uniform float3 lightSpecularColour"<getNumberOfLightsSupported() > 1) + if (i > 0) outStream << "uniform float4 lightAttenuation"<getNumberOfLightsSupported() > 1) + if (i > 0) outStream << // pre-multiply light color with attenuation factor "d = length( lightDir"<getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - if (terrain->getSceneManager()->getFogMode() == FOG_LINEAR) - { - outStream << - " float fogVal = saturate((oPos.z - fogParams.y) * fogParams.w);\n"; - } - else - { - outStream << - " float fogVal = saturate(1 / (exp(oPos.z * fogParams.x)));\n"; - } - outStream << - " oPosObj.w = fogVal; \n"; - } + " oPosObj.w = oPos.z;\n"; if (prof->isShadowingEnabled(tt, terrain)) generateVpDynamicShadows(prof, terrain, tt, outStream); @@ -1369,6 +1343,16 @@ namespace Ogre bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; if (fog) { + if (terrain->getSceneManager()->getFogMode() == FOG_LINEAR) + { + outStream << + " float fogVal = saturate((position.w - fogParams.y) * fogParams.w);\n"; + } + else + { + outStream << + " float fogVal = saturate(1 / (exp(position.w * fogParams.x)));\n"; + } outStream << " outputCol.rgb = lerp(outputCol.rgb, fogColour, fogVal);\n"; } @@ -1376,7 +1360,7 @@ namespace Ogre outStream << " oColor = outputCol;\n"; if (MWRender::RenderingManager::useMRT()) outStream << - " oColor1 = float4(uvMisc.z / far, 0, 0, 1); \n"; + " oColor1 = float4(position.w / far, 0, 0, 1); \n"; outStream << "}\n"; @@ -1585,7 +1569,7 @@ namespace Ogre { uint numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); outStream << - " float camDepth = uvMisc.z;\n"; + " float camDepth = position.w;\n"; if (prof->getReceiveDynamicShadowsDepth()) { @@ -1629,8 +1613,8 @@ namespace Ogre outStream << " float fadeRange = shadowFar_fadeStart.x - shadowFar_fadeStart.y; \n" - " float fade = 1-((uvMisc.z - shadowFar_fadeStart.y) / fadeRange); \n" - " rtshadow = (uvMisc.z > shadowFar_fadeStart.x) ? 1 : ((uvMisc.z > shadowFar_fadeStart.y) ? 1-((1-rtshadow)*fade) : rtshadow); \n" + " float fade = 1-((position.w - shadowFar_fadeStart.y) / fadeRange); \n" + " rtshadow = (position.w > shadowFar_fadeStart.x) ? 1 : ((position.w > shadowFar_fadeStart.y) ? 1-((1-rtshadow)*fade) : rtshadow); \n" " rtshadow = (1-(1-rtshadow)*0.6); \n" // make the shadow a little less intensive " shadow = min(shadow, rtshadow);\n"; From fa5a1432c9817238245be20ec3ee17ec3107c3f9 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 14 Apr 2012 15:58:58 +0200 Subject: [PATCH 58/74] map lighting tweak, default settings tweak --- apps/openmw/mwrender/renderingmanager.cpp | 2 ++ files/settings-default.cfg | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 984b7ddc9..c1462807f 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -482,11 +482,13 @@ void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell) void RenderingManager::disableLights() { mObjects.disableLights(); + sunDisable(); } void RenderingManager::enableLights() { mObjects.enableLights(); + sunEnable(); } const bool RenderingManager::useMRT() diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 4d2d46fca..553a82e49 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -93,7 +93,7 @@ rtt size = 512 reflect terrain = true reflect statics = false reflect small statics = false -reflect actors = true +reflect actors = false reflect misc = false # Enable underwater effect. It is not resource intensive, so only disable it if you have problems. From 4b0099fb5b1c90214a14e0d387d52a2ed2668c0f Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 14 Apr 2012 16:10:47 +0200 Subject: [PATCH 59/74] npc visibility flags fix --- apps/openmw/mwrender/npcanimation.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 9de5705e3..a231e8fe7 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -240,6 +240,7 @@ Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, std::stri NIFLoader::load(mesh); Entity* ent = mRend.getScene()->createEntity(mesh); + ent->setVisibilityFlags(RV_Actors); base->attachObjectToBone(bonename, ent); return ent; @@ -249,9 +250,7 @@ void NpcAnimation::insertFreePart(const std::string &mesh, const std::string suf NIFLoader::load(meshNumbered); Ogre::Entity* ent = mRend.getScene()->createEntity(meshNumbered); - - - + ent->setVisibilityFlags(RV_Actors); insert->attachObject(ent); entityparts.push_back(ent); From 5d4ad4cd810501e09f2b6550fb4e28204ebe8223 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 14 Apr 2012 16:44:46 -0400 Subject: [PATCH 60/74] 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 1fbc11c63..672a2b60a 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 34dbb0862..08c53f39d 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 b3d9b3c4a..377560222 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 61/74] 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 08c53f39d..bacee7f2d 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 377560222..545634e1f 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 62/74] 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 bacee7f2d..5adb9914d 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 545634e1f..7785ffc1a 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 63/74] 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 5adb9914d..3a9525949 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 7785ffc1a..255989d28 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 64/74] Adding tons of skin body parts --- apps/openmw/mwrender/npcanimation.cpp | 137 ++++++++++++++++++++++++-- 1 file changed, 130 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 3a9525949..bc134581d 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_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); } + 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_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_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 45a5877b235e6e41841e83554ada94b0186b9000 Mon Sep 17 00:00:00 2001 From: gugus Date: Sun, 15 Apr 2012 12:05:46 +0200 Subject: [PATCH 65/74] implement getPCRank. Does not work yet. --- apps/openmw/mwscript/docs/vmformat.txt | 6 ++- apps/openmw/mwscript/statsextensions.cpp | 53 ++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index fda8d1954..c38ff611c 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -26,8 +26,10 @@ op 0x20009: LoopAnim, explicit reference op 0x2000a: Choice op 0x2000b: PCRaiseRank op 0x2000c: PCLowerRank -op x20000d: PCJoinFaction -opcodes 0x2000e-0x3ffff unused +op 0x2000d: PCJoinFaction +op 0x2000e: PCGetRank implicit +op 0x2000f: PCGetRank explicit +opcodes 0x20010-0x3ffff unused Segment 4: (not implemented yet) diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 9d3009870..727b2d0e1 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -435,6 +435,54 @@ namespace MWScript } }; + template + class OpGetPCRank : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + MWWorld::Ptr ptr = R()(runtime); + runtime.pop(); + + std::string factionID = ""; + if(arg0 >0) + { + factionID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + } + else + { + if(MWWorld::Class::get(ptr).getNpcStats(ptr).mFactionRank.empty()) + { + //throw exception? + } + else + { + factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).mFactionRank.begin()->first; + } + } + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + if(factionID!="") + { + if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) != MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) + { + runtime.push(MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID]); + } + else + { + runtime.push(-1); + } + } + else + { + runtime.push(-1); + } + } + }; + template class OpModDisposition : public Interpreter::Opcode0 { @@ -492,6 +540,8 @@ namespace MWScript const int opcodePCRaiseRank = 0x2000b; const int opcodePCLowerRank = 0x2000c; const int opcodePCJoinFaction = 0x2000d; + const int opcodeGetPCRank = 0x2000e; + const int opcodeGetPCRankExplicit = 0x2000f; const int opcodeModDisposition = 0x200014d; const int opcodeModDispositionExplicit = 0x200014e; @@ -576,6 +626,7 @@ namespace MWScript extensions.registerInstruction("pcjoinfaction","/S",opcodePCJoinFaction); extensions.registerInstruction("moddisposition","l",opcodeModDisposition, opcodeModDispositionExplicit); + extensions.registerFunction("getpcrank",'l',"/S",opcodeGetPCRank,opcodeGetPCRankExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -645,6 +696,8 @@ namespace MWScript interpreter.installSegment3(opcodePCJoinFaction,new OpPCJoinFaction); interpreter.installSegment5(opcodeModDisposition,new OpModDisposition); interpreter.installSegment5(opcodeModDispositionExplicit,new OpModDisposition); + interpreter.installSegment3(opcodeGetPCRank,new OpGetPCRank); + interpreter.installSegment3(opcodeGetPCRankExplicit,new OpGetPCRank); } } } From f68248e0d0800d37a18afde61fa2380ec79dccd4 Mon Sep 17 00:00:00 2001 From: gugus Date: Sun, 15 Apr 2012 14:20:08 +0200 Subject: [PATCH 66/74] corrected a bug in getPCRank --- apps/openmw/mwscript/statsextensions.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 727b2d0e1..239f8d768 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -443,7 +443,6 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { MWWorld::Ptr ptr = R()(runtime); - runtime.pop(); std::string factionID = ""; if(arg0 >0) From c24a85848f0d162b76c320465e524883e8124d07 Mon Sep 17 00:00:00 2001 From: gugus Date: Sun, 15 Apr 2012 15:56:36 +0200 Subject: [PATCH 67/74] forceGreeting script instruction --- apps/openmw/mwscript/dialogueextensions.cpp | 17 +++++++++++++++++ apps/openmw/mwscript/docs/vmformat.txt | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/dialogueextensions.cpp b/apps/openmw/mwscript/dialogueextensions.cpp index 0cca028e2..178485f78 100644 --- a/apps/openmw/mwscript/dialogueextensions.cpp +++ b/apps/openmw/mwscript/dialogueextensions.cpp @@ -11,6 +11,7 @@ #include "../mwdialogue/dialoguemanager.hpp" #include "interpretercontext.hpp" +#include "ref.hpp" namespace MWScript { @@ -115,12 +116,26 @@ namespace MWScript } }; + template + class OpForceGreeting : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + context.getEnvironment().mDialogueManager->startDialogue (ptr); + } + }; const int opcodeJournal = 0x2000133; const int opcodeSetJournalIndex = 0x2000134; const int opcodeGetJournalIndex = 0x2000135; const int opcodeAddTopic = 0x200013a; const int opcodeChoice = 0x2000a; + const int opcodeForceGreeting = 0x200014f; void registerExtensions (Compiler::Extensions& extensions) { @@ -129,6 +144,7 @@ namespace MWScript extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex); extensions.registerInstruction ("addtopic", "S" , opcodeAddTopic); extensions.registerInstruction ("choice", "/SlSlSlSlSlSlSlSlSlSlSlSlSlSlSlSl", opcodeChoice); + extensions.registerInstruction("forcegreeting","",-1,opcodeForceGreeting); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -138,6 +154,7 @@ namespace MWScript interpreter.installSegment5 (opcodeGetJournalIndex, new OpGetJournalIndex); interpreter.installSegment5 (opcodeAddTopic, new OpAddTopic); interpreter.installSegment3 (opcodeChoice,new OpChoice); + interpreter.installSegment5 (opcodeForceGreeting, new OpForceGreeting); } } diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index c38ff611c..9155746ed 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -142,4 +142,5 @@ op 0x200014b: GetSpell op 0x200014c: GetSpell, explicit reference op 0x200014d: ModDisposition op 0x200014e: ModDisposition, explicit reference -opcodes 0x200014f-0x3ffffff unused +op 0x200014f: ForceGreeting +opcodes 0x200015-0x3ffffff unused From b5d12d0723731a39ef6ce1bf61c669bf47957bc1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 15 Apr 2012 17:08:22 +0200 Subject: [PATCH 68/74] fixed ForceGreeting --- apps/openmw/mwscript/dialogueextensions.cpp | 8 ++++++-- apps/openmw/mwscript/docs/vmformat.txt | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwscript/dialogueextensions.cpp b/apps/openmw/mwscript/dialogueextensions.cpp index 178485f78..fec539d3e 100644 --- a/apps/openmw/mwscript/dialogueextensions.cpp +++ b/apps/openmw/mwscript/dialogueextensions.cpp @@ -136,6 +136,7 @@ namespace MWScript const int opcodeAddTopic = 0x200013a; const int opcodeChoice = 0x2000a; const int opcodeForceGreeting = 0x200014f; + const int opcodeForceGreetingExplicit = 0x2000150; void registerExtensions (Compiler::Extensions& extensions) { @@ -144,7 +145,9 @@ namespace MWScript extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex); extensions.registerInstruction ("addtopic", "S" , opcodeAddTopic); extensions.registerInstruction ("choice", "/SlSlSlSlSlSlSlSlSlSlSlSlSlSlSlSl", opcodeChoice); - extensions.registerInstruction("forcegreeting","",-1,opcodeForceGreeting); + extensions.registerInstruction("forcegreeting","",opcodeForceGreeting); + extensions.registerInstruction("forcegreeting","",opcodeForceGreeting, + opcodeForceGreetingExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -154,7 +157,8 @@ namespace MWScript interpreter.installSegment5 (opcodeGetJournalIndex, new OpGetJournalIndex); interpreter.installSegment5 (opcodeAddTopic, new OpAddTopic); interpreter.installSegment3 (opcodeChoice,new OpChoice); - interpreter.installSegment5 (opcodeForceGreeting, new OpForceGreeting); + interpreter.installSegment5 (opcodeForceGreeting, new OpForceGreeting); + interpreter.installSegment5 (opcodeForceGreetingExplicit, new OpForceGreeting); } } diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 9155746ed..58960aac4 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -143,4 +143,5 @@ op 0x200014c: GetSpell, explicit reference op 0x200014d: ModDisposition op 0x200014e: ModDisposition, explicit reference op 0x200014f: ForceGreeting -opcodes 0x200015-0x3ffffff unused +op 0x2000150: ForceGreeting, explicit reference +opcodes 0x2000151-0x3ffffff unused From 1b5d327f7e7ec8d94c7c25baee11cd4252db74be Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sun, 15 Apr 2012 18:56:46 +0200 Subject: [PATCH 69/74] Fixed OS X build with static MyGUI --- cmake/FindFreetype.cmake | 69 ++++++++++++++++++++++++++++++++ cmake/FindMyGUI.cmake | 86 ++++++++++++++++++++++++---------------- 2 files changed, 121 insertions(+), 34 deletions(-) create mode 100644 cmake/FindFreetype.cmake diff --git a/cmake/FindFreetype.cmake b/cmake/FindFreetype.cmake new file mode 100644 index 000000000..fc36d548e --- /dev/null +++ b/cmake/FindFreetype.cmake @@ -0,0 +1,69 @@ +#------------------------------------------------------------------- +# This file is part of the CMake build system for OGRE +# (Object-oriented Graphics Rendering Engine) +# For the latest info, see http://www.ogre3d.org/ +# +# The contents of this file are placed in the public domain. Feel +# free to make use of it in any way you like. +#------------------------------------------------------------------- + +# - Try to find FreeType +# Once done, this will define +# +# FREETYPE_FOUND - system has FreeType +# FREETYPE_INCLUDE_DIRS - the FreeType include directories +# FREETYPE_LIBRARIES - link these to use FreeType + +include(FindPkgMacros) +findpkg_begin(FREETYPE) + +# Get path, convert backslashes as ${ENV_${var}} +getenv_path(FREETYPE_HOME) + +# construct search paths +set(FREETYPE_PREFIX_PATH ${FREETYPE_HOME} ${ENV_FREETYPE_HOME}) +create_search_paths(FREETYPE) +# redo search if prefix path changed +clear_if_changed(FREETYPE_PREFIX_PATH + FREETYPE_LIBRARY_FWK + FREETYPE_LIBRARY_REL + FREETYPE_LIBRARY_DBG + FREETYPE_INCLUDE_DIR +) + +set(FREETYPE_LIBRARY_NAMES freetype2311 freetype239 freetype238 freetype235 freetype219 freetype) +get_debug_names(FREETYPE_LIBRARY_NAMES) + +use_pkgconfig(FREETYPE_PKGC freetype2) + +# prefer static library over framework +set(CMAKE_FIND_FRAMEWORK "LAST") + +message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}") +findpkg_framework(FREETYPE) +message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}") + +find_path(FREETYPE_INCLUDE_DIR NAMES freetype/freetype.h HINTS ${FREETYPE_INC_SEARCH_PATH} ${FREETYPE_PKGC_INCLUDE_DIRS} PATH_SUFFIXES freetype2) +find_path(FREETYPE_FT2BUILD_INCLUDE_DIR NAMES ft2build.h HINTS ${FREETYPE_INC_SEARCH_PATH} ${FREETYPE_PKGC_INCLUDE_DIRS}) + +if (SYMBIAN) +set(ORIGINAL_CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH}) +set(CMAKE_PREFIX_PATH ${CMAKE_SYSYEM_OUT_DIR}) +message(STATUS "Lib will be searched in Symbian out dir: ${CMAKE_SYSYEM_OUT_DIR}") +endif (SYMBIAN) +find_library(FREETYPE_LIBRARY_REL NAMES ${FREETYPE_LIBRARY_NAMES} HINTS ${FREETYPE_LIB_SEARCH_PATH} ${FREETYPE_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" release relwithdebinfo minsizerel) +find_library(FREETYPE_LIBRARY_DBG NAMES ${FREETYPE_LIBRARY_NAMES_DBG} HINTS ${FREETYPE_LIB_SEARCH_PATH} ${FREETYPE_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" debug) +if (SYMBIAN) +set(CMAKE_PREFIX_PATH ${ORIGINAL_CMAKE_PREFIX_PATH}) +endif (SYMBIAN) + +make_library_set(FREETYPE_LIBRARY) + +findpkg_finish(FREETYPE) +mark_as_advanced(FREETYPE_FT2BUILD_INCLUDE_DIR) +if (NOT FREETYPE_FT2BUILD_INCLUDE_DIR STREQUAL FREETYPE_INCLUDE_DIR) + set(FREETYPE_INCLUDE_DIRS ${FREETYPE_INCLUDE_DIRS} ${FREETYPE_FT2BUILD_INCLUDE_DIR}) +endif () + +# Reset framework finding +set(CMAKE_FIND_FRAMEWORK "FIRST") diff --git a/cmake/FindMyGUI.cmake b/cmake/FindMyGUI.cmake index 6731d584c..dbcf8f11c 100644 --- a/cmake/FindMyGUI.cmake +++ b/cmake/FindMyGUI.cmake @@ -82,37 +82,49 @@ findpkg_finish ( "MYGUI" ) ELSE (WIN32) #Unix CMAKE_MINIMUM_REQUIRED(VERSION 2.4.7 FATAL_ERROR) FIND_PACKAGE(PkgConfig) - IF(MYGUI_STATIC) - PKG_SEARCH_MODULE(MYGUI MYGUIStatic MyGUIStatic) - IF (MYGUI_INCLUDE_DIRS) - SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) - SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) - SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") - SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") - ELSE (MYGUI_INCLUDE_DIRS) - FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) - FIND_LIBRARY(MYGUI_LIBRARIES myguistatic PATHS /usr/lib /usr/local/lib) - SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") - SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) - STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") - STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") - ENDIF (MYGUI_INCLUDE_DIRS) - ELSE(MYGUI_STATIC) - PKG_SEARCH_MODULE(MYGUI MYGUI MyGUI) - IF (MYGUI_INCLUDE_DIRS) - SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) - SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) - SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") - SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") - ELSE (MYGUI_INCLUDE_DIRS) - FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) - FIND_LIBRARY(MYGUI_LIBRARIES mygui PATHS /usr/lib /usr/local/lib) - SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") - SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) - STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") - STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") - ENDIF (MYGUI_INCLUDE_DIRS) - ENDIF(MYGUI_STATIC) + IF(MYGUI_STATIC) + # don't use pkgconfig on OS X, find freetype & append it's libs to resulting MYGUI_LIBRARIES + IF (NOT APPLE) + PKG_SEARCH_MODULE(MYGUI MYGUIStatic MyGUIStatic) + IF (MYGUI_INCLUDE_DIRS) + SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) + SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) + SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + ELSE (MYGUI_INCLUDE_DIRS) + FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) + FIND_LIBRARY(MYGUI_LIBRARIES myguistatic PATHS /usr/lib /usr/local/lib) + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) + STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") + STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") + ENDIF (MYGUI_INCLUDE_DIRS) + ELSE (NOT APPLE) + SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${MYGUI_DEPENDENCIES_DIR} ${OGRE_DEPENDENCIES_DIR}) + FIND_PACKAGE(freetype) + FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) + FIND_LIBRARY(MYGUI_LIBRARIES MyGUIEngineStatic PATHS /usr/lib /usr/local/lib) + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) + STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") + STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") + ENDIF (NOT APPLE) + ELSE(MYGUI_STATIC) + PKG_SEARCH_MODULE(MYGUI MYGUI MyGUI) + IF (MYGUI_INCLUDE_DIRS) + SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) + SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) + SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + ELSE (MYGUI_INCLUDE_DIRS) + FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) + FIND_LIBRARY(MYGUI_LIBRARIES mygui PATHS /usr/lib /usr/local/lib) + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) + STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") + STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") + ENDIF (MYGUI_INCLUDE_DIRS) + ENDIF(MYGUI_STATIC) ENDIF (WIN32) #Do some preparation @@ -120,17 +132,23 @@ SEPARATE_ARGUMENTS(MYGUI_INCLUDE_DIRS) SEPARATE_ARGUMENTS(MYGUI_LIBRARIES) SEPARATE_ARGUMENTS(MYGUI_PLATFORM_LIBRARIES) +SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} ${FREETYPE_LIBRARIES}) + SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS} CACHE PATH "") SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") SET(MYGUI_PLATFORM_LIBRARIES ${MYGUI_PLATFORM_LIBRARIES} CACHE STRING "") SET(MYGUI_LIB_DIR ${MYGUI_LIB_DIR} CACHE PATH "") -IF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES) +IF (NOT APPLE OR NOT MYGUI_STATIC) # we need freetype libs only on OS X for static build, for other cases just make it TRUE + SET(FREETYPE_LIBRARIES TRUE) +ENDIF (NOT APPLE OR NOT MYGUI_STATIC) + +IF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES AND FREETYPE_LIBRARIES) SET(MYGUI_FOUND TRUE) -ENDIF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES) +ENDIF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES AND FREETYPE_LIBRARIES) IF (MYGUI_FOUND) -MARK_AS_ADVANCED(MYGUI_LIB_DIR) + MARK_AS_ADVANCED(MYGUI_LIB_DIR) IF (NOT MYGUI_FIND_QUIETLY) MESSAGE(STATUS " libraries : ${MYGUI_LIBRARIES} from ${MYGUI_LIB_DIR}") MESSAGE(STATUS " includes : ${MYGUI_INCLUDE_DIRS}") From bc8bb9c57ead538e4568f629b68b40863804c0be Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 15 Apr 2012 14:22:55 -0400 Subject: [PATCH 70/74] 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 d0019154e..5755418e2 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 71/74] 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 bc134581d..2f8763549 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 255989d28..c7c22ad55 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); + }; } From 677a907528f9e5fbcecabc2a4489efb119e950c5 Mon Sep 17 00:00:00 2001 From: Nikolay Kasyanov Date: Sun, 15 Apr 2012 21:37:33 +0200 Subject: [PATCH 72/74] fixed comment --- cmake/FindMyGUI.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/FindMyGUI.cmake b/cmake/FindMyGUI.cmake index dbcf8f11c..c79ee5998 100644 --- a/cmake/FindMyGUI.cmake +++ b/cmake/FindMyGUI.cmake @@ -139,7 +139,7 @@ SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") SET(MYGUI_PLATFORM_LIBRARIES ${MYGUI_PLATFORM_LIBRARIES} CACHE STRING "") SET(MYGUI_LIB_DIR ${MYGUI_LIB_DIR} CACHE PATH "") -IF (NOT APPLE OR NOT MYGUI_STATIC) # we need freetype libs only on OS X for static build, for other cases just make it TRUE +IF (NOT APPLE OR NOT MYGUI_STATIC) # we need explicit freetype libs only on OS X for static build, for other cases just make it TRUE SET(FREETYPE_LIBRARIES TRUE) ENDIF (NOT APPLE OR NOT MYGUI_STATIC) From 268b7cd6fc3a5f9e6281ba6627be735a461a8665 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 15 Apr 2012 22:05:33 +0200 Subject: [PATCH 73/74] replaced typename checks --- apps/openmw/mwrender/npcanimation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 9cc3c26f6..0f25a1ff4 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -308,12 +308,12 @@ void NpcAnimation::updateParts(){ } if(!isBeast && boots != inv.end()){ - if(boots->getTypeName() == "struct ESM::Clothing"){ + if(boots->getTypeName() == typeid(ESM::Clothing).name()){ const ESM::Clothing *clothes = (boots->get())->base; std::vector parts = clothes->parts.parts; addPartGroup(MWWorld::InventoryStore::Slot_Boots, 2, parts); } - else + else if(boots->getTypeName() == typeid(ESM::Armor).name()) { const ESM::Armor *armor = (boots->get())->base; std::vector parts = armor->parts.parts; @@ -323,7 +323,7 @@ void NpcAnimation::updateParts(){ } if(leftglove != inv.end()){ - if(leftglove->getTypeName() == "struct ESM::Clothing"){ + if(leftglove->getTypeName() == typeid(ESM::Clothing).name()){ const ESM::Clothing *clothes = (leftglove->get())->base; std::vector parts = clothes->parts.parts; addPartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet, 2, parts); @@ -338,7 +338,7 @@ void NpcAnimation::updateParts(){ } if(rightglove != inv.end()){ - if(rightglove->getTypeName() == "struct ESM::Clothing"){ + if(rightglove->getTypeName() == typeid(ESM::Clothing).name()){ const ESM::Clothing *clothes = (rightglove->get())->base; std::vector parts = clothes->parts.parts; addPartGroup(MWWorld::InventoryStore::Slot_RightGauntlet, 2, parts); From b76fd249c7272350015fff07a9936cfa94448cb2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 15 Apr 2012 23:18:34 +0200 Subject: [PATCH 74/74] updated changelog; bumped version number --- CMakeLists.txt | 6 +++--- readme.txt | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 713cfa3e2..f1325c784 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ include (OpenMWMacros) # Version set (OPENMW_VERSION_MAJOR 0) -set (OPENMW_VERSION_MINOR 13) +set (OPENMW_VERSION_MINOR 14) set (OPENMW_VERSION_RELEASE 0) set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") @@ -122,7 +122,7 @@ set(OENGINE_BULLET ${LIBDIR}/openengine/bullet/physic.hpp ${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp ${LIBDIR}/openengine/bullet/BulletShapeLoader.h - + ) set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI} ${OENGINE_BULLET}) @@ -361,7 +361,7 @@ if(WIN32) INSTALL(FILES ${files} DESTINATION ".") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") INSTALL(FILES - "${OpenMW_SOURCE_DIR}/readme.txt" + "${OpenMW_SOURCE_DIR}/readme.txt" "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION ".") INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".") diff --git a/readme.txt b/readme.txt index e1c24ab52..52c4e11a2 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ OpenMW: A reimplementation of The Elder Scrolls III: Morrowind OpenMW is an attempt at recreating the engine for the popular role-playing game Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work. -Version: 0.13.0 +Version: 0.14.0 License: GPL (see GPL3.txt for more information) Website: http://www.openmw.org @@ -64,8 +64,6 @@ Allowed options: --start arg (=Beshara) set initial cell --master arg master file(s) --plugin arg plugin file(s) - --fps [=arg(=1)] (=0) fps counter detail (0 = off, 1 = fps counter - , 2 = full detail) --anim-verbose [=arg(=1)] (=0) output animation indices files --debug [=arg(=1)] (=0) debug mode --nosound [=arg(=1)] (=0) disable all sounds @@ -90,6 +88,7 @@ Allowed options: win1252 - Western European (Latin) alphabet, used by default --report-focus [=arg(=1)] (=0) write name of focussed object to cout + --fallback arg fallback values CREDITS @@ -134,6 +133,36 @@ Thanks to Kevin Ryan for kindly providing us with the icon used for the Data Fil CHANGELOG +0.14.0 + +Bug #1: Meshes rendered with wrong orientation +Bug #6/Task #220: Picking up small objects doesn't always work +Bug #127: tcg doesn't work +Bug #178: Compablity problems with Ogre 1.8.0 RC 1 +Bug #211: Wireframe mode (toggleWireframe command) should not apply to Console & other UI +Bug #227: Terrain crashes when moving away from predefined cells +Bug #229: On OS X Launcher cannot launch game if path to binary contains spaces +Bug #235: TGA texture loading problem +Bug #246: wireframe mode does not work in water +Feature #8/#232: Water Rendering +Feature #13: Terrain Rendering +Feature #37: Render Path Grid +Feature #66: Factions +Feature #77: Local Map +Feature #78: Compass/Mini-Map +Feature #97: Render Clothing/Armour +Feature #121: Window Pinning +Feature #205: Auto equip +Feature #217: Contiainer should track changes to its content +Feature #221: NPC Dialogue Window Enhancements +Feature #233: Game settings manager +Feature #240: Spell List and selected spell (no GUI yet) +Feature #243: Draw State +Task #113: Morrowind.ini Importer +Task #215: Refactor the sound code +Task #216: Update MyGUI + + 0.13.0 Bug #145: Fixed sound problems after cell change