physx. kezdeti teendők letöltés: ogrephysicsbase.zip kicsomagol futtat: ogrephysics.sln include...
TRANSCRIPT
PhysX
Kezdeti teendőkLetöltés: OgrePhysicsBase.zipKicsomagolFuttat: OgrePhysics.slnInclude és library útvonalak beállításaWorking directory beállításaFordítFuttat
#include "Ogre.h"#define OIS_DYNAMIC_LIB#include <OIS/OIS.h>
using namespace Ogre;
Root* ogreRoot;SceneManager* sceneManager;Camera* camera;RenderWindow* renderWindow;OIS::InputManager* OISInputManager;SceneNode* box1Node;SceneNode* box2Node;SceneNode* box3Node;
createGround();
SceneNode* rootNode = sceneManager->getRootSceneNode();box1Node = rootNode->createChildSceneNode();Entity* box1 = sceneManager->createEntity("box1", "doboz.mesh");box1Node->attachObject(box1);box1Node->setScale(10,10,10);box1Node->setPosition(0,10,0);
box2Node = rootNode->createChildSceneNode();Entity* box2 = sceneManager->createEntity("box2", "doboz.mesh");box2Node->attachObject(box2);box2Node->setScale(15,15,15);box2Node->setPosition(5,30,0);
box3Node = rootNode->createChildSceneNode();Entity* box3 = sceneManager->createEntity("box3", "doboz.mesh");box3Node->attachObject(box3);box3Node->setScale(5,5,5);box3Node->setPosition(-2,50,5);
sceneManager->setSkyBox(true, "Sky", 10, true);
Próba
class PhysicsHandler;PhysicsHandler* physicsHandler;class PhysicsHandler: public FrameListener{
public:
PhysicsHandler (){
}~PhysicsHandler (){
}bool frameStarted(const FrameEvent& evt){
return true;}
};
class ControlDeviceHandler : public FrameListener
void setupListeners(){
ogreRoot->addFrameListener(new ControlDeviceHandler());physicsHandler = new PhysicsHandler();ogreRoot->addFrameListener(physicsHandler);
}
Bullet Physics-hez mi kell indulásképpen?#include "btBulletDynamicsCommon.h"
Include path beállítása: ..\BulletSDK_vc10\include
Library path beállítása: ..\BulletSDK_vc10\src\lib
Library megadása : • LinearMath_vs2010_debug.lib• BulletCollision_vs2010_debug.lib• BulletDynamics_vs2010_debug.lib
Próba… fordul-e?
class PhysicsHandler : public FrameListener{protected: bool inited; btDiscreteDynamicsWorld * dynamicsWorld;public:
PhysicsHandler(){
inited = false; //collision configuration contains default setup for memory , collision setup. //Advanced users can create their oconfiguration . btDefaultCollisionConfiguration* collisionConfiguration = new
btDefaultCollisionConfiguration(); //use the default collision dispatcher. //For parallel processing you can use a diffent dispatcher ( see Extras/BulletMultiThreaded ) btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); //btDbvtBoadphase is a good general purpose broadphase . You can also try out btAxis3Sweep . btBroadphaseInterface * overlappingPairCache = new btDbvtBroadphase(); //the default constraint solver. //For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) btSequentialImpulseConstraintSolver * solver = new btSequentialImpulseConstraintSolver; dynamicsWorld = new btDiscreteDynamicsWorld ( dispatcher, overlappingPairCache, solver, collisionConfiguration); dynamicsWorld->setGravity(btVector3(0 , -100 ,0));
inited = true;}
Szimulációbool frameStarted(const FrameEvent& evt){
if(!inited)return true;
dynamicsWorld->stepSimulation(evt.timeSinceLastFrame, 7);
return true;}
Próba… fordul-e, fut-e?
class PhysicsHandler : public FrameListener{protected:.. btCollisionShape* groundShape; btDefaultMotionState* groundMotionState; btRigidBody* groundRigidBody;public:
PhysicsHandler(){
... dynamicsWorld->setGravity(btVector3(0 , -100 ,0));
groundShape = new btStaticPlaneShape(btVector3(0,1,0), 0); groundMotionState = new
btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,0,0))); btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0)); btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI); dynamicsWorld->addRigidBody(groundRigidBody);
inited = true;}
Próba… fordul-e, fut-e?
class PhysicsHandler : public FrameListener{protected:.. btCollisionShape* groundShape; btDefaultMotionState* groundMotionState; btRigidBody* groundRigidBody;public:
PhysicsHandler(){
... dynamicsWorld->setGravity(btVector3(0 , -100 ,0));
groundShape = new btStaticPlaneShape(btVector3(0,1,0), 0); groundMotionState = new
btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,0,0))); btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0)); btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI); dynamicsWorld->addRigidBody(groundRigidBody);
inited = true;}
Próba… fordul-e, fut-e?
class PhysXBoxObject{protected: SceneNode* ogreNode; btRigidBody* physicsBody; btCollisionShape* physicsShape; btDefaultMotionState* physicsMotionState;public: PhysXBoxObject(SceneNode* ogreNode, btDiscreteDynamicsWorld*
dynamicsWorld) { this->ogreNode = ogreNode; physicsShape = new btBoxShape( btVector3(btScalar(ogreNode->getScale().x * 0.5), btScalar(ogreNode->getScale().y * 0.5), btScalar(ogreNode->getScale().z * 0.5))); physicsMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(ogreNode->getPosition().x, ogreNode->getPosition().y, ogreNode->getPosition().z))); btScalar mass = 1; btVector3 inertia(0,0,0); physicsShape->calculateLocalInertia(mass,inertia); btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, physicsMotionState, physicsShape, inertia); physicsBody = new btRigidBody(rigidBodyCI); dynamicsWorld->addRigidBody(physicsBody); }};
class PhysicsHandler : public FrameListener{protected:
...PhysXBoxObject* boxes[3];
public:PhysicsHandler(){…
dynamicsWorld->addRigidBody(groundRigidBody);
boxes[0] = new PhysXBoxObject(box1Node, dynamicsWorld); boxes[1] = new PhysXBoxObject(box2Node, dynamicsWorld); boxes[2] = new PhysXBoxObject(box3Node, dynamicsWorld);
inited = true;}
class PhysXBoxObject{public:
void update(){
btTransform worldTrans; physicsMotionState->getWorldTransform(worldTrans); btQuaternion rot = worldTrans.getRotation(); ogreNode->setOrientation(rot.w(), rot.x(), rot.y(), rot.z()); ogreNode->setPosition(worldTrans.getOrigin().x(), worldTrans.getOrigin().y(), worldTrans.getOrigin().z());
}
Próba
class PhysicsHandler : public FrameListener{…
bool frameStarted(const FrameEvent& evt){
...
boxes[0]->update();boxes[1]->update();boxes[2]->update();
return true;}
class PhysXBallObject{protected:SceneNode* ogreNode;btRigidBody* physicsBody;btCollisionShape* physicsShape; btDefaultMotionState* physicsMotionState;public:
PhysXBallObject(SceneNode* ogreNode, btDiscreteDynamicsWorld* dynamicsWorld){this->ogreNode = ogreNode; physicsShape = new btSphereShape(btScalar(3)); physicsMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(camera->getPosition().x, camera->getPosition().y, camera->getPosition().z))); btScalar mass = 1; btVector3 inertia(0,0,0); physicsShape->calculateLocalInertia(mass, inertia); btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, physicsMotionState, physicsShape, inertia); physicsBody = new btRigidBody(rigidBodyCI); dynamicsWorld->addRigidBody(physicsBody); physicsBody->applyCentralImpulse(btVector3(camera->getDirection().x * 200, camera->getDirection().y * 200, camera->getDirection().z * 200)); }void update(){ btTransform worldTrans; physicsMotionState->getWorldTransform(worldTrans); btQuaternion rot = worldTrans.getRotation(); ogreNode->setOrientation(rot.w(), rot.x(), rot.y(), rot.z()); ogreNode->setPosition(worldTrans.getOrigin().x(), worldTrans.getOrigin().y(), worldTrans.getOrigin().z());}};
class PhysicsHandler : public FrameListener{protected:
…std::vector<PhysXBallObject*> balls;
public:void addBall(SceneNode* ogreNode){
balls.push_back(new PhysXBallObject(ogreNode, mPhysicsScene));}bool frameStarted(const FrameEvent& evt){
…boxes[0]->update();boxes[1]->update();boxes[2]->update();
std::vector<PhysXBallObject*>::iterator it = balls.begin();std::vector<PhysXBallObject*>::iterator itend = balls.end();while(it != itend){
(*it)->update();it++;
}
return true;}
void addBall(){
static int id = 0;SceneNode* ballNode = sceneManager->getRootSceneNode()->createChildSceneNode();Entity *ballEnt = sceneManager->createEntity("ball"+StringConverter::toString(id),"strippedBall.mesh");ballNode->attachObject(ballEnt);ballNode->setScale(3,3,3);physicsHandler->addBall(ballNode);id++;
}
class ControlDeviceHandler : public FrameListener...
class ControlDeviceHandler : public FrameListener{…bool frameStarted(const FrameEvent& evt)
{if( mKeyboard->isKeyDown(OIS::KC_SPACE) &&
mTimeUntilNextToggle < 0){
addBall();mTimeUntilNextToggle = 0.5f;
}…
Próba
Statikus ActorPhysXBoxObject(SceneNode* ogreNode,
btDiscreteDynamicsWorld* dynamicsWorld){... btScalar mass = 0;…
Ekkor az update függvényre sincs szükség!!
Utána állítsuk vissza dynamic actor-ra (mass != 0)!!
PhysXBallObject:... physicsBody = new btRigidBody(rigidBodyCI); physicsBody->setDamping(0.1, 0.3); physicsBody->setRestitution(0.6);
PhysicsHandler:... btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI); groundRigidBody->setRestitution(1.0);
Próba…lehet más értékekkel is próbálkozni ...
Animáció//globális változóSceneNode* hammerNode;
…
class AnimController : public FrameListener{public:
bool frameStarted(const FrameEvent& evt){
hammerNode->rotate(Vector3::UNIT_Y, Radian(evt.timeSinceLastFrame * 2.0f));
return true;}
};
void setupListeners(){
ogreRoot->addFrameListener(new AnimController());…}
void setupScene(){
…
hammerNode = rootNode->createChildSceneNode();SceneNode* tempNode = hammerNode->createChildSceneNode();Entity* hammer = sceneManager->createEntity("hammer", "TrollMace.mesh");tempNode->attachObject(hammer);tempNode->rotate(Vector3::UNIT_X,Radian(Degree(90)));hammerNode->setScale(30,30,30);hammerNode->setPosition(0,5,30);
…
}
Próba
class PhysXHammerObject{protected: SceneNode* ogreNode; btRigidBody* physicsBody; btCollisionShape* physicsCompoundShape; btCollisionShape* physicsHeadShape; btCollisionShape* physicsHandleShape; btDefaultMotionState* physicsMotionState;public: PhysXHammerObject(SceneNode* ogreNode, btDiscreteDynamicsWorld* dynamicsWorld) { this->ogreNode = ogreNode; physicsHeadShape = new btBoxShape(btVector3(ogreNode->getScale().x
*0.25f, ogreNode->getScale().y * 0.25 * 0.5f, ogreNode->getScale().z * 0.25 * 0.5f)); physicsHandleShape = new btBoxShape(btVector3( ogreNode->getScale().x * 0.5f * 0.1f, ogreNode->getScale().y * 0.5f, ogreNode->getScale().z * 0.5f * 0.1f)); btCompoundShape* allShapes = new btCompoundShape(); physicsCompoundShape = allShapes; allShapes->addChildShape(btTransform(btQuaternion(0,0,0,1), btVector3(0,ogreNode->getScale().y * 0.865f,0)), physicsHeadShape); allShapes->addChildShape(btTransform(btQuaternion(0,0,0,1), btVector3(0,ogreNode->getScale().y * 0.5,0)), physicsHandleShape);...
... physicsMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(camera->getPosition().x,
camera->getPosition().y, camera->getPosition().z)));
btScalar mass = 1; btVector3 inertia(0,0,0); physicsCompoundShape->calculateLocalInertia(mass, inertia); btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, physicsMotionState, physicsCompoundShape, inertia); physicsBody = new btRigidBody(rigidBodyCI); dynamicsWorld->addRigidBody(physicsBody); physicsBody->setCollisionFlags( physicsBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); physicsBody->setActivationState(DISABLE_DEACTIVATION); }...
void update(){
SceneNode* tempNode = ((SceneNode*) ogreNode->getChild(0)); Vector3 pos = tempNode->_getDerivedPosition(); Quaternion orient = tempNode->_getDerivedOrientation();
btTransform worldTrans; worldTrans.setRotation(btQuaternion(orient.x,orient.y,orient.z,orient.w)); worldTrans.setOrigin(btVector3(pos.x, pos.y, pos.z)); physicsMotionState->setWorldTransform(worldTrans);
}};
class PhysicsHandler : public FrameListener{protected:
PhysXHammerObject* hammer;…
PhysicsHandler(){
…hammer = new PhysXHammerObject(hammerNode, dynamicsWorld);
}bool frameStarted(const FrameEvent& evt){
…hammer->update();
}
Próba
Önálló (otthoni) feladat
Kamera köré egy kinematikus Actor-t.Lehessen löködni a dobozokat.
class Explosive{public:
Explosive(SceneManager* sceneManager, btDiscreteDynamicsWorld* dynamicsWorld){static int id = 0;
float a = Math::RangeRandom(0, 360);float d = Math::RangeRandom(50, 120);float x = Math::Cos(a) * d;float z = Math::Sin(a) * d;
SceneNode* node = sceneManager->getRootSceneNode()->createChildSceneNode();Entity* entity = sceneManager->createEntity("explosive"+StringConverter::toString(id),"explosive.mesh");node->attachObject(entity);node->setScale(10,10,10);node->setPosition(x,0,z);
id++;}
};
void setupExplosives()
{
for(int i = 0; i <8; i ++)
new Explosive(sceneManager, physicsHandler->getWorld());
}
…
int _tmain(int argc, _TCHAR* argv[])
{
…
setupScene();
setupListeners();
setupExplosives();
…
}
class PhysicsHandler : public FrameListener{…public:
btDiscreteDynamicsWorld* getWorld() { return dynamicsWorld; }…
Próba
protected:
btRigidBody* physicsBody;
btCollisionShape* physicsShape;
btDefaultMotionState* physicsMotionState;
public:
Explosive(SceneManager* sceneManager, NxScene* physXScene)
{
…
node->setPosition(x,0,z);
physicsShape = new btBoxShape(btVector3(2.5,5,2.5));
physicsMotionState =
new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),
btVector3(x,5,z)));
…
…
btScalar mass = 0; btVector3 inertia(0,0,0); physicsShape->calculateLocalInertia(mass,inertia); btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, physicsMotionState, physicsShape, inertia); physicsBody = new btRigidBody(rigidBodyCI); dynamicsWorld->addRigidBody(physicsBody);
physicsBody->setCollisionFlags(physicsBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); physicsBody->setCollisionFlags(physicsBody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); if(id == 0) gContactProcessedCallback = globalTriggerCallback;
id++;}
Trigger report//Globális függvénybool globalTriggerCallback(btManifoldPoint& cp, void* body0, void* body1) { btRigidBody* rigidbody0 = (btRigidBody*)body0; btRigidBody* rigidbody1 = (btRigidBody*)body1; if(!(rigidbody0->getCollisionFlags() &
btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) && !(rigidbody1->getCollisionFlags() &
btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)) return true;
static int cnt = 0; printf("Trigger Callback %i !!!!\n", cnt++);
float f = 100; btVector3 force(Math::RangeRandom(-f, f),Math::RangeRandom(0, 5 *
f),Math::RangeRandom(-f, f)); rigidbody0->applyCentralImpulse(force); rigidbody1->applyCentralImpulse(force);
return true; }
Próba