From 122fabac87a521dde2a1da0378e8c77962ea9ca4 Mon Sep 17 00:00:00 2001 From: erwin coumans Date: Fri, 12 Dec 2014 18:14:49 -0800 Subject: [PATCH 1/3] prepare to create coordinate frame demo, minor cleanup for create funcs in demo entries, fix r2d2.urdf inertia --- Demos3/AllBullet2Demos/BulletDemoEntries.h | 89 +++--- Demos3/AllBullet2Demos/main.cpp | 2 +- Demos3/ImportObjDemo/ImportObjSetup.cpp | 6 +- Demos3/ImportObjDemo/ImportObjSetup.h | 6 +- Demos3/ImportSTLDemo/ImportSTLSetup.cpp | 6 +- Demos3/ImportSTLDemo/ImportSTLSetup.h | 6 +- Demos3/ImportURDFDemo/ImportURDFSetup.cpp | 274 +++++++++++++++++- Demos3/ImportURDFDemo/ImportURDFSetup.h | 6 +- .../CoordinateFrameDemoPhysicsSetup.cpp | 90 ++++++ .../CoordinateFrameDemoPhysicsSetup.h | 28 ++ data/r2d2.urdf | 2 + 11 files changed, 433 insertions(+), 82 deletions(-) create mode 100644 Demos3/bullet2/CoordinateFramesDemo/CoordinateFrameDemoPhysicsSetup.cpp create mode 100644 Demos3/bullet2/CoordinateFramesDemo/CoordinateFrameDemoPhysicsSetup.h diff --git a/Demos3/AllBullet2Demos/BulletDemoEntries.h b/Demos3/AllBullet2Demos/BulletDemoEntries.h index e1fb78105..0966d93cd 100644 --- a/Demos3/AllBullet2Demos/BulletDemoEntries.h +++ b/Demos3/AllBullet2Demos/BulletDemoEntries.h @@ -4,6 +4,9 @@ #include "Bullet3AppSupport/BulletDemoInterface.h" #include "../bullet2/BasicDemo/BasicDemo.h" + +#include "../bullet2/CoordinateFramesDemo/CoordinateFrameDemoPhysicsSetup.h" + #include "../bullet2/BasicDemo/HingeDemo.h" #include "../bullet2/BasicDemo/HingeDemo.h" @@ -29,59 +32,33 @@ #include "../../Demos3/FiniteElementMethod/FiniteElementDemo.h" //#include "../../Demos3/bullet2/SoftDemo/SoftDemo.h" -static BulletDemoInterface* TestJointTorqueCreateFunc(CommonGraphicsApp* app) -{ - CommonPhysicsSetup* physicsSetup = new TestJointTorqueSetup(); - return new BasicDemo(app, physicsSetup); -} -static BulletDemoInterface* MultiBodyVehicleCreateFunc(CommonGraphicsApp* app) -{ - CommonPhysicsSetup* physicsSetup = new MultiBodyVehicleSetup(); - return new BasicDemo(app, physicsSetup); -} -static BulletDemoInterface* LuaDemoCreateFunc(CommonGraphicsApp* app) -{ - CommonPhysicsSetup* physicsSetup = new LuaPhysicsSetup(app); - return new BasicDemo(app, physicsSetup); + +#define MYCREATEFUNC(func) \ +static BulletDemoInterface* func##CreateFunc(CommonGraphicsApp* app)\ +{\ + CommonPhysicsSetup* physicsSetup = new func##Setup();\ + return new BasicDemo(app, physicsSetup);\ } -static BulletDemoInterface* MyCcdPhysicsDemoCreateFunc(CommonGraphicsApp* app) -{ - CommonPhysicsSetup* physicsSetup = new CcdPhysicsSetup(); - return new BasicDemo(app, physicsSetup); +#define MYCREATEFUNC2(func,setup) \ +static BulletDemoInterface* func(CommonGraphicsApp* app)\ +{\ + CommonPhysicsSetup* physicsSetup = new setup(app);\ + return new BasicDemo(app, physicsSetup);\ } -static BulletDemoInterface* MyKinematicObjectCreateFunc(CommonGraphicsApp* app) -{ - CommonPhysicsSetup* physicsSetup = new KinematicObjectSetup(); - return new BasicDemo(app, physicsSetup); -} -static BulletDemoInterface* MySerializeCreateFunc(CommonGraphicsApp* app) -{ - CommonPhysicsSetup* physicsSetup = new SerializeSetup(); - return new BasicDemo(app, physicsSetup); -} -static BulletDemoInterface* MyConstraintCreateFunc(CommonGraphicsApp* app) -{ - CommonPhysicsSetup* physicsSetup = new ConstraintPhysicsSetup(); - return new BasicDemo(app, physicsSetup); -} +MYCREATEFUNC(TestJointTorque); +MYCREATEFUNC(MultiBodyVehicle); +MYCREATEFUNC2(LuaDemoCreateFunc,LuaPhysicsSetup); +MYCREATEFUNC(Serialize); +MYCREATEFUNC(CcdPhysics); +MYCREATEFUNC(KinematicObject); +MYCREATEFUNC(ConstraintPhysics); +MYCREATEFUNC(ImportUrdf); +MYCREATEFUNC2(ImportObjCreateFunc,ImportObjSetup); +MYCREATEFUNC2(ImportSTLCreateFunc,ImportSTLSetup); +MYCREATEFUNC(CoordinateFrameDemoPhysics); -static BulletDemoInterface* MyImportUrdfCreateFunc(CommonGraphicsApp* app) -{ - CommonPhysicsSetup* physicsSetup = new ImportUrdfDemo(); - return new BasicDemo(app, physicsSetup); -} -static BulletDemoInterface* MyImportObjCreateFunc(CommonGraphicsApp* app) -{ - CommonPhysicsSetup* physicsSetup = new ImportObjDemo(app); - return new BasicDemo(app, physicsSetup); -} -static BulletDemoInterface* MyImportSTLCreateFunc(CommonGraphicsApp* app) -{ - CommonPhysicsSetup* physicsSetup = new ImportSTLDemo(app); - return new BasicDemo(app, physicsSetup); -} static BulletDemoInterface* MyImportColladaCreateFunc(CommonGraphicsApp* app) { @@ -92,7 +69,6 @@ static BulletDemoInterface* MyImportColladaCreateFunc(CommonGraphicsApp* app) - struct BulletDemoEntry { int m_menuLevel; @@ -107,21 +83,22 @@ 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}, - { 1, "CcdDemo", MyCcdPhysicsDemoCreateFunc }, - { 1, "Kinematic", MyKinematicObjectCreateFunc }, - { 1, "Constraints", MyConstraintCreateFunc }, + { 1, "CcdDemo", CcdPhysicsCreateFunc }, + { 1, "Kinematic", KinematicObjectCreateFunc }, + { 1, "Constraints", ConstraintPhysicsCreateFunc }, { 1, "LuaDemo",LuaDemoCreateFunc}, {0,"File Formats", 0}, - { 1, ".bullet",MySerializeCreateFunc}, - { 1, "Wavefront Obj", MyImportObjCreateFunc}, - { 1, "URDF", MyImportUrdfCreateFunc }, - { 1, "STL", MyImportSTLCreateFunc}, + { 1, ".bullet",SerializeCreateFunc}, + { 1, "Wavefront Obj", ImportObjCreateFunc}, + { 1, "URDF", ImportUrdfCreateFunc }, + { 1, "STL", ImportSTLCreateFunc}, { 1, "COLLADA", MyImportColladaCreateFunc}, {0,"Experiments", 0}, {1, "Finite Element Demo", FiniteElementDemo::CreateFunc}, diff --git a/Demos3/AllBullet2Demos/main.cpp b/Demos3/AllBullet2Demos/main.cpp index f8df8c3f1..ae2e396d3 100644 --- a/Demos3/AllBullet2Demos/main.cpp +++ b/Demos3/AllBullet2Demos/main.cpp @@ -321,7 +321,7 @@ void openURDFDemo(const char* filename) s_parameterInterface->removeAllParameters(); - ImportUrdfDemo* physicsSetup = new ImportUrdfDemo(); + ImportUrdfSetup* physicsSetup = new ImportUrdfSetup(); physicsSetup->setFileName(filename); sCurrentDemo = new BasicDemo(app, physicsSetup); diff --git a/Demos3/ImportObjDemo/ImportObjSetup.cpp b/Demos3/ImportObjDemo/ImportObjSetup.cpp index 13331a8ab..51f7f9d2b 100644 --- a/Demos3/ImportObjDemo/ImportObjSetup.cpp +++ b/Demos3/ImportObjDemo/ImportObjSetup.cpp @@ -7,13 +7,13 @@ #include "OpenGLWindow/SimpleOpenGL3App.h" #include "Wavefront2GLInstanceGraphicsShape.h" -ImportObjDemo::ImportObjDemo(CommonGraphicsApp* app) +ImportObjSetup::ImportObjSetup(CommonGraphicsApp* app) :m_app(app) { } -ImportObjDemo::~ImportObjDemo() +ImportObjSetup::~ImportObjSetup() { } @@ -24,7 +24,7 @@ ImportObjDemo::~ImportObjDemo() -void ImportObjDemo::initPhysics(GraphicsPhysicsBridge& gfxBridge) +void ImportObjSetup::initPhysics(GraphicsPhysicsBridge& gfxBridge) { gfxBridge.setUpAxis(2); this->createEmptyDynamicsWorld(); diff --git a/Demos3/ImportObjDemo/ImportObjSetup.h b/Demos3/ImportObjDemo/ImportObjSetup.h index a2fc64caf..3a88523b7 100644 --- a/Demos3/ImportObjDemo/ImportObjSetup.h +++ b/Demos3/ImportObjDemo/ImportObjSetup.h @@ -4,12 +4,12 @@ #include "Bullet3AppSupport/CommonRigidBodySetup.h" -class ImportObjDemo : public CommonRigidBodySetup +class ImportObjSetup : public CommonRigidBodySetup { struct CommonGraphicsApp* m_app; public: - ImportObjDemo(CommonGraphicsApp* app); - virtual ~ImportObjDemo(); + ImportObjSetup(CommonGraphicsApp* app); + virtual ~ImportObjSetup(); virtual void initPhysics(GraphicsPhysicsBridge& gfxBridge); }; diff --git a/Demos3/ImportSTLDemo/ImportSTLSetup.cpp b/Demos3/ImportSTLDemo/ImportSTLSetup.cpp index 4206be2f6..37a1a1373 100644 --- a/Demos3/ImportSTLDemo/ImportSTLSetup.cpp +++ b/Demos3/ImportSTLDemo/ImportSTLSetup.cpp @@ -6,20 +6,20 @@ #include "OpenGLWindow/SimpleOpenGL3App.h" #include "LoadMeshFromSTL.h" -ImportSTLDemo::ImportSTLDemo(CommonGraphicsApp* app) +ImportSTLSetup::ImportSTLSetup(CommonGraphicsApp* app) :m_app(app) { } -ImportSTLDemo::~ImportSTLDemo() +ImportSTLSetup::~ImportSTLSetup() { } -void ImportSTLDemo::initPhysics(GraphicsPhysicsBridge& gfxBridge) +void ImportSTLSetup::initPhysics(GraphicsPhysicsBridge& gfxBridge) { gfxBridge.setUpAxis(2); this->createEmptyDynamicsWorld(); diff --git a/Demos3/ImportSTLDemo/ImportSTLSetup.h b/Demos3/ImportSTLDemo/ImportSTLSetup.h index 7b3da3941..40c9c2bdf 100644 --- a/Demos3/ImportSTLDemo/ImportSTLSetup.h +++ b/Demos3/ImportSTLDemo/ImportSTLSetup.h @@ -4,12 +4,12 @@ #include "Bullet3AppSupport/CommonRigidBodySetup.h" -class ImportSTLDemo : public CommonRigidBodySetup +class ImportSTLSetup : public CommonRigidBodySetup { struct CommonGraphicsApp* m_app; public: - ImportSTLDemo(CommonGraphicsApp* app); - virtual ~ImportSTLDemo(); + ImportSTLSetup(CommonGraphicsApp* app); + virtual ~ImportSTLSetup(); virtual void initPhysics(GraphicsPhysicsBridge& gfxBridge); }; diff --git a/Demos3/ImportURDFDemo/ImportURDFSetup.cpp b/Demos3/ImportURDFDemo/ImportURDFSetup.cpp index affa8c93e..82113e2e8 100644 --- a/Demos3/ImportURDFDemo/ImportURDFSetup.cpp +++ b/Demos3/ImportURDFDemo/ImportURDFSetup.cpp @@ -12,12 +12,12 @@ static int bodyCollisionFilterMask=btBroadphaseProxy::AllFilter&(~btBroadphasePr static bool enableConstraints = true;//false; -ImportUrdfDemo::ImportUrdfDemo() +ImportUrdfSetup::ImportUrdfSetup() { - sprintf(m_fileName,"r2d2.urdf"); + sprintf(m_fileName,"r2d2.urdf");//sphere2.urdf");// } -ImportUrdfDemo::~ImportUrdfDemo() +ImportUrdfSetup::~ImportUrdfSetup() { } @@ -41,7 +41,7 @@ btVector3 selectColor() return color; } -void ImportUrdfDemo::setFileName(const char* urdfFileName) +void ImportUrdfSetup::setFileName(const char* urdfFileName) { memcpy(m_fileName,urdfFileName,strlen(urdfFileName)+1); } @@ -544,7 +544,260 @@ void URDFvisual2BulletCollisionShape(my_shared_ptr link, GraphicsPhy } -void ImportUrdfDemo::initPhysics(GraphicsPhysicsBridge& gfxBridge) + + + +btMultiBody* URDF2BulletMultiBody(my_shared_ptr link, GraphicsPhysicsBridge& gfxBridge, const btTransform& parentTransformInWorldSpace, btMultiBodyDynamicsWorld* world, URDF2BulletMappings& mappings, const char* pathPrefix, btMultiBody* mb, int totalNumJoints) +{ + + btScalar mass = 0.f; + btTransform localInertialTransform; localInertialTransform.setIdentity(); + btVector3 localInertiaDiagonal(0,0,0); + + { + + if ((*link).inertial) + { + mass = (*link).inertial->mass; + btMatrix3x3 inertiaMat; + inertiaMat.setIdentity(); + inertiaMat.setValue( + (*link).inertial->ixx,(*link).inertial->ixy,(*link).inertial->ixz, + (*link).inertial->ixy,(*link).inertial->iyy,(*link).inertial->iyz, + (*link).inertial->ixz,(*link).inertial->iyz,(*link).inertial->izz); + + btScalar threshold = 0.00001f; + int maxSteps=20; + btMatrix3x3 inertia2PrincipalAxis; + inertiaMat.diagonalize(inertia2PrincipalAxis,threshold,maxSteps); + localInertiaDiagonal.setValue(inertiaMat[0][0],inertiaMat[1][1],inertiaMat[2][2]); + + btVector3 inertiaLocalCOM((*link).inertial->origin.position.x,(*link).inertial->origin.position.y,(*link).inertial->origin.position.z); + localInertialTransform.setOrigin(inertiaLocalCOM); + btQuaternion inertiaOrn((*link).inertial->origin.rotation.x,(*link).inertial->origin.rotation.y,(*link).inertial->origin.rotation.z,(*link).inertial->origin.rotation.w); + btMatrix3x3 inertiaOrnMat(inertiaOrn); + + if (mass > 0 && (localInertiaDiagonal[0]==0.f || localInertiaDiagonal[1] == 0.f + || localInertiaDiagonal[2] == 0.f)) + { + b3Warning("Error: inertia should not be zero if mass is positive\n"); + localInertiaDiagonal.setMax(btVector3(0.1,0.1,0.1)); + localInertialTransform.setIdentity();//.setBasis(inertiaOrnMat); + } + else + { + localInertialTransform.setBasis(inertiaOrnMat*inertia2PrincipalAxis); + } + } + } + btTransform linkTransformInWorldSpace; + int parentIndex = -1; + + const Link* parentLink = (*link).getParent(); + if (parentLink) + { + parentIndex = parentLink->m_link_index; + btAssert(parentIndex>=0); + } + int linkIndex = mappings.m_linkMasses.size(); + + btTransform parent2joint; + + if ((*link).parent_joint) + { + const urdf::Vector3 pos = (*link).parent_joint->parent_to_joint_origin_transform.position; + const urdf::Rotation orn = (*link).parent_joint->parent_to_joint_origin_transform.rotation; + parent2joint.setOrigin(btVector3(pos.x,pos.y,pos.z)); + parent2joint.setRotation(btQuaternion(orn.x,orn.y,orn.z,orn.w)); + linkTransformInWorldSpace =parentTransformInWorldSpace*parent2joint; + } else + { + linkTransformInWorldSpace = parentTransformInWorldSpace; + + btAssert(mb==0); + + bool multiDof = true; + bool canSleep = false; + bool isFixedBase = (mass==0);//todo: figure out when base is fixed + + mb = new btMultiBody(totalNumJoints,mass, localInertiaDiagonal, isFixedBase, canSleep, multiDof); + + + } + + btAssert(mb); + + (*link).m_link_index = linkIndex; + + //compute this links center of mass transform, aligned with the principal axis of inertia + + + { + //btTransform rigidBodyFrameInWorldSpace =linkTransformInWorldSpace*inertialFrame; + + mappings.m_linkMasses.push_back(mass); + mappings.m_linkLocalDiagonalInertiaTensors.push_back(localInertiaDiagonal); + mappings.m_linkLocalInertiaTransforms.push_back(localInertialTransform); + + + + if ((*link).parent_joint) + { + btTransform offsetInA,offsetInB; + offsetInA.setIdentity(); + //offsetInA = mappings.m_linkLocalInertiaTransforms[parentIndex].inverse()*parent2joint; + offsetInA = parent2joint; + offsetInB.setIdentity(); + //offsetInB = localInertialTransform.inverse(); + + const Joint* pj = (*link).parent_joint.get(); + //btVector3 jointAxis(0,0,1);//pj->axis.x,pj->axis.y,pj->axis.z); + btVector3 jointAxis(pj->axis.x,pj->axis.y,pj->axis.z); + mappings.m_jointAxisArray.push_back(jointAxis); + mappings.m_jointOffsetInParent.push_back(offsetInA); + mappings.m_jointOffsetInChild.push_back(offsetInB); + mappings.m_jointTypeArray.push_back(pj->type); + + switch (pj->type) + { + case Joint::FIXED: + { + printf("Fixed joint\n"); + mb->setupFixed(linkIndex-1,mass,localInertiaDiagonal,parentIndex-1,offsetInA.getRotation(),offsetInA.getOrigin(),offsetInB.getOrigin()); + + break; + } + case Joint::CONTINUOUS: + case Joint::REVOLUTE: + { + printf("Revolute joint\n"); + mb->setupRevolute(linkIndex-1,mass,localInertiaDiagonal,parentIndex-1,offsetInA.getRotation(),jointAxis,offsetInA.getOrigin(),offsetInB.getOrigin(),true); + mb->finalizeMultiDof(); + //mb->setJointVel(linkIndex-1,1); + + break; + } + case Joint::PRISMATIC: + { + mb->setupPrismatic(linkIndex-1,mass,localInertiaDiagonal,parentIndex-1,offsetInA.getRotation(),jointAxis,offsetInB.getOrigin(),true); + printf("Prismatic joint\n"); + break; + } + default: + { + printf("Unknown joint\n"); + btAssert(0); + } + }; + + + + + } else + { + mappings.m_jointAxisArray.push_back(btVector3(0,0,0)); + btTransform ident; + ident.setIdentity(); + mappings.m_jointOffsetInParent.push_back(ident); + mappings.m_jointOffsetInChild.push_back(ident); + mappings.m_jointTypeArray.push_back(-1); + + + } + } + + //btCompoundShape* compoundShape = new btCompoundShape(); + btCollisionShape* shape = 0; + + for (int v=0;v<(int)link->collision_array.size();v++) + { + const Collision* visual = link->collision_array[v].get(); + + shape = convertVisualToCollisionShape(visual,pathPrefix); + + if (shape)//childShape) + { + gfxBridge.createCollisionShapeGraphicsObject(shape);//childShape); + + //btVector3 color = selectColor(); + /* + if (visual->material.get()) + { + color.setValue(visual->material->color.r,visual->material->color.g,visual->material->color.b);//,visual->material->color.a); + } + */ + btVector3 localInertia(0,0,0); + if (mass) + { + shape->calculateLocalInertia(mass,localInertia); + } + //btRigidBody::btRigidBodyConstructionInfo rbci(mass,0,shape,localInertia); + + + btVector3 visual_pos(visual->origin.position.x,visual->origin.position.y,visual->origin.position.z); + btQuaternion visual_orn(visual->origin.rotation.x,visual->origin.rotation.y,visual->origin.rotation.z,visual->origin.rotation.w); + btTransform visual_frame; + visual_frame.setOrigin(visual_pos); + visual_frame.setRotation(visual_orn); + btTransform childTransform; + childTransform.setIdentity();//TODO(erwincoumans): compute relative visual/inertial transform + // compoundShape->addChildShape(childTransform,childShape); + } + } + + if (shape)//compoundShape->getNumChildShapes()>0) + { + btMultiBodyLinkCollider* col= new btMultiBodyLinkCollider(mb, linkIndex-1); + col->setCollisionShape(shape); + + btTransform tr; + tr.setIdentity(); + tr = linkTransformInWorldSpace; + //if we don't set the initial pose of the btCollisionObject, the simulator will do this + //when syncing the btMultiBody link transforms to the btMultiBodyLinkCollider + + //tr.setOrigin(local_origin[0]); + //tr.setRotation(btQuaternion(quat[0],quat[1],quat[2],quat[3])); + col->setWorldTransform(tr); + + bool isDynamic = true; + short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter); + short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); + + world->addCollisionObject(col,collisionFilterGroup,collisionFilterMask); + + btVector3 color = selectColor();//(0.0,0.0,0.5); + gfxBridge.createCollisionObjectGraphicsObject(col,color); + btScalar friction = 0.5f; + + col->setFriction(friction); + + if (parentIndex>=0) + { + mb->getLink(linkIndex-1).m_collider=col; + } else + { + mb->setBaseCollider(col); + } + } + + for (std::vector >::const_iterator child = link->child_links.begin(); child != link->child_links.end(); child++) + { + if (*child) + { + URDF2BulletMultiBody(*child,gfxBridge, linkTransformInWorldSpace, world,mappings,pathPrefix,mb,totalNumJoints); + + } + else + { + std::cout << "root link: " << link->name << " has a null child!" << *child << std::endl; + } + } + return mb; +} + + +void ImportUrdfSetup::initPhysics(GraphicsPhysicsBridge& gfxBridge) { int upAxis = 2; @@ -620,15 +873,16 @@ void ImportUrdfDemo::initPhysics(GraphicsPhysicsBridge& gfxBridge) int numJoints = (*robot).m_numJoints; - if (1) + static bool useFeatherstone = false; + if (!useFeatherstone) { URDF2BulletMappings mappings; URDFvisual2BulletCollisionShape(root_link, gfxBridge, identityTrans,m_dynamicsWorld,mappings,pathPrefix); } //the btMultiBody support is work-in-progress :-) -#if 0 - if (0) +#if 1 + else { URDF2BulletMappings mappings; @@ -641,7 +895,7 @@ void ImportUrdfDemo::initPhysics(GraphicsPhysicsBridge& gfxBridge) } #endif// - + useFeatherstone = !useFeatherstone; printf("numJoints/DOFS = %d\n", numJoints); if (0) @@ -681,7 +935,7 @@ void ImportUrdfDemo::initPhysics(GraphicsPhysicsBridge& gfxBridge) } -void ImportUrdfDemo::stepSimulation(float deltaTime) +void ImportUrdfSetup::stepSimulation(float deltaTime) { if (m_dynamicsWorld) { diff --git a/Demos3/ImportURDFDemo/ImportURDFSetup.h b/Demos3/ImportURDFDemo/ImportURDFSetup.h index a9e0e4ef5..482a36915 100644 --- a/Demos3/ImportURDFDemo/ImportURDFSetup.h +++ b/Demos3/ImportURDFDemo/ImportURDFSetup.h @@ -4,13 +4,13 @@ #include "Bullet3AppSupport/CommonMultiBodySetup.h" -class ImportUrdfDemo : public CommonMultiBodySetup +class ImportUrdfSetup : public CommonMultiBodySetup { char m_fileName[1024]; public: - ImportUrdfDemo(); - virtual ~ImportUrdfDemo(); + ImportUrdfSetup(); + virtual ~ImportUrdfSetup(); virtual void initPhysics(GraphicsPhysicsBridge& gfxBridge); virtual void stepSimulation(float deltaTime); diff --git a/Demos3/bullet2/CoordinateFramesDemo/CoordinateFrameDemoPhysicsSetup.cpp b/Demos3/bullet2/CoordinateFramesDemo/CoordinateFrameDemoPhysicsSetup.cpp new file mode 100644 index 000000000..f0c533ade --- /dev/null +++ b/Demos3/bullet2/CoordinateFramesDemo/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 + +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 + @@ -145,6 +146,7 @@ + From 548fe5b04e3448e7b7293de94feb29ff4cc60f91 Mon Sep 17 00:00:00 2001 From: erwin coumans Date: Tue, 16 Dec 2014 14:27:38 -0800 Subject: [PATCH 2/3] 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 --- Demos/BasicDemo/BasicDemoPhysicsSetup.cpp | 3 +- Demos3/AllBullet2Demos/BulletDemoEntries.h | 11 +- Demos3/AllBullet2Demos/CMakeLists.txt | 2 + Demos3/AllBullet2Demos/main.cpp | 37 +- Demos3/AllBullet2Demos/premake4.lua | 2 + Demos3/Geometry/DistributePoints.h | 308 ++++++++++++++++ Demos3/Geometry/SphereCreation.h | 345 ++++++++++++++++++ .../CoordinateFrameDemoPhysicsSetup.cpp | 90 +++++ .../CoordinateFrameDemoPhysicsSetup.h | 2 +- .../CoordinateFrameDemoPhysicsSetup.cpp | 90 ----- .../Bullet2RigidBodyDemo.cpp | 181 ++++----- btgui/Bullet3AppSupport/gwenUserInterface.cpp | 20 + btgui/Bullet3AppSupport/gwenUserInterface.h | 2 + btgui/Gwen/Controls/TreeControl.cpp | 18 +- btgui/Gwen/Controls/TreeNode.cpp | 4 + btgui/Gwen/Controls/TreeNode.h | 2 + btgui/OpenGLWindow/CommonRenderInterface.h | 1 + 17 files changed, 922 insertions(+), 196 deletions(-) create mode 100644 Demos3/Geometry/DistributePoints.h create mode 100644 Demos3/Geometry/SphereCreation.h create mode 100644 Demos3/bullet2/CoordinateFrameDemo/CoordinateFrameDemoPhysicsSetup.cpp rename Demos3/bullet2/{CoordinateFramesDemo => CoordinateFrameDemo}/CoordinateFrameDemoPhysicsSetup.h (95%) delete mode 100644 Demos3/bullet2/CoordinateFramesDemo/CoordinateFrameDemoPhysicsSetup.cpp 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; From 5eb2c019575ff2ed4cd5bfbb566ab19a8dcf19a6 Mon Sep 17 00:00:00 2001 From: erwin coumans Date: Tue, 16 Dec 2014 14:58:50 -0800 Subject: [PATCH 3/3] fix double precision build --- btgui/OpenGLWindow/CommonRenderInterface.h | 1 + btgui/OpenGLWindow/GLInstancingRenderer.cpp | 9 +++++++++ btgui/OpenGLWindow/GLInstancingRenderer.h | 1 + 3 files changed, 11 insertions(+) diff --git a/btgui/OpenGLWindow/CommonRenderInterface.h b/btgui/OpenGLWindow/CommonRenderInterface.h index 6cc62f6bc..58bb42c23 100644 --- a/btgui/OpenGLWindow/CommonRenderInterface.h +++ b/btgui/OpenGLWindow/CommonRenderInterface.h @@ -43,6 +43,7 @@ struct CommonRenderInterface 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 void drawPoint(const double* position, const double color[4], double 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; diff --git a/btgui/OpenGLWindow/GLInstancingRenderer.cpp b/btgui/OpenGLWindow/GLInstancingRenderer.cpp index 6eb62a5cf..58aed9646 100644 --- a/btgui/OpenGLWindow/GLInstancingRenderer.cpp +++ b/btgui/OpenGLWindow/GLInstancingRenderer.cpp @@ -1339,10 +1339,19 @@ void GLInstancingRenderer::renderScene() } + +void GLInstancingRenderer::drawPoint(const double* position, const double color[4], double pointDrawSize) +{ + float pos[4]={position[0],position[1],position[2],0}; + float clr[4] = {color[0],color[1],color[2],color[3]}; + drawPoints(pos,clr,1,3*sizeof(float),float(pointDrawSize)); +} + void GLInstancingRenderer::drawPoint(const float* positions, const float color[4], float pointDrawSize) { drawPoints(positions,color,1,3*sizeof(float),pointDrawSize); } + void GLInstancingRenderer::drawPoints(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, float pointDrawSize) { diff --git a/btgui/OpenGLWindow/GLInstancingRenderer.h b/btgui/OpenGLWindow/GLInstancingRenderer.h index 27e26faf8..68880093d 100644 --- a/btgui/OpenGLWindow/GLInstancingRenderer.h +++ b/btgui/OpenGLWindow/GLInstancingRenderer.h @@ -104,6 +104,7 @@ public: virtual void drawLines(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, const unsigned int* indices, int numIndices, float pointDrawSize); virtual void drawPoints(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, float pointDrawSize); virtual void drawPoint(const float* position, const float color[4], float pointSize=1); + virtual void drawPoint(const double* position, const double color[4], double pointDrawSize=1); virtual void updateCamera(int upAxis=1); virtual void getCameraPosition(float cameraPos[4]);