java - 球体碰撞测试 react 太快

标签 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);
}

是我的代码或数学有问题吗?我想不出还有什么可以尝试的,如果有人能指出我正确的方向,将会很有帮助。

最佳答案

您的 worldSpaceBoundingSphereRadius() 很可能是罪魁祸首。 任意顶点 是 (1,1,1) 的 vector ,因此只有当立方体模型的边长度为 2 * sqrt(1/3) 时,您的数学运算才有效。您想要做的是找到立方体模型边缘的确切长度,使用我的评论中的公式 (rad = sqrt( 3 * (x/2) * (x/2) )) 并使用该半径作为您的 任意顶点 (rad,rad,rad,1)。

此外,将乘法结果除以齐次坐标 (worldSpaceVector[0]/worldSpaceVector[3])。通过适当的旋转、平移或缩放,齐次坐标应始终恰好为 1(如果它以 1 开始)。如果不是,则可能有一个投影矩阵或其他不是基本变换的东西。

编辑:

由于您使用 worldSpaceBoundingSphereRadius() 仅获取半径,因此您只需要 getModelMatrix() 的缩放组件。如果返回缩放和平移,则该平移将应用于您的半径并使其比实际大得多。

关于java - 球体碰撞测试 react 太快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34319226/

相关文章:

android:screenOrientation ="sensorLandscape"显示最小 SDK 为 2.2 的项目的错误

iphone - iOS OpenGL ES 2.0 球体上的广告牌对象并随球体旋转

opengl-es - 如何将纹理作为一个 16 位(灰度)组件发送到 GPU?

java - 如何使用简单的 for 循环创建数组?

java - java中构造函数和方法返回不同的值

java - 如何查找文件是否为 CSV 文件?

java - 如何使用 libgdx 获取手机语言?

java - 使用自定义适配器创建列表时出现“无空构造函数”logcat 错误

python - 有多少人能够使用 Kivy 和 OpenGL2.0 运行应用程序

java - 使用 JavaFX 浏览器/WebEngine (Gradle) 构建 swing 项目