Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Background

I am following on from this question, which isn't answered yet. Basically I have a cube and a UVSphere in my scene, with UVSphere on the top of the cube without touching the cube. Both exported from blender.

When I run the app The UVSphere does circle around the cube for 3 or 4 times and jump out of the scene. What I actually expect was the sphere to fall on top of the cube.

What this question about

From the comment to the linked question, I got to know about bullet debug drawing, which helps in debugging by drawing outline of physics bodies which are normally invisible. I did some research on that and came up with the code given below. From whatever I have read, below code should work, but it doesn't.

My Code

My bullet initialization code.

-(void) initializeScene {
    /*Setup physics world*/
    _physicsWorld = [[CC3PhysicsWorld alloc] init];
    [_physicsWorld setGravity:0 y:-9.8 z:0];

    /*Setting up debug draw*/
    MyDebugDraw *draw   =   new MyDebugDraw;
    draw->setDebugMode(draw->getDebugMode() 
                      | btIDebugDraw::DBG_DrawWireframe );
    _physicsWorld._discreteDynamicsWorld->setDebugDrawer(draw);

    /*Setup camera and lamb*/
    …………..

    //This simpleCube.pod contains the cube
    [self addContentFromPODFile: @"simpleCube.pod"];
    //This file contains sphere
    [self addContentFromPODFile: @"SimpleSphere.pod"];

    [self createGLBuffers];

    CC3MeshNode* cubeNode   = (CC3MeshNode*)[self getNodeNamed:@"Cube"];
    CC3MeshNode* sphereNode = (CC3MeshNode*)[self getNodeNamed:@"Sphere"]; 
    // both cubeNode and sphereNode are not nil from this point


    float *cVertexData  = (float*)((CC3VertexArrayMesh*)cubeNode.mesh)
                               .vertexLocations.vertices;
    int cVertexCount    = ((CC3VertexArrayMesh*)cubeNode.mesh)
                               .vertexLocations.vertexCount;

    btTriangleMesh* cTriangleMesh  = new btTriangleMesh();

    int offset = 0;
    for (int i = 0; i < (cVertexCount / 3); i++)
    {
        unsigned int index1 = offset;
        unsigned int index2 = offset+6;
        unsigned int index3 = offset+12;
        cTriangleMesh->addTriangle(
          btVector3(cVertexData[index1], cVertexData[index1+1], cVertexData[index1+2]),
          btVector3(cVertexData[index2], cVertexData[index2+1], cVertexData[index2+2]), 
          btVector3(cVertexData[index3], cVertexData[index3+1], cVertexData[index3+2]));
        offset += 18;
    }

    [self releaseRedundantData];

    /*Create a triangle mesh from the vertices*/
    btBvhTriangleMeshShape* cTriMeshShape 
                       = new btBvhTriangleMeshShape(cTriangleMesh,true);
    btCollisionShape *sphereShape = new btSphereShape(1);

    gTriMeshObject =   [_physicsWorld createPhysicsObjectTrimesh:cubeNode 
                            shape:cTriMeshShape 
                            mass:0 
                            restitution:1.0 
                            position:cubeNode.location];
    sphereObject   =   [_physicsWorld createPhysicsObject:sphereNode 
                            shape:sphereShape 
                            mass:1 
                            restitution:0.1 
                            position:sphereNode.location];
    sphereObject.rigidBody->setDamping(0.1,0.8);

    /*Enable debug drawing*/
    _physicsWorld._discreteDynamicsWorld->debugDrawWorld();
}

And My btIDebugDraw implementation (MyDebugDraw.h)

//MyDebugDraw.h
class MyDebugDraw: public btIDebugDraw{
    int m_debugMode;

public:

    virtual void drawLine(const btVector3& from,const btVector3& to
              ,const btVector3& color);

    virtual void   drawContactPoint(const btVector3& PointOnB
             ,const btVector3& normalOnB,btScalar distance
              ,int lifeTime,const btVector3& color);

    virtual void   reportErrorWarning(const char* warningString);

    virtual void   draw3dText(const btVector3& location
                             ,const char* textString);

    virtual void   setDebugMode(int debugMode);

    virtual int      getDebugMode() const;
};

void MyDebugDraw::drawLine(const btVector3& from,const btVector3& to
                              ,const btVector3& color){
    LogInfo(@"Works!!");
    glPushMatrix();
    glColor4f(color.getX(), color.getY(), color.getZ(), 1.0);

    const GLfloat line[] = {
        from.getX()*1, from.getY()*1, from.getZ()*1, //point A
        to.getX()*1, to.getY()*1,to.getZ()*1 //point B
    };
    glVertexPointer( 3,
                    GL_FLOAT,
                    0,
                    &line );
    glPointSize( 5.0f );
    glDrawArrays( GL_POINTS, 0, 2 );
    glDrawArrays( GL_LINES, 0, 2 );
    glPopMatrix();
}

void MyDebugDraw::drawContactPoint(const btVector3 &PointOnB 
         ,const btVector3 &normalOnB, btScalar distance
         ,int lifeTime, const btVector3 &color){      
}

