fix crash in BasicDemo

add small experiments to distribute points on a sphere
prepare for coordinate frame demo (incomplete)
fix/hack around gwen update of scroll bars and Focu
This commit is contained in:
erwin coumans
2014-12-16 14:27:38 -08:00
parent 122fabac87
commit 548fe5b04e
17 changed files with 922 additions and 196 deletions

View File

@@ -10,7 +10,8 @@ void BasicDemoPhysicsSetup::initPhysics(GraphicsPhysicsBridge& gfxBridge)
{
createEmptyDynamicsWorld();
gfxBridge.createPhysicsDebugDrawer(m_dynamicsWorld);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
if (m_dynamicsWorld->getDebugDrawer())
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));

View File

@@ -5,7 +5,7 @@
#include "Bullet3AppSupport/BulletDemoInterface.h"
#include "../bullet2/BasicDemo/BasicDemo.h"
#include "../bullet2/CoordinateFramesDemo/CoordinateFrameDemoPhysicsSetup.h"
#include "../bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.h"
#include "../bullet2/BasicDemo/HingeDemo.h"
#include "../bullet2/BasicDemo/HingeDemo.h"
@@ -31,7 +31,8 @@
#include "../bullet2/BasicConcepts/CoordinateSystemDemo.h"
#include "../../Demos3/FiniteElementMethod/FiniteElementDemo.h"
//#include "../../Demos3/bullet2/SoftDemo/SoftDemo.h"
#include "../Geometry/SphereCreation.h"
#include "../Geometry/DistributePoints.h"
#define MYCREATEFUNC(func) \
static BulletDemoInterface* func##CreateFunc(CommonGraphicsApp* app)\
@@ -83,8 +84,7 @@ static BulletDemoEntry allDemos[]=
{0,"Basic Concepts",0},
{1,"Basis Frame", &CoordinateSystemDemo::CreateFunc},
{1,"SupportFunc", &MySupportFuncDemo::CreateFunc},
{1,"Coordinate Frames", CoordinateFrameDemoPhysicsCreateFunc},
//{"emptydemo",EmptyBulletDemo::MyCreateFunc},
{0,"API Demos", 0},
{1,"BasicDemo",BasicDemo::MyCreateFunc},
@@ -102,6 +102,9 @@ static BulletDemoEntry allDemos[]=
{ 1, "COLLADA", MyImportColladaCreateFunc},
{0,"Experiments", 0},
{1, "Finite Element Demo", FiniteElementDemo::CreateFunc},
{1,"SphereCreation", &SphereCreation::CreateFunc},
{1,"DistributePoints", &DistributePoints::CreateFunc},
{1,"Coordinate Frames", CoordinateFrameDemoPhysicsCreateFunc},
// {0,"Soft Body", 0},
// {1,"Cloth1", SoftDemo::CreateFunc},

View File

@@ -25,6 +25,8 @@ SET(App_AllBullet2Demos_SRCS
../bullet2/MultiBodyDemo/MultiBodyVehicle.cpp
../bullet2/ConstraintDemo/ConstraintPhysicsSetup.cpp
../bullet2/ConstraintDemo/ConstraintPhysicsSetup.h
../bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.cpp
../bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.h
../bullet2/FeatherstoneMultiBodyDemo/BulletMultiBodyDemos.cpp
../bullet2/FeatherstoneMultiBodyDemo/BulletMultiBodyDemos.h
../bullet2/FeatherstoneMultiBodyDemo/MultiDofDemo.cpp

View File

@@ -207,7 +207,10 @@ static BulletDemoInterface* sCurrentDemo = 0;
static b3AlignedObjectArray<const char*> allNames;
bool drawGUI=true;
extern bool useShadowMap;
static bool wireframe=false;
static bool visualWireframe=false;
static bool renderVisualGeometry=true;
static bool renderGrid = true;
static bool pauseSimulation=false;//true;
int midiBaseIndex = 176;
@@ -243,15 +246,18 @@ void MyKeyboardCallback(int key, int state)
if (key=='w' && state)
{
wireframe=!wireframe;
if (wireframe)
{
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
} else
{
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
}
visualWireframe=!visualWireframe;
}
if (key=='v' && state)
{
renderVisualGeometry = !renderVisualGeometry;
}
if (key=='g' && state)
{
renderGrid = !renderGrid;
}
if (key=='i' && state)
{
pauseSimulation = !pauseSimulation;
@@ -595,7 +601,7 @@ int main(int argc, char* argv[])
MyProfileWindow* profWindow = setupProfileWindow(gui->getInternalData());
profileWindowSetVisible(profWindow,false);
gui->setFocus();
#if 0
{
MyGraphInput input(gui->getInternalData());
@@ -720,6 +726,8 @@ int main(int argc, char* argv[])
BT_PROFILE("Update Camera");
s_instancingRenderer->updateCamera(dg.upAxis);
}
if (renderGrid)
{
BT_PROFILE("Draw Grid");
app->drawGrid(dg);
@@ -748,11 +756,18 @@ int main(int argc, char* argv[])
sCurrentDemo->stepSimulation(deltaTimeInSeconds);//1./60.f);
prevTimeInMicroseconds = curTimeInMicroseconds;
}
if (renderVisualGeometry)
{
if (visualWireframe)
{
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
}
BT_PROFILE("Render Scene");
sCurrentDemo->renderScene();
}
{
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
sCurrentDemo->physicsDebugDraw();
}
}
@@ -785,7 +800,7 @@ int main(int argc, char* argv[])
app->swapBuffer();
}
gui->forceUpdateScrollBars();
} while (!s_window->requestedExit());
// selectDemo(0);

