Three.js Object3d cylinder rotation to align to a vector - javascript

I have searched far and wide, but can't seem to figure this pretty basic thing out. I have seen other examples on stackoverflow and elsewhere from a year or two ago, but they fail to work with the latest version of Three.js.
Here is a version of what i'm working on: http://medschoolgunners.com/sandbox/3d/.
I'm trying to get the grey cone to exactly align with the unlabeled red vector. Ie. I want the tip of the cone to be exactly aligned with the vector and point out from the origin in that direction.
Here is the code I have right now:
//FUNCTION TO CREATE A CYLINDER
function create_cylinder(radiusTop,radiusBottom, height, segmentsRadius, segmentsHeight, openEnded, color)
{
var material = new THREE.MeshLambertMaterial({
color: color, //0x0000ff
opacity: 0.2
});
var cylinder = new THREE.Mesh(new THREE.CylinderGeometry(radiusTop,radiusBottom, height, segmentsRadius, segmentsHeight, openEnded), material);
cylinder.overdraw = true;
return cylinder;
}
//ALIGN THE CYLINDER TO A GIVEN VECTOR
var alignVector=new THREE.Vector3(-50,50,50); //the vector to be aligned with
var newcylinder = create_cylinder(0.1, 10, 40, 50, 50, false, "0x0ff0f0"); // the object to be aligned with the vector above
var cylinderQuaternion = new THREE.Quaternion();
cylinderQuaternion.setFromEuler(alignVector);
newcylinder.useQuaternion = true;
newcylinder.quaternion=cylinderQuaternion;
scatterPlot.add(newcylinder);

If you have an arbitrary vector:
var vector = new THREE.Vector3(100, 60, 20);
You can align an object, such as a cylinder, to the vector like this:
var geometry = new THREE.CylinderGeometry(2, 2, vector.length(), 4, 4);
var mesh = new THREE.Mesh(geometry, someMaterial);
var axis = new THREE.Vector3(0, 1, 0);
mesh.quaternion.setFromUnitVectors(axis, vector.clone().normalize());
Where axis is the original direction of the cylinder (pointing up).
You can also move the cylinder to match the position of the vector like this:
mesh.position.copy(vector.clone().multiplyScalar(0.5));
This puts one end of the cylinder at the 0, 0, 0 and the other at 100, 60, 20, and works because I set the cylinder length to vector.length().

i know this is an old question, but in case anyone is still wondering, what worked for me was adding the vector to the mesh position and use lookAt to align it to the vector:
//Mesh to align
var material = new THREE.MeshLambertMaterial({color: 0x0000ff});
var cylinder = new THREE.Mesh(new THREE.CylinderGeometry(10, 10, 15), material);
//vector to align to
var vector = new THREE.Vector3(
5,//x
10,//y
15 //z
);
//create a point to lookAt
var focalPoint = new THREE.Vector3(
cylinder.position.x + vector.x,
cylinder.position.y + vector.y,
cylinder.position.z + vector.z
);
//all that remains is setting the up vector (if needed) and use lookAt
cylinder.up = new THREE.Vector3(0,0,1);//Z axis up
cylinder.lookAt(focalPoint);

