//Autor: Tiago buriol
//---------------------------
// C++ includes
#include < stdio.h >
#include < sys/time.h >
// OSG includes
#include < osgViewer/Viewer >
#include < osg/Geometry >
#include < osgGA/TrackballManipulator >
#include < osg/Vec3d >
#include < osg/PositionAttitudeTransform >
#include < osg/ShapeDrawable >
// PhysX include
#include "NxPhysics.h"
// Declaracao de variaveis globais para o PhysX
static NxPhysicsSDK* gPhysicsSDK = NULL;
static NxScene* gScene = NULL;
NxActor* box = NULL;
// Inicializa o Physx e define alguns parametros
static bool InitNx()
{
// Inicializa o PhysX SDK
NxPhysicsSDKDesc desc;
gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
if (!gPhysicsSDK) return false;
gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.001);
// Cria uma cena
NxSceneDesc sceneDesc;
//sceneDesc.simType = NX_SIMULATION_HW;
sceneDesc.simType = NX_SIMULATION_SW;
sceneDesc.gravity = NxVec3(0.0f, -9.81f, 0.0f);
gScene = gPhysicsSDK->createScene(sceneDesc);
// Set default material
NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0);
defaultMaterial->setRestitution(0.2f);
defaultMaterial->setStaticFriction(0.01f);
defaultMaterial->setDynamicFriction(0.01f);
// Create ground plane
NxPlaneShapeDesc planeDesc;
//planeDesc.skinWidth = 0.01f;
NxActorDesc actorDesc;
actorDesc.shapes.pushBack(&planeDesc);
actorDesc.globalPose.t = NxVec3(0.0, 0.0, 0.0);
gScene->createActor(actorDesc);
// Add a single-shape actor to the scene
NxActorDesc boxActorDesc;
NxBodyDesc boxBodyDesc;
// The actor has one shape, a box, 1m on a side
NxBoxShapeDesc boxDesc;
boxDesc.dimensions.set(1.0, 1.0, 1.0);
//boxDesc.skinWidth = 0.01f;
boxActorDesc.shapes.pushBack(&boxDesc);
boxActorDesc.body = & boxBodyDesc;
boxActorDesc.density = 5.0f;
boxActorDesc.globalPose.M.fromQuat(NxQuat(30.0, NxVec3(1, 0, 0)));
boxActorDesc.globalPose.t = NxVec3(0,5.0,0);
box = gScene->createActor(boxActorDesc);
//printf("altura %f\n",box->getGlobalPosition().y);
return true;
}
int main(int argc, char** argv)
{
double delta_t;
struct timeval tv1, tv2;
// Cria o visualizador
osgViewer::Viewer viewer;
osg::ref_ptr
osg::Sphere* unitSphere = new osg::Sphere(osg::Vec3(0,0,0), 1.0);
osg::ShapeDrawable* unitSphereDrawable = new osg::ShapeDrawable(unitSphere);
unitSphereDrawable->setColor(osg::Vec4(1, 0, 0, 1));
osg::Geode* unitSphereGeode = new osg::Geode();
unitSphereGeode->addDrawable(unitSphereDrawable);
osg::PositionAttitudeTransform* unitSpherePAT = new osg::PositionAttitudeTransform();
unitSpherePAT->setPosition(osg::Vec3(2.0,0.0,1.0));
unitSpherePAT->addChild(unitSphereGeode);
// Cria o cubo a ser renderizado
osg::Box* unitBox = new osg::Box(osg::Vec3(0,0,-0.5), 1.0, 1.0, 1.0);
osg::ShapeDrawable* unitBoxDrawable = new osg::ShapeDrawable(unitBox);
unitBoxDrawable->setColor(osg::Vec4(1, 1, 0, 1));
osg::Geode* unitBoxGeode = new osg::Geode();
unitBoxGeode->addDrawable(unitBoxDrawable);
osg::PositionAttitudeTransform* unitBoxPAT = new osg::PositionAttitudeTransform();
unitBoxPAT->addChild(unitBoxGeode);
// Desenha um plano
osg::Vec3 coords[] = { osg::Vec3(-3.0, 3.0, -0.01),
osg::Vec3(3.0, 3.0, -0.01),
osg::Vec3(3.0, -3.0, -0.01),
osg::Vec3(-3.0, -3.0, -0.01)
};
osg::Vec3Array* vertices = new osg::Vec3Array(4,coords);
osg::Geometry* planeGeometry = new osg::Geometry();
planeGeometry->setVertexArray(vertices);
planeGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(0.8f,0.8f,1.0f,1.0f));
planeGeometry->setColorArray(colors);
planeGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);
osg::Vec3Array *shared_normals = new osg::Vec3Array;
shared_normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
// use the shared normal array.
planeGeometry->setNormalArray(shared_normals);
planeGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
osg::Geode* planeGeode = new osg::Geode();
planeGeode->addDrawable(planeGeometry);
root->addChild(unitSpherePAT);
root->addChild(unitBoxPAT);
root->addChild(planeGeode);
viewer.setSceneData(root.get());
viewer.setUpViewInWindow(0, 0, 800, 600);
viewer.setCameraManipulator(new osgGA::TrackballManipulator());
viewer.realize();
// Initialize physics scene and start the application main loop if scene was created
if (InitNx())
delta_t = 0.001;
// Loop principal da simulacao
while (!viewer.done()) {
// Pega o tempo inicial
gettimeofday(&tv1, NULL);
// Realiza um passo da simulacao para um intervalo de tempo igual a delta_t
gScene->simulate((NxReal)delta_t);
gScene->flushStream();
gScene->fetchResults(NX_RIGID_BODY_FINISHED, false);
// Sincroniza as posicao e rotacao dos cubos simulado e renderizado
unitBoxPAT->setAttitude(osg::Quat(box->getGlobalOrientationQuat().x,
box->getGlobalOrientationQuat().z,
box->getGlobalOrientationQuat().y,
box->getGlobalOrientationQuat().w) );
unitBoxPAT->setPosition(osg::Vec3d(box->getGlobalPosition().x,
box->getGlobalPosition().z,
box->getGlobalPosition().y) );
// Atualiza o frame
viewer.frame();
// Pega o tempo final e calcula o tempo entre um frame e outro
gettimeofday(&tv2, NULL);
delta_t = (tv2.tv_usec - tv1.tv_usec)*0.000001;
}
return 0;
}