【问题标题】:GML: 3D vector to 2D point on screenGML:3D 矢量到屏幕上的 2D 点
【发布时间】:2016-01-09 23:25:25
【问题描述】:

我有一个脚本,是的,它需要 11 个参数。它将屏幕上的鼠标坐标转换为用于 3D 鼠标坐标的 3D 矢量。它的准确性非常完美。

{
var mm,dX,dY,dZ,uX,uY,uZ,vX,vY,vZ,mX,mY,mZ, width, height, tFOV;
dX = argument3-argument0;
dY = argument4-argument1;
dZ = argument5-argument2;
mm = sqrt(dX*dX+dY*dY+dZ*dZ);
dX /= mm;
dY /= mm;
dZ /= mm;
uX = argument6;
uY = argument7;
uZ = argument8;
mm = uX*dX+uY*dY+uZ*dZ;
uX -= mm*dX;
uY -= mm*dY;
uZ -= mm*dZ
mm = sqrt(uX*uX+uY*uY+uZ*uZ);
uX /= mm;
uY /= mm;
uZ /= mm;
// v = u x d
vX = uY*dZ-dY*uZ;
vY = uZ*dX-dZ*uX;
vZ = uX*dY-dX*uY;
tFOV = tan(argument9*pi/360);
uX *= tFOV;
uY *= tFOV;
uZ *= tFOV;
vX *= tFOV*argument10;
vY *= tFOV*argument10;
vZ *= tFOV*argument10;
width = window_get_width();
height = window_get_height();
mX = dX+uX*(1-2*mouse_y/height)+vX*(2*mouse_x/width-1);
mY = dY+uY*(1-2*mouse_y/height)+vY*(2*mouse_x/width-1);
mZ = dZ+uZ*(1-2*mouse_y/height)+vZ*(2*mouse_x/width-1);
mm = sqrt(mX*mX+mY*mY+mZ*mZ);
global.mouse_dx = mX/mm;
global.mouse_dy = mY/mm;
global.mouse_dz = mZ/mm;
}

我想要做的是反转这个脚本,以便 14 个参数。与这个相同的 11,但多了 3 个代表向量的 x、y 和 z。

我知道这不是很多人都能真正理解的编码语言。您可能已经习惯了 C、Java、Lua、Python 或类似的东西。这不一样。语法大不相同。 3D中的mouse_x和mouse_y代表游戏窗口中鼠标的x和y。

不管怎样,我已经尝试了很长时间。谁能帮我从最后开始反转这个脚本并返回一个包含 2 个索引 x 和 y 的数组?它可能不会那么容易工作,但我正在尝试将 3D 点转换为涉及相机的 2D 点。

这里是原始脚本的参数列表:

(xfrom,yfrom,zfrom,xto,yto,zto,xup,yup,zup,角度,方面)

xfrom、yfrom 和 zfrom 表示相机的 x,y,z。 xto、yto 和 zto 表示相机正在看的坐标。 xup、yup 和 zup 是相机感知为“向上”的向量。在我的例子中,0,0,1 用于将正 z 值表示为向上,将负 z 值表示为向下。角度是相机的水平视野。 aspect 是窗口的宽度除以窗口的高度。

【问题讨论】:

    标签: 3d game-maker gml


    【解决方案1】:

    非常奇怪的是,您正在使用的脚本的作者(在该程序的官方论坛上使用用户名“Yourself”)也制作了一个相反的脚本。事实上,这些通常是一起分发的,我有点惊讶你偶然发现了一个只有其中一个的示例/帖子/教程。

    不管怎样,有a pretty popular example基于这些脚本,将共享代码组合成第三个脚本,然后提供两个修改变量的脚本。

    或者,这是一个我稍微清理过的单脚本版本。它返回该点是否可见,因为这些点也可以在有效的 XY 位置但在相机后面。

    /// c3d(xfrom, yfrom, zfrom, xto, yto, zto, xup, yup, zup, fov, aspect, px, py, pz)
    var     xfrom, yfrom, zfrom, xto, yto, zto, ux, uy, uz, fov, aspect, px, py, pz;
    xfrom = argument0; yfrom = argument1; zfrom = argument2;
    xto = argument3; yto = argument4; zto = argument5;
    ux = argument6; uy = argument7; uz = argument8;
    fov = argument9; aspect = argument10;
    px = argument11; py = argument12; pz = argument13;
    // delta:
    var dn, dx, dy, n;
    dx = xto - xfrom;
    dy = yto - yfrom;
    dz = zto - zfrom;
    n = sqrt(dx * dx + dy * dy + dz * dz);
    dx /= n; dy /= n; dz /= n; // (normalization)
    // up-vector:
    n = ux * dx + uy * dy + uz * dz;
    ux -= n * dx; uy -= n * dy; uz -= n * dz;
    // up-vector normalization:
    n = sqrt(ux * ux + uy * uy + uz * uz);
    ux /= n; uy /= n; uz /= n;
    // field-of-view:
    var tfov; tfov = tan(fov * pi / 360);
    ux *= tfov; uy *= tfov; uz *= tfov;
    // vxyz = uxyz * dxyz:
    var vx, vy, vz;
    vx = uy * dz - dy * uz;
    vy = uz * dx - dz * ux;
    vz = ux * dy - dx * uy;
    // aspect:
    afov = aspect;
    vx *= afov; vy *= afov; vz *= afov;
    // target coordinates:
    px -= xfrom; py -= yfrom; pz -= zfrom;
    // compute screen Z to ensure that the point is visible
    // (is in front rather than behind the camera):
    n = (px * dx + py * dy + pz * dz);
    if (n <= 0) {
        global.c3d_x = 0;
        global.c3d_y = -1;
        return false;
    }
    // compute and store screen XY (0..1):
    px /= n; py /= n; pz /= n;
    n = (px * vx + py * vy + pz * vz) / sqr(aspect * tan(pi / 8));
    global.c3d_x = (n + 1) / 2;
    n = (px * ux + py * uy + pz * uz) / sqr(tan(pi / 8));
    global.c3d_y = (1 - n) / 2;
    //
    return true;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多