Consistent rotation on click as opposed to drag - three.js

I'm probably missing something to get this done.
https://codepen.io/ndsp/pen/YQavxG
<html lang="en">
<head>
<title>three.js webgl - materials - cube reflection [cars]</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.js"></script>
<script>
var controls, camera, scene, renderer;
var cameraCube, sceneCube;
var textureCube;
var cubeMesh;
var currentLookat, newLookat;
init();
animate();
function init() {
// CAMERAS
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 5000 );
camera.position.set( 0, 0, 1000 );
cameraCube = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 5000 );
currentLookat = new THREE.Vector3( 0, 0, - 1 );
newLookat = new THREE.Vector3( 0, 0, - 1 );
// SCENE
scene = new THREE.Scene();
sceneCube = new THREE.Scene();
// Lights
var ambient = new THREE.AmbientLight( 0xffffff );
scene.add( ambient );
var starsGeometry = new THREE.Geometry();
for ( var i = 0; i < 1000; i ++ ) {
var star = new THREE.Vector3();
star.x = THREE.Math.randFloatSpread( 5000 );
star.y = THREE.Math.randFloatSpread( 5000 );
star.z = THREE.Math.randFloatSpread( 5000 );
starsGeometry.vertices.push( star )
}
var starsMaterial = new THREE.PointsMaterial( { color: 0x888888 } )
var starField = new THREE.Points( starsGeometry, starsMaterial );
scene.add( starField );
var geometry = new THREE.BoxGeometry(10, 10, 10);
var material = new THREE.MeshStandardMaterial({ color: 0xff0000 });
var cube = new THREE.Mesh(geometry, material);
cube.position.z = 20;
cube.position.y = 10;
scene.add( cube );
renderer = new THREE.WebGLRenderer();
renderer.autoClear = false;
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setFaceCulling( THREE.CullFaceNone );
document.body.appendChild( renderer.domElement );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
cameraCube.aspect = window.innerWidth / window.innerHeight;
cameraCube.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
currentLookat.lerp(newLookat, 0.05);
camera.lookAt(currentLookat);
// controls.update();
requestAnimationFrame( animate );
render();
}
function render() {
var timer = -0.0002 * Date.now();
cameraCube.rotation.copy( camera.rotation );
renderer.render( sceneCube, cameraCube );
renderer.render( scene, camera );
}
function onMouseDown( event ) {
var canvasPosition = renderer.domElement.getBoundingClientRect();
var mouseX = event.clientX - canvasPosition.left;
var mouseY = event.clientY - canvasPosition.top;
var mouseVector = new THREE.Vector3 (
2 * (mouseX / window.innerWidth) - 1,
1 - 2 * (mouseY / window.innerHeight), 1);
console.log(mouseVector);
mouseVector.unproject( camera );
console.log(mouseVector);
// console.log(unproject( camera ));
var dir = mouseVector.sub( camera.position ).normalize();
var distance = - camera.position.z / dir.z;
var oldPos = camera.position.clone();
newLookat = camera.position.clone().add( dir.multiplyScalar( distance ) );
currentLookat.applyQuaternion( camera.quaternion );
}
window.addEventListener( 'mousedown', onMouseDown, false );
</script>
</body>
The idea is to click an area in space and rotate the camera (or camera lookat) to that point based on the mouse coordinates to world coordinates thing that is going on in the example. the smaller the interpolation factor in lerp, the more pronounced the inaccurate rotation presents itself.
I tried passing both matrices and vectors into lerp, but I get the exact same behavior. Without lerp, it doesn't look like the problem exists, although it's hard to tell.
I need help just to diagnose, let alone fix it.
Related to this: Tween question but I wanted to eliminate tween.js, partially on comments I received there.
Thank you!

Related

Draw a line from the camera position to the origin

