Bullet Physics MultiSphereShape用法

时间:2012-01-24 01:43:49

标签: physics-engine bulletphysics rigid-bodies

  1. 我在这里发帖是因为我没有成功地直接在Bullet物理论坛上找到一个有用的答案,或者任何那些已经移植了库[JBullet,BulletCS]或将其纳入其中的相关论坛自己的产品[Blender,Panda3d]。在这看来,至少如果我能正确地提出这个问题,似乎最好得到一个有用的答复。

  2. 我想模拟骰子的滚动。我能找到的所有例子似乎都满足于使用Box形状。我对儿童游戏很感兴趣,而不是拉斯维加斯。至少在我的应用程序中,定义的差异是骰子[无论是6面还是其他东西,但让我们在这里坚持使用6面]具有'kinder-gentler'圆角边缘,没有尖角。

  3. 似乎btMultiSphereShape对我来说是完美的 - 我是一个没有从低级原语构建任何复杂形状的知识的人,我是一个希望使用已经内置的东西的人Bullet引擎的碰撞智能,而不是试图设计任何新的异国行为的人。

  4. 根据前言,我非常感谢一个简洁的例子:

    一个。如何将参数传递给btMultiSphhereShape构造函数;  湾如何配置需要传递给btDefaultMaotionState的转换;和  C。如何设置localInertia。

  5. 我知道这是一个通用的库,其中的类几乎可以支持任何内容,但是对于初学者来说,请不要讨论精心设计的工具包的那些非常好的属性,最重要的是什么对我有帮助[我相信很多其他用户]将是一个明确的例子,将这些关键属性提供给这些细节的必要类和方法:

    一个。一个尺寸相同的六面模具,让每边约2厘米的圆形立方体;  湾让'拐角'的半径为0.1厘米。

  6. 现在,还有一个请求。为了观察模具的行为,从一个简单的“下降”开始,仅考虑重力引起的力,请建议一个变换,这将导致与通常的“地板”示例碰撞产生某种有趣的翻滚结果;换句话说,它应该在圆角上撞击地板。

2 个答案:

答案 0 :(得分:1)

我在iOS设备上使用Bullet Physics来制作骰子游戏。为了获得更逼真的骰子,我创建了一个“RoundedCube”对象,它只是一个带有斜边的立方体。这是我写的用于创建verticies的Objective-c代码

//
//  Created by John Carter on 4/9/09.
//

#import "RoundedCube.h"


static const GLfloat voffset[] =
        {
        // Front Face (counterclockwise winding)
        +1.0f, +1.0f, +1.0f,
        -1.0f, +1.0f, +1.0f,
        -1.0f, -1.0f, +1.0f,
        +1.0f, +1.0f, +1.0f,
        -1.0f, -1.0f, +1.0f,
        +1.0f, -1.0f, +1.0f,

        // Back Face (clockwise winding)
        +1.0f, +1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,    
        -1.0f, +1.0f, -1.0f,
        +1.0f, +1.0f, -1.0f,
        +1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,

        // Top Face (counterclockwise winding)
        -1.0f, +1.0f, +1.0f,
        +1.0f, +1.0f, -1.0f,
        -1.0f, +1.0f, -1.0f,
        -1.0f, +1.0f, +1.0f,
        +1.0f, +1.0f, +1.0f,
        +1.0f, +1.0f, -1.0f,

        // Bottom Face (clockwise winding)
        -1.0f, -1.0f, +1.0f,
        -1.0f, -1.0f, -1.0f,
        +1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f, +1.0f,
        +1.0f, -1.0f, -1.0f,
        +1.0f, -1.0f, +1.0f,

        // Right Face (clockwise winding)
        +1.0f, -1.0f, +1.0f,
        +1.0f, +1.0f, -1.0f,
        +1.0f, +1.0f, +1.0f,
        +1.0f, -1.0f, +1.0f,
        +1.0f, -1.0f, -1.0f,
        +1.0f, +1.0f, -1.0f,

        // Left Face (counterclockwise winding)
        -1.0f, -1.0f, +1.0f,
        -1.0f, +1.0f, +1.0f,
        -1.0f, +1.0f, -1.0f,
        -1.0f, +1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f, +1.0f,
        };



// Private Methods
//
@interface RoundedCube()

- (void) computeRoundedCubeNormals;

@end



@implementation RoundedCube


- (void) dealloc
    {
    [super dealloc];
    }





