从3D对象获取2D边界框

时间:2015-01-15 20:32:28

标签: three.js 2d bounding-box

我有一个充满〜百个长方形小行星形物体的场景。我想在每个标签下面放置一个文本标签,以便从任何摄像机角度都可以看到标签。我将文字广告牌,使其始终面向相机。

首先,使用.translateY将文本放在3d对象下方,一切看起来都很棒。但是,当您开始在场景中移动时,标签不再低于'对象取决于您的相机位置。使用trackballControls进行定位时尤其如此。

如何在下面放置文字'对象无论方向如何。也许如果我在每个帧上围绕每个对象创建一个2d边界框 - 我可以将文本标签放在第2个框的正下方。

我还担心每帧计算一百个3d对象上的2d边界框可能会变得昂贵。想法?

截图:

首先,文本标签会在对象下方正确翻译 enter image description here

但是当您旋转相机时,标签会侧向移动 enter image description here

一直翻转相机会显示标签倒置 enter image description here

我的目标是让对象位于对象下方,无论相机方向如何。

2 个答案:

答案 0 :(得分:0)

您是否尝试将文字标签添加到对象中?

object.add(Label)而不是scene.add(Label)

答案 1 :(得分:0)

我在这里有一个演示网站,可能会帮助您查看源代码:

https://dl.dropboxusercontent.com/u/31495717/cubemaker/index.html

当鼠标指针在3D对象上移动时,此站点将文本DOM元素放置在基于屏幕坐标的恒定距离上,该距离与使用CSS设置样式的3D对象保持一致。

来自消息来源:

var id_label = document.createElement('div');
id_label.id = INTERSECTED.name;
id_label.style.position = 'absolute';
id_label.style.top = '-10000px';
id_label.style.left = '-10000px';
id_label.innerHTML = '<span class="particle_label">' + INTERSECTED.name + '<br><span class="particle_sublabel">' + INTERSECTED.subname + '</span></span>';
container.appendChild(id_label);
var id_label_rect = id_label.getBoundingClientRect();
id_label.style.top = (screen_object_center.y - 0.85 * (id_label_rect.height / 2)) + 'px';
if (mouse.x < 0)
    id_label.style.left = (screen_object_center.x - horizontal_fudge * (screen_object_edge.x - screen_object_center.x)) + 'px';
else {
    id_label.style.left = (screen_object_center.x + horizontal_fudge * (screen_object_edge.x - screen_object_center.x) - id_label_rect.width) + 'px';
    id_label.style.textAlign = 'right';
}

DOM元素在屏幕外绘制,然后根据其边界框的属性以及与之关联的3D元素的世界坐标重新定位。当鼠标指针移动到3D元素边界之外时,文本标签将从DOM中删除。

由于您始终显示标签,因此您可以修改此标签以在初始化步骤中绘制元素一次,并只需更改渲染循环中的topleft样式属性。