对于我正在制作三维游戏的屏幕叠加,我需要在3D世界中的某些位置显示图标。我已经设法从游戏中获得了几个可以实现这一目标的变量:
使用这些变量,我设法获得摄像机视图的右边缘和左边缘。使用这两个变量,我能够得到0到1之间的点,其中图标应该显示在x轴上。 (0在左边缘,1是右边缘)这似乎工作得很好,但只有当我与X轴或Z轴对齐时,如下例所示:
我一直在尝试使用以下旋转矩阵来解决这个问题:
[ Math.Cos(angle), -Math.Sin(angle) ]
[ Math.Sin(angle), Math.Cos(angle) ]
我所做的是,我将玩家位置,相机位置和相机边缘位置放在矩阵中作为世界点的旋转点。问题是,一旦我将角度量设置为90度,X和Y就会被翻转。我一直试图找到一个解决方案几天,但我找不到它,所以我希望任何人都可以在这里推动我朝着正确的方向前进。以下是我的代码的一些部分,可能有助于找到解决方案:
float PCDistXZ = (float)Math.Sqrt(deltaPCx * deltaPCx + deltaPCz * deltaPCz); // X/Z distance from the world point to the camera
Point fakeAvatarPos = RotateAround(new Point((int)point.x, (int)point.z), new Point((int)avatar.x, (int)avatar.z), (int)90);
Point fakeCameraPos = RotateAround(new Point((int)point.x, (int)point.z), new Point((int)camera.x, (int)camera.z), (int)90);
double edgeRight = fakeC.X + (Math.Sin(45) * PCDistXZ);
double edgeLeft = fakeC.X - (Math.Sin(45) * PCDistXZ);
float edgeTest_ScreenPositionX = (1 - (float)((edgeRight - P.x) / (edgeRight - edgeLeft))) * screenWidth;
public static Point RotateAround(Point pCenter,Point pPoint, float pAngle)
{
double angle = (pAngle * Math.PI) / 180;
double[,] matrix = new Double[2, 2] {
{ Math.Cos(angle), Math.Sin(angle) },
{ Math.Sin(angle), Math.Cos(angle) }
};
double xOffset = pPoint.X - pCenter.X;
double yOffset = pPoint.Y - pCenter.Y;
Point newPoint = new Point(
(int)(((pPoint.X - xOffset) * matrix[0, 0]) - ((pPoint.Y - xOffset) * matrix[0, 1])),
(int)(((pPoint.X - yOffset) * matrix[1, 0]) + ((pPoint.Y - yOffset) * matrix[1, 1]))
);
newPoint.X += (int)xOffset;
newPoint.Y += (int)yOffset;
return new Point(newPoint.X,newPoint.Y);
}
注意:我已将某些变量的名称更改为更易理解的名称,因此名称可能存在不一致。
编辑:我发现了视图和投影矩阵。我或许可以使用它们将3D位置转换为屏幕。我不确定是否可以用我有限的信息制作这个矩阵。