- (void) computeRoundedCubeNormals
    {
    int i;

    xMinVertex = FLT_MAX;
    yMinVertex = FLT_MAX;
    zMinVertex = FLT_MAX;
    xMaxVertex = -FLT_MAX;
    yMaxVertex = -FLT_MAX;
    zMaxVertex = -FLT_MAX;

    for (i=0; i<vertexDataCount; i+=3)
        {
        if ( vertexData[i+0] < xMinVertex )
            xMinVertex = vertexData[i+0] ;
        if ( vertexData[i+1] < yMinVertex )
            yMinVertex = vertexData[i+1] ;
        if ( vertexData[i+2] < zMinVertex )
            zMinVertex = vertexData[i+2] ;

        if ( vertexData[i+0] > xMaxVertex )
            xMaxVertex = vertexData[i+0] ;
        if ( vertexData[i+1] > yMaxVertex )
            yMaxVertex = vertexData[i+1] ;
        if ( vertexData[i+2] > zMaxVertex )
            zMaxVertex = vertexData[i+2] ;
        }

    xVertexRange = fabs(xMaxVertex - xMinVertex);
    yVertexRange = fabs(yMaxVertex - yMinVertex);
    zVertexRange = fabs(zMaxVertex - zMinVertex);

    for (i=0; i<vertexDataCount; i+=9)
        {
        btVector3 V0 = btVector3( vertexData[i+0], vertexData[i+1], vertexData[i+2] );
        btVector3 V1 = btVector3( vertexData[i+3], vertexData[i+4], vertexData[i+5] );
        btVector3 V2 = btVector3( vertexData[i+6], vertexData[i+7], vertexData[i+8] );

        btVector3 delta1 = (V1) - (V0);
        btVector3 delta2 = (V2) - (V0);

        btVector3 vertexNormal = delta1.cross(delta2);
        vertexNormal = vertexNormal.normalize();

        if ( useAbsNormals )
            {
            vertexNormal = vertexNormal.absolute();
            }

        normalData[i+0] = vertexNormal[0];
        normalData[i+1] = vertexNormal[1];
        normalData[i+2] = vertexNormal[2];

        normalData[i+3] = vertexNormal[0];
        normalData[i+4] = vertexNormal[1];
        normalData[i+5] = vertexNormal[2];

        normalData[i+6] = vertexNormal[0];
        normalData[i+7] = vertexNormal[1];
        normalData[i+8] = vertexNormal[2];
        }
    }






- (void) addBeveledCorner:(int)bevelPlane At:(btVector3)bevelLocation Size:(btVector3)bevelSize Rotation:(double)rotationOrigin
    {
    btVector3 vertexPoint[6];
    double delta;
    double theta0;
    double theta1;
    double phi0;
    double phi1;
    int vp;
    int i;
    int j;
    int k;

    delta = (double)M_PI_2 / (double)smoothFactor;

    // vertical segments
    //
    for( i=0; i<smoothFactor; i++)
        {
        theta0 = (double)i * (double)delta;
        theta1 = (double)(i+1) * (double)delta;

        if ( bevelPlane==1 )
            {
            theta0 += M_PI;
            theta1 += M_PI;
            }

        // horizontal segments
        //
        for( j=0; j<smoothFactor; j++)
            {
            phi0 = (double)j * (double)delta;
            phi1 = (double)(j+1) * (double)delta;

            phi0 += rotationOrigin;
            phi1 += rotationOrigin;

            if ( bevelPlane==1 )
                {
                phi0 += M_PI;
                phi1 += M_PI;
                }

            vp=0;

            if ( bevelPlane==0 )
                {
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta0)*cos(phi0)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta0)), bevelLocation[2]+bevelSize[2]*btScalar(sin(theta0)*sin(phi0)));
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta0)*cos(phi1)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta0)), bevelLocation[2]+bevelSize[2]*btScalar(sin(theta0)*sin(phi1)));
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta1)*cos(phi1)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta1)), bevelLocation[2]+bevelSize[2]*btScalar(sin(theta1)*sin(phi1)));

                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta0)*cos(phi0)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta0)), bevelLocation[2]+bevelSize[2]*btScalar(sin(theta0)*sin(phi0)));
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta1)*cos(phi1)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta1)), bevelLocation[2]+bevelSize[2]*btScalar(sin(theta1)*sin(phi1)));
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta1)*cos(phi0)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta1)), bevelLocation[2]+bevelSize[2]*btScalar(sin(theta1)*sin(phi0)));
                }
            else
                {
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta0)*cos(phi0)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta0)), bevelLocation[2]+bevelSize[2]*btScalar(sin(theta0)*sin(phi0)));
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta1)*cos(phi1)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta1)), bevelLocation[2]+bevelSize[2]*btScalar(sin(theta1)*sin(phi1)));
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta0)*cos(phi1)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta0)), bevelLocation[2]+bevelSize[2]*btScalar(sin(theta0)*sin(phi1)));

                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta0)*cos(phi0)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta0)), bevelLocation[2]+bevelSize[2]*btScalar(sin(theta0)*sin(phi0)));
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta1)*cos(phi0)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta1)), bevelLocation[2]+bevelSize[2]*btScalar(sin(theta1)*sin(phi0)));
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta1)*cos(phi1)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta1)), bevelLocation[2]+bevelSize[2]*btScalar(sin(theta1)*sin(phi1)));
                }

            for ( k=0; k<6; k++ )
                {
                vertexData[coordinateElement++] = vertexPoint[k][0];
                vertexData[coordinateElement++] = vertexPoint[k][1];
                vertexData[coordinateElement++] = vertexPoint[k][2];

                colorData[colorElement++] = rgba[0];
                colorData[colorElement++] = rgba[1];
                colorData[colorElement++] = rgba[2];
                colorData[colorElement++] = rgba[3];
                }
            }
        }

    }