View File

@@ -46,6 +46,8 @@
"../bullet2/MultiBodyDemo/TestJointTorqueSetup.h",
"../bullet2/MultiBodyDemo/MultiBodyVehicle.cpp",
"../bullet2/MultiBodyDemo/MultiBodyVehicle.h",
"../bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.cpp",
"../bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.h",
-- "../DifferentialGearDemo/DifferentialGearSetup.cpp",
-- "../DifferentialGearDemo/DifferentialGearSetup.h",
"../FiniteElementMethod/FiniteElementDemo.cpp",

View File

@@ -0,0 +1,308 @@
#ifndef DISTRIBUTE_POINTS_H
#define DISTRIBUTE_POINTS_H
#include "Bullet3AppSupport/BulletDemoInterface.h"
#include "OpenGLWindow/CommonGraphicsApp.h"
#include "BulletCollision/CollisionShapes/btConvexHullShape.h"
#include "BulletCollision/CollisionShapes/btConvexPolyhedron.h"
#include "btBulletDynamicsCommon.h"
inline btScalar randRange(btScalar minRange, btScalar maxRange)
{
return (rand() / (btScalar(RAND_MAX) + btScalar(1.0))) * (maxRange - minRange) + minRange;
}
void myCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
{
if (1)
{
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
btRigidBody* body0 = btRigidBody::upcast(colObj0);
btRigidBody* body1 = btRigidBody::upcast(colObj1);
if (body0 && body1)
{
btVector3 vec = body1->getWorldTransform().getOrigin()-body0->getWorldTransform().getOrigin();
vec.safeNormalize();
//add a small 'random' direction to avoid getting stuck in a plane
//vec += 0.00001*btVector3(randRange(0,1),randRange(0,1),randRange(0,1));
//magnitude: 1./vec.length1();
btScalar l = vec.length();
btScalar mag = 1.1/(l*l*l);
body0->applyImpulse(-mag*vec,btVector3(0,0,0));
body1->applyImpulse(mag*vec,btVector3(0,0,0));
}
} else
{
btCollisionDispatcher::defaultNearCallback(collisionPair,dispatcher,dispatchInfo);
}
}
class DistributePoints : public BulletDemoInterface
{
CommonGraphicsApp* m_app;
float m_x;
float m_y;
btDefaultCollisionConfiguration* m_collisionConfiguration;
btCollisionDispatcher* m_dispatcher;
btDiscreteDynamicsWorld* m_dynamicsWorld;
btDbvtBroadphase* m_broadphase;
btSequentialImpulseConstraintSolver* m_solver;
public:
DistributePoints(CommonGraphicsApp* app)
:m_app(app),
m_x(0),
m_y(0)
{
m_app->setUpAxis(1);
m_collisionConfiguration = new btDefaultCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
m_solver = sol;
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
m_dispatcher->setNearCallback(myCallback);
}
virtual ~DistributePoints()
{
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
static BulletDemoInterface* CreateFunc(CommonGraphicsApp* app)
{
return new DistributePoints(app);
}
inline btScalar randRange(btScalar minRange, btScalar maxRange)
{
return (rand() / (btScalar(RAND_MAX) + btScalar(1.0))) * (maxRange - minRange) + minRange;
}
virtual void initPhysics()
{
//create spheres, attached with point to point constraint
//use a collision callback, apply forces
btScalar radius = 0.01;
btSphereShape* sphere = new btSphereShape(1);
int sphereId = m_app->registerGraphicsSphereShape(radius,false);
for (int i=0;i<256;i++)
{
btScalar mass =1.f;
btVector3 localInertia;
sphere->calculateLocalInertia(mass,localInertia);
btRigidBody::btRigidBodyConstructionInfo ci(mass,0,sphere,localInertia);
ci.m_startWorldTransform.setIdentity();
btVector3 center(randRange(-1,1),randRange(-1,1),randRange(-1,1));
center.normalize();
ci.m_startWorldTransform.setOrigin(center);
btRigidBody* body = new btRigidBody(ci);
const btVector3& pos = body->getWorldTransform().getOrigin();
btQuaternion orn = body->getWorldTransform().getRotation();
btVector4 color(1,0,0,1);
btVector3 scaling(radius,radius,radius);
int instanceId = m_app->m_renderer->registerGraphicsInstance(sphereId,pos,orn,color,scaling);
body->setUserIndex(instanceId);
m_dynamicsWorld->addRigidBody(body);
btVector3 pivotInA = -body->getWorldTransform().getOrigin();
btVector3 pivotInB(0,0,0);
// btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body, btTypedConstraint::getFixedBody(),pivotInA,pivotInB);
// m_dynamicsWorld->addConstraint(p2p);
body->setActivationState(DISABLE_DEACTIVATION);
}
m_dynamicsWorld->setGravity(btVector3(0,0,0));
m_app->m_renderer->writeTransforms();
}
virtual void exitPhysics()
{
}
virtual void stepSimulation(float deltaTime)
{
m_dynamicsWorld->stepSimulation(1./60.,0);
for (int i=0;i<m_dynamicsWorld->getNumCollisionObjects();i++)
{
btRigidBody* body = btRigidBody::upcast(m_dynamicsWorld->getCollisionObjectArray()[i]);
if (body && body->getUserIndex()>=0)
{
btTransform pos = body->getWorldTransform();
pos.setOrigin(pos.getOrigin().normalized());
body->setWorldTransform(pos);
body->setAngularVelocity(btVector3(0,0,0));
body->setLinearVelocity(btVector3(0,0,0));
}
}
}
virtual void renderScene()
{
//sync transforms
for (int i=0;i<m_dynamicsWorld->getNumCollisionObjects();i++)
{
btRigidBody* body = btRigidBody::upcast(m_dynamicsWorld->getCollisionObjectArray()[i]);
if (body && body->getUserIndex()>=0)
{
const btVector3& pos = body->getWorldTransform().getOrigin();
btQuaternion orn = body->getWorldTransform().getRotation();
m_app->m_renderer->writeSingleInstanceTransformToCPU(pos,orn,body->getUserIndex());
}
}
m_app->m_renderer->writeTransforms();
m_app->m_renderer->renderScene();
}
virtual void physicsDebugDraw()
{
int lineWidth = 1;
int pointSize = 2;
btAlignedObjectArray<btVector3> m_vertices;
for (int i=0;i<m_dynamicsWorld->getNumCollisionObjects();i++)
{
btRigidBody* body = btRigidBody::upcast(m_dynamicsWorld->getCollisionObjectArray()[i]);
if (body && body->getUserIndex()>=0)
{
btTransform pos = body->getWorldTransform();
m_vertices.push_back(pos.getOrigin());
}
}
btConvexHullShape* m_convexHull = new btConvexHullShape(&m_vertices[0].x(),m_vertices.size(),sizeof(btVector3));
m_convexHull->initializePolyhedralFeatures();
const btConvexPolyhedron* poly = m_convexHull->getConvexPolyhedron();
btScalar averageEdgeLength = 0.f;
btScalar numLengths=0;
for (int p=0;p<poly->m_faces.size();p++)
{
for (int f=2;f<poly->m_faces[p].m_indices.size();f++)
{
btVector4 color0(0,0,1,1);
btVector4 color1(0,0,1,1);
btVector4 color2(0,0,1,1);
int index0=poly->m_faces[p].m_indices[f-2];
int index1=poly->m_faces[p].m_indices[f-1];
int index2=poly->m_faces[p].m_indices[f];
btVector3 v0 = poly->m_vertices[index0];
btVector3 v1 = poly->m_vertices[index1];
btVector3 v2 = poly->m_vertices[index2];
btVector3 e0 = v1-v0;
btVector3 e1 = v2-v1;
btVector3 e2 = v0-v2;
btScalar e0Length = e0.length();
btScalar e1Length = e1.length();
btScalar e2Length = e2.length();
averageEdgeLength+=e0Length;
averageEdgeLength+=e1Length;
averageEdgeLength+=e2Length;
numLengths+=3;
}
}
averageEdgeLength/=numLengths;
btScalar maxLengthDiff = 0.f;
for (int p=0;p<poly->m_faces.size();p++)
{
for (int f=2;f<poly->m_faces[p].m_indices.size();f++)
{
btVector4 color0(0,0,1,1);
btVector4 color1(0,0,1,1);
btVector4 color2(0,0,1,1);
int index0=poly->m_faces[p].m_indices[f-2];
int index1=poly->m_faces[p].m_indices[f-1];
int index2=poly->m_faces[p].m_indices[f];
btVector3 v0 = poly->m_vertices[index0];
btVector3 v1 = poly->m_vertices[index1];
btVector3 v2 = poly->m_vertices[index2];
btVector3 e0 = v1-v0;
btVector3 e1 = v2-v1;
btVector3 e2 = v0-v2;
btScalar e0LengthDiff = btFabs(averageEdgeLength-e0.length());
btScalar e1LengthDiff = btFabs(averageEdgeLength-e1.length());
btScalar e2LengthDiff = btFabs(averageEdgeLength-e2.length());
btSetMax(maxLengthDiff,e0LengthDiff);
btSetMax(maxLengthDiff,e1LengthDiff);
btSetMax(maxLengthDiff,e2LengthDiff);
m_app->m_renderer->drawLine(&v0.x(),
&v1.x(),
color0,lineWidth);
m_app->m_renderer->drawLine(&v1.x(),
&v2.x(),
color1,lineWidth);
m_app->m_renderer->drawLine(&v2.x(),
&v0.x(),
color2,lineWidth);
}
//printf("maxEdgeLength=%f\n",maxEdgeLength);
}
for (int i=0;i<poly->m_vertices.size();i++)
{
btVector4 color(1,0,0,1);
m_app->m_renderer->drawPoint(poly->m_vertices[i],color,pointSize);
}
delete m_convexHull;
char msg[1024];
btScalar targetDist = 2.0f*sqrtf(4.0f/(btScalar)m_vertices.size());
sprintf(msg,"average Edge Length = %f, maxLengthDiff = %f",averageEdgeLength,maxLengthDiff);
b3Printf(msg);
}
virtual bool mouseMoveCallback(float x,float y)
{
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
return false;
}
virtual bool keyboardCallback(int key, int state)
{
return false;
}
};
#endif //DISTRIBUTE_POINTS_H

View File

@@ -0,0 +1,345 @@
#ifndef SPHERE_CREATION_H
#define SPHERE_CREATION_H
#include "Bullet3AppSupport/BulletDemoInterface.h"
#include "OpenGLWindow/CommonGraphicsApp.h"
#include "BulletCollision/CollisionShapes/btConvexHullShape.h"
#include "BulletCollision/CollisionShapes/btConvexPolyhedron.h"
class SphereCreation : public BulletDemoInterface
{
CommonGraphicsApp* m_app;
float m_x;
float m_y;
btAlignedObjectArray<btVector3> m_vertices;
btConvexHullShape* m_convexHull;
public:
SphereCreation(CommonGraphicsApp* app)
:m_app(app),
m_x(0),
m_y(0)
{
m_app->setUpAxis(1);
m_app->m_renderer->writeTransforms();
}
virtual ~SphereCreation()
{
}
static BulletDemoInterface* CreateFunc(CommonGraphicsApp* app)
{
return new SphereCreation(app);
}
inline btScalar randRange(btScalar minRange, btScalar maxRange)
{
return (rand() / (btScalar(RAND_MAX) + btScalar(1.0))) * (maxRange - minRange) + minRange;
}
virtual void initPhysics()
{
srand(0);
//create random vertices
int numVerts = 256;
for (int i=0;i<numVerts;i++)
{
btVector3 v(randRange(-1,1),randRange(-1,1),randRange(-1,1));
v.safeNormalize();
m_vertices.push_back(v);
}
for (int i=0;i<1;i++)
{
distributeVerticesOnSphere(5,0.2);
}
m_convexHull = new btConvexHullShape(&m_vertices[0].x(),m_vertices.size(),sizeof(btVector3));
m_convexHull->initializePolyhedralFeatures();
}
virtual void exitPhysics()
{
//dump vertices
printf("indices:\n");
const btConvexPolyhedron* poly = m_convexHull->getConvexPolyhedron();
for (int i=0;i<poly->m_vertices.size();i++)
{
printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,\n",poly->m_vertices[i].x(),
poly->m_vertices[i].y(),
poly->m_vertices[i].z(),
1.f,
poly->m_vertices[i].x(),
poly->m_vertices[i].y(),
poly->m_vertices[i].z(),
0.5f,0.5f);
}
for (int p=0;p<poly->m_faces.size();p++)
{
for (int f=2;f<poly->m_faces[p].m_indices.size();f++)
{
int index0=poly->m_faces[p].m_indices[f-2];
int index1=poly->m_faces[p].m_indices[f-1];
int index2=poly->m_faces[p].m_indices[f];
printf("%d,%d,%d,\n",index0,index1,index2);
}
}
}
void distributeVerticesOnSphere(int iterations,btScalar relaxation)
{
btScalar previousAverage=0;
btScalar averageDist = 0;
btScalar previousAverageError = 0.0f;
btScalar maxError = -1e30f;
btScalar averageError = 0.f;
///bring closest the closest neighbor of each vertex closer to the 'average' neighbor distance
for (int i=0;i<iterations;i++)
{
maxError = -1e30f;
averageDist = 0.f;
averageError = 0.f;
int numActualVerts = 0;
for (int v=0;v<m_vertices.size();v++)
{
btScalar minDist = 1e30f;
int closestOther = -1;
//find closest vertex
for (int w=0;w<m_vertices.size();w++)
{
if (w!=v)
{
numActualVerts++;
btVector3 vec = m_vertices[w]-m_vertices[v];
btScalar d = vec.length();
if (d<minDist)
{
minDist = d;
closestOther = w;
}
}
}
btScalar errorDist = previousAverage-minDist;
if (maxError < errorDist)
{
maxError = errorDist;
}
averageDist+=minDist;
if (closestOther>=0)
{
btVector3 vec = m_vertices[closestOther]-m_vertices[v];
vec.safeNormalize();
if (previousAverage)
{
averageError+=btFabs(errorDist);
m_vertices[v] -= vec*previousAverageError*relaxation;
m_vertices[closestOther] += vec*previousAverageError*relaxation;
m_vertices[v].normalize();
m_vertices[closestOther].normalize();
}
}
}
averageDist /= btScalar(m_vertices.size());
averageError /= btScalar(m_vertices.size());
previousAverageError = averageError;
previousAverage = averageDist;
}
char msg[1024];
btScalar targetDist = 2.0f*sqrtf(4.0f/(btScalar)m_vertices.size());
sprintf(msg,"averageDist = %f, previousAverageError = %f, maxError = %f, target = %f\n",averageDist,previousAverageError,maxError,targetDist);
b3Printf(msg);
}
virtual void stepSimulation(float deltaTime)
{
m_x+=0.01f;
m_y+=0.02f;
//bringVerticesTogether();
}
virtual void renderScene()
{
m_app->m_renderer->renderScene();
}
virtual void physicsDebugDraw()
{
int lineWidth = 1;
int pointSize = 2;
distributeVerticesOnSphere(12,0.2f);
delete m_convexHull;
m_convexHull = new btConvexHullShape(&m_vertices[0].x(),m_vertices.size(),sizeof(btVector3));
m_convexHull->initializePolyhedralFeatures();
const btConvexPolyhedron* poly = m_convexHull->getConvexPolyhedron();
if (m_vertices.size() != poly->m_vertices.size())
{
printf("Warning: m_vertices.size()=%d and poly->m_vertices.size()=%d\n", m_vertices.size(),
poly->m_vertices.size());
return;
} else
{
for (int i=0;i<m_vertices.size();i++)
{
m_vertices[i] = poly->m_vertices[i];
}
}
btScalar maxEdgeLength = -1e30f;
btScalar averageEdgeLength=0.f;
btScalar numLengts = 0;
for (int p=0;p<poly->m_faces.size();p++)
{
for (int f=2;f<poly->m_faces[p].m_indices.size();f++)
{
btVector4 color0(0,0,1,1);
btVector4 color1(0,0,1,1);
btVector4 color2(0,0,1,1);
int index0=poly->m_faces[p].m_indices[f-2];
int index1=poly->m_faces[p].m_indices[f-1];
int index2=poly->m_faces[p].m_indices[f];
btVector3 v0 = poly->m_vertices[index0];
btVector3 v1 = poly->m_vertices[index1];
btVector3 v2 = poly->m_vertices[index2];
btVector3 e0 = v1-v0;
btVector3 e1 = v2-v1;
btVector3 e2 = v0-v2;
btScalar e0Length = e0.length();
btScalar e1Length = e1.length();
btScalar e2Length = e2.length();
averageEdgeLength+= e0Length;
averageEdgeLength+= e1Length;
averageEdgeLength+= e2Length;
numLengts+=3.f;
}
}
averageEdgeLength/=numLengts;
for (int p=0;p<poly->m_faces.size();p++)
{
for (int f=2;f<poly->m_faces[p].m_indices.size();f++)
{
btVector4 color0(0,0,1,1);
btVector4 color1(0,0,1,1);
btVector4 color2(0,0,1,1);
int index0=poly->m_faces[p].m_indices[f-2];
int index1=poly->m_faces[p].m_indices[f-1];
int index2=poly->m_faces[p].m_indices[f];
btVector3 v0 = m_vertices[index0];
btVector3 v1 = m_vertices[index1];
btVector3 v2 = m_vertices[index2];
btVector3 e0 = v1-v0;
btVector3 e1 = v2-v1;
btVector3 e2 = v0-v2;
btScalar e0Length = e0.length();
btScalar e1Length = e1.length();
btScalar e2Length = e2.length();
btScalar scaling = -0.01;//-0.01f;//0;//-0.02f;
if (e0Length>maxEdgeLength)
maxEdgeLength = e0Length;
{
btScalar errorLength = averageEdgeLength-e0Length;
m_vertices[index0] += e0.normalized()*errorLength*scaling;
m_vertices[index1] -= e0.normalized()*errorLength*scaling;
m_vertices[index0].normalize();
m_vertices[index1].normalize();
color0.setValue(1,0,0,1);
//shift vertices
}
if (e1Length>maxEdgeLength)
maxEdgeLength = e1Length;
{
btScalar errorLength = averageEdgeLength-e1Length;
m_vertices[index1] += e1.normalized()*errorLength*scaling;
m_vertices[index2] -= e1.normalized()*errorLength*scaling;
m_vertices[index1].normalize();
m_vertices[index2].normalize();
color1.setValue(1,0,0,1);
}
if (e2Length>maxEdgeLength)
maxEdgeLength = e2Length;
{
btScalar errorLength = averageEdgeLength-e2Length;
m_vertices[index2] += e2.normalized()*errorLength*scaling;
m_vertices[index0] -= e2.normalized()*errorLength*scaling;
color2.setValue(1,0,0,1);
m_vertices[index2].normalize();
m_vertices[index0].normalize();
}
}
}
for (int p=0;p<poly->m_faces.size();p++)
{
for (int f=2;f<poly->m_faces[p].m_indices.size();f++)
{
btVector4 color0(0,0,1,1);
btVector4 color1(0,0,1,1);
btVector4 color2(0,0,1,1);
int index0=poly->m_faces[p].m_indices[f-2];
int index1=poly->m_faces[p].m_indices[f-1];
int index2=poly->m_faces[p].m_indices[f];
btVector3 v0 = m_vertices[index0];
btVector3 v1 = m_vertices[index1];
btVector3 v2 = m_vertices[index2];
m_app->m_renderer->drawLine(&v0.x(),
&v1.x(),
color0,lineWidth);
m_app->m_renderer->drawLine(&v1.x(),
&v2.x(),
color1,lineWidth);
m_app->m_renderer->drawLine(&v2.x(),
&v0.x(),
color2,lineWidth);
}
//printf("maxEdgeLength=%f\n",maxEdgeLength);
}
for (int i=0;i<m_vertices.size();i++)
{
btVector4 color(1,0,0,1);
m_app->m_renderer->drawPoint(m_vertices[i],color,pointSize);
}
}
virtual bool mouseMoveCallback(float x,float y)
{
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
return false;
}
virtual bool keyboardCallback(int key, int state)
{
return false;
}
};
#endif //SPHERE_CREATION_H

