Merge remote-tracking branch 'jhooks/physicsaedra3' into next

pull/37/head
Marc Zinnschlag 12 years ago
commit 4abb9a00da

@ -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)
{
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);
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)
{
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;
}
ObjectMap[body->mName] = body;
}
RigidBodyMap[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);
/**
* 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();
btQuaternion getRotation(void);
/**
* Returns the visual orientation of the PhysicActor
*/
Ogre::Quaternion getRotation();
void setPosition(const btVector3& pos);
/**
* 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);
btKinematicCharacterController* mCharacter;
/**
* Sets the view angles for pmove directly.
* Remember, add 90 for yaw. Set roll to 0.
*/
void setPmoveViewAngles(float pitch, float yaw, float roll);
PairCachingGhostObject* internalGhostObject;
btCollisionShape* internalCollisionShape;
/**
* Sets the scale of the PhysicActor
*/
void setScale(float scale);
PairCachingGhostObject* externalGhostObject;
btCollisionShape* externalCollisionShape;
/**
* Runs pmove for this PhysicActor
*/
void runPmove();
std::string mName;
/**
*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;
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…
Cancel
Save