- (void) addBeveledEdge:(int)bevelPlane At:(btVector3)bevelLocation Size:(btVector3)bevelSize Rotation:(double)rotationOrigin
    {
    btVector3 vertexPoint[6];
    double origin;
    double delta;
    double theta0;
    double theta1;
    int vp;
    int i;
    int j;

    delta = (double)(M_PI_2) / (double)smoothFactor;

    for ( i=0; i<smoothFactor; i++ )
        {
        theta0 = (double)i * (double)delta;
        theta1 = (double)(i+1) * (double)delta;

        theta0 += rotationOrigin;
        theta1 += rotationOrigin;

        origin = (double)0.0;
        vp=0;

        switch( bevelPlane )
            {
            case 0:
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0], bevelLocation[1]+bevelSize[1]*btScalar(sin(theta0+origin)), bevelLocation[2]+bevelSize[2]*btScalar(cos(theta0+origin)) );
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0], bevelLocation[1]+bevelSize[1]*btScalar(sin(theta1+origin)), bevelLocation[2]+bevelSize[2]*btScalar(cos(theta1+origin)) );
                vertexPoint[vp++] = btVector3( bevelLocation[0]-bevelSize[0], bevelLocation[1]+bevelSize[1]*btScalar(sin(theta1+origin)), bevelLocation[2]+bevelSize[2]*btScalar(cos(theta1+origin)) );

                vertexPoint[vp++] = btVector3( bevelLocation[0]-bevelSize[0], bevelLocation[1]+bevelSize[1]*btScalar(sin(theta0+origin)), bevelLocation[2]+bevelSize[2]*btScalar(cos(theta0+origin)) );
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0], bevelLocation[1]+bevelSize[1]*btScalar(sin(theta0+origin)), bevelLocation[2]+bevelSize[2]*btScalar(cos(theta0+origin)) );
                vertexPoint[vp++] = btVector3( bevelLocation[0]-bevelSize[0], bevelLocation[1]+bevelSize[1]*btScalar(sin(theta1+origin)), bevelLocation[2]+bevelSize[2]*btScalar(cos(theta1+origin)) );
                break;

            case 1:
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta0+origin)), bevelLocation[1]+bevelSize[1], bevelLocation[2]+bevelSize[2]*btScalar(cos(theta0+origin)) );
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta1+origin)), bevelLocation[1]-bevelSize[1], bevelLocation[2]+bevelSize[2]*btScalar(cos(theta1+origin)) );
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta1+origin)), bevelLocation[1]+bevelSize[1], bevelLocation[2]+bevelSize[2]*btScalar(cos(theta1+origin)) );

                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta0+origin)), bevelLocation[1]-bevelSize[1], bevelLocation[2]+bevelSize[2]*btScalar(cos(theta0+origin)) );
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta1+origin)), bevelLocation[1]-bevelSize[1], bevelLocation[2]+bevelSize[2]*btScalar(cos(theta1+origin)) );
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta0+origin)), bevelLocation[1]+bevelSize[1], bevelLocation[2]+bevelSize[2]*btScalar(cos(theta0+origin)) );
                break;

            case 2:
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta0+origin)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta0+origin)), bevelLocation[2]+bevelSize[2] );
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta1+origin)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta1+origin)), bevelLocation[2]+bevelSize[2] );
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta1+origin)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta1+origin)), bevelLocation[2]-bevelSize[2] );

                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta0+origin)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta0+origin)), bevelLocation[2]-bevelSize[2] );
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta0+origin)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta0+origin)), bevelLocation[2]+bevelSize[2] );
                vertexPoint[vp++] = btVector3( bevelLocation[0]+bevelSize[0]*btScalar(sin(theta1+origin)), bevelLocation[1]+bevelSize[1]*btScalar(cos(theta1+origin)), bevelLocation[2]-bevelSize[2] );
                break;
            }


        for ( j=0; j<6; j++ )
            {
            vertexData[coordinateElement++] = vertexPoint[j][0];
            vertexData[coordinateElement++] = vertexPoint[j][1];
            vertexData[coordinateElement++] = vertexPoint[j][2];

            colorData[colorElement++] = rgba[0];
            colorData[colorElement++] = rgba[1];
            colorData[colorElement++] = rgba[2];
            colorData[colorElement++] = rgba[3];
            }
        }
    }