Unfortunately I haven't worked with Quaternions, so can't help much. It seems to my that some offsetting is needed, since the cylinder's pivot is at the centre of the mesh, not at one end.
If played with matrices a bit, and I've got decent results.
Here's one way to this, using Mesh's lookAt() method:
var HALF_PI = -Math.PI * .5;
var p1 = new THREE.Vector3(Math.random()-.5,Math.random()-.5,Math.random()-.5).multiplyScalar(30);
var p2 = new THREE.Vector3(Math.random(),Math.random(),Math.random()).multiplyScalar(300);
var halfLength = diff.length() * .5;
var c = new THREE.CylinderGeometry(10, 10, halfLength * 2, 12, 1, false );
var orientation = new THREE.Matrix4();
orientation.setRotationFromEuler(new THREE.Vector3(HALF_PI,0,0));//rotate on X 90 degrees
orientation.setPosition(new THREE.Vector3(0,0,halfLength));//move half way on Z, since default pivot is at centre
c.applyMatrix(orientation);//apply transformation for geometry
var m = new THREE.Mesh( c, new THREE.MeshLambertMaterial( { color: 0x009900, wireframe: true, shading: THREE.FlatShading } ) );
scene.add(m);
m.lookAt(p2);//tell mesh to orient itself towards p2
//just for debugging - to illustrate orientation
m.add(new THREE.Axes());
//visualize p1,p2 vectors
var PI2 = Math.PI * 2;
var program = function ( context ) {
context.beginPath();
context.arc( 0, 0, 1, 0, PI2, true );
context.closePath();
context.fill();
}
particleMaterial = new THREE.ParticleCanvasMaterial( { color: 0x990000, program: program } );
var pp1 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0x990000, program: program } ) );
pp1.scale.multiplyScalar(10);
pp1.position.copy(p1);
scene.add( pp1 );
var pp2 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0x009900, program: program } ) );
pp2.scale.multiplyScalar(10);
pp2.position.copy(p2);
scene.add( pp2 );
This should draw a cylinder that starts at p1, ends at p2 and is oriented towards it.
Offsetting might need some tweaking, but the geometry follows the vector direction pretty close.
There's also the longer version of manually computing the matrices, as opposed to relying on the lookAt() functionality:
plane.add(getCylinderBetweenPoints(p1,p2,new THREE.MeshLambertMaterial( { color: 0x009900, wireframe: true, shading: THREE.FlatShading } )));
function getCylinderBetweenPoints(point1,point2,material){
var HALF_PI = -Math.PI * .5;
var diff = new THREE.Vector3().sub(point1,point2);//delta vector
var halfLength = diff.length() * .5;
var c = new THREE.CylinderGeometry(10, 10, halfLength * 2, 12, 1, false );
var orientation = new THREE.Matrix4();//a new orientation matrix to offset pivot
var offsetRotation = new THREE.Matrix4();//a matrix to fix pivot rotation
var offsetPosition = new THREE.Matrix4();//a matrix to fix pivot position
orientation.lookAt(point1,point2,new THREE.Vector3(0,1,0));//look at destination
offsetRotation.setRotationX(HALF_PI);//rotate 90 degs on X
offsetPosition.setPosition(new THREE.Vector3(-point1.x,diff.length()*.5+point1.z,point1.y*.5));//move by pivot offset on Y
orientation.multiplySelf(offsetRotation);//combine orientation with rotation transformations
orientation.multiplySelf(offsetPosition);//combine orientation with position transformations
c.applyMatrix(orientation);//apply the final matrix
var m = new THREE.Mesh( c, material );
m.add(new THREE.Axes());
return m;
}
var PI2 = Math.PI * 2;
var program = function ( context ) {
context.beginPath();
context.arc( 0, 0, 1, 0, PI2, true );
context.closePath();
context.fill();
}
//visualize p1,p2 vectors
particleMaterial = new THREE.ParticleCanvasMaterial( { color: 0x990000, program: program } );
var pp1 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0x990000, program: program } ) );
pp1.scale.multiplyScalar(10);
pp1.position.copy(p1);
plane.add( pp1 );
var pp2 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0x009900, program: program } ) );
pp2.scale.multiplyScalar(10);
pp2.position.copy(p2);
plane.add( pp2 );
This looks like me more work than using quaternion, from what I see in you're code. If the setFromEuler does the magic for orientation, the mesh's geometry still might need to move (pivot from one end rather than centre)
HTH

Related

How to calculate angle between two planes?

I have two planes, how can I calculate angle between them? Is it also possible to calculate angle between two Object3D points like in case of planes?
Heres an example fiddle: https://jsfiddle.net/rsu842v8/1/
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(25, 25, 12);
var material = new THREE.MeshBasicMaterial({
color: 0x00fff0,
side: THREE.DoubleSide
});
window.plane1 = new THREE.Mesh(new THREE.PlaneGeometry(10, 10), material);
scene.add(plane1);
plane1.position.set(0.3, 1, -2);
plane1.rotation.set(Math.PI / 3, Math.PI / 2, 1);
window.plane2 = new THREE.Mesh(new THREE.PlaneGeometry(10, 10), new THREE.MeshBasicMaterial({
color: 0x0fff00,
side: THREE.DoubleSide
}));
scene.add(plane2);
// setup rest
var pointLight = new THREE.PointLight(0xFFFFFF);
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;
scene.add(pointLight)
const renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x20252f);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
const controls = new THREE.OrbitControls(camera, renderer.domElement);
animate();
// TODO: What is the angle between plane1 and plane2?
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r82/three.js"></script>
<script src="https://yume.human-interactive.org/examples/buffer-geometry/OrbitControls.js"></script>
You want to find the angle between two three.js plane meshes.
Unrotated, a THREE.PlaneGeometry is oriented to face the positive z-axis. So the plane's normal points in the direction of the positive z-axis.
So, create a ( 0, 0, 1 ) vector, and apply the same rotation to it as is applied to the plane mesh.
Note that plane.quaternion is automatically updated when you set plane.rotation, so you can use the quaternion in the calculation -- like so:
var vec1 = new THREE.Vector3( 0, 0, 1 ); // create once and reuse
var vec2 = new THREE.Vector3( 0, 0, 1 );
vec1.applyQuaternion( plane1.quaternion );
vec2.applyQuaternion( plane2.quaternion );
var angle = vec1.angleTo( vec2 ); // radians
The problem is a bit more complicated if the planes are children of other rotated objects.
Of course, you can use angleTo() to find the angle between any two vectors.
three.js r.86
I would suggest somehow calculating the normal vectors for each plane you are rendering. Once you have these two vectors - let's say n1 and n2 - it is easy to calculate the angle between the planes with the dot product.
If you aren't familiar with the dot product, dot(n1,n2) where n1 = (x1,y1,z1) and n2 = (x2,y2,z2) would be equal to x1*x2 + y1*y2 + z1*z2. There is another simple identity that says dot(n1,n2) = |v1||v2|cos(a) where || indicates the magnitude of a vector - i.e. |v| = sqrt(x*x + y*y + z*z) if v = (x,y,z) - and a is the angle between the normals which is the angle between the planes. Here is a link to a Mathematics Stack Exchange answer.
In short a = arccos(dot(n1,n2) / |n1||n2|).
If you are interested in learning more about how planes are defined and what the normal vector represents try looking at this.
If you know n1 and n2 are unit vectors then the equation simplifies further to a = arccos(dot(n1,n2)).

Animate object along a path in three.js

