From 7375035fef34fee75085dcab850f9467c25fe945 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 9 Jul 2012 17:54:15 -0400 Subject: [PATCH 01/29] Counter changed back to 10 --- libs/openengine/bullet/pmove.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index e13e9e6c0..924812c29 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -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) From cacf0bd10dca7efd216f823976404b0be273fd95 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 4 Aug 2012 15:43:33 -0400 Subject: [PATCH 02/29] Basic collision with npcs --- apps/openmw/mwclass/npc.cpp | 2 +- apps/openmw/mwrender/npcanimation.cpp | 2 +- apps/openmw/mwworld/physicssystem.cpp | 18 +++++++++++++----- components/nifbullet/bullet_nif_loader.cpp | 21 +++++++++++++++++---- components/nifbullet/bullet_nif_loader.hpp | 1 + libs/openengine/bullet/physic.cpp | 4 +++- libs/openengine/bullet/pmove.cpp | 2 +- libs/openengine/bullet/pmove.h | 2 +- libs/openengine/bullet/trace.cpp | 13 ++++++++----- libs/openengine/bullet/trace.h | 1 - 10 files changed, 46 insertions(+), 20 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index ab4e2d5e6..72565abda 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -140,7 +140,7 @@ namespace MWClass std::string smodel = "meshes\\base_anim.nif"; if(beast) smodel = "meshes\\base_animkna.nif"; - physics.insertActorPhysics(ptr, smodel); + physics.insertObjectPhysics(ptr, smodel); MWBase::Environment::get().getMechanicsManager()->addActor (ptr); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index fa88b7277..3cc0589f0 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -161,7 +161,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRendere textmappings = NIFLoader::getSingletonPtr()->getTextIndices(smodel); insert->attachObject(base); - + if(isFemale) insert->scale(race->data.height.female, race->data.height.female, race->data.height.female); else diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 9848efe6e..86268567a 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -156,10 +156,11 @@ namespace MWWorld act->setWalkDirection(btVector3(0,0,0)); } playerMove::playercmd& pm_ref = playerphysics->cmd; - + //playerphysics->ps.snappingImplemented = false; 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()); @@ -175,12 +176,14 @@ namespace MWWorld Ogre::Quaternion yawQuat = yawNode->getOrientation(); Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); + playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees(); - playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90; - + playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() * -1 + 90; + if(playerphysics->ps.viewangles.y < 0) + playerphysics->ps.viewangles.y += 360; Ogre::Quaternion quat = yawNode->getOrientation(); Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); @@ -213,7 +216,7 @@ namespace MWWorld Ogre::Vector3 coord(newPos.x(), newPos.y(), newPos.z()); if(it->first == "player"){ - coord = playerphysics->ps.origin; + coord = playerphysics->ps.origin ; } @@ -242,7 +245,12 @@ namespace MWWorld OEngine::Physic::RigidBody* body = mEngine->createRigidBody(mesh,handle,scale); mEngine->addRigidBody(body); btTransform tr; - tr.setOrigin(btVector3(position.x,position.y,position.z)); + btBoxShape* box = dynamic_cast(body->getCollisionShape()); + if(box != NULL){ + tr.setOrigin(btVector3(position.x,position.y,position.z + box->getHalfExtentsWithMargin().getZ())); + } + else + tr.setOrigin(btVector3(position.x,position.y,position.z)); tr.setRotation(btQuaternion(rotation.x,rotation.y,rotation.z,rotation.w)); body->setWorldTransform(tr); } diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 17c5f18ac..e0215fe19 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -136,6 +136,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) cShape = static_cast(resource); resourceName = cShape->getName(); cShape->collide = false; + mBoundingBox = NULL; mTriMesh = new btTriangleMesh(); @@ -199,9 +200,13 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) delete m_meshInterface; } }; - - currentShape = new TriangleMeshShape(mTriMesh,true); - cShape->Shape = currentShape; + if(mBoundingBox != NULL) + cShape->Shape = mBoundingBox; + else + { + currentShape = new TriangleMeshShape(mTriMesh,true); + cShape->Shape = currentShape; + } } bool ManualBulletShapeLoader::hasRootCollisionNode(Nif::Node* node) @@ -289,7 +294,15 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, final.scale *= trafo->scale; } - + if(node->hasBounds) + { + btVector3 getHalf = getbtVector(*(node->boundXYZ)); + //getHalf.setX(getHalf.getX() / 2); + //getHalf.setY(getHalf.getY() / 2); + //getHalf.setZ(getHalf.getZ() / 2); + const btVector3 boxsize = getHalf; + 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 488a7a42b..93809ff7d 100644 --- a/components/nifbullet/bullet_nif_loader.hpp +++ b/components/nifbullet/bullet_nif_loader.hpp @@ -126,6 +126,7 @@ private: BulletShape* cShape;//current shape btTriangleMesh *mTriMesh; + btBoxShape *mBoundingBox; btBvhTriangleMeshShape* currentShape;//the shape curently under construction }; diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 904747afa..8c07d6e2c 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -344,7 +344,9 @@ namespace Physic 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); diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 924812c29..4c70971a3 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -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, halfExtents, Ogre::Math::DegreesToRadians(pm->ps.viewangles.y), pm->isInterior, pm->mEngine); // up = vec3(0, 0, 1) //VectorSet(up, 0, 0, 1); diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index aea63d1db..a0fec3d1c 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -55,7 +55,7 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2); #define CONTENTS_FOG 64 static const float pm_accelerate = 10.0f; static const float pm_stopspeed = 100.0f; -static const float pm_friction = 12.0f; +static const float pm_friction = 6.0f; static const float pm_flightfriction = 3.0f; static const float pm_waterfriction = 1.0f; static const float pm_airaccelerate = 1.0f; diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 2d18aaa4d..6d2166baa 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -13,7 +13,8 @@ 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; @@ -21,10 +22,12 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr // 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 +35,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; diff --git a/libs/openengine/bullet/trace.h b/libs/openengine/bullet/trace.h index 076baf56e..bd554031a 100644 --- a/libs/openengine/bullet/trace.h +++ b/libs/openengine/bullet/trace.h @@ -9,7 +9,6 @@ #include - enum traceWorldType { collisionWorldTrace = 1, From 38c2c5d480d7f159ebeb1566628f60dea577ca9a Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Thu, 9 Aug 2012 18:09:11 -0400 Subject: [PATCH 03/29] Creatures now use object physics --- apps/openmw/mwclass/creature.cpp | 2 +- components/files/ogreplugin.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 0f3141f5c..620f809e7 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -89,7 +89,7 @@ namespace MWClass { const std::string model = getModel(ptr); if(!model.empty()){ - physics.insertActorPhysics(ptr, model); + physics.insertObjectPhysics(ptr, model); } MWBase::Environment::get().getMechanicsManager()->addActor (ptr); } diff --git a/components/files/ogreplugin.hpp b/components/files/ogreplugin.hpp index c5292b3a2..2d56bfb47 100644 --- a/components/files/ogreplugin.hpp +++ b/components/files/ogreplugin.hpp @@ -32,7 +32,7 @@ namespace Ogre { class Root; } -#if (BOOST_VERSION <= 104300) +#if (BOOST_VERSION <= 104500) namespace boost { namespace filesystem { inline path absolute(const path& p, const path& base=current_path()) { From e7329d5f8bc36f29578304c6a111f9518e0623dd Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 12 Aug 2012 00:36:49 -0400 Subject: [PATCH 04/29] Creatures now have a properly positioned box shape --- apps/openmw/mwworld/physicssystem.cpp | 13 ++----------- components/nifbullet/bullet_nif_loader.cpp | 8 +++++++- components/nifbullet/bullet_nif_loader.hpp | 2 ++ libs/openengine/bullet/BulletShapeLoader.h | 3 ++- libs/openengine/bullet/physic.cpp | 15 ++++++++++++++- libs/openengine/bullet/physic.hpp | 2 +- 6 files changed, 28 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 7f773b5cb..3bdf76bcd 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -173,7 +173,7 @@ namespace MWWorld act->setWalkDirection(btVector3(0,0,0)); } playerMove::playercmd& pm_ref = playerphysics->cmd; - //playerphysics->ps.snappingImplemented = false; + pm_ref.rightmove = 0; pm_ref.forwardmove = 0; pm_ref.upmove = 0; @@ -259,17 +259,8 @@ 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; - btBoxShape* box = dynamic_cast(body->getCollisionShape()); - if(box != NULL){ - tr.setOrigin(btVector3(position.x,position.y,position.z + box->getHalfExtentsWithMargin().getZ())); - } - else - 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, diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 13c2cbbb7..7af56d04c 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -73,6 +73,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) resourceName = cShape->getName(); cShape->collide = false; mBoundingBox = NULL; + boxTranslation = Ogre::Vector3(0,0,0); mTriMesh = new btTriangleMesh(); @@ -126,8 +127,10 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) delete m_meshInterface; } }; + cShape->boxTranslation = boxTranslation; if(mBoundingBox != NULL) cShape->Shape = mBoundingBox; + else { currentShape = new TriangleMeshShape(mTriMesh,true); @@ -220,8 +223,11 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, if(node->hasBounds) { - btVector3 boxsize = getbtVector((node->boundXYZ)); + + btVector3 boxsize = getbtVector((node->boundXYZ)); + boxTranslation = node->boundPos; + mBoundingBox = new btBoxShape(boxsize); } diff --git a/components/nifbullet/bullet_nif_loader.hpp b/components/nifbullet/bullet_nif_loader.hpp index 8bf91d127..beb4274b0 100644 --- a/components/nifbullet/bullet_nif_loader.hpp +++ b/components/nifbullet/bullet_nif_loader.hpp @@ -102,6 +102,8 @@ private: std::string resourceName; std::string resourceGroup; + Ogre::Vector3 boxTranslation; + BulletShape* cShape;//current shape btTriangleMesh *mTriMesh; btBoxShape *mBoundingBox; diff --git a/libs/openengine/bullet/BulletShapeLoader.h b/libs/openengine/bullet/BulletShapeLoader.h index 316ee523c..c09f0dc7e 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,7 @@ public: virtual ~BulletShape(); btCollisionShape* Shape; + Ogre::Vector3 boxTranslation; //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 743024c40..9d0a290e9 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -332,7 +332,7 @@ namespace Physic mHeightFieldMap.erase(name); } - RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name,float scale) + RigidBody* PhysicEngine::createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation) { std::string sid = (boost::format("%07.3f") % scale).str(); std::string outputstring = mesh + sid; @@ -354,6 +354,19 @@ namespace Physic btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,shape->Shape); RigidBody* body = new RigidBody(CI,name); body->collide = shape->collide; + + btTransform tr; + btBoxShape* box = dynamic_cast(body->getCollisionShape()); + if(box != NULL){ + Ogre::Vector3 transrot = rotation * (shape->boxTranslation * scale); + Ogre::Vector3 newPosition = transrot + position; + tr.setOrigin(btVector3(newPosition.x, newPosition.y, newPosition.z)); + } + else + tr.setOrigin(btVector3(position.x,position.y,position.z)); + tr.setRotation(btQuaternion(rotation.x,rotation.y,rotation.z,rotation.w)); + body->setWorldTransform(tr); + return body; } diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 9ae8e7607..42f648766 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -146,7 +146,7 @@ namespace Physic * 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. */ - 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); /** * Add a HeightField to the simulation From 1f5bc229e0ef5c7e5d72b1f721bc0eb7c5e90e75 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Tue, 14 Aug 2012 18:04:58 -0400 Subject: [PATCH 05/29] Separate adjustRigidBody function --- apps/openmw/mwworld/physicssystem.cpp | 24 ++++++++++--------- apps/openmw/mwworld/physicssystem.hpp | 6 ++--- apps/openmw/mwworld/worldimp.cpp | 6 ++--- components/nifbullet/bullet_nif_loader.cpp | 2 +- libs/openengine/bullet/physic.cpp | 28 +++++++++++++--------- libs/openengine/bullet/physic.hpp | 2 ++ libs/openengine/bullet/trace.cpp | 5 +++- 7 files changed, 43 insertions(+), 30 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 3bdf76bcd..faacc5b06 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -193,8 +193,8 @@ namespace MWWorld Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); + //playerphysics->ps.snappingImplemented = false; - playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees(); @@ -280,19 +280,20 @@ 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) { 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(); + Ogre::Vector3 position = node->getPosition(); tr.setOrigin(btVector3(position.x,position.y,position.z)); body->setWorldTransform(tr); } if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) { - // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow + /*// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow // start positions others than 0, 0, 0 if (handle == "player") { @@ -301,31 +302,32 @@ namespace MWWorld else { act->setPosition(btVector3(position.x,position.y,position.z)); - } + }*/ } } - void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation) + void PhysicsSystem::rotateObject (const std::string& handle, Ogre::SceneNode* node) { - if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) + /*if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) { act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); - } + }*/ if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) { + Ogre::Quaternion rotation = node->getOrientation(); body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); } } - 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); } } diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index e42fa536b..4ed8d59f6 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -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 8fb7b1ba7..d5046db2d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -585,7 +585,7 @@ namespace MWWorld { moveObjectImp(ptr, x, y, z); - mPhysics->moveObject (ptr.getRefData().getHandle(), Ogre::Vector3 (x, y, z)); + mPhysics->moveObject (ptr.getRefData().getHandle(), ptr.getRefData().getBaseNode()); } void World::scaleObject (const Ptr& ptr, float scale) @@ -595,7 +595,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) @@ -610,7 +610,7 @@ namespace MWWorld Ogre::Quaternion roty(Ogre::Degree(-y),Ogre::Vector3::UNIT_Y); Ogre::Quaternion rotz(Ogre::Degree(-z),Ogre::Vector3::UNIT_Z); ptr.getRefData().getBaseNode()->setOrientation(rotx*roty*rotz); - mPhysics->rotateObject(ptr.getRefData().getHandle(),ptr.getRefData().getBaseNode()->getOrientation()); + mPhysics->rotateObject(ptr.getRefData().getHandle(),ptr.getRefData().getBaseNode()); } void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 7af56d04c..fc7fb5ec2 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -129,7 +129,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) }; cShape->boxTranslation = boxTranslation; if(mBoundingBox != NULL) - cShape->Shape = mBoundingBox; + cShape->Shape = mBoundingBox; else { diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 9d0a290e9..af73a42a6 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -332,6 +332,20 @@ namespace Physic mHeightFieldMap.erase(name); } + void PhysicEngine::adjustRigidBody(BulletShapePtr shape, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation){ + btTransform tr; + btBoxShape* box = dynamic_cast(body->getCollisionShape()); + if(box != NULL){ + Ogre::Vector3 transrot = rotation * (shape->boxTranslation * scale); + Ogre::Vector3 newPosition = transrot + position; + tr.setOrigin(btVector3(newPosition.x, newPosition.y, newPosition.z)); + } + else + tr.setOrigin(btVector3(position.x,position.y,position.z)); + tr.setRotation(btQuaternion(rotation.x,rotation.y,rotation.z,rotation.w)); + body->setWorldTransform(tr); + } + RigidBody* PhysicEngine::createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation) { std::string sid = (boost::format("%07.3f") % scale).str(); @@ -355,17 +369,9 @@ namespace Physic RigidBody* body = new RigidBody(CI,name); body->collide = shape->collide; - btTransform tr; - btBoxShape* box = dynamic_cast(body->getCollisionShape()); - if(box != NULL){ - Ogre::Vector3 transrot = rotation * (shape->boxTranslation * scale); - Ogre::Vector3 newPosition = transrot + position; - tr.setOrigin(btVector3(newPosition.x, newPosition.y, newPosition.z)); - } - else - tr.setOrigin(btVector3(position.x,position.y,position.z)); - tr.setRotation(btQuaternion(rotation.x,rotation.y,rotation.z,rotation.w)); - body->setWorldTransform(tr); + //Pass in BulletShape, RigidBody, scale, position, rotation + + adjustRigidBody(shape, body, scale, position, rotation); return body; diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 42f648766..fc52ad127 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -148,6 +148,8 @@ namespace Physic */ RigidBody* createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation); + void adjustRigidBody(BulletShapePtr shape, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation); + /** * Add a HeightField to the simulation */ diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 6d2166baa..2329ed652 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -21,6 +21,7 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr //if (!traceobj->incellptr) // return; + const Ogre::Vector3 rayDir = end - start; @@ -34,6 +35,7 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr //Ogre::Vector3 startReplace = Ogre::Vector3(650,950, 45); //Ogre::Vector3 endReplace = startReplace; //endReplace.z -= .25; + const bool hasHit = NewPhysicsTrace(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0f,0.0f), isInterior, enginePass); @@ -104,7 +106,8 @@ const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Ogre::Vector3& const btVector3 btend(end.x, end.y, end.z); const btQuaternion btrot(rotation.y, rotation.x, rotation.z); //y, x, z - const btBoxShape newshape(btVector3(BBHalfExtents.x, BBHalfExtents.y, BBHalfExtents.z)); + const 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); From 7b8b4c366d5de40e148b780b86e409544975385d Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Tue, 14 Aug 2012 20:29:48 -0400 Subject: [PATCH 06/29] Set angle now working for npcs and creatures --- apps/openmw/mwclass/npc.cpp | 3 +-- apps/openmw/mwworld/physicssystem.cpp | 16 ++++++++++++---- libs/openengine/bullet/physic.cpp | 12 ++++++++++++ libs/openengine/bullet/physic.hpp | 2 +- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 72501e8ac..217d92025 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -379,8 +379,7 @@ namespace MWClass void Npc::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const { - y = 0; - x = 0; + } MWWorld::Ptr diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index faacc5b06..3d4a08c69 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -286,10 +286,15 @@ namespace MWWorld { // 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(); Ogre::Vector3 position = node->getPosition(); - 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 + mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, position, node->getOrientation()); } if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) { @@ -315,7 +320,10 @@ namespace MWWorld if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) { Ogre::Quaternion rotation = node->getOrientation(); - 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); } } diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index af73a42a6..2f0624470 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -345,6 +345,18 @@ namespace Physic 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(shape, body, scale, position, rotation); + } RigidBody* PhysicEngine::createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation) { diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index fc52ad127..088bbc465 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -149,7 +149,7 @@ namespace Physic RigidBody* createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation); void adjustRigidBody(BulletShapePtr shape, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation); - + void boxAdjustExternal(std::string mesh, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation); /** * Add a HeightField to the simulation */ From 8762f4a47abfd873acc036e70f24859105d0a6f7 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 15 Aug 2012 16:47:26 -0400 Subject: [PATCH 07/29] boxrotation nif field; commented functions --- apps/openmw/mwworld/physicssystem.cpp | 2 +- components/nifbullet/bullet_nif_loader.cpp | 6 +++--- components/nifbullet/bullet_nif_loader.hpp | 2 +- libs/openengine/bullet/BulletShapeLoader.h | 1 + libs/openengine/bullet/physic.cpp | 3 ++- libs/openengine/bullet/physic.hpp | 9 +++++++++ libs/openengine/bullet/pmove.cpp | 5 ++++- 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 3d4a08c69..d1e39c8b7 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -194,7 +194,7 @@ namespace MWWorld //playerphysics->ps.snappingImplemented = false; - + //playerphysics->ps.speed = 240; playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees(); diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index fc7fb5ec2..6fec6241f 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -73,7 +73,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) resourceName = cShape->getName(); cShape->collide = false; mBoundingBox = NULL; - boxTranslation = Ogre::Vector3(0,0,0); + cShape->boxTranslation = Ogre::Vector3(0,0,0); mTriMesh = new btTriangleMesh(); @@ -127,7 +127,6 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) delete m_meshInterface; } }; - cShape->boxTranslation = boxTranslation; if(mBoundingBox != NULL) cShape->Shape = mBoundingBox; @@ -226,7 +225,8 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, btVector3 boxsize = getbtVector((node->boundXYZ)); - boxTranslation = node->boundPos; + cShape->boxTranslation = node->boundPos; + cShape->boxRotation = node->boundRot; mBoundingBox = new btBoxShape(boxsize); } diff --git a/components/nifbullet/bullet_nif_loader.hpp b/components/nifbullet/bullet_nif_loader.hpp index beb4274b0..82ac227a0 100644 --- a/components/nifbullet/bullet_nif_loader.hpp +++ b/components/nifbullet/bullet_nif_loader.hpp @@ -102,7 +102,7 @@ private: std::string resourceName; std::string resourceGroup; - Ogre::Vector3 boxTranslation; + BulletShape* cShape;//current shape btTriangleMesh *mTriMesh; diff --git a/libs/openengine/bullet/BulletShapeLoader.h b/libs/openengine/bullet/BulletShapeLoader.h index c09f0dc7e..8640fd54f 100644 --- a/libs/openengine/bullet/BulletShapeLoader.h +++ b/libs/openengine/bullet/BulletShapeLoader.h @@ -32,6 +32,7 @@ public: 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 2f0624470..0845864ef 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -336,9 +336,10 @@ namespace Physic btTransform tr; btBoxShape* box = dynamic_cast(body->getCollisionShape()); if(box != NULL){ - Ogre::Vector3 transrot = rotation * (shape->boxTranslation * scale); + Ogre::Vector3 transrot = rotation * shape->boxRotation * (shape->boxTranslation * scale); Ogre::Vector3 newPosition = transrot + position; tr.setOrigin(btVector3(newPosition.x, newPosition.y, newPosition.z)); + rotation = rotation * shape->boxRotation; } else tr.setOrigin(btVector3(position.x,position.y,position.z)); diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 088bbc465..403af6c6c 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -145,10 +145,19 @@ namespace Physic /** * 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. + + After created, the body is set to the correct rotation, position, and scale */ RigidBody* createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation); + /** + * Adjusts a rigid body to the right position and rotation + */ + void adjustRigidBody(BulletShapePtr shape, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation); + /** + 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 diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 4c70971a3..32a11179f 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -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) From 63a40e9ba320b4ca44413c72d4aabcafe482b465 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Thu, 16 Aug 2012 15:41:42 -0400 Subject: [PATCH 08/29] npc xy disabled --- apps/openmw/mwclass/npc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 217d92025..72501e8ac 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -379,7 +379,8 @@ namespace MWClass void Npc::adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const { - + y = 0; + x = 0; } MWWorld::Ptr From b7697a62adcbf5df4fa1d23e35292b4330719a18 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 29 Aug 2012 18:35:39 -0400 Subject: [PATCH 09/29] Position set back to zero --- libs/openengine/bullet/pmove.cpp | 2 +- libs/openengine/bullet/pmove.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 32a11179f..3d2462ab5 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -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 diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index a0fec3d1c..aa10a6bff 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -92,7 +92,7 @@ struct playerMove { playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), snappingImplemented(true), bSnap(false), counter(-1) { - origin = Ogre::Vector3(733.164f,900.0f, 839.432f); + 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); From 2efceba1fca6e5d430a5e285016a8937503ad9ec Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 3 Sep 2012 20:32:20 -0400 Subject: [PATCH 10/29] Tearing apart PhysicActor --- apps/openmw/mwworld/physicssystem.cpp | 22 +++--- apps/openmw/mwworld/physicssystem.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 2 +- libs/openengine/bullet/physic.cpp | 106 +++++++------------------- libs/openengine/bullet/physic.hpp | 30 ++++---- 5 files changed, 53 insertions(+), 109 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 0af9511cf..7b75ff948 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -254,12 +254,12 @@ namespace MWWorld } 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); + mEngine->addCharacter(handle, mesh, position, scale, rotation); OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle); - act->setPosition(btVector3(position.x,position.y,position.z)); + } void PhysicsSystem::removeObject (const std::string& handle) @@ -272,11 +272,12 @@ namespace MWWorld 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 - Ogre::Vector3 position = node->getPosition(); + if(dynamic_cast(body->getCollisionShape()) == NULL){ btTransform tr = body->getWorldTransform(); @@ -288,7 +289,7 @@ namespace MWWorld } if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) { - /*// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow + // TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow // start positions others than 0, 0, 0 if (handle == "player") { @@ -297,19 +298,20 @@ namespace MWWorld else { act->setPosition(btVector3(position.x,position.y,position.z)); - }*/ + } } } void PhysicsSystem::rotateObject (const std::string& handle, Ogre::SceneNode* node) { - /*if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) + Ogre::Quaternion rotation = node->getOrientation(); + if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) { + //Needs to be changed act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); - }*/ + } if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) { - Ogre::Quaternion rotation = node->getOrientation(); if(dynamic_cast(body->getCollisionShape()) == NULL) body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); else @@ -380,7 +382,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 949aa9d45..1427060f6 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, diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 73efdd816..7b1c4e819 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -189,7 +189,7 @@ 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)); + mPhysics->addActor (mPlayer->getPlayer().getRefData().getHandle(), "", Ogre::Vector3 (0, 0, 0), 0, Ogre::Quaternion::ZERO); // global variables mGlobalVariables = new Globals (mStore); diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 0845864ef..584c3db75 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -26,111 +26,71 @@ namespace Physic COL_RAYCASTING = BIT(3) }; - PhysicActor::PhysicActor(std::string name) + PhysicActor::PhysicActor(std::string name, std::string mesh, PhysicEngine* engine, Ogre::Vector3 position, Ogre::Quaternion rotation, float scale): + mName(name), mEngine(engine), mMesh(mesh), mBoxTranslation(Ogre::Vector3::ZERO), mBoxRotation(Ogre::Quaternion::ZERO), mBody(0) { - mName = name; // The capsule is at the origin btTransform transform; transform.setIdentity(); - // External capsule - externalGhostObject = new PairCachingGhostObject(name); - externalGhostObject->setWorldTransform( transform ); - - btScalar externalCapsuleHeight = 120; - btScalar externalCapsuleWidth = 19; - - externalCollisionShape = new btCapsuleShapeZ( externalCapsuleWidth, externalCapsuleHeight ); - externalCollisionShape->setMargin( 0.1 ); - - externalGhostObject->setCollisionShape( externalCollisionShape ); - externalGhostObject->setCollisionFlags( btCollisionObject::CF_CHARACTER_OBJECT ); - - // Internal capsule - internalGhostObject = new PairCachingGhostObject(name); - internalGhostObject->setWorldTransform( transform ); - //internalGhostObject->getBroadphaseHandle()->s - btScalar internalCapsuleHeight = 110; - btScalar internalCapsuleWidth = 17; - - internalCollisionShape = new btCapsuleShapeZ( internalCapsuleWidth, internalCapsuleHeight ); - internalCollisionShape->setMargin( 0.1 ); - - internalGhostObject->setCollisionShape( internalCollisionShape ); - internalGhostObject->setCollisionFlags( btCollisionObject::CF_CHARACTER_OBJECT ); - - mCharacter = new btKinematicCharacterController( externalGhostObject,internalGhostObject,btScalar( 40 ),1,4,20,9.8,0.2 ); - mCharacter->setUpAxis(btKinematicCharacterController::Z_AXIS); - mCharacter->setUseGhostSweepTest(false); - - mCharacter->mCollision = false; - setGravity(0); - - mTranslation = btVector3(0,0,70); } PhysicActor::~PhysicActor() { - delete mCharacter; - delete internalGhostObject; - delete internalCollisionShape; - delete externalGhostObject; - delete externalCollisionShape; + if(mBody){ + mEngine->dynamicsWorld->removeRigidBody(mBody); + delete mBody; + } } void PhysicActor::setGravity(float gravity) { - mCharacter->setGravity(gravity); - //mCharacter-> + } void PhysicActor::enableCollisions(bool collision) { - mCharacter->mCollision = collision; + } void PhysicActor::setVerticalVelocity(float z) { - mCharacter->setVerticalVelocity(z); + } bool PhysicActor::getCollisionMode() { - return mCharacter->mCollision; + return false; } void PhysicActor::setWalkDirection(const btVector3& mvt) { - mCharacter->setWalkDirection( mvt ); + } - void PhysicActor::Rotate(const btQuaternion& quat) - { - externalGhostObject->getWorldTransform().setRotation( externalGhostObject->getWorldTransform().getRotation() * quat ); - internalGhostObject->getWorldTransform().setRotation( internalGhostObject->getWorldTransform().getRotation() * quat ); - } + void PhysicActor::setRotation(const btQuaternion& quat) { - externalGhostObject->getWorldTransform().setRotation( quat ); - internalGhostObject->getWorldTransform().setRotation( quat ); + //externalGhostObject->getWorldTransform().setRotation( quat ); + //internalGhostObject->getWorldTransform().setRotation( quat ); } btVector3 PhysicActor::getPosition(void) { - return internalGhostObject->getWorldTransform().getOrigin() -mTranslation; + return btVector3(0,0,0);//return internalGhostObject->getWorldTransform().getOrigin() -mTranslation; } btQuaternion PhysicActor::getRotation(void) { - return internalGhostObject->getWorldTransform().getRotation(); + return btQuaternion(0,0,0);//return btQuaternion::internalGhostObject->getWorldTransform().getRotation(); } void PhysicActor::setPosition(const btVector3& pos) { - internalGhostObject->getWorldTransform().setOrigin(pos+mTranslation); - externalGhostObject->getWorldTransform().setOrigin(pos+mTranslation); + //internalGhostObject->getWorldTransform().setOrigin(pos+mTranslation); + //externalGhostObject->getWorldTransform().setOrigin(pos+mTranslation); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -247,9 +207,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; @@ -477,16 +435,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; } @@ -499,20 +458,7 @@ 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); diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 403af6c6c..af4d56e33 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -15,7 +15,6 @@ class btDefaultCollisionConfiguration; class btSequentialImpulseConstraintSolver; class btCollisionDispatcher; class btDiscreteDynamicsWorld; -class btKinematicCharacterController; class btHeightfieldTerrainShape; namespace BtOgre @@ -33,6 +32,8 @@ namespace Physic { class CMotionState; struct PhysicEvent; + class PhysicEngine; + class RigidBody; /** *This is just used to be able to name objects. @@ -55,7 +56,7 @@ namespace Physic 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(); @@ -66,8 +67,6 @@ namespace Physic */ void setWalkDirection(const btVector3& mvt); - void Rotate(const btQuaternion& quat); - void setRotation(const btQuaternion& quat); void setGravity(float gravity); @@ -84,21 +83,17 @@ namespace Physic void setPosition(const btVector3& pos); - btKinematicCharacterController* mCharacter; - - PairCachingGhostObject* internalGhostObject; - btCollisionShape* internalCollisionShape; - - PairCachingGhostObject* externalGhostObject; - btCollisionShape* externalCollisionShape; + 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 mBoxTranslation; + Ogre::Quaternion mBoxRotation; + std::string mMesh; + PhysicEngine* mEngine; }; /** @@ -195,7 +190,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? From 23777033fdcf94fc83479af7fdc71c1e0718a8dd Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 5 Sep 2012 17:44:11 -0400 Subject: [PATCH 11/29] Starting to implement new PhysicActor --- apps/openmw/mwclass/creature.cpp | 2 +- apps/openmw/mwclass/npc.cpp | 4 +-- apps/openmw/mwrender/renderingmanager.cpp | 4 ++- apps/openmw/mwworld/physicssystem.cpp | 8 +++-- apps/openmw/mwworld/worldimp.cpp | 4 ++- libs/openengine/bullet/physic.cpp | 44 +++++++++++++---------- libs/openengine/bullet/physic.hpp | 15 ++++---- libs/openengine/bullet/trace.cpp | 5 ++- 8 files changed, 49 insertions(+), 37 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index f03c0fdb1..7c6021652 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -89,7 +89,7 @@ namespace MWClass { const std::string model = getModel(ptr); if(!model.empty()){ - physics.insertObjectPhysics(ptr, model); + physics.insertActorPhysics(ptr, model); } MWBase::Environment::get().getMechanicsManager()->addActor (ptr); } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index c9b16ae1e..851cf050b 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -125,7 +125,7 @@ namespace MWClass void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const { - physics.insertObjectPhysics(ptr, getModel(ptr)); + physics.insertActorPhysics(ptr, getModel(ptr)); MWBase::Environment::get().getMechanicsManager()->addActor(ptr); } @@ -294,7 +294,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/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index edeb0fe12..bec84e0c9 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -266,13 +266,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 7b75ff948..4285eeb18 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -201,8 +201,7 @@ namespace MWWorld 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; } @@ -214,6 +213,7 @@ 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++) @@ -224,6 +224,7 @@ namespace MWWorld if(it->first == "player"){ coord = playerphysics->ps.origin ; + } @@ -257,8 +258,9 @@ namespace MWWorld const Ogre::Vector3& position, float scale, const Ogre::Quaternion& rotation) { //TODO:optimize this. Searching the std::map isn't very efficient i think. + std::cout << "NPC position" << position << "\n"; mEngine->addCharacter(handle, mesh, position, scale, rotation); - OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle); + } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 7b1c4e819..55c2f4161 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), 0, Ogre::Quaternion::ZERO); + 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); diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 584c3db75..7db0b154b 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -27,12 +27,12 @@ namespace Physic }; PhysicActor::PhysicActor(std::string name, std::string mesh, PhysicEngine* engine, Ogre::Vector3 position, Ogre::Quaternion rotation, float scale): - mName(name), mEngine(engine), mMesh(mesh), mBoxTranslation(Ogre::Vector3::ZERO), mBoxRotation(Ogre::Quaternion::ZERO), mBody(0) + mName(name), mEngine(engine), mMesh(mesh), mBoxTranslation(Ogre::Vector3::ZERO), mBoxRotation(Ogre::Quaternion::ZERO), mBody(0), collisionMode(false) { - - // The capsule is at the origin - btTransform transform; - transform.setIdentity(); + Ogre::Vector3 test; + mBody = mEngine->createAndAdjustRigidBody(mesh, mName, scale, position, rotation, &test); + std::cout << "Test" << test << "\n"; + mEngine->addRigidBody(mBody, false); //Add rigid body to dynamics world, but do not add to object map } @@ -51,7 +51,7 @@ namespace Physic void PhysicActor::enableCollisions(bool collision) { - + collisionMode = collision; } void PhysicActor::setVerticalVelocity(float z) @@ -61,7 +61,7 @@ namespace Physic bool PhysicActor::getCollisionMode() { - return false; + return collisionMode; } void PhysicActor::setWalkDirection(const btVector3& mvt) @@ -79,12 +79,12 @@ namespace Physic btVector3 PhysicActor::getPosition(void) { - return btVector3(0,0,0);//return internalGhostObject->getWorldTransform().getOrigin() -mTranslation; + return mBody->getWorldTransform().getOrigin();//return internalGhostObject->getWorldTransform().getOrigin() -mTranslation; } btQuaternion PhysicActor::getRotation(void) { - return btQuaternion(0,0,0);//return btQuaternion::internalGhostObject->getWorldTransform().getRotation(); + return mBody->getWorldTransform().getRotation();//return btQuaternion::internalGhostObject->getWorldTransform().getRotation(); } void PhysicActor::setPosition(const btVector3& pos) @@ -290,7 +290,8 @@ namespace Physic mHeightFieldMap.erase(name); } - void PhysicEngine::adjustRigidBody(BulletShapePtr shape, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation){ + void PhysicEngine::adjustRigidBody(BulletShapePtr shape, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation, + Ogre::Vector3 scaledBoxPosition, Ogre::Quaternion boxRotation){ btTransform tr; btBoxShape* box = dynamic_cast(body->getCollisionShape()); if(box != NULL){ @@ -317,8 +318,11 @@ namespace Physic adjustRigidBody(shape, body, scale, position, rotation); } - RigidBody* PhysicEngine::createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation) + RigidBody* PhysicEngine::createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation, + Ogre::Vector3* scaledBoxPosition, Ogre::Quaternion* boxRotation) { + if(scaledBoxPosition != 0) + *scaledBoxPosition = Ogre::Vector3(0, 5, 0); std::string sid = (boost::format("%07.3f") % scale).str(); std::string outputstring = mesh + sid; //std::cout << "The string" << outputstring << "\n"; @@ -348,7 +352,7 @@ namespace Physic } - void PhysicEngine::addRigidBody(RigidBody* body) + void PhysicEngine::addRigidBody(RigidBody* body, bool addToMap) { if(body) { @@ -361,14 +365,16 @@ 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 = RigidBodyMap[body->mName]; + if (oldBody != NULL) + { + dynamicsWorld->removeRigidBody(oldBody); + delete oldBody; + } + + RigidBodyMap[body->mName] = body; } - - RigidBodyMap[body->mName] = body; } } diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index af4d56e33..f22380483 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -92,6 +92,7 @@ namespace Physic OEngine::Physic::RigidBody* mBody; Ogre::Vector3 mBoxTranslation; Ogre::Quaternion mBoxRotation; + bool collisionMode; std::string mMesh; PhysicEngine* mEngine; }; @@ -138,18 +139,18 @@ 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. - - After created, the body is set to the correct rotation, position, and scale + * 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* createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation); + RigidBody* createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation, + Ogre::Vector3* scaledBoxPosition = 0, Ogre::Quaternion* boxRotation = 0); /** * Adjusts a rigid body to the right position and rotation */ - void adjustRigidBody(BulletShapePtr shape, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation); + void adjustRigidBody(BulletShapePtr shape, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation, + Ogre::Vector3 scaledBoxPosition = Ogre::Vector3::ZERO, Ogre::Quaternion boxRotation = Ogre::Quaternion::ZERO); /** Mainly used to (but not limited to) adjust rigid bodies based on box shapes to the right position and rotation. */ @@ -169,7 +170,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. diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 57b729db1..474d87ee9 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -35,9 +35,8 @@ void newtrace(traceResults* const results, const Ogre::Vector3& start, const Ogr //Ogre::Vector3 startReplace = Ogre::Vector3(650,950, 45); //Ogre::Vector3 endReplace = startReplace; //endReplace.z -= .25; - - const bool hasHit = NewPhysicsTrace(&out, start, end, BBHalfExtents, Ogre::Vector3(0.0f, 0.0f,0.0f), 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; @@ -100,7 +99,7 @@ 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); From 3e3437f9c3e2ed0bdf36bf4496a04d6d76f578ea Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Thu, 6 Sep 2012 20:11:59 -0400 Subject: [PATCH 12/29] Revised create and adjust rigid body functions --- libs/openengine/bullet/physic.cpp | 38 ++++++++++++++++--------------- libs/openengine/bullet/physic.hpp | 6 ++--- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 7db0b154b..f453915c8 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -290,18 +290,13 @@ namespace Physic mHeightFieldMap.erase(name); } - void PhysicEngine::adjustRigidBody(BulletShapePtr shape, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation, - Ogre::Vector3 scaledBoxPosition, Ogre::Quaternion boxRotation){ + void PhysicEngine::adjustRigidBody(RigidBody* body, Ogre::Vector3 position, Ogre::Quaternion rotation, + Ogre::Vector3 scaledBoxTranslation, Ogre::Quaternion boxRotation){ btTransform tr; - btBoxShape* box = dynamic_cast(body->getCollisionShape()); - if(box != NULL){ - Ogre::Vector3 transrot = rotation * shape->boxRotation * (shape->boxTranslation * scale); - Ogre::Vector3 newPosition = transrot + position; - tr.setOrigin(btVector3(newPosition.x, newPosition.y, newPosition.z)); - rotation = rotation * shape->boxRotation; - } - else - tr.setOrigin(btVector3(position.x,position.y,position.z)); + 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); } @@ -315,14 +310,18 @@ namespace Physic BulletShapeManager::getSingletonPtr()->load(outputstring,"General"); BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General"); - adjustRigidBody(shape, body, scale, position, rotation); + btBoxShape* box = dynamic_cast(shape->Shape); + if(box != NULL) + adjustRigidBody(body, position, rotation, shape->boxTranslation * scale, shape->boxRotation); + else + adjustRigidBody(body, position, rotation); } RigidBody* PhysicEngine::createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation, - Ogre::Vector3* scaledBoxPosition, Ogre::Quaternion* boxRotation) + Ogre::Vector3* scaledBoxTranslation, Ogre::Quaternion* boxRotation) { - if(scaledBoxPosition != 0) - *scaledBoxPosition = Ogre::Vector3(0, 5, 0); + if(scaledBoxTranslation != 0) + *scaledBoxTranslation = Ogre::Vector3(0, 5, 0); std::string sid = (boost::format("%07.3f") % scale).str(); std::string outputstring = mesh + sid; //std::cout << "The string" << outputstring << "\n"; @@ -332,6 +331,7 @@ namespace Physic BulletShapeManager::getSingletonPtr()->load(outputstring,"General"); BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General"); shape->Shape->setLocalScaling( btVector3(scale,scale,scale)); + // @@ -344,9 +344,11 @@ namespace Physic RigidBody* body = new RigidBody(CI,name); body->collide = shape->collide; - //Pass in BulletShape, RigidBody, scale, position, rotation - - adjustRigidBody(shape, body, scale, position, rotation); + btBoxShape* box = dynamic_cast(shape->Shape); + if(box != NULL) + adjustRigidBody(body, position, rotation, shape->boxTranslation * scale, shape->boxRotation); + else + adjustRigidBody(body, position, rotation); return body; diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index f22380483..f699b7d44 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -143,14 +143,14 @@ namespace Physic * After created, the body is set to the correct rotation, position, and scale */ RigidBody* createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation, - Ogre::Vector3* scaledBoxPosition = 0, Ogre::Quaternion* boxRotation = 0); + Ogre::Vector3* scaledBoxTranslation = 0, Ogre::Quaternion* boxRotation = 0); /** * Adjusts a rigid body to the right position and rotation */ - void adjustRigidBody(BulletShapePtr shape, RigidBody* body, float scale, Ogre::Vector3 position, Ogre::Quaternion rotation, - Ogre::Vector3 scaledBoxPosition = Ogre::Vector3::ZERO, Ogre::Quaternion boxRotation = Ogre::Quaternion::ZERO); + 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. */ From c5b25ef70b9264c2a9036bcbb04da7fb50336b25 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 10 Sep 2012 20:29:24 -0400 Subject: [PATCH 13/29] Very basic actor physics (no set scale/rotate functions) --- apps/openmw/mwrender/npcanimation.cpp | 1 + components/nifbullet/bullet_nif_loader.cpp | 1 + libs/openengine/bullet/physic.cpp | 46 +++++++++++----------- libs/openengine/bullet/physic.hpp | 7 ++-- 4 files changed, 28 insertions(+), 27 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index e509bd170..e0304e06e 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -122,6 +122,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRendere } + if(isFemale) mInsert->scale(race->data.height.female, race->data.height.female, race->data.height.female); else diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 6fec6241f..1dc22a0d3 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -74,6 +74,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) cShape->collide = false; mBoundingBox = NULL; cShape->boxTranslation = Ogre::Vector3(0,0,0); + cShape->boxRotation = Ogre::Quaternion::IDENTITY; mTriMesh = new btTriangleMesh(); diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index f453915c8..8fa7681f5 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -27,13 +27,10 @@ namespace Physic }; PhysicActor::PhysicActor(std::string name, std::string mesh, PhysicEngine* engine, Ogre::Vector3 position, Ogre::Quaternion rotation, float scale): - mName(name), mEngine(engine), mMesh(mesh), mBoxTranslation(Ogre::Vector3::ZERO), mBoxRotation(Ogre::Quaternion::ZERO), mBody(0), collisionMode(false) + mName(name), mEngine(engine), mMesh(mesh), mBoxScaledTranslation(0,0,0), mBoxRotationInverse(0,0,0,0), mBody(0), collisionMode(false), mBoxRotation(0,0,0,0) { - Ogre::Vector3 test; - mBody = mEngine->createAndAdjustRigidBody(mesh, mName, scale, position, rotation, &test); - std::cout << "Test" << test << "\n"; + mBody = mEngine->createAndAdjustRigidBody(mesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation, &mBoxRotationInverse); mEngine->addRigidBody(mBody, false); //Add rigid body to dynamics world, but do not add to object map - } PhysicActor::~PhysicActor() @@ -79,12 +76,17 @@ namespace Physic btVector3 PhysicActor::getPosition(void) { - return mBody->getWorldTransform().getOrigin();//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; + btVector3 visualPosition = vec - btVector3(transrot.x, transrot.y, transrot.z); + return visualPosition; } btQuaternion PhysicActor::getRotation(void) { - return mBody->getWorldTransform().getRotation();//return btQuaternion::internalGhostObject->getWorldTransform().getRotation(); + return mBody->getWorldTransform().getRotation() * mBoxRotationInverse; } void PhysicActor::setPosition(const btVector3& pos) @@ -296,6 +298,7 @@ namespace Physic 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); @@ -310,21 +313,14 @@ namespace Physic BulletShapeManager::getSingletonPtr()->load(outputstring,"General"); BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General"); - btBoxShape* box = dynamic_cast(shape->Shape); - if(box != NULL) - adjustRigidBody(body, position, rotation, shape->boxTranslation * scale, shape->boxRotation); - else - adjustRigidBody(body, position, rotation); + 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) + Ogre::Vector3* scaledBoxTranslation, btQuaternion* boxRotation, btQuaternion* boxRotationInverse) { - if(scaledBoxTranslation != 0) - *scaledBoxTranslation = Ogre::Vector3(0, 5, 0); 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"); @@ -332,9 +328,6 @@ namespace Physic BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(outputstring,"General"); shape->Shape->setLocalScaling( btVector3(scale,scale,scale)); - - - // //create the motionState CMotionState* newMotionState = new CMotionState(this,name); @@ -344,11 +337,16 @@ namespace Physic RigidBody* body = new RigidBody(CI,name); body->collide = shape->collide; - btBoxShape* box = dynamic_cast(shape->Shape); - if(box != NULL) - adjustRigidBody(body, position, rotation, shape->boxTranslation * scale, shape->boxRotation); - else - adjustRigidBody(body, position, rotation); + if(scaledBoxTranslation != 0) + *scaledBoxTranslation = shape->boxTranslation * scale; + if(boxRotation != 0) + *boxRotation = btQuaternion(shape->boxRotation.x, shape->boxRotation.y, shape->boxRotation.z,shape->boxRotation.w); + if(boxRotationInverse != 0){ + Ogre::Quaternion inverse = shape->boxRotation.Inverse(); + *boxRotationInverse = btQuaternion(inverse.x,inverse.y,inverse.z,inverse.w); + } + + adjustRigidBody(body, position, rotation, shape->boxTranslation * scale, shape->boxRotation); return body; diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index f699b7d44..1ff706146 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -90,8 +90,9 @@ namespace Physic private: OEngine::Physic::RigidBody* mBody; - Ogre::Vector3 mBoxTranslation; - Ogre::Quaternion mBoxRotation; + Ogre::Vector3 mBoxScaledTranslation; + btQuaternion mBoxRotationInverse; + btQuaternion mBoxRotation; bool collisionMode; std::string mMesh; PhysicEngine* mEngine; @@ -143,7 +144,7 @@ namespace Physic * After created, the body is set to the correct rotation, position, and 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); + Ogre::Vector3* scaledBoxTranslation = 0, btQuaternion* boxRotation = 0, btQuaternion* boxRotationInverse = 0); /** * Adjusts a rigid body to the right position and rotation From a1a773373007ff4f63d63cf92df07165c53f25dc Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 12 Sep 2012 18:30:32 -0400 Subject: [PATCH 14/29] Set scale implemented --- apps/openmw/mwworld/physicssystem.cpp | 9 +++++++-- libs/openengine/bullet/physic.cpp | 27 ++++++++++++++++++++++----- libs/openengine/bullet/physic.hpp | 6 +++--- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 4285eeb18..243ec61ba 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -218,9 +218,8 @@ namespace MWWorld 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 ; @@ -332,6 +331,12 @@ namespace MWWorld 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() diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 8fa7681f5..2824da4ca 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -29,7 +29,7 @@ namespace Physic 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(mesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation, &mBoxRotationInverse); + mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation, &mBoxRotationInverse); mEngine->addRigidBody(mBody, false); //Add rigid body to dynamics world, but do not add to object map } @@ -74,19 +74,20 @@ namespace Physic //internalGhostObject->getWorldTransform().setRotation( quat ); } - btVector3 PhysicActor::getPosition(void) + Ogre::Vector3 PhysicActor::getPosition(void) { 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; - btVector3 visualPosition = vec - btVector3(transrot.x, transrot.y, transrot.z); + Ogre::Vector3 visualPosition = Ogre::Vector3(vec.getX(), vec.getY(), vec.getZ()) - transrot; return visualPosition; } - btQuaternion PhysicActor::getRotation(void) + Ogre::Quaternion PhysicActor::getRotation(void) { - return mBody->getWorldTransform().getRotation() * mBoxRotationInverse; + btQuaternion quat = mBody->getWorldTransform().getRotation() * mBoxRotationInverse; + return Ogre::Quaternion(quat.getW(), quat.getX(), quat.getY(), quat.getZ()); } void PhysicActor::setPosition(const btVector3& pos) @@ -95,6 +96,22 @@ namespace Physic //externalGhostObject->getWorldTransform().setOrigin(pos+mTranslation); } + void PhysicActor::setScale(float scale){ + std::cout << "Trying to set scale to " << scale << "\n"; + 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 + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 1ff706146..2568cc36f 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -77,13 +77,13 @@ namespace Physic bool getCollisionMode(); - btVector3 getPosition(void); + Ogre::Vector3 getPosition(void); - btQuaternion getRotation(void); + Ogre::Quaternion getRotation(void); void setPosition(const btVector3& pos); - + void setScale(float scale); std::string mName; From 02bca98e9f45e0d13157d031f67593e069e55800 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 15 Sep 2012 13:23:49 -0400 Subject: [PATCH 15/29] Setrotate working --- apps/openmw/mwworld/physicssystem.cpp | 5 +---- libs/openengine/bullet/physic.cpp | 20 +++++++++----------- libs/openengine/bullet/physic.hpp | 11 ++++++++--- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 243ec61ba..5e58f61a3 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -257,10 +257,7 @@ namespace MWWorld const Ogre::Vector3& position, float scale, const Ogre::Quaternion& rotation) { //TODO:optimize this. Searching the std::map isn't very efficient i think. - std::cout << "NPC position" << position << "\n"; mEngine->addCharacter(handle, mesh, position, scale, rotation); - - } void PhysicsSystem::removeObject (const std::string& handle) @@ -309,7 +306,7 @@ namespace MWWorld if (OEngine::Physic::PhysicActor* act = mEngine->getCharacter(handle)) { //Needs to be changed - act->setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); + act->setRotation(rotation); } if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle)) { diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 2824da4ca..f3cebfb40 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -29,7 +29,9 @@ namespace Physic 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, &mBoxRotationInverse); + 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 } @@ -68,10 +70,11 @@ namespace Physic - 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); + } } Ogre::Vector3 PhysicActor::getPosition(void) @@ -97,7 +100,6 @@ namespace Physic } void PhysicActor::setScale(float scale){ - std::cout << "Trying to set scale to " << scale << "\n"; Ogre::Vector3 position = getPosition(); Ogre::Quaternion rotation = getRotation(); //We only need to change the scaled box translation, box rotations remain the same. @@ -334,7 +336,7 @@ namespace Physic } RigidBody* PhysicEngine::createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation, - Ogre::Vector3* scaledBoxTranslation, btQuaternion* boxRotation, btQuaternion* boxRotationInverse) + Ogre::Vector3* scaledBoxTranslation, Ogre::Quaternion* boxRotation) { std::string sid = (boost::format("%07.3f") % scale).str(); std::string outputstring = mesh + sid; @@ -357,11 +359,7 @@ namespace Physic if(scaledBoxTranslation != 0) *scaledBoxTranslation = shape->boxTranslation * scale; if(boxRotation != 0) - *boxRotation = btQuaternion(shape->boxRotation.x, shape->boxRotation.y, shape->boxRotation.z,shape->boxRotation.w); - if(boxRotationInverse != 0){ - Ogre::Quaternion inverse = shape->boxRotation.Inverse(); - *boxRotationInverse = btQuaternion(inverse.x,inverse.y,inverse.z,inverse.w); - } + *boxRotation = shape->boxRotation; adjustRigidBody(body, position, rotation, shape->boxTranslation * scale, shape->boxRotation); diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 2568cc36f..7ea6a323d 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -67,7 +67,12 @@ namespace Physic */ void setWalkDirection(const btVector3& mvt); - 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); @@ -92,7 +97,7 @@ namespace Physic OEngine::Physic::RigidBody* mBody; Ogre::Vector3 mBoxScaledTranslation; btQuaternion mBoxRotationInverse; - btQuaternion mBoxRotation; + Ogre::Quaternion mBoxRotation; bool collisionMode; std::string mMesh; PhysicEngine* mEngine; @@ -144,7 +149,7 @@ namespace Physic * After created, the body is set to the correct rotation, position, and scale */ RigidBody* createAndAdjustRigidBody(std::string mesh,std::string name,float scale, Ogre::Vector3 position, Ogre::Quaternion rotation, - Ogre::Vector3* scaledBoxTranslation = 0, btQuaternion* boxRotation = 0, btQuaternion* boxRotationInverse = 0); + Ogre::Vector3* scaledBoxTranslation = 0, Ogre::Quaternion* boxRotation = 0); /** * Adjusts a rigid body to the right position and rotation From f586f53a42e3ab3c4f10745c0ca2dc9b11298948 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 15 Sep 2012 16:45:50 -0400 Subject: [PATCH 16/29] positioning --- apps/openmw/mwworld/physicssystem.cpp | 7 +++++-- apps/openmw/mwworld/worldimp.cpp | 2 +- libs/openengine/bullet/physic.cpp | 5 ++--- libs/openengine/bullet/physic.hpp | 22 +++++++++++++++++++--- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 5e58f61a3..d0291b01a 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -282,8 +282,11 @@ namespace MWWorld tr.setOrigin(btVector3(position.x,position.y,position.z)); body->setWorldTransform(tr); } - else + 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)) { @@ -295,7 +298,7 @@ namespace MWWorld } else { - act->setPosition(btVector3(position.x,position.y,position.z)); + act->setPosition(position); } } } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 55c2f4161..3ad58dc7d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -637,7 +637,7 @@ 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; diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index f3cebfb40..9c387e140 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -93,10 +93,9 @@ namespace Physic 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); } void PhysicActor::setScale(float scale){ diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 7ea6a323d..1598d3e87 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -51,7 +51,8 @@ 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 { @@ -82,15 +83,29 @@ namespace Physic bool getCollisionMode(); + /** + * 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(void); + /** + * Returns the visual orientation of the PhysicActor + */ Ogre::Quaternion getRotation(void); - 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); + /** + * Sets the scale of the PhysicActor + */ void setScale(float scale); - std::string mName; + private: @@ -101,6 +116,7 @@ namespace Physic bool collisionMode; std::string mMesh; PhysicEngine* mEngine; + std::string mName; }; /** From f6384574dae1c31acb0dd7adc96e98838a589ac7 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 15 Sep 2012 18:17:42 -0400 Subject: [PATCH 17/29] Starting to introduce pmove --- libs/openengine/bullet/physic.cpp | 28 +++++++++++++++------------- libs/openengine/bullet/physic.hpp | 10 +++++++++- libs/openengine/bullet/trace.h | 2 +- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 9c387e140..a9f483aa4 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" @@ -33,6 +34,7 @@ namespace Physic 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; } PhysicActor::~PhysicActor() @@ -41,6 +43,7 @@ namespace Physic mEngine->dynamicsWorld->removeRigidBody(mBody); delete mBody; } + delete pmove; } void PhysicActor::setGravity(float gravity) @@ -210,8 +213,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) { @@ -380,22 +383,22 @@ namespace Physic } body->setActivationState(DISABLE_DEACTIVATION); if(addToMap){ - RigidBody* oldBody = RigidBodyMap[body->mName]; + RigidBody* oldBody = ObjectMap[body->mName]; if (oldBody != NULL) { dynamicsWorld->removeRigidBody(oldBody); delete oldBody; } - RigidBodyMap[body->mName] = body; + ObjectMap[body->mName] = body; } } } void PhysicEngine::removeRigidBody(std::string name) { - RigidBodyContainer::iterator it = RigidBodyMap.find(name); - if (it != RigidBodyMap.end() ) + RigidBodyContainer::iterator it = ObjectMap.find(name); + if (it != ObjectMap.end() ) { RigidBody* body = it->second; if(body != NULL) @@ -414,8 +417,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()); @@ -428,16 +431,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 @@ -483,7 +486,6 @@ namespace Physic } 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 1598d3e87..f51675398 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -9,6 +9,8 @@ #include "BulletShapeLoader.h" #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" + + class btRigidBody; class btBroadphaseInterface; class btDefaultCollisionConfiguration; @@ -16,6 +18,7 @@ class btSequentialImpulseConstraintSolver; class btCollisionDispatcher; class btDiscreteDynamicsWorld; class btHeightfieldTerrainShape; +struct playerMove; namespace BtOgre { @@ -27,6 +30,7 @@ namespace MWWorld class World; } + namespace OEngine { namespace Physic { @@ -109,6 +113,7 @@ namespace Physic private: + OEngine::Physic::RigidBody* mBody; Ogre::Vector3 mBoxScaledTranslation; btQuaternion mBoxRotationInverse; @@ -117,6 +122,8 @@ namespace Physic std::string mMesh; PhysicEngine* mEngine; std::string mName; + playerMove* pmove; + }; /** @@ -284,7 +291,7 @@ namespace Physic HeightFieldContainer mHeightFieldMap; typedef std::map RigidBodyContainer; - RigidBodyContainer RigidBodyMap; + RigidBodyContainer ObjectMap; typedef std::map PhysicActorContainer; PhysicActorContainer PhysicActorMap; @@ -293,6 +300,7 @@ namespace Physic BtOgre::DebugDrawer* mDebugDrawer; bool isDebugCreated; bool mDebugActive; + }; diff --git a/libs/openengine/bullet/trace.h b/libs/openengine/bullet/trace.h index bd554031a..1bfe0c717 100644 --- a/libs/openengine/bullet/trace.h +++ b/libs/openengine/bullet/trace.h @@ -5,8 +5,8 @@ #include #include #include -#include #include +#include "pmove.h" enum traceWorldType From 76f2a8288498910dd1f271dd43f4317b2785adeb Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 15 Sep 2012 22:48:24 -0400 Subject: [PATCH 18/29] More pmove stuff; Turned off broadphase, we could not fall in exteriors --- apps/openmw/mwworld/physicssystem.cpp | 8 ++++---- libs/openengine/bullet/physic.cpp | 17 ++++++++++++++--- libs/openengine/bullet/physic.hpp | 4 +++- libs/openengine/bullet/pmove.cpp | 2 +- libs/openengine/bullet/pmove.h | 4 ++-- libs/openengine/bullet/trace.cpp | 3 ++- 6 files changed, 26 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index d0291b01a..27bff68c6 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); + } } @@ -356,8 +360,6 @@ namespace MWWorld if(cmode) { act->enableCollisions(false); - act->setGravity(0.); - act->setVerticalVelocity(0); mFreeFly = true; return false; } @@ -365,8 +367,6 @@ namespace MWWorld { mFreeFly = false; act->enableCollisions(true); - act->setGravity(4.); - act->setVerticalVelocity(0); return true; } } diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index a9f483aa4..181aa62b5 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -46,19 +46,30 @@ namespace Physic delete pmove; } + void PhysicActor::setCurrentWater(bool hasWater, int waterHeight){ + pmove->hasWater = hasWater; + if(hasWater){ + pmove->waterHeight = waterHeight; + } + } + void PhysicActor::setGravity(float gravity) { - + pmove->ps.gravity = gravity; } void PhysicActor::enableCollisions(bool 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) { - + pmove->ps.jump_velocity = velocity; } bool PhysicActor::getCollisionMode() diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index f51675398..481fa2ed8 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -65,6 +65,8 @@ namespace Physic ~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: @@ -81,7 +83,7 @@ namespace Physic void setGravity(float gravity); - void setVerticalVelocity(float z); + void setJumpVelocity(float velocity); void enableCollisions(bool collision); diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index 3d2462ab5..f3e1a470a 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -704,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 ); diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index aef028ba4..63d03f86a 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -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,7 +89,7 @@ struct playerMove { struct playerStruct { - playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0), 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) { origin = Ogre::Vector3(0.0f, 0.0f, 0.0f); velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); @@ -122,6 +121,7 @@ struct playerMove 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 474d87ee9..03ed4ffb1 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -181,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; } } } From 192d6340985bd8b97e36dd241572fa972cfdce51 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 16 Sep 2012 13:19:38 -0400 Subject: [PATCH 19/29] Movement keys; View angles --- apps/openmw/mwworld/physicssystem.cpp | 4 ++-- libs/openengine/bullet/physic.cpp | 22 ++++++++++++++++++++-- libs/openengine/bullet/physic.hpp | 17 +++++++++++++---- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 27bff68c6..8de415980 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -176,11 +176,11 @@ 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; diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 181aa62b5..ca7709c2c 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -35,6 +35,7 @@ namespace Physic 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; } PhysicActor::~PhysicActor() @@ -77,9 +78,18 @@ namespace Physic return collisionMode; } - void PhysicActor::setWalkDirection(const btVector3& mvt) + void PhysicActor::setMovement(signed char rightmove, signed char forwardmove, signed char upmove) { - + playerMove::playercmd& pm_ref = pmove->cmd; + pm_ref.rightmove = rightmove; + pm_ref.forwardmove = forwardmove; + pm_ref.upmove = upmove; + } + + void PhysicActor::setPmoveViewAngles(float pitch, float yaw, float roll){ + pmove->ps.viewangles.x = pitch; + pmove->ps.viewangles.y = yaw; + pmove->ps.viewangles.z = roll; } @@ -110,6 +120,8 @@ namespace Physic void PhysicActor::setPosition(const Ogre::Vector3 pos) { 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){ @@ -127,6 +139,12 @@ namespace Physic mEngine->addRigidBody(mBody, false); //Add rigid body to dynamics world, but do not add to object map } + void PhysicActor::runPmove(){ + Pmove(pmove); + Ogre::Vector3 newpos = pmove->ps.origin; + mBody->getWorldTransform().setOrigin(btVector3(newpos.x, newpos.y, newpos.z)); + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 481fa2ed8..56b7f1fb7 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -68,11 +68,9 @@ namespace Physic 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); /** * This adjusts the rotation of a PhysicActor @@ -106,11 +104,22 @@ namespace Physic */ void setPosition(const Ogre::Vector3 pos); + /** + * Sets the view angles for pmove directly. + * Remember, add 90 for yaw. Set roll to 0. + */ + void setPmoveViewAngles(float pitch, float yaw, float roll); + /** * Sets the scale of the PhysicActor */ void setScale(float scale); + /** + * Runs pmove for this PhysicActor + */ + void runPmove(); + From 0fa1dea6c1cdd9c5a02b185db253a39896513dd0 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 16 Sep 2012 17:29:16 -0400 Subject: [PATCH 20/29] Box size set; Set speed --- libs/openengine/bullet/physic.cpp | 13 +++++++++++++ libs/openengine/bullet/physic.hpp | 2 ++ libs/openengine/bullet/pmove.cpp | 20 ++++++++++---------- libs/openengine/bullet/pmove.h | 5 +++-- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index ca7709c2c..4ced2db90 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -36,6 +36,10 @@ namespace Physic 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()); + btVector3 size = box->getHalfExtentsWithMargin(); + Ogre::Vector3 halfExtents = Ogre::Vector3(size.getX(), size.getY(), size.getZ()); + pmove->ps.halfExtents = halfExtents; } PhysicActor::~PhysicActor() @@ -58,6 +62,11 @@ namespace Physic { pmove->ps.gravity = gravity; } + + void PhysicActor::setSpeed(float speed) + { + pmove->ps.speed = speed; + } void PhysicActor::enableCollisions(bool collision) { @@ -137,6 +146,10 @@ namespace Physic //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()); + btVector3 size = box->getHalfExtentsWithMargin(); + Ogre::Vector3 halfExtents = Ogre::Vector3(size.getX(), size.getY(), size.getZ()); + pmove->ps.halfExtents = halfExtents; } void PhysicActor::runPmove(){ diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 56b7f1fb7..a69d80e53 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -81,6 +81,8 @@ namespace Physic void setGravity(float gravity); + void setSpeed(float speed); + void setJumpVelocity(float velocity); void enableCollisions(bool collision); diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index f3e1a470a..645abf205 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) { @@ -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, down, start_o, 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; @@ -902,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; } @@ -1182,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) { @@ -1228,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 ) { @@ -1240,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; } @@ -1341,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; @@ -1416,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 63d03f86a..fa303184e 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 @@ -89,7 +89,7 @@ struct playerMove { struct playerStruct { - 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) + 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(0.0f, 0.0f, 0.0f); velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); @@ -116,6 +116,7 @@ struct playerMove Ogre::Vector3 velocity; Ogre::Vector3 origin; + Ogre::Vector3 halfExtents; bool bSnap; bool snappingImplemented; int counter; From 05687c120fc5692bf04cbff89ab5230bd7ab78d7 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 16 Sep 2012 17:48:18 -0400 Subject: [PATCH 21/29] protection for null cast --- libs/openengine/bullet/physic.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 4ced2db90..b52c09eda 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -37,9 +37,11 @@ namespace Physic pmove = new playerMove; pmove->mEngine = mEngine; btBoxShape* box = static_cast (mBody->getCollisionShape()); - btVector3 size = box->getHalfExtentsWithMargin(); - Ogre::Vector3 halfExtents = Ogre::Vector3(size.getX(), size.getY(), size.getZ()); - pmove->ps.halfExtents = halfExtents; + if(box != NULL){ + btVector3 size = box->getHalfExtentsWithMargin(); + Ogre::Vector3 halfExtents = Ogre::Vector3(size.getX(), size.getY(), size.getZ()); + pmove->ps.halfExtents = halfExtents; + } } PhysicActor::~PhysicActor() @@ -147,9 +149,11 @@ namespace Physic 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()); - btVector3 size = box->getHalfExtentsWithMargin(); - Ogre::Vector3 halfExtents = Ogre::Vector3(size.getX(), size.getY(), size.getZ()); - pmove->ps.halfExtents = halfExtents; + 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(){ From f01aae138f1fc88f3358b4d31c2b024f52b60413 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 17 Sep 2012 17:23:26 -0400 Subject: [PATCH 22/29] Removing void --- libs/openengine/bullet/physic.cpp | 4 ++-- libs/openengine/bullet/physic.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index b52c09eda..74352b358 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -112,7 +112,7 @@ namespace Physic } } - Ogre::Vector3 PhysicActor::getPosition(void) + Ogre::Vector3 PhysicActor::getPosition() { btVector3 vec = mBody->getWorldTransform().getOrigin(); Ogre::Quaternion rotation = Ogre::Quaternion(mBody->getWorldTransform().getRotation().getW(), mBody->getWorldTransform().getRotation().getX(), @@ -122,7 +122,7 @@ namespace Physic return visualPosition; } - Ogre::Quaternion PhysicActor::getRotation(void) + Ogre::Quaternion PhysicActor::getRotation() { btQuaternion quat = mBody->getWorldTransform().getRotation() * mBoxRotationInverse; return Ogre::Quaternion(quat.getW(), quat.getX(), quat.getY(), quat.getZ()); diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index a69d80e53..e4e71706f 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -93,12 +93,12 @@ namespace Physic * 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(void); + Ogre::Vector3 getPosition(); /** * Returns the visual orientation of the PhysicActor */ - Ogre::Quaternion getRotation(void); + Ogre::Quaternion getRotation(); /** * Sets the position of mBody from a visual position input. From 0ba996f290eefb21ae11e93f81ef0f6421426dea Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 18 Sep 2012 18:29:03 +0200 Subject: [PATCH 23/29] dialog layout --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwgui/waitdialog.cpp | 12 ++ apps/openmw/mwgui/waitdialog.hpp | 19 +++ apps/openmw/mwgui/widgets.cpp | 166 ++++++++++++++++++++++--- apps/openmw/mwgui/widgets.hpp | 19 ++- apps/openmw/mwgui/windowmanagerimp.cpp | 9 +- apps/openmw/mwgui/windowmanagerimp.hpp | 2 + files/mygui/CMakeLists.txt | 1 + files/mygui/openmw_wait_dialog.layout | 45 +++++++ 9 files changed, 257 insertions(+), 18 deletions(-) create mode 100644 apps/openmw/mwgui/waitdialog.cpp create mode 100644 apps/openmw/mwgui/waitdialog.hpp create mode 100644 files/mygui/openmw_wait_dialog.layout diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 2542ef350..bcd5fc853 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -29,7 +29,7 @@ add_openmw_dir (mwgui map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list formatting inventorywindow container hud countdialog tradewindow settingswindow confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu - itemselection spellbuyingwindow loadingscreen levelupdialog + itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp new file mode 100644 index 000000000..5b491a4f2 --- /dev/null +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -0,0 +1,12 @@ +#include "waitdialog.hpp" + +namespace MWGui +{ + + WaitDialog::WaitDialog(MWBase::WindowManager &parWindowManager) + : WindowBase("openmw_wait_dialog.layout", parWindowManager) + { + center(); + } + +} diff --git a/apps/openmw/mwgui/waitdialog.hpp b/apps/openmw/mwgui/waitdialog.hpp new file mode 100644 index 000000000..3c68c1249 --- /dev/null +++ b/apps/openmw/mwgui/waitdialog.hpp @@ -0,0 +1,19 @@ +#ifndef MWGUI_WAIT_DIALOG_H +#define MWGUI_WAIT_DIALOG_H + +#include "window_base.hpp" + +namespace MWGui +{ + + class WaitDialog : public WindowBase + { + public: + WaitDialog(MWBase::WindowManager& parWindowManager); + + + }; + +} + +#endif diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 97a5b2eb5..e8cee2141 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -869,29 +869,33 @@ void AutoSizedButton::setPropertyOverride(const std::string& _key, const std::st Box::Box() : mSpacing(4) + , mPadding(0) + , mAutoResize(false) { } -void Box::setPropertyOverride(const std::string& _key, const std::string& _value) -{ - if (_key == "Spacing") - { - mSpacing = MyGUI::utility::parseValue(_value); - } -} - void Box::notifyChildrenSizeChanged () { align(); } +void Box::_setPropertyImpl(const std::string& _key, const std::string& _value) +{ + if (_key == "Spacing") + mSpacing = MyGUI::utility::parseValue(_value); + else if (_key == "Padding") + mPadding = MyGUI::utility::parseValue(_value); + else if (_key == "AutoResize") + mAutoResize = MyGUI::utility::parseValue(_value); +} void HBox::align () { unsigned int count = getChildCount (); size_t h_stretched_count = 0; int total_width = 0; + int total_height = 0; std::vector< std::pair > sizes; for (unsigned int i = 0; i < count; ++i) @@ -904,28 +908,43 @@ void HBox::align () { sizes.push_back(std::make_pair(aw->getRequestedSize (), hstretch)); total_width += aw->getRequestedSize ().width; + total_height = std::max(total_height, aw->getRequestedSize ().height); } else { - if (!hstretch) h_stretched_count ++; - sizes.push_back (std::make_pair(MyGUI::IntSize(0,0), true)); + sizes.push_back (std::make_pair(w->getSize(), hstretch)); + total_width += w->getSize().width; } if (i != count-1) total_width += mSpacing; } + if (mAutoResize && (total_width+mPadding*2 != getSize().width || total_height+mPadding*2 != getSize().height)) + { + setSize(MyGUI::IntSize(total_width+mPadding*2, total_height+mPadding*2)); + return; + } + + int curX = 0; for (unsigned int i = 0; i < count; ++i) { + if (i == 0) + curX += mPadding; + MyGUI::Widget* w = getChildAt(i); + + bool vstretch = w->getUserString ("VStretch") == "true"; + int height = vstretch ? total_height : sizes[i].first.height; + MyGUI::IntCoord widgetCoord; widgetCoord.left = curX; - widgetCoord.top = (getSize().height - sizes[i].first.height) / 2; - int width = sizes[i].second ? sizes[i].first.width + (getSize().width - total_width)/h_stretched_count + widgetCoord.top = mPadding + (getSize().height-mPadding*2 - height) / 2; + int width = sizes[i].second ? sizes[i].first.width + (getSize().width-mPadding*2 - total_width)/h_stretched_count : sizes[i].first.width; widgetCoord.width = width; - widgetCoord.height = sizes[i].first.height; + widgetCoord.height = height; w->setCoord(widgetCoord); curX += width; @@ -934,12 +953,33 @@ void HBox::align () } } +void HBox::setPropertyOverride(const std::string& _key, const std::string& _value) +{ + Box::_setPropertyImpl (_key, _value); +} + void HBox::setSize (const MyGUI::IntSize& _value) { MyGUI::Widget::setSize (_value); align(); } +void HBox::setCoord (const MyGUI::IntCoord& _value) +{ + MyGUI::Widget::setCoord (_value); + align(); +} + +void HBox::onWidgetCreated(MyGUI::Widget* _widget) +{ + align(); +} + +void HBox::onWidgetDestroy(MyGUI::Widget* _widget) +{ + align(); +} + MyGUI::IntSize HBox::getRequestedSize () { MyGUI::IntSize size(0,0); @@ -954,6 +994,16 @@ MyGUI::IntSize HBox::getRequestedSize () if (i != getChildCount()-1) size.width += mSpacing; } + else + { + MyGUI::IntSize requested = getChildAt(i)->getSize (); + size.height = std::max(size.height, requested.height); + size.width = size.width + requested.width; + if (i != getChildCount()-1) + size.width += mSpacing; + } + size.height += mPadding*2; + size.width += mPadding*2; } return size; } @@ -963,7 +1013,69 @@ MyGUI::IntSize HBox::getRequestedSize () void VBox::align () { - // not yet implemented + unsigned int count = getChildCount (); + size_t v_stretched_count = 0; + int total_height = 0; + int total_width = 0; + std::vector< std::pair > sizes; + for (unsigned int i = 0; i < count; ++i) + { + MyGUI::Widget* w = getChildAt(i); + bool vstretch = w->getUserString ("VStretch") == "true"; + v_stretched_count += vstretch; + AutoSizedWidget* aw = dynamic_cast(w); + if (aw) + { + sizes.push_back(std::make_pair(aw->getRequestedSize (), vstretch)); + total_height += aw->getRequestedSize ().height; + total_width = std::max(total_width, aw->getRequestedSize ().width); + } + else + { + sizes.push_back (std::make_pair(w->getSize(), vstretch)); + total_height += w->getSize().height; + } + + if (i != count-1) + total_height += mSpacing; + } + + if (mAutoResize && (total_width+mPadding*2 != getSize().width || total_height+mPadding*2 != getSize().height)) + { + setSize(MyGUI::IntSize(total_width+mPadding*2, total_height+mPadding*2)); + return; + } + + + int curY = 0; + for (unsigned int i = 0; i < count; ++i) + { + if (i==0) + curY += mPadding; + + MyGUI::Widget* w = getChildAt(i); + + bool hstretch = w->getUserString ("HStretch") == "true"; + int width = hstretch ? total_width : sizes[i].first.width; + + MyGUI::IntCoord widgetCoord; + widgetCoord.top = curY; + widgetCoord.left = mPadding + (getSize().width-mPadding*2 - width) / 2; + int height = sizes[i].second ? sizes[i].first.height + (getSize().height-mPadding*2 - total_height)/v_stretched_count + : sizes[i].first.height; + widgetCoord.height = height; + widgetCoord.width = width; + w->setCoord(widgetCoord); + curY += height; + + if (i != count-1) + curY += mSpacing; + } +} + +void VBox::setPropertyOverride(const std::string& _key, const std::string& _value) +{ + Box::_setPropertyImpl (_key, _value); } void VBox::setSize (const MyGUI::IntSize& _value) @@ -972,6 +1084,12 @@ void VBox::setSize (const MyGUI::IntSize& _value) align(); } +void VBox::setCoord (const MyGUI::IntCoord& _value) +{ + MyGUI::Widget::setCoord (_value); + align(); +} + MyGUI::IntSize VBox::getRequestedSize () { MyGUI::IntSize size(0,0); @@ -986,6 +1104,26 @@ MyGUI::IntSize VBox::getRequestedSize () if (i != getChildCount()-1) size.height += mSpacing; } + else + { + MyGUI::IntSize requested = getChildAt(i)->getSize (); + size.width = std::max(size.width, requested.width); + size.height = size.height + requested.height; + if (i != getChildCount()-1) + size.height += mSpacing; + } + size.height += mPadding*2; + size.width += mPadding*2; } return size; } + +void VBox::onWidgetCreated(MyGUI::Widget* _widget) +{ + align(); +} + +void VBox::onWidgetDestroy(MyGUI::Widget* _widget) +{ + align(); +} diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index 16c2adec9..6298ea77d 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -357,10 +357,13 @@ namespace MWGui protected: virtual void align() = 0; - virtual void setPropertyOverride(const std::string& _key, const std::string& _value); - + virtual void _setPropertyImpl(const std::string& _key, const std::string& _value); int mSpacing; // how much space to put between elements + + int mPadding; // outer padding + + bool mAutoResize; // auto resize the box so that it exactly fits all elements }; class HBox : public Box, public MyGUI::Widget @@ -369,10 +372,16 @@ namespace MWGui public: virtual void setSize (const MyGUI::IntSize &_value); + virtual void setCoord (const MyGUI::IntCoord &_value); protected: virtual void align(); virtual MyGUI::IntSize getRequestedSize(); + + virtual void setPropertyOverride(const std::string& _key, const std::string& _value); + + virtual void onWidgetCreated(MyGUI::Widget* _widget); + virtual void onWidgetDestroy(MyGUI::Widget* _widget); }; class VBox : public Box, public MyGUI::Widget @@ -381,10 +390,16 @@ namespace MWGui public: virtual void setSize (const MyGUI::IntSize &_value); + virtual void setCoord (const MyGUI::IntCoord &_value); protected: virtual void align(); virtual MyGUI::IntSize getRequestedSize(); + + virtual void setPropertyOverride(const std::string& _key, const std::string& _value); + + virtual void onWidgetCreated(MyGUI::Widget* _widget); + virtual void onWidgetDestroy(MyGUI::Widget* _widget); }; } } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 0241cc734..5efd2b47a 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -45,6 +45,7 @@ #include "quickkeysmenu.hpp" #include "loadingscreen.hpp" #include "levelupdialog.hpp" +#include "waitdialog.hpp" using namespace MWGui; @@ -71,6 +72,8 @@ WindowManager::WindowManager( , mSpellWindow(NULL) , mLoadingScreen(NULL) , mCharGen(NULL) + , mLevelupDialog(NULL) + , mWaitDialog(NULL) , mPlayerClass() , mPlayerName() , mPlayerRaceId() @@ -150,6 +153,7 @@ WindowManager::WindowManager( mSpellWindow = new SpellWindow(*this); mQuickKeysMenu = new QuickKeysMenu(*this); mLevelupDialog = new LevelupDialog(*this); + mWaitDialog = new WaitDialog(*this); mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this); mLoadingScreen->onResChange (w,h); @@ -204,6 +208,7 @@ WindowManager::~WindowManager() delete mSpellWindow; delete mLoadingScreen; delete mLevelupDialog; + delete mWaitDialog; cleanupGarbage(); @@ -252,6 +257,7 @@ void WindowManager::updateVisible() mSpellWindow->setVisible(false); mQuickKeysMenu->setVisible(false); mLevelupDialog->setVisible(false); + mWaitDialog->setVisible(false); mHud->setVisible(true); @@ -304,7 +310,8 @@ void WindowManager::updateVisible() mAlchemyWindow->setVisible(true); break; case GM_Rest: - mLevelupDialog->setVisible(true); + //mLevelupDialog->setVisible(true); + mWaitDialog->setVisible(true); break; case GM_Name: case GM_Race: diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index a02aa17b5..15c9c6631 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -63,6 +63,7 @@ namespace MWGui class QuickKeysMenu; class LoadingScreen; class LevelupDialog; + class WaitDialog; class WindowManager : public MWBase::WindowManager { @@ -229,6 +230,7 @@ namespace MWGui QuickKeysMenu* mQuickKeysMenu; LoadingScreen* mLoadingScreen; LevelupDialog* mLevelupDialog; + WaitDialog* mWaitDialog; CharacterCreation* mCharGen; diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index 55230fa76..44235fa0e 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -73,6 +73,7 @@ set(MYGUI_FILES openmw_spell_buying_window.layout openmw_loading_screen.layout openmw_levelup_dialog.layout + openmw_wait_dialog.layout smallbars.png VeraMono.ttf markers.png diff --git a/files/mygui/openmw_wait_dialog.layout b/files/mygui/openmw_wait_dialog.layout new file mode 100644 index 000000000..527d5158d --- /dev/null +++ b/files/mygui/openmw_wait_dialog.layout @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From ab698bb401ad668f9c6713471a49ee45d73d571c Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 18 Sep 2012 20:53:32 +0200 Subject: [PATCH 24/29] date time label --- apps/openmw/mwbase/world.hpp | 5 ++ apps/openmw/mwgui/waitdialog.cpp | 101 ++++++++++++++++++++++++++ apps/openmw/mwgui/waitdialog.hpp | 16 ++++ apps/openmw/mwgui/widgets.cpp | 10 ++- apps/openmw/mwworld/worldimp.cpp | 20 +++++ apps/openmw/mwworld/worldimp.hpp | 5 ++ files/mygui/openmw_wait_dialog.layout | 11 +-- 7 files changed, 159 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index b841e5427..05b31b3df 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -160,6 +160,9 @@ namespace MWBase virtual void setDay (int day) = 0; ///< Set in-game time day. + virtual int getDay() = 0; + virtual int getMonth() = 0; + virtual MWWorld::TimeStamp getTimeStamp() const = 0; ///< Return current in-game time stamp. @@ -281,6 +284,8 @@ namespace MWBase virtual void renderPlayer() = 0; virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0; + + virtual bool canRest() = 0; }; } diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index 5b491a4f2..622191566 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -1,12 +1,113 @@ #include "waitdialog.hpp" +#include + +#include + +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" + +#include "../mwworld/timestamp.hpp" + +#include "widgets.hpp" + + namespace MWGui { WaitDialog::WaitDialog(MWBase::WindowManager &parWindowManager) : WindowBase("openmw_wait_dialog.layout", parWindowManager) { + getWidget(mDateTimeText, "DateTimeText"); + getWidget(mRestText, "RestText"); + getWidget(mHourText, "HourText"); + getWidget(mHourSlider, "HourSlider"); + getWidget(mUntilHealedButton, "UntilHealedButton"); + getWidget(mWaitButton, "WaitButton"); + getWidget(mCancelButton, "CancelButton"); + + mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onCancelButtonClicked); + mUntilHealedButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onUntilHealedButtonClicked); + mWaitButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onWaitButtonClicked); + + mHourSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &WaitDialog::onHourSliderChangedPosition); + } + + void WaitDialog::open() + { + setCanRest(MWBase::Environment::get().getWorld ()->canRest ()); + + onHourSliderChangedPosition(mHourSlider, 0); + mHourSlider->setScrollPosition (0); + + // http://www.uesp.net/wiki/Lore:Calendar + std::string month; + int m = MWBase::Environment::get().getWorld ()->getMonth (); + if (m == 0) + month = "#{sMonthMorningstar}"; + else if (m == 1) + month = "#{sMonthSunsdawn}"; + else if (m == 2) + month = "#{sMonthFirstseed}"; + else if (m == 3) + month = "#{sMonthRainshand}"; + else if (m == 4) + month = "#{sMonthSecondseed}"; + else if (m == 5) + month = "#{sMonthMidyear}"; + else if (m == 6) + month = "#{sMonthSunsheight}"; + else if (m == 7) + month = "#{sMonthLastseed}"; + else if (m == 8) + month = "#{sMonthHeartfire}"; + else if (m == 9) + month = "#{sMonthFrostfall}"; + else if (m == 10) + month = "#{sMonthSunsdusk}"; + else if (m == 11) + month = "#{sMonthEveningstar}"; + + int hour = MWBase::Environment::get().getWorld ()->getTimeStamp ().getHour (); + bool pm = hour >= 12; + if (hour >= 13) hour -= 12; + + std::string dateTimeText = + boost::lexical_cast(MWBase::Environment::get().getWorld ()->getDay ()+1) + " " + + month + " (#{sDay} " + boost::lexical_cast(MWBase::Environment::get().getWorld ()->getTimeStamp ().getDay ()+1) + + ") " + boost::lexical_cast(hour) + " " + (pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}"); + + mDateTimeText->setCaptionWithReplacing (dateTimeText); + center(); } + void WaitDialog::onUntilHealedButtonClicked(MyGUI::Widget* sender) + { + + } + + void WaitDialog::onWaitButtonClicked(MyGUI::Widget* sender) + { + //MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1); + } + + void WaitDialog::onCancelButtonClicked(MyGUI::Widget* sender) + { + mWindowManager.removeGuiMode (GM_Rest); + } + + void WaitDialog::onHourSliderChangedPosition(MyGUI::ScrollBar* sender, size_t position) + { + mHourText->setCaptionWithReplacing (boost::lexical_cast(position+1) + " #{sRestMenu2}"); + } + + void WaitDialog::setCanRest (bool canRest) + { + mUntilHealedButton->setVisible(canRest); + mWaitButton->setCaptionWithReplacing (canRest ? "#{sRest}" : "#{sWait}"); + mRestText->setCaptionWithReplacing (canRest ? "#{sRestMenu3}" : "#{sRestIllegal}"); + } + } diff --git a/apps/openmw/mwgui/waitdialog.hpp b/apps/openmw/mwgui/waitdialog.hpp index 3c68c1249..040779819 100644 --- a/apps/openmw/mwgui/waitdialog.hpp +++ b/apps/openmw/mwgui/waitdialog.hpp @@ -11,7 +11,23 @@ namespace MWGui public: WaitDialog(MWBase::WindowManager& parWindowManager); + virtual void open(); + protected: + MyGUI::TextBox* mDateTimeText; + MyGUI::TextBox* mRestText; + MyGUI::TextBox* mHourText; + MyGUI::ScrollBar* mHourSlider; + MyGUI::Button* mUntilHealedButton; + MyGUI::Button* mWaitButton; + MyGUI::Button* mCancelButton; + + void onUntilHealedButtonClicked(MyGUI::Widget* sender); + void onWaitButtonClicked(MyGUI::Widget* sender); + void onCancelButtonClicked(MyGUI::Widget* sender); + void onHourSliderChangedPosition(MyGUI::ScrollBar* sender, size_t position); + + void setCanRest(bool canRest); }; } diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index e8cee2141..4f7ecb775 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -998,7 +998,10 @@ MyGUI::IntSize HBox::getRequestedSize () { MyGUI::IntSize requested = getChildAt(i)->getSize (); size.height = std::max(size.height, requested.height); - size.width = size.width + requested.width; + + if (getChildAt(i)->getUserString("HStretch") != "true") + size.width = size.width + requested.width; + if (i != getChildCount()-1) size.width += mSpacing; } @@ -1108,7 +1111,10 @@ MyGUI::IntSize VBox::getRequestedSize () { MyGUI::IntSize requested = getChildAt(i)->getSize (); size.width = std::max(size.width, requested.width); - size.height = size.height + requested.height; + + if (getChildAt(i)->getUserString("VStretch") != "true") + size.height = size.height + requested.height; + if (i != getChildCount()-1) size.height += mSpacing; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 831611618..af0a53655 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -450,6 +450,16 @@ namespace MWWorld mRendering->skySetDate (mGlobalVariables->getInt ("day"), month); } + int World::getDay() + { + return mGlobalVariables->getInt("day"); + } + + int World::getMonth() + { + return mGlobalVariables->getInt("month"); + } + TimeStamp World::getTimeStamp() const { return TimeStamp (mGlobalVariables->getFloat ("gamehour"), @@ -1241,4 +1251,14 @@ namespace MWWorld { mRendering->setupExternalRendering (rendering); } + + bool World::canRest () + { + Ptr::CellStore *currentCell = mWorldScene->getCurrentCell(); + assert (currentCell); + if (currentCell->cell->data.flags & ESM::Cell::NoSleep) + return false; + else + return true; + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index d48a0ec81..e918a85e0 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -179,6 +179,9 @@ namespace MWWorld virtual void setDay (int day); ///< Set in-game time day. + virtual int getDay(); + virtual int getMonth(); + virtual TimeStamp getTimeStamp() const; ///< Return current in-game time stamp. @@ -312,6 +315,8 @@ namespace MWWorld virtual void renderPlayer(); virtual void setupExternalRendering (MWRender::ExternalRendering& rendering); + + virtual bool canRest(); }; } diff --git a/files/mygui/openmw_wait_dialog.layout b/files/mygui/openmw_wait_dialog.layout index 527d5158d..66e0ec22f 100644 --- a/files/mygui/openmw_wait_dialog.layout +++ b/files/mygui/openmw_wait_dialog.layout @@ -6,22 +6,19 @@ - + - - + - - + - - + From 4829f47a4f86234658cc1a11406b761636d34151 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 18 Sep 2012 21:04:43 +0200 Subject: [PATCH 25/29] rewrote the fader to use Rectangle2d instead of overlay, in order to not cover the UI --- libs/openengine/ogre/fader.cpp | 61 +++++++++++++------------- libs/openengine/ogre/fader.hpp | 72 +++++++++++++++---------------- libs/openengine/ogre/renderer.cpp | 2 +- 3 files changed, 66 insertions(+), 69 deletions(-) diff --git a/libs/openengine/ogre/fader.cpp b/libs/openengine/ogre/fader.cpp index 41b7773ea..498b659ee 100644 --- a/libs/openengine/ogre/fader.cpp +++ b/libs/openengine/ogre/fader.cpp @@ -1,52 +1,49 @@ #include "fader.hpp" -#include -#include -#include #include #include #include #include +#include +#include -#define FADE_OVERLAY_NAME "FadeInOutOverlay" -#define FADE_OVERLAY_PANEL_NAME "FadeInOutOverlayPanel" -#define FADE_MATERIAL_NAME "FadeInOutMaterial" using namespace Ogre; using namespace OEngine::Render; -Fader::Fader() : - mMode(FadingMode_In), - mRemainingTime(0.f), - mTargetTime(0.f), - mTargetAlpha(0.f), - mCurrentAlpha(0.f), - mStartAlpha(0.f) +Fader::Fader(Ogre::SceneManager* sceneMgr) + : mSceneMgr(sceneMgr) + , mMode(FadingMode_In) + , mRemainingTime(0.f) + , mTargetTime(0.f) + , mTargetAlpha(0.f) + , mCurrentAlpha(0.f) + , mStartAlpha(0.f) { - // Create the fading material - MaterialPtr material = MaterialManager::getSingleton().create( FADE_MATERIAL_NAME, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME ); + MaterialPtr material = MaterialManager::getSingleton().create("FadeInOutMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME ); Pass* pass = material->getTechnique(0)->getPass(0); pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); mFadeTextureUnit = pass->createTextureUnitState(); mFadeTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(0.f, 0.f, 0.f)); // always black colour - // Create the overlay - OverlayManager& ovm = OverlayManager::getSingleton(); + mRectangle = new Ogre::Rectangle2D(true); + mRectangle->setCorners(-1.0, 1.0, 1.0, -1.0); + mRectangle->setMaterial("FadeInOutMaterial"); + mRectangle->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY-1); + // Use infinite AAB to always stay visible + Ogre::AxisAlignedBox aabInf; + aabInf.setInfinite(); + mRectangle->setBoundingBox(aabInf); + // Attach background to the scene + Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + node->attachObject(mRectangle); + mRectangle->setVisible(false); +} - mOverlay = ovm.create( FADE_OVERLAY_NAME ); - - OverlayContainer* overlay_panel; - overlay_panel = (OverlayContainer*)ovm.createOverlayElement("Panel", FADE_OVERLAY_PANEL_NAME); - - // position it over the whole screen - overlay_panel->_setPosition(0, 0); - overlay_panel->_setDimensions(1, 1); - - overlay_panel->setMaterialName( FADE_MATERIAL_NAME ); - overlay_panel->show(); - mOverlay->add2D(overlay_panel); - mOverlay->hide(); +Fader::~Fader() +{ + delete mRectangle; } void Fader::update(float dt) @@ -69,12 +66,12 @@ void Fader::update(float dt) mRemainingTime -= dt; } - if (mCurrentAlpha == 0.f) mOverlay->hide(); + if (mCurrentAlpha == 0.f) mRectangle->setVisible(false); } void Fader::applyAlpha() { - mOverlay->show(); + mRectangle->setVisible(true); mFadeTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, mCurrentAlpha); } diff --git a/libs/openengine/ogre/fader.hpp b/libs/openengine/ogre/fader.hpp index efb12a5d2..bddf5dc91 100644 --- a/libs/openengine/ogre/fader.hpp +++ b/libs/openengine/ogre/fader.hpp @@ -4,52 +4,52 @@ /* A class that handles fading in the screen from black or fading it out to black. - To achieve this, it uses a full-screen Ogre::Overlay - - inspired by http://www.ogre3d.org/tikiwiki/FadeEffectOverlay (heavily adjusted) + To achieve this, it uses a full-screen Rectangle2d */ namespace Ogre { class TextureUnitState; - class Overlay; + class Rectangle2D; + class SceneManager; } namespace OEngine { namespace Render { - class Fader - { - public: - Fader(); - - void update(float dt); - - void fadeIn(const float time); - void fadeOut(const float time); - void fadeTo(const int percent, const float time); - - private: - enum FadingMode + class Fader { - FadingMode_In, - FadingMode_Out + public: + Fader(Ogre::SceneManager* sceneMgr); + ~Fader(); + + void update(float dt); + + void fadeIn(const float time); + void fadeOut(const float time); + void fadeTo(const int percent, const float time); + + private: + enum FadingMode + { + FadingMode_In, + FadingMode_Out + }; + + void applyAlpha(); + + Ogre::TextureUnitState* mFadeTextureUnit; + Ogre::Rectangle2D* mRectangle; + + FadingMode mMode; + + float mRemainingTime; + float mTargetTime; + float mTargetAlpha; + float mCurrentAlpha; + float mStartAlpha; + + Ogre::SceneManager* mSceneMgr; }; - - void applyAlpha(); - - Ogre::TextureUnitState* mFadeTextureUnit; - Ogre::Overlay* mOverlay; - - FadingMode mMode; - - float mRemainingTime; - float mTargetTime; - float mTargetAlpha; - float mCurrentAlpha; - float mStartAlpha; - - protected: - }; -}} + }} #endif diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 65911df34..ec68c37ab 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -243,7 +243,7 @@ void OgreRenderer::createScene(const std::string& camName, float fov, float near // Alter the camera aspect ratio to match the viewport mCamera->setAspectRatio(Real(mView->getActualWidth()) / Real(mView->getActualHeight())); - mFader = new Fader(); + mFader = new Fader(mScene); } void OgreRenderer::adjustViewport() From bf5e30b24fc22c3d68126ae6f159a40787633240 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 19 Sep 2012 02:53:06 +0200 Subject: [PATCH 26/29] everything done except health/mana restore --- apps/openmw/mwbase/world.hpp | 7 +- apps/openmw/mwgui/levelupdialog.cpp | 2 +- apps/openmw/mwgui/mode.hpp | 1 + apps/openmw/mwgui/race.cpp | 2 +- apps/openmw/mwgui/waitdialog.cpp | 112 +++++++++++++++++- apps/openmw/mwgui/waitdialog.hpp | 29 +++++ apps/openmw/mwgui/widgets.cpp | 1 - apps/openmw/mwgui/windowmanagerimp.cpp | 10 +- apps/openmw/mwscript/guiextensions.cpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 24 +++- apps/openmw/mwworld/worldimp.hpp | 7 +- files/mygui/CMakeLists.txt | 1 + files/mygui/openmw_alchemy_window.layout | 5 +- files/mygui/openmw_chargen_birth.layout | 4 +- files/mygui/openmw_chargen_class.layout | 4 +- .../mygui/openmw_chargen_create_class.layout | 4 +- ...penmw_chargen_generate_class_result.layout | 4 +- files/mygui/openmw_chargen_race.layout | 5 +- files/mygui/openmw_chargen_review.layout | 4 +- files/mygui/openmw_confirmation_dialog.layout | 4 +- files/mygui/openmw_container_window.layout | 4 +- files/mygui/openmw_count_window.layout | 4 +- files/mygui/openmw_trade_window.layout | 4 +- .../openmw_wait_dialog_progressbar.layout | 13 ++ libs/openengine/ogre/fader.cpp | 1 + 25 files changed, 228 insertions(+), 30 deletions(-) create mode 100644 files/mygui/openmw_wait_dialog_progressbar.layout diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 05b31b3df..521bbb988 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -285,7 +285,12 @@ namespace MWBase virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0; - virtual bool canRest() = 0; + virtual int canRest() = 0; + ///< check if the player is allowed to rest \n + /// 0 - yes \n + /// 1 - only waiting \n + /// 2 - player is underwater \n + /// 3 - enemies are nearby (not implemented) }; } diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index 3616283d9..980a9e13b 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -173,7 +173,7 @@ namespace MWGui creatureStats.setLevel (creatureStats.getLevel()+1); pcStats.levelUp (); - mWindowManager.removeGuiMode (GM_Rest); + mWindowManager.removeGuiMode (GM_Levelup); } } diff --git a/apps/openmw/mwgui/mode.hpp b/apps/openmw/mwgui/mode.hpp index eb2c52b26..64aa1dc21 100644 --- a/apps/openmw/mwgui/mode.hpp +++ b/apps/openmw/mwgui/mode.hpp @@ -20,6 +20,7 @@ namespace MWGui GM_Dialogue, // NPC interaction GM_Barter, GM_Rest, + GM_RestBed, GM_SpellBuying, GM_Levelup, diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 3fe70d959..5cb73e682 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -40,7 +40,7 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager) getWidget(mHeadRotate, "HeadRotate"); mHeadRotate->setScrollRange(50); - mHeadRotate->setScrollPosition(20); + mHeadRotate->setScrollPosition(25); mHeadRotate->setScrollViewPage(10); mHeadRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate); diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index 622191566..cc9019f2b 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -9,6 +9,11 @@ #include "../mwbase/environment.hpp" #include "../mwworld/timestamp.hpp" +#include "../mwworld/player.hpp" +#include "../mwworld/ptr.hpp" +#include "../mwworld/class.hpp" + +#include "../mwmechanics/npcstats.hpp" #include "widgets.hpp" @@ -16,8 +21,34 @@ namespace MWGui { + WaitDialogProgressBar::WaitDialogProgressBar(MWBase::WindowManager &parWindowManager) + : WindowBase("openmw_wait_dialog_progressbar.layout", parWindowManager) + { + getWidget(mProgressBar, "ProgressBar"); + getWidget(mProgressText, "ProgressText"); + } + + void WaitDialogProgressBar::open() + { + center(); + } + + void WaitDialogProgressBar::setProgress (int cur, int total) + { + mProgressBar->setProgressRange (total); + mProgressBar->setProgressPosition (cur); + mProgressText->setCaption(boost::lexical_cast(cur) + "/" + boost::lexical_cast(total)); + } + + // --------------------------------------------------------------------------------------------------------- + WaitDialog::WaitDialog(MWBase::WindowManager &parWindowManager) : WindowBase("openmw_wait_dialog.layout", parWindowManager) + , mProgressBar(parWindowManager) + , mWaiting(false) + , mSleeping(false) + , mHours(1) + , mRemainingTime(0.05) { getWidget(mDateTimeText, "DateTimeText"); getWidget(mRestText, "RestText"); @@ -32,11 +63,27 @@ namespace MWGui mWaitButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onWaitButtonClicked); mHourSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &WaitDialog::onHourSliderChangedPosition); + + mProgressBar.setVisible (false); } void WaitDialog::open() { - setCanRest(MWBase::Environment::get().getWorld ()->canRest ()); + if (!MWBase::Environment::get().getWindowManager ()->getRestEnabled ()) + { + mWindowManager.popGuiMode (); + } + + int canRest = MWBase::Environment::get().getWorld ()->canRest (); + + if (canRest == 2) + { + // resting underwater or mid-air not allowed + mWindowManager.messageBox ("#{sNotifyMessage1}", std::vector()); + mWindowManager.popGuiMode (); + } + + setCanRest(canRest == 0); onHourSliderChangedPosition(mHourSlider, 0); mHourSlider->setScrollPosition (0); @@ -79,28 +126,38 @@ namespace MWGui + ") " + boost::lexical_cast(hour) + " " + (pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}"); mDateTimeText->setCaptionWithReplacing (dateTimeText); - - center(); } void WaitDialog::onUntilHealedButtonClicked(MyGUI::Widget* sender) { - + startWaiting(); } void WaitDialog::onWaitButtonClicked(MyGUI::Widget* sender) { - //MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1); + startWaiting(); + } + + void WaitDialog::startWaiting () + { + MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0.2); + setVisible(false); + mProgressBar.setVisible (true); + mWaiting = true; + mCurHour = 0; + mRemainingTime = 0.05; + mProgressBar.setProgress (0, mHours); } void WaitDialog::onCancelButtonClicked(MyGUI::Widget* sender) { - mWindowManager.removeGuiMode (GM_Rest); + mWindowManager.popGuiMode (); } void WaitDialog::onHourSliderChangedPosition(MyGUI::ScrollBar* sender, size_t position) { mHourText->setCaptionWithReplacing (boost::lexical_cast(position+1) + " #{sRestMenu2}"); + mHours = position+1; } void WaitDialog::setCanRest (bool canRest) @@ -108,6 +165,49 @@ namespace MWGui mUntilHealedButton->setVisible(canRest); mWaitButton->setCaptionWithReplacing (canRest ? "#{sRest}" : "#{sWait}"); mRestText->setCaptionWithReplacing (canRest ? "#{sRestMenu3}" : "#{sRestIllegal}"); + + mSleeping = canRest; + + dynamic_cast(mMainWidget)->notifyChildrenSizeChanged(); + center(); + } + + void WaitDialog::onFrame(float dt) + { + if (!mWaiting) + return; + + mRemainingTime -= dt; + + if (mRemainingTime < 0) + { + mRemainingTime = 0.05; + ++mCurHour; + mProgressBar.setProgress (mCurHour, mHours); + + if (mCurHour <= mHours) + MWBase::Environment::get().getWorld ()->advanceTime (1); + } + + if (mCurHour > mHours) + stopWaiting(); + } + + void WaitDialog::stopWaiting () + { + MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.2); + mProgressBar.setVisible (false); + mWindowManager.popGuiMode (); + mWaiting = false; + + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWMechanics::NpcStats pcstats = MWWorld::Class::get(player).getNpcStats(player); + + // trigger levelup if possible + if (mSleeping && pcstats.getLevelProgress () >= 10) + { + mWindowManager.pushGuiMode (GM_Levelup); + } } } diff --git a/apps/openmw/mwgui/waitdialog.hpp b/apps/openmw/mwgui/waitdialog.hpp index 040779819..1d079a8aa 100644 --- a/apps/openmw/mwgui/waitdialog.hpp +++ b/apps/openmw/mwgui/waitdialog.hpp @@ -6,6 +6,20 @@ namespace MWGui { + class WaitDialogProgressBar : public WindowBase + { + public: + WaitDialogProgressBar(MWBase::WindowManager& parWindowManager); + + virtual void open(); + + void setProgress(int cur, int total); + + protected: + MyGUI::ProgressBar* mProgressBar; + MyGUI::TextBox* mProgressText; + }; + class WaitDialog : public WindowBase { public: @@ -13,6 +27,10 @@ namespace MWGui virtual void open(); + void onFrame(float dt); + + void bedActivated() { setCanRest(true); } + protected: MyGUI::TextBox* mDateTimeText; MyGUI::TextBox* mRestText; @@ -22,12 +40,23 @@ namespace MWGui MyGUI::Button* mWaitButton; MyGUI::Button* mCancelButton; + bool mWaiting; + bool mSleeping; + int mCurHour; + int mHours; + float mRemainingTime; + + WaitDialogProgressBar mProgressBar; + void onUntilHealedButtonClicked(MyGUI::Widget* sender); void onWaitButtonClicked(MyGUI::Widget* sender); void onCancelButtonClicked(MyGUI::Widget* sender); void onHourSliderChangedPosition(MyGUI::ScrollBar* sender, size_t position); void setCanRest(bool canRest); + + void startWaiting(); + void stopWaiting(); }; } diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index 4f7ecb775..313820534 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -795,7 +795,6 @@ void MWDynamicStat::initialiseOverride() // --------------------------------------------------------------------------------------------------------------------- - void AutoSizedWidget::notifySizeChange (MyGUI::Widget* w) { if (w->getParent () != 0) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 5efd2b47a..5de35367a 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -310,9 +310,15 @@ void WindowManager::updateVisible() mAlchemyWindow->setVisible(true); break; case GM_Rest: - //mLevelupDialog->setVisible(true); mWaitDialog->setVisible(true); break; + case GM_RestBed: + mWaitDialog->setVisible(true); + mWaitDialog->bedActivated(); + break; + case GM_Levelup: + mLevelupDialog->setVisible(true); + break; case GM_Name: case GM_Race: case GM_Class: @@ -547,6 +553,8 @@ void WindowManager::onFrame (float frameDuration) mStatsWindow->onFrame(); + mWaitDialog->onFrame(frameDuration); + mHud->onFrame(frameDuration); mDialogueWindow->checkReferenceAvailable(); diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index 7f3b9777b..6e5540fa8 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -160,7 +160,7 @@ opcodeEnableStatsReviewMenu); new OpEnableRest ()); interpreter.installSegment5 (opcodeShowRestMenu, - new OpShowDialogue (MWGui::GM_Rest)); + new OpShowDialogue (MWGui::GM_RestBed)); interpreter.installSegment5 (opcodeGetButtonPressed, new OpGetButtonPressed); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index af0a53655..dae95255e 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1252,13 +1252,27 @@ namespace MWWorld mRendering->setupExternalRendering (rendering); } - bool World::canRest () + int World::canRest () { Ptr::CellStore *currentCell = mWorldScene->getCurrentCell(); - assert (currentCell); + + Ogre::Vector3 playerPos; + float* pos = mPlayer->getPlayer ().getRefData ().getPosition ().pos; + playerPos.x = pos[0]; + playerPos.y = pos[1]; + playerPos.z = pos[2]; + + std::pair hit = + mPhysics->castRay(playerPos, Ogre::Vector3(0,0,-1), 50); + bool isOnGround = (hit.first ? (hit.second.distance (playerPos) < 25) : false); + + if (!isOnGround || isUnderwater (*currentCell->cell, playerPos)) + return 2; + if (currentCell->cell->data.flags & ESM::Cell::NoSleep) - return false; - else - return true; + return 1; + + return 0; + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index e918a85e0..90cd2151b 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -316,7 +316,12 @@ namespace MWWorld virtual void setupExternalRendering (MWRender::ExternalRendering& rendering); - virtual bool canRest(); + virtual int canRest(); + ///< check if the player is allowed to rest \n + /// 0 - yes \n + /// 1 - only waiting \n + /// 2 - player is underwater \n + /// 3 - enemies are nearby (not implemented) }; } diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index 44235fa0e..ae8d3afbe 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -74,6 +74,7 @@ set(MYGUI_FILES openmw_loading_screen.layout openmw_levelup_dialog.layout openmw_wait_dialog.layout + openmw_wait_dialog_progressbar.layout smallbars.png VeraMono.ttf markers.png diff --git a/files/mygui/openmw_alchemy_window.layout b/files/mygui/openmw_alchemy_window.layout index 458d24b2c..8471f69df 100644 --- a/files/mygui/openmw_alchemy_window.layout +++ b/files/mygui/openmw_alchemy_window.layout @@ -77,8 +77,9 @@ - - + + + diff --git a/files/mygui/openmw_chargen_birth.layout b/files/mygui/openmw_chargen_birth.layout index 5edec72d3..f4b8c518d 100644 --- a/files/mygui/openmw_chargen_birth.layout +++ b/files/mygui/openmw_chargen_birth.layout @@ -15,7 +15,9 @@ - + + + diff --git a/files/mygui/openmw_chargen_class.layout b/files/mygui/openmw_chargen_class.layout index baa36b24a..00e3793bc 100644 --- a/files/mygui/openmw_chargen_class.layout +++ b/files/mygui/openmw_chargen_class.layout @@ -61,7 +61,9 @@ - + + + diff --git a/files/mygui/openmw_chargen_create_class.layout b/files/mygui/openmw_chargen_create_class.layout index 5e08db6e5..54f73f221 100644 --- a/files/mygui/openmw_chargen_create_class.layout +++ b/files/mygui/openmw_chargen_create_class.layout @@ -59,7 +59,9 @@ - + + + diff --git a/files/mygui/openmw_chargen_generate_class_result.layout b/files/mygui/openmw_chargen_generate_class_result.layout index 65dbf016c..aa4a89d28 100644 --- a/files/mygui/openmw_chargen_generate_class_result.layout +++ b/files/mygui/openmw_chargen_generate_class_result.layout @@ -21,7 +21,9 @@ - + + + diff --git a/files/mygui/openmw_chargen_race.layout b/files/mygui/openmw_chargen_race.layout index b69073899..a9ec9905d 100644 --- a/files/mygui/openmw_chargen_race.layout +++ b/files/mygui/openmw_chargen_race.layout @@ -57,7 +57,10 @@ - + + + + diff --git a/files/mygui/openmw_chargen_review.layout b/files/mygui/openmw_chargen_review.layout index dbe7a4780..97e32cfe2 100644 --- a/files/mygui/openmw_chargen_review.layout +++ b/files/mygui/openmw_chargen_review.layout @@ -112,7 +112,9 @@ - + + + diff --git a/files/mygui/openmw_confirmation_dialog.layout b/files/mygui/openmw_confirmation_dialog.layout index fe7f7cbf6..46b477407 100644 --- a/files/mygui/openmw_confirmation_dialog.layout +++ b/files/mygui/openmw_confirmation_dialog.layout @@ -14,7 +14,9 @@ - + + + diff --git a/files/mygui/openmw_container_window.layout b/files/mygui/openmw_container_window.layout index 896566fdd..94e9458a5 100644 --- a/files/mygui/openmw_container_window.layout +++ b/files/mygui/openmw_container_window.layout @@ -12,7 +12,9 @@ - + + + diff --git a/files/mygui/openmw_count_window.layout b/files/mygui/openmw_count_window.layout index a021d7df9..5812ec7fd 100644 --- a/files/mygui/openmw_count_window.layout +++ b/files/mygui/openmw_count_window.layout @@ -22,7 +22,9 @@ - + + + diff --git a/files/mygui/openmw_trade_window.layout b/files/mygui/openmw_trade_window.layout index 7de6c85e6..d38377f98 100644 --- a/files/mygui/openmw_trade_window.layout +++ b/files/mygui/openmw_trade_window.layout @@ -56,7 +56,9 @@ - + + + diff --git a/files/mygui/openmw_wait_dialog_progressbar.layout b/files/mygui/openmw_wait_dialog_progressbar.layout new file mode 100644 index 000000000..93793fd8e --- /dev/null +++ b/files/mygui/openmw_wait_dialog_progressbar.layout @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/libs/openengine/ogre/fader.cpp b/libs/openengine/ogre/fader.cpp index 498b659ee..ba532b527 100644 --- a/libs/openengine/ogre/fader.cpp +++ b/libs/openengine/ogre/fader.cpp @@ -39,6 +39,7 @@ Fader::Fader(Ogre::SceneManager* sceneMgr) Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); node->attachObject(mRectangle); mRectangle->setVisible(false); + mRectangle->setVisibilityFlags (0x01); } Fader::~Fader() From be44810623c8c970defb65bebe6c8c292cf0b79e Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 19 Sep 2012 03:11:23 +0200 Subject: [PATCH 27/29] implemented GetPCSleep --- apps/openmw/mwbase/windowmanager.hpp | 2 ++ apps/openmw/mwgui/waitdialog.hpp | 2 ++ apps/openmw/mwgui/windowmanagerimp.cpp | 5 +++++ apps/openmw/mwgui/windowmanagerimp.hpp | 2 ++ apps/openmw/mwscript/docs/vmformat.txt | 3 ++- apps/openmw/mwscript/miscextensions.cpp | 14 ++++++++++++++ 6 files changed, 27 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 0fd78225a..49f1f95b0 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -222,6 +222,8 @@ namespace MWBase virtual void enableRest() = 0; virtual bool getRestEnabled() = 0; + + virtual bool getPlayerSleeping() = 0; }; } diff --git a/apps/openmw/mwgui/waitdialog.hpp b/apps/openmw/mwgui/waitdialog.hpp index 1d079a8aa..4a401c0c6 100644 --- a/apps/openmw/mwgui/waitdialog.hpp +++ b/apps/openmw/mwgui/waitdialog.hpp @@ -31,6 +31,8 @@ namespace MWGui void bedActivated() { setCanRest(true); } + bool getSleeping() { return mWaiting && mSleeping; } + protected: MyGUI::TextBox* mDateTimeText; MyGUI::TextBox* mRestText; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 5de35367a..9d4aaf749 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -946,3 +946,8 @@ void WindowManager::loadingDone () { mLoadingScreen->loadingDone (); } + +bool WindowManager::getPlayerSleeping () +{ + return mWaitDialog->getSleeping(); +} diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 15c9c6631..0ed5e1fea 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -204,6 +204,8 @@ namespace MWGui virtual void enableRest() { mRestAllowed = true; } virtual bool getRestEnabled() { return mRestAllowed; } + virtual bool getPlayerSleeping(); + private: OEngine::GUI::MyGUIManager *mGuiManager; HUD *mHud; diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index d58045a0a..a9f2cd143 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -202,5 +202,6 @@ op 0x200019b: PlaceItem op 0x200019c: PlaceAtPc op 0x200019d: PlaceAtMe op 0x200019e: PlaceAtMe Explicit -opcodes 0x200019f-0x3ffffff unused +op 0x200019f: GetPcSleep +opcodes 0x20001a0-0x3ffffff unused diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 864c1a1ee..a869f882b 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -10,6 +10,7 @@ #include #include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwworld/class.hpp" @@ -20,6 +21,16 @@ namespace MWScript { namespace Misc { + class OpGetPcSleep : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + runtime.push (MWBase::Environment::get().getWindowManager ()->getPlayerSleeping()); + } + }; + class OpXBox : public Interpreter::Opcode0 { public: @@ -249,6 +260,7 @@ namespace MWScript const int opcodeTogglePathgrid = 0x2000146; const int opcodeDontSaveObject = 0x2000153; const int opcodeToggleVanityMode = 0x2000174; + const int opcodeGetPcSleep = 0x200019f; void registerExtensions (Compiler::Extensions& extensions) { @@ -273,6 +285,7 @@ namespace MWScript extensions.registerInstruction ("dontsaveobject", "", opcodeDontSaveObject); extensions.registerInstruction ("togglevanitymode", "", opcodeToggleVanityMode); extensions.registerInstruction ("tvm", "", opcodeToggleVanityMode); + extensions.registerFunction ("getpcsleep", 'l', "", opcodeGetPcSleep); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -293,6 +306,7 @@ namespace MWScript interpreter.installSegment5 (opcodeToggleWater, new OpToggleWater); interpreter.installSegment5 (opcodeDontSaveObject, new OpDontSaveObject); interpreter.installSegment5 (opcodeToggleVanityMode, new OpToggleVanityMode); + interpreter.installSegment5 (opcodeGetPcSleep, new OpGetPcSleep); } } } From d9f6072f02b279963b6e1929dfe519fb5580f999 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 19 Sep 2012 23:25:07 +0200 Subject: [PATCH 28/29] gamma correct rendering & adjustment setting --- apps/openmw/mwrender/renderingmanager.cpp | 2 ++ files/materials/core.h | 4 ++++ files/materials/objects.shader | 14 +++++++++----- files/materials/terrain.shader | 16 ++++++++++------ files/settings-default.cfg | 2 ++ 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 308a01688..5fffa30d3 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -129,6 +129,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty(new sh::FloatValue(0))); sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty(new sh::Vector3(0.5, -0.8, 0.2))); sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty(new sh::Vector2(1, 0.6))); + sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty(new sh::FloatValue( + Settings::Manager::getFloat ("gamma", "Video")))); applyCompositors(); diff --git a/files/materials/core.h b/files/materials/core.h index cba716777..e9577bbf3 100644 --- a/files/materials/core.h +++ b/files/materials/core.h @@ -1,3 +1,7 @@ +#define gammaCorrectRead(v) pow(v, float3(gammaCorrection,gammaCorrection,gammaCorrection)) +#define gammaCorrectOutput(v) pow(v, float3(1.f/gammaCorrection,1.f/gammaCorrection,1.f/gammaCorrection)) + + #if SH_HLSL == 1 || SH_CG == 1 #define shTexture2D sampler2D diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 8e5cbf76e..45f33774d 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -112,6 +112,8 @@ shUniform(float, far) @shAutoConstant(far, far_clip_distance) #endif + shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection) + #if LIGHTING shInput(float3, normalPassthrough) shInput(float3, objSpacePositionPassthrough) @@ -173,7 +175,8 @@ SH_START_PROGRAM { shOutputColour(0) = shSample(diffuseMap, UV); - + shOutputColour(0).xyz = gammaCorrectRead(shOutputColour(0).xyz); + #if LIGHTING float3 normal = normalize(normalPassthrough); float3 lightDir; @@ -259,7 +262,7 @@ // regular fog only if fragment is above water if (worldPos.y > waterLevel) #endif - shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue); + shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue); #endif // prevent negative colour output (for example with negative lights) @@ -274,12 +277,11 @@ float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz)); waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); - float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5; + float3 waterSunColour = gammaCorrectRead(float3(0.0,1.0,0.85)) *waterSunGradient * 0.5; float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0)); waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0); - float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0; - float3 waterext = float3(0.6, 0.9, 1.0);//water extinction + float3 watercolour = ( gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0; watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3; @@ -292,6 +294,8 @@ shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled); #endif + shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz); + #if MRT shOutputColour(1) = float4(depthPassthrough / far,1,1,1); #endif diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index 7ef26d035..9183595e3 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -137,6 +137,8 @@ shSampler2D(normalMap) // global normal map + shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection) + @shForeach(@shPropertyString(num_blendmaps)) shSampler2D(blendMap@shIterator) @@ -247,9 +249,9 @@ #if IS_FIRST_PASS == 1 && @shIterator == 0 // first layer of first pass doesn't need a blend map - albedo = shSample(diffuseMap0, UV * 10).rgb; + albedo = gammaCorrectRead(shSample(diffuseMap0, UV * 10).rgb); #else - albedo = shLerp(albedo, shSample(diffuseMap@shIterator, UV * 10).rgb, blendValues@shPropertyString(blendmap_component_@shIterator)); + albedo = shLerp(albedo, gammaCorrectRead(shSample(diffuseMap@shIterator, UV * 10).rgb), blendValues@shPropertyString(blendmap_component_@shIterator)); #endif @shEndForeach @@ -336,7 +338,7 @@ // regular fog only if fragment is above water if (worldPos.y > waterLevel) #endif - shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue); + shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue); #endif // prevent negative colour output (for example with negative lights) @@ -351,12 +353,12 @@ float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz)); waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); - float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5; + float3 waterSunColour = gammaCorrectRead(float3(0.0,1.0,0.85))*waterSunGradient * 0.5; float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0)); waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0); - float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0; - float3 waterext = float3(0.6, 0.9, 1.0);//water extinction + float3 watercolour = (gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0; + float3 waterext = gammaCorrectRead(float3(0.6, 0.9, 1.0));//water extinction watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3; @@ -369,6 +371,8 @@ shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater); #endif + shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz); + #if MRT shOutputColour(1) = float4(depth / far,1,1,1); diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 6a77b7fc0..1768b2f5e 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -28,6 +28,8 @@ vsync = false # PBuffer, FBO, Copy opengl rtt mode = FBO +gamma = 2.2 + [GUI] # 1 is fully opaque menu transparency = 0.84 From b9a3f8e8d74e2fc97fc48c1ad6e613d6f4d5b280 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 19 Sep 2012 23:47:42 +0200 Subject: [PATCH 29/29] gamma slider --- apps/openmw/mwgui/settingswindow.cpp | 19 +++++++++++++++++ apps/openmw/mwgui/settingswindow.hpp | 1 + apps/openmw/mwrender/renderingmanager.cpp | 5 +++++ files/mygui/openmw_settings_window.layout | 25 +++++++++++++++++++---- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index d1e206a95..cdfe4d2b6 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -122,6 +122,7 @@ namespace MWGui getWidget(mInvertYButton, "InvertYButton"); getWidget(mUISensitivitySlider, "UISensitivitySlider"); getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider"); + getWidget(mGammaSlider, "GammaSlider"); mSubtitlesButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); @@ -143,6 +144,7 @@ namespace MWGui mViewDistanceSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected); mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); + mGammaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); mShadowsEnabledButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mShadowsLargeDistance->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); @@ -200,6 +202,14 @@ namespace MWGui getWidget(fovText, "FovText"); fovText->setCaption("Field of View (" + boost::lexical_cast(int(Settings::Manager::getFloat("field of view", "General"))) + ")"); + float gammaVal = (Settings::Manager::getFloat("gamma", "Video")-0.1f)/(3.f-0.1f); + mGammaSlider->setScrollPosition(gammaVal * (mGammaSlider->getScrollRange()-1)); + MyGUI::TextBox* gammaText; + getWidget(gammaText, "GammaText"); + std::stringstream gamma; + gamma << std::setprecision (2) << Settings::Manager::getFloat("gamma", "Video"); + gammaText->setCaption("Gamma (" + gamma.str() + ")"); + float anisotropyVal = Settings::Manager::getInt("anisotropy", "General") / 16.0; mAnisotropySlider->setScrollPosition(anisotropyVal * (mAnisotropySlider->getScrollRange()-1)); std::string tf = Settings::Manager::getString("texture filtering", "General"); @@ -511,6 +521,15 @@ namespace MWGui fovText->setCaption("Field of View (" + boost::lexical_cast(int((1-val) * sFovMin + val * sFovMax)) + ")"); Settings::Manager::setFloat("field of view", "General", (1-val) * sFovMin + val * sFovMax); } + else if (scroller == mGammaSlider) + { + Settings::Manager::setFloat("gamma", "Video", (1-val) * 0.1f + val * 3.f); + MyGUI::TextBox* gammaText; + getWidget(gammaText, "GammaText"); + std::stringstream gamma; + gamma << std::setprecision (2) << Settings::Manager::getFloat("gamma", "Video"); + gammaText->setCaption("Gamma (" + gamma.str() + ")"); + } else if (scroller == mAnisotropySlider) { mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast(int(val*16)) + ")"); diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp index d1f35ed71..e878d0abe 100644 --- a/apps/openmw/mwgui/settingswindow.hpp +++ b/apps/openmw/mwgui/settingswindow.hpp @@ -40,6 +40,7 @@ namespace MWGui MyGUI::Button* mFPSButton; MyGUI::ScrollBar* mViewDistanceSlider; MyGUI::ScrollBar* mFOVSlider; + MyGUI::ScrollBar* mGammaSlider; MyGUI::ScrollBar* mAnisotropySlider; MyGUI::Button* mTextureFilteringButton; MyGUI::TextBox* mAnisotropyLabel; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 5fffa30d3..d63f9c2fc 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -749,6 +749,11 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects")); mObjects.rebuildStaticGeometry (); } + else if (it->second == "gamma" && it->first == "Video") + { + sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty(new sh::FloatValue( + Settings::Manager::getFloat ("gamma", "Video")))); + } else if (it->second == "shader mode" && it->first == "General") { sh::Language lang; diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index 38d2786e5..2f9b5a67f 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -157,7 +157,7 @@ - + @@ -174,20 +174,37 @@ - + - + - + + + + + + + + + + + + + + + + + +