View File

@@ -0,0 +1,90 @@
#include "CoordinateFrameDemoPhysicsSetup.h"
#include "btBulletDynamicsCommon.h"
#define ARRAY_SIZE_Y 5
#define ARRAY_SIZE_X 5
#define ARRAY_SIZE_Z 5
bool showRigidBodyCenterOfMass = true;
void CoordinateFrameDemoPhysicsSetup::debugDraw()
{
/*
for (int i=0;i<m_dynamicsWorld->getCollisionObjectArray().size();i++)
{
const btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[i];
if (showRigidBodyCenterOfMass)
{
m_dynamicsWorld->getDebugDrawer()->drawTransform(colObj->getWorldTransform(),1);
}
}
*/
m_dynamicsWorld->debugDrawWorld();
}
void CoordinateFrameDemoPhysicsSetup::initPhysics(GraphicsPhysicsBridge& gfxBridge)
{
createEmptyDynamicsWorld();
m_dynamicsWorld->setGravity(btVector3(0,0,0));
gfxBridge.createPhysicsDebugDrawer(m_dynamicsWorld);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(m_dynamicsWorld->getDebugDrawer()->getDebugMode() + btIDebugDraw::DBG_DrawFrames);
btScalar sqr2 = btSqrt(2);
btVector3 tetraVerts[] = {
btVector3(1.f, 0.f, -1/sqr2),
btVector3(-1.f, 0.f, -1/sqr2),
btVector3(0, 1.f, 1/sqr2),
btVector3(0, -1.f, 1/sqr2),
};
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
btCompoundShape* hull = new btCompoundShape();
btConvexHullShape* childHull = new btConvexHullShape(&tetraVerts[0].getX(),sizeof(tetraVerts)/sizeof(btVector3),sizeof(btVector3));
childHull->initializePolyhedralFeatures();
btTransform childTrans;
childTrans.setIdentity();
childTrans.setOrigin(btVector3(2,0,0));
hull->addChildShape(childTrans,childHull);
gfxBridge.createCollisionShapeGraphicsObject(hull);
m_collisionShapes.push_back(hull);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
if (isDynamic)
hull->calculateLocalInertia(mass,localInertia);
startTransform.setOrigin(btVector3(0,0,0));
btRigidBody* body = createRigidBody(mass,startTransform,hull);
gfxBridge.createRigidBodyGraphicsObject(body, btVector3(1, 1, 0));
}
}

View File

@@ -22,7 +22,7 @@ struct CoordinateFrameDemoPhysicsSetup : public CommonRigidBodySetup
{
virtual void initPhysics(GraphicsPhysicsBridge& gfxBridge);
virtual void debugDraw();
};
#endif //COORDINATE_FRAME_DEMO_PHYSICS_SETUP_H

View File

@@ -1,90 +0,0 @@
#include "CoordinateFrameDemoPhysicsSetup.h"
#include "btBulletDynamicsCommon.h"
#define ARRAY_SIZE_Y 5
#define ARRAY_SIZE_X 5
#define ARRAY_SIZE_Z 5
void CoordinateFrameDemoPhysicsSetup::initPhysics(GraphicsPhysicsBridge& gfxBridge)
{
createEmptyDynamicsWorld();
gfxBridge.createPhysicsDebugDrawer(m_dynamicsWorld);
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);
///create a few basic rigid bodies
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
gfxBridge.createCollisionShapeGraphicsObject(groundShape);
//groundShape->initializePolyhedralFeatures();
// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50);
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-50,0));
{
btScalar mass(0.);
btRigidBody* body = createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1));
gfxBridge.createRigidBodyGraphicsObject(body, btVector3(0, 1, 0));
}
{
//create a few dynamic rigidbodies
// Re-using the same collision is better for memory usage and performance
btBoxShape* colShape = createBoxShape(btVector3(1,1,1));
gfxBridge.createCollisionShapeGraphicsObject(colShape);
//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
m_collisionShapes.push_back(colShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
btScalar mass(1.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0,0,0);
if (isDynamic)
colShape->calculateLocalInertia(mass,localInertia);
for (int k=0;k<ARRAY_SIZE_Y;k++)
{
for (int i=0;i<ARRAY_SIZE_X;i++)
{
for(int j = 0;j<ARRAY_SIZE_Z;j++)
{
startTransform.setOrigin(btVector3(
btScalar(2.0*i),
btScalar(20+2.0*k),
btScalar(2.0*j)));
btRigidBody* body = createRigidBody(mass,startTransform,colShape);
gfxBridge.createRigidBodyGraphicsObject(body, btVector3(1, 1, 0));
}
}
}
}
}