I am trying to animate a cube along a path in three.js.
CODE
// Ellipse class, which extends the virtual base class Curve
var curve = new THREE.EllipseCurve(
0, 0, // ax, aY
16, 21.28, // xRadius, yRadius
0, 2 * Math.PI, // aStartAngle, aEndAngle
false, // aClockwise
0 // aRotation
);
//defines the amount of points the path will have
var path = new THREE.Path( curve.getPoints( 100 ) );
var geometrycirc = path.createPointsGeometry( 100 );
var materialcirc = new THREE.LineBasicMaterial( {
color : 0xff0000
} );
// Create the final object to add to the scene
var ellipse = new THREE.Line( geometrycirc, materialcirc );
ellipse.position.set(0,1,0);
this.scene.add( ellipse );
// add the box to the scene
this.scene.add(this.box);
I have being doing some research into how this could be done and came across this fiddle animate on path This method uses a the THREE.SplineCurve3 method to create the points for the box to use.
My question is do I need to convert my path to use the THREE.SplineCurve3 method.
Or can I use the path as it is?
Any help or pointers would be appreciated.
many thanks
Object Animating on path
Code
// GLOBALS - ALLOCATE THESE OUTSIDE OF THE RENDER LOOP - CHANGED
var cubes = [], marker, spline;
var matrix = new THREE.Matrix4();
var up = new THREE.Vector3( 0, 1, 0 );
var axis = new THREE.Vector3( );
var pt, radians, axis, tangent, path;
// the getPoint starting variable - !important - You get me ;)
var t = 0;
//This function generates the cube and chooses a random color for it
//on initial load.
function getCube(){
// cube mats and cube
var mats = [];
for (var i = 0; i < 6; i ++) {
mats.push(new
THREE.MeshBasicMaterial({color:Math.random()*0xffffff}));
}
var cube = new THREE.Mesh(
new THREE.CubeGeometry(2, 2, 2),
new THREE.MeshFaceMaterial( mats )
);
return cube
}
// Ellipse class, which extends the virtual base class Curve
function Ellipse( xRadius, yRadius ) {
THREE.Curve.call( this );
// add radius as a property
this.xRadius = xRadius;
this.yRadius = yRadius;
}
Ellipse.prototype = Object.create( THREE.Curve.prototype );
Ellipse.prototype.constructor = Ellipse;
// define the getPoint function for the subClass
Ellipse.prototype.getPoint = function ( t ) {
var radians = 2 * Math.PI * t;
return new THREE.Vector3( this.xRadius * Math.cos( radians ),
this.yRadius * Math.sin( radians ),
0 );
};
//
var mesh, renderer, scene, camera, controls;
function init() {
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 20, 20, 20 );
// controls
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', render ); // use if there is no animation loop
controls.minDistance = 10;
controls.maxDistance = 50;
// light
var light = new THREE.PointLight( 0xffffff, 0.7 );
camera.add( light );
scene.add( camera ); // add to scene only because the camera has a child
// axes
scene.add( new THREE.AxisHelper( 20 ) );
////////////////////////////////////////
// Create the cube //
////////////////////////////////////////
marker = getCube();
marker.position.set(0,0,0);
scene.add(marker);
////////////////////////////////////////
// Create an Extruded shape //
////////////////////////////////////////
// path
path = new Ellipse( 5, 10 );
// params
var pathSegments = 64;
var tubeRadius = 0.5;
var radiusSegments = 16;
var closed = true;
var geometry = new THREE.TubeBufferGeometry( path, pathSegments, tubeRadius, radiusSegments, closed );
// material
var material = new THREE.MeshPhongMaterial( {
color: 0x0080ff,
} );
// mesh
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
//////////////////////////////////////////////////////////////////////////
// Create the path which is based on our shape above //
//////////////////////////////////////////////////////////////////////////
//Please note that this red ellipse was only created has a guide so that I could be certain that the square is true to the tangent and positioning.
// Ellipse class, which extends the virtual base class Curve
var curve = new THREE.EllipseCurve(
0, 0, // ax, aY
6, 11, // xRadius, yRadius
0, 2 * Math.PI, // aStartAngle, aEndAngle
false, // aClockwise
0 // aRotation
);
//defines the amount of points the path will have
var path2 = new THREE.Path( curve.getPoints( 100 ) );
geometrycirc = path2.createPointsGeometry( 100 );
var materialcirc = new THREE.LineBasicMaterial( {
color : 0xff0000
} );
// Create the final object to add to the scene
var ellipse = new THREE.Line( geometrycirc, materialcirc );
ellipse.position.set(0,0,0);
scene.add( ellipse );
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
// set the marker position
pt = path.getPoint( t );
// set the marker position
marker.position.set( pt.x, pt.y, pt.z );
// get the tangent to the curve
tangent = path.getTangent( t ).normalize();
// calculate the axis to rotate around
axis.crossVectors( up, tangent ).normalize();
// calcluate the angle between the up vector and the tangent
radians = Math.acos( up.dot( tangent ) );
// set the quaternion
marker.quaternion.setFromAxisAngle( axis, radians );
t = (t >= 1) ? 0 : t += 0.002;
renderer.render( scene, camera );
}
init();
animate();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/82/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
Conclusion
So I was very Fortunate to stumble upon the answer.
In my case it was the creation of a subclass to my object which allowed me to use it's data as points so that an object could use it as a guide.
Yes I am aware that you are thinking 'What is this guy talking about' so I have created a fiddle for you to look at and study.
Fiddle: Object Animating on path

Three JS Circle Line Geom Color for Negative Values

