From 18a139cd66dada5a42b93a7f26bb46c7929fa744 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 24 Mar 2012 22:03:08 -0400 Subject: [PATCH 01/22] adding up and down move buttons --- apps/openmw/mwclass/npc.cpp | 5 +- apps/openmw/mwinput/inputmanager.cpp | 16 + apps/openmw/mwmechanics/movement.hpp | 3 +- apps/openmw/mwrender/objects.cpp | 2 + apps/openmw/mwworld/physicssystem.cpp | 15 +- apps/openmw/mwworld/player.cpp | 9 + apps/openmw/mwworld/player.hpp | 1 + apps/openmw/physicssystem.cpp | 225 +++++++ libs/openengine/bullet/physic.cpp | 4 +- libs/openengine/bullet/pmove.cpp | 27 +- libs/openengine/bullet/pmove.h | 4 +- libs/openengine/bullet/trace.cpp | 4 +- libs/openengine/bullet/weather.cpp | 811 ++++++++++++++++++++++++++ libs/openengine/bullet/weather.hpp | 272 +++++++++ 14 files changed, 1374 insertions(+), 24 deletions(-) create mode 100644 apps/openmw/physicssystem.cpp create mode 100644 libs/openengine/bullet/weather.cpp create mode 100644 libs/openengine/bullet/weather.hpp diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 83a94d27d1..522fce3a3c 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -269,8 +269,9 @@ namespace MWClass { Ogre::Vector3 vector (0, 0, 0); - vector.x = - getMovementSettings (ptr).mLeftRight * 200; - vector.y = getMovementSettings (ptr).mForwardBackward * 200; + vector.x = - getMovementSettings (ptr).mLeftRight * 127; + vector.y = getMovementSettings (ptr).mForwardBackward * 127; + vector.z = getMovementSettings(ptr).mUpDown * 127; if (getStance (ptr, Run, false)) vector *= 2; diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index 88534dddae..074f8a906a 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -60,6 +60,7 @@ namespace MWInput A_CycleWeaponRight, A_ToggleSneak, //Toggles Sneak, add Push-Sneak later A_ToggleWalk, //Toggle Walking/Running + A_Crouch, A_QuickSave, A_QuickLoad, @@ -259,6 +260,9 @@ namespace MWInput poller.bind(A_MoveRight, KC_D); poller.bind(A_MoveForward, KC_W); poller.bind(A_MoveBackward, KC_S); + + poller.bind(A_Jump, KC_E); + poller.bind(A_Crouch, KC_LCONTROL); } //NOTE: Used to check for movement keys @@ -306,6 +310,18 @@ namespace MWInput else player.setForwardBackward (0); + if (poller.isDown(A_Jump)) + { + + player.setUpDown (1); + } + else if (poller.isDown(A_Crouch)) + { + player.setUpDown (-1); + } + else + player.setUpDown (0); + return true; } diff --git a/apps/openmw/mwmechanics/movement.hpp b/apps/openmw/mwmechanics/movement.hpp index a555ac010a..11eb83151e 100644 --- a/apps/openmw/mwmechanics/movement.hpp +++ b/apps/openmw/mwmechanics/movement.hpp @@ -8,8 +8,9 @@ namespace MWMechanics { signed char mLeftRight; // 1: wants to move left, -1: wants to move right signed char mForwardBackward; // 1:wants to move forward, -1: wants to move backward + signed char mUpDown; - Movement() : mLeftRight (0), mForwardBackward (0) {} + Movement() : mLeftRight (0), mForwardBackward (0), mUpDown(0) {} }; } diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index 717064ada5..0d19a30130 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -56,8 +56,10 @@ void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_) Ogre::SceneNode* insert = cellnode->createChildSceneNode(); const float *f = ptr.getRefData().getPosition().pos; + insert->setPosition(f[0], f[1], f[2]); insert->setScale(ptr.getCellRef().scale, ptr.getCellRef().scale, ptr.getCellRef().scale); + // Convert MW rotation to a quaternion: f = ptr.getCellRef().pos.rot; diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 11a43c7d30..d54f4696a2 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -103,7 +103,7 @@ namespace MWWorld playerphysics->ps.viewangles.x = 0; playerphysics->ps.viewangles.z = 0; - playerphysics->ps.viewangles.y = both.getYaw().valueDegrees() *-1 + 90; + playerphysics->ps.viewangles.y = both.getYaw().valueDegrees() *-1 + 90; //playerphysics->ps.viewangles.z = both.getPitch().valueDegrees(); @@ -113,6 +113,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; + pm_ref.upmove = dir1.y; @@ -127,6 +128,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; + pm_ref.upmove = dir.y; dir = 0.025*(quat*dir1); } @@ -135,7 +137,7 @@ namespace MWWorld //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++) @@ -147,7 +149,7 @@ namespace MWWorld coord = playerphysics->ps.origin; //std::cout << "Coord" << coord << "\n"; - coord = Ogre::Vector3(coord.x, coord.z, coord.y); //x, z, -y + //coord = Ogre::Vector3(coord.x, coord.z, coord.y); //x, z, -y } response.push_back(std::pair(it->first, coord)); @@ -218,6 +220,10 @@ namespace MWWorld bool PhysicsSystem::toggleCollisionMode() { + if(playerphysics->ps.move_type==PM_NOCLIP) + playerphysics->ps.move_type=PM_NORMAL; + else + playerphysics->ps.move_type=PM_NOCLIP; for(std::map::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) { if (it->first=="player") @@ -248,7 +254,10 @@ namespace MWWorld } void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){ + Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); + Ogre::Vector3 objPos = node->getPosition(); + addObject (node->getName(), model, node->getOrientation(), node->getScale().x, node->getPosition()); } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 5bfb82138c..884a72c3a6 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -80,6 +80,14 @@ namespace MWWorld MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value; } + void Player::setUpDown(int value) + { + MWWorld::Ptr ptr = getPlayer(); + + + + MWWorld::Class::get (ptr).getMovementSettings (ptr).mUpDown = value; + } void Player::toggleRunning() { @@ -89,4 +97,5 @@ namespace MWWorld MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Run, !running); } + } diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index 01c71da437..da74fe6ded 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -111,6 +111,7 @@ namespace MWWorld void setLeftRight (int value); void setForwardBackward (int value); + void setUpDown(int value); void toggleRunning(); }; diff --git a/apps/openmw/physicssystem.cpp b/apps/openmw/physicssystem.cpp new file mode 100644 index 0000000000..a07358f8ee --- /dev/null +++ b/apps/openmw/physicssystem.cpp @@ -0,0 +1,225 @@ +#include + +#include "physicssystem.hpp" +#include "../mwworld/ptr.hpp" +#include "../mwworld/world.hpp" // FIXME +#include + +#include "OgreRoot.h" +#include "OgreRenderWindow.h" +#include "OgreSceneManager.h" +#include "OgreViewport.h" +#include "OgreCamera.h" +#include "OgreTextureManager.h" + + +using namespace Ogre; +namespace MWWorld +{ + + PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) : + mRender(_rend), mEngine(0), mFreeFly (true) + { + // Create physics. shapeLoader is deleted by the physic engine + NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader(); + mEngine = new OEngine::Physic::PhysicEngine(shapeLoader); + } + + PhysicsSystem::~PhysicsSystem() + { + delete mEngine; + + } + OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine() + { + return mEngine; + } + + std::pair PhysicsSystem::getFacedHandle (MWWorld::World& world) + { + std::string handle = ""; + + //get a ray pointing to the center of the viewport + Ray centerRay = mRender.getCamera()->getCameraToViewportRay( + mRender.getViewport()->getWidth()/2, + mRender.getViewport()->getHeight()/2); + //let's avoid the capsule shape of the player. + centerRay.setOrigin(centerRay.getOrigin() + 20*centerRay.getDirection()); + btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y); + btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y); + + return mEngine->rayTest(from,to); + } + + bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to) + { + btVector3 _from, _to; + _from = btVector3(from.x, from.y, from.z); + _to = btVector3(to.x, to.y, to.z); + + std::pair result = mEngine->rayTest(_from, _to); + + return !(result.first == ""); + } + + + std::vector< std::pair > PhysicsSystem::doPhysics (float duration, + const std::vector >& actors) + { + //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)); + } + + for (std::vector >::const_iterator iter (actors.begin()); + iter!=actors.end(); ++iter) + { + OEngine::Physic::PhysicActor* act = mEngine->getCharacter(iter->first); + + //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(); + if(mFreeFly) + { + Ogre::Quaternion yawQuat = yawNode->getOrientation(); + Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); + Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); + dir = 0.07*(yawQuat*pitchQuat*dir1); + } + else + { + Ogre::Quaternion quat = yawNode->getOrientation(); + Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); + dir = 0.025*(quat*dir1); + } + + //set the walk direction + act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y)); + } + 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()); + + 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) + { + OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale); + mEngine->addRigidBody(body); + btTransform tr; + tr.setOrigin(btVector3(position.x,position.y,position.z)); + std::cout << "Position object:" << position << "\n"; + tr.setRotation(btQuaternion(rotation.x,rotation.y,rotation.z,rotation.w)); + body->setWorldTransform(tr); + } + + void PhysicsSystem::addActor (const std::string& handle, const std::string& mesh, + const Ogre::Vector3& position) + { + //TODO:optimize this. Searching the std::map isn't very efficient i think. + mEngine->addCharacter(handle); + OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle); + act->setPosition(btVector3(position.x,position.y,position.z)); + } + + void PhysicsSystem::removeObject (const std::string& handle) + { + //TODO:check if actor??? + mEngine->removeCharacter(handle); + mEngine->removeRigidBody(handle); + mEngine->deleteRigidBody(handle); + } + + void PhysicsSystem::moveObject (const std::string& handle, const Ogre::Vector3& position) + { + if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) + { + // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow + // start positions others than 0, 0, 0 + btTransform tr = body->getWorldTransform(); + tr.setOrigin(btVector3(position.x,position.y,position.z)); + body->setWorldTransform(tr); + } + if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) + { + // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow + // start positions others than 0, 0, 0 + act->setPosition(btVector3(position.x,position.y,position.z)); + } + } + + void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation) + { + if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) + { + // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow + // start positions others than 0, 0, 0 + act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); + } + } + + void PhysicsSystem::scaleObject (const std::string& handle, float scale) + { + + } + + bool PhysicsSystem::toggleCollisionMode() + { + for(std::map::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) + { + if (it->first=="player") + { + OEngine::Physic::PhysicActor* act = it->second; + + bool cmode = act->getCollisionMode(); + if(cmode) + { + act->enableCollisions(false); + act->setGravity(0.); + act->setVerticalVelocity(0); + mFreeFly = true; + return false; + } + else + { + mFreeFly = false; + act->enableCollisions(true); + act->setGravity(4.); + act->setVerticalVelocity(0); + return true; + } + } + } + + throw std::logic_error ("can't find player"); + } + + void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){ + Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); + addObject (node->getName(), model, node->getOrientation(), + node->getScale().x, node->getPosition()); + } + + void PhysicsSystem::insertActorPhysics(const MWWorld::Ptr& ptr, const std::string model){ + Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); + // std::cout << "Adding node with name" << node->getName(); + addActor (node->getName(), model, node->getPosition()); + } + +} diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 07bad30535..911f6279bd 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -156,10 +156,10 @@ namespace Physic solver = new btSequentialImpulseConstraintSolver; //TODO: memory leak? - btOverlappingPairCache* pairCache = new btSortedOverlappingPairCache(); + //btOverlappingPairCache* pairCache = new btSortedOverlappingPairCache(); //pairCache->setInternalGhostPairCallback( new btGhostPairCallback() ); - broadphase = new btDbvtBroadphase(pairCache); + broadphase = new btDbvtBroadphase(); // The world. dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration); diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 45fe84f4fc..71c15fe45f 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -786,7 +786,7 @@ static void PM_WaterMove( playerMove* const pm ) 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; + wishvel.z += pm->cmd.upmove * scale; } //VectorCopy (wishvel, wishdir); @@ -1094,21 +1094,22 @@ void AngleVectors( const Ogre::Vector3& angles, Ogre::Vector3* const forward, Og if (forward) { forward->x = cp * cy; - forward->z = cp * sy; - forward->y = -sp; + forward->y = cp * sy; + forward->z = -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; + right->y = (-1 * sr * sp * sy + -1 * cr * cy); + right->z = 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; + up->x =(cr * sp * cy + -sr * -sy); + up->y=(cr * sp * sy + -sr * cy); + up->z = cr * cp; } + } void PM_GroundTraceMissed() @@ -1356,7 +1357,7 @@ static void PM_CrashLand( void ) static void PM_GroundTrace( void ) { - std::cout << "Ground trace\n"; + //std::cout << "Ground trace\n"; Ogre::Vector3 point; traceResults trace; @@ -1578,9 +1579,12 @@ static void PM_NoclipMove( void ) //for (i=0 ; i<3 ; i++) //wishvel[i] = pml.forward[i] * fmove + pml.right[i] * smove; + std::cout << "Forward" << pml.forward << "\n"; + std::cout << "Right" << pml.right << "\n"; + std::cout << "Up" << pml.up << "\n"; wishvel = pml.forward * fmove + pml.right * smove; //wishvel[2] += pm->cmd.upmove; - wishvel.y += pm->cmd.upmove; + wishvel.z += pm->cmd.upmove; //VectorCopy (wishvel, wishdir); wishdir = wishvel; @@ -1720,7 +1724,6 @@ void PM_SetWaterLevel( playerMove* const pm ) void PmoveSingle (playerMove* const pmove) { - std::cout << "Pmove single\n"; //pm = pmove; // Aedra doesn't support Q3-style VM traps D: //while(1); @@ -1944,7 +1947,7 @@ void PmoveSingle (playerMove* const pmove) else { // airborne - std::cout << "AIRMOVE\n"; + //std::cout << "AIRMOVE\n"; PM_AirMove(); //bprintf("AirMove\n"); } diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index e90cc3b35d..5dfd18f6dc 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -90,9 +90,9 @@ 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) + playerStruct() : gravity(50.0f), speed(320.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0) { - origin = Ogre::Vector3(733.164f,1000.0f, 839.432f); + origin = Ogre::Vector3(733.164f,900.0f, 839.432f); velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); viewangles = Ogre::Vector3(0.0f, 0.0f, 0.0f); diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 49e12064ee..57d071f170 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -112,8 +112,8 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& 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 << "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"; diff --git a/libs/openengine/bullet/weather.cpp b/libs/openengine/bullet/weather.cpp new file mode 100644 index 0000000000..90afc4e78b --- /dev/null +++ b/libs/openengine/bullet/weather.cpp @@ -0,0 +1,811 @@ +#include "weather.hpp" +#include "world.hpp" +#include "player.hpp" + +#include "../mwrender/renderingmanager.hpp" +#include "../mwsound/soundmanager.hpp" + +#include +#include +#include + +#include + +using namespace Ogre; +using namespace MWWorld; +using namespace MWSound; + +#define lerp(x, y) (x * (1-factor) + y * factor) + +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), + mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0) +{ + mRendering = rendering; + mEnvironment = env; + + #define clr(r,g,b) ColourValue(r/255.f, g/255.f, b/255.f) + + /// \todo read these from Morrowind.ini + Weather clear; + clear.mCloudTexture = "tx_sky_clear.dds"; + clear.mCloudsMaximumPercent = 1.0; + clear.mTransitionDelta = 0.015; + clear.mSkySunriseColor = clr(118, 141, 164); + clear.mSkyDayColor = clr(95, 135, 203); + clear.mSkySunsetColor = clr(56, 89, 129); + clear.mSkyNightColor = clr(9, 10, 11); + clear.mFogSunriseColor = clr(255, 189, 157); + clear.mFogDayColor = clr(206, 227, 255); + clear.mFogSunsetColor = clr(255, 189, 157); + clear.mFogNightColor = clr(9, 10, 11); + clear.mAmbientSunriseColor = clr(47, 66, 96); + clear.mAmbientDayColor = clr(137, 140, 160); + clear.mAmbientSunsetColor = clr(68, 75, 96); + clear.mAmbientNightColor = clr(32, 35, 42); + clear.mSunSunriseColor = clr(242, 159, 99); + clear.mSunDayColor = clr(255, 252, 238); + clear.mSunSunsetColor = clr(255, 115, 79); + clear.mSunNightColor = clr(59, 97, 176); + clear.mSunDiscSunsetColor = clr(255, 189, 157); + clear.mLandFogDayDepth = 0.69; + clear.mLandFogNightDepth = 0.69; + clear.mWindSpeed = 0.1; + clear.mCloudSpeed = 1.25; + clear.mGlareView = 1.0; + mWeatherSettings["clear"] = clear; + + Weather cloudy; + cloudy.mCloudTexture = "tx_sky_cloudy.dds"; + cloudy.mCloudsMaximumPercent = 1.0; + cloudy.mTransitionDelta = 0.015; + cloudy.mSkySunriseColor = clr(126, 158, 173); + cloudy.mSkyDayColor = clr(117, 160, 215); + cloudy.mSkySunsetColor = clr(111, 114, 159); + cloudy.mSkyNightColor = clr(9, 10, 11); + cloudy.mFogSunriseColor = clr(255, 207, 149); + cloudy.mFogDayColor = clr(245, 235, 224); + cloudy.mFogSunsetColor = clr(255, 155, 106); + cloudy.mFogNightColor = clr(9, 10, 11); + cloudy.mAmbientSunriseColor = clr(66, 74, 87); + cloudy.mAmbientDayColor = clr(137, 145, 160); + cloudy.mAmbientSunsetColor = clr(71, 80, 92); + cloudy.mAmbientNightColor = clr(32, 39, 54); + cloudy.mSunSunriseColor = clr(241, 177, 99); + cloudy.mSunDayColor = clr(255, 236, 221); + cloudy.mSunSunsetColor = clr(255, 89, 00); + cloudy.mSunNightColor = clr(77, 91, 124); + cloudy.mSunDiscSunsetColor = clr(255, 202, 179); + cloudy.mLandFogDayDepth = 0.72; + cloudy.mLandFogNightDepth = 0.72; + cloudy.mWindSpeed = 0.2; + cloudy.mCloudSpeed = 2; + cloudy.mGlareView = 1.0; + mWeatherSettings["cloudy"] = cloudy; + + Weather foggy; + foggy.mCloudTexture = "tx_sky_foggy.dds"; + foggy.mCloudsMaximumPercent = 1.0; + foggy.mTransitionDelta = 0.015; + foggy.mSkySunriseColor = clr(197, 190, 180); + foggy.mSkyDayColor = clr(184, 211, 228); + foggy.mSkySunsetColor = clr(142, 159, 176); + foggy.mSkyNightColor = clr(18, 23, 28); + foggy.mFogSunriseColor = clr(173, 164, 148); + foggy.mFogDayColor = clr(150, 187, 209); + foggy.mFogSunsetColor = clr(113, 135, 157); + foggy.mFogNightColor = clr(19, 24, 29); + foggy.mAmbientSunriseColor = clr(48, 43, 37); + foggy.mAmbientDayColor = clr(92, 109, 120); + foggy.mAmbientSunsetColor = clr(28, 33, 39); + foggy.mAmbientNightColor = clr(28, 33, 39); + foggy.mSunSunriseColor = clr(177, 162, 137); + foggy.mSunDayColor = clr(111, 131, 151); + foggy.mSunSunsetColor = clr(125, 157, 189); + foggy.mSunNightColor = clr(81, 100, 119); + foggy.mSunDiscSunsetColor = clr(223, 223, 223); + foggy.mLandFogDayDepth = 1.0; + foggy.mLandFogNightDepth = 1.9; + foggy.mWindSpeed = 0; + foggy.mCloudSpeed = 1.25; + foggy.mGlareView = 0.25; + mWeatherSettings["foggy"] = foggy; + + Weather thunderstorm; + thunderstorm.mCloudTexture = "tx_sky_thunder.dds"; + thunderstorm.mCloudsMaximumPercent = 0.66; + thunderstorm.mTransitionDelta = 0.03; + thunderstorm.mSkySunriseColor = clr(35, 36, 39); + thunderstorm.mSkyDayColor = clr(97, 104, 115); + thunderstorm.mSkySunsetColor = clr(35, 36, 39); + thunderstorm.mSkyNightColor = clr(19, 20, 22); + thunderstorm.mFogSunriseColor = clr(70, 74, 85); + thunderstorm.mFogDayColor = clr(97, 104, 115); + thunderstorm.mFogSunsetColor = clr(70, 74, 85); + thunderstorm.mFogNightColor = clr(19, 20, 22); + thunderstorm.mAmbientSunriseColor = clr(54, 54, 54); + thunderstorm.mAmbientDayColor = clr(90, 90, 90); + thunderstorm.mAmbientSunsetColor = clr(54, 54, 54); + thunderstorm.mAmbientNightColor = clr(49, 51, 54); + thunderstorm.mSunSunriseColor = clr(91, 99, 122); + thunderstorm.mSunDayColor = clr(138, 144, 155); + thunderstorm.mSunSunsetColor = clr(96, 101, 117); + thunderstorm.mSunNightColor = clr(55, 76, 110); + thunderstorm.mSunDiscSunsetColor = clr(128, 128, 128); + thunderstorm.mLandFogDayDepth = 1; + thunderstorm.mLandFogNightDepth = 1.15; + thunderstorm.mWindSpeed = 0.5; + thunderstorm.mCloudSpeed = 3; + thunderstorm.mGlareView = 0; + thunderstorm.mRainLoopSoundID = "rain heavy"; + mWeatherSettings["thunderstorm"] = thunderstorm; + + Weather rain; + rain.mCloudTexture = "tx_sky_rainy.dds"; + rain.mCloudsMaximumPercent = 0.66; + rain.mTransitionDelta = 0.015; + rain.mSkySunriseColor = clr(71, 74, 75); + rain.mSkyDayColor = clr(116, 120, 122); + rain.mSkySunsetColor = clr(73, 73, 73); + rain.mSkyNightColor = clr(24, 25, 26); + rain.mFogSunriseColor = clr(71, 74, 75); + rain.mFogDayColor = clr(116, 120, 122); + rain.mFogSunsetColor = clr(73, 73, 73); + rain.mFogNightColor = clr(24, 25, 26); + rain.mAmbientSunriseColor = clr(97, 90, 88); + rain.mAmbientDayColor = clr(105, 110, 113); + rain.mAmbientSunsetColor = clr(88, 97, 97); + rain.mAmbientNightColor = clr(50, 55, 67); + rain.mSunSunriseColor = clr(131, 122, 120); + rain.mSunDayColor = clr(149, 157, 170); + rain.mSunSunsetColor = clr(120, 126, 131); + rain.mSunNightColor = clr(50, 62, 101); + rain.mSunDiscSunsetColor = clr(128, 128, 128); + rain.mLandFogDayDepth = 0.8; + rain.mLandFogNightDepth = 0.8; + rain.mWindSpeed = 0.3; + rain.mCloudSpeed = 2; + rain.mGlareView = 0; + rain.mRainLoopSoundID = "rain"; + mWeatherSettings["rain"] = rain; + + Weather overcast; + overcast.mCloudTexture = "tx_sky_overcast.dds"; + overcast.mCloudsMaximumPercent = 1.0; + overcast.mTransitionDelta = 0.015; + overcast.mSkySunriseColor = clr(91, 99, 106); + overcast.mSkyDayColor = clr(143, 146, 149); + overcast.mSkySunsetColor = clr(108, 115, 121); + overcast.mSkyNightColor = clr(19, 22, 25); + overcast.mFogSunriseColor = clr(91, 99, 106); + overcast.mFogDayColor = clr(143, 146, 149); + overcast.mFogSunsetColor = clr(108, 115, 121); + overcast.mFogNightColor = clr(19, 22, 25); + overcast.mAmbientSunriseColor = clr(84, 88, 92); + overcast.mAmbientDayColor = clr(93, 96, 105); + overcast.mAmbientSunsetColor = clr(83, 77, 75); + overcast.mAmbientNightColor = clr(57, 60, 66); + overcast.mSunSunriseColor = clr(87, 125, 163); + overcast.mSunDayColor = clr(163, 169, 183); + overcast.mSunSunsetColor = clr(85, 103, 157); + overcast.mSunNightColor = clr(32, 54, 100); + overcast.mSunDiscSunsetColor = clr(128, 128, 128); + overcast.mLandFogDayDepth = 0.7; + overcast.mLandFogNightDepth = 0.7; + overcast.mWindSpeed = 0.2; + overcast.mCloudSpeed = 1.5; + overcast.mGlareView = 0; + mWeatherSettings["overcast"] = overcast; + + Weather ashstorm; + ashstorm.mCloudTexture = "tx_sky_ashstorm.dds"; + ashstorm.mCloudsMaximumPercent = 1.0; + ashstorm.mTransitionDelta = 0.035; + ashstorm.mSkySunriseColor = clr(91, 56, 51); + ashstorm.mSkyDayColor = clr(124, 73, 58); + ashstorm.mSkySunsetColor = clr(106, 55, 40); + ashstorm.mSkyNightColor = clr(20, 21, 22); + ashstorm.mFogSunriseColor = clr(91, 56, 51); + ashstorm.mFogDayColor = clr(124, 73, 58); + ashstorm.mFogSunsetColor = clr(106, 55, 40); + ashstorm.mFogNightColor = clr(20, 21, 22); + ashstorm.mAmbientSunriseColor = clr(52, 42, 37); + ashstorm.mAmbientDayColor = clr(75, 49, 41); + ashstorm.mAmbientSunsetColor = clr(48, 39, 35); + ashstorm.mAmbientNightColor = clr(36, 42, 49); + ashstorm.mSunSunriseColor = clr(184, 91, 71); + ashstorm.mSunDayColor = clr(228, 139, 114); + ashstorm.mSunSunsetColor = clr(185, 86, 57); + ashstorm.mSunNightColor = clr(54, 66, 74); + ashstorm.mSunDiscSunsetColor = clr(128, 128, 128); + ashstorm.mLandFogDayDepth = 1.1; + ashstorm.mLandFogNightDepth = 1.2; + ashstorm.mWindSpeed = 0.8; + ashstorm.mCloudSpeed = 7; + ashstorm.mGlareView = 0; + ashstorm.mAmbientLoopSoundID = "ashstorm"; + mWeatherSettings["ashstorm"] = ashstorm; + + Weather blight; + blight.mCloudTexture = "tx_sky_blight.dds"; + blight.mCloudsMaximumPercent = 1.0; + blight.mTransitionDelta = 0.04; + blight.mSkySunriseColor = clr(90, 35, 35); + blight.mSkyDayColor = clr(90, 35, 35); + blight.mSkySunsetColor = clr(92, 33, 33); + blight.mSkyNightColor = clr(44, 14, 14); + blight.mFogSunriseColor = clr(90, 35, 35); + blight.mFogDayColor = clr(128, 19, 19); + blight.mFogSunsetColor = clr(92, 33, 33); + blight.mFogNightColor = clr(44, 14, 14); + blight.mAmbientSunriseColor = clr(61, 40, 40); + blight.mAmbientDayColor = clr(79, 54, 54); + blight.mAmbientSunsetColor = clr(61, 40, 40); + blight.mAmbientNightColor = clr(56, 58, 62); + blight.mSunSunriseColor = clr(180, 78, 78); + blight.mSunDayColor = clr(224, 84, 84); + blight.mSunSunsetColor = clr(180, 78, 78); + blight.mSunNightColor = clr(61, 91, 143); + blight.mSunDiscSunsetColor = clr(128, 128, 128); + blight.mLandFogDayDepth = 1.1; + blight.mLandFogNightDepth = 1.2; + blight.mWindSpeed = 0.9; + blight.mCloudSpeed = 9; + blight.mGlareView = 0; + blight.mAmbientLoopSoundID = "blight"; + mWeatherSettings["blight"] = blight; + + Weather snow; + snow.mCloudTexture = "tx_bm_sky_snow.dds"; + snow.mCloudsMaximumPercent = 1.0; + snow.mTransitionDelta = 0.014; + snow.mSkySunriseColor = clr(196, 91, 91); + snow.mSkyDayColor = clr(153, 158, 166); + snow.mSkySunsetColor = clr(96, 115, 134); + snow.mSkyNightColor = clr(31, 35, 39); + snow.mFogSunriseColor = clr(106, 91, 91); + snow.mFogDayColor = clr(153, 158, 166); + snow.mFogSunsetColor = clr(96, 115, 134); + snow.mFogNightColor = clr(31, 35, 39); + snow.mAmbientSunriseColor = clr(92, 84, 84); + snow.mAmbientDayColor = clr(93, 96, 105); + snow.mAmbientSunsetColor = clr(70, 79, 87); + snow.mAmbientNightColor = clr(49, 58, 68); + snow.mSunSunriseColor = clr(141, 109, 109); + snow.mSunDayColor = clr(163, 169, 183); + snow.mSunSunsetColor = clr(101, 121, 141); + snow.mSunNightColor = clr(55, 66, 77); + snow.mSunDiscSunsetColor = clr(128, 128, 128); + snow.mLandFogDayDepth = 1.0; + snow.mLandFogNightDepth = 1.2; + snow.mWindSpeed = 0; + snow.mCloudSpeed = 1.5; + snow.mGlareView = 0; + mWeatherSettings["snow"] = snow; + + Weather blizzard; + blizzard.mCloudTexture = "tx_bm_sky_blizzard.dds"; + blizzard.mCloudsMaximumPercent = 1.0; + blizzard.mTransitionDelta = 0.030; + blizzard.mSkySunriseColor = clr(91, 99, 106); + blizzard.mSkyDayColor = clr(121, 133, 145); + blizzard.mSkySunsetColor = clr(108, 115, 121); + blizzard.mSkyNightColor = clr(27, 29, 31); + blizzard.mFogSunriseColor = clr(91, 99, 106); + blizzard.mFogDayColor = clr(121, 133, 145); + blizzard.mFogSunsetColor = clr(108, 115, 121); + blizzard.mFogNightColor = clr(21, 24, 28); + blizzard.mAmbientSunriseColor = clr(84, 88, 92); + blizzard.mAmbientDayColor = clr(93, 96, 105); + blizzard.mAmbientSunsetColor = clr(83, 77, 75); + blizzard.mAmbientNightColor = clr(53, 62, 70); + blizzard.mSunSunriseColor = clr(114, 128, 146); + blizzard.mSunDayColor = clr(163, 169, 183); + blizzard.mSunSunsetColor = clr(106, 114, 136); + blizzard.mSunNightColor = clr(57, 66, 74); + blizzard.mSunDiscSunsetColor = clr(128, 128, 128); + blizzard.mLandFogDayDepth = 2.8; + blizzard.mLandFogNightDepth = 3.0; + blizzard.mWindSpeed = 0.9; + blizzard.mCloudSpeed = 7.5; + blizzard.mGlareView = 0; + blizzard.mAmbientLoopSoundID = "BM Blizzard"; + mWeatherSettings["blizzard"] = blizzard; +} + +void WeatherManager::setWeather(const String& weather, bool instant) +{ + if (instant || mFirstUpdate) + { + mNextWeather = ""; + mCurrentWeather = weather; + mFirstUpdate = false; + } + else + { + if (mNextWeather != "") + { + // transition more than 50% finished? + if (mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60) <= 0.5) + mCurrentWeather = mNextWeather; + } + + mNextWeather = weather; + mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60; + } +} + +WeatherResult WeatherManager::getResult(const String& weather) +{ + const Weather& current = mWeatherSettings[weather]; + WeatherResult result; + + result.mCloudTexture = current.mCloudTexture; + result.mCloudBlendFactor = 0; + result.mCloudOpacity = current.mCloudsMaximumPercent; + result.mWindSpeed = current.mWindSpeed; + result.mCloudSpeed = current.mCloudSpeed; + result.mGlareView = current.mGlareView; + result.mAmbientLoopSoundID = current.mAmbientLoopSoundID; + result.mSunColor = current.mSunDiscSunsetColor; + + const float fade_duration = current.mTransitionDelta * 24.f; + + result.mNight = (mHour < 6.f+fade_duration || mHour > 20.f-fade_duration); + + result.mFogDepth = result.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth; + + // night + if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration) + || mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration)) + { + result.mFogColor = current.mFogNightColor; + result.mAmbientColor = current.mAmbientNightColor; + result.mSunColor = current.mSunNightColor; + result.mSkyColor = current.mSkyNightColor; + result.mNightFade = 1.f; + } + + // sunrise + else if (mHour >= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration) && mHour <= WeatherGlobals::mSunriseTime) + { + if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration)) + { + // fade in + float advance = (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration)-mHour; + float factor = (advance / fade_duration); + result.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor); + result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor); + result.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor); + result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor); + result.mNightFade = factor; + } + else if (mHour >= (WeatherGlobals::mSunriseTime-fade_duration)) + { + // fade out + float advance = mHour-(WeatherGlobals::mSunriseTime-fade_duration); + float factor = advance / fade_duration; + result.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor); + result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor); + result.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor); + result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor); + } + else + { + result.mFogColor = current.mFogSunriseColor; + result.mAmbientColor = current.mAmbientSunriseColor; + result.mSunColor = current.mSunSunriseColor; + result.mSkyColor = current.mSkySunriseColor; + } + } + + // day + else if (mHour >= (WeatherGlobals::mSunriseTime) && mHour <= (WeatherGlobals::mSunsetTime)) + { + result.mFogColor = current.mFogDayColor; + result.mAmbientColor = current.mAmbientDayColor; + result.mSunColor = current.mSunDayColor; + result.mSkyColor = current.mSkyDayColor; + } + + // sunset + else if (mHour >= (WeatherGlobals::mSunsetTime) && mHour <= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration)) + { + if (mHour <= (WeatherGlobals::mSunsetTime+fade_duration)) + { + // fade in + float advance = (WeatherGlobals::mSunsetTime+fade_duration)-mHour; + float factor = (advance / fade_duration); + result.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor); + result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor); + result.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor); + result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor); + } + else if (mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration)) + { + // fade out + float advance = mHour-(WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration); + float factor = advance / fade_duration; + result.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor); + result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor); + result.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor); + result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor); + result.mNightFade = factor; + } + else + { + result.mFogColor = current.mFogSunsetColor; + result.mAmbientColor = current.mAmbientSunsetColor; + result.mSunColor = current.mSunSunsetColor; + result.mSkyColor = current.mSkySunsetColor; + } + } + + return result; +} + +WeatherResult WeatherManager::transition(float factor) +{ + const WeatherResult& current = getResult(mCurrentWeather); + const WeatherResult& other = getResult(mNextWeather); + WeatherResult result; + + result.mCloudTexture = current.mCloudTexture; + result.mNextCloudTexture = other.mCloudTexture; + result.mCloudBlendFactor = factor; + + result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity); + result.mFogColor = lerp(current.mFogColor, other.mFogColor); + result.mSunColor = lerp(current.mSunColor, other.mSunColor); + result.mSkyColor = lerp(current.mSkyColor, other.mSkyColor); + + result.mAmbientColor = lerp(current.mAmbientColor, other.mAmbientColor); + result.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor); + result.mFogDepth = lerp(current.mFogDepth, other.mFogDepth); + result.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed); + result.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed); + result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity); + result.mGlareView = lerp(current.mGlareView, other.mGlareView); + + result.mNight = current.mNight; + + // sound change behaviour: + // if 'other' has a new sound, switch to it after 1/2 of the transition length + if (other.mAmbientLoopSoundID != "") + result.mAmbientLoopSoundID = factor>0.5 ? other.mAmbientLoopSoundID : current.mAmbientLoopSoundID; + // if 'current' has a sound and 'other' does not have a sound, turn off the sound immediately + else if (current.mAmbientLoopSoundID != "") + result.mAmbientLoopSoundID = ""; + + return result; +} + +void WeatherManager::update(float duration) +{ + mWeatherUpdateTime -= duration; + if (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior()) + { + std::string regionstr = mEnvironment->mWorld->getPlayer().getPlayer().getCell()->cell->region; + boost::algorithm::to_lower(regionstr); + + if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) + { + mCurrentRegion = regionstr; + mWeatherUpdateTime = WeatherGlobals::mWeatherUpdateTime*60.f; + + std::string weather; + + if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) + weather = mRegionOverrides[regionstr]; + else + { + // get weather probabilities for the current region + const ESM::Region *region = mEnvironment->mWorld->getStore().regions.find (regionstr); + + float clear = region->data.clear/255.f; + float cloudy = region->data.cloudy/255.f; + float foggy = region->data.foggy/255.f; + float overcast = region->data.overcast/255.f; + float rain = region->data.rain/255.f; + 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; + + // re-scale to 100 percent + 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) + weather = "blight"; + else if (random >= thunder+rain+overcast+foggy+cloudy+clear) + weather = "ashstorm"; + else if (random >= rain+overcast+foggy+cloudy+clear) + weather = "thunderstorm"; + else if (random >= overcast+foggy+cloudy+clear) + weather = "rain"; + else if (random >= foggy+cloudy+clear) + weather = "overcast"; + else if (random >= cloudy+clear) + weather = "foggy"; + else if (random >= clear) + weather = "cloudy"; + else + weather = "clear"; + } + + setWeather(weather, false); + /* + std::cout << "roll result: " << random << std::endl; + + std::cout << regionstr << " weather probabilities: " << clear << " " << cloudy << " " << foggy << " " + << overcast << " " << rain << " " << thunder << " " << ash << " " << blight << " " << snow << " " + << blizzard << std::endl; + + std::cout << "New weather : " << weather << std::endl; + */ + } + + WeatherResult result; + + if (mNextWeather != "") + { + mRemainingTransitionTime -= duration; + if (mRemainingTransitionTime < 0) + { + mCurrentWeather = mNextWeather; + mNextWeather = ""; + } + } + + if (mNextWeather != "") + result = transition(1-(mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60))); + else + result = getResult(mCurrentWeather); + + mRendering->configureFog(result.mFogDepth, result.mFogColor); + + // disable sun during night + if (mHour >= WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration + || mHour <= WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration) + mRendering->getSkyManager()->sunDisable(); + else + { + // during day, calculate sun angle + float height = 1-std::abs(((mHour-13)/7.f)); + int facing = mHour > 13.f ? 1 : -1; + Vector3 final( + (1-height)*facing, + (1-height)*facing, + height); + mRendering->setSunDirection(final); + + mRendering->getSkyManager()->sunEnable(); + } + + // moon calculations + float night; + if (mHour >= 14) + night = mHour-14; + else if (mHour <= 10) + night = mHour+10; + else + night = 0; + + night /= 20.f; + + if (night != 0) + { + float moonHeight = 1-std::abs((night-0.5)*2); + int facing = (mHour > 0.f && mHour<12.f) ? 1 : -1; + Vector3 masser( + (1-moonHeight)*facing, + (1-moonHeight)*facing, + moonHeight); + + Vector3 secunda( + (1-moonHeight)*facing*0.8, + (1-moonHeight)*facing*1.25, + moonHeight); + + mRendering->getSkyManager()->setMasserDirection(masser); + mRendering->getSkyManager()->setSecundaDirection(secunda); + mRendering->getSkyManager()->masserEnable(); + mRendering->getSkyManager()->secundaEnable(); + + float hour_fade; + if (mHour >= 7.f && mHour <= 14.f) + hour_fade = 1-(mHour-7)/3.f; + else if (mHour >= 14 && mHour <= 15.f) + hour_fade = mHour-14; + else + hour_fade = 1; + + float secunda_angle_fade; + float masser_angle_fade; + float angle = moonHeight*90.f; + + if (angle >= 30 && angle <= 50) + secunda_angle_fade = (angle-30)/20.f; + else if (angle <30) + secunda_angle_fade = 0.f; + else + secunda_angle_fade = 1.f; + + if (angle >= 40 && angle <= 50) + masser_angle_fade = (angle-40)/10.f; + else if (angle <40) + masser_angle_fade = 0.f; + else + masser_angle_fade = 1.f; + + masser_angle_fade *= hour_fade; + secunda_angle_fade *= hour_fade; + + mRendering->getSkyManager()->setMasserFade(masser_angle_fade); + mRendering->getSkyManager()->setSecundaFade(secunda_angle_fade); + } + else + { + mRendering->getSkyManager()->masserDisable(); + mRendering->getSkyManager()->secundaDisable(); + } + + if (mCurrentWeather == "thunderstorm" && mNextWeather == "") + { + if (mThunderFlash > 0) + { + // play the sound after a delay + mThunderSoundDelay -= duration; + if (mThunderSoundDelay <= 0) + { + // pick a random sound + int sound = rand() % 4; + std::string soundname; + if (sound == 0) soundname = WeatherGlobals::mThunderSoundID0; + else if (sound == 1) soundname = WeatherGlobals::mThunderSoundID1; + else if (sound == 2) soundname = WeatherGlobals::mThunderSoundID2; + else if (sound == 3) soundname = WeatherGlobals::mThunderSoundID3; + mEnvironment->mSoundManager->playSound(soundname, 1.0, 1.0); + mThunderSoundDelay = 1000; + } + + mThunderFlash -= duration; + if (mThunderFlash > 0) + mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold ); + else + { + srand(time(NULL)); + mThunderChanceNeeded = rand() % 100; + mThunderChance = 0; + mRendering->getSkyManager()->setThunder( 0.f ); + } + } + else + { + // no thunder active + mThunderChance += duration*4; // chance increases by 4 percent every second + if (mThunderChance >= mThunderChanceNeeded) + { + mThunderFlash = WeatherGlobals::mThunderThreshold; + + mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold ); + + mThunderSoundDelay = WeatherGlobals::mThunderSoundDelay; + } + } + } + else + mRendering->getSkyManager()->setThunder(0.f); + + mRendering->setAmbientColour(result.mAmbientColor); + mRendering->sunEnable(); + mRendering->setSunColour(result.mSunColor); + + mRendering->getSkyManager()->setWeather(result); + } + else + { + mRendering->sunDisable(); + mRendering->skyDisable(); + mRendering->getSkyManager()->setThunder(0.f); + } +} + +void WeatherManager::setHour(const float hour) +{ + // accelerate a bit for testing + /* + mHour += 0.005; + + if (mHour >= 24.f) mHour = 0.f; + + std::cout << "hour " << mHour << std::endl; + */ + + mHour = hour; +} + +void WeatherManager::setDate(const int day, const int month) +{ + mDay = day; + mMonth = month; +} + +unsigned int WeatherManager::getWeatherID() const +{ + // Source: http://www.uesp.net/wiki/Tes3Mod:GetCurrentWeather + + if (mCurrentWeather == "clear") + return 0; + else if (mCurrentWeather == "cloudy") + return 1; + else if (mCurrentWeather == "foggy") + return 2; + else if (mCurrentWeather == "overcast") + return 3; + else if (mCurrentWeather == "rain") + return 4; + else if (mCurrentWeather == "thunderstorm") + return 5; + else if (mCurrentWeather == "ashstorm") + return 6; + else if (mCurrentWeather == "blight") + return 7; + else if (mCurrentWeather == "snow") + return 8; + else if (mCurrentWeather == "blizzard") + return 9; + + else + return 0; +} + +void WeatherManager::changeWeather(const std::string& region, const unsigned int id) +{ + std::string weather; + if (id==0) + weather = "clear"; + else if (id==1) + weather = "cloudy"; + else if (id==2) + weather = "foggy"; + else if (id==3) + weather = "overcast"; + else if (id==4) + weather = "rain"; + else if (id==5) + weather = "thunderstorm"; + else if (id==6) + weather = "ashstorm"; + else if (id==7) + weather = "blight"; + else if (id==8) + weather = "snow"; + else if (id==9) + weather = "blizzard"; + else + weather = "clear"; + + mRegionOverrides[region] = weather; +} diff --git a/libs/openengine/bullet/weather.hpp b/libs/openengine/bullet/weather.hpp new file mode 100644 index 0000000000..9353f7cd1d --- /dev/null +++ b/libs/openengine/bullet/weather.hpp @@ -0,0 +1,272 @@ +#ifndef GAME_MWWORLD_WEATHER_H +#define GAME_MWWORLD_WEATHER_H + +#include +#include + +namespace MWRender +{ + class RenderingManager; +} + +namespace MWWorld +{ + class Environment; + + /// Global weather manager properties (according to INI) + struct WeatherGlobals + { + /* + [Weather] + EnvReduceColor=255,255,255,255 + LerpCloseColor=037,046,048,255 + BumpFadeColor=230,239,255,255 + AlphaReduce=0.35 + Minimum Time Between Environmental Sounds=1.0 + Maximum Time Between Environmental Sounds=5.0 + Sun Glare Fader Max=0.5 + Sun Glare Fader Angle Max=30.0 + Sun Glare Fader Color=222,095,039 + Timescale Clouds=0 + Precip Gravity=575 + Hours Between Weather Changes=20 + Rain Ripples=1 + Rain Ripple Radius=1024 + Rain Ripples Per Drop=1 + Rain Ripple Scale=0.3 + Rain Ripple Speed=1.0 + Fog Depth Change Speed=3 + Sunrise Time=6 + Sunset Time=18 + Sunrise Duration=2 + Sunset Duration=2 + Sky Pre-Sunrise Time=.5 + Sky Post-Sunrise Time=1 + Sky Pre-Sunset Time=1.5 + Sky Post-Sunset Time=.5 + Ambient Pre-Sunrise Time=.5 + Ambient Post-Sunrise Time=2 + Ambient Pre-Sunset Time=1 + Ambient Post-Sunset Time=1.25 + Fog Pre-Sunrise Time=.5 + Fog Post-Sunrise Time=1 + Fog Pre-Sunset Time=2 + Fog Post-Sunset Time=1 + Sun Pre-Sunrise Time=0 + Sun Post-Sunrise Time=0 + Sun Pre-Sunset Time=1 + Sun Post-Sunset Time=1.25 + Stars Post-Sunset Start=1 + Stars Pre-Sunrise Finish=2 + Stars Fading Duration=2 + Snow Ripples=0 + Snow Ripple Radius=1024 + Snow Ripples Per Flake=1 + Snow Ripple Scale=0.3 + Snow Ripple Speed=1.0 + Snow Gravity Scale=0.1 + Snow High Kill=700 + Snow Low Kill=150 + + + [Moons] + Masser Size=94 + Masser Fade In Start=14 + Masser Fade In Finish=15 + Masser Fade Out Start=7 + Masser Fade Out Finish=10 + Masser Axis Offset=35 + Masser Speed=.5 + Masser Daily Increment=1 + Masser Fade Start Angle=50 + Masser Fade End Angle=40 + Masser Moon Shadow Early Fade Angle=0.5 + Secunda Size=40 + Secunda Fade In Start=14 + Secunda Fade In Finish=15 + Secunda Fade Out Start=7 + Secunda Fade Out Finish=10 + Secunda Axis Offset=50 + Secunda Speed=.6 + Secunda Daily Increment=1.2 + Secunda Fade Start Angle=50 + Secunda Fade End Angle=30 + Secunda Moon Shadow Early Fade Angle=0.5 + Script Color=255,20,20 + */ + + static const float mSunriseTime; + static const float mSunsetTime; + static const float mSunriseDuration; + static const float mSunsetDuration; + + 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; + static const float mThunderThreshold; + static const float mThunderSoundDelay; + static const std::string mThunderSoundID0; + static const std::string mThunderSoundID1; + static const std::string mThunderSoundID2; + static const std::string mThunderSoundID3; + }; + + /// Defines the actual weather that results from weather setting (see below), time of day and weather transition + struct WeatherResult + { + Ogre::String mCloudTexture; + Ogre::String mNextCloudTexture; + float mCloudBlendFactor; + + Ogre::ColourValue mFogColor; + + Ogre::ColourValue mAmbientColor; + + Ogre::ColourValue mSkyColor; + + Ogre::ColourValue mSunColor; + + Ogre::ColourValue mSunDiscColor; + + float mFogDepth; + + float mWindSpeed; + + float mCloudSpeed; + + float mCloudOpacity; + + float mGlareView; + + bool mNight; // use night skybox + float mNightFade; // fading factor for night skybox + + Ogre::String mAmbientLoopSoundID; + }; + + + /// Defines a single weather setting (according to INI) + struct Weather + { + Ogre::String mCloudTexture; + + // Sky (atmosphere) colors + Ogre::ColourValue mSkySunriseColor, + mSkyDayColor, + mSkySunsetColor, + mSkyNightColor; + + // Fog colors + Ogre::ColourValue mFogSunriseColor, + mFogDayColor, + mFogSunsetColor, + mFogNightColor; + + // Ambient lighting colors + Ogre::ColourValue mAmbientSunriseColor, + mAmbientDayColor, + mAmbientSunsetColor, + mAmbientNightColor; + + // Sun (directional) lighting colors + Ogre::ColourValue mSunSunriseColor, + mSunDayColor, + mSunSunsetColor, + mSunNightColor; + + // Fog depth/density + float mLandFogDayDepth, + mLandFogNightDepth; + + // Color modulation for the sun itself during sunset (not completely sure) + Ogre::ColourValue mSunDiscSunsetColor; + + // Duration of weather transition (in days) + float mTransitionDelta; + + // No idea what this one is used for? + float mWindSpeed; + + // Cloud animation speed multiplier + float mCloudSpeed; + + // Multiplier for clouds transparency + float mCloudsMaximumPercent; + + // Value between 0 and 1, defines the strength of the sun glare effect + float mGlareView; + + // Sound effect + // This is used for Blight, Ashstorm and Blizzard (Bloodmoon) + Ogre::String mAmbientLoopSoundID; + + // Rain sound effect + Ogre::String mRainLoopSoundID; + + /// \todo disease chance + }; + + /// + /// Interface for weather settings + /// + class WeatherManager + { + public: + WeatherManager(MWRender::RenderingManager*, MWWorld::Environment*); + + /** + * Change the weather in the specified region + * @param region that should be changed + * @param ID of the weather setting to shift to + */ + void changeWeather(const std::string& region, const unsigned int id); + + /** + * Per-frame update + * @param duration + */ + void update(float duration); + + void setHour(const float hour); + + void setDate(const int day, const int month); + + unsigned int getWeatherID() const; + + private: + float mHour; + int mDay, mMonth; + + MWRender::RenderingManager* mRendering; + MWWorld::Environment* mEnvironment; + + std::map mWeatherSettings; + + std::map mRegionOverrides; + + Ogre::String mCurrentWeather; + Ogre::String mNextWeather; + + std::string mCurrentRegion; + + bool mFirstUpdate; + + float mWeatherUpdateTime; + + float mRemainingTransitionTime; + + float mThunderFlash; + float mThunderChance; + float mThunderChanceNeeded; + float mThunderSoundDelay; + + WeatherResult transition(const float factor); + WeatherResult getResult(const Ogre::String& weather); + + void setWeather(const Ogre::String& weather, bool instant=false); + }; +} + +#endif // GAME_MWWORLD_WEATHER_H From e4251be5299c7114a9b3f9053b5bb35706062453 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 25 Mar 2012 15:16:02 -0400 Subject: [PATCH 02/22] Down gravity --- apps/openmw/mwworld/physicssystem.cpp | 1 + libs/openengine/bullet/pmove.cpp | 75 +-- libs/openengine/bullet/trace.cpp | 10 +- libs/openengine/bullet/weather.cpp | 811 -------------------------- libs/openengine/bullet/weather.hpp | 272 --------- 5 files changed, 46 insertions(+), 1123 deletions(-) delete mode 100644 libs/openengine/bullet/weather.cpp delete mode 100644 libs/openengine/bullet/weather.hpp diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index d54f4696a2..15d2d3f9f6 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -148,6 +148,7 @@ namespace MWWorld if(it->first == "player"){ coord = playerphysics->ps.origin; + //std::cout << "ZCoord: " << coord.z << "\n"; //std::cout << "Coord" << coord << "\n"; //coord = Ogre::Vector3(coord.x, coord.z, coord.y); //x, z, -y diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 71c15fe45f..8dd01ef190 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -178,7 +178,7 @@ bool PM_SlideMove( bool gravity ) float into; Ogre::Vector3 endVelocity; Ogre::Vector3 endClipVelocity; - + std::cout << "Slide move\n"; numbumps = 4; // primal_velocity = pm->ps->velocity @@ -191,14 +191,14 @@ bool PM_SlideMove( bool gravity ) //VectorCopy( pm->ps->velocity, endVelocity ); endVelocity = pm->ps.velocity; //endVelocity[2] -= pm->ps->gravity * pml.frametime; - endVelocity.y -= pm->ps.gravity * pml.frametime; + endVelocity.z -= 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; + pm->ps.velocity.z= (pm->ps.velocity.z + endVelocity.z) * 0.5f; //primal_velocity[2] = endVelocity[2]; - primal_velocity.y = endVelocity.y; + primal_velocity.z = endVelocity.z; if ( pml.groundPlane ) // slide along the ground plane @@ -239,7 +239,7 @@ bool PM_SlideMove( bool gravity ) { // 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; + pm->ps.velocity.z = 0; return true; } @@ -427,10 +427,11 @@ int PM_StepSlideMove( bool gravity ) if ( PM_SlideMove( gravity ) == false ) return 1; // we got exactly where we wanted to go first try + std::cout << "Step Slide move\n"; // down = start_o - vec3(0, 0, STEPSIZE) //VectorCopy(start_o, down); down = start_o; - down.y -= STEPSIZE; + down.z -= STEPSIZE; //pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask); //tracefunc(&trace, start_o, down, , 0, pml.scene); @@ -439,11 +440,11 @@ int PM_StepSlideMove( bool gravity ) // up = vec3(0, 0, 1) //VectorSet(up, 0, 0, 1); - up = Ogre::Vector3(0.0f, 1.0f, 0.0f); + up = Ogre::Vector3(0.0f, 0.0f, 1.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 && ( + if (pm->ps.velocity.z > 0 && ( trace.fraction == 1.0 || trace.planenormal.dotProduct(up) < 0.7 ) ) return 2; @@ -460,7 +461,7 @@ int PM_StepSlideMove( bool gravity ) //VectorCopy (start_o, up); up = start_o; //up[2] += STEPSIZE; - up.y += STEPSIZE; + up.z += 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); @@ -475,7 +476,7 @@ int PM_StepSlideMove( bool gravity ) } //stepSize = trace.endpos[2] - start_o[2]; - stepSize = trace.endpos.y - start_o.y; + stepSize = trace.endpos.z - start_o.z; // try slidemove from this position //VectorCopy (trace.endpos, pm->ps->origin); // pm->ps->origin = trace.endpos @@ -491,7 +492,7 @@ int PM_StepSlideMove( bool gravity ) //VectorCopy (pm->ps->origin, down); down = pm->ps.origin; //down[2] -= stepSize; - down.y -= stepSize; + down.z -= stepSize; //pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask); @@ -510,7 +511,7 @@ int PM_StepSlideMove( bool gravity ) float delta; //delta = pm->ps->origin[2] - start_o[2]; - delta = pm->ps.origin.y - start_o.y; + delta = pm->ps.origin.z - start_o.z; if ( delta > 2 ) { if (gravity) @@ -541,6 +542,7 @@ int PM_StepSlideMove( bool gravity ) void PM_Friction(void) { + std::cout << "Friction\n"; Ogre::Vector3 vec; float* vel; float speed, newspeed, control; @@ -554,14 +556,14 @@ void PM_Friction(void) if ( pml.walking ) //vec[2] = 0; // ignore slope movement - vec.y = 0; + vec.z = 0; //speed = VectorLength(vec); speed = vec.length(); if (speed < 1) { vel[0] = 0; - vel[2] = 0; // allow sinking underwater + vel[1] = 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; @@ -636,6 +638,7 @@ static void PM_Accelerate( Ogre::Vector3& wishdir, float wishspeed, float accel { // int i; float addspeed, accelspeed, currentspeed; + std::cout << "Accelerate\n"; // currentspeed = pm->ps->velocity dot wishdir //currentspeed = DotProduct (pm->ps->velocity, wishdir); @@ -681,7 +684,7 @@ static bool PM_CheckJump(void) //pm->ps->pm_flags |= PMF_JUMP_HELD; pm->ps.groundEntityNum = ENTITYNUM_NONE; - pm->ps.velocity.y = JUMP_VELOCITY; + pm->ps.velocity.z = JUMP_VELOCITY; //PM_AddEvent( EV_JUMP ); /*if ( pm->cmd.forwardmove >= 0 ) @@ -776,8 +779,8 @@ static void PM_WaterMove( playerMove* const pm ) wishvel[2] = -60; // sink towards bottom */ wishvel.x = 0; - wishvel.y = -60; - wishvel.z = 0; + wishvel.z = -60; + wishvel.y = 0; } else { @@ -834,6 +837,7 @@ static void PM_WalkMove( playerMove* const pmove ) playerMove::playercmd cmd; float accelerate; float vel; + std::cout << "Walking\n"; if ( pm->ps.waterlevel > 2 && //DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) pml.forward.dotProduct(pml.groundTrace.planenormal) > 0.0f) @@ -937,10 +941,10 @@ static void PM_WalkMove( playerMove* const pmove ) // project moves down to flat plane //pml.forward[2] = 0; - pml.forward.y = 0; + pml.forward.z = 0; //pml.right[2] = 0; - pml.right.y = 0; + pml.right.z = 0; // project the forward and right directions onto the ground plane PM_ClipVelocity (pml.forward, pml.groundTrace.planenormal, pml.forward, OVERCLIP ); @@ -1035,7 +1039,7 @@ void PM_UpdateViewAngles( playerMove::playerStruct* const ps, playerMove::player { short temp; int i; - + std::cout << "Updating viewangles\n"; //while(1); //if ( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPINTERMISSION) @@ -1128,7 +1132,7 @@ void PM_GroundTraceMissed() //VectorCopy( pm->ps->origin, point ); point = pm->ps.origin; //point[2] -= 64; - point.y -= 64; + point.z -= 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); @@ -1188,7 +1192,7 @@ static bool PM_CorrectAllSolid(traceResults* const trace) point[1] = pm->ps->origin[1]; point[2] = pm->ps->origin[2] - 0.25;*/ point = pm->ps.origin; - point.y -= 0.25f; + point.z -= 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); @@ -1215,7 +1219,7 @@ static void PM_CrashLand( void ) float vel, acc; float t; float a, b, c, den; - + std::cout << "Crash land\n"; // decide which landing animation to use /*if ( pm->ps->pm_flags & PMF_BACKWARDS_JUMP ) PM_ForceLegsAnim( LEGS_LANDB ); @@ -1227,10 +1231,10 @@ static void PM_CrashLand( void ) // calculate the exact velocity on landing //dist = pm->ps->origin[2] - pml.previous_origin[2]; - dist = pm->ps.origin.y - pml.previous_origin.y; + dist = pm->ps.origin.z - pml.previous_origin.z; //vel = pml.previous_velocity[2]; - vel = pml.previous_velocity.y; + vel = pml.previous_velocity.z; //acc = -pm->ps->gravity; acc = -pm->ps.gravity; @@ -1294,7 +1298,7 @@ static void PM_CrashLand( void ) const float waterHeight = pm->waterHeight; const float waterHeightSplash = waterHeight + halfExtents.y; - if (pm->ps.origin.y < waterHeightSplash) + if (pm->ps.origin.z < waterHeightSplash) { splashSound = true; } @@ -1357,7 +1361,7 @@ static void PM_CrashLand( void ) static void PM_GroundTrace( void ) { - //std::cout << "Ground trace\n"; + std::cout << "Ground trace\n"; Ogre::Vector3 point; traceResults trace; @@ -1365,7 +1369,7 @@ static void PM_GroundTrace( void ) point[1] = pm->ps->origin[1]; point[2] = pm->ps->origin[2] - 0.25;*/ point = pm->ps.origin; - point.y -= 0.25f; + point.z -= 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); @@ -1392,7 +1396,7 @@ static void PM_GroundTrace( void ) // 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->ps.velocity.z > 0 && pm->ps.velocity.dotProduct(trace.planenormal) > 10.0f) { //if ( pm->debugLevel ) //Com_Printf("%i:kickoff\n", c_pmove); @@ -1417,7 +1421,7 @@ static void PM_GroundTrace( void ) // 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 (trace.planenormal.z < MIN_WALK_NORMAL) { //if ( pm->debugLevel ) //Com_Printf("%i:steep\n", c_pmove); @@ -1451,7 +1455,7 @@ static void PM_GroundTrace( void ) // 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) + if (pml.previous_velocity.z < -200) { // don't allow another jump for a little while //pm->ps->pm_flags |= PMF_TIME_LAND; @@ -1469,6 +1473,7 @@ static void PM_GroundTrace( void ) static void PM_AirMove() { + std::cout << "Air move\n"; //int i; Ogre::Vector3 wishvel; float fmove, smove; @@ -1490,7 +1495,7 @@ static void PM_AirMove() // project moves down to flat plane //pml.forward[2] = 0; - pml.forward.y = 0; + pml.forward.y = 0; //Z or Y? //pml.right[2] = 0; pml.right.y = 0; //VectorNormalize (pml.forward); @@ -1503,7 +1508,7 @@ static void PM_AirMove() wishvel = pml.forward * fmove + pml.right * smove; //wishvel[2] = 0; - wishvel.y = 0; + wishvel.z = 0; //VectorCopy (wishvel, wishdir); wishdir = wishvel; @@ -1659,7 +1664,7 @@ static void PM_FlyMove( void ) 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; + wishvel.z += /*6.35f * */pm->cmd.upmove * scale; } //VectorCopy (wishvel, wishdir); @@ -1939,7 +1944,7 @@ void PmoveSingle (playerMove* const pmove) PM_WaterMove(pmove); else if ( pml.walking ) { - std::cout << "WALKING\n"; + // walking on ground PM_WalkMove(pmove); //bprintf("WalkMove\n"); diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 57d071f170..8f2423c242 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -28,11 +28,11 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr NewPhysTraceResults out; //std::cout << "Starting trace\n"; - Ogre::Vector3 startReplace = Ogre::Vector3(650,950, 45); - Ogre::Vector3 endReplace = startReplace; - endReplace.y -= .25; + //Ogre::Vector3 startReplace = Ogre::Vector3(650,950, 45); + //Ogre::Vector3 endReplace = startReplace; + //endReplace.z -= .25; - const bool hasHit = NewPhysicsTrace(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, rotation, 0.0f), isInterior, enginePass); + const bool hasHit = NewPhysicsTrace(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0f, rotation), isInterior, enginePass); if(hasHit) std::cout << "Has hit\n"; if (out.fraction < 0.001f) @@ -65,7 +65,7 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr if (!hasHit) { results->endpos = end; - results->planenormal = Ogre::Vector3(0.0f, 1.0f, 0.0f); + results->planenormal = Ogre::Vector3(0.0f, 0.0f, 1.0f); results->entityNum = ENTITYNUM_NONE; results->fraction = 1.0f; } diff --git a/libs/openengine/bullet/weather.cpp b/libs/openengine/bullet/weather.cpp deleted file mode 100644 index 90afc4e78b..0000000000 --- a/libs/openengine/bullet/weather.cpp +++ /dev/null @@ -1,811 +0,0 @@ -#include "weather.hpp" -#include "world.hpp" -#include "player.hpp" - -#include "../mwrender/renderingmanager.hpp" -#include "../mwsound/soundmanager.hpp" - -#include -#include -#include - -#include - -using namespace Ogre; -using namespace MWWorld; -using namespace MWSound; - -#define lerp(x, y) (x * (1-factor) + y * factor) - -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), - mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0) -{ - mRendering = rendering; - mEnvironment = env; - - #define clr(r,g,b) ColourValue(r/255.f, g/255.f, b/255.f) - - /// \todo read these from Morrowind.ini - Weather clear; - clear.mCloudTexture = "tx_sky_clear.dds"; - clear.mCloudsMaximumPercent = 1.0; - clear.mTransitionDelta = 0.015; - clear.mSkySunriseColor = clr(118, 141, 164); - clear.mSkyDayColor = clr(95, 135, 203); - clear.mSkySunsetColor = clr(56, 89, 129); - clear.mSkyNightColor = clr(9, 10, 11); - clear.mFogSunriseColor = clr(255, 189, 157); - clear.mFogDayColor = clr(206, 227, 255); - clear.mFogSunsetColor = clr(255, 189, 157); - clear.mFogNightColor = clr(9, 10, 11); - clear.mAmbientSunriseColor = clr(47, 66, 96); - clear.mAmbientDayColor = clr(137, 140, 160); - clear.mAmbientSunsetColor = clr(68, 75, 96); - clear.mAmbientNightColor = clr(32, 35, 42); - clear.mSunSunriseColor = clr(242, 159, 99); - clear.mSunDayColor = clr(255, 252, 238); - clear.mSunSunsetColor = clr(255, 115, 79); - clear.mSunNightColor = clr(59, 97, 176); - clear.mSunDiscSunsetColor = clr(255, 189, 157); - clear.mLandFogDayDepth = 0.69; - clear.mLandFogNightDepth = 0.69; - clear.mWindSpeed = 0.1; - clear.mCloudSpeed = 1.25; - clear.mGlareView = 1.0; - mWeatherSettings["clear"] = clear; - - Weather cloudy; - cloudy.mCloudTexture = "tx_sky_cloudy.dds"; - cloudy.mCloudsMaximumPercent = 1.0; - cloudy.mTransitionDelta = 0.015; - cloudy.mSkySunriseColor = clr(126, 158, 173); - cloudy.mSkyDayColor = clr(117, 160, 215); - cloudy.mSkySunsetColor = clr(111, 114, 159); - cloudy.mSkyNightColor = clr(9, 10, 11); - cloudy.mFogSunriseColor = clr(255, 207, 149); - cloudy.mFogDayColor = clr(245, 235, 224); - cloudy.mFogSunsetColor = clr(255, 155, 106); - cloudy.mFogNightColor = clr(9, 10, 11); - cloudy.mAmbientSunriseColor = clr(66, 74, 87); - cloudy.mAmbientDayColor = clr(137, 145, 160); - cloudy.mAmbientSunsetColor = clr(71, 80, 92); - cloudy.mAmbientNightColor = clr(32, 39, 54); - cloudy.mSunSunriseColor = clr(241, 177, 99); - cloudy.mSunDayColor = clr(255, 236, 221); - cloudy.mSunSunsetColor = clr(255, 89, 00); - cloudy.mSunNightColor = clr(77, 91, 124); - cloudy.mSunDiscSunsetColor = clr(255, 202, 179); - cloudy.mLandFogDayDepth = 0.72; - cloudy.mLandFogNightDepth = 0.72; - cloudy.mWindSpeed = 0.2; - cloudy.mCloudSpeed = 2; - cloudy.mGlareView = 1.0; - mWeatherSettings["cloudy"] = cloudy; - - Weather foggy; - foggy.mCloudTexture = "tx_sky_foggy.dds"; - foggy.mCloudsMaximumPercent = 1.0; - foggy.mTransitionDelta = 0.015; - foggy.mSkySunriseColor = clr(197, 190, 180); - foggy.mSkyDayColor = clr(184, 211, 228); - foggy.mSkySunsetColor = clr(142, 159, 176); - foggy.mSkyNightColor = clr(18, 23, 28); - foggy.mFogSunriseColor = clr(173, 164, 148); - foggy.mFogDayColor = clr(150, 187, 209); - foggy.mFogSunsetColor = clr(113, 135, 157); - foggy.mFogNightColor = clr(19, 24, 29); - foggy.mAmbientSunriseColor = clr(48, 43, 37); - foggy.mAmbientDayColor = clr(92, 109, 120); - foggy.mAmbientSunsetColor = clr(28, 33, 39); - foggy.mAmbientNightColor = clr(28, 33, 39); - foggy.mSunSunriseColor = clr(177, 162, 137); - foggy.mSunDayColor = clr(111, 131, 151); - foggy.mSunSunsetColor = clr(125, 157, 189); - foggy.mSunNightColor = clr(81, 100, 119); - foggy.mSunDiscSunsetColor = clr(223, 223, 223); - foggy.mLandFogDayDepth = 1.0; - foggy.mLandFogNightDepth = 1.9; - foggy.mWindSpeed = 0; - foggy.mCloudSpeed = 1.25; - foggy.mGlareView = 0.25; - mWeatherSettings["foggy"] = foggy; - - Weather thunderstorm; - thunderstorm.mCloudTexture = "tx_sky_thunder.dds"; - thunderstorm.mCloudsMaximumPercent = 0.66; - thunderstorm.mTransitionDelta = 0.03; - thunderstorm.mSkySunriseColor = clr(35, 36, 39); - thunderstorm.mSkyDayColor = clr(97, 104, 115); - thunderstorm.mSkySunsetColor = clr(35, 36, 39); - thunderstorm.mSkyNightColor = clr(19, 20, 22); - thunderstorm.mFogSunriseColor = clr(70, 74, 85); - thunderstorm.mFogDayColor = clr(97, 104, 115); - thunderstorm.mFogSunsetColor = clr(70, 74, 85); - thunderstorm.mFogNightColor = clr(19, 20, 22); - thunderstorm.mAmbientSunriseColor = clr(54, 54, 54); - thunderstorm.mAmbientDayColor = clr(90, 90, 90); - thunderstorm.mAmbientSunsetColor = clr(54, 54, 54); - thunderstorm.mAmbientNightColor = clr(49, 51, 54); - thunderstorm.mSunSunriseColor = clr(91, 99, 122); - thunderstorm.mSunDayColor = clr(138, 144, 155); - thunderstorm.mSunSunsetColor = clr(96, 101, 117); - thunderstorm.mSunNightColor = clr(55, 76, 110); - thunderstorm.mSunDiscSunsetColor = clr(128, 128, 128); - thunderstorm.mLandFogDayDepth = 1; - thunderstorm.mLandFogNightDepth = 1.15; - thunderstorm.mWindSpeed = 0.5; - thunderstorm.mCloudSpeed = 3; - thunderstorm.mGlareView = 0; - thunderstorm.mRainLoopSoundID = "rain heavy"; - mWeatherSettings["thunderstorm"] = thunderstorm; - - Weather rain; - rain.mCloudTexture = "tx_sky_rainy.dds"; - rain.mCloudsMaximumPercent = 0.66; - rain.mTransitionDelta = 0.015; - rain.mSkySunriseColor = clr(71, 74, 75); - rain.mSkyDayColor = clr(116, 120, 122); - rain.mSkySunsetColor = clr(73, 73, 73); - rain.mSkyNightColor = clr(24, 25, 26); - rain.mFogSunriseColor = clr(71, 74, 75); - rain.mFogDayColor = clr(116, 120, 122); - rain.mFogSunsetColor = clr(73, 73, 73); - rain.mFogNightColor = clr(24, 25, 26); - rain.mAmbientSunriseColor = clr(97, 90, 88); - rain.mAmbientDayColor = clr(105, 110, 113); - rain.mAmbientSunsetColor = clr(88, 97, 97); - rain.mAmbientNightColor = clr(50, 55, 67); - rain.mSunSunriseColor = clr(131, 122, 120); - rain.mSunDayColor = clr(149, 157, 170); - rain.mSunSunsetColor = clr(120, 126, 131); - rain.mSunNightColor = clr(50, 62, 101); - rain.mSunDiscSunsetColor = clr(128, 128, 128); - rain.mLandFogDayDepth = 0.8; - rain.mLandFogNightDepth = 0.8; - rain.mWindSpeed = 0.3; - rain.mCloudSpeed = 2; - rain.mGlareView = 0; - rain.mRainLoopSoundID = "rain"; - mWeatherSettings["rain"] = rain; - - Weather overcast; - overcast.mCloudTexture = "tx_sky_overcast.dds"; - overcast.mCloudsMaximumPercent = 1.0; - overcast.mTransitionDelta = 0.015; - overcast.mSkySunriseColor = clr(91, 99, 106); - overcast.mSkyDayColor = clr(143, 146, 149); - overcast.mSkySunsetColor = clr(108, 115, 121); - overcast.mSkyNightColor = clr(19, 22, 25); - overcast.mFogSunriseColor = clr(91, 99, 106); - overcast.mFogDayColor = clr(143, 146, 149); - overcast.mFogSunsetColor = clr(108, 115, 121); - overcast.mFogNightColor = clr(19, 22, 25); - overcast.mAmbientSunriseColor = clr(84, 88, 92); - overcast.mAmbientDayColor = clr(93, 96, 105); - overcast.mAmbientSunsetColor = clr(83, 77, 75); - overcast.mAmbientNightColor = clr(57, 60, 66); - overcast.mSunSunriseColor = clr(87, 125, 163); - overcast.mSunDayColor = clr(163, 169, 183); - overcast.mSunSunsetColor = clr(85, 103, 157); - overcast.mSunNightColor = clr(32, 54, 100); - overcast.mSunDiscSunsetColor = clr(128, 128, 128); - overcast.mLandFogDayDepth = 0.7; - overcast.mLandFogNightDepth = 0.7; - overcast.mWindSpeed = 0.2; - overcast.mCloudSpeed = 1.5; - overcast.mGlareView = 0; - mWeatherSettings["overcast"] = overcast; - - Weather ashstorm; - ashstorm.mCloudTexture = "tx_sky_ashstorm.dds"; - ashstorm.mCloudsMaximumPercent = 1.0; - ashstorm.mTransitionDelta = 0.035; - ashstorm.mSkySunriseColor = clr(91, 56, 51); - ashstorm.mSkyDayColor = clr(124, 73, 58); - ashstorm.mSkySunsetColor = clr(106, 55, 40); - ashstorm.mSkyNightColor = clr(20, 21, 22); - ashstorm.mFogSunriseColor = clr(91, 56, 51); - ashstorm.mFogDayColor = clr(124, 73, 58); - ashstorm.mFogSunsetColor = clr(106, 55, 40); - ashstorm.mFogNightColor = clr(20, 21, 22); - ashstorm.mAmbientSunriseColor = clr(52, 42, 37); - ashstorm.mAmbientDayColor = clr(75, 49, 41); - ashstorm.mAmbientSunsetColor = clr(48, 39, 35); - ashstorm.mAmbientNightColor = clr(36, 42, 49); - ashstorm.mSunSunriseColor = clr(184, 91, 71); - ashstorm.mSunDayColor = clr(228, 139, 114); - ashstorm.mSunSunsetColor = clr(185, 86, 57); - ashstorm.mSunNightColor = clr(54, 66, 74); - ashstorm.mSunDiscSunsetColor = clr(128, 128, 128); - ashstorm.mLandFogDayDepth = 1.1; - ashstorm.mLandFogNightDepth = 1.2; - ashstorm.mWindSpeed = 0.8; - ashstorm.mCloudSpeed = 7; - ashstorm.mGlareView = 0; - ashstorm.mAmbientLoopSoundID = "ashstorm"; - mWeatherSettings["ashstorm"] = ashstorm; - - Weather blight; - blight.mCloudTexture = "tx_sky_blight.dds"; - blight.mCloudsMaximumPercent = 1.0; - blight.mTransitionDelta = 0.04; - blight.mSkySunriseColor = clr(90, 35, 35); - blight.mSkyDayColor = clr(90, 35, 35); - blight.mSkySunsetColor = clr(92, 33, 33); - blight.mSkyNightColor = clr(44, 14, 14); - blight.mFogSunriseColor = clr(90, 35, 35); - blight.mFogDayColor = clr(128, 19, 19); - blight.mFogSunsetColor = clr(92, 33, 33); - blight.mFogNightColor = clr(44, 14, 14); - blight.mAmbientSunriseColor = clr(61, 40, 40); - blight.mAmbientDayColor = clr(79, 54, 54); - blight.mAmbientSunsetColor = clr(61, 40, 40); - blight.mAmbientNightColor = clr(56, 58, 62); - blight.mSunSunriseColor = clr(180, 78, 78); - blight.mSunDayColor = clr(224, 84, 84); - blight.mSunSunsetColor = clr(180, 78, 78); - blight.mSunNightColor = clr(61, 91, 143); - blight.mSunDiscSunsetColor = clr(128, 128, 128); - blight.mLandFogDayDepth = 1.1; - blight.mLandFogNightDepth = 1.2; - blight.mWindSpeed = 0.9; - blight.mCloudSpeed = 9; - blight.mGlareView = 0; - blight.mAmbientLoopSoundID = "blight"; - mWeatherSettings["blight"] = blight; - - Weather snow; - snow.mCloudTexture = "tx_bm_sky_snow.dds"; - snow.mCloudsMaximumPercent = 1.0; - snow.mTransitionDelta = 0.014; - snow.mSkySunriseColor = clr(196, 91, 91); - snow.mSkyDayColor = clr(153, 158, 166); - snow.mSkySunsetColor = clr(96, 115, 134); - snow.mSkyNightColor = clr(31, 35, 39); - snow.mFogSunriseColor = clr(106, 91, 91); - snow.mFogDayColor = clr(153, 158, 166); - snow.mFogSunsetColor = clr(96, 115, 134); - snow.mFogNightColor = clr(31, 35, 39); - snow.mAmbientSunriseColor = clr(92, 84, 84); - snow.mAmbientDayColor = clr(93, 96, 105); - snow.mAmbientSunsetColor = clr(70, 79, 87); - snow.mAmbientNightColor = clr(49, 58, 68); - snow.mSunSunriseColor = clr(141, 109, 109); - snow.mSunDayColor = clr(163, 169, 183); - snow.mSunSunsetColor = clr(101, 121, 141); - snow.mSunNightColor = clr(55, 66, 77); - snow.mSunDiscSunsetColor = clr(128, 128, 128); - snow.mLandFogDayDepth = 1.0; - snow.mLandFogNightDepth = 1.2; - snow.mWindSpeed = 0; - snow.mCloudSpeed = 1.5; - snow.mGlareView = 0; - mWeatherSettings["snow"] = snow; - - Weather blizzard; - blizzard.mCloudTexture = "tx_bm_sky_blizzard.dds"; - blizzard.mCloudsMaximumPercent = 1.0; - blizzard.mTransitionDelta = 0.030; - blizzard.mSkySunriseColor = clr(91, 99, 106); - blizzard.mSkyDayColor = clr(121, 133, 145); - blizzard.mSkySunsetColor = clr(108, 115, 121); - blizzard.mSkyNightColor = clr(27, 29, 31); - blizzard.mFogSunriseColor = clr(91, 99, 106); - blizzard.mFogDayColor = clr(121, 133, 145); - blizzard.mFogSunsetColor = clr(108, 115, 121); - blizzard.mFogNightColor = clr(21, 24, 28); - blizzard.mAmbientSunriseColor = clr(84, 88, 92); - blizzard.mAmbientDayColor = clr(93, 96, 105); - blizzard.mAmbientSunsetColor = clr(83, 77, 75); - blizzard.mAmbientNightColor = clr(53, 62, 70); - blizzard.mSunSunriseColor = clr(114, 128, 146); - blizzard.mSunDayColor = clr(163, 169, 183); - blizzard.mSunSunsetColor = clr(106, 114, 136); - blizzard.mSunNightColor = clr(57, 66, 74); - blizzard.mSunDiscSunsetColor = clr(128, 128, 128); - blizzard.mLandFogDayDepth = 2.8; - blizzard.mLandFogNightDepth = 3.0; - blizzard.mWindSpeed = 0.9; - blizzard.mCloudSpeed = 7.5; - blizzard.mGlareView = 0; - blizzard.mAmbientLoopSoundID = "BM Blizzard"; - mWeatherSettings["blizzard"] = blizzard; -} - -void WeatherManager::setWeather(const String& weather, bool instant) -{ - if (instant || mFirstUpdate) - { - mNextWeather = ""; - mCurrentWeather = weather; - mFirstUpdate = false; - } - else - { - if (mNextWeather != "") - { - // transition more than 50% finished? - if (mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60) <= 0.5) - mCurrentWeather = mNextWeather; - } - - mNextWeather = weather; - mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60; - } -} - -WeatherResult WeatherManager::getResult(const String& weather) -{ - const Weather& current = mWeatherSettings[weather]; - WeatherResult result; - - result.mCloudTexture = current.mCloudTexture; - result.mCloudBlendFactor = 0; - result.mCloudOpacity = current.mCloudsMaximumPercent; - result.mWindSpeed = current.mWindSpeed; - result.mCloudSpeed = current.mCloudSpeed; - result.mGlareView = current.mGlareView; - result.mAmbientLoopSoundID = current.mAmbientLoopSoundID; - result.mSunColor = current.mSunDiscSunsetColor; - - const float fade_duration = current.mTransitionDelta * 24.f; - - result.mNight = (mHour < 6.f+fade_duration || mHour > 20.f-fade_duration); - - result.mFogDepth = result.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth; - - // night - if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration) - || mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration)) - { - result.mFogColor = current.mFogNightColor; - result.mAmbientColor = current.mAmbientNightColor; - result.mSunColor = current.mSunNightColor; - result.mSkyColor = current.mSkyNightColor; - result.mNightFade = 1.f; - } - - // sunrise - else if (mHour >= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration) && mHour <= WeatherGlobals::mSunriseTime) - { - if (mHour <= (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration)) - { - // fade in - float advance = (WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration+fade_duration)-mHour; - float factor = (advance / fade_duration); - result.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor); - result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor); - result.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor); - result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor); - result.mNightFade = factor; - } - else if (mHour >= (WeatherGlobals::mSunriseTime-fade_duration)) - { - // fade out - float advance = mHour-(WeatherGlobals::mSunriseTime-fade_duration); - float factor = advance / fade_duration; - result.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor); - result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor); - result.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor); - result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor); - } - else - { - result.mFogColor = current.mFogSunriseColor; - result.mAmbientColor = current.mAmbientSunriseColor; - result.mSunColor = current.mSunSunriseColor; - result.mSkyColor = current.mSkySunriseColor; - } - } - - // day - else if (mHour >= (WeatherGlobals::mSunriseTime) && mHour <= (WeatherGlobals::mSunsetTime)) - { - result.mFogColor = current.mFogDayColor; - result.mAmbientColor = current.mAmbientDayColor; - result.mSunColor = current.mSunDayColor; - result.mSkyColor = current.mSkyDayColor; - } - - // sunset - else if (mHour >= (WeatherGlobals::mSunsetTime) && mHour <= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration)) - { - if (mHour <= (WeatherGlobals::mSunsetTime+fade_duration)) - { - // fade in - float advance = (WeatherGlobals::mSunsetTime+fade_duration)-mHour; - float factor = (advance / fade_duration); - result.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor); - result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor); - result.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor); - result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor); - } - else if (mHour >= (WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration)) - { - // fade out - float advance = mHour-(WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration-fade_duration); - float factor = advance / fade_duration; - result.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor); - result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor); - result.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor); - result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor); - result.mNightFade = factor; - } - else - { - result.mFogColor = current.mFogSunsetColor; - result.mAmbientColor = current.mAmbientSunsetColor; - result.mSunColor = current.mSunSunsetColor; - result.mSkyColor = current.mSkySunsetColor; - } - } - - return result; -} - -WeatherResult WeatherManager::transition(float factor) -{ - const WeatherResult& current = getResult(mCurrentWeather); - const WeatherResult& other = getResult(mNextWeather); - WeatherResult result; - - result.mCloudTexture = current.mCloudTexture; - result.mNextCloudTexture = other.mCloudTexture; - result.mCloudBlendFactor = factor; - - result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity); - result.mFogColor = lerp(current.mFogColor, other.mFogColor); - result.mSunColor = lerp(current.mSunColor, other.mSunColor); - result.mSkyColor = lerp(current.mSkyColor, other.mSkyColor); - - result.mAmbientColor = lerp(current.mAmbientColor, other.mAmbientColor); - result.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor); - result.mFogDepth = lerp(current.mFogDepth, other.mFogDepth); - result.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed); - result.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed); - result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity); - result.mGlareView = lerp(current.mGlareView, other.mGlareView); - - result.mNight = current.mNight; - - // sound change behaviour: - // if 'other' has a new sound, switch to it after 1/2 of the transition length - if (other.mAmbientLoopSoundID != "") - result.mAmbientLoopSoundID = factor>0.5 ? other.mAmbientLoopSoundID : current.mAmbientLoopSoundID; - // if 'current' has a sound and 'other' does not have a sound, turn off the sound immediately - else if (current.mAmbientLoopSoundID != "") - result.mAmbientLoopSoundID = ""; - - return result; -} - -void WeatherManager::update(float duration) -{ - mWeatherUpdateTime -= duration; - if (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior()) - { - std::string regionstr = mEnvironment->mWorld->getPlayer().getPlayer().getCell()->cell->region; - boost::algorithm::to_lower(regionstr); - - if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) - { - mCurrentRegion = regionstr; - mWeatherUpdateTime = WeatherGlobals::mWeatherUpdateTime*60.f; - - std::string weather; - - if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) - weather = mRegionOverrides[regionstr]; - else - { - // get weather probabilities for the current region - const ESM::Region *region = mEnvironment->mWorld->getStore().regions.find (regionstr); - - float clear = region->data.clear/255.f; - float cloudy = region->data.cloudy/255.f; - float foggy = region->data.foggy/255.f; - float overcast = region->data.overcast/255.f; - float rain = region->data.rain/255.f; - 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; - - // re-scale to 100 percent - 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) - weather = "blight"; - else if (random >= thunder+rain+overcast+foggy+cloudy+clear) - weather = "ashstorm"; - else if (random >= rain+overcast+foggy+cloudy+clear) - weather = "thunderstorm"; - else if (random >= overcast+foggy+cloudy+clear) - weather = "rain"; - else if (random >= foggy+cloudy+clear) - weather = "overcast"; - else if (random >= cloudy+clear) - weather = "foggy"; - else if (random >= clear) - weather = "cloudy"; - else - weather = "clear"; - } - - setWeather(weather, false); - /* - std::cout << "roll result: " << random << std::endl; - - std::cout << regionstr << " weather probabilities: " << clear << " " << cloudy << " " << foggy << " " - << overcast << " " << rain << " " << thunder << " " << ash << " " << blight << " " << snow << " " - << blizzard << std::endl; - - std::cout << "New weather : " << weather << std::endl; - */ - } - - WeatherResult result; - - if (mNextWeather != "") - { - mRemainingTransitionTime -= duration; - if (mRemainingTransitionTime < 0) - { - mCurrentWeather = mNextWeather; - mNextWeather = ""; - } - } - - if (mNextWeather != "") - result = transition(1-(mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*60))); - else - result = getResult(mCurrentWeather); - - mRendering->configureFog(result.mFogDepth, result.mFogColor); - - // disable sun during night - if (mHour >= WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration - || mHour <= WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration) - mRendering->getSkyManager()->sunDisable(); - else - { - // during day, calculate sun angle - float height = 1-std::abs(((mHour-13)/7.f)); - int facing = mHour > 13.f ? 1 : -1; - Vector3 final( - (1-height)*facing, - (1-height)*facing, - height); - mRendering->setSunDirection(final); - - mRendering->getSkyManager()->sunEnable(); - } - - // moon calculations - float night; - if (mHour >= 14) - night = mHour-14; - else if (mHour <= 10) - night = mHour+10; - else - night = 0; - - night /= 20.f; - - if (night != 0) - { - float moonHeight = 1-std::abs((night-0.5)*2); - int facing = (mHour > 0.f && mHour<12.f) ? 1 : -1; - Vector3 masser( - (1-moonHeight)*facing, - (1-moonHeight)*facing, - moonHeight); - - Vector3 secunda( - (1-moonHeight)*facing*0.8, - (1-moonHeight)*facing*1.25, - moonHeight); - - mRendering->getSkyManager()->setMasserDirection(masser); - mRendering->getSkyManager()->setSecundaDirection(secunda); - mRendering->getSkyManager()->masserEnable(); - mRendering->getSkyManager()->secundaEnable(); - - float hour_fade; - if (mHour >= 7.f && mHour <= 14.f) - hour_fade = 1-(mHour-7)/3.f; - else if (mHour >= 14 && mHour <= 15.f) - hour_fade = mHour-14; - else - hour_fade = 1; - - float secunda_angle_fade; - float masser_angle_fade; - float angle = moonHeight*90.f; - - if (angle >= 30 && angle <= 50) - secunda_angle_fade = (angle-30)/20.f; - else if (angle <30) - secunda_angle_fade = 0.f; - else - secunda_angle_fade = 1.f; - - if (angle >= 40 && angle <= 50) - masser_angle_fade = (angle-40)/10.f; - else if (angle <40) - masser_angle_fade = 0.f; - else - masser_angle_fade = 1.f; - - masser_angle_fade *= hour_fade; - secunda_angle_fade *= hour_fade; - - mRendering->getSkyManager()->setMasserFade(masser_angle_fade); - mRendering->getSkyManager()->setSecundaFade(secunda_angle_fade); - } - else - { - mRendering->getSkyManager()->masserDisable(); - mRendering->getSkyManager()->secundaDisable(); - } - - if (mCurrentWeather == "thunderstorm" && mNextWeather == "") - { - if (mThunderFlash > 0) - { - // play the sound after a delay - mThunderSoundDelay -= duration; - if (mThunderSoundDelay <= 0) - { - // pick a random sound - int sound = rand() % 4; - std::string soundname; - if (sound == 0) soundname = WeatherGlobals::mThunderSoundID0; - else if (sound == 1) soundname = WeatherGlobals::mThunderSoundID1; - else if (sound == 2) soundname = WeatherGlobals::mThunderSoundID2; - else if (sound == 3) soundname = WeatherGlobals::mThunderSoundID3; - mEnvironment->mSoundManager->playSound(soundname, 1.0, 1.0); - mThunderSoundDelay = 1000; - } - - mThunderFlash -= duration; - if (mThunderFlash > 0) - mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold ); - else - { - srand(time(NULL)); - mThunderChanceNeeded = rand() % 100; - mThunderChance = 0; - mRendering->getSkyManager()->setThunder( 0.f ); - } - } - else - { - // no thunder active - mThunderChance += duration*4; // chance increases by 4 percent every second - if (mThunderChance >= mThunderChanceNeeded) - { - mThunderFlash = WeatherGlobals::mThunderThreshold; - - mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold ); - - mThunderSoundDelay = WeatherGlobals::mThunderSoundDelay; - } - } - } - else - mRendering->getSkyManager()->setThunder(0.f); - - mRendering->setAmbientColour(result.mAmbientColor); - mRendering->sunEnable(); - mRendering->setSunColour(result.mSunColor); - - mRendering->getSkyManager()->setWeather(result); - } - else - { - mRendering->sunDisable(); - mRendering->skyDisable(); - mRendering->getSkyManager()->setThunder(0.f); - } -} - -void WeatherManager::setHour(const float hour) -{ - // accelerate a bit for testing - /* - mHour += 0.005; - - if (mHour >= 24.f) mHour = 0.f; - - std::cout << "hour " << mHour << std::endl; - */ - - mHour = hour; -} - -void WeatherManager::setDate(const int day, const int month) -{ - mDay = day; - mMonth = month; -} - -unsigned int WeatherManager::getWeatherID() const -{ - // Source: http://www.uesp.net/wiki/Tes3Mod:GetCurrentWeather - - if (mCurrentWeather == "clear") - return 0; - else if (mCurrentWeather == "cloudy") - return 1; - else if (mCurrentWeather == "foggy") - return 2; - else if (mCurrentWeather == "overcast") - return 3; - else if (mCurrentWeather == "rain") - return 4; - else if (mCurrentWeather == "thunderstorm") - return 5; - else if (mCurrentWeather == "ashstorm") - return 6; - else if (mCurrentWeather == "blight") - return 7; - else if (mCurrentWeather == "snow") - return 8; - else if (mCurrentWeather == "blizzard") - return 9; - - else - return 0; -} - -void WeatherManager::changeWeather(const std::string& region, const unsigned int id) -{ - std::string weather; - if (id==0) - weather = "clear"; - else if (id==1) - weather = "cloudy"; - else if (id==2) - weather = "foggy"; - else if (id==3) - weather = "overcast"; - else if (id==4) - weather = "rain"; - else if (id==5) - weather = "thunderstorm"; - else if (id==6) - weather = "ashstorm"; - else if (id==7) - weather = "blight"; - else if (id==8) - weather = "snow"; - else if (id==9) - weather = "blizzard"; - else - weather = "clear"; - - mRegionOverrides[region] = weather; -} diff --git a/libs/openengine/bullet/weather.hpp b/libs/openengine/bullet/weather.hpp deleted file mode 100644 index 9353f7cd1d..0000000000 --- a/libs/openengine/bullet/weather.hpp +++ /dev/null @@ -1,272 +0,0 @@ -#ifndef GAME_MWWORLD_WEATHER_H -#define GAME_MWWORLD_WEATHER_H - -#include -#include - -namespace MWRender -{ - class RenderingManager; -} - -namespace MWWorld -{ - class Environment; - - /// Global weather manager properties (according to INI) - struct WeatherGlobals - { - /* - [Weather] - EnvReduceColor=255,255,255,255 - LerpCloseColor=037,046,048,255 - BumpFadeColor=230,239,255,255 - AlphaReduce=0.35 - Minimum Time Between Environmental Sounds=1.0 - Maximum Time Between Environmental Sounds=5.0 - Sun Glare Fader Max=0.5 - Sun Glare Fader Angle Max=30.0 - Sun Glare Fader Color=222,095,039 - Timescale Clouds=0 - Precip Gravity=575 - Hours Between Weather Changes=20 - Rain Ripples=1 - Rain Ripple Radius=1024 - Rain Ripples Per Drop=1 - Rain Ripple Scale=0.3 - Rain Ripple Speed=1.0 - Fog Depth Change Speed=3 - Sunrise Time=6 - Sunset Time=18 - Sunrise Duration=2 - Sunset Duration=2 - Sky Pre-Sunrise Time=.5 - Sky Post-Sunrise Time=1 - Sky Pre-Sunset Time=1.5 - Sky Post-Sunset Time=.5 - Ambient Pre-Sunrise Time=.5 - Ambient Post-Sunrise Time=2 - Ambient Pre-Sunset Time=1 - Ambient Post-Sunset Time=1.25 - Fog Pre-Sunrise Time=.5 - Fog Post-Sunrise Time=1 - Fog Pre-Sunset Time=2 - Fog Post-Sunset Time=1 - Sun Pre-Sunrise Time=0 - Sun Post-Sunrise Time=0 - Sun Pre-Sunset Time=1 - Sun Post-Sunset Time=1.25 - Stars Post-Sunset Start=1 - Stars Pre-Sunrise Finish=2 - Stars Fading Duration=2 - Snow Ripples=0 - Snow Ripple Radius=1024 - Snow Ripples Per Flake=1 - Snow Ripple Scale=0.3 - Snow Ripple Speed=1.0 - Snow Gravity Scale=0.1 - Snow High Kill=700 - Snow Low Kill=150 - - - [Moons] - Masser Size=94 - Masser Fade In Start=14 - Masser Fade In Finish=15 - Masser Fade Out Start=7 - Masser Fade Out Finish=10 - Masser Axis Offset=35 - Masser Speed=.5 - Masser Daily Increment=1 - Masser Fade Start Angle=50 - Masser Fade End Angle=40 - Masser Moon Shadow Early Fade Angle=0.5 - Secunda Size=40 - Secunda Fade In Start=14 - Secunda Fade In Finish=15 - Secunda Fade Out Start=7 - Secunda Fade Out Finish=10 - Secunda Axis Offset=50 - Secunda Speed=.6 - Secunda Daily Increment=1.2 - Secunda Fade Start Angle=50 - Secunda Fade End Angle=30 - Secunda Moon Shadow Early Fade Angle=0.5 - Script Color=255,20,20 - */ - - static const float mSunriseTime; - static const float mSunsetTime; - static const float mSunriseDuration; - static const float mSunsetDuration; - - 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; - static const float mThunderThreshold; - static const float mThunderSoundDelay; - static const std::string mThunderSoundID0; - static const std::string mThunderSoundID1; - static const std::string mThunderSoundID2; - static const std::string mThunderSoundID3; - }; - - /// Defines the actual weather that results from weather setting (see below), time of day and weather transition - struct WeatherResult - { - Ogre::String mCloudTexture; - Ogre::String mNextCloudTexture; - float mCloudBlendFactor; - - Ogre::ColourValue mFogColor; - - Ogre::ColourValue mAmbientColor; - - Ogre::ColourValue mSkyColor; - - Ogre::ColourValue mSunColor; - - Ogre::ColourValue mSunDiscColor; - - float mFogDepth; - - float mWindSpeed; - - float mCloudSpeed; - - float mCloudOpacity; - - float mGlareView; - - bool mNight; // use night skybox - float mNightFade; // fading factor for night skybox - - Ogre::String mAmbientLoopSoundID; - }; - - - /// Defines a single weather setting (according to INI) - struct Weather - { - Ogre::String mCloudTexture; - - // Sky (atmosphere) colors - Ogre::ColourValue mSkySunriseColor, - mSkyDayColor, - mSkySunsetColor, - mSkyNightColor; - - // Fog colors - Ogre::ColourValue mFogSunriseColor, - mFogDayColor, - mFogSunsetColor, - mFogNightColor; - - // Ambient lighting colors - Ogre::ColourValue mAmbientSunriseColor, - mAmbientDayColor, - mAmbientSunsetColor, - mAmbientNightColor; - - // Sun (directional) lighting colors - Ogre::ColourValue mSunSunriseColor, - mSunDayColor, - mSunSunsetColor, - mSunNightColor; - - // Fog depth/density - float mLandFogDayDepth, - mLandFogNightDepth; - - // Color modulation for the sun itself during sunset (not completely sure) - Ogre::ColourValue mSunDiscSunsetColor; - - // Duration of weather transition (in days) - float mTransitionDelta; - - // No idea what this one is used for? - float mWindSpeed; - - // Cloud animation speed multiplier - float mCloudSpeed; - - // Multiplier for clouds transparency - float mCloudsMaximumPercent; - - // Value between 0 and 1, defines the strength of the sun glare effect - float mGlareView; - - // Sound effect - // This is used for Blight, Ashstorm and Blizzard (Bloodmoon) - Ogre::String mAmbientLoopSoundID; - - // Rain sound effect - Ogre::String mRainLoopSoundID; - - /// \todo disease chance - }; - - /// - /// Interface for weather settings - /// - class WeatherManager - { - public: - WeatherManager(MWRender::RenderingManager*, MWWorld::Environment*); - - /** - * Change the weather in the specified region - * @param region that should be changed - * @param ID of the weather setting to shift to - */ - void changeWeather(const std::string& region, const unsigned int id); - - /** - * Per-frame update - * @param duration - */ - void update(float duration); - - void setHour(const float hour); - - void setDate(const int day, const int month); - - unsigned int getWeatherID() const; - - private: - float mHour; - int mDay, mMonth; - - MWRender::RenderingManager* mRendering; - MWWorld::Environment* mEnvironment; - - std::map mWeatherSettings; - - std::map mRegionOverrides; - - Ogre::String mCurrentWeather; - Ogre::String mNextWeather; - - std::string mCurrentRegion; - - bool mFirstUpdate; - - float mWeatherUpdateTime; - - float mRemainingTransitionTime; - - float mThunderFlash; - float mThunderChance; - float mThunderChanceNeeded; - float mThunderSoundDelay; - - WeatherResult transition(const float factor); - WeatherResult getResult(const Ogre::String& weather); - - void setWeather(const Ogre::String& weather, bool instant=false); - }; -} - -#endif // GAME_MWWORLD_WEATHER_H From 318355f1be3fa5f14abe34d39a3b76b063b5b9a3 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 26 Mar 2012 21:35:20 -0400 Subject: [PATCH 03/22] Bouncy effect gone --- libs/openengine/bullet/pmove.cpp | 48 ++++++++++++++++++++++---------- libs/openengine/bullet/trace.cpp | 4 +-- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 8dd01ef190..d8880a49f1 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -178,7 +178,7 @@ bool PM_SlideMove( bool gravity ) float into; Ogre::Vector3 endVelocity; Ogre::Vector3 endClipVelocity; - std::cout << "Slide move\n"; + std::cout << "Slide move" << pm->ps.velocity << "\n"; numbumps = 4; // primal_velocity = pm->ps->velocity @@ -415,6 +415,7 @@ int PM_StepSlideMove( bool gravity ) // vec3_t delta, delta2; Ogre::Vector3 up, down; float stepSize; + std::cout << "Step Slide move" << pm->ps.velocity << "\n"; // start_o = pm->ps->origin //VectorCopy (pm->ps->origin, start_o); @@ -427,7 +428,7 @@ int PM_StepSlideMove( bool gravity ) if ( PM_SlideMove( gravity ) == false ) return 1; // we got exactly where we wanted to go first try - std::cout << "Step Slide move\n"; + // down = start_o - vec3(0, 0, STEPSIZE) //VectorCopy(start_o, down); down = start_o; @@ -711,7 +712,7 @@ static void PM_WaterMove( playerMove* const pm ) Ogre::Vector3 wishdir; float scale; float vel; - + std::cout << "Water moving"; /*if ( PM_CheckWaterJump() ) { PM_WaterJumpMove(); @@ -837,7 +838,7 @@ static void PM_WalkMove( playerMove* const pmove ) playerMove::playercmd cmd; float accelerate; float vel; - std::cout << "Walking\n"; + std::cout << "Walking" << pm->ps.velocity << "\n"; if ( pm->ps.waterlevel > 2 && //DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) pml.forward.dotProduct(pml.groundTrace.planenormal) > 0.0f) @@ -927,6 +928,7 @@ static void PM_WalkMove( playerMove* const pmove ) PM_Friction (); + std::cout << "After friction" << pm->ps.velocity << "\n"; //bprintf("vel: (%f, %f, %f)\n", pm->ps.velocity.x, pm->ps.velocity.y, pm->ps.velocity.z); @@ -945,20 +947,28 @@ static void PM_WalkMove( playerMove* const pmove ) //pml.right[2] = 0; pml.right.z = 0; + //std::cout << "Further down" << pm->ps.velocity << "\n"; + // 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 ); + std::cout << "Clip velocity" << pm->ps.velocity << "\n"; // - //VectorNormalize (pml.forward); - pml.forward = pml.forward.normalise(); - pml.right = pml.right.normalise(); + + VectorNormalize (pml.forward); + VectorNormalize (pml.right); + //pml.forward = pml.forward.normalise(); + //pml.right = pml.right.normalise(); + std::cout << "forward2" << pml.forward << "\n"; + std::cout << "right2" << pml.right << "\n"; // 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; + std::cout << "WishVel" << wishvel << "\n"; //bprintf("f: (%f, %f, %f), s: (%f, %f, %f)\n", fmove, smove); @@ -971,7 +981,9 @@ static void PM_WalkMove( playerMove* const pmove ) wishdir = wishvel; wishspeed = VectorNormalize(wishdir); + std::cout << "Wishspeed: " << wishspeed << "\n"; wishspeed *= scale; + std::cout << "Wishspeed scaled:" << wishspeed << "\n"; // clamp the speed lower if ducking if ( pm->cmd.ducking ) @@ -998,6 +1010,7 @@ static void PM_WalkMove( playerMove* const pmove ) PM_Accelerate (wishdir, wishspeed, accelerate); + std::cout << "Velocityafter: " << pm->ps.velocity << "\n"; //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)); @@ -1012,15 +1025,18 @@ static void PM_WalkMove( playerMove* const pmove ) //vel = VectorLength(pm->ps->velocity); vel = pm->ps.velocity.length(); + std::cout << "The length" << vel << "\n"; // slide along the ground plane PM_ClipVelocity (pm->ps.velocity, pml.groundTrace.planenormal, pm->ps.velocity, OVERCLIP ); + std::cout << "Velocity clipped" << pm->ps.velocity << "\n"; // don't decrease velocity when going up or down a slope - //VectorNormalize(pm->ps->velocity); - pm->ps.velocity = pm->ps.velocity.normalise(); + VectorNormalize(pm->ps.velocity); + //pm->ps.velocity = pm->ps.velocity.normalise(); + std::cout << "Final:" << pm->ps.velocity << "\n"; //VectorScale(pm->ps->velocity, vel, pm->ps->velocity); pm->ps.velocity = pm->ps.velocity * vel; @@ -1032,6 +1048,7 @@ static void PM_WalkMove( playerMove* const pmove ) PM_StepSlideMove( false ); //Com_Printf("velocity2 = %1.1f\n", VectorLength(pm->ps->velocity)); + std::cout << "Walk2" << pm->ps.velocity << "\n"; } @@ -1361,7 +1378,7 @@ static void PM_CrashLand( void ) static void PM_GroundTrace( void ) { - std::cout << "Ground trace\n"; + std::cout << "Ground trace" << pm->ps.velocity << "\n"; Ogre::Vector3 point; traceResults trace; @@ -1467,13 +1484,13 @@ static void PM_GroundTrace( void ) // don't reset the z velocity for slopes // pm->ps->velocity[2] = 0; - + std::cout << "Ground trace2" << pm->ps.velocity << "\n"; //PM_AddTouchEnt( trace.entityNum ); } static void PM_AirMove() { - std::cout << "Air move\n"; + std::cout << "Air move " << pm->ps.velocity << "\n"; //int i; Ogre::Vector3 wishvel; float fmove, smove; @@ -1495,9 +1512,9 @@ static void PM_AirMove() // project moves down to flat plane //pml.forward[2] = 0; - pml.forward.y = 0; //Z or Y? + pml.forward.z = 0; //Z or Y? //pml.right[2] = 0; - pml.right.y = 0; + pml.right.z = 0; //VectorNormalize (pml.forward); pml.forward = Ogre::Vector3(pml.forward.normalise()); pml.right = Ogre::Vector3(pml.right.normalise()); @@ -1535,8 +1552,9 @@ static void PM_AirMove() else PM_SlideMove ( qtrue ); #endif*/ - + /*bprintf("%i ", */PM_StepSlideMove ( true )/* )*/; + std::cout << "Velocity 2 " << pm->ps.velocity << "\n"; } static void PM_NoclipMove( void ) diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 8f2423c242..18a668e55b 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.z -= .25; - const bool hasHit = NewPhysicsTrace(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0f, rotation), 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) @@ -100,7 +100,7 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& 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 btQuaternion btrot(rotation.y, rotation.x, rotation.z); //y, x, z const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z)); const btTransform from(btrot, btstart); From b9fabce9c4654f99c3b3bc8e296e64e35b13639d Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Tue, 27 Mar 2012 20:17:54 -0400 Subject: [PATCH 04/22] Awesome, working --- apps/openmw/mwclass/npc.cpp | 4 +- apps/openmw/mwworld/physicssystem.cpp | 7 ++- libs/openengine/bullet/pmove.cpp | 67 +++++++++++++-------------- libs/openengine/bullet/pmove.h | 2 +- libs/openengine/bullet/trace.cpp | 8 ++-- 5 files changed, 44 insertions(+), 44 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 522fce3a3c..8bb394129f 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -273,8 +273,8 @@ namespace MWClass vector.y = getMovementSettings (ptr).mForwardBackward * 127; vector.z = getMovementSettings(ptr).mUpDown * 127; - if (getStance (ptr, Run, false)) - vector *= 2; + //if (getStance (ptr, Run, false)) + // vector *= 2; return vector; } diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 15d2d3f9f6..fdcee417f4 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -116,7 +116,6 @@ namespace MWWorld pm_ref.upmove = dir1.y; - //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"; @@ -124,11 +123,15 @@ namespace MWWorld } 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; - pm_ref.upmove = dir.y; + pm_ref.upmove = dir1.y; + + dir = 0.025*(quat*dir1); } diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index d8880a49f1..8fb72aa1f0 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -93,6 +93,7 @@ static inline void PM_ClipVelocity(const Ogre::Vector3& in, const Ogre::Vector3& { change = normal[i]*backoff; out[i] = in[i] - change; + }*/ float changex = normal.x * backoff; out.x = in.x - changex; @@ -178,7 +179,7 @@ bool PM_SlideMove( bool gravity ) float into; Ogre::Vector3 endVelocity; Ogre::Vector3 endClipVelocity; - std::cout << "Slide move" << pm->ps.velocity << "\n"; + numbumps = 4; // primal_velocity = pm->ps->velocity @@ -415,7 +416,7 @@ int PM_StepSlideMove( bool gravity ) // vec3_t delta, delta2; Ogre::Vector3 up, down; float stepSize; - std::cout << "Step Slide move" << pm->ps.velocity << "\n"; + // start_o = pm->ps->origin //VectorCopy (pm->ps->origin, start_o); @@ -543,7 +544,7 @@ int PM_StepSlideMove( bool gravity ) void PM_Friction(void) { - std::cout << "Friction\n"; + Ogre::Vector3 vec; float* vel; float speed, newspeed, control; @@ -639,7 +640,6 @@ static void PM_Accelerate( Ogre::Vector3& wishdir, float wishspeed, float accel { // int i; float addspeed, accelspeed, currentspeed; - std::cout << "Accelerate\n"; // currentspeed = pm->ps->velocity dot wishdir //currentspeed = DotProduct (pm->ps->velocity, wishdir); @@ -712,7 +712,7 @@ static void PM_WaterMove( playerMove* const pm ) Ogre::Vector3 wishdir; float scale; float vel; - std::cout << "Water moving"; + /*if ( PM_CheckWaterJump() ) { PM_WaterJumpMove(); @@ -838,7 +838,7 @@ static void PM_WalkMove( playerMove* const pmove ) playerMove::playercmd cmd; float accelerate; float vel; - std::cout << "Walking" << pm->ps.velocity << "\n"; + if ( pm->ps.waterlevel > 2 && //DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) pml.forward.dotProduct(pml.groundTrace.planenormal) > 0.0f) @@ -851,6 +851,7 @@ static void PM_WalkMove( playerMove* const pmove ) if ( PM_CheckJump () ) { + // jumped away if ( pm->ps.waterlevel > 1 ) PM_WaterMove(pmove); @@ -928,12 +929,13 @@ static void PM_WalkMove( playerMove* const pmove ) PM_Friction (); - std::cout << "After friction" << pm->ps.velocity << "\n"; + //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 ); @@ -953,22 +955,23 @@ static void PM_WalkMove( playerMove* const pmove ) // 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 ); - std::cout << "Clip velocity" << pm->ps.velocity << "\n"; + //std::cout << "Clip velocity" << pm->ps.velocity << "\n"; // VectorNormalize (pml.forward); VectorNormalize (pml.right); //pml.forward = pml.forward.normalise(); //pml.right = pml.right.normalise(); - std::cout << "forward2" << pml.forward << "\n"; - std::cout << "right2" << pml.right << "\n"; + //std::cout << "forward2" << pml.forward << "\n"; + //std::cout << "right2" << pml.right << "\n"; // 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; - std::cout << "WishVel" << wishvel << "\n"; + + //bprintf("f: (%f, %f, %f), s: (%f, %f, %f)\n", fmove, smove); @@ -981,9 +984,9 @@ static void PM_WalkMove( playerMove* const pmove ) wishdir = wishvel; wishspeed = VectorNormalize(wishdir); - std::cout << "Wishspeed: " << wishspeed << "\n"; + //std::cout << "Wishspeed: " << wishspeed << "\n"; wishspeed *= scale; - std::cout << "Wishspeed scaled:" << wishspeed << "\n"; + //std::cout << "Wishspeed scaled:" << wishspeed << "\n"; // clamp the speed lower if ducking if ( pm->cmd.ducking ) @@ -1010,7 +1013,7 @@ static void PM_WalkMove( playerMove* const pmove ) PM_Accelerate (wishdir, wishspeed, accelerate); - std::cout << "Velocityafter: " << pm->ps.velocity << "\n"; + //std::cout << "Velocityafter: " << pm->ps.velocity << "\n"; //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)); @@ -1025,18 +1028,18 @@ static void PM_WalkMove( playerMove* const pmove ) //vel = VectorLength(pm->ps->velocity); vel = pm->ps.velocity.length(); - std::cout << "The length" << vel << "\n"; + //std::cout << "The length" << vel << "\n"; // slide along the ground plane PM_ClipVelocity (pm->ps.velocity, pml.groundTrace.planenormal, pm->ps.velocity, OVERCLIP ); - std::cout << "Velocity clipped" << pm->ps.velocity << "\n"; + //std::cout << "Velocity clipped" << pm->ps.velocity << "\n"; // don't decrease velocity when going up or down a slope VectorNormalize(pm->ps.velocity); //pm->ps.velocity = pm->ps.velocity.normalise(); - std::cout << "Final:" << pm->ps.velocity << "\n"; + //std::cout << "Final:" << pm->ps.velocity << "\n"; //VectorScale(pm->ps->velocity, vel, pm->ps->velocity); pm->ps.velocity = pm->ps.velocity * vel; @@ -1048,7 +1051,7 @@ static void PM_WalkMove( playerMove* const pmove ) PM_StepSlideMove( false ); //Com_Printf("velocity2 = %1.1f\n", VectorLength(pm->ps->velocity)); - std::cout << "Walk2" << pm->ps.velocity << "\n"; + } @@ -1056,7 +1059,7 @@ void PM_UpdateViewAngles( playerMove::playerStruct* const ps, playerMove::player { short temp; int i; - std::cout << "Updating viewangles\n"; + //while(1); //if ( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPINTERMISSION) @@ -1178,7 +1181,6 @@ 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); @@ -1236,7 +1238,7 @@ static void PM_CrashLand( void ) float vel, acc; float t; float a, b, c, den; - std::cout << "Crash land\n"; + // decide which landing animation to use /*if ( pm->ps->pm_flags & PMF_BACKWARDS_JUMP ) PM_ForceLegsAnim( LEGS_LANDB ); @@ -1378,7 +1380,6 @@ static void PM_CrashLand( void ) static void PM_GroundTrace( void ) { - std::cout << "Ground trace" << pm->ps.velocity << "\n"; Ogre::Vector3 point; traceResults trace; @@ -1484,13 +1485,12 @@ static void PM_GroundTrace( void ) // don't reset the z velocity for slopes // pm->ps->velocity[2] = 0; - std::cout << "Ground trace2" << pm->ps.velocity << "\n"; + //PM_AddTouchEnt( trace.entityNum ); } static void PM_AirMove() { - std::cout << "Air move " << pm->ps.velocity << "\n"; //int i; Ogre::Vector3 wishvel; float fmove, smove; @@ -1516,8 +1516,8 @@ static void PM_AirMove() //pml.right[2] = 0; pml.right.z = 0; //VectorNormalize (pml.forward); - pml.forward = Ogre::Vector3(pml.forward.normalise()); - pml.right = Ogre::Vector3(pml.right.normalise()); + VectorNormalize(pml.forward); + VectorNormalize(pml.right); //VectorNormalize (pml.right); //for ( i = 0 ; i < 2 ; i++ ) @@ -1554,7 +1554,6 @@ static void PM_AirMove() #endif*/ /*bprintf("%i ", */PM_StepSlideMove ( true )/* )*/; - std::cout << "Velocity 2 " << pm->ps.velocity << "\n"; } static void PM_NoclipMove( void ) @@ -1602,9 +1601,7 @@ static void PM_NoclipMove( void ) //for (i=0 ; i<3 ; i++) //wishvel[i] = pml.forward[i] * fmove + pml.right[i] * smove; - std::cout << "Forward" << pml.forward << "\n"; - std::cout << "Right" << pml.right << "\n"; - std::cout << "Up" << pml.up << "\n"; + wishvel = pml.forward * fmove + pml.right * smove; //wishvel[2] += pm->cmd.upmove; wishvel.z += pm->cmd.upmove; @@ -1614,6 +1611,7 @@ static void PM_NoclipMove( void ) wishspeed = VectorNormalize(wishdir); wishspeed *= scale; + PM_Accelerate( wishdir, wishspeed, pm_accelerate ); // move @@ -1747,6 +1745,7 @@ void PM_SetWaterLevel( playerMove* const pm ) void PmoveSingle (playerMove* const pmove) { + //pm = pmove; // Aedra doesn't support Q3-style VM traps D: //while(1); @@ -1898,7 +1897,7 @@ void PmoveSingle (playerMove* const pmove) if ( pm->ps.move_type == PM_SPECTATOR ) { - std::cout << "SPECTATOR\n"; + //PM_CheckDuck (); PM_FlyMove (); PM_DropTimers (); @@ -1907,20 +1906,19 @@ void PmoveSingle (playerMove* const pmove) 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 } @@ -2006,6 +2004,7 @@ void Ext_UpdateViewAngles(playerMove* const pm) void Pmove (playerMove* const pmove) { + int fmove = pmove->cmd.forwardmove; pm = pmove; int finalTime; diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index 5dfd18f6dc..30572a92a2 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -90,7 +90,7 @@ struct playerMove { struct playerStruct { - playerStruct() : gravity(50.0f), speed(320.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0) + playerStruct() : gravity(800.0f), speed(320.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0) { origin = Ogre::Vector3(733.164f,900.0f, 839.432f); velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 18a668e55b..ca68a5d5c0 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -32,9 +32,8 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr //Ogre::Vector3 endReplace = startReplace; //endReplace.z -= .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"; + const bool hasHit = NewPhysicsTrace(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0, rotation), isInterior, enginePass); + if (out.fraction < 0.001f) results->startsolid = true; else @@ -180,8 +179,7 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& const bool hasHit = newTraceCallback.hasHit(); - if(hasHit) - std::cout << "HIT\n"; + return hasHit; From c5f044eb0df83cb1b550bf3e3559d2f7621b7637 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 28 Mar 2012 22:46:29 +0200 Subject: [PATCH 05/22] fixed compilation --- apps/openmw/mwworld/scene.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 79e7d565d2..205d66cd7d 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -112,9 +112,12 @@ namespace MWWorld float worldsize = ESM::Land::REAL_SIZE; if (!(cell->cell->data.flags & ESM::Cell::Interior)) - mPhysics->addHeightField (cell->land[1][1]->landData->heights, + { + ESM::Land* land = mWorld->getStore().lands.search(cell->cell->data.gridX,cell->cell->data.gridY); + mPhysics->addHeightField (land->landData->heights, cell->cell->data.gridX, cell->cell->data.gridY, 0, ( worldsize/(verts-1) ), verts); + } mRendering.configureAmbient(*cell); mRendering.requestMap(cell); From bc636f036ce6c10470625e33bc3e2e762989ab96 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 8 Apr 2012 18:25:50 +0200 Subject: [PATCH 06/22] made it compile --- libs/openengine/bullet/pmove.cpp | 2 +- libs/openengine/bullet/trace.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 8fb72aa1f0..dcb2e9f9b0 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -1489,7 +1489,7 @@ static void PM_GroundTrace( void ) //PM_AddTouchEnt( trace.entityNum ); } -static void PM_AirMove() +void PM_AirMove() { //int i; Ogre::Vector3 wishvel; diff --git a/libs/openengine/bullet/trace.h b/libs/openengine/bullet/trace.h index 025673ab7a..fb666b6ebd 100644 --- a/libs/openengine/bullet/trace.h +++ b/libs/openengine/bullet/trace.h @@ -53,10 +53,10 @@ struct traceResults template const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass); -template const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass); -template const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass); +//template const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass); +//template const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass); void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBExtents, const float rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass); -#endif \ No newline at end of file +#endif From 5f9056c45d06fadd12a77be438c3eab930e25ecb Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Tue, 17 Apr 2012 20:31:36 -0400 Subject: [PATCH 07/22] Better no clip --- apps/openmw/mwworld/physicssystem.cpp | 7 ++++--- libs/openengine/bullet/pmove.cpp | 4 +++- libs/openengine/bullet/pmove.h | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 29c65b411b..98c15e3383 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -127,11 +127,11 @@ namespace MWWorld Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); Ogre::Quaternion both = yawQuat * pitchQuat; - playerphysics->ps.viewangles.x = 0; + playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees(); playerphysics->ps.viewangles.z = 0; - playerphysics->ps.viewangles.y = both.getYaw().valueDegrees() *-1 + 90; + playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90; - //playerphysics->ps.viewangles.z = both.getPitch().valueDegrees(); + if(mFreeFly) @@ -259,6 +259,7 @@ namespace MWWorld { if(playerphysics->ps.move_type==PM_NOCLIP) playerphysics->ps.move_type=PM_NORMAL; + else playerphysics->ps.move_type=PM_NOCLIP; for(std::map::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 8fb72aa1f0..86d069273e 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -632,6 +632,8 @@ float PM_CmdScale(playerMove::playercmd* const cmd) 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 ); + if(pm->ps.move_type == PM_NOCLIP) + scale *= 2; return scale; } @@ -1125,7 +1127,7 @@ void AngleVectors( const Ogre::Vector3& angles, Ogre::Vector3* const forward, Og { right->x = (-1 * sr * sp * cy + -1 * cr * -sy); right->y = (-1 * sr * sp * sy + -1 * cr * cy); - right->z = 0.0f;//-1 * sp * cp; + right->z = 0; } if (up) { diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index 30572a92a2..304572b021 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -55,7 +55,7 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2); #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_friction = 12.0f; static const float pm_flightfriction = 3.0f; static const float pm_waterfriction = 1.0f; static const float pm_airaccelerate = 1.0f; @@ -90,7 +90,7 @@ struct playerMove { struct playerStruct { - playerStruct() : gravity(800.0f), speed(320.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0) + playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0) { origin = Ogre::Vector3(733.164f,900.0f, 839.432f); velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); From 4d07ae7fe031dad3019b8c7d837fc4059a3ffee9 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 18 Apr 2012 00:13:38 -0400 Subject: [PATCH 08/22] Swimming working --- apps/openmw/mwworld/physicssystem.cpp | 7 +++++++ apps/openmw/mwworld/physicssystem.hpp | 2 ++ apps/openmw/mwworld/scene.cpp | 2 ++ libs/openengine/bullet/pmove.cpp | 10 +++++----- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 98c15e3383..d224385ae5 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -67,6 +67,13 @@ namespace MWWorld return mEngine->rayTest2(from,to); } + void PhysicsSystem::setCurrentWater(bool hasWater, int waterHeight){ + playerphysics->hasWater = hasWater; + if(hasWater){ + playerphysics->waterHeight = waterHeight; + } + + } btVector3 PhysicsSystem::getRayPoint(float extent) { diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index fb15a1486f..2d73cab27c 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -49,6 +49,8 @@ namespace MWWorld void insertActorPhysics(const MWWorld::Ptr&, std::string model); OEngine::Physic::PhysicEngine* getEngine(); + + void setCurrentWater(bool hasWater, int waterHeight); private: OEngine::Render::OgreRenderer &mRender; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 2123b47999..5244d53f83 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -117,6 +117,8 @@ namespace MWWorld void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position, bool adjustPlayerPos) { + bool hasWater = cell->cell->data.flags & cell->cell->HasWater; + mPhysics->setCurrentWater(hasWater, cell->cell->water); if (adjustPlayerPos) mWorld->getPlayer().setPos (position.pos[0], position.pos[1], position.pos[2]); diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 86d069273e..214a7e5989 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -1715,11 +1715,11 @@ void PM_SetWaterLevel( playerMove* const pm ) 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; + point.y = pm->ps.origin.y; + point.z = pm->ps.origin.z + MINS_Z + 1; //cont = pm->pointcontents( point, pm->ps->clientNum ); - bool checkWater = (pml.hasWater && pml.waterHeight > point.y); + bool checkWater = (pml.hasWater && pml.waterHeight > point.z); //if ( cont & MASK_WATER ) if ( checkWater) { @@ -1729,14 +1729,14 @@ void PM_SetWaterLevel( playerMove* const pm ) 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; + point.z = pm->ps.origin.z + 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; + point.z = pm->ps.origin.z + MINS_Z + sample2; //cont = pm->pointcontents (point, pm->ps->clientNum ); //if ( cont & MASK_WATER ) if (checkWater ) From 00260a24ce0c125582b48a1a2ca4d3457913cf5b Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 18 Apr 2012 21:28:25 -0400 Subject: [PATCH 09/22] Water corrections --- libs/openengine/bullet/pmove.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 214a7e5989..7741d2f047 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -1730,6 +1730,7 @@ void PM_SetWaterLevel( playerMove* const pm ) pm->ps.waterlevel = WL_ANKLE; //point[2] = pm->ps->origin[2] + MINS_Z + sample1; point.z = pm->ps.origin.z + MINS_Z + sample1; + checkWater = (pml.hasWater && pml.waterHeight > point.z); //cont = pm->pointcontents (point, pm->ps->clientNum ); //if ( cont & MASK_WATER ) if (checkWater) @@ -1739,6 +1740,7 @@ void PM_SetWaterLevel( playerMove* const pm ) point.z = pm->ps.origin.z + MINS_Z + sample2; //cont = pm->pointcontents (point, pm->ps->clientNum ); //if ( cont & MASK_WATER ) + checkWater = (pml.hasWater && pml.waterHeight > point.z); if (checkWater ) pm->ps.waterlevel = WL_UNDERWATER; } From 16855291a7c640d1b796448a529784299c1bd632 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 21 Apr 2012 16:21:30 -0400 Subject: [PATCH 10/22] Implementing snapping --- apps/openmw/mwworld/physicssystem.cpp | 2 + libs/openengine/bullet/pmove.cpp | 84 ++++++++++++++++----------- libs/openengine/bullet/pmove.h | 7 ++- 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index d224385ae5..9af7a72852 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -27,6 +27,8 @@ namespace MWWorld NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader(); mEngine = new OEngine::Physic::PhysicEngine(shapeLoader); playerphysics->mEngine = mEngine; + //playerphysics->ps.snappingImplemented = true; + } diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 7741d2f047..82f473085f 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -417,7 +417,7 @@ int PM_StepSlideMove( bool gravity ) Ogre::Vector3 up, down; float stepSize; - + std::cout << "StepSlideMove\n"; // start_o = pm->ps->origin //VectorCopy (pm->ps->origin, start_o); start_o = pm->ps.origin; @@ -516,6 +516,7 @@ int PM_StepSlideMove( bool gravity ) delta = pm->ps.origin.z - start_o.z; if ( delta > 2 ) { + pm->ps.counter = 10; if (gravity) printf("g on: %f ", delta); else @@ -688,6 +689,7 @@ static bool PM_CheckJump(void) pm->ps.groundEntityNum = ENTITYNUM_NONE; pm->ps.velocity.z = JUMP_VELOCITY; + pm->ps.bSnap = false; //PM_AddEvent( EV_JUMP ); /*if ( pm->cmd.forwardmove >= 0 ) @@ -840,7 +842,7 @@ static void PM_WalkMove( playerMove* const pmove ) playerMove::playercmd cmd; float accelerate; float vel; - + //pm->ps.gravity = 4000; if ( pm->ps.waterlevel > 2 && //DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) pml.forward.dotProduct(pml.groundTrace.planenormal) > 0.0f) @@ -1142,9 +1144,7 @@ void PM_GroundTraceMissed() { traceResults trace; Ogre::Vector3 point; - - if ( pm->ps.groundEntityNum != ENTITYNUM_NONE ) - { + std::cout << "Ground trace missed\n"; // we just transitioned into freefall //if ( pm->debugLevel ) //Com_Printf("%i:lift\n", c_pmove); @@ -1154,29 +1154,28 @@ void PM_GroundTraceMissed() //VectorCopy( pm->ps->origin, point ); point = pm->ps.origin; //point[2] -= 64; - point.z -= 64; + point.z -= 32; //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 ) + //It hit the ground below + if ( trace.fraction < 1.0 && pm->ps.origin.z > trace.endpos.z) { - 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.origin = trace.endpos; + pml.walking = true; + pml.groundPlane = true; + pm->ps.groundEntityNum = trace.entityNum; + } - } + else{ + pm->ps.groundEntityNum = ENTITYNUM_NONE; + pml.groundPlane = false; + pml.walking = false; + pm->ps.bSnap = false; + } - pm->ps.groundEntityNum = ENTITYNUM_NONE; - pml.groundPlane = false; - pml.walking = false; + } static bool PM_CorrectAllSolid(traceResults* const trace) @@ -1404,19 +1403,26 @@ static void PM_GroundTrace( void ) return; } } - - // if the trace didn't hit anything, we are in free fall - if ( trace.fraction == 1.0 ) + // 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; + if(pm->ps.snappingImplemented){ + if(pm->ps.bSnap && pm->ps.counter <= 0) + PM_GroundTraceMissed(); + } + + return; } + else + { + //It hit something, so we are on the ground + pm->ps.bSnap = true; - // check if getting thrown off the ground + } + // 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.z > 0 && pm->ps.velocity.dotProduct(trace.planenormal) > 10.0f) + if (pm->ps.velocity.z > 0 && pm->ps.velocity.dotProduct(trace.planenormal) > 10.0f ) { //if ( pm->debugLevel ) //Com_Printf("%i:kickoff\n", c_pmove); @@ -1432,13 +1438,22 @@ static void PM_GroundTrace( void ) PM_ForceLegsAnim( LEGS_JUMPB ); pm->ps->pm_flags |= PMF_BACKWARDS_JUMP; }*/ - + if(!pm->ps.bSnap){ pm->ps.groundEntityNum = ENTITYNUM_NONE; pml.groundPlane = false; pml.walking = false; + } + else + { + pml.groundPlane = true; + pml.walking = true; + } return; } + + + // slopes that are too steep will not be considered onground //if ( trace.plane.normal[2] < MIN_WALK_NORMAL ) if (trace.planenormal.z < MIN_WALK_NORMAL) @@ -1500,7 +1515,7 @@ static void PM_AirMove() float wishspeed; float scale; playerMove::playercmd cmd; - + //pm->ps.gravity = 800; PM_Friction(); fmove = pm->cmd.forwardmove; @@ -1508,7 +1523,6 @@ static void PM_AirMove() cmd = pm->cmd; scale = PM_CmdScale( &cmd ); - // set the movementDir so clients can rotate the legs for strafing //PM_SetMovementDir(); @@ -1749,7 +1763,7 @@ void PM_SetWaterLevel( playerMove* const pm ) void PmoveSingle (playerMove* const pmove) { - + pmove->ps.counter--; //pm = pmove; // Aedra doesn't support Q3-style VM traps D: //while(1); @@ -1763,6 +1777,10 @@ void PmoveSingle (playerMove* const pmove) pm->ps.watertype = 0; pm->ps.waterlevel = WL_DRYLAND; + if(pml.walking) + std::cout << "Walking\n"; + else + std::cout << "Not Walking\n"; //if ( pm->ps->stats[STAT_HEALTH] <= 0 ) //pm->tracemask &= ~CONTENTS_BODY; // corpses can fly through bodies diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index 304572b021..a14a1e660d 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -42,7 +42,7 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2); #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 JUMP_VELOCITY (270) #define PS_PMOVEFRAMECOUNTBITS 6 #define MINS_Z -24 #define DEFAULT_VIEWHEIGHT 26 @@ -90,7 +90,7 @@ struct playerMove { struct playerStruct { - playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0) + playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1) { origin = Ogre::Vector3(733.164f,900.0f, 839.432f); velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); @@ -117,6 +117,9 @@ struct playerMove Ogre::Vector3 velocity; Ogre::Vector3 origin; + bool bSnap; + bool snappingImplemented; + int counter; float gravity; // default = 800 float speed; // default = 320 From 8ebae0b7061ee3ef4056c5cbbd123c3917427725 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 21 Apr 2012 16:57:46 -0400 Subject: [PATCH 11/22] Solid trace --- apps/openmw/mwworld/physicssystem.cpp | 2 +- libs/openengine/bullet/pmove.cpp | 4 ---- libs/openengine/bullet/trace.cpp | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 9af7a72852..63bf8dda39 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -27,7 +27,7 @@ namespace MWWorld NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader(); mEngine = new OEngine::Physic::PhysicEngine(shapeLoader); playerphysics->mEngine = mEngine; - //playerphysics->ps.snappingImplemented = true; + } diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 82f473085f..922fd844c0 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -1777,10 +1777,6 @@ void PmoveSingle (playerMove* const pmove) pm->ps.watertype = 0; pm->ps.waterlevel = WL_DRYLAND; - if(pml.walking) - std::cout << "Walking\n"; - else - std::cout << "Not Walking\n"; //if ( pm->ps->stats[STAT_HEALTH] <= 0 ) //pm->tracemask &= ~CONTENTS_BODY; // corpses can fly through bodies diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index ca68a5d5c0..81c064c2d3 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -172,7 +172,7 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& if (!TestPointAgainstAabb2(aabbMin, aabbMax, *(const btVector3* const)&(start) ) ) { //We're solid - out->startSolid = false; + out->startSolid = true; } } } From 86b6184f438ad45b15c849a512b138910c70814c Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 30 Apr 2012 23:55:22 +0200 Subject: [PATCH 12/22] pMove in a seperate loop with fixed timestep to prevent frame-dependent movement --- apps/openmw/mwworld/physicssystem.cpp | 103 +++++++++++++------------- apps/openmw/mwworld/physicssystem.hpp | 10 ++- apps/openmw/mwworld/world.cpp | 53 +++++++++---- apps/openmw/mwworld/world.hpp | 8 +- libs/openengine/bullet/physic.cpp | 2 +- 5 files changed, 102 insertions(+), 74 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 7fe83eeabb..fb13e37c6a 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -21,27 +21,24 @@ 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() { delete mEngine; - + } OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine() { return mEngine; } - + std::pair PhysicsSystem::getFacedHandle (MWWorld::World& world) { std::string handle = ""; @@ -74,7 +71,7 @@ namespace MWWorld if(hasWater){ playerphysics->waterHeight = waterHeight; } - + } btVector3 PhysicsSystem::getRayPoint(float extent) @@ -86,26 +83,23 @@ namespace MWWorld btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y); return result; } - + bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to) { btVector3 _from, _to; _from = btVector3(from.x, from.y, from.z); _to = btVector3(to.x, to.y, to.z); - + std::pair result = mEngine->rayTest(_from, _to); - + return !(result.first == ""); } - - std::vector< std::pair > PhysicsSystem::doPhysics (float duration, - const std::vector >& actors) + void PhysicsSystem::doPhysics(float dt, const std::vector >& actors) { //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++) { @@ -117,8 +111,7 @@ namespace MWWorld 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) @@ -133,29 +126,24 @@ namespace MWWorld Ogre::Node* yawNode = sceneNode->getChildIterator().getNext(); Ogre::Node* pitchNode = yawNode->getChildIterator().getNext(); Ogre::Quaternion yawQuat = yawNode->getOrientation(); - Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); + Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); - // unused - //Ogre::Quaternion both = yawQuat * pitchQuat; - - playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees(); - playerphysics->ps.viewangles.z = 0; + // unused + //Ogre::Quaternion both = yawQuat * pitchQuat; + + playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees(); + playerphysics->ps.viewangles.z = 0; playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90; - - - if(mFreeFly) { - Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); pm_ref.rightmove = -dir1.x; pm_ref.forwardmove = dir1.z; pm_ref.upmove = dir1.y; - - + //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"; @@ -163,46 +151,50 @@ namespace MWWorld } 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; pm_ref.upmove = dir1.y; - - - + + + dir = 0.025*(quat*dir1); } - + //set the walk direction act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y)); } - mEngine->stepSimulation(duration); - Pmove(playerphysics); + mEngine->stepSimulation(dt); + } + + std::vector< std::pair > PhysicsSystem::doPhysicsFixed ( + const std::vector >& actors) + { + 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 << "ZCoord: " << coord.z << "\n"; - //std::cout << "Coord" << coord << "\n"; - //coord = Ogre::Vector3(coord.x, coord.z, coord.y); //x, z, -y - - } - + Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z()); + if(it->first == "player"){ + + coord = playerphysics->ps.origin; + //std::cout << "ZCoord: " << coord.z << "\n"; + //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; } @@ -260,7 +252,14 @@ namespace MWWorld { // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow // start positions others than 0, 0, 0 - act->setPosition(btVector3(position.x,position.y,position.z)); + if (handle == "player") + { + playerphysics->ps.origin = position; + } + else + { + act->setPosition(btVector3(position.x,position.y,position.z)); + } } } @@ -316,7 +315,7 @@ namespace MWWorld } void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){ - + Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); // unused diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index cb559f0007..1af6bcca2f 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -16,8 +16,11 @@ namespace MWWorld PhysicsSystem (OEngine::Render::OgreRenderer &_rend); ~PhysicsSystem (); - std::vector< std::pair > doPhysics (float duration, - const std::vector >& actors); + void doPhysics(float duration, const std::vector >& actors); + ///< do physics with dt - Usage: first call doPhysics with frame dt, then call doPhysicsFixed as often as time steps have passed + + std::vector< std::pair > doPhysicsFixed (const std::vector >& actors); + ///< do physics with fixed timestep - Usage: first call doPhysics with frame dt, then call doPhysicsFixed as often as time steps have passed void addObject (const std::string& handle, const std::string& mesh, const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position); @@ -55,7 +58,7 @@ namespace MWWorld void insertActorPhysics(const MWWorld::Ptr&, std::string model); OEngine::Physic::PhysicEngine* getEngine(); - + void setCurrentWater(bool hasWater, int waterHeight); private: @@ -64,7 +67,6 @@ namespace MWWorld bool mFreeFly; playerMove* playerphysics; - PhysicsSystem (const PhysicsSystem&); PhysicsSystem& operator= (const PhysicsSystem&); }; diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 04bc999a09..adbdaece61 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -215,6 +215,7 @@ namespace MWWorld setFallbackValues(fallbackMap); + lastTick = mTimer.getMilliseconds(); } @@ -559,8 +560,9 @@ namespace MWWorld } } - void World::moveObjectImp (Ptr ptr, float x, float y, float z) + bool World::moveObjectImp (Ptr ptr, float x, float y, float z) { + bool ret = false; ptr.getRefData().getPosition().pos[0] = x; ptr.getRefData().getPosition().pos[1] = y; ptr.getRefData().getPosition().pos[2] = z; @@ -582,6 +584,7 @@ namespace MWWorld if (currentCell->cell->data.gridX!=cellX || currentCell->cell->data.gridY!=cellY) { mWorldScene->changeCell (cellX, cellY, mPlayer->getPlayer().getRefData().getPosition(), false); + ret = true; } } @@ -591,6 +594,8 @@ namespace MWWorld /// \todo cell change for non-player ref mRendering->moveObject (ptr, Ogre::Vector3 (x, y, z)); + + return ret; } void World::moveObject (Ptr ptr, float x, float y, float z) @@ -632,29 +637,45 @@ namespace MWWorld void World::doPhysics (const std::vector >& actors, float duration) { - std::vector< std::pair > vectors = mPhysics->doPhysics (duration, actors); + mPhysics->doPhysics(duration, actors); - std::vector< std::pair >::iterator player = vectors.end(); + const int tick = 16; // 16 ms ^= 60 Hz - for (std::vector< std::pair >::iterator it = vectors.begin(); - it!= vectors.end(); ++it) + // Game clock part of the loop, contains everything that has to be executed in a fixed timestep + long long dt = mTimer.getMilliseconds() - lastTick; + if (dt >= 100) dt = 100; // throw away wall clock time if necessary to keep the framerate above the minimum of 10 fps + while (dt >= tick) { - if (it->first=="player") + dt -= tick; + lastTick += tick; + + std::vector< std::pair > vectors = mPhysics->doPhysicsFixed (actors); + + std::vector< std::pair >::iterator player = vectors.end(); + + for (std::vector< std::pair >::iterator it = vectors.begin(); + it!= vectors.end(); ++it) { - player = it; + if (it->first=="player") + { + player = it; + } + else + { + MWWorld::Ptr ptr = getPtrViaHandle (it->first); + moveObjectImp (ptr, it->second.x, it->second.y, it->second.z); + } } - else + + // Make sure player is moved last (otherwise the cell might change in the middle of an update + // loop) + if (player!=vectors.end()) { - MWWorld::Ptr ptr = getPtrViaHandle (it->first); - moveObjectImp (ptr, it->second.x, it->second.y, it->second.z); + if (moveObjectImp (getPtrViaHandle (player->first), + player->second.x, player->second.y, player->second.z) == true) + return; // abort the current loop if the cell has changed } } - - // Make sure player is moved last (otherwise the cell might change in the middle of an update - // loop) - if (player!=vectors.end()) - moveObjectImp (getPtrViaHandle (player->first), - player->second.x, player->second.y, player->second.z); } bool World::toggleCollisionMode() diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 77e5bcef62..7359f8b902 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -22,6 +22,8 @@ #include #include +#include + namespace Ogre { class Vector3; @@ -100,9 +102,13 @@ namespace MWWorld int mNumFacing; std::map mFallback; + unsigned long lastTick; + Ogre::Timer mTimer; + int getDaysPerMonth (int month) const; - void moveObjectImp (Ptr ptr, float x, float y, float z); + bool moveObjectImp (Ptr ptr, float x, float y, float z); + ///< @return true if the active cell (cell player is in) changed public: diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 3d507d4eee..42853d8cfa 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -393,7 +393,7 @@ namespace Physic void PhysicEngine::stepSimulation(double deltaT) { - dynamicsWorld->stepSimulation(deltaT,10); + dynamicsWorld->stepSimulation(deltaT,10, 1/60.0); if(isDebugCreated) { mDebugDrawer->step(); From b3caf82714d0b1e2f508ac82481e81472fff6f9a Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 1 May 2012 10:12:45 -0700 Subject: [PATCH 13/22] Avoid using vector<>::data(), which requires C++11 --- apps/openmw/mwsound/mpgsnd_decoder.cpp | 2 +- apps/openmw/mwsound/openal_output.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwsound/mpgsnd_decoder.cpp b/apps/openmw/mwsound/mpgsnd_decoder.cpp index 9b91b4e74e..7f7a84889a 100644 --- a/apps/openmw/mwsound/mpgsnd_decoder.cpp +++ b/apps/openmw/mwsound/mpgsnd_decoder.cpp @@ -189,7 +189,7 @@ void MpgSnd_Decoder::readAll(std::vector &output) { size_t pos = output.size(); output.resize(pos + mSndInfo.frames*mSndInfo.channels*2); - sf_readf_short(mSndFile, (short*)(output.data()+pos), mSndInfo.frames); + sf_readf_short(mSndFile, (short*)(&output[0]+pos), mSndInfo.frames); return; } // Fallback in case we don't know the total already diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 615def7019..ac4baa8b29 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -222,8 +222,8 @@ void OpenAL_SoundStream::play() for(ALuint i = 0;i < sNumBuffers;i++) { size_t got; - got = mDecoder->read(data.data(), data.size()); - alBufferData(mBuffers[i], mFormat, data.data(), got, mSampleRate); + got = mDecoder->read(&data[0], data.size()); + alBufferData(mBuffers[i], mFormat, &data[0], got, mSampleRate); } throwALerror(); @@ -299,11 +299,11 @@ bool OpenAL_SoundStream::process() if(finished) continue; - got = mDecoder->read(data.data(), data.size()); + got = mDecoder->read(&data[0], data.size()); finished = (got < data.size()); if(got > 0) { - alBufferData(bufid, mFormat, data.data(), got, mSampleRate); + alBufferData(bufid, mFormat, &data[0], got, mSampleRate); alSourceQueueBuffers(mSource, 1, &bufid); } } while(processed > 0); @@ -595,7 +595,7 @@ ALuint OpenAL_Output::getBuffer(const std::string &fname) alGenBuffers(1, &buf); throwALerror(); - alBufferData(buf, format, data.data(), data.size(), srate); + alBufferData(buf, format, &data[0], data.size(), srate); mBufferCache[fname] = buf; mBufferRefs[buf] = 1; From 6acb777c5a3f085f19314b0e599dec37e9958ceb Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 1 May 2012 20:51:32 +0200 Subject: [PATCH 14/22] minimum framerate fix --- apps/openmw/mwworld/world.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index adbdaece61..4adaf79183 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -643,7 +643,12 @@ namespace MWWorld // Game clock part of the loop, contains everything that has to be executed in a fixed timestep long long dt = mTimer.getMilliseconds() - lastTick; - if (dt >= 100) dt = 100; // throw away wall clock time if necessary to keep the framerate above the minimum of 10 fps + if (dt >= 100) + { + // throw away wall clock time if necessary to keep the framerate above the minimum of 10 fps + lastTick += (dt - 100); + dt = 100; + } while (dt >= tick) { dt -= tick; From 7f15385dc5afa870723a0cf84079740a55ab2a2e Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 1 May 2012 20:58:09 +0200 Subject: [PATCH 15/22] unrelated cleanup --- apps/openmw/engine.cpp | 2 -- apps/openmw/engine.hpp | 1 - 2 files changed, 3 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 539afe1c87..12a5956a98 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -148,7 +148,6 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) , mNewGame (false) , mUseSound (true) , mCompileAll (false) - , mFocusTDiff (0) , mScriptContext (0) , mFSStrict (false) , mCfgMgr(configurationManager) @@ -263,7 +262,6 @@ void OMW::Engine::setNewGame(bool newGame) void OMW::Engine::go() { - mFocusTDiff = 0; assert (!mCellName.empty()); assert (!mMaster.empty()); assert (!mOgre); diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index c834ee438d..09d6bc8201 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -74,7 +74,6 @@ namespace OMW bool mNewGame; bool mUseSound; bool mCompileAll; - float mFocusTDiff; std::string mFocusName; std::map mFallbackMap; From a13f5423965871737c2fbf08e43de5116c4f1d86 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 1 May 2012 21:01:18 +0200 Subject: [PATCH 16/22] disable snapping underwater --- libs/openengine/bullet/pmove.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index e215d8ff63..210f7eb705 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -717,6 +717,8 @@ static void PM_WaterMove( playerMove* const pm ) float scale; float vel; + pm->ps.bSnap = false; + /*if ( PM_CheckWaterJump() ) { PM_WaterJumpMove(); From 6850f3945c9ee82cd00d699e653582ce70ba93ef Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 1 May 2012 21:13:41 +0200 Subject: [PATCH 17/22] disable those physics debug prints --- libs/openengine/bullet/pmove.cpp | 16 +++++++++------- libs/openengine/bullet/pmove.h | 4 ++-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 210f7eb705..35bbd9c033 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -372,7 +372,7 @@ bool PM_SlideMove( bool gravity ) // stop dead at a tripple plane interaction //VectorClear( pm->ps->velocity ); - printf("Stop dead at a triple plane interaction\n"); + //printf("Stop dead at a triple plane interaction\n"); pm->ps.velocity = Ogre::Vector3(0,0,0); return true; } @@ -417,7 +417,7 @@ int PM_StepSlideMove( bool gravity ) Ogre::Vector3 up, down; float stepSize; - std::cout << "StepSlideMove\n"; + //std::cout << "StepSlideMove\n"; // start_o = pm->ps->origin //VectorCopy (pm->ps->origin, start_o); start_o = pm->ps.origin; @@ -517,6 +517,8 @@ int PM_StepSlideMove( bool gravity ) if ( delta > 2 ) { pm->ps.counter = 10; + + /* if (gravity) printf("g on: %f ", delta); else @@ -534,7 +536,7 @@ int PM_StepSlideMove( bool gravity ) else printf("stepped 15+\n"); //PM_AddEvent( EV_STEP_16 ); - + */ } /*if ( pm->debugLevel ) Com_Printf("%i:stepped\n", c_pmove);*/ @@ -863,7 +865,7 @@ static void PM_WalkMove( playerMove* const pmove ) PM_WaterMove(pmove); else PM_AirMove(); - printf("Jumped away\n"); + //printf("Jumped away\n"); return; } @@ -1146,7 +1148,7 @@ void PM_GroundTraceMissed() { traceResults trace; Ogre::Vector3 point; - std::cout << "Ground trace missed\n"; + //std::cout << "Ground trace missed\n"; // we just transitioned into freefall //if ( pm->debugLevel ) //Com_Printf("%i:lift\n", c_pmove); @@ -1292,14 +1294,14 @@ static void PM_CrashLand( void ) 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) { /* diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index 2c61b3e7d7..e46eb9d2e7 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -105,13 +105,13 @@ struct playerMove inline void SpeedUp(void) { - printf("speed up to: %f\n", speed); + //printf("speed up to: %f\n", speed); speed *= 1.25f; } inline void SpeedDown(void) { - printf("speed down to %f\n", speed); + //printf("speed down to %f\n", speed); speed /= 1.25f; } From 04ead5eb42e67b1346f8e5055d16d37d8fa06741 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 1 May 2012 21:22:15 +0200 Subject: [PATCH 18/22] make the no-clip mode move much faster --- libs/openengine/bullet/pmove.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 35bbd9c033..591f1869f8 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -636,7 +636,7 @@ float PM_CmdScale(playerMove::playercmd* const cmd) + cmd->rightmove * cmd->rightmove + cmd->upmove * cmd->upmove) ); scale = (float)pm->ps.speed * max / ( 127.0f * total ); if(pm->ps.move_type == PM_NOCLIP) - scale *= 2; + scale *= 10; return scale; } From 144d52cf495a93aa7eb7204fd580ff0f9cf0f472 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 1 May 2012 20:30:31 -0700 Subject: [PATCH 19/22] Add voices to the chargen class questions --- apps/openmw/mwgui/charactercreation.cpp | 16 +++++++++++ apps/openmw/mwsound/soundmanager.cpp | 36 +++++++++++++++++++++++++ apps/openmw/mwsound/soundmanager.hpp | 11 ++++++-- 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index 9a23758558..10c4cdcb4f 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -9,6 +9,7 @@ #include "mode.hpp" #include "../mwbase/environment.hpp" +#include "../mwsound/soundmanager.hpp" namespace { @@ -16,6 +17,7 @@ namespace { const char* mText; const char* mButtons[3]; + const char* mSound; ESM::Class::Specialization mSpecializations[3]; // The specialization for each answer }; @@ -25,6 +27,7 @@ namespace {"Draw your dagger, mercifully endings its life with a single thrust.", "Use herbs from your pack to put it to sleep.", "Do not interfere in the natural evolution of events, but rather take the opportunity to learn more about a strange animal that you have never seen before."}, + "vo\\misc\\chargen qa1.wav", {ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth} }, // Question 2 @@ -32,6 +35,7 @@ namespace {"Work in the forge with him casting iron for a new plow.", "Gather herbs for your mother who is preparing dinner.", "Go catch fish at the stream using a net and line."}, + "vo\\misc\\chargen qa2.wav", {ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth} }, // Question 3 @@ -39,6 +43,7 @@ namespace {"Beat up your cousin, then tell him that if he ever calls you that nickname again, you will bloody him worse than this time.", "Make up a story that makes your nickname a badge of honor instead of something humiliating.", "Make up an even more embarrassing nickname for him and use it constantly until he learns his lesson."}, + "vo\\misc\\chargen qa3.wav", {ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth} }, // Question 4 @@ -46,6 +51,7 @@ namespace {"This is a terrible practice. A person's thoughts are his own and no one, not even a king, has the right to make such an invasion into another human's mind.", "Loyal followers to the king have nothing to fear from a Telepath. It is important to have a method of finding assassins and spies before it is too late.", "In these times, it is a necessary evil. Although you do not necessarily like the idea, a Telepath could have certain advantages during a time of war or in finding someone innocent of a crime."}, + "vo\\misc\\chargen qa4.wav", {ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth} }, // Question 5 @@ -53,6 +59,7 @@ namespace {"Return to the store and give the shopkeeper his hard-earned money, explaining to him the mistake?", "Decide to put the extra money to good use and purchase items that would help your family?", "Pocket the extra money, knowing that shopkeepers in general tend to overcharge customers anyway?"}, + "vo\\misc\\chargen qa5.wav", {ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth} }, // Question 6 @@ -60,6 +67,7 @@ namespace {"Pick up the bag and signal to the guard, knowing that the only honorable thing to do is return the money to its rightful owner.", "Leave the bag there, knowing that it is better not to get involved.", "Pick up the bag and pocket it, knowing that the extra windfall will help your family in times of trouble."}, + "vo\\misc\\chargen qa6.wav", {ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth} }, // Question 7 @@ -67,6 +75,7 @@ namespace {"Decline his offer, knowing that your father expects you to do the work, and it is better not to be in debt.", "Ask him to help you, knowing that two people can do the job faster than one, and agree to help him with one task of his choosing in the future.", "Accept his offer, reasoning that as long as the stables are cleaned, it matters not who does the cleaning."}, + "vo\\misc\\chargen qa7.wav", {ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth} }, // Question 8 @@ -74,6 +83,7 @@ namespace {"Position yourself between the pipe and your mother.", "Grab the hot pipe and try to push it away.", "Push your mother out of the way."}, + "vo\\misc\\chargen qa8.wav", {ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth} }, // Question 9 @@ -81,6 +91,7 @@ namespace {"Drop the sweetroll and step on it, then get ready for the fight.", "Give him the sweetroll now without argument, knowing that later this afternoon you will have all your friends with you and can come and take whatever he owes you.", "Act like you're going to give him the sweetroll, but at the last minute throw it in the air, hoping that they'll pay attention to it long enough for you to get a shot in on the leader."}, + "vo\\misc\\chargen qa9.wav", {ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth} }, // Question 10 @@ -88,6 +99,7 @@ namespace {"Rush to the town's aid immediately, despite your lack of knowledge of the circumstances.", "Stand aside and allow the man and the mob to pass, realizing it is probably best not to get involved.", "Rush to the man's aid immediately, despite your lack of knowledge of the circumstances."}, + "vo\\misc\\chargen qa10.wav", {ESM::Class::Combat, ESM::Class::Magic, ESM::Class::Stealth} } } }; @@ -479,6 +491,8 @@ void CharacterCreation::onCreateClassDialogBack() void CharacterCreation::onClassQuestionChosen(int _index) { + MWBase::Environment::get().getSoundManager()->stopSay(); + if (mGenerateClassQuestionDialog) mWM->removeDialog(mGenerateClassQuestionDialog); if (_index < 0 || _index >= 3) @@ -584,6 +598,8 @@ void CharacterCreation::showClassQuestionDialog() mGenerateClassQuestionDialog->setButtons(buttons); mGenerateClassQuestionDialog->eventButtonSelected += MyGUI::newDelegate(this, &CharacterCreation::onClassQuestionChosen); mGenerateClassQuestionDialog->open(); + + MWBase::Environment::get().getSoundManager()->say(sGenerateClassSteps[mGenerateClassStep].mSound); } void CharacterCreation::onGenerateClassBack() diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index 4656efb6ed..9eefc7a28d 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -228,11 +228,47 @@ namespace MWSound } } + void SoundManager::say(const std::string& filename) + { + if(!mOutput->isInitialized()) + return; + try + { + float basevol = mMasterVolume * mSFXVolume; + std::string filePath = "Sound/"+filename; + + SoundPtr sound = mOutput->playSound(filePath, basevol, 1.0f, Play_Normal); + sound->mBaseVolume = basevol; + + mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), std::string("_say_sound")); + } + catch(std::exception &e) + { + std::cout <<"Sound Error: "<second.first == ptr && snditer->second.second == "_say_sound") + { + snditer->first->stop(); + mActiveSounds.erase(snditer++); + } + else + snditer++; + } + } + + SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, int mode) { diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index 8afd488e11..e1816cd1f3 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -97,11 +97,18 @@ namespace MWSound void say(MWWorld::Ptr reference, const std::string& filename); ///< Make an actor say some text. - /// \param filename name of a sound file in "Sound/Vo/" in the data directory. + /// \param filename name of a sound file in "Sound/" in the data directory. - bool sayDone(MWWorld::Ptr reference) const; + void say(const std::string& filename); + ///< Say some text, without an actor ref + /// \param filename name of a sound file in "Sound/" in the data directory. + + bool sayDone(MWWorld::Ptr reference=MWWorld::Ptr()) const; ///< Is actor not speaking? + void stopSay(MWWorld::Ptr reference=MWWorld::Ptr()); + ///< Stop an actor speaking + SoundPtr playSound(const std::string& soundId, float volume, float pitch, int mode=Play_Normal); ///< Play a sound, independently of 3D-position From c4b63bdb2fdb98afc809778c1c06a87119c02ffc Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 2 May 2012 23:27:56 +0200 Subject: [PATCH 20/22] .gitmodules --- libs/openengine/.gitmodules | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 libs/openengine/.gitmodules diff --git a/libs/openengine/.gitmodules b/libs/openengine/.gitmodules deleted file mode 100644 index 0a9a9121fd..0000000000 --- a/libs/openengine/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "mangle"] - path = mangle - url = git://github.com/korslund/mangle From dc378fc6cfc5e0ad01a7cf6d8e636ed7b32f06fb Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 3 May 2012 06:07:41 +0200 Subject: [PATCH 21/22] allow talking with creatures --- apps/openmw/mwdialogue/dialoguemanager.cpp | 48 ++++++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index ac41244d1c..282fba3543 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -161,6 +161,8 @@ namespace MWDialogue bool DialogueManager::functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice) { + bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name()); + for (std::vector::const_iterator iter (info.selects.begin()); iter != info.selects.end(); ++iter) { @@ -195,6 +197,9 @@ namespace MWDialogue case 46://Same faction { + if (isCreature) + return false; + MWMechanics::NpcStats PCstats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); MWMechanics::NpcStats NPCstats = MWWorld::Class::get(actor).getNpcStats(actor); int sameFaction = 0; @@ -283,6 +288,8 @@ namespace MWDialogue bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const { + bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name()); + char type = select.selectRule[1]; if (type!='0') @@ -380,6 +387,9 @@ namespace MWDialogue return true; case '8':// not faction + if (isCreature) + return false; + if(select.type==ESM::VT_Int) { ESMS::LiveCellRef* npc = actor.get(); @@ -394,6 +404,9 @@ namespace MWDialogue return true; case '9':// not class + if (isCreature) + return false; + if(select.type==ESM::VT_Int) { ESMS::LiveCellRef* npc = actor.get(); @@ -408,6 +421,9 @@ namespace MWDialogue return true; case 'A'://not Race + if (isCreature) + return false; + if(select.type==ESM::VT_Int) { ESMS::LiveCellRef* npc = actor.get(); @@ -464,6 +480,8 @@ namespace MWDialogue bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const { + bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name()); + // actor id if (!info.actor.empty()) if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor)) @@ -472,6 +490,9 @@ namespace MWDialogue //NPC race if (!info.race.empty()) { + if (isCreature) + return false; + ESMS::LiveCellRef *cellRef = actor.get(); if (!cellRef) @@ -484,6 +505,9 @@ namespace MWDialogue //NPC class if (!info.clas.empty()) { + if (isCreature) + return false; + ESMS::LiveCellRef *cellRef = actor.get(); if (!cellRef) @@ -496,6 +520,9 @@ namespace MWDialogue //NPC faction if (!info.npcFaction.empty()) { + if (isCreature) + return false; + //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); @@ -529,16 +556,18 @@ namespace MWDialogue } //check gender - ESMS::LiveCellRef* npc = actor.get(); - if(npc->base->flags&npc->base->Female) + if (!isCreature) { - if(static_cast (info.data.gender)==0) return false; + ESMS::LiveCellRef* npc = actor.get(); + if(npc->base->flags&npc->base->Female) + { + if(static_cast (info.data.gender)==0) return false; + } + else + { + if(static_cast (info.data.gender)==1) return false; + } } - else - { - if(static_cast (info.data.gender)==1) return false; - } - // check cell if (!info.cell.empty()) @@ -839,6 +868,9 @@ namespace MWDialogue std::string DialogueManager::getFaction() { + if (mActor.getTypeName() != typeid(ESM::NPC).name()) + return ""; + std::string factionID(""); MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mActor); if(stats.mFactionRank.empty()) From b653f047acfbe61f0d7b4b21f8548e1ee3202c5a Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 3 May 2012 09:15:56 +0200 Subject: [PATCH 22/22] removed a file that wasn't supposed to be there --- apps/openmw/physicssystem.cpp | 225 ---------------------------------- 1 file changed, 225 deletions(-) delete mode 100644 apps/openmw/physicssystem.cpp diff --git a/apps/openmw/physicssystem.cpp b/apps/openmw/physicssystem.cpp deleted file mode 100644 index a07358f8ee..0000000000 --- a/apps/openmw/physicssystem.cpp +++ /dev/null @@ -1,225 +0,0 @@ -#include - -#include "physicssystem.hpp" -#include "../mwworld/ptr.hpp" -#include "../mwworld/world.hpp" // FIXME -#include - -#include "OgreRoot.h" -#include "OgreRenderWindow.h" -#include "OgreSceneManager.h" -#include "OgreViewport.h" -#include "OgreCamera.h" -#include "OgreTextureManager.h" - - -using namespace Ogre; -namespace MWWorld -{ - - PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) : - mRender(_rend), mEngine(0), mFreeFly (true) - { - // Create physics. shapeLoader is deleted by the physic engine - NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader(); - mEngine = new OEngine::Physic::PhysicEngine(shapeLoader); - } - - PhysicsSystem::~PhysicsSystem() - { - delete mEngine; - - } - OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine() - { - return mEngine; - } - - std::pair PhysicsSystem::getFacedHandle (MWWorld::World& world) - { - std::string handle = ""; - - //get a ray pointing to the center of the viewport - Ray centerRay = mRender.getCamera()->getCameraToViewportRay( - mRender.getViewport()->getWidth()/2, - mRender.getViewport()->getHeight()/2); - //let's avoid the capsule shape of the player. - centerRay.setOrigin(centerRay.getOrigin() + 20*centerRay.getDirection()); - btVector3 from(centerRay.getOrigin().x,-centerRay.getOrigin().z,centerRay.getOrigin().y); - btVector3 to(centerRay.getPoint(500).x,-centerRay.getPoint(500).z,centerRay.getPoint(500).y); - - return mEngine->rayTest(from,to); - } - - bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to) - { - btVector3 _from, _to; - _from = btVector3(from.x, from.y, from.z); - _to = btVector3(to.x, to.y, to.z); - - std::pair result = mEngine->rayTest(_from, _to); - - return !(result.first == ""); - } - - - std::vector< std::pair > PhysicsSystem::doPhysics (float duration, - const std::vector >& actors) - { - //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)); - } - - for (std::vector >::const_iterator iter (actors.begin()); - iter!=actors.end(); ++iter) - { - OEngine::Physic::PhysicActor* act = mEngine->getCharacter(iter->first); - - //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(); - if(mFreeFly) - { - Ogre::Quaternion yawQuat = yawNode->getOrientation(); - Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); - Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); - dir = 0.07*(yawQuat*pitchQuat*dir1); - } - else - { - Ogre::Quaternion quat = yawNode->getOrientation(); - Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); - dir = 0.025*(quat*dir1); - } - - //set the walk direction - act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y)); - } - 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()); - - 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) - { - OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale); - mEngine->addRigidBody(body); - btTransform tr; - tr.setOrigin(btVector3(position.x,position.y,position.z)); - std::cout << "Position object:" << position << "\n"; - tr.setRotation(btQuaternion(rotation.x,rotation.y,rotation.z,rotation.w)); - body->setWorldTransform(tr); - } - - void PhysicsSystem::addActor (const std::string& handle, const std::string& mesh, - const Ogre::Vector3& position) - { - //TODO:optimize this. Searching the std::map isn't very efficient i think. - mEngine->addCharacter(handle); - OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle); - act->setPosition(btVector3(position.x,position.y,position.z)); - } - - void PhysicsSystem::removeObject (const std::string& handle) - { - //TODO:check if actor??? - mEngine->removeCharacter(handle); - mEngine->removeRigidBody(handle); - mEngine->deleteRigidBody(handle); - } - - void PhysicsSystem::moveObject (const std::string& handle, const Ogre::Vector3& position) - { - if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) - { - // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow - // start positions others than 0, 0, 0 - btTransform tr = body->getWorldTransform(); - tr.setOrigin(btVector3(position.x,position.y,position.z)); - body->setWorldTransform(tr); - } - if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) - { - // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow - // start positions others than 0, 0, 0 - act->setPosition(btVector3(position.x,position.y,position.z)); - } - } - - void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation) - { - if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) - { - // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow - // start positions others than 0, 0, 0 - act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); - } - } - - void PhysicsSystem::scaleObject (const std::string& handle, float scale) - { - - } - - bool PhysicsSystem::toggleCollisionMode() - { - for(std::map::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) - { - if (it->first=="player") - { - OEngine::Physic::PhysicActor* act = it->second; - - bool cmode = act->getCollisionMode(); - if(cmode) - { - act->enableCollisions(false); - act->setGravity(0.); - act->setVerticalVelocity(0); - mFreeFly = true; - return false; - } - else - { - mFreeFly = false; - act->enableCollisions(true); - act->setGravity(4.); - act->setVerticalVelocity(0); - return true; - } - } - } - - throw std::logic_error ("can't find player"); - } - - void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){ - Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); - addObject (node->getName(), model, node->getOrientation(), - node->getScale().x, node->getPosition()); - } - - void PhysicsSystem::insertActorPhysics(const MWWorld::Ptr& ptr, const std::string model){ - Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); - // std::cout << "Adding node with name" << node->getName(); - addActor (node->getName(), model, node->getPosition()); - } - -}