Current vertice position in Three.js - javascript

I am creating a Cube with standard new THREE.CubeGeometry. I am also changing the position of the mesh (x,y,z) and I add it to the scene. Later when user clicks on the option, I would like to draw a cube in all 6 corners of the cube. How can I get the position of each vertice in the coordinate system?

You can do simply :
var geometry = new THREE.CubeGeometry(...);
var verices = geometry.vertices;

if u looking for 8 vertices/corners... http://jsfiddle.net/ebeit303/54uQ9/
function addShapes() {
width = 100;
height = 100
depth = 100;
var geometry = new THREE.CubeGeometry( width, height, depth );
var material = new THREE.MeshBasicMaterial({color:0xffccff, side:2, overdraw:true} );
mesh = new THREE.Mesh( geometry, material );
group.add( mesh );
mesh.position.set(10,20,20);
var x = mesh.position.x;
var y = mesh.position.y;
var z = mesh.position.z;
console.log(geometry.vertices);
var len = geometry.vertices.length;
for(var i = 0; i < len; i++){
var vx = geometry.vertices[i].x;
var vy = geometry.vertices[i].y;
var vz = geometry.vertices[i].z;
var material1 = new THREE.MeshBasicMaterial({color:Math.random()*0xffffff, side:2, overdraw:true, opacity:0.6, transparent:true} );
var mesh1 = new THREE.Mesh( geometry, material1 );
group.add(mesh1);
mesh1.position.set( (vx*2)+x,(vy*2)+y,(vz*2)+z);
}
}
here the cube consist of 8 vertices/corners, now new cubes were drawn and position on each vertices of the middle cube, its a simple logic... cubegeometry - geometry.vertices and mesh position is used for simple calculation.... just go through the jsfiddle link... it might give you some fair idea...

Related

Creating THREE.Points return Cannot convert undefined or null to object

This is a part of the code. I tested the geometry and material variables on both return values. Removing these variables, the error disappear.
var actionZ = 0;
var rotationA = 1.1;
var movementSpeed = 1;
var totalObjects = 40000;
var rotated = false;
var container = document.createElement('div');
container.className = 'home-background';
document.body.appendChild( container );
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight,1, 2000)
camera.position.z = 2000;
var scene = new THREE.Scene();
scene.add(camera);
scene.fog = new THREE.FogExp2( 0x00b4f1, 0.0003 );
var geometry = new THREE.Geometry();
var i = 0;
for (i = 0; i < totalObjects; i ++) {
var vertex = new THREE.Vector3();
vertex.x = Math.random()*40000-20000;
vertex.y = Math.random()*7000-3500;
vertex.z = Math.random()*7000-3500;
geometry.vertices.push( vertex );
}
var material = new THREE.PointsMaterial( { size: 3, color: 0x00b4f1});
var particles = new THREE.Points( geometry, material );
There is currently a bug in R106 when creating THREE.Points with THREE.Geometry. You can avoid the issue by using THREE.BufferGeometry or by using the latest dev version. R107 will be released at the end of July. Here is the related PR that fixed the issue:
https://github.com/mrdoob/three.js/pull/16932

Three.js render not showing a simple cube when I want to show simple mesh

I want to show a simple plane and a simple cube but the plane hides the cube, the cube is located between the camera and the plane, but the plane "hides" the cube.
This is my scene without plane:
and here it is with the plane added:
I am pretty sure they are in a location where the cube should to be showed.
Here is my code:
var scene = new THREE.Scene(),
camera = new THREE.PerspectiveCamera(45,Window.innerWidth,window.innerHeight,0.1,1000),
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
var axes = new THREE.AxisHelper(20);
scene.add(axes);
var cubeGeometry = new THREE.CubeGeometry(4,4,4);
var cubeMaterial = new THREE.MeshBasicMaterial({color:0x777777});
var cube = new THREE.Mesh(cubeGeometry,cubeMaterial);
//cube.castShadow = true;
cube.position.x = 0;
cube.position.y = 10;
cube.position.z = 5;
scene.add(cube);
var planeGeometry = new THREE.PlaneGeometry(60,20);
var planeMaterial = new THREE.MeshBasicMaterial({color: 0x55cc88});
var plane = new THREE.Mesh(planeGeometry,planeMaterial);
plane.rotation.x = -0.5*Math.PI;
plane.position.x = 15;
plane.position.y = 0;
plane.position.z = 0;
//scene.add(plane);
//plane.receiveShadow = true;
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position);
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40,60,-10);
scene.add(spotLight);
//renderer.setClearColor(0xEEEEEE,1);
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.render(scene,camera);
$("#WebGl-salida").append(renderer.domElement);
Pay attention to names of objects and order and correctness of parameters in methods:
camera = new THREE.PerspectiveCamera(45,Window.innerWidth,window.innerHeight,0.1,1000)
should be like:
camera = new THREE.PerspectiveCamera(45,window.innerWidth / window.innerHeight,0.1,1000)
jsfiddle example
Many thanks! Both for the answer and for the suggestion to edit the question to make it more understandable (my English has to improve) Now it is working perfectly.

