Java 使用二维HUD图标在三维环境中跟踪对象
我试图有一个2D HUD,其中有图标,跟踪3D环境中HUD后面3D对象在屏幕上的位置 推理:有时你看不到3D对象(太远或离屏幕太远),但你仍然想知道它在哪里 问题:3D场景使用透视矩阵进行变换,赋予其深度(z轴),HUD严格为2D(xy平面)。由于深度的原因,2D HUD无法正确跟踪距离较远/较近的对象 我想要的:一种获取二维向量[(x,y)pos]的方法,用于放置图标,使其位于背景中三维对象的中心位置 xy平面(z=0)中所有对象的示例:Java 使用二维HUD图标在三维环境中跟踪对象,java,opengl,vector,jogl,hud,Java,Opengl,Vector,Jogl,Hud,我试图有一个2D HUD,其中有图标,跟踪3D环境中HUD后面3D对象在屏幕上的位置 推理:有时你看不到3D对象(太远或离屏幕太远),但你仍然想知道它在哪里 问题:3D场景使用透视矩阵进行变换,赋予其深度(z轴),HUD严格为2D(xy平面)。由于深度的原因,2D HUD无法正确跟踪距离较远/较近的对象 我想要的:一种获取二维向量[(x,y)pos]的方法,用于放置图标,使其位于背景中三维对象的中心位置 xy平面(z=0)中所有对象的示例: // Function call in the Ope
// Function call in the OpenGL draw() method
FloatMatrix proj = FloatMatrix.getPerspectiveMatrix( this.fov, this.width, this.height, 0.1f, 200.0f );
// Function
public static FloatMatrix getPerspectiveMatrix( Double fov, float w, float h, float near, float far ){
float asp = w/h;
float fov_cos = (float) Math.cos( fov / 2.0d );
float fov_sin = (float) Math.sin( fov / 2.0d );
float fov_cot = fov_cos/fov_sin;
float a_0 = fov_cot/asp;
float a_3 = (far + near)/(near-far);
float a_43 = (2.0f * far * near)/(near-far);
float[] an = {
a_0, 0.0f, 0.0f, 0.0f,
0.0f, fov_cot, 0.0f, 0.0f,
0.0f, 0.0f, a_3, -1.0f,
0.0f, 0.0f, a_43, 0.0f,
};
return new FloatMatrix( an, 4, 4 );
}
您可以看到,随着对象离中心越来越远,图标(白色的圆圈)越来越偏离中心。
深度增加的对象示例(离中心越远==越深):
// Function call in the OpenGL draw() method
FloatMatrix proj = FloatMatrix.getPerspectiveMatrix( this.fov, this.width, this.height, 0.1f, 200.0f );
// Function
public static FloatMatrix getPerspectiveMatrix( Double fov, float w, float h, float near, float far ){
float asp = w/h;
float fov_cos = (float) Math.cos( fov / 2.0d );
float fov_sin = (float) Math.sin( fov / 2.0d );
float fov_cot = fov_cos/fov_sin;
float a_0 = fov_cot/asp;
float a_3 = (far + near)/(near-far);
float a_43 = (2.0f * far * near)/(near-far);
float[] an = {
a_0, 0.0f, 0.0f, 0.0f,
0.0f, fov_cot, 0.0f, 0.0f,
0.0f, 0.0f, a_3, -1.0f,
0.0f, 0.0f, a_43, 0.0f,
};
return new FloatMatrix( an, 4, 4 );
}
可以看到,HUD认为三维对象仍然在同一平面上。
伪代码:
// Function call in the OpenGL draw() method
FloatMatrix proj = FloatMatrix.getPerspectiveMatrix( this.fov, this.width, this.height, 0.1f, 200.0f );
// Function
public static FloatMatrix getPerspectiveMatrix( Double fov, float w, float h, float near, float far ){
float asp = w/h;
float fov_cos = (float) Math.cos( fov / 2.0d );
float fov_sin = (float) Math.sin( fov / 2.0d );
float fov_cot = fov_cos/fov_sin;
float a_0 = fov_cot/asp;
float a_3 = (far + near)/(near-far);
float a_43 = (2.0f * far * near)/(near-far);
float[] an = {
a_0, 0.0f, 0.0f, 0.0f,
0.0f, fov_cot, 0.0f, 0.0f,
0.0f, 0.0f, a_3, -1.0f,
0.0f, 0.0f, a_43, 0.0f,
};
return new FloatMatrix( an, 4, 4 );
}
.getPos()获取向量(x,y,z)
我的透视矩阵:
// Function call in the OpenGL draw() method
FloatMatrix proj = FloatMatrix.getPerspectiveMatrix( this.fov, this.width, this.height, 0.1f, 200.0f );
// Function
public static FloatMatrix getPerspectiveMatrix( Double fov, float w, float h, float near, float far ){
float asp = w/h;
float fov_cos = (float) Math.cos( fov / 2.0d );
float fov_sin = (float) Math.sin( fov / 2.0d );
float fov_cot = fov_cos/fov_sin;
float a_0 = fov_cot/asp;
float a_3 = (far + near)/(near-far);
float a_43 = (2.0f * far * near)/(near-far);
float[] an = {
a_0, 0.0f, 0.0f, 0.0f,
0.0f, fov_cot, 0.0f, 0.0f,
0.0f, 0.0f, a_3, -1.0f,
0.0f, 0.0f, a_43, 0.0f,
};
return new FloatMatrix( an, 4, 4 );
}
这很简单。你可以用。它将采用给定的模型视图、投影和视口变换,以及一个三维点,并应用反转,在窗口坐标中为您吐出一个二维点(对于小的输入错误,我深表歉意,只需在此处键入此项): 完成此操作后,将在二维窗口坐标中创建三维点。然后简单地将投影切换到二维正交投影,以窗口像素为单位,并在二维空间中绘制HUD
对于性能,如果每帧要绘制多个HUD项目;只需每帧获取一次modelview/projection/viewport(或者,更好的是,如果您更改缓存并仅在需要时重新查询它们,则使其无效),并在后续调用
gluProject
时重用它们 @MichaelMitchell如果你想了解数学,请查看官方文件,其中底部显示了使用的矩阵方程。对于一个非常深入的描述,将给你一个完整的理解所涉及的数学加上一些,检查。这个链接显示了OpenGL从3D位置到最终渲染窗口坐标的所有步骤。哇!谢谢你的链接!