mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 07:23:51 +00:00
Merge remote branch 'scrawl/physicsaedra2'
This commit is contained in:
commit
1149e282b8
20 changed files with 2789 additions and 81 deletions
|
@ -122,6 +122,10 @@ set(OENGINE_BULLET
|
||||||
${LIBDIR}/openengine/bullet/physic.hpp
|
${LIBDIR}/openengine/bullet/physic.hpp
|
||||||
${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp
|
${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp
|
||||||
${LIBDIR}/openengine/bullet/BulletShapeLoader.h
|
${LIBDIR}/openengine/bullet/BulletShapeLoader.h
|
||||||
|
${LIBDIR}/openengine/bullet/pmove.cpp
|
||||||
|
${LIBDIR}/openengine/bullet/pmove.h
|
||||||
|
${LIBDIR}/openengine/bullet/trace.cpp
|
||||||
|
${LIBDIR}/openengine/bullet/trace.h
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,6 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
|
||||||
, mNewGame (false)
|
, mNewGame (false)
|
||||||
, mUseSound (true)
|
, mUseSound (true)
|
||||||
, mCompileAll (false)
|
, mCompileAll (false)
|
||||||
, mFocusTDiff (0)
|
|
||||||
, mScriptContext (0)
|
, mScriptContext (0)
|
||||||
, mFSStrict (false)
|
, mFSStrict (false)
|
||||||
, mCfgMgr(configurationManager)
|
, mCfgMgr(configurationManager)
|
||||||
|
@ -263,7 +262,6 @@ void OMW::Engine::setNewGame(bool newGame)
|
||||||
|
|
||||||
void OMW::Engine::go()
|
void OMW::Engine::go()
|
||||||
{
|
{
|
||||||
mFocusTDiff = 0;
|
|
||||||
assert (!mCellName.empty());
|
assert (!mCellName.empty());
|
||||||
assert (!mMaster.empty());
|
assert (!mMaster.empty());
|
||||||
assert (!mOgre);
|
assert (!mOgre);
|
||||||
|
|
|
@ -74,7 +74,6 @@ namespace OMW
|
||||||
bool mNewGame;
|
bool mNewGame;
|
||||||
bool mUseSound;
|
bool mUseSound;
|
||||||
bool mCompileAll;
|
bool mCompileAll;
|
||||||
float mFocusTDiff;
|
|
||||||
std::string mFocusName;
|
std::string mFocusName;
|
||||||
std::map<std::string,std::string> mFallbackMap;
|
std::map<std::string,std::string> mFallbackMap;
|
||||||
|
|
||||||
|
|
|
@ -287,11 +287,12 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
Ogre::Vector3 vector (0, 0, 0);
|
Ogre::Vector3 vector (0, 0, 0);
|
||||||
|
|
||||||
vector.x = - getMovementSettings (ptr).mLeftRight * 200;
|
vector.x = - getMovementSettings (ptr).mLeftRight * 127;
|
||||||
vector.y = getMovementSettings (ptr).mForwardBackward * 200;
|
vector.y = getMovementSettings (ptr).mForwardBackward * 127;
|
||||||
|
vector.z = getMovementSettings(ptr).mUpDown * 127;
|
||||||
|
|
||||||
if (getStance (ptr, Run, false))
|
//if (getStance (ptr, Run, false))
|
||||||
vector *= 2;
|
// vector *= 2;
|
||||||
|
|
||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ namespace MWInput
|
||||||
A_CycleWeaponRight,
|
A_CycleWeaponRight,
|
||||||
A_ToggleSneak, //Toggles Sneak, add Push-Sneak later
|
A_ToggleSneak, //Toggles Sneak, add Push-Sneak later
|
||||||
A_ToggleWalk, //Toggle Walking/Running
|
A_ToggleWalk, //Toggle Walking/Running
|
||||||
|
A_Crouch,
|
||||||
|
|
||||||
A_QuickSave,
|
A_QuickSave,
|
||||||
A_QuickLoad,
|
A_QuickLoad,
|
||||||
|
@ -310,6 +311,9 @@ namespace MWInput
|
||||||
poller.bind(A_MoveRight, KC_D);
|
poller.bind(A_MoveRight, KC_D);
|
||||||
poller.bind(A_MoveForward, KC_W);
|
poller.bind(A_MoveForward, KC_W);
|
||||||
poller.bind(A_MoveBackward, KC_S);
|
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
|
//NOTE: Used to check for movement keys
|
||||||
|
@ -356,6 +360,13 @@ namespace MWInput
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
player.setForwardBackward (0);
|
player.setForwardBackward (0);
|
||||||
|
|
||||||
|
if (poller.isDown(A_Jump))
|
||||||
|
player.setUpDown (1);
|
||||||
|
else if (poller.isDown(A_Crouch))
|
||||||
|
player.setUpDown (-1);
|
||||||
|
else
|
||||||
|
player.setUpDown (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch between gui modes. Besides controlling the Gui windows
|
// Switch between gui modes. Besides controlling the Gui windows
|
||||||
|
|
|
@ -8,8 +8,9 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
signed char mLeftRight; // 1: wants to move left, -1: wants to move right
|
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 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) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,11 @@ void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
|
||||||
|
|
||||||
Ogre::SceneNode* insert = cellnode->createChildSceneNode();
|
Ogre::SceneNode* insert = cellnode->createChildSceneNode();
|
||||||
const float *f = ptr.getRefData().getPosition().pos;
|
const float *f = ptr.getRefData().getPosition().pos;
|
||||||
|
|
||||||
insert->setPosition(f[0], f[1], f[2]);
|
insert->setPosition(f[0], f[1], f[2]);
|
||||||
insert->setScale(ptr.getCellRef().scale, ptr.getCellRef().scale, ptr.getCellRef().scale);
|
insert->setScale(ptr.getCellRef().scale, ptr.getCellRef().scale, ptr.getCellRef().scale);
|
||||||
|
|
||||||
|
|
||||||
// Convert MW rotation to a quaternion:
|
// Convert MW rotation to a quaternion:
|
||||||
f = ptr.getCellRef().pos.rot;
|
f = ptr.getCellRef().pos.rot;
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,11 @@ namespace MWWorld
|
||||||
mRender(_rend), mEngine(0), mFreeFly (true)
|
mRender(_rend), mEngine(0), mFreeFly (true)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
playerphysics = new playerMove;
|
||||||
// Create physics. shapeLoader is deleted by the physic engine
|
// Create physics. shapeLoader is deleted by the physic engine
|
||||||
NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
|
NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
|
||||||
mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
|
mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
|
||||||
|
playerphysics->mEngine = mEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicsSystem::~PhysicsSystem()
|
PhysicsSystem::~PhysicsSystem()
|
||||||
|
@ -65,6 +66,13 @@ namespace MWWorld
|
||||||
|
|
||||||
return mEngine->rayTest2(from,to);
|
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)
|
btVector3 PhysicsSystem::getRayPoint(float extent)
|
||||||
{
|
{
|
||||||
|
@ -87,22 +95,22 @@ namespace MWWorld
|
||||||
return !(result.first == "");
|
return !(result.first == "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicsSystem::doPhysics(float dt, const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
|
||||||
std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysics (float duration,
|
|
||||||
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
|
|
||||||
{
|
{
|
||||||
//set the DebugRenderingMode. To disable it,set it to 0
|
//set the DebugRenderingMode. To disable it,set it to 0
|
||||||
//eng->setDebugRenderingMode(1);
|
//eng->setDebugRenderingMode(1);
|
||||||
|
|
||||||
|
|
||||||
//set the walkdirection to 0 (no movement) for every actor)
|
//set the walkdirection to 0 (no movement) for every actor)
|
||||||
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
|
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
|
||||||
{
|
{
|
||||||
OEngine::Physic::PhysicActor* act = it->second;
|
OEngine::Physic::PhysicActor* act = it->second;
|
||||||
act->setWalkDirection(btVector3(0,0,0));
|
act->setWalkDirection(btVector3(0,0,0));
|
||||||
}
|
}
|
||||||
|
playerMove::playercmd& pm_ref = playerphysics->cmd;
|
||||||
|
|
||||||
|
pm_ref.rightmove = 0;
|
||||||
|
pm_ref.forwardmove = 0;
|
||||||
|
pm_ref.upmove = 0;
|
||||||
|
|
||||||
//playerphysics->ps.move_type = PM_NOCLIP;
|
//playerphysics->ps.move_type = PM_NOCLIP;
|
||||||
for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
|
for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
|
||||||
|
@ -119,18 +127,21 @@ namespace MWWorld
|
||||||
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
|
Ogre::Node* pitchNode = yawNode->getChildIterator().getNext();
|
||||||
Ogre::Quaternion yawQuat = yawNode->getOrientation();
|
Ogre::Quaternion yawQuat = yawNode->getOrientation();
|
||||||
Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
|
Ogre::Quaternion pitchQuat = pitchNode->getOrientation();
|
||||||
Ogre::Quaternion both = yawQuat * pitchQuat;
|
|
||||||
|
|
||||||
|
// unused
|
||||||
|
//Ogre::Quaternion both = yawQuat * pitchQuat;
|
||||||
|
|
||||||
//playerphysics->ps.viewangles.z = both.getPitch().valueDegrees();
|
playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
|
||||||
|
playerphysics->ps.viewangles.z = 0;
|
||||||
|
playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
|
||||||
|
|
||||||
if(mFreeFly)
|
if(mFreeFly)
|
||||||
{
|
{
|
||||||
|
|
||||||
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
|
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";
|
//std::cout << "Current angle" << yawQuat.getYaw().valueDegrees() - 90<< "\n";
|
||||||
|
@ -140,9 +151,15 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
Ogre::Quaternion quat = yawNode->getOrientation();
|
Ogre::Quaternion quat = yawNode->getOrientation();
|
||||||
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
|
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);
|
dir = 0.025*(quat*dir1);
|
||||||
}
|
}
|
||||||
|
@ -151,7 +168,13 @@ namespace MWWorld
|
||||||
//set the walk direction
|
//set the walk direction
|
||||||
act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y));
|
act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y));
|
||||||
}
|
}
|
||||||
mEngine->stepSimulation(duration);
|
mEngine->stepSimulation(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysicsFixed (
|
||||||
|
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
|
||||||
|
{
|
||||||
|
Pmove(playerphysics);
|
||||||
|
|
||||||
std::vector< std::pair<std::string, Ogre::Vector3> > response;
|
std::vector< std::pair<std::string, Ogre::Vector3> > response;
|
||||||
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
|
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
|
||||||
|
@ -159,12 +182,34 @@ namespace MWWorld
|
||||||
btVector3 newPos = it->second->getPosition();
|
btVector3 newPos = it->second->getPosition();
|
||||||
|
|
||||||
Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z());
|
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<std::string, Ogre::Vector3>(it->first, coord));
|
response.push_back(std::pair<std::string, Ogre::Vector3>(it->first, coord));
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicsSystem::addHeightField (float* heights,
|
||||||
|
int x, int y, float yoffset,
|
||||||
|
float triSize, float sqrtVerts)
|
||||||
|
{
|
||||||
|
mEngine->addHeightField(heights, x, y, yoffset, triSize, sqrtVerts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicsSystem::removeHeightField (int x, int y)
|
||||||
|
{
|
||||||
|
mEngine->removeHeightField(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh,
|
void PhysicsSystem::addObject (const std::string& handle, const std::string& mesh,
|
||||||
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
|
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
|
||||||
{
|
{
|
||||||
|
@ -207,9 +252,16 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
|
// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
|
||||||
// start positions others than 0, 0, 0
|
// start positions others than 0, 0, 0
|
||||||
|
if (handle == "player")
|
||||||
|
{
|
||||||
|
playerphysics->ps.origin = position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
act->setPosition(btVector3(position.x,position.y,position.z));
|
act->setPosition(btVector3(position.x,position.y,position.z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation)
|
void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation)
|
||||||
{
|
{
|
||||||
|
@ -228,6 +280,11 @@ namespace MWWorld
|
||||||
|
|
||||||
bool PhysicsSystem::toggleCollisionMode()
|
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<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
|
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
|
||||||
{
|
{
|
||||||
if (it->first=="player")
|
if (it->first=="player")
|
||||||
|
@ -258,7 +315,12 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){
|
void PhysicsSystem::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string model){
|
||||||
|
|
||||||
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
|
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
|
||||||
|
|
||||||
|
// unused
|
||||||
|
//Ogre::Vector3 objPos = node->getPosition();
|
||||||
|
|
||||||
addObject (node->getName(), model, node->getOrientation(),
|
addObject (node->getName(), model, node->getOrientation(),
|
||||||
node->getScale().x, node->getPosition());
|
node->getScale().x, node->getPosition());
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <openengine/ogre/renderer.hpp>
|
#include <openengine/ogre/renderer.hpp>
|
||||||
#include <openengine/bullet/physic.hpp>
|
#include <openengine/bullet/physic.hpp>
|
||||||
#include "ptr.hpp"
|
#include "ptr.hpp"
|
||||||
|
#include <openengine/bullet/pmove.h>
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
@ -15,8 +16,11 @@ namespace MWWorld
|
||||||
PhysicsSystem (OEngine::Render::OgreRenderer &_rend);
|
PhysicsSystem (OEngine::Render::OgreRenderer &_rend);
|
||||||
~PhysicsSystem ();
|
~PhysicsSystem ();
|
||||||
|
|
||||||
std::vector< std::pair<std::string, Ogre::Vector3> > doPhysics (float duration,
|
void doPhysics(float duration, const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
|
||||||
const std::vector<std::pair<std::string, Ogre::Vector3> >& 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<std::string, Ogre::Vector3> > doPhysicsFixed (const std::vector<std::pair<std::string, Ogre::Vector3> >& 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,
|
void addObject (const std::string& handle, const std::string& mesh,
|
||||||
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position);
|
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position);
|
||||||
|
@ -24,6 +28,12 @@ namespace MWWorld
|
||||||
void addActor (const std::string& handle, const std::string& mesh,
|
void addActor (const std::string& handle, const std::string& mesh,
|
||||||
const Ogre::Vector3& position);
|
const Ogre::Vector3& position);
|
||||||
|
|
||||||
|
void addHeightField (float* heights,
|
||||||
|
int x, int y, float yoffset,
|
||||||
|
float triSize, float sqrtVerts);
|
||||||
|
|
||||||
|
void removeHeightField (int x, int y);
|
||||||
|
|
||||||
void removeObject (const std::string& handle);
|
void removeObject (const std::string& handle);
|
||||||
|
|
||||||
void moveObject (const std::string& handle, const Ogre::Vector3& position);
|
void moveObject (const std::string& handle, const Ogre::Vector3& position);
|
||||||
|
@ -49,11 +59,13 @@ namespace MWWorld
|
||||||
|
|
||||||
OEngine::Physic::PhysicEngine* getEngine();
|
OEngine::Physic::PhysicEngine* getEngine();
|
||||||
|
|
||||||
|
void setCurrentWater(bool hasWater, int waterHeight);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OEngine::Render::OgreRenderer &mRender;
|
OEngine::Render::OgreRenderer &mRender;
|
||||||
OEngine::Physic::PhysicEngine* mEngine;
|
OEngine::Physic::PhysicEngine* mEngine;
|
||||||
bool mFreeFly;
|
bool mFreeFly;
|
||||||
|
playerMove* playerphysics;
|
||||||
|
|
||||||
PhysicsSystem (const PhysicsSystem&);
|
PhysicsSystem (const PhysicsSystem&);
|
||||||
PhysicsSystem& operator= (const PhysicsSystem&);
|
PhysicsSystem& operator= (const PhysicsSystem&);
|
||||||
|
|
|
@ -85,6 +85,14 @@ namespace MWWorld
|
||||||
|
|
||||||
MWWorld::Class::get (ptr).getMovementSettings (ptr).mForwardBackward = value;
|
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()
|
void Player::toggleRunning()
|
||||||
{
|
{
|
||||||
|
@ -100,4 +108,5 @@ namespace MWWorld
|
||||||
MWWorld::Ptr ptr = getPlayer();
|
MWWorld::Ptr ptr = getPlayer();
|
||||||
return MWWorld::Class::get(ptr).getNpcStats(ptr).mDrawState;
|
return MWWorld::Class::get(ptr).getNpcStats(ptr).mDrawState;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,6 +116,7 @@ namespace MWWorld
|
||||||
void setLeftRight (int value);
|
void setLeftRight (int value);
|
||||||
|
|
||||||
void setForwardBackward (int value);
|
void setForwardBackward (int value);
|
||||||
|
void setUpDown(int value);
|
||||||
|
|
||||||
void toggleRunning();
|
void toggleRunning();
|
||||||
};
|
};
|
||||||
|
|
|
@ -75,11 +75,14 @@ namespace MWWorld
|
||||||
|
|
||||||
|
|
||||||
// silence annoying g++ warning
|
// silence annoying g++ warning
|
||||||
for (std::vector<Ogre::SceneNode*>::const_iterator iter (functor.mHandles.begin());
|
for (std::vector<Ogre::SceneNode*>::const_iterator iter2 (functor.mHandles.begin());
|
||||||
iter!=functor.mHandles.end(); ++iter){
|
iter2!=functor.mHandles.end(); ++iter2){
|
||||||
Ogre::SceneNode* node = *iter;
|
Ogre::SceneNode* node = *iter2;
|
||||||
mPhysics->removeObject (node->getName());
|
mPhysics->removeObject (node->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!((*iter)->cell->data.flags & ESM::Cell::Interior))
|
||||||
|
mPhysics->removeHeightField( (*iter)->cell->data.gridX, (*iter)->cell->data.gridY );
|
||||||
}
|
}
|
||||||
|
|
||||||
mRendering.removeCell(*iter);
|
mRendering.removeCell(*iter);
|
||||||
|
@ -103,20 +106,36 @@ namespace MWWorld
|
||||||
|
|
||||||
std::pair<CellStoreCollection::iterator, bool> result =
|
std::pair<CellStoreCollection::iterator, bool> result =
|
||||||
mActiveCells.insert(cell);
|
mActiveCells.insert(cell);
|
||||||
if(result.second){
|
|
||||||
|
if(result.second)
|
||||||
|
{
|
||||||
insertCell(*cell);
|
insertCell(*cell);
|
||||||
mRendering.cellAdded (cell);
|
mRendering.cellAdded (cell);
|
||||||
|
|
||||||
|
float verts = ESM::Land::LAND_SIZE;
|
||||||
|
float worldsize = ESM::Land::REAL_SIZE;
|
||||||
|
|
||||||
|
if (!(cell->cell->data.flags & ESM::Cell::Interior))
|
||||||
|
{
|
||||||
|
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.configureAmbient(*cell);
|
||||||
mRendering.requestMap(cell);
|
mRendering.requestMap(cell);
|
||||||
mRendering.configureAmbient(*cell);
|
mRendering.configureAmbient(*cell);
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position,
|
void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position,
|
||||||
bool adjustPlayerPos)
|
bool adjustPlayerPos)
|
||||||
{
|
{
|
||||||
|
bool hasWater = cell->cell->data.flags & cell->cell->HasWater;
|
||||||
|
mPhysics->setCurrentWater(hasWater, cell->cell->water);
|
||||||
if (adjustPlayerPos)
|
if (adjustPlayerPos)
|
||||||
mWorld->getPlayer().setPos (position.pos[0], position.pos[1], position.pos[2]);
|
mWorld->getPlayer().setPos (position.pos[0], position.pos[1], position.pos[2]);
|
||||||
|
|
||||||
|
|
|
@ -215,6 +215,7 @@ namespace MWWorld
|
||||||
|
|
||||||
setFallbackValues(fallbackMap);
|
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[0] = x;
|
||||||
ptr.getRefData().getPosition().pos[1] = y;
|
ptr.getRefData().getPosition().pos[1] = y;
|
||||||
ptr.getRefData().getPosition().pos[2] = z;
|
ptr.getRefData().getPosition().pos[2] = z;
|
||||||
|
@ -582,6 +584,7 @@ namespace MWWorld
|
||||||
if (currentCell->cell->data.gridX!=cellX || currentCell->cell->data.gridY!=cellY)
|
if (currentCell->cell->data.gridX!=cellX || currentCell->cell->data.gridY!=cellY)
|
||||||
{
|
{
|
||||||
mWorldScene->changeCell (cellX, cellY, mPlayer->getPlayer().getRefData().getPosition(), false);
|
mWorldScene->changeCell (cellX, cellY, mPlayer->getPlayer().getRefData().getPosition(), false);
|
||||||
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -591,6 +594,8 @@ namespace MWWorld
|
||||||
/// \todo cell change for non-player ref
|
/// \todo cell change for non-player ref
|
||||||
|
|
||||||
mRendering->moveObject (ptr, Ogre::Vector3 (x, y, z));
|
mRendering->moveObject (ptr, Ogre::Vector3 (x, y, z));
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::moveObject (Ptr ptr, float x, float y, float z)
|
void World::moveObject (Ptr ptr, float x, float y, float z)
|
||||||
|
@ -632,7 +637,24 @@ namespace MWWorld
|
||||||
void World::doPhysics (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors,
|
void World::doPhysics (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors,
|
||||||
float duration)
|
float duration)
|
||||||
{
|
{
|
||||||
std::vector< std::pair<std::string, Ogre::Vector3> > vectors = mPhysics->doPhysics (duration, actors);
|
mPhysics->doPhysics(duration, actors);
|
||||||
|
|
||||||
|
const int tick = 16; // 16 ms ^= 60 Hz
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
lastTick += tick;
|
||||||
|
|
||||||
|
std::vector< std::pair<std::string, Ogre::Vector3> > vectors = mPhysics->doPhysicsFixed (actors);
|
||||||
|
|
||||||
std::vector< std::pair<std::string, Ogre::Vector3> >::iterator player = vectors.end();
|
std::vector< std::pair<std::string, Ogre::Vector3> >::iterator player = vectors.end();
|
||||||
|
|
||||||
|
@ -653,8 +675,12 @@ namespace MWWorld
|
||||||
// Make sure player is moved last (otherwise the cell might change in the middle of an update
|
// Make sure player is moved last (otherwise the cell might change in the middle of an update
|
||||||
// loop)
|
// loop)
|
||||||
if (player!=vectors.end())
|
if (player!=vectors.end())
|
||||||
moveObjectImp (getPtrViaHandle (player->first),
|
{
|
||||||
player->second.x, player->second.y, player->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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::toggleCollisionMode()
|
bool World::toggleCollisionMode()
|
||||||
|
@ -789,7 +815,8 @@ namespace MWWorld
|
||||||
std::vector < std::pair < float, std::string > >::iterator it = results.begin();
|
std::vector < std::pair < float, std::string > >::iterator it = results.begin();
|
||||||
while (it != results.end())
|
while (it != results.end())
|
||||||
{
|
{
|
||||||
if ( getPtrViaHandle((*it).second) == mPlayer->getPlayer() )
|
if ( (*it).second.find("HeightField") != std::string::npos // not interested in terrain
|
||||||
|
|| getPtrViaHandle((*it).second) == mPlayer->getPlayer() ) // not interested in player (unless you want to talk to yourself)
|
||||||
{
|
{
|
||||||
it = results.erase(it);
|
it = results.erase(it);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include <openengine/bullet/physic.hpp>
|
#include <openengine/bullet/physic.hpp>
|
||||||
#include <openengine/ogre/fader.hpp>
|
#include <openengine/ogre/fader.hpp>
|
||||||
|
|
||||||
|
#include <OgreTimer.h>
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
class Vector3;
|
class Vector3;
|
||||||
|
@ -100,9 +102,13 @@ namespace MWWorld
|
||||||
int mNumFacing;
|
int mNumFacing;
|
||||||
std::map<std::string,std::string> mFallback;
|
std::map<std::string,std::string> mFallback;
|
||||||
|
|
||||||
|
unsigned long lastTick;
|
||||||
|
Ogre::Timer mTimer;
|
||||||
|
|
||||||
int getDaysPerMonth (int month) const;
|
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:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "physic.hpp"
|
#include "physic.hpp"
|
||||||
#include <btBulletDynamicsCommon.h>
|
#include <btBulletDynamicsCommon.h>
|
||||||
#include <btBulletCollisionCommon.h>
|
#include <btBulletCollisionCommon.h>
|
||||||
|
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
|
||||||
#include <components/nifbullet/bullet_nif_loader.hpp>
|
#include <components/nifbullet/bullet_nif_loader.hpp>
|
||||||
//#include <apps\openmw\mwworld\world.hpp>
|
//#include <apps\openmw\mwworld\world.hpp>
|
||||||
#include "CMotionState.h"
|
#include "CMotionState.h"
|
||||||
|
@ -10,6 +11,8 @@
|
||||||
#include "BtOgreGP.h"
|
#include "BtOgreGP.h"
|
||||||
#include "BtOgreExtras.h"
|
#include "BtOgreExtras.h"
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
#define BIT(x) (1<<(x))
|
#define BIT(x) (1<<(x))
|
||||||
|
|
||||||
namespace OEngine {
|
namespace OEngine {
|
||||||
|
@ -161,10 +164,12 @@ namespace Physic
|
||||||
// The actual physics solver
|
// The actual physics solver
|
||||||
solver = new btSequentialImpulseConstraintSolver;
|
solver = new btSequentialImpulseConstraintSolver;
|
||||||
|
|
||||||
|
//btOverlappingPairCache* pairCache = new btSortedOverlappingPairCache();
|
||||||
pairCache = new btSortedOverlappingPairCache();
|
pairCache = new btSortedOverlappingPairCache();
|
||||||
|
|
||||||
//pairCache->setInternalGhostPairCallback( new btGhostPairCallback() );
|
//pairCache->setInternalGhostPairCallback( new btGhostPairCallback() );
|
||||||
|
|
||||||
broadphase = new btDbvtBroadphase(pairCache);
|
broadphase = new btDbvtBroadphase();
|
||||||
|
|
||||||
// The world.
|
// The world.
|
||||||
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
|
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
|
||||||
|
@ -253,6 +258,60 @@ namespace Physic
|
||||||
delete mShapeLoader;
|
delete mShapeLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicEngine::addHeightField(float* heights,
|
||||||
|
int x, int y, float yoffset,
|
||||||
|
float triSize, float sqrtVerts)
|
||||||
|
{
|
||||||
|
const std::string name = "HeightField_"
|
||||||
|
+ boost::lexical_cast<std::string>(x) + "_"
|
||||||
|
+ boost::lexical_cast<std::string>(y);
|
||||||
|
|
||||||
|
// find the minimum and maximum heights (needed for bullet)
|
||||||
|
float minh;
|
||||||
|
float maxh;
|
||||||
|
for (int i=0; i<sqrtVerts*sqrtVerts; ++i)
|
||||||
|
{
|
||||||
|
float h = heights[i];
|
||||||
|
if (i==0)
|
||||||
|
{
|
||||||
|
minh = h;
|
||||||
|
maxh = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h>maxh) maxh = h;
|
||||||
|
if (h<minh) minh = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
btHeightfieldTerrainShape* hfShape = new btHeightfieldTerrainShape(
|
||||||
|
sqrtVerts, sqrtVerts, heights, 1,
|
||||||
|
minh, maxh, 2,
|
||||||
|
PHY_FLOAT,true);
|
||||||
|
|
||||||
|
hfShape->setUseDiamondSubdivision(true);
|
||||||
|
|
||||||
|
btVector3 scl(triSize, triSize, 1);
|
||||||
|
hfShape->setLocalScaling(scl);
|
||||||
|
|
||||||
|
CMotionState* newMotionState = new CMotionState(this,name);
|
||||||
|
|
||||||
|
btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,hfShape);
|
||||||
|
RigidBody* body = new RigidBody(CI,name);
|
||||||
|
body->collide = true;
|
||||||
|
body->getWorldTransform().setOrigin(btVector3( (x+0.5)*triSize*(sqrtVerts-1), (y+0.5)*triSize*(sqrtVerts-1), (maxh+minh)/2.f));
|
||||||
|
|
||||||
|
addRigidBody(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhysicEngine::removeHeightField(int x, int y)
|
||||||
|
{
|
||||||
|
const std::string name = "HeightField_"
|
||||||
|
+ boost::lexical_cast<std::string>(x) + "_"
|
||||||
|
+ boost::lexical_cast<std::string>(y);
|
||||||
|
|
||||||
|
removeRigidBody(name);
|
||||||
|
deleteRigidBody(name);
|
||||||
|
}
|
||||||
|
|
||||||
RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale)
|
RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale)
|
||||||
{
|
{
|
||||||
//get the shape from the .nif
|
//get the shape from the .nif
|
||||||
|
@ -334,7 +393,7 @@ namespace Physic
|
||||||
|
|
||||||
void PhysicEngine::stepSimulation(double deltaT)
|
void PhysicEngine::stepSimulation(double deltaT)
|
||||||
{
|
{
|
||||||
dynamicsWorld->stepSimulation(deltaT,1,1/50.);
|
dynamicsWorld->stepSimulation(deltaT,10, 1/60.0);
|
||||||
if(isDebugCreated)
|
if(isDebugCreated)
|
||||||
{
|
{
|
||||||
mDebugDrawer->step();
|
mDebugDrawer->step();
|
||||||
|
|
|
@ -140,6 +140,18 @@ namespace Physic
|
||||||
*/
|
*/
|
||||||
RigidBody* createRigidBody(std::string mesh,std::string name,float scale);
|
RigidBody* createRigidBody(std::string mesh,std::string name,float scale);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a HeightField to the simulation
|
||||||
|
*/
|
||||||
|
void addHeightField(float* heights,
|
||||||
|
int x, int y, float yoffset,
|
||||||
|
float triSize, float sqrtVerts);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a HeightField from the simulation
|
||||||
|
*/
|
||||||
|
void removeHeightField(int x, int y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a RigidBody to the simulation
|
* Add a RigidBody to the simulation
|
||||||
*/
|
*/
|
||||||
|
|
2095
libs/openengine/bullet/pmove.cpp
Normal file
2095
libs/openengine/bullet/pmove.cpp
Normal file
File diff suppressed because it is too large
Load diff
200
libs/openengine/bullet/pmove.h
Normal file
200
libs/openengine/bullet/pmove.h
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
#ifndef OENGINE_BULLET_PMOVE_H
|
||||||
|
#define OENGINE_BULLET_PMOVE_H
|
||||||
|
/*
|
||||||
|
This source file is a *modified* version of various header files from the Quake 3 Arena source code,
|
||||||
|
which was released under the GNU GPL (v2) in 2005.
|
||||||
|
Quake 3 Arena is copyright (C) 1999-2005 Id Software, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Ogre.h>
|
||||||
|
#include <OgreMath.h>
|
||||||
|
#include <float.h>
|
||||||
|
#include "trace.h"
|
||||||
|
#include "physic.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
//#include "GameMath.h"
|
||||||
|
//#include "GameTime.h"
|
||||||
|
|
||||||
|
// Forwards-declare it!
|
||||||
|
|
||||||
|
/*#ifndef COMPILING_PMOVE
|
||||||
|
#include "Scene.h"
|
||||||
|
extern SceneInstance* global_lastscene;
|
||||||
|
#endif*/
|
||||||
|
|
||||||
|
static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2);
|
||||||
|
|
||||||
|
#define MAX_CLIP_PLANES 5
|
||||||
|
#define OVERCLIP 1.001f
|
||||||
|
//#define STEPSIZE 18 // 18 is way too much
|
||||||
|
#define STEPSIZE (18 / 2)
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846f
|
||||||
|
#endif
|
||||||
|
#define YAW 0
|
||||||
|
#define PITCH /*1*/2
|
||||||
|
#define ROLL /*2*/1
|
||||||
|
#define SHORT2ANGLE(x) ( (x) * (360.0f / 65536.0f) )
|
||||||
|
#define ANGLE2SHORT(x) ( (const short)( (x) / (360.0f / 65536.0f) ) )
|
||||||
|
#define GENTITYNUM_BITS 10 // don't need to send any more
|
||||||
|
#define MAX_GENTITIES (1 << GENTITYNUM_BITS)
|
||||||
|
#define ENTITYNUM_NONE (MAX_GENTITIES - 1)
|
||||||
|
#define ENTITYNUM_WORLD (MAX_GENTITIES - 2)
|
||||||
|
#define MIN_WALK_NORMAL 0.7f // can't walk on very steep slopes
|
||||||
|
#define JUMP_VELOCITY (270)
|
||||||
|
#define PS_PMOVEFRAMECOUNTBITS 6
|
||||||
|
#define MINS_Z -24
|
||||||
|
#define DEFAULT_VIEWHEIGHT 26
|
||||||
|
#define CROUCH_VIEWHEIGHT 12
|
||||||
|
#define DEAD_VIEWHEIGHT (-16)
|
||||||
|
#define CONTENTS_SOLID 1 // an eye is never valid in a solid
|
||||||
|
#define CONTENTS_LAVA 8
|
||||||
|
#define CONTENTS_SLIME 16
|
||||||
|
#define CONTENTS_WATER 32
|
||||||
|
#define CONTENTS_FOG 64
|
||||||
|
static const float pm_accelerate = 10.0f;
|
||||||
|
static const float pm_stopspeed = 100.0f;
|
||||||
|
static const float pm_friction = 12.0f;
|
||||||
|
static const float pm_flightfriction = 3.0f;
|
||||||
|
static const float pm_waterfriction = 1.0f;
|
||||||
|
static const float pm_airaccelerate = 1.0f;
|
||||||
|
static const float pm_swimScale = 0.50f;
|
||||||
|
static const float pm_duckScale = 0.25f;
|
||||||
|
static const float pm_flyaccelerate = 8.0f;
|
||||||
|
static const float pm_wateraccelerate = 4.0f;
|
||||||
|
|
||||||
|
enum pmtype_t
|
||||||
|
{
|
||||||
|
PM_NORMAL, // can accelerate and turn
|
||||||
|
PM_NOCLIP, // noclip movement
|
||||||
|
PM_SPECTATOR, // still run into walls
|
||||||
|
PM_DEAD, // no acceleration or turning, but free falling
|
||||||
|
PM_FREEZE, // stuck in place with no control
|
||||||
|
PM_INTERMISSION, // no movement or status bar
|
||||||
|
PM_SPINTERMISSION // no movement or status bar
|
||||||
|
};
|
||||||
|
|
||||||
|
enum waterlevel_t
|
||||||
|
{
|
||||||
|
WL_DRYLAND = 0,
|
||||||
|
WL_ANKLE,
|
||||||
|
WL_WAIST,
|
||||||
|
WL_UNDERWATER
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//#include "bprintf.h"
|
||||||
|
|
||||||
|
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), snappingImplemented(true), bSnap(false), counter(-1)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
delta_angles[0] = delta_angles[1] = delta_angles[2] = 0;
|
||||||
|
|
||||||
|
lastframe_origin.x = lastframe_origin.y = lastframe_origin.z = 0;
|
||||||
|
lerp_multiplier.x = lerp_multiplier.y = lerp_multiplier.z = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SpeedUp(void)
|
||||||
|
{
|
||||||
|
//printf("speed up to: %f\n", speed);
|
||||||
|
speed *= 1.25f;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SpeedDown(void)
|
||||||
|
{
|
||||||
|
//printf("speed down to %f\n", speed);
|
||||||
|
speed /= 1.25f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ogre::Vector3 velocity;
|
||||||
|
Ogre::Vector3 origin;
|
||||||
|
bool bSnap;
|
||||||
|
bool snappingImplemented;
|
||||||
|
int counter;
|
||||||
|
float gravity; // default = 800
|
||||||
|
float speed; // default = 320
|
||||||
|
|
||||||
|
int commandTime; // the time at which this command was issued (in milliseconds)
|
||||||
|
|
||||||
|
int pm_time;
|
||||||
|
|
||||||
|
Ogre::Vector3 viewangles;
|
||||||
|
|
||||||
|
int groundEntityNum;
|
||||||
|
|
||||||
|
int pmove_framecount;
|
||||||
|
|
||||||
|
int watertype;
|
||||||
|
waterlevel_t waterlevel;
|
||||||
|
|
||||||
|
signed short delta_angles[3];
|
||||||
|
|
||||||
|
pmtype_t move_type;
|
||||||
|
|
||||||
|
float last_compute_time;
|
||||||
|
Ogre::Vector3 lastframe_origin;
|
||||||
|
Ogre::Vector3 lerp_multiplier;
|
||||||
|
} ps;
|
||||||
|
|
||||||
|
struct playercmd
|
||||||
|
{
|
||||||
|
enum CMDstateChange
|
||||||
|
{
|
||||||
|
NO_CHANGE,
|
||||||
|
KEYDOWN,
|
||||||
|
KEYUP
|
||||||
|
};
|
||||||
|
|
||||||
|
playercmd() : forwardmove(0), rightmove(0), upmove(0), serverTime(50), ducking(false),
|
||||||
|
activating(false), lastActivatingState(false), procActivating(NO_CHANGE),
|
||||||
|
dropping(false), lastDroppingState(false), procDropping(NO_CHANGE)
|
||||||
|
{
|
||||||
|
angles[0] = angles[1] = angles[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int serverTime;
|
||||||
|
|
||||||
|
short angles[3];
|
||||||
|
|
||||||
|
signed char forwardmove;
|
||||||
|
signed char rightmove;
|
||||||
|
signed char upmove;
|
||||||
|
|
||||||
|
bool ducking;
|
||||||
|
bool activating; // if the user is holding down the activate button
|
||||||
|
bool dropping; // if the user is dropping an item
|
||||||
|
|
||||||
|
bool lastActivatingState;
|
||||||
|
bool lastDroppingState;
|
||||||
|
|
||||||
|
CMDstateChange procActivating;
|
||||||
|
CMDstateChange procDropping;
|
||||||
|
} cmd;
|
||||||
|
|
||||||
|
playerMove() : msec(50), pmove_fixed(false), pmove_msec(50), waterHeight(0), isInterior(true), hasWater(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int msec;
|
||||||
|
int pmove_msec;
|
||||||
|
bool pmove_fixed;
|
||||||
|
int waterHeight;
|
||||||
|
bool hasWater;
|
||||||
|
bool isInterior;
|
||||||
|
//Object* traceObj;
|
||||||
|
OEngine::Physic::PhysicEngine* mEngine;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Pmove (playerMove* const pmove);
|
||||||
|
void Ext_UpdateViewAngles(playerMove* const pm);
|
||||||
|
void AngleVectors( const Ogre::Vector3& angles, Ogre::Vector3* const forward, Ogre::Vector3* const right, Ogre::Vector3* const up) ;
|
||||||
|
#endif
|
190
libs/openengine/bullet/trace.cpp
Normal file
190
libs/openengine/bullet/trace.cpp
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogre::Vector3& end, const Ogre::Vector3& BBHalfExtents, const float rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass) //Traceobj was a Aedra Object
|
||||||
|
{
|
||||||
|
|
||||||
|
//if (!traceobj)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
//if (!traceobj->incellptr)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
const Ogre::Vector3 rayDir = end - start;
|
||||||
|
|
||||||
|
// Nudge starting point backwards
|
||||||
|
//const Position3D nudgestart = start + (rayDir * -0.1f); // by 10% (isn't that too much?)
|
||||||
|
//const Position3D nudgestart = start;
|
||||||
|
|
||||||
|
NewPhysTraceResults out;
|
||||||
|
//std::cout << "Starting trace\n";
|
||||||
|
//Ogre::Vector3 startReplace = Ogre::Vector3(650,950, 45);
|
||||||
|
//Ogre::Vector3 endReplace = startReplace;
|
||||||
|
//endReplace.z -= .25;
|
||||||
|
|
||||||
|
const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0, rotation), isInterior, enginePass);
|
||||||
|
|
||||||
|
if (out.fraction < 0.001f)
|
||||||
|
results->startsolid = true;
|
||||||
|
else
|
||||||
|
results->startsolid = false;
|
||||||
|
|
||||||
|
|
||||||
|
//results->allsolid = out.startSolid;
|
||||||
|
|
||||||
|
// If outside and underground, we're solid
|
||||||
|
/*if (isInterior)
|
||||||
|
{
|
||||||
|
const Ogre::Vector3 height = GetGroundPosition(start, CellCoords(traceCell->data->gridX, traceCell->data->gridY) );
|
||||||
|
if (start.yPos - height.yPos < (-2.0f * BBHalfExtents.yPos) )
|
||||||
|
{
|
||||||
|
results->allsolid = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
results->allsolid = false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// If inside and out of the tree, we're solid
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
results->allsolid = out.startSolid;
|
||||||
|
//std::cout << "allsolid" << results->allsolid << "\n";
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (!hasHit)
|
||||||
|
{
|
||||||
|
results->endpos = end;
|
||||||
|
results->planenormal = Ogre::Vector3(0.0f, 0.0f, 1.0f);
|
||||||
|
results->entityNum = ENTITYNUM_NONE;
|
||||||
|
results->fraction = 1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
results->fraction = out.fraction;
|
||||||
|
results->planenormal = out.hitNormal;
|
||||||
|
results->endpos = rayDir * results->fraction + start;
|
||||||
|
results->entityNum = ENTITYNUM_WORLD;
|
||||||
|
/*bprintf("Start: (%f, %f, %f) End: (%f, %f, %f) TraceDir: (%f, %f, %f) HitNormal: (%f, %f, %f) Fraction: %f Hitpos: (%f, %f, %f) CompensatedHitpos: (%f, %f, %f)\n",
|
||||||
|
start.xPos, start.yPos, start.zPos,
|
||||||
|
end.xPos, end.yPos, end.zPos,
|
||||||
|
rayDir.xPos, rayDir.yPos, rayDir.zPos,
|
||||||
|
results->planenormal.xPos, results->planenormal.yPos, results->planenormal.zPos, results->fraction,
|
||||||
|
out.endPos.xPos, out.endPos.yPos, out.endPos.zPos,
|
||||||
|
results->endpos.xPos, results->endpos.yPos, results->endpos.zPos);*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <const traceWorldType traceType>
|
||||||
|
const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& start, const Ogre::Vector3& end,
|
||||||
|
const Ogre::Vector3& BBHalfExtents, const Ogre::Vector3& rotation, bool isInterior, OEngine::Physic::PhysicEngine* enginePass)
|
||||||
|
{
|
||||||
|
//if (!traceobj->incellptr)
|
||||||
|
// return false;
|
||||||
|
//if(enginePass->dynamicsWorld->getCollisionObjectArray().at(60)->getCollisionShape()->isConvex())
|
||||||
|
// std::cout << "It's convex\n";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const btVector3 btstart(start.x, start.y, start.z);
|
||||||
|
const btVector3 btend(end.x, end.y, end.z);
|
||||||
|
const btQuaternion btrot(rotation.y, rotation.x, rotation.z); //y, x, z
|
||||||
|
|
||||||
|
const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z));
|
||||||
|
const btTransform from(btrot, btstart);
|
||||||
|
const btTransform to(btrot, btend);
|
||||||
|
|
||||||
|
// warning: unused variable ...
|
||||||
|
/*
|
||||||
|
float x = from.getOrigin().getX();
|
||||||
|
float y = from.getOrigin().getY();
|
||||||
|
float z = from.getOrigin().getZ();
|
||||||
|
float x2 = to.getOrigin().getX();
|
||||||
|
float y2 = to.getOrigin().getY();
|
||||||
|
float z2 = to.getOrigin().getZ();
|
||||||
|
*/
|
||||||
|
|
||||||
|
//std::cout << "BtFrom: " << x << "," << y << "," << z << "\n";
|
||||||
|
//std::cout << "BtTo: " << x2 << "," << y2 << "," << z2 << "\n";
|
||||||
|
//std::cout << "BtTo: " << to.getOrigin().getX() << "," << to.getOrigin().getY() << "," << to.getOrigin().getZ() << "\n";
|
||||||
|
|
||||||
|
|
||||||
|
btCollisionWorld::ClosestConvexResultCallback
|
||||||
|
newTraceCallback(btstart, btend);
|
||||||
|
|
||||||
|
newTraceCallback.m_collisionFilterMask = (traceType == collisionWorldTrace) ? Only_Collision : Only_Pickup;
|
||||||
|
|
||||||
|
|
||||||
|
enginePass->dynamicsWorld->convexSweepTest(&newshape, from, to, newTraceCallback);
|
||||||
|
//newTraceCallback.
|
||||||
|
|
||||||
|
|
||||||
|
//std::cout << "NUM: " << enginePass->dynamicsWorld->getNumCollisionObjects() << "\n";
|
||||||
|
|
||||||
|
// Copy the hit data over to our trace results struct:
|
||||||
|
out->fraction = newTraceCallback.m_closestHitFraction;
|
||||||
|
|
||||||
|
Ogre::Vector3& outhitnormal = out->hitNormal;
|
||||||
|
const btVector3& tracehitnormal = newTraceCallback.m_hitNormalWorld;
|
||||||
|
|
||||||
|
outhitnormal.x = tracehitnormal.x();
|
||||||
|
outhitnormal.y = tracehitnormal.y();
|
||||||
|
outhitnormal.z = tracehitnormal.z();
|
||||||
|
|
||||||
|
Ogre::Vector3& outhitpos = out->endPos;
|
||||||
|
const btVector3& tracehitpos = newTraceCallback.m_hitPointWorld;
|
||||||
|
|
||||||
|
outhitpos.x = tracehitpos.x();
|
||||||
|
outhitpos.y = tracehitpos.y();
|
||||||
|
outhitpos.z= tracehitpos.z();
|
||||||
|
|
||||||
|
// StartSolid test:
|
||||||
|
{
|
||||||
|
out->startSolid = false;
|
||||||
|
//btCollisionObject collision;
|
||||||
|
//collision.setCollisionShape(const_cast<btBoxShape* const>(&newshape) );
|
||||||
|
|
||||||
|
//CustomContactCallback crb;
|
||||||
|
|
||||||
|
//world.world->contactTest(&collision, crb);
|
||||||
|
//out->startSolid = crb.hit;
|
||||||
|
|
||||||
|
// If outside and underground, we're solid
|
||||||
|
if (!isInterior) //Check if we are interior
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// If inside and out of the tree, we're solid
|
||||||
|
else
|
||||||
|
{
|
||||||
|
btVector3 aabbMin, aabbMax;
|
||||||
|
enginePass->broadphase->getBroadphaseAabb(aabbMin, aabbMax);
|
||||||
|
//std::cout << "AABBMIN" << aabbMin.getX() <<"," <<aabbMin.getY() << "," << aabbMin.getZ() << "\n";
|
||||||
|
//std::cout << "AABBMAX" << aabbMax.getX() <<"," <<aabbMax.getY() << "," << aabbMax.getZ() << "\n";
|
||||||
|
//std::cout << "AABBMAX" << aabbMax << "\n";
|
||||||
|
if (!TestPointAgainstAabb2(aabbMin, aabbMax, *(const btVector3* const)&(start) ) )
|
||||||
|
{
|
||||||
|
//We're solid
|
||||||
|
out->startSolid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool hasHit = newTraceCallback.hasHit();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return hasHit;
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ enum traceWorldType
|
||||||
bothWorldTrace = collisionWorldTrace | pickWorldTrace
|
bothWorldTrace = collisionWorldTrace | pickWorldTrace
|
||||||
};
|
};
|
||||||
|
|
||||||
enum collaborativePhysicsType : unsigned
|
enum collaborativePhysicsType
|
||||||
{
|
{
|
||||||
No_Physics = 0, // Both are empty (example: statics you can walk through, like tall grass)
|
No_Physics = 0, // Both are empty (example: statics you can walk through, like tall grass)
|
||||||
Only_Collision = 1, // This object only has collision physics but no pickup physics (example: statics)
|
Only_Collision = 1, // This object only has collision physics but no pickup physics (example: statics)
|
||||||
|
@ -53,8 +53,8 @@ struct traceResults
|
||||||
|
|
||||||
template <const traceWorldType traceType>
|
template <const traceWorldType traceType>
|
||||||
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);
|
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<collisionWorldTrace>(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<collisionWorldTrace>(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<pickWorldTrace>(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<pickWorldTrace>(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);
|
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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue