diff --git a/Demos/BasicDemo/BasicDemoPhysicsSetup.cpp b/Demos/BasicDemo/BasicDemoPhysicsSetup.cpp index b3465d0b4..6956f0fc0 100644 --- a/Demos/BasicDemo/BasicDemoPhysicsSetup.cpp +++ b/Demos/BasicDemo/BasicDemoPhysicsSetup.cpp @@ -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.))); diff --git a/Demos3/AllBullet2Demos/BulletDemoEntries.h b/Demos3/AllBullet2Demos/BulletDemoEntries.h index 0966d93cd..0eaed02d5 100644 --- a/Demos3/AllBullet2Demos/BulletDemoEntries.h +++ b/Demos3/AllBullet2Demos/BulletDemoEntries.h @@ -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}, diff --git a/Demos3/AllBullet2Demos/CMakeLists.txt b/Demos3/AllBullet2Demos/CMakeLists.txt index f2302168f..c46d331e5 100644 --- a/Demos3/AllBullet2Demos/CMakeLists.txt +++ b/Demos3/AllBullet2Demos/CMakeLists.txt @@ -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 diff --git a/Demos3/AllBullet2Demos/main.cpp b/Demos3/AllBullet2Demos/main.cpp index ae2e396d3..e570e4ca8 100644 --- a/Demos3/AllBullet2Demos/main.cpp +++ b/Demos3/AllBullet2Demos/main.cpp @@ -207,7 +207,10 @@ static BulletDemoInterface* sCurrentDemo = 0; static b3AlignedObjectArray 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); diff --git a/Demos3/AllBullet2Demos/premake4.lua b/Demos3/AllBullet2Demos/premake4.lua index 0b2038f57..9f5aadfb8 100644 --- a/Demos3/AllBullet2Demos/premake4.lua +++ b/Demos3/AllBullet2Demos/premake4.lua @@ -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", diff --git a/Demos3/Geometry/DistributePoints.h b/Demos3/Geometry/DistributePoints.h new file mode 100644 index 000000000..facf8a3bc --- /dev/null +++ b/Demos3/Geometry/DistributePoints.h @@ -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;igetNumCollisionObjects();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;igetNumCollisionObjects();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 m_vertices; + for (int i=0;igetNumCollisionObjects();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;pm_faces.size();p++) + { + for (int f=2;fm_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;pm_faces.size();p++) + { + for (int f=2;fm_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;im_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 + diff --git a/Demos3/Geometry/SphereCreation.h b/Demos3/Geometry/SphereCreation.h new file mode 100644 index 000000000..8febf629f --- /dev/null +++ b/Demos3/Geometry/SphereCreation.h @@ -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 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;iinitializePolyhedralFeatures(); + + } + virtual void exitPhysics() + { + //dump vertices + + printf("indices:\n"); + const btConvexPolyhedron* poly = m_convexHull->getConvexPolyhedron(); + for (int i=0;im_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;pm_faces.size();p++) + { + for (int f=2;fm_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=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;im_vertices[i]; + } + } + + btScalar maxEdgeLength = -1e30f; + btScalar averageEdgeLength=0.f; + btScalar numLengts = 0; + + for (int p=0;pm_faces.size();p++) + { + for (int f=2;fm_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;pm_faces.size();p++) + { + for (int f=2;fm_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;pm_faces.size();p++) + { + for (int f=2;fm_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;im_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 + diff --git a/Demos3/bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.cpp b/Demos3/bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.cpp new file mode 100644 index 000000000..a8f31b71c --- /dev/null +++ b/Demos3/bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.cpp @@ -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;igetCollisionObjectArray().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)); + } + +} + + + + + + + + + + diff --git a/Demos3/bullet2/CoordinateFramesDemo/CoordinateFrameDemoPhysicsSetup.h b/Demos3/bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.h similarity index 95% rename from Demos3/bullet2/CoordinateFramesDemo/CoordinateFrameDemoPhysicsSetup.h rename to Demos3/bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.h index ae6ee446e..2e13e5232 100644 --- a/Demos3/bullet2/CoordinateFramesDemo/CoordinateFrameDemoPhysicsSetup.h +++ b/Demos3/bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.h @@ -22,7 +22,7 @@ struct CoordinateFrameDemoPhysicsSetup : public CommonRigidBodySetup { virtual void initPhysics(GraphicsPhysicsBridge& gfxBridge); - + virtual void debugDraw(); }; #endif //COORDINATE_FRAME_DEMO_PHYSICS_SETUP_H diff --git a/Demos3/bullet2/CoordinateFramesDemo/CoordinateFrameDemoPhysicsSetup.cpp b/Demos3/bullet2/CoordinateFramesDemo/CoordinateFrameDemoPhysicsSetup.cpp deleted file mode 100644 index f0c533ade..000000000 --- a/Demos3/bullet2/CoordinateFramesDemo/CoordinateFrameDemoPhysicsSetup.cpp +++ /dev/null @@ -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;kgetCollisionShape(); 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& verticesOut, btAlignedObjectArray& 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;tnumTriangles();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;igetNumChildShapes();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 vertices; + btAlignedObjectArray 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 gvertices; - btAlignedObjectArray indices; - - for (int t=0;tnumTriangles();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) { diff --git a/btgui/Bullet3AppSupport/gwenUserInterface.cpp b/btgui/Bullet3AppSupport/gwenUserInterface.cpp index ad094c673..8100c57d2 100644 --- a/btgui/Bullet3AppSupport/gwenUserInterface.cpp +++ b/btgui/Bullet3AppSupport/gwenUserInterface.cpp @@ -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; diff --git a/btgui/Bullet3AppSupport/gwenUserInterface.h b/btgui/Bullet3AppSupport/gwenUserInterface.h index 4f6ed88c7..4b7fac785 100644 --- a/btgui/Bullet3AppSupport/gwenUserInterface.h +++ b/btgui/Bullet3AppSupport/gwenUserInterface.h @@ -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); diff --git a/btgui/Gwen/Controls/TreeControl.cpp b/btgui/Gwen/Controls/TreeControl.cpp index bb53413fe..d89f9ce1a 100644 --- a/btgui/Gwen/Controls/TreeControl.cpp +++ b/btgui/Gwen/Controls/TreeControl.cpp @@ -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; } diff --git a/btgui/Gwen/Controls/TreeNode.cpp b/btgui/Gwen/Controls/TreeNode.cpp index df3945b8c..0877c8a46 100644 --- a/btgui/Gwen/Controls/TreeNode.cpp +++ b/btgui/Gwen/Controls/TreeNode.cpp @@ -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: diff --git a/btgui/Gwen/Controls/TreeNode.h b/btgui/Gwen/Controls/TreeNode.h index cfeb7b11b..5cbbcc4bd 100644 --- a/btgui/Gwen/Controls/TreeNode.h +++ b/btgui/Gwen/Controls/TreeNode.h @@ -94,6 +94,8 @@ namespace Gwen bool m_bRoot; bool m_bSelected; bool m_bSelectable; + int m_bUpdateScrollBar; + }; } diff --git a/btgui/OpenGLWindow/CommonRenderInterface.h b/btgui/OpenGLWindow/CommonRenderInterface.h index 013239ef3..6cc62f6bc 100644 --- a/btgui/OpenGLWindow/CommonRenderInterface.h +++ b/btgui/OpenGLWindow/CommonRenderInterface.h @@ -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;