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 83a94d27d..522fce3a3 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 88534ddda..074f8a906 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 a555ac010..11eb83151 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 717064ada..0d19a3013 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 11a43c7d3..d54f4696a 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 5bfb82138..884a72c3a 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 01c71da43..da74fe6de 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 000000000..a07358f8e --- /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 07bad3053..911f6279b 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 45fe84f4f..71c15fe45 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 e90cc3b35..5dfd18f6d 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 49e12064e..57d071f17 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 000000000..90afc4e78 --- /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 000000000..9353f7cd1 --- /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 d54f4696a..15d2d3f9f 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 71c15fe45..8dd01ef19 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 57d071f17..8f2423c24 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 90afc4e78..000000000 --- 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 9353f7cd1..000000000 --- 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 8dd01ef19..d8880a49f 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 8f2423c24..18a668e55 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 522fce3a3..8bb394129 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 15d2d3f9f..fdcee417f 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 d8880a49f..8fb72aa1f 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 5dfd18f6d..30572a92a 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 18a668e55..ca68a5d5c 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 79e7d565d..205d66cd7 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 8fb72aa1f..dcb2e9f9b 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 025673ab7..fb666b6eb 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 29c65b411..98c15e338 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 8fb72aa1f..86d069273 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 30572a92a..304572b02 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 98c15e338..d224385ae 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 fb15a1486..2d73cab27 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 2123b4799..5244d53f8 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 86d069273..214a7e598 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 214a7e598..7741d2f04 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 d224385ae..9af7a7285 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 7741d2f04..82f473085 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 304572b02..a14a1e660 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 9af7a7285..63bf8dda3 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 82f473085..922fd844c 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 ca68a5d5c..81c064c2d 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 7fe83eeab..fb13e37c6 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 cb559f000..1af6bcca2 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 04bc999a0..adbdaece6 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 77e5bcef6..7359f8b90 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 3d507d4ee..42853d8cf 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 9b91b4e74..7f7a84889 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 615def701..ac4baa8b2 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 adbdaece6..4adaf7918 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 539afe1c8..12a5956a9 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 c834ee438..09d6bc820 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 e215d8ff6..210f7eb70 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 210f7eb70..35bbd9c03 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 2c61b3e7d..e46eb9d2e 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 35bbd9c03..591f1869f 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 9a2375855..10c4cdcb4 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 4656efb6e..9eefc7a28 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 8afd488e1..e1816cd1f 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 0a9a9121f..000000000 --- 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 ac41244d1..282fba354 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 a07358f8e..000000000 --- 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()); - } - -}