Using threejs, I'm trying to draw a line from the camera position to the origin.
I expect that the line will always point to the middle of the screen (assuming that the renedered scene is viewed from the camera origin)
but it does not (the line always points towards the side of the screen).
The code below is a subset of the formal threejs webgl_geometry_extrude_shapes.html example.
I added the function draw_line_from_camera_to_origin(scene, camera)
What am I doing wrong?
Thanks,
Avner
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - geometry - extrude shapes</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #222;
margin: 0px;
overflow: hidden;
}
a {
color: #f80;
}
</style>
</head>
<body>
<script src="../build/three.js"></script>
<script src="js/controls/TrackballControls.js"></script>
<script>
var container;
var camera, scene, renderer, controls;
init();
animate();
function draw_line_from_camera_to_origin(scene, camera)
{
// Draw line from camera to origin
var pointA2 = new THREE.Vector3( camera.position.x, camera.position.y, camera.position.z );
var pointB2 = new THREE.Vector3( 0, 0, 0 );
var geometry2 = new THREE.Geometry();
geometry2.vertices.push( pointA2 );
geometry2.vertices.push( pointB2 );
var material2 = new THREE.LineBasicMaterial( { color : 'yellow' } );
var line2 = new THREE.Line( geometry2, material2 );
scene.add( line2 );
}
function init() {
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.style.color = '#fff';
info.style.link = '#f80';
info.innerHTML = 'three.js webgl - geometry extrude shapes';
document.body.appendChild( info );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x222222 );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 0, 0, 500 );
controls = new THREE.TrackballControls( camera, renderer.domElement );
controls.minDistance = 200;
controls.maxDistance = 500;
scene.add( new THREE.AmbientLight( 0x222222 ) );
var light = new THREE.PointLight( 0xffffff );
light.position.copy( camera.position );
scene.add( light );
//
var closedSpline = new THREE.CatmullRomCurve3( [
new THREE.Vector3( -60, -100, 60 ),
new THREE.Vector3( -60, 20, 60 ),
new THREE.Vector3( -60, 120, 60 ),
new THREE.Vector3( 60, 20, -60 ),
new THREE.Vector3( 60, -100, -60 )
] );
closedSpline.curveType = 'catmullrom';
closedSpline.closed = true;
var extrudeSettings = {
steps : 100,
bevelEnabled : false,
extrudePath : closedSpline
};
var pts = [], count = 3;
for ( var i = 0; i < count; i ++ ) {
var l = 20;
var a = 2 * i / count * Math.PI;
pts.push( new THREE.Vector2 ( Math.cos( a ) * l, Math.sin( a ) * l ) );
}
var shape = new THREE.Shape( pts );
var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
var material = new THREE.MeshLambertMaterial( { color: 0xb00000, wireframe: false } );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
draw_line_from_camera_to_origin(scene, camera);
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
</script>
</body>
</html>
You need to update the location of the other point.
When you first create the line you tell it a point in space and it never moves from there. It may seem like its moving around but thats just because it is a very long line.
So you need to make geometry2 a global variable (at the top):
var camera, scene, renderer, controls, geomerty2;
Then remove var when you declare geometry2 in draw_line_from_camera_to_origin
Then your animation loop should be:
function animate() {
geometry2.vertices[0].x = camera.position.x;
geometry2.vertices[0].y = camera.position.y;
geometry2.vertices[0].z = camera.position.z;
geometry2.verticesNeedUpdate = true;
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
Now when you move the camera you see the line move with it then drift back to the camera's position. I'm not sure why it does that, I was actually expecting the line to be invisible (because lines have 0 width, and its pointing directly at the camera).
But anyways, happy coding haha hello world 42

Create a planet orbit

i want create a red ring to visualize the Orbit of the green Sphere around the yellow Sphere. With lookat() i have orientate the rings to the green Spheres but i have no idea how i can move the rings in the right angel.
My script:
<!doctype html>
<html>
<head>
</head>
<body>
<div id="container"></div>
<!--Load three.js-->
<script src="js/three.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script>
var camera, controls, scene, renderer, raycaster;
var mouse = new THREE.Vector2();
init();
animate();
function init() {
scene = new THREE.Scene();
raycaster = new THREE.Raycaster();
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x000000);
var container = document.getElementById( 'container' );
container.appendChild( renderer.domElement );
camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 100000000000000000);
camera.position.z = 30;
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', render );
controls.enableKeys = false;
var planet = ["-4067664386091","-710580828973","-3956610895959","2060000",
"29476716044","5149291420","-46417511315","2660000",
"124056083719","21671373654","16235707106","4810000",
"-107354576606","-18753785170","436797007078","18890000",
"-639929607985","-111789387758","-1118379774141","57970000",
"2907924314427","507985682645","-950946134275","2830000",
"-2275005926406","-397421085828","3223734974754","7480000",
"-4067664386091","-710580828973","-3956610895959","5110000"]
for ( var i = 0; i < 7; i ++ ) {
var geometry = new THREE.SphereGeometry(5, 32, 32);
var material = new THREE.MeshBasicMaterial( {color: 0x09F425} );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.x = planet[i * 4] / 1000000000;
mesh.position.y = planet[i * 4 + 1] / 1000000000;
mesh.position.z = planet[i * 4 + 2] / 1000000000;
scene.add( mesh );
var startPoint = new THREE.Vector3(0,0,0);
var endPoint = new THREE.Vector3(planet[i * 4] / 1000000000,planet[i * 4 + 1] / 1000000000,planet[i * 4 + 2] / 1000000000);
var direction = new THREE.Vector3().subVectors(endPoint, startPoint).normalize();
var arrow = new THREE.ArrowHelper(direction, startPoint, startPoint.distanceTo(endPoint), 0xCC0000 );
scene.add(arrow);
<!-- I want this red ring in to show the Orbit of the green Spheres -->
var geometry = new THREE.RingGeometry(startPoint.distanceTo(endPoint) - 1, startPoint.distanceTo(endPoint), 32);
var material = new THREE.MeshBasicMaterial( { color: 0xCC0000, side: THREE.DoubleSide } );
var mesh = new THREE.Mesh( geometry, material );
var testPoint = new THREE.Vector3(planet[i * 4] / 1000000000,(planet[i * 4 + 1] / 1000000000)*0.5,planet[i * 4 + 2] / 1000000000);
var pos = new THREE.Vector3();
pos.addVectors(testPoint, mesh.position);
mesh.lookAt(pos);
scene.add(mesh);
<!--------->
}
var geometry = new THREE.SphereGeometry(10, 32, 32);
var material = new THREE.MeshBasicMaterial( {color: 0xCDF409} );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.x = 0;
mesh.position.y = 0;
mesh.position.z = 0;
scene.add( mesh );
window.addEventListener( 'mousemove', onMouseMove, false );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onMouseMove( event ) {
// calculate mouse position in normalized device coordinates
// (-1 to +1) for both components
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
// update the picking ray with the camera and mouse position
raycaster.setFromCamera( mouse, camera );
// calculate objects intersecting the picking ray
var intersects = raycaster.intersectObjects( scene.children );
for ( var i = 0; i < intersects.length; i++ ) {
//intersects[ i ].object.material.color.set( 0xff0000 );
}
renderer.render(scene, camera);
}
</script>
</body>
</html>
If I got you right.
For orbits, there can be a rough solution:
var geometry = new THREE.CircleGeometry(startPoint.distanceTo(endPoint), 128);
geometry.vertices.shift();
geometry.rotateX(-Math.PI / 2);
var material = new THREE.LineBasicMaterial( { color: 0xCC0000 } );
var mesh = new THREE.Line( geometry, material );
and then to align your orbits to their planets:
mesh.lookAt(endPoint); // as you calculated endPoint before, then no need to calculate the same for testPoint
jsfidde example. Clarify, if I missed something from your question.

