命中测试伪3d空间

时间:2010-10-11 23:00:51

标签: html5 3d canvas

所以我正在为html5中的canvas元素编写一个小的迷你伪3d引擎。在下面的代码中,我绘制了一堆具有不同位置和旋转的正方形(围绕z轴旋转,因此没有变形)

现在我希望能够告诉用户点击哪个方格。在对象数组中,项目由z位置支持,从距离摄像机最远的方块开始(以便它们正确绘制)。因此,如果相对于画布角的左上角有一个3d点,我怎么知道哪个方块被点击了?

//Draw objects
for (var i = 0; i < objects.length; i++) {
    var object = objects[i];
    var cz = object.position.z - camera.position.z;

    if (cz > 0) {
        cz = 1 / ((cz - 1) * 0.75 + 1);

        context.save();

        context.translate(halfWidth, halfHeight); //viewport transform
        context.scale(1, -1); //invert y axis
        context.scale(cz, cz); //perspective
        context.translate(-camera.position.x, -camera.position.y); //camera transform
        context.translate(object.position.x, object.position.y); //world transform
        context.rotate(object.rotation);

        context.fillStyle = object.color;
        context.fillRect(-40, -40, 80, 80);

        context.restore();
    }
}

P.S。如果我做任何奇怪或倒退的事情并且你知道改进的方法,我很乐意听取建议

1 个答案:

答案 0 :(得分:0)

我建议您将具有相同转换的对象绘制到相同大小的隐藏画布,但为每个方块赋予唯一的颜色(可能来自索引i)。

你会这样做:

var col = index.toString(16);                 // convert to hex
while (col.length < 6) col = "0"+col;     // pad leading 0s
ctx.fillStyle = "#"+col;
ctx.fillRect(-40,-40,80,80);

然后,当您在可见画布上获得鼠标点击事件时,请在隐藏的画布中查看该位置以获取所选对象的颜色(索引):

var colData = ctx.getImageData(clickX, clickY, 1, 1).data;
var index = (colData[2]<<16) | (colData[1]<<8) | colData[0];

这适用于多达16M的对象,非常简单。