【问题标题】:How to calculate if 3D model is intersecting terrain surface LWJGL如何计算 3D 模型是否与地形表面相交 LWJGL
【发布时间】:2020-07-29 21:17:08
【问题描述】:

我目前正在开展一个项目,该项目使用 3d 单纯形噪声和行进立方体算法来程序生成地形。我正在尝试在玩家对象和地形网格之间实现碰撞检测,但我不知道如何开始。我已经阅读了一些关于使用 JBullet 和其他库的文章和帖子,但它们不支持复杂的网格,例如由单纯形噪声生成的网格。为了简化我自己的事情,我决定让玩家只能朝我指向的方向移动,这意味着我只需要检查玩家身上的一个奇点是否与地形相交。有什么方法可以实现这样的过程吗? (编辑:我已经研究过重心坐标,但我不知道如何在游戏中实现)

当前玩家代码

package Entities;

import org.lwjgl.glfw.GLFW;

import Engine.Input;
import Maths.Vector3f;
import Models.TexturedModel;

public class Player extends Entity {
    
    public float xspeed = 0,zspeed = 0, yspeed = 0; 
    public Vector3f mousePos;
    public float yrotation = 0, zrotation = 0;
    public float maxYRotation = 75f;
    
    private double lastMousePosX = 600 , newMousePosX;
    private double lastMousePosY = 500 , newMousePosY;
    private float speed = 3;
    
    public Player(TexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, float scale) {
        super(model, position, rotX, rotY, rotZ, scale);
    }
    public void move(){
        checkInput();
        System.out.println("x ="+this.position.x+" y ="+this.position.y+" z ="+this.position.z);
        checkCollision();
    }
    public boolean checkCollision(){
        if(terrain != null){
            for(int i = 0; i<terrain.getVertices().length; i+=9){
                Vector3f vertex1 = new Vector3f(terrain.getVertices()[i],terrain.getVertices()[i+1],terrain.getVertices()[i+2]);
                Vector3f vertex2 = new Vector3f(terrain.getVertices()[i+3],terrain.getVertices()[i+4],terrain.getVertices()[i+5]);
                Vector3f vertex3 = new Vector3f(terrain.getVertices()[i+6],terrain.getVertices()[i+7],terrain.getVertices()[i+8]);
                
                //Check if point p is interseting triangle (vertex1, vertex2, vertex3)
                if(someCalculationFunction(position, vertex1, vertex2, vertex3){
                    return true;
                }
            }
        }
        return false;
    }

    public void checkInput(){
        newMousePosX = Input.getMouseX();
        newMousePosY = Input.getMouseY();
        
        float dx = (float)(newMousePosX-lastMousePosX)*0.07f;
        float dy = (float)(newMousePosY-lastMousePosY)*0.07f;
        
        if(!Input.isMouseDown(GLFW.GLFW_MOUSE_BUTTON_1)){

            this.rotY -= dx/2;
            this.rotX -= dy*0.8f;
        
        }
        
        if(Math.abs(rotX) > 50){
            this.rotX = Math.abs(rotX)/rotX*50;
        }
        
        if(this.rotY<0){
            this.rotY = 360;
        }
        
        float horizontalDistance = speed*(float)(Math.cos(Math.toRadians(rotX)));
        float verticleDistance = speed*(float)(Math.sin(Math.toRadians(rotX)));

        if(Input.isKeyDown(GLFW.GLFW_KEY_W)){
            this.position.x += horizontalDistance*Math.sin(Math.toRadians(-rotY));
            this.position.z -= horizontalDistance*Math.cos(Math.toRadians(-rotY));
            this.position.y += verticleDistance;
        }else if(Input.isKeyDown(GLFW.GLFW_KEY_S)){
            this.position.x -= horizontalDistance*Math.sin(Math.toRadians(-rotY));
            this.position.z += horizontalDistance*Math.cos(Math.toRadians(-rotY));
            this.position.y -= verticleDistance;    
        }
        
        lastMousePosX = newMousePosX;
        lastMousePosY = newMousePosY;       
        
    }

}

【问题讨论】:

    标签: java opengl collision-detection lwjgl mesh


    【解决方案1】:

    如果我正确理解了这个问题,我并不肯定,但这个答案将解决确保玩家身高与其所站立的地形高度一致的问题

    使用重心坐标,您可以通过使用构成该三角形的三个顶点的高度来计算玩家的身高:

    public static float baryCentric(Vector3f p1, Vector3f p2, Vector3f p3, Vector2f pos) {
        float det = (p2.z - p3.z) * (p1.x - p3.x) + (p3.x - p2.x) * (p1.z - p3.z);
        float l1 = ((p2.z - p3.z) * (pos.x - p3.x) + (p3.x - p2.x) * (pos.y - p3.z)) / det;
        float l2 = ((p3.z - p1.z) * (pos.x - p3.x) + (p1.x - p3.x) * (pos.y - p3.z)) / det;
        float l3 = 1.0f - l1 - l2;
        return l1 * p1.y + l2 * p2.y + l3 * p3.y;
    }
    

    为了获得这三个点,您可以使用玩家的世界坐标进行计算:

        //Assuming the world is constructed of equal height and width sized triangles
        float gridSquareSize = SIZE_OF_TERRAIN_MESH / NUM_TRIANGLES_PER_ROW;
        float xCoord = worldX % gridSquareSize / gridSquareSize;
        float zCoord = worldZ % gridSquareSize / gridSquareSize;
    

    使用 xCoord 和 zCoord,您可以确定需要用于重心计算的 3 个点

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-01
      • 1970-01-01
      • 2014-02-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-28
      • 1970-01-01
      相关资源
      最近更新 更多