Getting the coordinates on the scene (three js)

I'm really struggling with this and have gone through several discussions that are not really related to my problem. If anybody can help, I would greatly appreciate.
I'm writing a html document using the three.js library. There is a scene called scaledScene as below (scaledMap and scaledScene are already defined):
scaledMap = new THREE.Mesh(
new THREE.PlaneGeometry( 1600, 1200 ),
new THREE.MeshBasicMaterial( {
map: new THREE.ImageUtils.loadTexture( 'texture/test1.png' ),
//wireframe: true,
side: THREE.DoubleSide
} )
);
scaledScene.add( scaledMap );
The scene is created by a high solution picture that's zoomed in to the highest level. Zooming is not allowed but only panning.
controls.noZoom = true;
controls.noPan = false;
I would like to get the absolute coordinates on the scene when panning. For example, if I pan to the top left corner, I'd like to get the information that the cursor or the view is located at top left corner. Is this possible? If so, how do I do it?
You want a picking ray.
A ray can be sent from the center of the viewport to the map in 3d space. this will tell you the pixel of the map that's currently at the center of the viewport.
I have created a fiddle.
The code is as follows. It disables rotation of the camera so that only panning is available. The pixel of the image that is at the center of the view port is listed below the viewport. Remember that threejs uses cartesian space. So an image that is 150px / 150px will report pixels from -75 to 75. So if both of your x is negative and your y is positive, then you know you're viewing the top left portion of the image.
The fiddle: http://jsfiddle.net/v1g64zkb/
var width = 400;
var height = 300;
var aspect = width/height;
var near = 1;
var far = 1000;
var angle = 45;
var createRenderer = function(){
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width,height);
return renderer;
}
var camera;
var createCamera = function(){
camera = new THREE.PerspectiveCamera(
angle, aspect, near, far);
camera.position.set( 0, 0, 100 );
camera.lookAt(new THREE.Vector3( 0, 0, 0 ));
return camera;
}
var createScene = function(){
var scene = new THREE.Scene();
return scene;
}
var createControls = function(camera){
var controls = new
THREE.OrbitControls(camera);
controls.rotateSpeed = 0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = true;
controls.noPan = false;
return controls;
}
var createLight = function(){
var light = new THREE.PointLight(0xFFFFFF);
light.position.x=0;
light.position.y=0;
light.position.z=100;
return light;
}
var scene = createScene();
var camera = createCamera();
var controls = createControls(camera);
var light = createLight();
var renderer = createRenderer();
scene.add(light);
scaledMap = new THREE.Mesh(
new THREE.PlaneGeometry( 150, 150 ),
new THREE.MeshBasicMaterial( {
map: new THREE.ImageUtils.loadTexture( '../img/logo.png' ),
color:0xFFFFFF,
side: THREE.DoubleSide
} )
);
scene.add( scaledMap );
var raycaster = new THREE.Raycaster();
var cameraPosition = new THREE.Vector2();
cameraPosition.x = 0;
cameraPosition.y = 0;
console.log(cameraPosition)
var render = function(){
renderer.render(scene,camera);
raycaster.setFromCamera( cameraPosition, camera );
var intersects = raycaster.intersectObjects( scene.children );
if(intersects[0] != undefined){
$("#output").html(intersects[0].point.x.toFixed(2)+" "+intersects[0].point.y.toFixed(2));
}
renderer.render( scene, camera );
}
controls.addEventListener('change',render);
var animate = function(){
requestAnimationFrame(animate);
render();
controls.update();
}
animate();
$("#container").append(renderer.domElement);
//edit: I would not run a picking ray inside a render call. This is just a simplified example. Use the controls change event or whatever to fire the picking ray.

Create torus graph using three js

