1

我项目的主要目标是将玩家角色从 3D 环境投影到 2D 屏幕。我已经在网上找到了一些有用的数学,但在过去的四天里,我无法让它发挥作用。每次我移动角色时,它都会出现在随机位置和/或离开屏幕。有时它水平跟随,但通常从不垂直。

我的问题很简单:我做错了什么?

// A few numbers to play with: 
// Case #1: myPos: 1104.031, 3505.031, -91.9875; myMousePos: 0, 180; myRotation: 153, 153, 25; playerPos: 1072, 3504, -91.9687 (Player Middle of Screen, Standing Behind Player)
// Case #2: myPos: 511.7656, 3549.25, -28.02344; myMousePos: 0, 347.5854; myRotation: 44, 2, 22; playerPos: 1632, 3232, -91.96875 (Player Middle of Screen, I stand higher and 1166 away)
// Case #3: myPos: 1105.523, 2898.336, -11.96875; myMousePos: 0, 58.67249; myRotation: 232, 184, 159; playerPos 1632, 3232, -91.96875 (Player Right, Lower Of Screen) 
Vect3d viewAngles;
Vect3d vForward, vRight, vUpward;
float ScreenX, ScreenY;
float[] fov;

bool 3dWorldTo2dScreen(Vect3d playerpos, Vect3d mypos, PlayerData myself)
{
    fov = new float[2];
    viewAngles = Vect3d();

    Vect3d vLocal, vTransForm;
    vTransForm = new Vect3d();
    vForward = new Vect3d();
    vRight = new Vect3d();
    vUpward = new Vect3d();

    fov[0] = myself.MouseX; // Sky: -89, Ground: 89, Middle: 0
    fov[1] = myself.MouseY; // 360 To 0

    viewAngles.x = myself.Rotation.x; 
    viewAngles.y = myself.Rotation.y;
    viewAngles.z = myself.Rotation.z;

    int screenCenterX = 320; // 640
    int screenCenterY = 240; // 480

    AngleVectors();
    vLocal = SubVectorDist(playerpos, mypos);

    vTransForm.x = vLocal.dotproduct(vRight);
    vTransForm.y = vLocal.dotproduct(vUpward);
    vTransForm.z = vLocal.dotproduct(vForward);

    if (vTransForm.z < 0.01)
        return false;

    ScreenX = screenCenterX + (screenCenterX / vTransForm.z * (1 / fov[0])) * vTransForm.x;
    ScreenY = screenCenterY - (screenCenterY / vTransForm.z * (1 / fov[1])) * vTransForm.y;

    return true;
}

Vect3d SubVectorDist(Vect3d playerFrom, Vect3d playerTo)
{
    return new Vect3d(playerFrom.x - playerTo.x, playerFrom.y - playerTo.y, playerFrom.z - playerTo.z);
}

private void AngleVectors()
{
    float angle;
    float sr, sp, sy, cr, cp, cy, 
    cpi = (3.141f * 2 / 360);

    angle = viewAngles.y * cpi;
    sy = (float)Math.Sin(angle);
    cy = (float)Math.Cos(angle);

    angle = viewAngles.x * cpi;
    sp = (float)Math.Sin(angle);
    cp = (float)Math.Cos(angle);

    angle = viewAngles.z * cpi;
    sr = (float)Math.Sin(angle);
    cr = (float)Math.Cos(angle);

    vForward.x = cp * cy;
    vForward.y = cp * sy;
    vForward.z = -sp;

    vRight.x = (-1 * sr * sp * cy + -1 * cr * -sy);
    vRight.y = (-1 * sr * sp * sy + -1 * cr * cy);
    vRight.z = -1 * sr * cp;

    vUpward.x = (cr * sp * cy + -sr * -sy);
    vUpward.y = (cr * sp * sy + -sr * cy);
    vUpward.z = cr * cp;
}
4

0 回答 0