I've been testing some ideas on how to get a circle to have a different color for the part of the circle that has positive Z values. I tried one approach, creating two separate line segments and using different materials. It works if the circle has segments that don't jump across Z=0. The problem I'm working on is more complicated as the line segments will jump across the Z=0 boundary so I end up with gaps if I try to do it in two segments. Is there a way to just use one line Geom and then change the color of the part of the line that falls into negative Z values? I'm not sure this is the right approach. Thanks!
Here is what I have so far for a test (using X,Y):
<html>
<head>
<title>Cirle Color</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="three.min.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 500, window.innerWidth/window.innerHeight, 0.1, 100000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var segmentCount = 100,
radius = 10,
geometry = new THREE.Geometry();
geometry2 = new THREE.Geometry();
material = new THREE.LineBasicMaterial({ color: "#5fd119" }); // light green
material2 = new THREE.LineBasicMaterial({ color: "#3d8710" }); // darker green
//PUSH THE ORIGIN VERTICY IN
geometry2.vertices.push(new THREE.Vector3(-10,0,0));
for (var i = 0; i <= segmentCount; i++) {
var theta = (i / segmentCount) * Math.PI * 2;
x = Math.cos(theta) * radius;
y = Math.sin(theta) * radius;
z = 0;
if (y >=0 ){
geometry.vertices.push(new THREE.Vector3(x, y, z));
} else {
geometry2.vertices.push(new THREE.Vector3(x, y, z));
}
}
scene.add(new THREE.Line(geometry, material));
scene.add(new THREE.Line(geometry2, material2));
camera.position.z = 5;
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
};
render();
</script>
</body>
</html>
Update using the answer below. Works great:
I hope I get you correctly. You can set colours of vertices of a geometry and then use vertexColors parameter of a material.
var radius = 5;
var shape = new THREE.Shape();
shape.moveTo(radius, 0);
shape.absarc(0, 0, radius, 0, 2 * Math.PI, false);
var spacedPoints = shape.createSpacedPointsGeometry(360);
var vertexColors = []; // array for our vertex colours
spacedPoints.vertices.forEach( function( vertex ){ // fill the array
if( vertex.y < 0 )
vertexColors.push( new THREE.Color( 0xff0000 ))
else
vertexColors.push( new THREE.Color( 0x0000ff ));
});
spacedPoints.colors = vertexColors; // assign the array
var orbit = new THREE.Line(spacedPoints, new THREE.LineBasicMaterial({
vertexColors: THREE.VertexColors // set this parameter like it shown here
}));
scene.add(orbit);
jsfiddle example

Why can't I draw a complete circle with arc() in Three.js?

I'm trying to draw a complex shape in Three.js using extruded arcs but they just didn't seem to be behaving properly. I don't know if I don't understand the API, but shouldn't this create a complete extruded circle of radius 100 centred at the origin?
var path = new THREE.Path();
path.moveTo(0, 0);
path.arc(0, 0, 100, 0, Math.PI * 2, false);
var shape = path.toShapes(false, false);
var extrudeSettings = {
amount : 20,
steps : 1
};
var geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
var mesh = new THREE.Mesh(geometry, material);
Instead it draws a Pacman shape:
Here's the JSFiddle:
http://jsfiddle.net/c8shqzpn/
You want to create a circle shape so you can extrude it.
Whenever you draw an arc, it connects the start of the arc to the current point, so in your case, you have to use the moveTo() command to set the start point on the perimeter of the circle.
var shape = new THREE.Shape();
shape.moveTo( circleRadius, 0 );
shape.absarc( 0, 0, circleRadius, 0, 2 * Math.PI, false );
three.js r.70
I had similar issues drawing 3/4 of a circle and extruding it and adding the result (a THREE.Mesh) to the screen. The circle seemed to miss a segment. Adding moveTo( x, y ) where x, y are coordinates of the beginning of the arc solved the issue. I used this code:
var extrudeSettings = {
bevelEnabled: false,
steps: 1,
amount: 2
};
var shape = new THREE.Shape();
var circleRadius = 4;
// THIS LINE SOLVES THE ISSUE
shape.moveTo( 0, -circleRadius );
shape.absarc( 0, 0, circleRadius, 0, 1.5 * Math.PI, false );
shape.lineTo( 0, 0 );
shape.closePath();
var geometry = shape.extrude( extrudeSettings );
scene.add( new THREE.Mesh( geometry, new THREE.MeshNormalMaterial() ) );
First my mesh looked like this:
After adding shape.moveTo( 0, -circleRadius ); the mesh looked like this:
Could it be solved if you multiply Math.PI bye 2.1, instead of 2?