- (RoundedCube *) Length:(GLfloat)initLength Width:(GLfloat)initWidth Height:(GLfloat)initHeight Bevel:(GLfloat)initBevel SmoothFactor:(int)initSmoothFactor RGBA:(GLubyte *)initRGBA AbsNormals:(BOOL)initUseAbsNormals
    {
    int i;

    smoothFactor = initSmoothFactor;
    useAbsNormals = initUseAbsNormals;

    shape = (id *)self;
    length = initLength;
    width = initWidth;
    height = initHeight;
    bevel = initBevel;

    coordinateElement=0;
    colorElement=0;

    for (i=0; i<24; i++)
        rgba[i] = initRGBA[i];

    vertexCount = 36 + (12 * 6 * smoothFactor) + (smoothFactor * smoothFactor * 6 * 8);


    modelType = MT_BOX;
    constructMode = GL_TRIANGLES;
    showColorAndTexture = NO;
    vertexDataCount = vertexCount * 3;
    colorDataCount = vertexCount * 4;
    normalDataCount = vertexCount * 3;

    [self setSurfaceToDefault];

    vertexData = (GLfloat *)malloc(sizeof(GLfloat) * vertexDataCount);
    memset(vertexData, (unsigned int)0, sizeof(GLfloat) * vertexDataCount);

    normalData = (GLfloat *)malloc(sizeof(GLfloat) * normalDataCount);
    memset(normalData, (unsigned int)0, sizeof(GLfloat) * normalDataCount);

    colorData = (GLubyte *)malloc(sizeof(GLubyte) * colorDataCount);
    memset(colorData, (unsigned int)0, sizeof(GLubyte) * colorDataCount);

    int cubeSide;
    int trianglesPerSide;
    int pointsPerTriangle;

    for ( cubeSide=0; cubeSide<6; cubeSide++ )
        {
        for ( trianglesPerSide=0; trianglesPerSide<2; trianglesPerSide++ )
            {
            for ( pointsPerTriangle=0; pointsPerTriangle<3; pointsPerTriangle++ )
                {
                switch( cubeSide )
                    {
                    case 0:
                    case 1:
                        vertexData[coordinateElement+0] = voffset[coordinateElement+0] * (length - bevel);
                        vertexData[coordinateElement+1] = voffset[coordinateElement+1] * (width - bevel);
                        vertexData[coordinateElement+2] = voffset[coordinateElement+2] * height;
                        break;

                    case 2:
                    case 3:
                        vertexData[coordinateElement+0] = voffset[coordinateElement+0] * (length - bevel);
                        vertexData[coordinateElement+1] = voffset[coordinateElement+1] * width;
                        vertexData[coordinateElement+2] = voffset[coordinateElement+2] * (height - bevel);
                        break;

                    case 4:
                    case 5:
                        vertexData[coordinateElement+0] = voffset[coordinateElement+0] * length;
                        vertexData[coordinateElement+1] = voffset[coordinateElement+1] * (width - bevel);
                        vertexData[coordinateElement+2] = voffset[coordinateElement+2] * (height - bevel);
                        break;
                    }

                coordinateElement += 3;

                colorData[colorElement++] = rgba[(cubeSide*4) + 0]; // 1 RGBA color set per side
                colorData[colorElement++] = rgba[(cubeSide*4) + 1]; // 1 RGBA color set per side
                colorData[colorElement++] = rgba[(cubeSide*4) + 2]; // 1 RGBA color set per side
                colorData[colorElement++] = rgba[(cubeSide*4) + 3]; // 1 RGBA color set per side
                }
            }
        }


    [self addBeveledEdge:2 At:btVector3((length-bevel), (width-bevel), 0) Size:btVector3(bevel,bevel,height-bevel) Rotation:(double)0.0];
    [self addBeveledEdge:2 At:btVector3(-(length-bevel), (width-bevel), 0) Size:btVector3(bevel,bevel,height-bevel) Rotation:(double)-M_PI_2];
    [self addBeveledEdge:2 At:btVector3(-(length-bevel), -(width-bevel), 0) Size:btVector3(bevel,bevel,height-bevel) Rotation:(double)-M_PI];
    [self addBeveledEdge:2 At:btVector3((length-bevel), -(width-bevel), 0) Size:btVector3(bevel,bevel,height-bevel) Rotation:(double)M_PI_2];

    [self addBeveledEdge:1 At:btVector3((length-bevel), 0, (height-bevel)) Size:btVector3(bevel,width-bevel,bevel) Rotation:(double)0.0];
    [self addBeveledEdge:1 At:btVector3(-(length-bevel), 0, (height-bevel)) Size:btVector3(bevel,width-bevel,bevel) Rotation:(double)-M_PI_2];
    [self addBeveledEdge:1 At:btVector3(-(length-bevel), 0, -(height-bevel)) Size:btVector3(bevel,width-bevel,bevel) Rotation:(double)-M_PI];
    [self addBeveledEdge:1 At:btVector3((length-bevel), 0, -(height-bevel)) Size:btVector3(bevel,width-bevel,bevel) Rotation:(double)M_PI_2];

    [self addBeveledEdge:0 At:btVector3(0, (width-bevel),  (height-bevel)) Size:btVector3(length-bevel,bevel,bevel) Rotation:(double)0.0];
    [self addBeveledEdge:0 At:btVector3(0, -(width-bevel),  (height-bevel)) Size:btVector3(length-bevel,bevel,bevel) Rotation:(double)-M_PI_2];
    [self addBeveledEdge:0 At:btVector3(0, -(width-bevel),  -(height-bevel)) Size:btVector3(length-bevel,bevel,bevel) Rotation:(double)-M_PI];
    [self addBeveledEdge:0 At:btVector3(0, (width-bevel), -(height-bevel)) Size:btVector3(length-bevel,bevel,bevel) Rotation:(double)M_PI_2];

    [self addBeveledCorner:0 At:btVector3((length-bevel), (width-bevel), (height-bevel)) Size:btVector3(bevel,bevel,bevel) Rotation:(double)0.0];
    [self addBeveledCorner:0 At:btVector3((length-bevel), (width-bevel), -(height-bevel)) Size:btVector3(bevel,bevel,bevel) Rotation:(double)-M_PI_2];
    [self addBeveledCorner:0 At:btVector3(-(length-bevel), (width-bevel), (height-bevel)) Size:btVector3(bevel,bevel,bevel) Rotation:(double)M_PI_2];
    [self addBeveledCorner:0 At:btVector3(-(length-bevel), (width-bevel), -(height-bevel)) Size:btVector3(bevel,bevel,bevel) Rotation:(double)M_PI];

    [self addBeveledCorner:1 At:btVector3((length-bevel), -(width-bevel), (height-bevel)) Size:btVector3(bevel,bevel,bevel) Rotation:(double)0.0];
    [self addBeveledCorner:1 At:btVector3((length-bevel), -(width-bevel), -(height-bevel)) Size:btVector3(bevel,bevel,bevel) Rotation:(double)-M_PI_2];
    [self addBeveledCorner:1 At:btVector3(-(length-bevel), -(width-bevel), (height-bevel)) Size:btVector3(bevel,bevel,bevel) Rotation:(double)M_PI_2];
    [self addBeveledCorner:1 At:btVector3(-(length-bevel), -(width-bevel), -(height-bevel)) Size:btVector3(bevel,bevel,bevel) Rotation:(double)M_PI];

    [self computeRoundedCubeNormals];

    return self;
    }

