几天前我自己也在问同样的问题。我的解决方案正如Sierox所说。创建 BoxShape 的刚体并将其添加到 DynaicsWorld。要移动相机,请对其刚体施加力。我将线性阻尼设置为 0.999,角度阻尼设置为 1,以便在没有施加力时停止相机,即播放器停止按下按钮。
我也使用 body.setAngularFactor(0);所以盒子不会到处翻滚。还要将质量设置得非常低,以免过多地干扰其他物体,但仍然可以跳上并撞到它们,否则会受到它们的影响。
请记住将您的 x、y 和 z 坐标转换为笛卡尔平面,以便您沿相机方向移动。即
protected void setCartesian(){//set xyz to a standard plane
yrotrad = (float) (yrot / 180 * Math.PI);
xrotrad = (float) (xrot / 180 * Math.PI);
float pd = (float) (Math.PI/180);
x = (float) (-Math.cos(xrot*pd)*Math.sin(yrot*pd));
z = (float) (-Math.cos(xrot*pd)*Math.cos(yrot*pd));
//y = (float) Math.sin(xrot*pd);
}//..
public void forward(){// move forward from position in direction of camera
setCartesian();
x += (Math.sin(yrotrad))*spd;
z -= (Math.cos(yrotrad))*spd;
//y -= (Math.sin(xrotrad))*spd;
body.applyForce(new Vector3f(x,0,z),getThrow());
}//..
public Vector3f getThrow(){// get relative position of the camera
float nx=x,ny=y,nz=z;
float xrotrad, yrotrad;
yrotrad = (float) (yrot / 180 * Math.PI);
xrotrad = (float) (xrot / 180 * Math.PI);
nx += (Math.sin(yrotrad))*2;
nz -= (Math.cos(yrotrad))*2;
ny -= (Math.sin(xrotrad))*2;
return new Vector3f(nx,ny,nz);
}//..
跳转只需使用 body.setLinearVelocity(new Vector3f(0,jumpHt,0));并将 jumpHt 设置为您希望的任何速度。
我使用 getThrow 为我可能在屏幕上“投掷”或携带的其他对象返回一个向量。我希望我回答了你的问题并且没有提供太多非必要的信息。我会尝试找到给我这个想法的来源。我相信是在 Bullet 论坛上。
------- 编辑 ------
很抱歉遗漏了那部分
一旦刚体正常运行,您只需获取它的坐标并将其应用到您的相机,例如:
float mat[] = new float[16];
Transform t = new Transform();
t = body.getWorldTransform(t);
t.origin.get(mat);
x = mat[0];
y = mat[1];
z = mat[2];
gl.glRotatef(xrot, 1, 0, 0); //rotate our camera on teh x-axis (left and right)
gl.glRotatef(yrot, 0, 1, 0); //rotate our camera on the y-axis (up and down)
gl.glTranslatef(-x, -y, -z); //translate the screen to the position of our camera
在我的例子中,我将 OpenGL 用于图形。 xrot 和 yrot 代表相机的俯仰和偏航。上面的代码以矩阵的形式获取世界变换,对于相机而言,您只需拉出 x、y 和 z 坐标,然后应用变换。
从这里,要移动相机,你可以设置刚体的线速度来移动相机或施加力。