void MyDebugDraw::reportErrorWarning(const char *warningString){
}

void MyDebugDraw::draw3dText(const btVector3 &location
                                , const char *textString){
}

void MyDebugDraw::setDebugMode(int debugMode){
}

int MyDebugDraw::getDebugMode() const{
    return DBG_DrawWireframe;
}

My Problem

The drawLine method is getting called. I can see the cube and sphere in place. Sphere again does some circling around the cube before jumping off.

No debug lines are getting drawn.

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

Okay I got it working. For everyone who faces this in the future..

Note : I use Cocos3D (2D) functions to draw the line. So this is not a generic solution.

This is how I done it.

1) Create a RuleSet objective C class

RuleSet.h

#import "CC3Scene.h"

@interface RuleSet : NSObject{
}
@property(strong, nonatomic) CC3Scene *currentScene;
@property (strong, nonatomic) NSMutableArray *lines;
+(id)sharedRuleSet;
-(void) debugLineFromX:(float)fromX fromY:(float)fromY 
      fromZ:(float)fromZ toX:(float)toX toY:(float)toY toZ:(float)toZ;
@end

RuleSet.m

#import "RuleSet.h"
#import "CC3MeshNode.h"

@implementation RuleSet
+(id)sharedRuleSet{
    static RuleSet *sharedRuleSet = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedRuleSet = [[self alloc] init];
    });
    return sharedRuleSet;
}

-(void) debugLineFromX:(float)fromX fromY:(float)fromY fromZ:(float)fromZ 
           toX:(float)toX toY:(float)toY toZ:(float)toZ {
    if (!self.lines) {
        self.lines        =   [NSMutableArray array];
    }
    float arr_location[] = {fromX,fromY,fromZ, toX,toY, toZ };
    CC3LineNode* lineNode = [CC3LineNode nodeWithName: @"Line test"];
    [lineNode populateAsLineStripWith: 2
                             vertices: arr_location
                            andRetain: YES];
    lineNode.color = ccRED;

    [self.lines addObject:lineNode];
    [self.currentScene addChild:lineNode];
}
@end

2) Create a custom btDebugDraw implementation

MyDebugDraw.h

#include <iostream>
#include "btIDebugDraw.h"
#import "RuleSet.h"

class MyDebugDraw: public btIDebugDraw{
    int m_debugMode;

public:
    virtual void drawLine(const btVector3& from,const btVector3& to
                    ,const btVector3& color);
    virtual void drawContactPoint(const btVector3& PointOnB
                       ,const btVector3& normalOnB,btScalar distance
                       ,int lifeTime,const btVector3& color);
    virtual void reportErrorWarning(const char* warningString);
    virtual void draw3dText(const btVector3& location,const char* textString);
    virtual void setDebugMode(int debugMode);
    virtual int  getDebugMode() const;
};

void MyDebugDraw::drawLine(const btVector3& from,const btVector3& to
                                ,const btVector3& color)
{
    RuleSet *rule = [RuleSet sharedToolSet];
    [rule debugLineFromX:from.x() fromY:from.y() fromZ:from.z() 
                    toX:to.x() toY:to.y() toZ:to.z()];
}

void MyDebugDraw::drawContactPoint(const btVector3 &PointOnB
            , const btVector3 &normalOnB, btScalar distance
            , int lifeTime, const btVector3 &color){}

void MyDebugDraw::reportErrorWarning(const char *warningString){}

void MyDebugDraw::draw3dText(const btVector3 &location
                , const char *textString){}

void MyDebugDraw::setDebugMode(int debugMode){}

int MyDebugDraw::getDebugMode() const{
    return DBG_DrawWireframe;
}

3) During physics world initialization

YourScene.m

......
#import "RuleSet.h"
#import "MyDebugDraw.h"
.......

-(void) initializeScene {
    RuleSet *rule       =   [RuleSet sharedToolSet];
    rule.currentScene   =   self;

    //Create physics world
    btBroadphaseInterface* broadphase = new btDbvtBroadphase();
    btDefaultCollisionConfiguration* collisionConfiguration 
                  = new btDefaultCollisionConfiguration();
    btCollisionDispatcher* dispatcher 
           = new btCollisionDispatcher(collisionConfiguration);
    btSequentialImpulseConstraintSolver* solver 
           = new btSequentialImpulseConstraintSolver();
    dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher
              ,broadphase,solver,collisionConfiguration);
    dynamicsWorld->setGravity(btVector3(0,-10.0,0));

    /*Create custom debug drawer*/
    MyDebugDraw *draw   =   new MyDebugDraw;
    draw->setDebugMode( draw->getDebugMode()
          | btIDebugDraw::DBG_DrawWireframe );
    dynamicsWorld->setDebugDrawer(draw);

    /*Add rigid bodies and collision objects to physics world*/    
    .....
    .....

    /*At the end of initializeScene function
        , after adding physics bodies*/    
    dynamicsWorld->debugDrawWorld();
}

And credit goes here. This is not my code.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.