Drawing a line between moving objects - javascript

I'm trying to draw a line between two moving vertices. The vertex's drawing is stored in a variable called object, which has a position, which is a THREE.Vector3.
The line is created thusly:
var Line = function(scene, source, target){
var geometry = new THREE.Geometry();
geometry.dynamic = true;
geometry.vertices.push(source.object.position);
geometry.vertices.push(target.object.position);
geometry.verticesNeedUpdate = true;
var material = new THREE.LineBasicMaterial({ color: 0x000000 });
var line = new THREE.Line( geometry, material );
scene.add(line);
return line;
};
..., where source and target are vertices and the vertices get updated via:
vertex.object.position.add(vertex.velocity);
Now, I assigned the source.object.position and target.object.position to the line.geometry.vertices[0] and line.geometry.vertices[1] because I wanted one to update with the other. But instead, the vertex positions vary wildly from the line positions. The vertices are where they are, but the lines don't connect to the vertices.
How can I make the lines move with the vertices?

In your animation loop you have to set line.geometry.verticesNeedUpdate = true. Because every time after rendering it becomes false. jsfiddle example

Related

Rotate a line around a circle in three.js

var lineGeometry = new THREE.Geometry();
var lineMaterial = new THREE.LineBasicMaterial({
color: 0x000000
});
lineGeometry.vertices.push(
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(0, 10, 0),
);
var line = new THREE.Line(lineGeometry, lineMaterial);
scene.add(line);
I want to update this line's endpoint in a circular fashion. In other languages it is straightforward, I would increase some variable and update the endpoint like radius * cos(dt) and radius * sin(dt). In three.js I tried the following, but it doesn't work:
var dt = 0;
function render(){
dt += 0.01;
line.geometry.vertices[1].x = 10*Math.cos(dt);
line.geometry.vertices[1].z = 10*Math.sin(dt);
renderer.render(scene, camera);
requestAnimationFrame(render);
}
edit: I don't want to use line.rotation.z += 0.01 method.
line.geometry.verticesNeedUpdate = true;
Add the above line before calling render. This will signal three.js that the vertex buffer has changed, so it will update it appropriately.
Since you mentioned using line.rotation, I must mention that updating the vertices is inefficient compared to rotating the line shape. When you rotate a line shape, you are simply updating the shape's transformation matrix. But when you update vertices, three.js needs to re-upload the entire set of vertices to the GPU. This may seem trivial for a single line segment, but it's a bad habit to get into if you ever intend to use larger shapes later.

how I can erase from memory the scene and meshes? Three.js

I am adding "n" number of circles on the scene.
var radius = 1;
var segments = 32;
var circleGeometry = new THREE.CircleGeometry( radius, segments);
function generateCircles(){
//scene.remove(circle);
var count=0;
while (1000> count) {
circle = new THREE.Mesh (circleGeometry, material);
scene.add (circle);
count ++;
}
}
It is effective to do it this way ?.
in my code I call this function. and every time you call it, it all goes back slower, I guess it's because there are more objects in the scene. what can I do?
Each time the function is called I need erased completely from the memory stage and the circles that were generated.
with "slower", I mean that I want my application to run faster. every time I run the function add more and more circles. so I want to be removed earlier. to add new ones. if there are many circles in the scene it slows execution.
http://jsfiddle.net/v8oxsxtc/
You can remove the old circles from the scene by calling the scene.remove method on each of the circles you previously added. Here is a simple example using your code:
var lastCircles = null;
function generateCircles(){
var count=0;
if(lastCircles) { // remove old circles if they exist
lastCircles.forEach(function(c) {
scene.remove(c);
});
}
lastCircles = []; // clear cache
while (1000 > count) {
circle = new THREE.Mesh (circleGeometry, material);
lastCircles.push(circle); // add each circle to cache
scene.add (circle);
circle.position.set(count,count,count)
count ++;
}
}

Three.js save modified mesh vertices r67

I have created a plane and when I click on a vertex, the vertex will move and render as expected . My problem is saving the mesh to a text file.The vertices don't seem to update on the file as expected.
If I move a vertex before the second render the vertex position will reflect on the external text file.
My question is once I have moved around a bunch of vertices x,y,z positions how do I save the result that appears on my screen as it seems to only save the original mesh .
var guiControls = new function () {
var t = ['Test Save File'];
this.save_mesh = function () {
for (var i = 0, j = ground.geometry.vertices.length; i < j; i++) {
t.push('['+ ground.geometry.vertices[i].x+','+ ground.geometry.vertices[i].y+ ','+ objects[0].geometry.vertices[i].z+ '#:'+']');
}
function passMesh(){
var data = {
value: t
};
$.post("./php/savefile.php", data);
}
passMesh();
};
I have tried to use the updates available:
geo.dynamic = true;
geo.computeVertexNormals();
geo.computeFaceNormals();
geo.verticesNeedUpdate = true;
geo.normalsNeedUpdate = true;
Any help is appreciated.
In 3D graphics all changes are only matrix transformations of the original mesh, which do not actually change this mesh. So my guess is that you need to apply the transformations to you objects prior to the export. try: .applyMatrix

Three.js connect two object as one

I made this function that for each vertices of geometry create a sphere and place it in the same position of vertice.For example if I have a cube,the function place a sphere for each cube vertice.
function makeSphereVertices(){
console.log("makesphere");
spheres = [];
for(var j=0 ; j<geometryContainer.length ; j++) {
for (var i=0 ; i<geometryContainer[j].geometry.vertices.length ; i++){
var sphereGeometry = new THREE.SphereGeometry(0.04,10,10);//relative to dimension object : ToDo
var sphereMaterial = new THREE.MeshBasicMaterial({transparent: false,color: 0x000000 /*opacity: 0.01*/});
spheres = new THREE.Mesh(sphereGeometry,sphereMaterial);
spheres.position.set(geometryContainer[j].geometry.vertices[i].x,
geometryContainer[j].geometry.vertices[i].y,
geometryContainer[j].geometry.vertices[i].z);
console.log(geometryContainer[j].id);
spheres.name = "sphere";
scene.add(spheres);
verticesSphere.push(spheres);
}
}
}
After this,I have created function to move my cube like this Draggable shape. Now the problem is: I can't find a way to move together cube and all spheres. For example if I drag cube all the spheres remains in the old position. Is there a way to chain the spheres to my cube?Thank you.
By placing them all in a new object.
group = new THREE.Object3D();//create an empty container
group.add( mesh );//add a mesh with geometry to it
scene.add( group );//when done, add the group to the scene
three.js - mesh group example? (THREE.Object3D() advanced)
So make sure you place the cube and all the spheres in your newly created group object.

In three.js renderDepth of the mesh seems to be ignored

I'd like to render a mesh on top of everything else, this solution works fine:
Three.js - Geometry on top of another
I was wondering if the same could be achievable with mesh.renderDepth, but I couldn't make it work so far. Seems like renderDepth only has an effect if material.depthTest or depthWrite is set to false, but then depth ordering is of course wrong within the same object:
http://jsfiddle.net/SF9tX/22/
var cube = new THREE.Mesh(geometry, material);
cube.renderDepth = 1;
scene.add(cube);
var cube2 = new THREE.Mesh(geometry, material);
cube2.position.x = 1;
cube2.renderDepth = 2;
scene.add(cube2);
// with any one of these lines the renderDepth has an effect
// but then of course the depth test/write is wrong within the same object
// material.depthWrite = false;
// material.depthTest = false;
For r70 is renderDept function removed.
https://github.com/mrdoob/three.js/issues/5496

Categories