I'm trying to create a torus graph where there are different coloured segments of different widths (depending on the data size), basically a pie graph that looks nicer.
Is it possible to do this using torus geometry or would it be best to create the segments as shapes and use exctrudegeometry?
In wither case, what's the best way of doing this?
Edit
I have implemented this via torus geometry like:
var prevAngle = 0;
for(var i = 0; i < data.length; i++){
var mat = new THREE.MeshPhongmaterial({materialOptions});
var angle = 2* Math.PI * data[i].size //size is decimal
var geo = new THREE.TorusGeometry(500, 200, 8, 6, angle);
var mesh = new THREE.Mesh(geo, mat);
mesh.rotation.z = prevAngle;
scene.add(mesh);
prevAngle = angle;
}
But when I render this (with 4 objects in data with size 0.25) I only get the top half of the torus (semi-torus?).
is the rotation correct?
You can look at the example at https://github.com/josdirksen/learning-threejs/blob/master/chapter-05/07-basic-3d-geometries-torus.html
As you can see, the last argument to the TorusGeometry is the arc which you can use to directly map the segments of your pie graph to segments of a torus geometry.
Working solution
var prevAngle = 0;
var material = new THREE.MeshPhongmaterial({materialOptions});
var graphContainer = new THREE.Object3D();
graphContainer.castShadow = false;
for(var i = 0; i < data.length; i++){
var mat = material.clone();
mat.color = new THREE.Color(this.coloursArray[i]); //colorsArray = ['#46adad', ...]
var angle = 2* Math.PI * data[i].size //size is decimal
var geo = new THREE.TorusGeometry(500, 200, 8, 6, angle);
var mesh = new THREE.Mesh(geo, mat);
mesh.rotation.z = prevAngle;
graphContainer.add(mesh);
prevAngle += angle;
}
this.scene.add(graphContainer);

Visualizing finegrained coordinates in ThreeJS

I'm visualizing UTM/WGS84 coordinates in three.js. My problem is that the granularity of the trajectories are very fine grained, meaning that I can't see any differences in the movement behaviour. I'm looking for a clean way to plot a Space-Time-Cube (X and Y is space, Z is time) but I can't figure out how to project the trajectory data into the scene that I can actually see the location changes (I normalized the data which kinda worked but I would rather prefer a more fancy method). I'm loading the trajectory info from a CSV which is stored in the variable data. I have 1500 of these tuples, with LAT, LON (EPSG 4326) and ascending seconds. As you can see the movement is very fine grained (I have movement data from an object moving over a size of approx. four football fields)
12.4309352,48.4640973,0
12.4301431,48.4655268,15
12.4288555,48.4658138,30
12.4266812,48.4653488,45
12.4245049,48.4648678,60
12.4228305,48.4639438,75
12.4217859,48.4625038,90
... ... ...
Here is my code so far with comments:
var data = $.csv.toArrays(csv);
var renderer,
scene,
camera,
controls
//using terrainSize was an experiment, it didn't change much
var terrainSize = 60;
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
renderer = new THREE.WebGLRenderer({ antialias: true });
document.body.appendChild( renderer.domElement );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColorHex( 0xeeeeee, 1.0 );
scene = new THREE.Scene();
var material = new THREE.LineBasicMaterial({
color: 0xff00cc,
fog: true
});
var geometry = new THREE.Geometry();
var x = []
var y = []
var z = []
var count = 0;
for(var row in data) {
count += parseInt(data[row][2]);
x.push(parseFloat(data[row][0]));
y.push(parseFloat(data[row][1]));
z.push(parseFloat(count));
}
//I normalize the seconds that everything is visible on the map
z_stretch = stretch_array(z,10,1)
function stretch_array(my_stretched_array, given_stretch, multiplier) {
ratio = Math.max.apply(this, my_stretched_array) / given_stretch,
l = my_stretched_array.length;
for ( i = 0; i < l; i++ ) {
my_stretched_array[i] = my_stretched_array[i] / ratio;
}
for ( i = 0; i < my_stretched_array.length; i++) {
my_stretched_array[i] = multiplier * my_stretched_array[i];
}
return my_stretched_array;
}
//I zip the data back together
var data_stretched = []
for ( i = 0; i < data.length; i++ ) {
data_stretched.push([x[i], y[i], z_stretch[i]]);
}
//I tried using d3.js but I couldn't figure out how to stretch the data accordingly
var projection = d3.geo.transverseMercator()
.translate([terrainSize / 2, terrainSize / 2])
.scale(10)
.center([12.4309352,48.4640973]);
//Looping through the data, translating it and adding each tuple to the geometry
for (var row in data_stretched) {
var x = data_stretched[row][0]
var y = data_stretched[row][2]
var z = data_stretched[row][2]
coord = translate(projection([y, x]));
geometry.vertices.push(new THREE.Vector3(parseFloat(coord[0]), parseFloat(z), parseFloat(coord[1])));
}
// Another experiment
function translate(point) {
return [point[0] - (terrainSize / 2), (terrainSize / 2) - point[1]];
}
// Plotting the line
var line = new THREE.Line(geometry, material);
scene.add( line );
// camera and control settings..
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, -terrainSize / 2, terrainSize / 2);
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 0.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
animate();
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
And this is how I want it to look like (I just stretched the values for this one, which is kinda ugly..)
Solved, I had to scale the coordinates.
var projection = d3.geo.transverseMercator()
.translate([window.innerWidth, window.innerHeight])
.scale(30000000);

Categories