Three.js: create a square cone with radius segments more than 4

I have done some math to create a square cone with radius segment
more than 4. When the top and bottom radius are the same it works fine as shown in the image.
but when the top and bottom radius are different it does not work as shown in the image.
I am not sure what the problem is? I really appreciate any other way to do this? Thank you in advance. here is my code:
<html>
<head>
<title>Lightshade</title>
<script src="three.js"> </script>
<script src="TrackballControls.js"></script>
</head>
<body>
<script>
//declaring variables
var camera, scene, renderer;
var controls;
var cone, coneGeometry;
scene = new THREE.Scene();
var camera = new THREE.OrthographicCamera( -window.innerWidth / 2.5, window.innerWidth / 2.5, window.innerHeight / 2.5, -window.innerHeight / 2.5, -10000, 1000000);
camera.position.set( 0, 2.0, 5.0);
camera.lookAt(scene.position);
//adding the renderer to the screen
renderer = new THREE.WebGLRenderer( { antialias: true} );
renderer.setClearColor( 0xeeeeee , 0); //eeeeee
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMapCullFace = THREE.CullFaceBack;
renderer.shadowMapEnabled = true;
document.body.appendChild( renderer.domElement );
//adding the camera interactive method
controls = new THREE.TrackballControls( camera, renderer.domElement );
controls.noKeys = true;
//creating materials for lightshade
lightshadeMaterial = new THREE.MeshPhongMaterial({color:0xffeb00,wireframe:false, side:THREE.DoubleSide, ambient: 0xffffff});
var coneGeometry = new THREE.CylinderGeometry( 50, 125, 150, 60, 44 , true);
var cone = new THREE.Mesh( coneGeometry, lightshadeMaterial );
cone.geometry.applyMatrix(new THREE.Matrix4().makeRotationY(Math.PI/2));
for (j=0;j<=2684;j=j+61) {
for (i=0;i<=60;i++) {
if (i<=15) {
tempLineGrad = (cone.geometry.vertices[15].z - cone.geometry.vertices[0].z) / (cone.geometry.vertices[15].x - cone.geometry.vertices[0].x);
cone.geometry.vertices[i+j].z = tempLineGrad * (cone.geometry.vertices[i+j].x - cone.geometry.vertices[0].x) + cone.geometry.vertices[0].z;
}
if (i>15 && i<=30){
tempLineGrad = (cone.geometry.vertices[30].z - cone.geometry.vertices[15].z) / (cone.geometry.vertices[30].x - cone.geometry.vertices[15].x);
if (tempLineGrad>999999) {
cone.geometry.vertices[i+j].x = cone.geometry.vertices[15].x;
} else {
cone.geometry.vertices[i+j].z = tempLineGrad * (cone.geometry.vertices[i+j].x - cone.geometry.vertices[15].x) + cone.geometry.vertices[15].z;
}
}
if (i>30 && i<=45){
tempLineGrad = (cone.geometry.vertices[45].z - cone.geometry.vertices[30].z) / (cone.geometry.vertices[45].x - cone.geometry.vertices[30].x);
cone.geometry.vertices[i+j].z = tempLineGrad * (cone.geometry.vertices[i+j].x - cone.geometry.vertices[30].x) + cone.geometry.vertices[30].z;
}
if (i>45 && i<=60){
tempLineGrad = (cone.geometry.vertices[60].z - cone.geometry.vertices[45].z) / (cone.geometry.vertices[60].x - cone.geometry.vertices[45].x);
cone.geometry.vertices[i+j].z = tempLineGrad * (cone.geometry.vertices[i+j].x - cone.geometry.vertices[45].x) + cone.geometry.vertices[45].z;
}
}
}
scene.add(cone);
// adding some light to the screen
var light3 = new THREE.PointLight( 0xffffff, 1, 1000);
light3.position.set( 0, 300.0, 0 );
scene.add( light3 );
var light1 = new THREE.PointLight( 0xffffff,0.7, 1000 );
light1.position.set( 0, 4.0, 0 );
scene.add( light1 );
var light2 = new THREE.PointLight( 0xffffff, 0.7, 1000 );
light2.position.set( 0, -1.0, 0 );
scene.add( light2 );
var light4 = new THREE.PointLight( 0xffffff, 1, 1000);
light4.position.set( 300.0, 160.0, 300.0 );
scene.add( light4 );
var light5 = new THREE.PointLight( 0xffffff, 1, 1000);
light5.position.set( -300.0, 160.0, 300.0 );
scene.add( light5 );
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
controls.update();
renderer.render( scene, camera );
}
animate();
</script>
</body>
</html>

