three.js Line disappears on updating the vertices of its geometry - javascript

I am learning three.js library in JS. I used the Line objects to create my own coordinate axes. I am trying to move them. The problem is when I update the vertices, two of the lines work fine, but the third line disappears completely. I tried printing its vertices on console but they are within visibility range. So, what is the reason I am facing this problem? My code:
// create and axes to the scene
//// X axis
var material = new THREE.LineBasicMaterial({
color: 0x00ff00
})
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(1500,0,0), new THREE.Vector3(-1500,0,0));
Xaxis = new THREE.Line(geometry,material);
scene.add(Xaxis);
//// Y axis
var material = new THREE.LineBasicMaterial({
color: 0xff0000
})
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0,1500,0), new THREE.Vector3(0,-1500,0));
Yaxis = new THREE.Line(geometry,material);
scene.add(Yaxis);
//// Z axis
var material = new THREE.LineBasicMaterial({
color: 0x0000ff
})
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0,0,1500), new THREE.Vector3(0,0,-1500));
Zaxis = new THREE.Line(geometry,material);
scene.add(Zaxis);
function changePosition(newVal)
{
if(!transformCo_ordinate) {
sphere.position.set((vx/100)*newVal,(vy/100)*newVal,(vz/100)*newVal);
}
else{
Xaxis.geometry.vertices[0].set(1500,-(vy/100)*newVal,-(vz/100)*newVal);
Xaxis.geometry.vertices[1].set(-1500,-(vy/100)*newVal,-(vz/100)*newVal);
Yaxis.geometry.vertices[0].set(-(vx/100)*newVal,1500,-(vz/100)*newVal);
Yaxis.geometry.vertices[1].set(-(vx/100)*newVal,-1500,-(vz/100)*newVal);
Zaxis.geometry.vertices[0].set(-(vx/100)*newVal,-(vy/100)*newVal,1500);
Zaxis.geometry.vertices[0].set(-(vx/100)*newVal,-(vy/100)*newVal,-1500);
Xaxis.geometry.verticesNeedUpdate = true;
Yaxis.geometry.verticesNeedUpdate = true;
Zaxis.geometry.verticesNeedUpdate = true;
console.log(Xaxis.geometry.vertices[1]);
}
}
THe function changePosition is being called by a slider which passes its current value as newVal within range 0-100. vx = 100, vy = 100, vz = -300
Xaxis is the line that disappears. transformCo_ordinate is a boolean controlled by a checkbox. I am new to three.js so please understand if I am doing some stupid mistake.

Zaxis.geometry.vertices[0].set(-(vx/100)*newVal,-(vy/100)*newVal,1500);
Zaxis.geometry.vertices[0].set(-(vx/100)*newVal,-(vy/100)*newVal,-1500);
It seems you are updating the same vertex of the z axis twice. I've ported a simplified version of your code into the following fiddle. After fixing this minor bug, everything seems to work fine.
https://jsfiddle.net/gcL7dwbp/
The axis are automatically updated two seconds after application start.
three.js R104

Related

How to animate the growth of a line in Three.js?