Trying to aim the particles to camera while rotating and alert message on intersecting in three js?

I'm trying to create event handler on the particles, with alert message on a sphere, aiming always on the camera.
Something similar to this demo ( and making it to work on IE 9+ )
here is my code..
http://jsfiddle.net/praveenv29/cVnKV/11/
var renderer, projector;
var mouseX, mouseY, stats, container;
var objects = [];
var INTERSECTED;
var camera, scene, renderer, material, mesh, cont;
var w1 = 960;
var h1 = 700;
var halfWidth = w1 / 2;
var halfHeigth = h1 / 2;
function init() {
cont = document.createElement('div');
cont.id = "cont";
document.body.appendChild(cont);
camera = new THREE.PerspectiveCamera(75, w1 / h1, 1, 10000);
camera.position.set(90, 90, -200);
scene = new THREE.Scene();
scene.add(camera);
controls = new THREE.OrbitControls(camera);
controls = new THREE.TrackballControls(camera, cont);
controls.rotateSpeed = 0.8;
controls.zoomSpeed = 1.2;
controls.panSpeed = 2.5;
controls.noZoom = true;
controls.noPan = true;
controls.staticMoving = false;
controls.target.set(0, 0, 0);
controls.keys = [95, 90, 84];
renderer = new THREE.CanvasRenderer();
material = new THREE.MeshBasicMaterial({
color: 0x000000,
wireframe: true
});
renderer.setSize(w1, h1);
cont.appendChild(renderer.domElement);
generateGeometry();
var light = new THREE.PointLight(0xffffff);
light.position.set(10, 0, 0);
scene.add(light);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
controls.update();
renderer.render(scene, camera);
}
function generateGeometry() {
var axis = new THREE.AxisHelper();
scene.add(axis);
for (var i = 0; i < 20; i++) {
var gloom = new THREE.ImageUtils.loadTexture('map_pin.png');
materialr = new THREE.MeshBasicMaterial({
map: gloom,
overdraw: true,
side: THREE.DoubleSide
});
var geometry = new THREE.PlaneGeometry(15, 15, 2, 2);
var cube = new THREE.Mesh(geometry, materialr);
cube.position.x = Math.random() * 2 - 1;
cube.position.y = Math.random() * 2 - 1;
cube.position.z = Math.random() * 2 - 1;
cube.position.normalize();
cube.position.multiplyScalar(125);
cube.rotation.x = cube.position.x / Math.PI; //57.38
cube.rotation.y = 360 / Math.PI * 2;
objects.push(cube);
scene.add(cube);
}
//earth
var texture = THREE.ImageUtils.loadTexture('world.jpg');
var materials = new THREE.MeshBasicMaterial({
map: texture,
overdraw: true
});
var cone = new THREE.SphereGeometry(120, 35, 35);
var coneMesh = new THREE.Mesh(cone, material);
coneMesh.position.y = 0;
coneMesh.rotation.set(0, 0, 0);
scene.add(coneMesh);
}
init();
animate();
It is pretty unclear what you are looking for; your demo link seems unrelated...
Are you trying to make cubes appear camera normal (always facing the camera)? If so, you'll need logic to re-orient them to re-face the camera anytime the user moves the camera view, as I see you are also setting up the TrackballControls, which actually move the camera, not the scene. This means a user can change the camera view of your scene, and items you want facing the camera need to be re-orientated. That re-orientation logic needs to be placed inside your render() function.
BTW, to get an object to always face the camera:
Define it such that when not rotated, it is facing the direction you
want;
Place the object into your scene via any method you want,
including whatever hierarchical rotations or translations you want to use to get them positioned where you want; (Note, they may not be facing
where you want at this point, but that is okay at this step);
Request from three.js that it calculate the local to world space
transformations for your scene. After that, each object's world
transformation matrix contains the concatenated rotations, and
translations that transform each object from local space to world
space.
Go into each object's local-to-world transform matrix and
replace the rotation 3x3 matrix components with the identity
transformation { [1 0 0] [0 1 0] [0 0 1] }. This effectively wipes
out the rotations in world space, making all the objects you do this
to always face the camera.

Categories