Как преобразовать 3D-координаты в 2D (X, Y) для позиционирования текста div чуть ниже трехмерного игрового объекта - PullRequest
0 голосов
/ 05 ноября 2019

Мне нужно расположить на экране чуть ниже 3d-плеера DIVSet в правильной позиции X, Y, но я не уверен, как преобразовать x, y, z в координаты x, y.

 this.player = player => {
    const pos = interpolate(player.position, player.movementVector)

    resetDivSets()

    calcViewMatrix()
    mat4Translate(viewMatrix, -pos.x * glScale, -3.1 * glScale, pos.y * glScale)
    mat4RotateY(viewMatrix, playerRotation(player, player.drawMovementVector))
    gl.uniformMatrix4fv(uVmatrix, false, viewMatrix)
    gl.uniform3f(uAmbientColor, 1, 1, 1)
    gl.drawElements(gl.TRIANGLES, builtSprites.player.ibCount, gl.UNSIGNED_SHORT, builtSprites.player.ibStart * 2)


// compute a clipspace position

        var clipspace =  WHAT TO HAVE HERE??;

        // divide X and Y by W just like the GPU does.
        clipspace[0] /= clipspace[3];
        clipspace[1] /= clipspace[3];

        // convert from clipspace to pixels
        var pixelX = (clipspace[0] *  0.5 + 0.5) * gl.canvas.width;
        var pixelY = (clipspace[1] * -0.5 + 0.5) * gl.canvas.height;

    addDivSet("Player Name under player object", pixelX , pixelY);

1 Ответ

1 голос
/ 05 ноября 2019

В этой статье это рассматривается

В основном

    // compute a clipspace position
    var modelRelativePosition = [0, 0, 0, 1];  // NOTE!! w = 1
    var clipspace = m4.transformVector(uVmatrix, modelRelativePosition);

    // divide X and Y by W just like the GPU does.
    clipspace[0] /= clipspace[3];
    clipspace[1] /= clipspace[3];

    // convert from clipspace to pixels
    var pixelX = (clipspace[0] *  0.5 + 0.5) * gl.canvas.width;
    var pixelY = (clipspace[1] * -0.5 + 0.5) * gl.canvas.height;

    // position the div
    div.style.left = Math.floor(pixelX) + "px";
    div.style.top  = Math.floor(pixelY) + "px";

, где transformVector - что-то вроде

  function transformVector(m, v, dst) {
    dst = new Float32Array(4);
    for (var i = 0; i < 4; ++i) {
      dst[i] = 0.0;
      for (var j = 0; j < 4; ++j) {
        dst[i] += v[j] * m[j * 4 + i];
      }
    }
    return dst;
  }

И если вы хотите сместить в2d просто добавь это внизу

    div.style.left = Math.floor(pixelX + offsetX) + "px";
    div.style.top  = Math.floor(pixelY + offsetY) + "px";

const gl = document.createElement('canvas').getContext('webgl');
// use the identity matrix as a test
var uVmatrix = [
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  0, 0, 0, 1,
];

// compute a clipspace position
var modelRelativePosition = [0, 0, 0, 1];  // NOTE! w = 1
var clipspace = transformVector(uVmatrix, modelRelativePosition);

// divide X and Y by W just like the GPU does.
clipspace[0] /= clipspace[3];
clipspace[1] /= clipspace[3];

// convert from clipspace to pixels
var pixelX = (clipspace[0] * 0.5 + 0.5) * gl.canvas.width;
var pixelY = (clipspace[1] * -0.5 + 0.5) * gl.canvas.height;

// position the div
//div.style.left = Math.floor(pixelX) + "px";
//div.style.top = Math.floor(pixelY) + "px";
console.log(Math.floor(pixelX) + "px", Math.floor(pixelY) + "px");

function transformVector(m, v, dst) {
  dst = new Float32Array(4);
  for (var i = 0; i < 4; ++i) {
    dst[i] = 0.0;
    for (var j = 0; j < 4; ++j) {
      dst[i] += v[j] * m[j * 4 + i];
    }
  }
  return dst;
}
...