Rotating Icosahedron With Circles Located At Every Vertex In Three.js
Solution 1:
The solution it multi-layered.
Your Icosahedron:
You were half-way there with rotating your icosahedron and its vertices. Rather than applying the rotation to all the vertices (which would actually cause some pretty extreme rotation), apply the rotation to the mesh only. But that doesn't update the vertices, right? Right. More on that in a moment.
Your Circles:
You have the right idea of placing them at each vertex, but as WestLangley said, you can't use lookAt
for objects with rotated/translated parents, so you'll need to add them directly to the scene. Also, if you can't get the new positions of the vertices for the rotated icosahedron, the circles will simply remain in place. So let's get those updated vertices.
Getting Updated Vertex Positions:
Like I said above, rotating the mesh updates its transformation matrix, not the vertices. But we can USE that updated transformation matrix to get the updated matrix positions for the circles. Object3D.localToWorld
allows us to transform a local THREE.Vector3
(like your icosahedron's vertices) into world coordinates. (Also note that I did a clone of each vertex, because localToWorld
overwrites the given THREE.Vector3
).
Takeaways:
I've tried to isolate the parts relative to your question into the JavaScript portion of the snippet below.
- Try not to update geometry unless you have to.
- Only use
lookAt
with objects in the world coordinate system - Use
localToWorld
andworldToLocal
to transform vectors between coordinate systems.
// You already had this partvar geometry = newTHREE.IcosahedronGeometry(10, 1);
var material = newTHREE.MeshBasicMaterial({
color: "blue",
wireframe: true
});
var isoMesh = newTHREE.Mesh(geometry, material);
scene.add(isoMesh);
// Add your circles directly to the scenevar nodes = [];
for(var i = 0, l = geometry.vertices.length; i < l; ++i){
nodes.push(newTHREE.Mesh(newTHREE.CircleGeometry(1, 32), material));
scene.add(nodes[nodes.length - 1]);
}
// This is called in render. Get the world positions of the vertices and apply them to the circles.var tempVector = newTHREE.Vector3();
functionupdateVertices(){
if(typeof isoMesh !== "undefined" && typeof nodes !== "undefined" && nodes.length === isoMesh.geometry.vertices.length){
isoMesh.rotation.x += 0.005;
isoMesh.rotation.y += 0.002;
for(var i = 0, l = nodes.length; i < l; ++i){
tempVector.copy(isoMesh.geometry.vertices[i]);
nodes[i].position.copy(isoMesh.localToWorld(tempVector));
nodes[i].lookAt(camera.position);
}
}
}
html *{
padding: 0;
margin: 0;
width: 100%;
overflow: hidden;
}
#host {
width: 100%;
height: 100%;
}
<scriptsrc="http://threejs.org/build/three.js"></script><scriptsrc="http://threejs.org/examples/js/controls/TrackballControls.js"></script><scriptsrc="http://threejs.org/examples/js/libs/stats.min.js"></script><divid="host"></div><script>// INITIALIZEvarWIDTH = window.innerWidth,
HEIGHT = window.innerHeight,
FOV = 35,
NEAR = 1,
FAR = 1000;
var renderer = newTHREE.WebGLRenderer({ antialias: true });
renderer.setSize(WIDTH, HEIGHT);
document.getElementById('host').appendChild(renderer.domElement);
var stats= newStats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0';
document.body.appendChild(stats.domElement);
var camera = newTHREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
camera.position.z = 50;
var trackballControl = newTHREE.TrackballControls(camera, renderer.domElement);
trackballControl.rotateSpeed = 5.0; // need to speed it up a littlevar scene = newTHREE.Scene();
var light = newTHREE.PointLight(0xffffff, 1, Infinity);
camera.add(light);
scene.add(light);
functionrender(){
if(typeof updateVertices !== "undefined"){
updateVertices();
}
renderer.render(scene, camera);
stats.update();
}
functionanimate(){
requestAnimationFrame(animate);
trackballControl.update();
render();
}
animate();
</script>
Post a Comment for "Rotating Icosahedron With Circles Located At Every Vertex In Three.js"