@end

如果你有iOS设备,你可以在我的免费应用Amazing Dice HD on iTunes

中看到一个示例。

答案 1 :(得分:1)

我已经从我的一些旧项目发布了另一段代码,可能会让你朝着正确的方向前进。我添加了所有的依赖性,所以它很多。可能有帮助的方法是MeshObject,我基本上采用模型的顶点来创建相应的子弹对象以添加到物理世界

//
//  BulletEngine.h
//  Created by John Carter on 4/9/09.
//

#import <Foundation/Foundation.h>
#include "btBulletDynamicsCommon.h"
#include "Matrix.h"

@interface BulletEngine : NSObject
    {
    btScalar cycles;            // number of clocktick cycles to run with each call
    btScalar clockTick;     // 0.016 = 1/60th of a second
    }

@property (readwrite) btScalar cycles;
@property (readwrite) btScalar clockTick;

- (void) timeStep:(UIAccelerationValue *)accelerationValue;
- (void) timeStep;
- (void) addConstraint:(btTypedConstraint *)hinge disableCollisionsBetweenLinkedBodies:(BOOL)linkcrash;
- (void) releaseConstraints;

@end



//
//  BulletEngine.m
//  Created by John Carter on 4/9/09.
//
#import "BulletEngine.h"
#import "PhysicsObject.h"

