diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 063f39d2a3..daf39a1eec 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -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; diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index fdf4910f80..5d1d3d6900 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -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 diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 308a016888..3636436fc5 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -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; } diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index b7cb2778dd..8de415980e 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -96,6 +96,10 @@ namespace MWWorld if(hasWater){ playerphysics->waterHeight = waterHeight; } + for(std::map::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::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 >::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 >& actors) { Pmove(playerphysics); + std::vector< std::pair > response; for(std::map::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) { - btVector3 newPos = it->second->getPosition(); - Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z()); + 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(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(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) diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index c6b8199fab..1427060f6a 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -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(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 8316116186..e9f4f64052 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -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) diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 0fb758ea8b..a70eb7629d 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -72,6 +72,9 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) cShape = static_cast(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) diff --git a/components/nifbullet/bullet_nif_loader.hpp b/components/nifbullet/bullet_nif_loader.hpp index 88e1ab1895..82ac227a0f 100644 --- a/components/nifbullet/bullet_nif_loader.hpp +++ b/components/nifbullet/bullet_nif_loader.hpp @@ -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 }; diff --git a/libs/openengine/bullet/BulletShapeLoader.h b/libs/openengine/bullet/BulletShapeLoader.h index 316ee523c2..8640fd54f0 100644 --- a/libs/openengine/bullet/BulletShapeLoader.h +++ b/libs/openengine/bullet/BulletShapeLoader.h @@ -4,7 +4,7 @@ #include #include #include - +#include //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; }; diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index a778aef3ad..74352b358b 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -2,6 +2,7 @@ #include #include #include +#include "pmove.h" #include #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 (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 (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 (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 (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) diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 9ae8e76077..e4e71706f7 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -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 RigidBodyContainer; - RigidBodyContainer RigidBodyMap; + RigidBodyContainer ObjectMap; typedef std::map PhysicActorContainer; PhysicActorContainer PhysicActorMap; @@ -263,6 +313,7 @@ namespace Physic BtOgre::DebugDrawer* mDebugDrawer; bool isDebugCreated; bool mDebugActive; + }; diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index e13e9e6c07..645abf205b 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -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... diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index aea63d1dbd..fa303184e5 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -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) diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 89d654e6a5..03ed4ffb14 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -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(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0, rotation), isInterior, enginePass); + const bool hasHit = NewPhysicsTrace(&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; } } } diff --git a/libs/openengine/bullet/trace.h b/libs/openengine/bullet/trace.h index 076baf56ef..1bfe0c7178 100644 --- a/libs/openengine/bullet/trace.h +++ b/libs/openengine/bullet/trace.h @@ -5,9 +5,8 @@ #include #include #include -#include #include - +#include "pmove.h" enum traceWorldType