View File

@@ -33,97 +33,114 @@ struct MyGraphicsPhysicsBridge : public GraphicsPhysicsBridge
btCollisionShape* shape = body->getCollisionShape();
btTransform startTransform = body->getWorldTransform();
int graphicsShapeId = shape->getUserIndex();
btAssert(graphicsShapeId >= 0);
btVector3 localScaling = shape->getLocalScaling();
int graphicsInstanceId = m_glApp->m_renderer->registerGraphicsInstance(graphicsShapeId, startTransform.getOrigin(), startTransform.getRotation(), color, localScaling);
body->setUserIndex(graphicsInstanceId);
if (graphicsShapeId>=0)
{
// btAssert(graphicsShapeId >= 0);
btVector3 localScaling = shape->getLocalScaling();
int graphicsInstanceId = m_glApp->m_renderer->registerGraphicsInstance(graphicsShapeId, startTransform.getOrigin(), startTransform.getRotation(), color, localScaling);
body->setUserIndex(graphicsInstanceId);
}
}
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape, const btTransform& parentTransform, btAlignedObjectArray<GraphicsVertex>& verticesOut, btAlignedObjectArray<int>& indicesOut)
{
//todo: support all collision shape types
switch (collisionShape->getShapeType())
{
case TRIANGLE_MESH_SHAPE_PROXYTYPE:
{
break;
}
default:
{
if (collisionShape->isConvex())
{
btConvexShape* convex = (btConvexShape*)collisionShape;
{
btShapeHull* hull = new btShapeHull(convex);
hull->buildHull(0.0);
{
//int strideInBytes = 9*sizeof(float);
//int numVertices = hull->numVertices();
//int numIndices =hull->numIndices();
for (int t=0;t<hull->numTriangles();t++)
{
btVector3 triNormal;
int index0 = hull->getIndexPointer()[t*3+0];
int index1 = hull->getIndexPointer()[t*3+1];
int index2 = hull->getIndexPointer()[t*3+2];
btVector3 pos0 =parentTransform*hull->getVertexPointer()[index0];
btVector3 pos1 =parentTransform*hull->getVertexPointer()[index1];
btVector3 pos2 =parentTransform*hull->getVertexPointer()[index2];
triNormal = (pos1-pos0).cross(pos2-pos0);
triNormal.normalize();
for (int v=0;v<3;v++)
{
int index = hull->getIndexPointer()[t*3+v];
GraphicsVertex vtx;
btVector3 pos =parentTransform*hull->getVertexPointer()[index];
vtx.pos[0] = pos.x();
vtx.pos[1] = pos.y();
vtx.pos[2] = pos.z();
vtx.pos[3] = 0.f;
vtx.normal[0] =triNormal.x();
vtx.normal[1] =triNormal.y();
vtx.normal[2] =triNormal.z();
vtx.texcoord[0] = 0.5f;
vtx.texcoord[1] = 0.5f;
indicesOut.push_back(verticesOut.size());
verticesOut.push_back(vtx);
}
}
}
}
} else
{
if (collisionShape->isCompound())
{
btCompoundShape* compound = (btCompoundShape*) collisionShape;
for (int i=0;i<compound->getNumChildShapes();i++)
{
btTransform childWorldTrans = parentTransform * compound->getChildTransform(i);
createCollisionShapeGraphicsObject(compound->getChildShape(i),childWorldTrans,verticesOut,indicesOut);
}
} else
{
btAssert(0);
}
}
}
};
}
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)
{
//already has a graphics object?
if (collisionShape->getUserIndex()>=0)
return;
//todo: support all collision shape types
switch (collisionShape->getShapeType())
btAlignedObjectArray<GraphicsVertex> vertices;
btAlignedObjectArray<int> indices;
btTransform startTrans;startTrans.setIdentity();
createCollisionShapeGraphicsObject(collisionShape,startTrans,vertices,indices);
if (vertices.size() && indices.size())
{
case BOX_SHAPE_PROXYTYPE:
{
btBoxShape* box = (btBoxShape*)collisionShape;
btVector3 halfExtents = box->getHalfExtentsWithMargin();
int cubeShapeId = m_glApp->registerCubeShape(halfExtents.x(), halfExtents.y(), halfExtents.z());
box->setUserIndex(cubeShapeId);
break;
int shapeId = m_glApp->m_renderer->registerShape(&vertices[0].pos[0],vertices.size(),&indices[0],indices.size());
collisionShape->setUserIndex(shapeId);
}
case TRIANGLE_MESH_SHAPE_PROXYTYPE:
{
break;
}
default:
{
if (collisionShape->isConvex())
{
btConvexShape* convex = (btConvexShape*)collisionShape;
{
btShapeHull* hull = new btShapeHull(convex);
hull->buildHull(0.0);
{
//int strideInBytes = 9*sizeof(float);
//int numVertices = hull->numVertices();
//int numIndices =hull->numIndices();
btAlignedObjectArray<GraphicsVertex> gvertices;
btAlignedObjectArray<int> indices;
for (int t=0;t<hull->numTriangles();t++)
{
btVector3 triNormal;
int index0 = hull->getIndexPointer()[t*3+0];
int index1 = hull->getIndexPointer()[t*3+1];
int index2 = hull->getIndexPointer()[t*3+2];
btVector3 pos0 =hull->getVertexPointer()[index0];
btVector3 pos1 =hull->getVertexPointer()[index1];
btVector3 pos2 =hull->getVertexPointer()[index2];
triNormal = (pos1-pos0).cross(pos2-pos0);
triNormal.normalize();
for (int v=0;v<3;v++)
{
int index = hull->getIndexPointer()[t*3+v];
GraphicsVertex vtx;
btVector3 pos =hull->getVertexPointer()[index];
vtx.pos[0] = pos.x();
vtx.pos[1] = pos.y();
vtx.pos[2] = pos.z();
vtx.pos[3] = 0.f;
vtx.normal[0] =triNormal.x();
vtx.normal[1] =triNormal.y();
vtx.normal[2] =triNormal.z();
vtx.texcoord[0] = 0.5f;
vtx.texcoord[1] = 0.5f;
indices.push_back(gvertices.size());
gvertices.push_back(vtx);
}
}
int shapeId = m_glApp->m_renderer->registerShape(&gvertices[0].pos[0],gvertices.size(),&indices[0],indices.size());
convex->setUserIndex(shapeId);
}
}
} else
{
btAssert(0);
}
}
};
}
virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)
{

View File

@@ -282,6 +282,26 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere
}
void GwenUserInterface::forceUpdateScrollBars()
{
b3Assert(m_data);
b3Assert(m_data->m_explorerTreeCtrl);
if (m_data && m_data->m_explorerTreeCtrl)
{
m_data->m_explorerTreeCtrl->ForceUpdateScrollBars();
}
}
void GwenUserInterface::setFocus()
{
b3Assert(m_data);
b3Assert(m_data->m_explorerTreeCtrl);
if (m_data && m_data->m_explorerTreeCtrl)
{
m_data->m_explorerTreeCtrl->Focus();
}
}
b3ToggleButtonCallback GwenUserInterface::getToggleButtonCallback()
{
return m_data->m_toggleButtonCallback;

View File

@@ -25,6 +25,8 @@ class GwenUserInterface
virtual ~GwenUserInterface();
void init(int width, int height,Gwen::Renderer::Base* gwenRenderer,float retinaScale);
void setFocus();
void forceUpdateScrollBars();
void draw(int width, int height);

View File

@@ -15,7 +15,7 @@ using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( TreeControl )
{
m_TreeControl = this;
m_bUpdateScrollBar = 2;
m_ToggleButton->DelayedDelete();
m_ToggleButton = NULL;
m_Title->DelayedDelete();
@@ -49,7 +49,7 @@ void TreeControl::ForceUpdateScrollBars()
void TreeControl::OnChildBoundsChanged( Gwen::Rect /*oldChildBounds*/, Base* /*pChild*/ )
{
//m_ScrollControl->UpdateScrollBars();
}
void TreeControl::Clear()
@@ -100,7 +100,7 @@ bool TreeControl::OnKeyUp( bool bDown )
{
if (bDown)
{
ForceUpdateScrollBars();
// int maxIndex = 0;
int newIndex = 0;
int maxItem=0;
@@ -151,6 +151,7 @@ bool TreeControl::OnKeyUp( bool bDown )
}
}
}
ForceUpdateScrollBars();
return true;
}
@@ -159,7 +160,7 @@ bool TreeControl::OnKeyDown( bool bDown )
{
if (bDown)
{
ForceUpdateScrollBars();
// int maxIndex = 0;
int newIndex = 0;
int maxItem=0;
@@ -210,6 +211,7 @@ bool TreeControl::OnKeyDown( bool bDown )
}
}
}
ForceUpdateScrollBars();
return true;
}
extern int avoidUpdate;
@@ -220,7 +222,7 @@ bool TreeControl::OnKeyRight( bool bDown )
{
avoidUpdate = -3;
ForceUpdateScrollBars();
iterate(ITERATE_ACTION_OPEN,0,0);
int maxItem=0;
int curItem=0;
@@ -255,6 +257,7 @@ bool TreeControl::OnKeyRight( bool bDown )
}
Invalidate();
}
ForceUpdateScrollBars();
return true;
}
bool TreeControl::OnKeyLeft( bool bDown )
@@ -264,7 +267,7 @@ bool TreeControl::OnKeyLeft( bool bDown )
avoidUpdate = -3;
ForceUpdateScrollBars();
iterate(ITERATE_ACTION_CLOSE,0,0);
@@ -304,11 +307,12 @@ bool TreeControl::OnKeyLeft( bool bDown )
}
//viewSize/contSize
printf("!\n");
//printf("!\n");
//this->Layout(0);
}
ForceUpdateScrollBars();
return true;
}

