球体碰撞测试反应太快

时间:2015-12-16 18:13:58

标签: java android opengl-es

我正在使用Java和OpenGL为Android编写游戏。我可以完美地将所有内容渲染到屏幕上,但是当我尝试检查两个对象是否发生碰撞时,我的算法会在屏幕上发生碰撞之前检测到碰撞。

以下是我测试碰撞的方法:

for(int i=0; i<enemies.size(); i++) {
    float enemyRadius = enemies.elementAt(i).worldSpaceBoundingSphereRadius();
    float[] enemyPosition = enemies.elementAt(i).getWorldSpaceCoordinates();

    for(int j=0; j<qubieBullets.size(); j++) {
        float bulletRadius = bullets.elementAt(j).worldSpaceBoundingSphereRadius();
        float[] bulletPosition = bullets.elementAt(j).getWorldSpaceCoordinates();

        float[] distanceVector = Vector3f.subtract(enemyPosition, bulletPosition);
        float distance = Vector3f.length(distanceVector);

        if(distance < (enemyRadius + bulletRadius)) {
            enemies.remove(i);
            qubieBullets.remove(j);

            i--;
            j--;

            // Reset enemy position
        }
    }
}

当敌方立方体(由用于碰撞检测的球体表示)关闭玩家时,玩家向敌人射击子弹(也是由球体表示的立方体)。我的期望是当子弹击中他的屏幕时敌人会被重置,但它发生的时间早于此。

计算世界空间位置和半径的方法:

public float[] getWorldSpaceCoordinates() {

    float[] modelSpaceCenter = {0.0f, 0.0f, 0.0f, 1.0f};
    float[] worldSpaceCenter = new float[4];
    Matrix.multiplyMV(worldSpaceCenter, 0, getModelMatrix(), 0, modelSpaceCenter, 0);
    return new float[] {worldSpaceCenter[0]/worldSpaceCenter[3], worldSpaceCenter[1]/worldSpaceCenter[3], worldSpaceCenter[2]/worldSpaceCenter[3]};
}

public float worldSpaceBoundingSphereRadius() {
    float[] arbitraryVertex = new float[] {1.0f, 1.0f, 1.0f, 1.0f};
    float[] worldSpaceVector = new float[4];
    Matrix.multiplyMV(worldSpaceVector, 0, getModelMatrix(), 0, arbitraryVertex, 0);
    float[] xyz = new float[] {worldSpaceVector[0]/worldSpaceVector[3], worldSpaceVector[1]/worldSpaceVector[3], worldSpaceVector[2]/worldSpaceVector[3]};
    return Vector3f.length(xyz);
}

我的代码或数学是错的吗?我想不出更多的尝试,如果有人能指出我正确的方向,那将会很有帮助。

1 个答案:

答案 0 :(得分:0)

你的 let fbAccessToken = FBSDKAccessToken.currentAccessToken().tokenString FBSDKGraphRequest(graphPath: "me?fields=id,name,email,gender,first_name,last_name,middle_name,birthday&access_token=\(fbAccessToken)", parameters: nil).startWithCompletionHandler({ (connection, result, error) in if ((error) != nil) { // Process error print("Error: \(error)") } else { print("fetched user: \(result)") } }) } func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) { print("User Logged Out") } 很可能是罪魁祸首。 worldSpaceBoundingSphereRadius()是(1,1,1)的向量,因此只有多维数据集模型的边长为arbitraryVertex时,您的数学才有效。你想要做的是找到你的立方体模型边缘的确切长度,使用我的评论(2 * sqrt(1/3))中的公式,并使用该半径作为rad = sqrt( 3 * (x/2) * (x/2) )arbitraryVertex)。

此外,您将乘法的结果除以同质坐标(rad,rad,rad,1)。通过适当的旋转,平移或缩放,同质坐标应始终精确worldSpaceVector[0]/worldSpaceVector[3](如果它始于一个)。如果不是,那么你可能有一个投影矩阵或其他不是基本转换的东西。

编辑:

由于您使用1仅获取半径,因此您只需要worldSpaceBoundingSphereRadius()的缩放组件。如果返回缩放转换,则此转换将应用于您的半径并使其大于实际大小。