I have below code now when the page is loaded I want the cube to zoom out and stop ..how do i do that..i am new to 3js so have no idea..I want it to start off with a small cube and come u as a big cube and stop
<script>
//var resultlabel = (document.getElementById('resultvalue').innerHTML);
//if (resultlabel == 0) {
var container
var camera, controls, scene, renderer;
var objects = [];
var plane = new THREE.Plane();
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2(),
offset = new THREE.Vector3(),
intersection = new THREE.Vector3(),
INTERSECTED, SELECTED;
init();
animate();
function init() {
container = document.getElementById('canvas1');
camera = new THREE.PerspectiveCamera(70, container.offsetWidth / container.offsetHeight, 1, 10000);
//camera.position.z = 2000;
camera.position.set(3000, 3000, 3000);
//camera.position.set(1000, 1000, 1000);
controls = new THREE.TrackballControls(camera, container); //**
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
scene = new THREE.Scene();
var directionalLight = new THREE.DirectionalLight(0x505050);
scene.add(directionalLight);
//var resultlabel = (document.getElementById('resultvalue').innerHTML);
//if (resultlabel == 0) {
var geometry = new THREE.BoxGeometry(500, 500, 500);
var ax = ay = az = 0;
for (var i = 0; i < 1; i++) {
var object = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ ambient: 0xffffff, map: THREE.ImageUtils.loadTexture('/imgs/12.jpg') }));
object.position.x = ax;
object.position.y = ay;
object.position.z = az;
object.scale.x = 2;
object.scale.y = 2;
object.scale.z = 2;
scene.add(object);
light = new THREE.DirectionalLight(0x666699);
light.position.set(0, 1, 0);
scene.add(light);
light = new THREE.DirectionalLight(0x666699);
light.position.set(0, -1, 0);
scene.add(light);
//back
light = new THREE.DirectionalLight(0x666699);
light.position.set(1, 0, 0);
scene.add(light);
// front
light = new THREE.DirectionalLight(0x666699);
light.position.set(-1, 0, 0);
scene.add(light);
//right
light = new THREE.DirectionalLight(0x666699);
light.position.set(0, 0, 1);
scene.add(light);
//left
light = new THREE.DirectionalLight(0x666699);
light.position.set(0, 0, -1);
scene.add(light);
objects.push(object);
}
var material = new THREE.MeshPhongMaterial({ map: THREE.ImageUtils.loadTexture('/1.png') });
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor(0xf0f0f0);
renderer.setPixelRatio(container.devicePixelRatio);
renderer.setSize(container.offsetWidth - 4, container.offsetHeight - 4);
renderer.sortObjects = false;
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFShadowMap;
container.appendChild(renderer.domElement);
stats = new Stats();
container.appendChild(stats.dom);
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
render();
stats.update();
}
function render() {
controls.update();
renderer.render(scene, camera);
}
You can use THREE.Vector3.lerp to get a smooth animation.
Declare a vector3 where you want your camera to go:
var destPosition = new THREE.Vector3(1000,1000,1000);
and in your animation loop write:
camera.position = camera.position.lerp(destPosition, alpha);
where alpha is a value between 0 and 1 and determine how far the camera will travel each loop.
This is a quick trick to get it going and have some flaws, like you will never really get to the destPosition (just very very close). Read up on linear interpolation for a deeper understanding. Good luck!
Related
I have a cube model which is GLTF format, now i am trying to animate it by changing the textures material.
Now currently, there are 300 heat map images as the texture material, the requirement from supervisor is animating the cube model by loading heat map images one by one.
Texture materials set
About the animation, I tried to use VectorKeyFrameTrack to change the child.material. But it does not work.
the codes:
if (WEBGL.isWebGLAvailable() === false) {
document.body.appendChild(WEBGL.getWebGLErrorMessage());
}
var camera, scene, renderer;
init();
function init() {
//init scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0x999999);
//add directional light and spotlight
var light = new THREE.DirectionalLight(0xffffff);
light.position.set(3, 15.0, -29).normalize();
scene.add(light);
var light1 = new THREE.DirectionalLight(0xffffff);
light.position.set(-20, 7.0, -2).normalize();
scene.add(light1);
var light2 = new THREE.DirectionalLight(0xffffff);
light.position.set(-5, 15.0, 30).normalize();
scene.add(light2);
var light3 = new THREE.DirectionalLight(0xffffff);
light.position.set(15, 5.0, -15).normalize();
scene.add(light3);
//add camera
camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 500);
camera.position.y = 5;
camera.position.z = 10;
scene.add(camera);
//add grid
var grid = new THREE.GridHelper(50, 50, 0xffffff, 0x555555);
scene.add(grid);
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//Generate textures array
var loadedTexture = new THREE.TextureLoader().load("1.png");
var material = new THREE.MeshBasicMaterial({map: loadedTexture});
var loadedTexture2 = new THREE.TextureLoader().load("2.png");
var material1 = new THREE.MeshBasicMaterial({map: loadedTexture2});
//Load Collada file
var path = "./image/"
var format = ".png";
var a = "Avg_Displacement_";
var material_list = [];
var times = [];
for (var i = 0; i <= 314; i++) {
var loadedTexture = new THREE.TextureLoader().load(path + a + i + format);
var material = new THREE.MeshBasicMaterial({map: loadedTexture});
material_list.push(material);
times.push(i);
}
console.log(material_list);
var loader = new THREE.GLTFLoader();
loader.load('scene.gltf', function (gltf) {
gltf.scene.scale.set(0.3, 0.3, 0.3);
// console.log(gltf.scene.children[0].material);
// var kf = new THREE.VectorKeyframeTrack( '.scene.material', times, material_list );
// var clip = new THREE.AnimationClip('Action', 315, [kf]);
//
// mixer = new THREE.AnimationMixer(gltf);
// var clipAction = mixer.clipAction(clip);
// clipAction.play();
gltf.scene.traverse(function (child) {
if (child.isMesh) {
var kf = new THREE.VectorKeyframeTrack('child.material', times, material_list);
var clip = new THREE.AnimationClip('Action', 3, [kf]);
mixer = new THREE.AnimationMixer(child);
var clipAction = mixer.clipAction(clip);
clipAction.play()
// child.material = material;
}
scene.add(gltf.scene);
});
});
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', render);
controls.update();
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
render();
}
function render() {
renderer.render(scene, camera);
}
// function animate() {
//
// requestAnimationFrame( animate );
//
// mesh.material.map.offset.x += 0.005;
// mesh.material.map.offset.y += 0.005;
//
// renderer.render( scene, camera );
//
// }
child.material
the second problem is how to animate the model by loading each image as the texture as material.
I'm trying to move the camera controlled by trackballControl into the position of an object.
Right now it's working but as you can see in my fiddle, each time the camera changes position it also changes the z which isn't what I want.
I'm trying to keep the same position but only rotate the globe into the position of the cube.
Here is my code so far
var camera, scene, renderer, controls, cubeMesh;
document.querySelector('button').onclick = function () {
camera.position.copy(cubeMesh.position);
camera.lookAt(controls.target);
};
var initLights = function () {
var light = new THREE.DirectionalLight(0xffffff);
light.position.set(1, 1, 1);
scene.add(light);
var light = new THREE.DirectionalLight(0x002288);
light.position.set(-1, -1, -1);
scene.add(light);
var light = new THREE.AmbientLight(0x222222);
scene.add(light);
};
var init = function () {
renderer = new THREE.WebGLRenderer({antialias: false});
renderer.setSize(window.innerWidth, window.innerHeight);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 300;
scene = new THREE.Scene();
controls = new THREE.TrackballControls(camera);
controls.target.set(0, 0, 0);
controls.rotateSpeed = 2;
document.body.appendChild(renderer.domElement);
var sphereGeom = new THREE.SphereGeometry(100, 32, 32);
var sphereMat = new THREE.MeshPhongMaterial({
color: 0xfb3550,
flatShading: true
});
var sphereMesh = new THREE.Mesh(sphereGeom, sphereMat);
//cube
var cubeDim = 20;
var cubeGeom = new THREE.BoxGeometry(cubeDim, cubeDim, cubeDim);
var cubeMat = new THREE.MeshPhongMaterial({
color: 0x7cf93e,
flatShading: true
});
cubeMesh = new THREE.Mesh(cubeGeom, cubeMat);
var spherical = new THREE.Spherical();
spherical.set(100 + cubeDim / 2, 0.4, 0);
cubeMesh.position.setFromSpherical(spherical);
var zero = new THREE.Vector3(0, 0, 0);
cubeMesh.lookAt(zero);
scene.add(sphereMesh);
sphereMesh.add(cubeMesh);
initLights();
};
var render = function () {
renderer.render(scene, camera);
};
var animate = function () {
requestAnimationFrame(animate);
controls.update();
render();
};
init();
animate()
You can test it in my fiddle here
Here is a fiddle where the camera is zoomed a little bit out by clicking the button.
JS Fiddle
var camera, scene, renderer, controls, cubeMesh;
document.querySelector('button').onclick = function () {
let x = cubeMesh.position.x
let y = cubeMesh.position.y
let z = cubeMesh.position.z
camera.position.x = 0
camera.position.y = y + 200
camera.position.z = z + 100
camera.lookAt(controls.target);
};
var initLights = function () {
var light = new THREE.DirectionalLight(0xffffff);
light.position.set(1, 1, 1);
scene.add(light);
var light = new THREE.DirectionalLight(0x002288);
light.position.set(-1, -1, -1);
scene.add(light);
var light = new THREE.AmbientLight(0x222222);
scene.add(light);
};
var init = function () {
renderer = new THREE.WebGLRenderer({antialias: false});
renderer.setSize(window.innerWidth, window.innerHeight);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 300;
scene = new THREE.Scene();
controls = new THREE.TrackballControls(camera);
controls.target.set(0, 0, 0);
controls.rotateSpeed = 2;
document.body.appendChild(renderer.domElement);
var sphereGeom = new THREE.SphereGeometry(100, 32, 32);
var sphereMat = new THREE.MeshPhongMaterial({
color: 0xfb3550,
flatShading: true
});
var sphereMesh = new THREE.Mesh(sphereGeom, sphereMat);
//cube
var cubeDim = 20;
var cubeGeom = new THREE.BoxGeometry(cubeDim, cubeDim, cubeDim);
var cubeMat = new THREE.MeshPhongMaterial({
color: 0x7cf93e,
flatShading: true
});
cubeMesh = new THREE.Mesh(cubeGeom, cubeMat);
var spherical = new THREE.Spherical();
spherical.set(100 + cubeDim / 2, 0.4, 0);
cubeMesh.position.setFromSpherical(spherical);
var zero = new THREE.Vector3(0, 0, 0);
cubeMesh.lookAt(zero);
scene.add(sphereMesh);
sphereMesh.add(cubeMesh);
initLights();
};
var render = function () {
console.log(camera.position)
renderer.render(scene, camera);
};
var animate = function () {
requestAnimationFrame(animate);
controls.update();
render();
};
init();
animate()
You have to set the camera target to the position where you want to look at.
var newTarget = new THREE.Vector3(0, 0, 0);
newTarget.copy(cubeMesh.position);
camera.lookAt(newTarget);
and the THREE.TrackballControls has to be notified to update from the camera THREE.TrackballControls.update:
document.querySelector('button').onclick = function () {
var newTarget = new THREE.Vector3(0, 0, 0);
newTarget.copy(cubeMesh.position);
controls.reset();
camera.lookAt(newTarget)
camera.updateProjectionMatrix();
controls.update();
};
If the current camera position should be kept and not be reseted, then the position has to be read form the world matrix of the camera and the initial position of the camera has to be set to its current position:
document.querySelector('button').onclick = function ()
var newPosition = new THREE.Vector3(0, 0, 0);
newPosition.applyMatrix4( camera.matrixWorld );
var newTarget = new THREE.Vector3(0, 0, 0);
newTarget.copy(cubeMesh.position);
controls.reset();
camera.position.copy(newPosition);
camera.lookAt(newTarget)
camera.updateProjectionMatrix();
controls.update();
};
See the example:
var camera, scene, renderer, controls, cubeMesh;
document.getElementById('reset').onclick = function () {
var newTarget = new THREE.Vector3(0, 0, 0);
newTarget.copy(cubeMesh.position);
controls.reset();
camera.lookAt(newTarget)
camera.updateProjectionMatrix();
controls.update();
};
document.getElementById('target').onclick = function () {
var newPosition = new THREE.Vector3(0, 0, 0);
newPosition.applyMatrix4( camera.matrixWorld );
var newTarget = new THREE.Vector3(0, 0, 0);
newTarget.copy(cubeMesh.position);
controls.reset();
camera.position.copy(newPosition);
camera.lookAt(newTarget)
camera.updateProjectionMatrix();
controls.update();
};
var initLights = function () {
var light = new THREE.DirectionalLight(0xffffff);
light.position.set(1, 1, 1);
scene.add(light);
var light = new THREE.DirectionalLight(0x002288);
light.position.set(-1, -1, -1);
scene.add(light);
var light = new THREE.AmbientLight(0x222222);
scene.add(light);
};
var init = function () {
renderer = new THREE.WebGLRenderer({antialias: false});
renderer.setSize(window.innerWidth, window.innerHeight);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 300;
scene = new THREE.Scene();
controls = new THREE.TrackballControls(camera);
controls.target.set(0, 0, 0);
controls.rotateSpeed = 2;
document.body.appendChild(renderer.domElement);
var sphereGeom = new THREE.SphereGeometry(100, 32, 32);
var sphereMat = new THREE.MeshPhongMaterial({
color: 0xfb3550,
flatShading: true
});
var sphereMesh = new THREE.Mesh(sphereGeom, sphereMat);
//cube
var cubeDim = 20;
var cubeGeom = new THREE.BoxGeometry(cubeDim, cubeDim, cubeDim);
var cubeMat = new THREE.MeshPhongMaterial({
color: 0x7cf93e,
flatShading: true
});
cubeMesh = new THREE.Mesh(cubeGeom, cubeMat);
var spherical = new THREE.Spherical();
spherical.set(100 + cubeDim / 2, 0.4, 0);
cubeMesh.position.setFromSpherical(spherical);
var zero = new THREE.Vector3(0, 0, 0);
cubeMesh.lookAt(zero);
scene.add(sphereMesh);
sphereMesh.add(cubeMesh);
initLights();
};
var render = function () {
renderer.render(scene, camera);
};
var animate = function () {
requestAnimationFrame(animate);
controls.update();
render();
};
init();
animate();
button {
position : absolute;
top : 0;
right : 0;
}
.button2 {
position : absolute;
top : 0;
left : 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script>
<button id="reset" class="button2">
reset camera
</button>
<button id="target">
look at target
</button>
i have a Three.js program, whenever i place the pointer over a cube, it gives me it's position. That is fine (that is what i need), but when i place the pointer over the line, my program stops. Could anybody tell me why and how to fix it? I need my program to continue running no matter where my pointer is.
When i place the pointer over the white line, i get the following error:
Uncaught TypeError: Cannot read property 'getHex' of undefined.
Code:
var container, stats;
var scene, camera, renderer, raycaster;
var cube;
var clock = new THREE.Clock();
var mouse = new THREE.Vector2(), INTERSECTED;
var radius = 100, theta = 0;
var composer;
initScene();
//Let's add a cube
var geometry = new THREE.BoxGeometry( 20, 20, 20 );
cube = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({
color : Math.random() * 0xffffff
}));
cube.position.set(0,20,50)
scene.add( cube );
//Let's add another cube
var geometry2 = new THREE.BoxGeometry( 20, 20, 20 );
var cube2 = new THREE.Mesh(geometry2, new THREE.MeshLambertMaterial({
color : Math.random() * 0xffffff
}));
cube2.position.set(200,20,50)
scene.add( cube2 );
//Let's add a line
var material = new THREE.LineBasicMaterial({
color: 0xffffff
});
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0, 20, 50));
geometry.vertices.push(new THREE.Vector3(200, 20, 50));
var line = new THREE.Line(geometry, material);
scene.add(line);
animate();
function initScene() {
container = document.createElement('div');
document.body.appendChild(container);
var fov = 70;
var aspect = window.innerWidth / window.innerHeight;
var near = 1;
var far = 10000;
var zpos = 300;
// Initialize camera
GlobalCamera(fov, aspect, near, far, zpos);
scene = new THREE.Scene();
// Set camera controls
cameraControls2();
// renderer controls
rendererControls2();
}
function GlobalCamera(fov, aspect, near, far, zpos) {
camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.z = zpos;
}
function cameraControls2() {
controls = new THREE.FlyControls(camera);
controls.movementSpeed = 2500;
controls.domElement = container;
controls.rollSpeed = Math.PI / 6;
controls.autoForward = false;
controls.dragToLook = false
}
function rendererControls2() {
renderer = new THREE.WebGLRenderer({
antialias : true,
alpha : true
});
renderer.setClearColor(0xf0f0f0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.sortObjects = false;
container.appendChild(renderer.domElement);
renderer.gammaInput = true;
renderer.gammaOutput = true;
}
function findIntersection() {
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
if (INTERSECTED != intersects[0].object) {
if (INTERSECTED)
INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
INTERSECTED = intersects[0].object;
INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
INTERSECTED.material.emissive.setHex(0xff0000);
console.log(INTERSECTED.position);
}
} else {
if (INTERSECTED)
INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
INTERSECTED = null;
}
}
function onDocumentMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
function preAnimate(){
raycaster = new THREE.Raycaster();
// events
document.addEventListener('mousemove', onDocumentMouseMove, false);
}
function animate() {
preAnimate();
requestAnimationFrame(animate);
render();
}
function render() {
var delta = clock.getDelta();
findIntersection();
controls.update(delta);
renderer.render(scene, camera);
}
This is my first adventure with Three.js, but I think I have tracked down your issue. What happens is that the THREE.LineBasicMaterial does not have the emissive property like the THREE.MeshLambertMaterial does. The property you want to manipulate on the THREE.LineBasicMaterial object is the color property.
Here is a working jsFiddle where I have added some checks on wheter the emissive property is available:
https://jsfiddle.net/thedole/4wkFu/162/ The difference is adding the mentioned checks in the findIntersection method:
function findIntersection() {
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(scene.children),
material;
if (intersects.length > 0) {
if (INTERSECTED != intersects[0].object) {
if (INTERSECTED){
material = INTERSECTED.material;
if(material.emissive){
material.emissive.setHex(INTERSECTED.currentHex);
}
else{
material.color.setHex(INTERSECTED.currentHex);
}
}
INTERSECTED = intersects[0].object;
material = INTERSECTED.material;
if(material.emissive){
INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
material.emissive.setHex(0xff0000);
}
else{
INTERSECTED.currentHex = material.color.getHex();
material.color.setHex(0xff0000);
}
console.log(INTERSECTED.position);
}
} else {
if (INTERSECTED){
material = INTERSECTED.material;
if(material.emissive){
material.emissive.setHex(INTERSECTED.currentHex);
}
else
{
material.color.setHex(INTERSECTED.currentHex);
}
}
INTERSECTED = null;
}
}
The interaction between pointlight and a plane seems to have changed from r.67 to r.68
I'm trying to learn three.js, going through a book that is a year old.
I've stripped down the tutorial example to just a plane, a cube, and a pointlight and The "Shinyness" effect of the light on the plane goes away when i use r.68, which is the point of the light effect tutorial.
I'm guessing it must have something to do with the material reflectivity of planes now?
I didn't get any clues going through three.js github revision notes or history of the function sourcecode or similar current three.js examples, but my three.js rookie status is probably holding me back from knowing what to look for.
If someone could explain what changed and why it's not working I would love to turn this broken tutorial into a learning experience.
EDITED TO ADD FIDDLE EXAMPLES INSTEAD OF SOURCE
Here is r.68:
http://jsfiddle.net/nnu3qnq8/5/
Here is r.67:
http://jsfiddle.net/nnu3qnq8/4/
Code:
$(function () {
var stats = initStats();
// create a scene, that will hold all our elements such as objects, cameras and lights.
var scene = new THREE.Scene();
// create a camera, which defines where we're looking at.
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// create a render and set the size
var renderer = new THREE.WebGLRenderer();
renderer.setClearColorHex(0xEEEEEE, 1.0);
renderer.setSize(window.innerWidth, window.innerHeight);
// create the ground plane
var planeGeometry = new THREE.PlaneGeometry(60, 20, 1, 1);
var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
// rotate and position the plane
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 15
plane.position.y = 0
plane.position.z = 0
// add the plane to the scene
scene.add(plane);
// create a cube
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff7777});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.castShadow = true;
// position the cube
cube.position.x = -4;
cube.position.y = 3;
cube.position.z = 0;
// add the cube to the scene
scene.add(cube);
// position and point the camera to the center of the scene
camera.position.x = -25;
camera.position.y = 30;
camera.position.z = 25;
camera.lookAt(new THREE.Vector3(10, 0, 0));
// add subtle ambient lighting
var ambiColor = "#0c0c0c";
var ambientLight = new THREE.AmbientLight(ambiColor);
scene.add(ambientLight);
// add spotlight for the shadows
// add spotlight for the shadows
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40, 60, -10);
spotLight.castShadow = true;
// scene.add( spotLight );
var pointColor = "#ccffcc";
var pointLight = new THREE.PointLight(pointColor);
pointLight.distance = 100;
pointLight.position = new THREE.Vector3(3, 5, 3);
scene.add(pointLight);
// add the output of the renderer to the html element
$("#WebGL-output").append(renderer.domElement);
// call the render function
var step = 0;
// used to determine the switch point for the light animation
var invert = 1;
var phase = 0;
var controls = new function () {
this.rotationSpeed = 0.03;
this.ambientColor = ambiColor;
this.pointColor = pointColor;
this.intensity = 1;
this.distance = 100;
}
var gui = new dat.GUI();
gui.addColor(controls, 'ambientColor').onChange(function (e) {
ambientLight.color = new THREE.Color(e);
});
gui.addColor(controls, 'pointColor').onChange(function (e) {
pointLight.color = new THREE.Color(e);
});
gui.add(controls, 'intensity', 0, 3).onChange(function (e) {
pointLight.intensity = e;
});
gui.add(controls, 'distance', 0, 100).onChange(function (e) {
pointLight.distance = e;
});
render();
function render() {
stats.update();
// move the light simulation
if (phase > 2 * Math.PI) {
invert = invert * -1;
phase -= 2 * Math.PI;
} else {
phase += controls.rotationSpeed;
}
pointLight.position.z = +(7 * (Math.sin(phase)));
pointLight.position.x = +(14 * (Math.cos(phase)));
if (invert < 0) {
var pivot = 14;
pointLight.position.x = (invert * (pointLight.position.x - pivot)) + pivot;
}
// render using requestAnimationFrame
requestAnimationFrame(render);
renderer.render(scene, camera);
}
function initStats() {
var stats = new Stats();
stats.setMode(0); // 0: fps, 1: ms
// Align top-left
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
$("#Stats-output").append(stats.domElement);
return stats;
}
});
You are using a pattern that is no longer supported.
pointLight.position = new THREE.Vector3( 3, 5, 3 );
Do not create a new object. Instead do this:
pointLight.position.set( 3, 5, 3 );
three.js r.68
I have two objects on my scene: a red line and a sphere.
While camera rotating/zooming/moving, I need to check the following:
Does the line intersects with the sphere looking from the current position of the camera (please see images below)? Please use this JS fiddle that creates the scene on the images.
I know how to find the intersection between the current mouse position and objects on the scene (just like this example shows).
But how to do this in my case?
JS Fiddle Code:
/**
* PREPARE SCENE
*/
var mouse = {
x : 0,
y : 0
};
var projector = new THREE.Projector();
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75,
window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = -5;
camera.position.y = 5;
camera.position.z = 30;
var renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.TrackballControls(camera,
renderer.domElement);
controls.rotateSpeed = 3.0;
controls.zoomSpeed = 1.5;
controls.panSpeed = 1.0;
controls.staticMoving = true;
var grid = new THREE.GridHelper(20, 5);
scene.add(grid);
/**
* CREATE SPHERE
*/
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(5, 10, 10),
new THREE.MeshNormalMaterial());
sphere.overdraw = true;
scene.add(sphere);
/**
* CREATE LINE
*/
var lineMaterial = new THREE.LineBasicMaterial({
color : 0xFF0000
});
var lineGeometry = new THREE.Geometry();
lineGeometry.vertices.push(new THREE.Vector3(8, 8, 8));
lineGeometry.vertices.push(new THREE.Vector3(8, 8, 20));
var line = new THREE.Line(lineGeometry, lineMaterial);
scene.add(line);
renderer.domElement.addEventListener('mousemove', render, false);
render();
function render(event) {
var mouse = {};
/*
* INTERSECTION
*/
if (event != null) {
//intersection job???
}
controls.update();
renderer.render(scene, camera);
}
So, I found the solution that is pretty simple (of course). See new JS Fiddle that checks intersection of the line and sphere and visualizes the ray for debugging.
The JS Fiddle code:
var camera, controls, scene, renderer;
init();
animate();
render();
function init() {
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 800;
controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = 5.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 4;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.addEventListener('change', render);
// world
scene = new THREE.Scene();
sceneTarget = new THREE.Scene();
var grid = new THREE.GridHelper(500, 50);
scene.add(grid);
/**
* CREATE LINE
*/
var lineMaterial = new THREE.LineBasicMaterial({
color : 0xFF0000
});
var lineGeometry = new THREE.Geometry();
lineGeometry.vertices.push(new THREE.Vector3(100, 200, 100));
lineGeometry.vertices.push(new THREE.Vector3(300, 200, 200));
var line = new THREE.Line(lineGeometry, lineMaterial);
sceneTarget.add(line);
/*
* CREARE SPHERE
*/
var sphere = new THREE.Mesh(new THREE.SphereGeometry(150, 100, 100), new THREE.MeshNormalMaterial());
sphere.overdraw = true;
scene.add(sphere);
// renderer
renderer = new THREE.WebGLRenderer({
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.autoClear = false;
renderer.setClearColor(0xffffff, 1);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
}
function render() {
renderer.render(scene, camera);
renderer.render(sceneTarget, camera);
intersect();
}
function intersect() {
var direction = new THREE.Vector3(100, 200, 100);
var startPoint = camera.position.clone();
var directionVector = direction.sub( startPoint );
var ray = new THREE.Raycaster(startPoint, directionVector.clone(). normalize());
scene.updateMatrixWorld(); // required, since you haven't rendered yet
var rayIntersects = ray.intersectObjects(scene.children, true);
if (rayIntersects[0]) {
//inersection is found
console.log(rayIntersects[0]);
//visualize the ray for debugging
var material = new THREE.LineBasicMaterial({
color: 0x0000ff
});
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(ray.ray.origin.x, ray.ray.origin.y, ray.ray.origin.z));
geometry.vertices.push(new THREE.Vector3(100, 200, 100));
var line = new THREE.Line(geometry, material);
sceneTarget.add( line );
}
}