// Private Methods
//
@interface BulletEngine()

@end


@implementation BulletEngine

@synthesize cycles;
@synthesize clockTick;

static btCollisionConfiguration* sCollisionConfig=0;
static btCollisionDispatcher* sCollisionDispatcher=0;
static btSequentialImpulseConstraintSolver* sConstraintSolver=0;
static btBroadphaseInterface* sBroadphase=0;
static btDiscreteDynamicsWorld *sDynamicsWorld=0;


- (id)init
    {
    self = [super init];

    if (self==nil)
        return self;

    // init Default Timing
    //
    cycles = 2;
    clockTick = 0.016;

    // init Bullet Objects
    //
    sCollisionConfig = new btDefaultCollisionConfiguration();
    sCollisionDispatcher = new btCollisionDispatcher(sCollisionConfig);
    sConstraintSolver = new btSequentialImpulseConstraintSolver;
    sBroadphase = new btDbvtBroadphase();

    sDynamicsWorld = new btDiscreteDynamicsWorld(sCollisionDispatcher,sBroadphase,sConstraintSolver,sCollisionConfig);
    sDynamicsWorld->setGravity(btVector3(0.0f,0.0f,0.0f));  // Initial Gravity of the object Space

    [PhysicsObject setDynamicsWorldPointerTo:sDynamicsWorld];

    //
    // 2.75 Increased performance by disabling motion state synchronization for static/inactive objects.
    // if that causes a problem. Uncomment the next line for backward compatibility.
    //
    // sDynamicsWorld->setSynchronizeAllMotionStates(true); 

    return self;
    }



- (void)dealloc
    {
    [self releaseConstraints];

    delete sDynamicsWorld;
    sDynamicsWorld=0;

    delete sConstraintSolver;
    sConstraintSolver=0;

    delete sCollisionDispatcher;
    sCollisionDispatcher=0;

    delete sBroadphase;
    sBroadphase=0;

    delete sCollisionConfig;
    sCollisionConfig=0;

    [super dealloc];
    }




- (void) releaseConstraints
    {
    int i;

    // remove contraints
    //
    for (i=sDynamicsWorld->getNumConstraints()-1; i>=0; i--)
        {
        btTypedConstraint *joint = sDynamicsWorld->getConstraint(i);
        sDynamicsWorld->removeConstraint(joint);
        delete joint;
        }
    }



- (void) addConstraint:(btTypedConstraint *)hinge disableCollisionsBetweenLinkedBodies:(BOOL)linkcrash
    {
    if (linkcrash)
        sDynamicsWorld->addConstraint(hinge, true);
    else
        sDynamicsWorld->addConstraint(hinge, false);
    }