Three.js - Collision by raycasting with a rotated origin mesh

Hello I try to control a mesh, he can turn and moove relative to its rotation by mesh.translate.
But for collisions, i cant find how to raycast relative to its rotation.
If the origin mesh is not rotated or if I moove it with mesh.position.x++, it works. But rotated and with translateX(1), it's not ok.
Thank you for your attention.
Here is my function only for right side (+X) :
function coll(b1,b2){
var hit = false;
var dist = (width/2);
var matrix = new THREE.Matrix4();
matrix.extractRotation( b1.matrix );
var origin = new THREE.Vector3(b1.position.x,b1.position.y,b1.position.z);
var direction = new THREE.Vector3( 1, 0, 0 );
direction = matrix.multiplyVector3( direction );
var ray = new THREE.Raycaster(origin, direction,0,dist);
var collisionResult = ray.intersectObject(b2);
if(collisionResult!=0){
hit = true; b1.translateX( -1 );
}else{
hit = false;
}//if
return hit;
}//coll()
And this is the entire code just in case :
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - geometry - cube</title>
<meta charset="utf-8">
<style>
body {
margin: 0px;
background-color: #000000;
overflow: hidden;
color: white;
}
</style>
</head>
<body>
<script src="../build/three.min.js"></script>
<script>
var camera, scene, renderer;
var width = 100;
var mesh, mesh2;
var key = {left:false};
function keyDown(e){
if (e.keyCode == 39) { key.right = true; }
}//keyPress()
window.addEventListener("keydown", keyDown);
function keyUp(e){
if (e.keyCode == 39) { key.right = false; }
}//keyPress()
window.addEventListener("keyup", keyUp);
function moove(m){
if (key.right){
m.translateX( 1 );
//m.position.x++;
}//if
if (key.left){
m.translateX( -1 );
}//if
}//moove()
function coll(b1,b2){
var hit = false;
var dist = (width/2);
var matrix = new THREE.Matrix4();
matrix.extractRotation( b1.matrix );
var origin = new THREE.Vector3(b1.position.x,b1.position.y,b1.position.z);
var direction = new THREE.Vector3( 1, 0, 0 );
direction = matrix.multiplyVector3( direction );
var ray = new THREE.Raycaster(origin, direction,0,dist);
var collisionResult = ray.intersectObject(b2);
if(collisionResult!=0){
hit = true; b1.translateX( -1 );
}else{
hit = false;
}//if
return hit;
}//coll()
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 400;
scene = new THREE.Scene();
var geometry = new THREE.BoxGeometry( width, 10, 10);
mesh = new THREE.Mesh( geometry);
scene.add( mesh );
mesh.position.x = -100;
mesh.position.y = -20;
mesh.rotation.z = 1;
geometry = new THREE.BoxGeometry( width, 100, 100);
mesh2 = new THREE.Mesh( geometry);
scene.add( mesh2 );
window.addEventListener( 'resize', onWindowResize, false );
}//init()
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}//resize()
function animate() {
requestAnimationFrame( animate );
coll(mesh,mesh2);
moove(mesh);
renderer.render( scene, camera );
}//animate()
</script>
</body>
</html>
I also tried with quaternion but its still the same result :
direction.applyQuaternion( b1.quaternion );
I have a collision with mesh.position.x++ so maybe translateX does something wrong ?
It is ok now. This collision works good finally.