What I have:
var pointA = new THREE.Vector3(camera_RC_Holder.position.x, camera_RC_Holder.position.y, camera_RC_Holder.position.z);
var direction = camera_RC.position.clone();
direction.applyMatrix4( camera_RC.matrixWorld );
direction.normalize();
var distance = 700;
var pointB = new THREE.Vector3();
pointB.addVectors ( pointA, direction.multiplyScalar( -distance ) );
var geometry = new THREE.Geometry();
geometry.vertices.push( pointA );
geometry.vertices.push( pointB );
var material = new THREE.LineBasicMaterial( { color : 0xff0000 } );
var line = new THREE.Line( geometry, material );
scene_Main.add( line );
What I want:
What I'm trying to do is to show that a ray has began from the camera and explores through the view volume. So, instead of instantly create a line (point_A, point_B) I want to grow the line from point_A pixel by pixel until it meets it's destination (point_B).
Question:
How to draw the lines pixel by pixel as shown in the code snippet below??
var w = 200;
var h = 150;
var x;
function setup(){
createCanvas(w,h);
x=0;
y=0;
}
function draw(){
if(x>w){
x = 0;
}
background(250);
line(0,50,x,50); //x1,y1,x2,y2
x++;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.js"></script>
Title question and explanation does not fit to me very well, maybe I did not understand your question perfectly. I will try to answer just the title question and edit this answer as soon as some clarifications are done from your side.
( Also I would always try to avoid multi-questions as much as possible. )
About the title question:
Adding something to the scene is basically drawing it... or do you mean something else?
Bind this code snippet to your click mouse event. This will create your raycast, in order to see it you need to add it to your scene. Afterwards you can move your camera and check how it looks like:
var material = new THREE.LineBasicMaterial({
color: 0x0000ff
});
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(raycaster.ray.origin.x, raycaster.ray.origin.y, raycaster.ray.origin.z));
geometry.vertices.push(new THREE.Vector3(raycaster.ray.origin.x + (raycaster.ray.direction.x * 100000), raycaster.ray.origin.y + (raycaster.ray.direction.y * 100000), raycaster.ray.origin.z + (raycaster.ray.direction.z * 100000)));
var line = new THREE.Line(geometry, material);

Threejs draw a path with textures

I want to draw a path in my 3D world, but the class of line is not useful. Who can help me?!
Like this image
Now I fixed my question
I want draw a path ,and fill it with texture
var SUBDIVISIONS = 20;
geometry = new THREE.Geometry();
var curve = new THREE.QuadraticBezierCurve3();
curve.v0 = new THREE.Vector3(0, 0, 110);
curve.v1 = new THREE.Vector3(0, 200, 110);
curve.v2 = new THREE.Vector3(200, 200, 110);
for (j = 0; j < SUBDIVISIONS; j++) {
geometry.vertices.push( curve.getPoint(j / SUBDIVISIONS) )
}
material = new THREE.LineBasicMaterial( { color: 0xff0000, linewidth: 5 } );
line = new THREE.Line(geometry, material);
scene.add(line);
this way has two problem 1:linewidth is not support on Windows ,2: LineBasicMaterial not support texture
So i search on google find class Three.MeshLine. linewidth is Ok,but texture mapping not fine. texture code there:var loader = new THREE.TextureLoader();
loader.load( 'assets/images.png', function( texture ) {
strokeTexture = texture;
strokeTexture.wrapS = strokeTexture.wrapT = THREE.RepeatWrapping;
strokeTexture.repeat.set( 5, 1);
strokeTexture.needsUpdate = true;
init()
} );
Regardless of the setting the texture and MeshLineMaterial ,The result is not what I want result image:result image
have a look at https://github.com/spite/THREE.MeshLine - it's an implementation of mesh-based lines. Also note the references on that site, could give you some insights.
Otherwise you might want to look into creating a shape from the line. This could be done using the THREE.ShapeGeometry-class.

Label on AxisHelper withTextGeometry and rotation issue

