我有一个相当宽泛的问题,但不知道如何解决这个问题。所以原谅我。three.js - 如何将非视觉属性连接到对象?
我想有几个(如200个或更多)对象,我们只是说,一个容器在字段的一侧,绘制对象。现在我想要的是,每个对象都有一些非可视属性,当我单击该对象时,属性应该出现在该容器中。
现在我可以去了解它吗?
我的意思是,我知道我可以询问所选对象的名称,然后从某个字典中进行键值查询。问题是,是否有更简单的方法去解决它。
我有一个相当宽泛的问题,但不知道如何解决这个问题。所以原谅我。three.js - 如何将非视觉属性连接到对象?
我想有几个(如200个或更多)对象,我们只是说,一个容器在字段的一侧,绘制对象。现在我想要的是,每个对象都有一些非可视属性,当我单击该对象时,属性应该出现在该容器中。
现在我可以去了解它吗?
我的意思是,我知道我可以询问所选对象的名称,然后从某个字典中进行键值查询。问题是,是否有更简单的方法去解决它。
是的,没关系。您可以将自己的自定义键直接放在Three.js对象上,只要不意外覆盖重要的内置Three.js键,它就不会打扰它。出于这个原因,我建议你把所有的自定义键放在对象上的“命名空间”中,这样它们就很好,整齐,容易。
举例来说,如果你有一个three.js所对象foo
,你可以把你所有的钥匙foo.myCustomNamespace
下,让喜欢foo.myCustomNamespace.name
,foo.myCustomNamespace.description
等自定义数据都在一起,不会干扰three.js所属性。
编辑:Three.js为用户数据提供了一个内置的名称空间,方便地称为userData
。访问它在THREE.Object3D.userData
。
https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js#L92
因为我使用了一种叫做threex.domevents库的单击事件,检查GitHub的页面了解更多信息,它的代码是自我解释的事件。
首先domevents需要在场景中像这样被初始化:
var domEvents = new THREEx.DomEvents(camera, renderer.domElement);
然后创建一个自定义的网格对象:
// random id
function genRandomId()
{
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for(var i=0; i < 5; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
// random int for position
var min = -50;
var max = 50;
function genRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
// custom mesh --------------------------------------------
function MyMesh(geometry, material, destinationContainer) {
THREE.Mesh.call(this, geometry, material);
this.userData = {
foo1: genRandomId(),
foo2: genRandomId(),
foo3: genRandomId(),
};
this.position.x = genRandomInt(min, max);
this.position.y = genRandomInt(min, max);
this.position.z = genRandomInt(min, max);
var that = this;
// click event listener
domEvents.addEventListener(this, 'click', function(event) {
console.log('clicked object on position:');
console.log(that.position);
destinationContainer.userData = that.userData;
console.log('Now the conainer has:');
console.log(destinationContainer.userData);
destinationContainer.userData = that.userData;
}, false);
}
MyMesh.prototype = Object.create(THREE.Mesh.prototype);
MyMesh.prototype.constructor = MyMesh;
genRandomId
和genRandomInt
是为了说明本的pourpose随机生成例如,我从Generate random string/characters in JavaScript获取随机ID的代码。
在场景中可以生成200(或更多)MyMesh
网格,并将它们添加到场景:
const color = 0x156289;
const emissive = 0x072534;
var planeGeometry = new THREE.PlaneGeometry(5, 5);
var planeMaterial = new THREE.MeshPhongMaterial({
color: color,
emissive: emissive,
side: THREE.DoubleSide,
shading: THREE.FlatShading
});
var planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
scene.add(planeMesh);
var objGeometry = new THREE.BoxGeometry(1, 1, 1);
var objMaterial = new THREE.MeshPhongMaterial({
color: color,
emissive: emissive,
shading: THREE.FlatShading
});
var i = 0;
while (i < 200) {
scene.add(new MyMesh(objGeometry, objMaterial, planeMesh));
i++;
}
最后渲染场景:
var render = function() {
requestAnimationFrame(render);
planeMesh.rotation.x += 0.010;
planeMesh.rotation.y += 0.010;
renderer.render(scene, camera);
};
render();
这与演示完整源代码:http://run.plnkr.co/plunks/W4x8XsXVroOaLUCSeXgO/
打开浏览器控制台并单击一个多维数据集,您将看到planeMesh
正在切换其userData
属性与点击立方体网格的属性。
也许应该添加:three.js在每个Object3D实例中都有一个名为'userData'的对象用于此目的:https://github.com/mrdoob/three.js/blob/master/src/core/ Object3D.js#L92(该对象中的数据将被自动克隆和序列化) –