three.js - identify point on tube circumference and rotate from that point

Below is my code for the scene of tube geometry. I've loaded 200 co-ordinates as JSON data from external file.
<!DOCTYPE html>
<html lang="en">
<head>
<title>3d Model using HTML5 and three.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
#info {
color:#000;
position: absolute;
top: 0px; width: 100%;
padding: 5px;
}
</style>
</head>
<body>
<div id="info">
WASD-move, RF-up/down, QE-roll, mouse-look around, mouse left/right click- zoom-in/out
</div>
<script src="three.min.js" type="text/javascript"></script>
<script src="Curve.js" type="text/javascript"></script>
<script src="Stats.js" type="text/javascript"></script>
<script src="Detector.js" type="text/javascript"></script>
<script src="path.js" type="text/javascript"></script>
<script>
// variables
var container, stats;
var camera, scene, renderer, controls;
var text, plane, tube, tubeMesh, parent;
var targetRotation = 0;
var targetRotationOnMouseDown = 0;
var mouseX = 0, mouseY = 0; var radius = 6371;
var mouseXOnMouseDown = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var clock = new THREE.Clock();
function plotPath()
{
var obj = getPath();
var segments = 60;
var closed = false;
var debug = true;
var radiusSegments = 12;
var tube;
var points = [];
var x=0,y=0,z=0;
var extrudePath;
for(var i=0; i<obj.path.length; i++)
{
console.log(obj.path[i].point);
points.push(obj.path[i].point);
}
extrudePath = new THREE.SplineCurve3(points);
tube = new THREE.TubeGeometry(extrudePath, segments, 2, radiusSegments, closed, debug);
tubeMesh = new THREE.Mesh(tube ,new THREE.MeshBasicMaterial({
color: 0x000000, side: THREE.DoubleSide,
opacity: 0.5, transparent: true, wireframe: true}));
if ( tube.debug ) tubeMesh.add( tube.debug );
scene.add( tubeMesh );
}
init();
animate();
function init(){
// container
container = document.createElement( 'div' );
document.body.appendChild( container );
// scene
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2( 0xcccccc, 0.002 );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setClearColor( scene.fog.color, 1 );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
// camera
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
// light
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 1, 1, 1 );
scene.add( light );
light = new THREE.DirectionalLight( 0x002288 );
light.position.set( -1, -1, -1 );
scene.add( light );
light = new THREE.AmbientLight( 0x555555 );
scene.add( light );
// CONTROLS
controls = new THREE.RollControls( camera );
controls.movementSpeed = 50;
controls.lookSpeed = 3;
controls.constrainVertical = [ -0.5, 0.5 ];
// Grid
geometry = new THREE.Geometry();
geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );
geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );
for ( var i = 0; i <= 20; i ++ ) {
line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
line.position.z = ( i * 50 ) - 500;
scene.add( line );
line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
line.position.x = ( i * 50 ) - 500;
line.rotation.y = 90 * Math.PI / 180;
scene.add( line );
}
// projector
projector = new THREE.Projector();
plotPath();
// stats
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
// events
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
update();
}
function update(){
controls.update(clock.getDelta());
stats.update();
}
function render() {
renderer.render( scene, camera );
}
</script>
</body>
</html>
How can I identify a point on tube circumference and how to rotate a tube from that point ?
OrbitControls, for example, has a property target which is both the center of rotation and the camera look-at position.
controls = new THREE.OrbitControls( camera );
You can change the center of rotation of the camera using picking.
function onDocumentMouseDown( event ) {
event.preventDefault();
var vector = new THREE.Vector3(
( event.clientX / window.innerWidth ) * 2 - 1,
- ( event.clientY / window.innerHeight ) * 2 + 1,
0.5 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
var intersects = ray.intersectObjects( objects );
if ( intersects.length > 0 ) {
controls.target.copy( intersects[0].point );
}
}
EDIT: Here is an updated fiddle: http://jsfiddle.net/eVkgs/30/
three.js r.65

Resources