- (void) timeStep:(UIAccelerationValue *)accelerationValue;
    {
    if (!sDynamicsWorld)
        return;


    sDynamicsWorld->setGravity(btVector3(accelerationValue[0], accelerationValue[1], accelerationValue[2]));


    //  Recommended values for faster systems or more simple Open/GL projects
    //
    //  cycles = 1;
    //  clockTick = 0.016f;
    //  
    sDynamicsWorld->stepSimulation( cycles*clockTick, cycles, clockTick);
    }


//
// Same as above but with NO Gravity
//
- (void) timeStep
    {
    if (!sDynamicsWorld)
        return;

    sDynamicsWorld->stepSimulation( cycles*clockTick, cycles, clockTick);
    }

@end









//
//  PhysicsObject.h
//  Created by John Carter on 4/9/09.
//
#import "BulletEngine.h"

@interface PhysicsObject : NSObject
    {
    btCollisionShape* collisionShape;
    btRigidBody *rigidBody;
    btDefaultMotionState *motionState;
    btCollisionObject *collisionObject;
    }

@property (readonly) btCollisionShape* collisionShape;
@property (readonly) btRigidBody *rigidBody;
@property (readonly) btDefaultMotionState *motionState;
@property (readonly) btCollisionObject *collisionObject;

+ (void) setDynamicsWorldPointerTo:(btDiscreteDynamicsWorld *)initSDynamicsWorld;

- (btRigidBody *) addPhysicsObject:(btCollisionShape *)newObjectShape At:(btVector3)location Tilt:(btVector3)tilt Mass:(btScalar)mass;
- (btRigidBody *) addInfinitePlane:(int)plane Shape:(btBoxShape *)worldBoxShape At:(btTransform)groundTransform Boundary:(btVector3)boundarySize;

@end




//
//  PhysicsObject.m
//  Created by John Carter on 4/9/09.
//
#import "PhysicsObject.h"


// Owned and Set by BulletEngine Object
//
static btDiscreteDynamicsWorld *sDynamicsWorld;


// Private Methods
//
@interface PhysicsObject()

@end


@implementation PhysicsObject


@synthesize collisionShape;
@synthesize rigidBody;
@synthesize motionState;
@synthesize collisionObject;




+ (void) setDynamicsWorldPointerTo:(btDiscreteDynamicsWorld *)initSDynamicsWorld
    {
    sDynamicsWorld=initSDynamicsWorld;
    }



- (void)dealloc
    {
    if (collisionShape)
        {
        delete collisionShape;
        collisionShape = 0;
        }

    if (rigidBody)
        {
        sDynamicsWorld->removeRigidBody(rigidBody);
        }

    if (motionState)
        {
        delete motionState;
        motionState = 0;
        }

    if (collisionObject)
        {
        sDynamicsWorld->removeCollisionObject( collisionObject );
        delete collisionObject;
        collisionObject = 0;
        }

    if (rigidBody)
        {
        delete rigidBody;
        rigidBody = 0;
        }

    [super dealloc];
    }



- (void) setCollisionObjectPointer
    {
    int i;
    for (i=sDynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
        {
        btCollisionObject* colObj = sDynamicsWorld->getCollisionObjectArray()[i];
        if (colObj)
            {
            btRigidBody* body = btRigidBody::upcast(colObj);
            if (body==rigidBody)
                {
                collisionObject = colObj;
                return;
                }
            }
        }

    collisionObject=0;

    return;
    }



- (btRigidBody *) addInfinitePlane:(int)plane Shape:(btBoxShape *)worldBoxShape At:(btTransform)groundTransform Boundary:(btVector3)boundarySize
    {
    btVector4 planeEq;

    worldBoxShape->getPlaneEquation( planeEq, plane);

    collisionShape = new btStaticPlaneShape( -planeEq, planeEq[3] );

    motionState = new btDefaultMotionState(groundTransform);

    btRigidBody::btRigidBodyConstructionInfo rbInfo(btScalar(0.0),  motionState,  collisionShape,  btVector3(btScalar(0.0),btScalar(0.0),btScalar(0.0)));

    btRigidBody* objectBody = new btRigidBody(rbInfo);

    sDynamicsWorld->addRigidBody(objectBody);

    [self setCollisionObjectPointer];

    return objectBody;
    }



- (btRigidBody *) addPhysicsObject:(btCollisionShape *)newObjectShape At:(btVector3)location Tilt:(btVector3)tilt Mass:(btScalar)mass
    {
    btTransform bodyTransform;
    bodyTransform.setIdentity();
    bodyTransform.setOrigin(location);
    bodyTransform.getBasis().setEulerZYX(tilt[0],tilt[1],tilt[2]);
    btVector3 localInertia(0,0,0);

    if ( mass > btScalar(0.0))
        {
        newObjectShape->calculateLocalInertia(mass,localInertia);
        }

    motionState = new btDefaultMotionState(bodyTransform);
    btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,motionState,newObjectShape,localInertia);
    btRigidBody* objectBody=new btRigidBody(rbInfo);

    //
    // Prevents objects from falling asleep after being idle for a long time
    //
    if ( objectBody != nil && mass >= btScalar(0.0))
        {
        objectBody->setDeactivationTime(0.0);
        objectBody->setSleepingThresholds(0.0, 0.0);
        objectBody->activate();
        }

    //add the body to the dynamics world
    //
    sDynamicsWorld->addRigidBody(objectBody);

    [self setCollisionObjectPointer];

    return objectBody;
    }

