2016-11-05 64 views
1

我有一个相当宽泛的问题,但不知道如何解决这个问题。所以原谅我。three.js - 如何将非视觉属性连接到对象?

我想有几个(如200个或更多)对象,我们只是说,一个容器在字段的一侧,绘制对象。现在我想要的是,每个对象都有一些非可视属性,当我单击该对象时,属性应该出现在该容器中。

现在我可以去了解它吗?

我的意思是,我知道我可以询问所选对象的名称,然后从某个字典中进行键值查询。问题是,是否有更简单的方法去解决它。

回答

1

是的,没关系。您可以将自己的自定义键直接放在Three.js对象上,只要不意外覆盖重要的内置Three.js键,它就不会打扰它。出于这个原因,我建议你把所有的自定义键放在对象上的“命名空间”中,这样​​它们就很好,整齐,容易。

举例来说,如果你有一个three.js所对象foo,你可以把你所有的钥匙foo.myCustomNamespace下,让喜欢foo.myCustomNamespace.namefoo.myCustomNamespace.description等自定义数据都在一起,不会干扰three.js所属性。

编辑:Three.js为用户数据提供了一个内置的名称空间,方便地称为userData。访问它在THREE.Object3D.userData

https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js#L92

+3

也许应该添加:three.js在每个Object3D实例中都有一个名为'userData'的对象用于此目的:https://github.com/mrdoob/three.js/blob/master/src/core/ Object3D.js#L92(该对象中的数据将被自动克隆和序列化) –

2

因为我使用了一种叫做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; 

genRandomIdgenRandomInt是为了说明本的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属性与点击立方体网格的属性。