mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 18:19:55 +00:00
Merge remote-tracking branch 'jhooks/physicsaedra3' into next
This commit is contained in:
commit
4abb9a00da
15 changed files with 387 additions and 228 deletions
|
@ -141,6 +141,7 @@ namespace MWClass
|
|||
assert(ref->base != NULL);
|
||||
|
||||
std::string headID = ref->base->head;
|
||||
|
||||
int end = headID.find_last_of("head_") - 4;
|
||||
std::string bodyRaceID = headID.substr(0, end);
|
||||
|
||||
|
@ -153,6 +154,7 @@ namespace MWClass
|
|||
model = "meshes\\base_animkna.nif";
|
||||
}
|
||||
return model;
|
||||
|
||||
}
|
||||
|
||||
std::string Npc::getName (const MWWorld::Ptr& ptr) const
|
||||
|
@ -297,7 +299,7 @@ namespace MWClass
|
|||
{
|
||||
Ogre::Vector3 vector (0, 0, 0);
|
||||
|
||||
vector.x = - getMovementSettings (ptr).mLeftRight * 127;
|
||||
vector.x = getMovementSettings (ptr).mLeftRight * 127;
|
||||
vector.y = getMovementSettings (ptr).mForwardBackward * 127;
|
||||
vector.z = getMovementSettings(ptr).mUpDown * 127;
|
||||
|
||||
|
|
|
@ -77,12 +77,6 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
|
|||
bodyRaceID = "b_n_"+ref->base->race;
|
||||
std::transform(bodyRaceID.begin(), bodyRaceID.end(), bodyRaceID.begin(), ::tolower);
|
||||
|
||||
/*std::cout << "Race: " << ref->base->race ;
|
||||
if(female)
|
||||
std::cout << " Sex: Female" << " Height: " << race->data.height.female << "\n";
|
||||
else
|
||||
std::cout << " Sex: Male" << " Height: " << race->data.height.male << "\n";
|
||||
*/
|
||||
|
||||
mInsert = node;
|
||||
assert(mInsert);
|
||||
|
@ -129,6 +123,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(isFemale)
|
||||
mInsert->scale(race->data.height.female, race->data.height.female, race->data.height.female);
|
||||
else
|
||||
|
|
|
@ -275,13 +275,15 @@ RenderingManager::rotateObject(
|
|||
float *f = ptr.getRefData().getPosition().rot;
|
||||
rot.x += f[0], rot.y += f[1], rot.z += f[2];
|
||||
}
|
||||
|
||||
if (!isPlayer && isActive) {
|
||||
Ogre::Quaternion xr(Ogre::Radian(rot.x), Ogre::Vector3::UNIT_X);
|
||||
Ogre::Quaternion yr(Ogre::Radian(rot.y), Ogre::Vector3::UNIT_Y);
|
||||
Ogre::Quaternion zr(Ogre::Radian(rot.z), Ogre::Vector3::UNIT_Z);
|
||||
|
||||
|
||||
ptr.getRefData().getBaseNode()->setOrientation(xr * yr * zr);
|
||||
}
|
||||
|
||||
return force;
|
||||
}
|
||||
|
||||
|
|
|
@ -96,6 +96,10 @@ namespace MWWorld
|
|||
if(hasWater){
|
||||
playerphysics->waterHeight = waterHeight;
|
||||
}
|
||||
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
|
||||
{
|
||||
it->second->setCurrentWater(hasWater, waterHeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -172,17 +176,20 @@ namespace MWWorld
|
|||
//set the DebugRenderingMode. To disable it,set it to 0
|
||||
//eng->setDebugRenderingMode(1);
|
||||
|
||||
//set the walkdirection to 0 (no movement) for every actor)
|
||||
//set the movement keys 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++)
|
||||
{
|
||||
OEngine::Physic::PhysicActor* act = it->second;
|
||||
act->setWalkDirection(btVector3(0,0,0));
|
||||
act->setMovement(0,0,0);
|
||||
}
|
||||
|
||||
playerMove::playercmd& pm_ref = playerphysics->cmd;
|
||||
|
||||
|
||||
pm_ref.rightmove = 0;
|
||||
pm_ref.forwardmove = 0;
|
||||
pm_ref.upmove = 0;
|
||||
|
||||
|
||||
//playerphysics->ps.move_type = PM_NOCLIP;
|
||||
for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
|
||||
|
@ -193,10 +200,12 @@ namespace MWWorld
|
|||
playerphysics->ps.viewangles.x =
|
||||
Ogre::Radian(mPlayerData.pitch).valueDegrees();
|
||||
|
||||
|
||||
|
||||
playerphysics->ps.viewangles.y =
|
||||
Ogre::Radian(mPlayerData.yaw).valueDegrees() + 90;
|
||||
|
||||
pm_ref.rightmove = -iter->second.x;
|
||||
pm_ref.rightmove = iter->second.x;
|
||||
pm_ref.forwardmove = -iter->second.y;
|
||||
pm_ref.upmove = iter->second.z;
|
||||
}
|
||||
|
@ -208,16 +217,17 @@ namespace MWWorld
|
|||
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
|
||||
{
|
||||
Pmove(playerphysics);
|
||||
|
||||
|
||||
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++)
|
||||
{
|
||||
btVector3 newPos = it->second->getPosition();
|
||||
|
||||
Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z());
|
||||
Ogre::Vector3 coord = it->second->getPosition();
|
||||
if(it->first == "player"){
|
||||
|
||||
coord = playerphysics->ps.origin;
|
||||
coord = playerphysics->ps.origin ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -243,21 +253,15 @@ namespace MWWorld
|
|||
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position)
|
||||
{
|
||||
handleToMesh[handle] = mesh;
|
||||
OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale);
|
||||
OEngine::Physic::RigidBody* body = mEngine->createAndAdjustRigidBody(mesh,handle,scale, position, rotation);
|
||||
mEngine->addRigidBody(body);
|
||||
btTransform tr;
|
||||
tr.setOrigin(btVector3(position.x,position.y,position.z));
|
||||
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)
|
||||
const Ogre::Vector3& position, float scale, const Ogre::Quaternion& rotation)
|
||||
{
|
||||
//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));
|
||||
mEngine->addCharacter(handle, mesh, position, scale, rotation);
|
||||
}
|
||||
|
||||
void PhysicsSystem::removeObject (const std::string& handle)
|
||||
|
@ -268,15 +272,25 @@ namespace MWWorld
|
|||
mEngine->deleteRigidBody(handle);
|
||||
}
|
||||
|
||||
void PhysicsSystem::moveObject (const std::string& handle, const Ogre::Vector3& position)
|
||||
void PhysicsSystem::moveObject (const std::string& handle, Ogre::SceneNode* node)
|
||||
{
|
||||
Ogre::Vector3 position = node->getPosition();
|
||||
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(dynamic_cast<btBoxShape*>(body->getCollisionShape()) == NULL){
|
||||
btTransform tr = body->getWorldTransform();
|
||||
tr.setOrigin(btVector3(position.x,position.y,position.z));
|
||||
body->setWorldTransform(tr);
|
||||
}
|
||||
else{
|
||||
//For objects that contain a box shape.
|
||||
//Do any such objects exist? Perhaps animated objects?
|
||||
mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, position, node->getOrientation());
|
||||
}
|
||||
}
|
||||
if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
|
||||
{
|
||||
|
@ -288,34 +302,45 @@ namespace MWWorld
|
|||
}
|
||||
else
|
||||
{
|
||||
act->setPosition(btVector3(position.x,position.y,position.z));
|
||||
act->setPosition(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation)
|
||||
void PhysicsSystem::rotateObject (const std::string& handle, Ogre::SceneNode* node)
|
||||
{
|
||||
Ogre::Quaternion rotation = node->getOrientation();
|
||||
if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
|
||||
{
|
||||
act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
|
||||
//Needs to be changed
|
||||
act->setRotation(rotation);
|
||||
}
|
||||
if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle))
|
||||
{
|
||||
body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
|
||||
if(dynamic_cast<btBoxShape*>(body->getCollisionShape()) == NULL)
|
||||
body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
|
||||
else
|
||||
mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, node->getPosition(), rotation);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsSystem::scaleObject (const std::string& handle, float scale)
|
||||
void PhysicsSystem::scaleObject (const std::string& handle, Ogre::SceneNode* node)
|
||||
{
|
||||
if(handleToMesh.find(handle) != handleToMesh.end())
|
||||
{
|
||||
btTransform transform = mEngine->getRigidBody(handle)->getWorldTransform();
|
||||
removeObject(handle);
|
||||
|
||||
Ogre::Quaternion quat = Ogre::Quaternion(transform.getRotation().getW(), transform.getRotation().getX(), transform.getRotation().getY(), transform.getRotation().getZ());
|
||||
Ogre::Vector3 vec = Ogre::Vector3(transform.getOrigin().getX(), transform.getOrigin().getY(), transform.getOrigin().getZ());
|
||||
float scale = node->getScale().x;
|
||||
Ogre::Quaternion quat = node->getOrientation();
|
||||
Ogre::Vector3 vec = node->getPosition();
|
||||
addObject(handle, handleToMesh[handle], quat, scale, vec);
|
||||
}
|
||||
|
||||
if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle))
|
||||
{
|
||||
float scale = node->getScale().x;
|
||||
act->setScale(scale);
|
||||
}
|
||||
}
|
||||
|
||||
bool PhysicsSystem::toggleCollisionMode()
|
||||
|
@ -335,8 +360,6 @@ namespace MWWorld
|
|||
if(cmode)
|
||||
{
|
||||
act->enableCollisions(false);
|
||||
act->setGravity(0.);
|
||||
act->setVerticalVelocity(0);
|
||||
mFreeFly = true;
|
||||
return false;
|
||||
}
|
||||
|
@ -344,8 +367,6 @@ namespace MWWorld
|
|||
{
|
||||
mFreeFly = false;
|
||||
act->enableCollisions(true);
|
||||
act->setGravity(4.);
|
||||
act->setVerticalVelocity(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -368,7 +389,7 @@ namespace MWWorld
|
|||
|
||||
void PhysicsSystem::insertActorPhysics(const MWWorld::Ptr& ptr, const std::string model){
|
||||
Ogre::SceneNode* node = ptr.getRefData().getBaseNode();
|
||||
addActor (node->getName(), model, node->getPosition());
|
||||
addActor (node->getName(), model, node->getPosition(), node->getScale().x, node->getOrientation());
|
||||
}
|
||||
|
||||
bool PhysicsSystem::getObjectAABB(const MWWorld::Ptr &ptr, Ogre::Vector3 &min, Ogre::Vector3 &max)
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace MWWorld
|
|||
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position);
|
||||
|
||||
void addActor (const std::string& handle, const std::string& mesh,
|
||||
const Ogre::Vector3& position);
|
||||
const Ogre::Vector3& position, float scale, const Ogre::Quaternion& rotation);
|
||||
|
||||
void addHeightField (float* heights,
|
||||
int x, int y, float yoffset,
|
||||
|
@ -34,11 +34,11 @@ namespace MWWorld
|
|||
|
||||
void removeObject (const std::string& handle);
|
||||
|
||||
void moveObject (const std::string& handle, const Ogre::Vector3& position);
|
||||
void moveObject (const std::string& handle, Ogre::SceneNode* node);
|
||||
|
||||
void rotateObject (const std::string& handle, const Ogre::Quaternion& rotation);
|
||||
void rotateObject (const std::string& handle, Ogre::SceneNode* node);
|
||||
|
||||
void scaleObject (const std::string& handle, float scale);
|
||||
void scaleObject (const std::string& handle, Ogre::SceneNode* node);
|
||||
|
||||
bool toggleCollisionMode();
|
||||
|
||||
|
|
|
@ -189,7 +189,9 @@ namespace MWWorld
|
|||
mPlayer = new MWWorld::Player (mStore.npcs.find ("player"), *this);
|
||||
mRendering->attachCameraTo(mPlayer->getPlayer());
|
||||
|
||||
mPhysics->addActor (mPlayer->getPlayer().getRefData().getHandle(), "", Ogre::Vector3 (0, 0, 0));
|
||||
std::string playerCollisionFile = "meshes\\base_anim.nif"; //This is used to make a collision shape for our player
|
||||
//We will need to support the 1st person file too in the future
|
||||
mPhysics->addActor (mPlayer->getPlayer().getRefData().getHandle(), playerCollisionFile, Ogre::Vector3 (0, 0, 0), 1, Ogre::Quaternion::ZERO);
|
||||
|
||||
// global variables
|
||||
mGlobalVariables = new Globals (mStore);
|
||||
|
@ -603,7 +605,7 @@ namespace MWWorld
|
|||
}
|
||||
if (haveToMove) {
|
||||
mRendering->moveObject(ptr, vec);
|
||||
mPhysics->moveObject(ptr.getRefData().getHandle(), vec);
|
||||
mPhysics->moveObject (ptr.getRefData().getHandle(), ptr.getRefData().getBaseNode());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -624,6 +626,8 @@ namespace MWWorld
|
|||
void World::moveObject (const Ptr& ptr, float x, float y, float z)
|
||||
{
|
||||
moveObjectImp(ptr, x, y, z);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void World::scaleObject (const Ptr& ptr, float scale)
|
||||
|
@ -633,7 +637,7 @@ namespace MWWorld
|
|||
ptr.getCellRef().scale = scale;
|
||||
//scale = scale/ptr.getRefData().getBaseNode()->getScale().x;
|
||||
ptr.getRefData().getBaseNode()->setScale(scale,scale,scale);
|
||||
mPhysics->scaleObject( ptr.getRefData().getHandle(), scale );
|
||||
mPhysics->scaleObject( ptr.getRefData().getHandle(), ptr.getRefData().getBaseNode());
|
||||
}
|
||||
|
||||
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
|
||||
|
@ -642,18 +646,20 @@ namespace MWWorld
|
|||
rot.x = Ogre::Degree(x).valueRadians();
|
||||
rot.y = Ogre::Degree(y).valueRadians();
|
||||
rot.z = Ogre::Degree(z).valueRadians();
|
||||
|
||||
|
||||
if (mRendering->rotateObject(ptr, rot, adjust)) {
|
||||
float *objRot = ptr.getRefData().getPosition().rot;
|
||||
objRot[0] = rot.x, objRot[1] = rot.y, objRot[2] = rot.z;
|
||||
|
||||
|
||||
if (ptr.getRefData().getBaseNode() != 0) {
|
||||
mPhysics->rotateObject(
|
||||
ptr.getRefData().getHandle(),
|
||||
ptr.getRefData().getBaseNode()->getOrientation()
|
||||
ptr.getRefData().getBaseNode()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos)
|
||||
|
|
|
@ -72,6 +72,9 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
|
|||
cShape = static_cast<BulletShape *>(resource);
|
||||
resourceName = cShape->getName();
|
||||
cShape->collide = false;
|
||||
mBoundingBox = NULL;
|
||||
cShape->boxTranslation = Ogre::Vector3(0,0,0);
|
||||
cShape->boxRotation = Ogre::Quaternion::IDENTITY;
|
||||
|
||||
mTriMesh = new btTriangleMesh();
|
||||
|
||||
|
@ -125,9 +128,14 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
|
|||
delete m_meshInterface;
|
||||
}
|
||||
};
|
||||
if(mBoundingBox != NULL)
|
||||
cShape->Shape = mBoundingBox;
|
||||
|
||||
currentShape = new TriangleMeshShape(mTriMesh,true);
|
||||
cShape->Shape = currentShape;
|
||||
else
|
||||
{
|
||||
currentShape = new TriangleMeshShape(mTriMesh,true);
|
||||
cShape->Shape = currentShape;
|
||||
}
|
||||
}
|
||||
|
||||
bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node)
|
||||
|
@ -218,6 +226,17 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags,
|
|||
|
||||
}
|
||||
|
||||
if(node->hasBounds)
|
||||
{
|
||||
|
||||
|
||||
btVector3 boxsize = getbtVector((node->boundXYZ));
|
||||
cShape->boxTranslation = node->boundPos;
|
||||
cShape->boxRotation = node->boundRot;
|
||||
|
||||
mBoundingBox = new btBoxShape(boxsize);
|
||||
}
|
||||
|
||||
|
||||
// For NiNodes, loop through children
|
||||
if (node->recType == Nif::RC_NiNode)
|
||||
|
|
|
@ -102,8 +102,11 @@ private:
|
|||
std::string resourceName;
|
||||
std::string resourceGroup;
|
||||
|
||||
|
||||
|
||||
BulletShape* cShape;//current shape
|
||||
btTriangleMesh *mTriMesh;
|
||||
btBoxShape *mBoundingBox;
|
||||
btBvhTriangleMeshShape* currentShape;//the shape curently under construction
|
||||
};
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <OgreResource.h>
|
||||
#include <OgreResourceManager.h>
|
||||
#include <btBulletCollisionCommon.h>
|
||||
|
||||
#include <OgreVector3.h>
|
||||
//For some reason, Ogre Singleton cannot be used in another namespace, that's why there is no namespace here.
|
||||
//But the risk of name collision seems pretty low here.
|
||||
|
||||
|
@ -31,6 +31,8 @@ public:
|
|||
virtual ~BulletShape();
|
||||
|
||||
btCollisionShape* Shape;
|
||||
Ogre::Vector3 boxTranslation;
|
||||
Ogre::Quaternion boxRotation;
|
||||
//this flag indicate if the shape is used for collision or if it's for raycasting only.
|
||||
bool collide;
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <btBulletDynamicsCommon.h>
|
||||
#include <btBulletCollisionCommon.h>
|
||||
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
|
||||
#include "pmove.h"
|
||||
#include <components/nifbullet/bullet_nif_loader.hpp>
|
||||
#include "CMotionState.h"
|
||||
#include "OgreRoot.h"
|
||||
|
@ -26,111 +27,139 @@ namespace Physic
|
|||
COL_RAYCASTING = BIT(3)
|
||||
};
|
||||
|
||||
PhysicActor::PhysicActor(std::string name)
|
||||
PhysicActor::PhysicActor(std::string name, std::string mesh, PhysicEngine* engine, Ogre::Vector3 position, Ogre::Quaternion rotation, float scale):
|
||||
mName(name), mEngine(engine), mMesh(mesh), mBoxScaledTranslation(0,0,0), mBoxRotationInverse(0,0,0,0), mBody(0), collisionMode(false), mBoxRotation(0,0,0,0)
|
||||
{
|
||||
mName = name;
|
||||
|
||||
// The capsule is at the origin
|
||||
btTransform transform;
|
||||
transform.setIdentity();
|
||||
|
||||
// External capsule
|
||||
externalGhostObject = new PairCachingGhostObject(name);
|
||||
externalGhostObject->setWorldTransform( transform );
|
||||
|
||||
btScalar externalCapsuleHeight = 120;
|
||||
btScalar externalCapsuleWidth = 19;
|
||||
|
||||
externalCollisionShape = new btCapsuleShapeZ( externalCapsuleWidth, externalCapsuleHeight );
|
||||
externalCollisionShape->setMargin( 0.1 );
|
||||
|
||||
externalGhostObject->setCollisionShape( externalCollisionShape );
|
||||
externalGhostObject->setCollisionFlags( btCollisionObject::CF_CHARACTER_OBJECT );
|
||||
|
||||
// Internal capsule
|
||||
internalGhostObject = new PairCachingGhostObject(name);
|
||||
internalGhostObject->setWorldTransform( transform );
|
||||
//internalGhostObject->getBroadphaseHandle()->s
|
||||
btScalar internalCapsuleHeight = 110;
|
||||
btScalar internalCapsuleWidth = 17;
|
||||
|
||||
internalCollisionShape = new btCapsuleShapeZ( internalCapsuleWidth, internalCapsuleHeight );
|
||||
internalCollisionShape->setMargin( 0.1 );
|
||||
|
||||
internalGhostObject->setCollisionShape( internalCollisionShape );
|
||||
internalGhostObject->setCollisionFlags( btCollisionObject::CF_CHARACTER_OBJECT );
|
||||
|
||||
mCharacter = new btKinematicCharacterController( externalGhostObject,internalGhostObject,btScalar( 40 ),1,4,20,9.8,0.2 );
|
||||
mCharacter->setUpAxis(btKinematicCharacterController::Z_AXIS);
|
||||
mCharacter->setUseGhostSweepTest(false);
|
||||
|
||||
mCharacter->mCollision = false;
|
||||
setGravity(0);
|
||||
|
||||
mTranslation = btVector3(0,0,70);
|
||||
mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation);
|
||||
Ogre::Quaternion inverse = mBoxRotation.Inverse();
|
||||
mBoxRotationInverse = btQuaternion(inverse.x, inverse.y, inverse.z,inverse.w);
|
||||
mEngine->addRigidBody(mBody, false); //Add rigid body to dynamics world, but do not add to object map
|
||||
pmove = new playerMove;
|
||||
pmove->mEngine = mEngine;
|
||||
btBoxShape* box = static_cast<btBoxShape*> (mBody->getCollisionShape());
|
||||
if(box != NULL){
|
||||
btVector3 size = box->getHalfExtentsWithMargin();
|
||||
Ogre::Vector3 halfExtents = Ogre::Vector3(size.getX(), size.getY(), size.getZ());
|
||||
pmove->ps.halfExtents = halfExtents;
|
||||
}
|
||||
}
|
||||
|
||||
PhysicActor::~PhysicActor()
|
||||
{
|
||||
delete mCharacter;
|
||||
delete internalGhostObject;
|
||||
delete internalCollisionShape;
|
||||
delete externalGhostObject;
|
||||
delete externalCollisionShape;
|
||||
if(mBody){
|
||||
mEngine->dynamicsWorld->removeRigidBody(mBody);
|
||||
delete mBody;
|
||||
}
|
||||
delete pmove;
|
||||
}
|
||||
|
||||
void PhysicActor::setCurrentWater(bool hasWater, int waterHeight){
|
||||
pmove->hasWater = hasWater;
|
||||
if(hasWater){
|
||||
pmove->waterHeight = waterHeight;
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicActor::setGravity(float gravity)
|
||||
{
|
||||
mCharacter->setGravity(gravity);
|
||||
//mCharacter->
|
||||
pmove->ps.gravity = gravity;
|
||||
}
|
||||
|
||||
void PhysicActor::setSpeed(float speed)
|
||||
{
|
||||
pmove->ps.speed = speed;
|
||||
}
|
||||
|
||||
void PhysicActor::enableCollisions(bool collision)
|
||||
{
|
||||
mCharacter->mCollision = collision;
|
||||
collisionMode = collision;
|
||||
if(collisionMode)
|
||||
pmove->ps.move_type=PM_NORMAL;
|
||||
else
|
||||
pmove->ps.move_type=PM_NOCLIP;
|
||||
}
|
||||
|
||||
void PhysicActor::setVerticalVelocity(float z)
|
||||
void PhysicActor::setJumpVelocity(float velocity)
|
||||
{
|
||||
mCharacter->setVerticalVelocity(z);
|
||||
pmove->ps.jump_velocity = velocity;
|
||||
}
|
||||
|
||||
bool PhysicActor::getCollisionMode()
|
||||
{
|
||||
return mCharacter->mCollision;
|
||||
return collisionMode;
|
||||
}
|
||||
|
||||
void PhysicActor::setWalkDirection(const btVector3& mvt)
|
||||
void PhysicActor::setMovement(signed char rightmove, signed char forwardmove, signed char upmove)
|
||||
{
|
||||
mCharacter->setWalkDirection( mvt );
|
||||
playerMove::playercmd& pm_ref = pmove->cmd;
|
||||
pm_ref.rightmove = rightmove;
|
||||
pm_ref.forwardmove = forwardmove;
|
||||
pm_ref.upmove = upmove;
|
||||
}
|
||||
|
||||
void PhysicActor::Rotate(const btQuaternion& quat)
|
||||
{
|
||||
externalGhostObject->getWorldTransform().setRotation( externalGhostObject->getWorldTransform().getRotation() * quat );
|
||||
internalGhostObject->getWorldTransform().setRotation( internalGhostObject->getWorldTransform().getRotation() * quat );
|
||||
void PhysicActor::setPmoveViewAngles(float pitch, float yaw, float roll){
|
||||
pmove->ps.viewangles.x = pitch;
|
||||
pmove->ps.viewangles.y = yaw;
|
||||
pmove->ps.viewangles.z = roll;
|
||||
}
|
||||
|
||||
void PhysicActor::setRotation(const btQuaternion& quat)
|
||||
|
||||
|
||||
void PhysicActor::setRotation(const Ogre::Quaternion quat)
|
||||
{
|
||||
externalGhostObject->getWorldTransform().setRotation( quat );
|
||||
internalGhostObject->getWorldTransform().setRotation( quat );
|
||||
if(!quat.equals(getRotation(), Ogre::Radian(0))){
|
||||
mEngine->adjustRigidBody(mBody, getPosition(), quat, mBoxScaledTranslation, mBoxRotation);
|
||||
}
|
||||
}
|
||||
|
||||
btVector3 PhysicActor::getPosition(void)
|
||||
Ogre::Vector3 PhysicActor::getPosition()
|
||||
{
|
||||
return internalGhostObject->getWorldTransform().getOrigin() -mTranslation;
|
||||
btVector3 vec = mBody->getWorldTransform().getOrigin();
|
||||
Ogre::Quaternion rotation = Ogre::Quaternion(mBody->getWorldTransform().getRotation().getW(), mBody->getWorldTransform().getRotation().getX(),
|
||||
mBody->getWorldTransform().getRotation().getY(), mBody->getWorldTransform().getRotation().getZ());
|
||||
Ogre::Vector3 transrot = rotation * mBoxScaledTranslation;
|
||||
Ogre::Vector3 visualPosition = Ogre::Vector3(vec.getX(), vec.getY(), vec.getZ()) - transrot;
|
||||
return visualPosition;
|
||||
}
|
||||
|
||||
btQuaternion PhysicActor::getRotation(void)
|
||||
Ogre::Quaternion PhysicActor::getRotation()
|
||||
{
|
||||
return internalGhostObject->getWorldTransform().getRotation();
|
||||
btQuaternion quat = mBody->getWorldTransform().getRotation() * mBoxRotationInverse;
|
||||
return Ogre::Quaternion(quat.getW(), quat.getX(), quat.getY(), quat.getZ());
|
||||
}
|
||||
|
||||
void PhysicActor::setPosition(const btVector3& pos)
|
||||
void PhysicActor::setPosition(const Ogre::Vector3 pos)
|
||||
{
|
||||
internalGhostObject->getWorldTransform().setOrigin(pos+mTranslation);
|
||||
externalGhostObject->getWorldTransform().setOrigin(pos+mTranslation);
|
||||
mEngine->adjustRigidBody(mBody, pos, getRotation(), mBoxScaledTranslation, mBoxRotation);
|
||||
btVector3 vec = mBody->getWorldTransform().getOrigin();
|
||||
pmove->ps.origin = Ogre::Vector3(vec.getX(), vec.getY(), vec.getZ());
|
||||
}
|
||||
|
||||
void PhysicActor::setScale(float scale){
|
||||
Ogre::Vector3 position = getPosition();
|
||||
Ogre::Quaternion rotation = getRotation();
|
||||
//We only need to change the scaled box translation, box rotations remain the same.
|
||||
mBoxScaledTranslation = mBoxScaledTranslation / mBody->getCollisionShape()->getLocalScaling().getX();
|
||||
mBoxScaledTranslation *= scale;
|
||||
if(mBody){
|
||||
mEngine->dynamicsWorld->removeRigidBody(mBody);
|
||||
delete mBody;
|
||||
}
|
||||
//Create the newly scaled rigid body
|
||||
mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation);
|
||||
mEngine->addRigidBody(mBody, false); //Add rigid body to dynamics world, but do not add to object map
|
||||
btBoxShape* box = static_cast<btBoxShape*> (mBody->getCollisionShape());
|
||||
if(box != NULL){
|
||||
btVector3 size = box->getHalfExtentsWithMargin();
|
||||
Ogre::Vector3 halfExtents = Ogre::Vector3(size.getX(), size.getY(), size.getZ());
|
||||
pmove->ps.halfExtents = halfExtents;
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicActor::runPmove(){
|
||||
Pmove(pmove);
|
||||
Ogre::Vector3 newpos = pmove->ps.origin;
|
||||
mBody->getWorldTransform().setOrigin(btVector3(newpos.x, newpos.y, newpos.z));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -230,8 +259,8 @@ namespace Physic
|
|||
delete hf_it->second.mBody;
|
||||
}
|
||||
|
||||
RigidBodyContainer::iterator rb_it = RigidBodyMap.begin();
|
||||
for (; rb_it != RigidBodyMap.end(); ++rb_it)
|
||||
RigidBodyContainer::iterator rb_it = ObjectMap.begin();
|
||||
for (; rb_it != ObjectMap.end(); ++rb_it)
|
||||
{
|
||||
if (rb_it->second != NULL)
|
||||
{
|
||||
|
@ -247,9 +276,7 @@ namespace Physic
|
|||
{
|
||||
if (pa_it->second != NULL)
|
||||
{
|
||||
dynamicsWorld->removeCollisionObject(pa_it->second->externalGhostObject);
|
||||
dynamicsWorld->removeCollisionObject(pa_it->second->internalGhostObject);
|
||||
dynamicsWorld->removeAction(pa_it->second->mCharacter);
|
||||
|
||||
|
||||
delete pa_it->second;
|
||||
pa_it->second = NULL;
|
||||
|
@ -332,18 +359,42 @@ namespace Physic
|
|||
mHeightFieldMap.erase(name);
|
||||
}
|
||||
|
||||
RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale)
|
||||
{
|
||||
void PhysicEngine::adjustRigidBody(RigidBody* body, Ogre::Vector3 position, Ogre::Quaternion rotation,
|
||||
Ogre::Vector3 scaledBoxTranslation, Ogre::Quaternion boxRotation){
|
||||
btTransform tr;
|
||||
rotation = rotation * boxRotation;
|
||||
Ogre::Vector3 transrot = rotation * scaledBoxTranslation;
|
||||
Ogre::Vector3 newPosition = transrot + position;
|
||||
|
||||
tr.setOrigin(btVector3(newPosition.x, newPosition.y, newPosition.z));
|
||||
tr.setRotation(btQuaternion(rotation.x,rotation.y,rotation.z,rotation.w));
|
||||
body->setWorldTransform(tr);
|
||||
}
|
||||
void PhysicEngine::boxAdjustExternal(std::string mesh, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation){
|
||||
std::string sid = (boost::format("%07.3f") % scale).str();
|
||||
std::string outputstring = mesh + sid;
|
||||
//std::cout << "The string" << outputstring << "\n";
|
||||
|
||||
//get the shape from the .nif
|
||||
mShapeLoader->load(outputstring,"General");
|
||||
BulletShapeManager::getSingletonPtr()->load(outputstring,"General");
|
||||
BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General");
|
||||
|
||||
adjustRigidBody(body, position, rotation, shape->boxTranslation * scale, shape->boxRotation);
|
||||
}
|
||||
|
||||
RigidBody* PhysicEngine::createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation,
|
||||
Ogre::Vector3* scaledBoxTranslation, Ogre::Quaternion* boxRotation)
|
||||
{
|
||||
std::string sid = (boost::format("%07.3f") % scale).str();
|
||||
std::string outputstring = mesh + sid;
|
||||
|
||||
//get the shape from the .nif
|
||||
mShapeLoader->load(outputstring,"General");
|
||||
BulletShapeManager::getSingletonPtr()->load(outputstring,"General");
|
||||
BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General");
|
||||
shape->Shape->setLocalScaling( btVector3(scale,scale,scale));
|
||||
//btScaledBvhTriangleMeshShape* scaled = new btScaledBvhTriangleMeshShape(dynamic_cast<btBvhTriangleMeshShape*> (shape->Shape), btVector3(scale,scale,scale));
|
||||
|
||||
|
||||
//create the motionState
|
||||
CMotionState* newMotionState = new CMotionState(this,name);
|
||||
|
@ -352,11 +403,19 @@ namespace Physic
|
|||
btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,shape->Shape);
|
||||
RigidBody* body = new RigidBody(CI,name);
|
||||
body->collide = shape->collide;
|
||||
|
||||
if(scaledBoxTranslation != 0)
|
||||
*scaledBoxTranslation = shape->boxTranslation * scale;
|
||||
if(boxRotation != 0)
|
||||
*boxRotation = shape->boxRotation;
|
||||
|
||||
adjustRigidBody(body, position, rotation, shape->boxTranslation * scale, shape->boxRotation);
|
||||
|
||||
return body;
|
||||
|
||||
}
|
||||
|
||||
void PhysicEngine::addRigidBody(RigidBody* body)
|
||||
void PhysicEngine::addRigidBody(RigidBody* body, bool addToMap)
|
||||
{
|
||||
if(body)
|
||||
{
|
||||
|
@ -369,21 +428,23 @@ namespace Physic
|
|||
dynamicsWorld->addRigidBody(body,COL_RAYCASTING,COL_RAYCASTING|COL_WORLD);
|
||||
}
|
||||
body->setActivationState(DISABLE_DEACTIVATION);
|
||||
RigidBody* oldBody = RigidBodyMap[body->mName];
|
||||
if (oldBody != NULL)
|
||||
{
|
||||
dynamicsWorld->removeRigidBody(oldBody);
|
||||
delete oldBody;
|
||||
}
|
||||
if(addToMap){
|
||||
RigidBody* oldBody = ObjectMap[body->mName];
|
||||
if (oldBody != NULL)
|
||||
{
|
||||
dynamicsWorld->removeRigidBody(oldBody);
|
||||
delete oldBody;
|
||||
}
|
||||
|
||||
RigidBodyMap[body->mName] = body;
|
||||
ObjectMap[body->mName] = body;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicEngine::removeRigidBody(std::string name)
|
||||
{
|
||||
RigidBodyContainer::iterator it = RigidBodyMap.find(name);
|
||||
if (it != RigidBodyMap.end() )
|
||||
RigidBodyContainer::iterator it = ObjectMap.find(name);
|
||||
if (it != ObjectMap.end() )
|
||||
{
|
||||
RigidBody* body = it->second;
|
||||
if(body != NULL)
|
||||
|
@ -402,8 +463,8 @@ namespace Physic
|
|||
|
||||
void PhysicEngine::deleteRigidBody(std::string name)
|
||||
{
|
||||
RigidBodyContainer::iterator it = RigidBodyMap.find(name);
|
||||
if (it != RigidBodyMap.end() )
|
||||
RigidBodyContainer::iterator it = ObjectMap.find(name);
|
||||
if (it != ObjectMap.end() )
|
||||
{
|
||||
RigidBody* body = it->second;
|
||||
//btScaledBvhTriangleMeshShape* scaled = dynamic_cast<btScaledBvhTriangleMeshShape*> (body->getCollisionShape());
|
||||
|
@ -416,16 +477,16 @@ namespace Physic
|
|||
{
|
||||
delete scaled;
|
||||
}*/
|
||||
RigidBodyMap.erase(it);
|
||||
ObjectMap.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
RigidBody* PhysicEngine::getRigidBody(std::string name)
|
||||
{
|
||||
RigidBodyContainer::iterator it = RigidBodyMap.find(name);
|
||||
if (it != RigidBodyMap.end() )
|
||||
RigidBodyContainer::iterator it = ObjectMap.find(name);
|
||||
if (it != ObjectMap.end() )
|
||||
{
|
||||
RigidBody* body = RigidBodyMap[name];
|
||||
RigidBody* body = ObjectMap[name];
|
||||
return body;
|
||||
}
|
||||
else
|
||||
|
@ -443,16 +504,17 @@ namespace Physic
|
|||
}
|
||||
}
|
||||
|
||||
void PhysicEngine::addCharacter(std::string name)
|
||||
void PhysicEngine::addCharacter(std::string name, std::string mesh,
|
||||
Ogre::Vector3 position, float scale, Ogre::Quaternion rotation)
|
||||
{
|
||||
// Remove character with given name, so we don't make memory
|
||||
// leak when character would be added twice
|
||||
removeCharacter(name);
|
||||
|
||||
PhysicActor* newActor = new PhysicActor(name);
|
||||
dynamicsWorld->addCollisionObject( newActor->externalGhostObject, COL_ACTOR_EXTERNAL, COL_WORLD |COL_ACTOR_EXTERNAL );
|
||||
dynamicsWorld->addCollisionObject( newActor->internalGhostObject, COL_ACTOR_INTERNAL, COL_WORLD |COL_ACTOR_INTERNAL );
|
||||
dynamicsWorld->addAction( newActor->mCharacter );
|
||||
PhysicActor* newActor = new PhysicActor(name, mesh, this, position, rotation, scale);
|
||||
|
||||
|
||||
//dynamicsWorld->addAction( newActor->mCharacter );
|
||||
PhysicActorMap[name] = newActor;
|
||||
}
|
||||
|
||||
|
@ -465,25 +527,11 @@ namespace Physic
|
|||
PhysicActor* act = it->second;
|
||||
if(act != NULL)
|
||||
{
|
||||
/*broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher);
|
||||
broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher);
|
||||
PhysicActorContainer::iterator it2 = PhysicActorMap.begin();
|
||||
for(;it2!=PhysicActorMap.end();it++)
|
||||
{
|
||||
it->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher);
|
||||
it->second->externalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher);
|
||||
it->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher);
|
||||
it->second->externalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher);
|
||||
}*/
|
||||
//act->externalGhostObject->
|
||||
dynamicsWorld->removeCollisionObject(act->externalGhostObject);
|
||||
dynamicsWorld->removeCollisionObject(act->internalGhostObject);
|
||||
dynamicsWorld->removeAction(act->mCharacter);
|
||||
|
||||
delete act;
|
||||
}
|
||||
PhysicActorMap.erase(it);
|
||||
}
|
||||
//std::cout << "ok";
|
||||
}
|
||||
|
||||
PhysicActor* PhysicEngine::getCharacter(std::string name)
|
||||
|
|
|
@ -9,14 +9,16 @@
|
|||
#include "BulletShapeLoader.h"
|
||||
#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
|
||||
|
||||
|
||||
|
||||
class btRigidBody;
|
||||
class btBroadphaseInterface;
|
||||
class btDefaultCollisionConfiguration;
|
||||
class btSequentialImpulseConstraintSolver;
|
||||
class btCollisionDispatcher;
|
||||
class btDiscreteDynamicsWorld;
|
||||
class btKinematicCharacterController;
|
||||
class btHeightfieldTerrainShape;
|
||||
struct playerMove;
|
||||
|
||||
namespace BtOgre
|
||||
{
|
||||
|
@ -28,11 +30,14 @@ namespace MWWorld
|
|||
class World;
|
||||
}
|
||||
|
||||
|
||||
namespace OEngine {
|
||||
namespace Physic
|
||||
{
|
||||
class CMotionState;
|
||||
struct PhysicEvent;
|
||||
class PhysicEngine;
|
||||
class RigidBody;
|
||||
|
||||
/**
|
||||
*This is just used to be able to name objects.
|
||||
|
@ -50,55 +55,88 @@ namespace Physic
|
|||
};
|
||||
|
||||
/**
|
||||
* A physic Actor use a modifed KinematicCharacterController taken in the bullet forum.
|
||||
* A physic actor uses a rigid body based on box shapes.
|
||||
* Pmove is used to move the physic actor around the dynamic world.
|
||||
*/
|
||||
class PhysicActor
|
||||
{
|
||||
public:
|
||||
PhysicActor(std::string name);
|
||||
PhysicActor(std::string name, std::string mesh, PhysicEngine *engine, Ogre::Vector3 position, Ogre::Quaternion rotation, float scale);
|
||||
|
||||
~PhysicActor();
|
||||
|
||||
void setCurrentWater(bool hasWater, int waterHeight);
|
||||
|
||||
/**
|
||||
* This function set the walkDirection. This is not relative to the actor orientation.
|
||||
* I think it's also needed to take time into account. A typical call should look like this:
|
||||
* setWalkDirection( mvt * orientation * dt)
|
||||
* This function sets the movement keys for pmove
|
||||
*/
|
||||
void setWalkDirection(const btVector3& mvt);
|
||||
void setMovement(signed char rightmove, signed char forwardmove, signed char upmove);
|
||||
|
||||
void Rotate(const btQuaternion& quat);
|
||||
|
||||
void setRotation(const btQuaternion& quat);
|
||||
/**
|
||||
* This adjusts the rotation of a PhysicActor
|
||||
* If we have any problems with this (getting stuck in pmove) we should change it
|
||||
* from setting the visual orientation to setting the orientation of the rigid body directly.
|
||||
*/
|
||||
void setRotation(const Ogre::Quaternion quat);
|
||||
|
||||
void setGravity(float gravity);
|
||||
|
||||
void setVerticalVelocity(float z);
|
||||
void setSpeed(float speed);
|
||||
|
||||
void setJumpVelocity(float velocity);
|
||||
|
||||
void enableCollisions(bool collision);
|
||||
|
||||
bool getCollisionMode();
|
||||
|
||||
btVector3 getPosition(void);
|
||||
|
||||
btQuaternion getRotation(void);
|
||||
|
||||
void setPosition(const btVector3& pos);
|
||||
|
||||
btKinematicCharacterController* mCharacter;
|
||||
|
||||
PairCachingGhostObject* internalGhostObject;
|
||||
btCollisionShape* internalCollisionShape;
|
||||
|
||||
PairCachingGhostObject* externalGhostObject;
|
||||
btCollisionShape* externalCollisionShape;
|
||||
|
||||
std::string mName;
|
||||
/**
|
||||
* This returns the visual position of the PhysicActor (used to position a scenenode).
|
||||
* Note - this is different from the position of the contained mBody.
|
||||
*/
|
||||
Ogre::Vector3 getPosition();
|
||||
|
||||
/**
|
||||
*NPC scenenode is located on there feet, and you can't simply translate a btShape, so this vector is used
|
||||
*each time get/setposition is called.
|
||||
*/
|
||||
btVector3 mTranslation;
|
||||
* Returns the visual orientation of the PhysicActor
|
||||
*/
|
||||
Ogre::Quaternion getRotation();
|
||||
|
||||
/**
|
||||
* Sets the position of mBody from a visual position input.
|
||||
* For most cases this should not be used. We should instead let pmove move the PhysicActor around for us
|
||||
*/
|
||||
void setPosition(const Ogre::Vector3 pos);
|
||||
|
||||
/**
|
||||
* Sets the view angles for pmove directly.
|
||||
* Remember, add 90 for yaw. Set roll to 0.
|
||||
*/
|
||||
void setPmoveViewAngles(float pitch, float yaw, float roll);
|
||||
|
||||
/**
|
||||
* Sets the scale of the PhysicActor
|
||||
*/
|
||||
void setScale(float scale);
|
||||
|
||||
/**
|
||||
* Runs pmove for this PhysicActor
|
||||
*/
|
||||
void runPmove();
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
OEngine::Physic::RigidBody* mBody;
|
||||
Ogre::Vector3 mBoxScaledTranslation;
|
||||
btQuaternion mBoxRotationInverse;
|
||||
Ogre::Quaternion mBoxRotation;
|
||||
bool collisionMode;
|
||||
std::string mMesh;
|
||||
PhysicEngine* mEngine;
|
||||
std::string mName;
|
||||
playerMove* pmove;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -143,11 +181,22 @@ namespace Physic
|
|||
~PhysicEngine();
|
||||
|
||||
/**
|
||||
* Create a RigidBody.It does not add it to the simulation, but it does add it to the rigidBody Map,
|
||||
* so you can get it with the getRigidBody function.
|
||||
* Creates a RigidBody. It does not add it to the simulation.
|
||||
* After created, the body is set to the correct rotation, position, and scale
|
||||
*/
|
||||
RigidBody* createRigidBody(std::string mesh,std::string name,float scale);
|
||||
RigidBody* createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation,
|
||||
Ogre::Vector3* scaledBoxTranslation = 0, Ogre::Quaternion* boxRotation = 0);
|
||||
|
||||
/**
|
||||
* Adjusts a rigid body to the right position and rotation
|
||||
*/
|
||||
|
||||
void adjustRigidBody(RigidBody* body, Ogre::Vector3 position, Ogre::Quaternion rotation,
|
||||
Ogre::Vector3 scaledBoxTranslation = Ogre::Vector3::ZERO, Ogre::Quaternion boxRotation = Ogre::Quaternion::IDENTITY);
|
||||
/**
|
||||
Mainly used to (but not limited to) adjust rigid bodies based on box shapes to the right position and rotation.
|
||||
*/
|
||||
void boxAdjustExternal(std::string mesh, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation);
|
||||
/**
|
||||
* Add a HeightField to the simulation
|
||||
*/
|
||||
|
@ -163,7 +212,7 @@ namespace Physic
|
|||
/**
|
||||
* Add a RigidBody to the simulation
|
||||
*/
|
||||
void addRigidBody(RigidBody* body);
|
||||
void addRigidBody(RigidBody* body, bool addToMap = true);
|
||||
|
||||
/**
|
||||
* Remove a RigidBody from the simulation. It does not delete it, and does not remove it from the RigidBodyMap.
|
||||
|
@ -184,7 +233,8 @@ namespace Physic
|
|||
/**
|
||||
* Create and add a character to the scene, and add it to the ActorMap.
|
||||
*/
|
||||
void addCharacter(std::string name);
|
||||
void addCharacter(std::string name, std::string mesh,
|
||||
Ogre::Vector3 position, float scale, Ogre::Quaternion rotation);
|
||||
|
||||
/**
|
||||
* Remove a character from the scene. TODO:delete it! for now, a small memory leak^^ done?
|
||||
|
@ -254,7 +304,7 @@ namespace Physic
|
|||
HeightFieldContainer mHeightFieldMap;
|
||||
|
||||
typedef std::map<std::string,RigidBody*> RigidBodyContainer;
|
||||
RigidBodyContainer RigidBodyMap;
|
||||
RigidBodyContainer ObjectMap;
|
||||
|
||||
typedef std::map<std::string, PhysicActor*> PhysicActorContainer;
|
||||
PhysicActorContainer PhysicActorMap;
|
||||
|
@ -263,6 +313,7 @@ namespace Physic
|
|||
BtOgre::DebugDrawer* mDebugDrawer;
|
||||
bool isDebugCreated;
|
||||
bool mDebugActive;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -231,7 +231,7 @@ bool PM_SlideMove( bool gravity )
|
|||
// see if we can make it there
|
||||
//pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemaskg);
|
||||
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&(end), *(const D3DXVECTOR3* const)&(pm->ps.velocity), 0, pml.traceObj);
|
||||
newtrace(&trace, pm->ps.origin, end, halfExtents, Ogre::Math::DegreesToRadians (pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
newtrace(&trace, pm->ps.origin, end, pm->ps.halfExtents, Ogre::Math::DegreesToRadians (pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
|
||||
if (trace.allsolid)
|
||||
{
|
||||
|
@ -301,7 +301,7 @@ bool PM_SlideMove( bool gravity )
|
|||
|
||||
if(planes[i].x >= .70)
|
||||
{
|
||||
pm->ps.velocity = Ogre::Vector3(0,0,0);
|
||||
pm->ps.velocity.z = 0;
|
||||
return true;
|
||||
}
|
||||
// see how hard we are hitting things
|
||||
|
@ -449,7 +449,7 @@ int PM_StepSlideMove( bool gravity )
|
|||
//pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
|
||||
//tracefunc(&trace, start_o, down, , 0, pml.scene);
|
||||
//tracefunc(&trace, *(const D3DXVECTOR3* const)&start_o, *(const D3DXVECTOR3* const)&down, D3DXVECTOR3(0.0f, -STEPSIZE, 0.0f), 0, pml.traceObj);
|
||||
newtrace(&trace, start_o, down, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
newtrace(&trace, down, start_o, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
|
||||
// up = vec3(0, 0, 1)
|
||||
//VectorSet(up, 0, 0, 1);
|
||||
|
@ -479,7 +479,7 @@ int PM_StepSlideMove( bool gravity )
|
|||
// test the player position if they were a stepheight higher
|
||||
//pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
|
||||
//tracefunc(&trace, *(const D3DXVECTOR3* const)&start_o, *(const D3DXVECTOR3* const)&up, D3DXVECTOR3(0.0f, STEPSIZE, 0.0f), 0, pml.traceObj);
|
||||
newtrace(&trace, start_o, up, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
newtrace(&trace, start_o, up, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
if ( trace.allsolid )
|
||||
{
|
||||
//if ( pm->debugLevel )
|
||||
|
@ -510,7 +510,7 @@ int PM_StepSlideMove( bool gravity )
|
|||
|
||||
//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
|
||||
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&down, D3DXVECTOR3(0.0f, -STEPSIZE, 0.0f), 0, pml.traceObj);
|
||||
newtrace(&trace, pm->ps.origin, down, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
newtrace(&trace, pm->ps.origin, down, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
if ( !trace.allsolid )
|
||||
//VectorCopy (trace.endpos, pm->ps->origin);
|
||||
pm->ps.origin = trace.endpos;
|
||||
|
@ -527,7 +527,7 @@ int PM_StepSlideMove( bool gravity )
|
|||
delta = pm->ps.origin.z - start_o.z;
|
||||
if ( delta > 2 )
|
||||
{
|
||||
pm->ps.counter = 5;
|
||||
pm->ps.counter = 10;
|
||||
|
||||
/*
|
||||
if (gravity)
|
||||
|
@ -657,10 +657,11 @@ static void PM_Accelerate( Ogre::Vector3& wishdir, float wishspeed, float accel
|
|||
// int i;
|
||||
float addspeed, accelspeed, currentspeed;
|
||||
|
||||
|
||||
// currentspeed = pm->ps->velocity dot wishdir
|
||||
//currentspeed = DotProduct (pm->ps->velocity, wishdir);
|
||||
currentspeed = pm->ps.velocity.dotProduct(wishdir);
|
||||
|
||||
|
||||
addspeed = wishspeed - currentspeed;
|
||||
if (addspeed <= 0)
|
||||
return;
|
||||
|
@ -675,6 +676,8 @@ static void PM_Accelerate( Ogre::Vector3& wishdir, float wishspeed, float accel
|
|||
//for (i=0 ; i<3 ; i++)
|
||||
//pm->ps->velocity[i] += accelspeed * wishdir[i];
|
||||
pm->ps.velocity += (wishdir * accelspeed);
|
||||
//pm->ps.velocity = wishdir * wishspeed; //New, for instant acceleration
|
||||
|
||||
}
|
||||
|
||||
static bool PM_CheckJump(void)
|
||||
|
@ -701,7 +704,7 @@ static bool PM_CheckJump(void)
|
|||
//pm->ps->pm_flags |= PMF_JUMP_HELD;
|
||||
|
||||
pm->ps.groundEntityNum = ENTITYNUM_NONE;
|
||||
pm->ps.velocity.z = JUMP_VELOCITY;
|
||||
pm->ps.velocity.z = pm->ps.jump_velocity;
|
||||
pm->ps.bSnap = false;
|
||||
//PM_AddEvent( EV_JUMP );
|
||||
|
||||
|
@ -899,7 +902,7 @@ static void PM_WalkMove( playerMove* const pmove )
|
|||
if (pmove->hasWater )
|
||||
{
|
||||
const float waterHeight = pmove->waterHeight;
|
||||
const float waterSoundStepHeight = waterHeight + halfExtents.y;
|
||||
const float waterSoundStepHeight = waterHeight + pm->ps.halfExtents.y;
|
||||
if (pmove->ps.origin.y < waterSoundStepHeight)
|
||||
step_underwater = true;
|
||||
}
|
||||
|
@ -1179,7 +1182,7 @@ void PM_GroundTraceMissed()
|
|||
|
||||
//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);
|
||||
newtrace(&trace, pm->ps.origin, point, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
//It hit the ground below
|
||||
if ( trace.fraction < 1.0 && pm->ps.origin.z > trace.endpos.z)
|
||||
{
|
||||
|
@ -1225,7 +1228,7 @@ static bool PM_CorrectAllSolid(traceResults* const trace)
|
|||
|
||||
//pm->trace (trace, point, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
|
||||
//tracefunc(trace, *(const D3DXVECTOR3* const)&point, *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, 0.0f, 0.0f), 0, pml.traceObj);
|
||||
newtrace(trace, point, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
newtrace(trace, point, point, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
|
||||
if ( !trace->allsolid )
|
||||
{
|
||||
|
@ -1237,7 +1240,7 @@ static bool PM_CorrectAllSolid(traceResults* const trace)
|
|||
|
||||
//pm->trace (trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
|
||||
//tracefunc(trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj);
|
||||
newtrace(trace, pm->ps.origin, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
newtrace(trace, pm->ps.origin, point, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
pml.groundTrace = *trace;
|
||||
return true;
|
||||
}
|
||||
|
@ -1338,7 +1341,7 @@ static void PM_CrashLand( void )
|
|||
{
|
||||
|
||||
const float waterHeight = pm->waterHeight;
|
||||
const float waterHeightSplash = waterHeight + halfExtents.y;
|
||||
const float waterHeightSplash = waterHeight + pm->ps.halfExtents.y;
|
||||
if (pm->ps.origin.z < waterHeightSplash)
|
||||
{
|
||||
splashSound = true;
|
||||
|
@ -1413,7 +1416,7 @@ static void PM_GroundTrace( void )
|
|||
|
||||
//pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask);
|
||||
//tracefunc(&trace, *(const D3DXVECTOR3* const)&(pm->ps.origin), *(const D3DXVECTOR3* const)&point, D3DXVECTOR3(0.0f, -0.25f, 0.0f), 0, pml.traceObj);
|
||||
newtrace(&trace, pm->ps.origin, point, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
newtrace(&trace, pm->ps.origin, point, pm->ps.halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine);
|
||||
pml.groundTrace = trace;
|
||||
|
||||
// do something corrective if the trace starts in a solid...
|
||||
|
|
|
@ -23,7 +23,7 @@ Quake 3 Arena is copyright (C) 1999-2005 Id Software, Inc.
|
|||
extern SceneInstance* global_lastscene;
|
||||
#endif*/
|
||||
|
||||
static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2);
|
||||
static const Ogre::Vector3 halfExtentsDefault(14.64f * 2, 14.24f * 2, 33.25f * 2);
|
||||
|
||||
#define MAX_CLIP_PLANES 5
|
||||
#define OVERCLIP 1.001f
|
||||
|
@ -42,7 +42,6 @@ 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 .7f // can't walk on very steep slopes
|
||||
#define JUMP_VELOCITY (270)
|
||||
#define PS_PMOVEFRAMECOUNTBITS 6
|
||||
#define MINS_Z -24
|
||||
#define DEFAULT_VIEWHEIGHT 26
|
||||
|
@ -90,9 +89,9 @@ 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)
|
||||
playerStruct() : gravity(800.0f), speed(480.0f), jump_velocity(270), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1), halfExtents(halfExtentsDefault)
|
||||
{
|
||||
origin = Ogre::Vector3(733.164f,900.0f, 839.432f);
|
||||
origin = Ogre::Vector3(0.0f, 0.0f, 0.0f);
|
||||
velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
viewangles = Ogre::Vector3(0.0f, 0.0f, 0.0f);
|
||||
|
@ -117,11 +116,13 @@ struct playerMove
|
|||
|
||||
Ogre::Vector3 velocity;
|
||||
Ogre::Vector3 origin;
|
||||
Ogre::Vector3 halfExtents;
|
||||
bool bSnap;
|
||||
bool snappingImplemented;
|
||||
int counter;
|
||||
float gravity; // default = 800
|
||||
float speed; // default = 320
|
||||
float jump_velocity; //default = 270
|
||||
|
||||
int commandTime; // the time at which this command was issued (in milliseconds)
|
||||
|
||||
|
|
|
@ -13,18 +13,22 @@
|
|||
|
||||
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
|
||||
{
|
||||
|
||||
static float lastyaw = 0.0f;
|
||||
static float lastpitch = 0.0f;
|
||||
//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";
|
||||
|
@ -32,7 +36,7 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr
|
|||
//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);
|
||||
const bool hasHit = NewPhysicsTrace<collisionWorldTrace>(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0f, 0.0f), isInterior, enginePass);
|
||||
|
||||
if (out.fraction < 0.001f)
|
||||
results->startsolid = true;
|
||||
|
@ -95,13 +99,14 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3&
|
|||
//if(enginePass->dynamicsWorld->getCollisionObjectArray().at(60)->getCollisionShape()->isConvex())
|
||||
// std::cout << "It's convex\n";
|
||||
|
||||
|
||||
|
||||
|
||||
const btVector3 btstart(start.x, start.y, start.z + BBHalfExtents.z);
|
||||
const btVector3 btend(end.x, end.y, end.z + BBHalfExtents.z);
|
||||
const btQuaternion btrot(rotation.y, rotation.x, rotation.z); //y, x, z
|
||||
|
||||
const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z));
|
||||
const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z));
|
||||
//const btCapsuleShapeZ newshape(BBHalfExtents.x, BBHalfExtents.z * 2 - BBHalfExtents.x * 2);
|
||||
const btTransform from(btrot, btstart);
|
||||
const btTransform to(btrot, btend);
|
||||
|
||||
|
@ -176,7 +181,8 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3&
|
|||
if (!TestPointAgainstAabb2(aabbMin, aabbMax, *(const btVector3* const)&(start) ) )
|
||||
{
|
||||
//We're solid
|
||||
out->startSolid = true;
|
||||
//THIS NEEDS TO BE TURNED OFF IF WE WANT FALLING IN EXTERIORS TO WORK CORRECTLY!!!!!!!
|
||||
//out->startSolid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
#include <btBulletDynamicsCommon.h>
|
||||
#include <btBulletCollisionCommon.h>
|
||||
#include <components/nifbullet/bullet_nif_loader.hpp>
|
||||
#include <openengine/bullet/pmove.h>
|
||||
#include <openengine/bullet/physic.hpp>
|
||||
|
||||
#include "pmove.h"
|
||||
|
||||
|
||||
enum traceWorldType
|
||||
|
|
Loading…
Reference in a new issue