Хит-тестирование псевдо-3d пространства - PullRequest
0 голосов
/ 12 октября 2010

Поэтому я пишу небольшой мини-псевдо-3d движок для элемента canvas в html5.В приведенном ниже коде я рисую группу квадратов с различными положениями и поворотами (вращение вокруг оси 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();
    }
}

PS Если я делаю что-то странное или задом наперед, и вы знаете способулучшить, я хотел бы услышать предложения

1 Ответ

0 голосов
/ 12 октября 2010

Я бы посоветовал вам нарисовать объекты с такими же преобразованиями на скрытом холсте того же размера, но дать каждому квадрату уникальный цвет (возможно, полученный из индекса 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];

Это будет работать до 16 миллионов объектов и довольно просто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...