@end







//
//  MeshObject.h
//  Created by John Carter on 4/9/09.
//
#import "PhysicsObject.h"

@interface MeshObject : PhysicsObject
    {
    btTriangleMesh *mesh;
    }

- (id) initAt:(btVector3)location Size:(btVector3)size VertexCount:(int)initVertexCount Verticies:(btVector3 *)initVertex Mass:(btScalar)mass;
- (id) initAt:(btVector3)location Size:(btVector3)size VertexCount:(int)initVertexCount Verticies:(btVector3 *)initVertex Tilt:(btVector3)tilt Mass:(btScalar)mass;

@end



//
//  MeshObject.m
//  Created by John Carter on 4/9/09.
//
#import "MeshObject.h"


// Private Methods
//
@interface MeshObject()

@end


@implementation MeshObject


- (void)dealloc
    {
    delete mesh;
    mesh=0;
    [super dealloc];
    }

- (id) initAt:(btVector3)location Size:(btVector3)size VertexCount:(int)initVertexCount Verticies:(btVector3 *)initVertex Mass:(btScalar)mass
    {
    self = [super init];

    if (self==nil)
        return self;

    mesh = new btTriangleMesh(false);

    int i;
    for ( i=0 ; i<initVertexCount; i+=3)
        {
        btVector3 v1 = btVector3( initVertex[i+0][0]*size[0], initVertex[i+0][1]*size[1], initVertex[i+0][2]*size[2]);
        btVector3 v2 = btVector3( initVertex[i+1][0]*size[0], initVertex[i+1][1]*size[1], initVertex[i+1][2]*size[2]);
        btVector3 v3 = btVector3( initVertex[i+2][0]*size[0], initVertex[i+2][1]*size[1], initVertex[i+2][2]*size[2]);
        mesh->addTriangle(v1,v2,v3);
        }

    collisionShape = new btBvhTriangleMeshShape( mesh, true );

    rigidBody = [self addPhysicsObject:(btCollisionShape *)collisionShape At:(btVector3)location Tilt:btVector3(btScalar(0.0), btScalar(0.0), btScalar(0.0)) Mass:(btScalar)mass];

    return self;
    }



- (id) initAt:(btVector3)location Size:(btVector3)size VertexCount:(int)initVertexCount Verticies:(btVector3 *)initVertex Tilt:(btVector3)tilt Mass:(btScalar)mass
    {
    self = [super init];

    if (self==nil)
        return self;

    mesh = new btTriangleMesh(false);

    int i;
    for ( i=0 ; i<initVertexCount; i+=3)
        {
        btVector3 v1 = btVector3( initVertex[i+0][0]*size[0], initVertex[i+0][1]*size[1], initVertex[i+0][2]*size[2]);
        btVector3 v2 = btVector3( initVertex[i+1][0]*size[0], initVertex[i+1][1]*size[1], initVertex[i+1][2]*size[2]);
        btVector3 v3 = btVector3( initVertex[i+2][0]*size[0], initVertex[i+2][1]*size[1], initVertex[i+2][2]*size[2]);
        mesh->addTriangle(v1,v2,v3);
        }

    collisionShape = new btBvhTriangleMeshShape( mesh, true );

    rigidBody = [self addPhysicsObject:(btCollisionShape *)collisionShape At:(btVector3)location Tilt:tilt Mass:(btScalar)mass];

    return self;
    }



@end