I have a main scene with a sphere and another subwindow (in right bottom) where I have drawn the (x,y,z) axis of main scene.
In this subwindow, I would like to draw the labels "X" "Y" and "Z" on each axis (more precisely located on the end of each AxisHelper). I know how to use TextGeometry but the issue is that I can't get to make rotate these labels in order to make them appear always in face on the user.
You can see the problem on the [following link][1] : label "X" is fixed relatively to axis and is rotating with camera, so it is not always in face of user.
From these two links link1 and link2, I tried to add (in my example, I tried with only "X" label) :
function addLabelAxes() {
// Axes label
var loader = new THREE.FontLoader();
loader.load( 'js/helvetiker_regular.typeface.js', function ( font ) {
var textGeo1 = new THREE.TextGeometry( 'X', {
font: font,
size: 5,
height: 0.1,
bevelThickness: 0.1,
bevelSize: 0.1,
bevelEnabled: true,
} );
var color = new THREE.Color();
color.setRGB(255, 255, 255);
textMaterial = new THREE.MeshBasicMaterial({ color: color });
var meshText1 = new THREE.Mesh(textGeo1, textMaterial);
// Position of axes extremities
var positionEndAxes = axes2.geometry.attributes.position;
var label1X = positionEndAxes.getX(0);
meshText1.position.x = label1X + axisLength;
meshText1.position.y = 0;
meshText1.position.z = 0;
// Rotation of "X" label
//meshText1.rotation = zoomCamera.rotation;
meshText1.lookAt(zoomCamera.position);
// Add meshText to zoomScene
zoomScene.add(meshText1);
});
}
zoomCamera represents a PerspectiveCamera which is the camera of subwindow (i.e zoomScene) ;I add TextGeometry to zoomScene by doing :
zoomScene.add(meshText1);
What might be wrong in my code ? I wonder if I can make rotate the "X" label on itself, i.e the "X" label is rotating like axis but a self (local) orientation is applied as a function of rotation theta angle, so the label is always kept in face of user during camera rotation ?
You are probably looking for THREE.SPRITE. From the docs:
Object3D -> Sprite: A sprite is a plane in an 3d scene which faces always towards the camera.
Here's a simple example of how to use it:
var map = new THREE.TextureLoader().load( "sprite.png" );
var material = new THREE.SpriteMaterial( { map: map, color: 0xffffff, fog: true } );
var sprite = new THREE.Sprite( material );
scene.add( sprite );
Here's a working example of a similar scenario (3 scaled sprites with different positioning). You can find the code on github.

How to plot 3D Graph in XYZ axis jquery

I am trying to plot a graph in my application. I am trying to plot a graph having 4 points which needs to be joined by lines. I tried with so many libralies such as canvasXpress.. But could not able to find the solution.
I had tried this much.
http://jsfiddle.net/rohitghatol/tn9sm/
var render = function(){
renderer.render(scene,camera);
}
render();
$("#container").append(renderer.domElement);
Now I have to draw 4 points with joining lines.
I am not getting how to scale and plot the lines in the graph.
I have found the solution using Three.Js javascript library. Here's the snippet.
I had used the following code to create the grid helpers and it worked.
var gridXZ = new THREE.GridHelper(100, 10);
gridXZ.setColors(new THREE.Color(0x939393), new THREE.Color(0xbdbdbd));
gridXZ.position.set(100, -.1, 100);
scene.add(gridXZ);
var gridXY = new THREE.GridHelper(100, 10);
gridXY.position.set(100, 100, 0);
gridXY.rotation.x = Math.PI / 2;
gridXY.setColors(new THREE.Color(0x0066FF), new THREE.Color(0xCCE0F9));
scene.add(gridXY);
var gridYZ = new THREE.GridHelper(100, 10);
gridYZ.position.set(0, 100, 100);
gridYZ.rotation.z = Math.PI / 2;
gridYZ.setColors(new THREE.Color(0xCC9900), new THREE.Color(0xF5EBCC));
scene.add(gridYZ);
And for drawing the lines I had drawn the lines using three D points
// Line one
material = new THREE.LineBasicMaterial({
color: 0x000000
});
geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3(x1, y1, z1),
new THREE.Vector3(x2, y2, z2)
);
line = new THREE.Line(geometry, material);
scene.add(line);

Threejs - Raycaster with direction parallel but offset by 3 from line reports true for intersectObject

I'm trying to use a THREE.Raycaster to determine if a line will intersect with my ray, but when comparing with parallel line the intersectObject method is returning true. Am I doing something wrong?
var rc = new THREE.Raycaster(new THREE.Vector3(500,0,0), new THREE.Vector3(1,0,0), 0, 100);
var material = new THREE.LineBasicMaterial();
var spline = new THREE.SplineCurve3([
new THREE.Vector3(0,0,3),
new THREE.Vector3(1000,0,3)
]);
var geometry = new THREE.Geometry();
geometry.vertices = spline.getPoints(1);
var line = new THREE.Line(geometry, material);
if (rc.intersectObject(line)) {
var found = document.createElement('div');
found.innerHTML = 'detected intersection, but why?';
document.querySelector('body').appendChild(found);
}
the above code displays:
detected intersection, but why?
link to fiddle
Yes, a ray and a line segement parallel to that ray should not intersect. :-)
This bug has now been fixed in the three.js development branch r.70dev.
three.js r.70dev

Categories

Resources