View File

@@ -144,13 +144,16 @@ void TreeNode::Open()
m_InnerPanel->Show();
if ( m_ToggleButton ) m_ToggleButton->SetToggleState( true );
Invalidate();
m_TreeControl->ForceUpdateScrollBars();
}
void TreeNode::Close()
{
m_InnerPanel->Hide();
if ( m_ToggleButton ) m_ToggleButton->SetToggleState( false );
Invalidate();
m_TreeControl->ForceUpdateScrollBars();
}
void TreeNode::ExpandAll()
@@ -273,6 +276,7 @@ void TreeNode::iterate(int action, int* curIndex, int* targetIndex)
{
Open();
break;
}
case ITERATE_ACTION_CLOSE:

View File

@@ -94,6 +94,8 @@ namespace Gwen
bool m_bRoot;
bool m_bSelected;
bool m_bSelectable;
int m_bUpdateScrollBar;
};
}

View File

@@ -42,6 +42,7 @@ struct CommonRenderInterface
virtual void drawLines(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, const unsigned int* indices, int numIndices, float pointDrawSize)=0;
virtual void drawLine(const float from[4], const float to[4], const float color[4], float lineWidth) = 0;
virtual void drawLine(const double from[4], const double to[4], const double color[4], double lineWidth) = 0;
virtual void drawPoint(const float* position, const float color[4], float pointDrawSize)=0;
virtual int registerShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType=B3_GL_TRIANGLES, int textureIndex=-1)=0;
virtual void updateShape(int shapeIndex, const float* vertices)=0;