Currently trying to wrap images around a cube on three.js and getting the following error 'THREE.MeshFaceMaterial has been removed. Use an Array instead.', from previous searches it looks like the method I'm trying to use might not be available anymore, is there a new method that anyone knows of? I'll attach the code below. Any help would be greatly appreciated. Thanks in advance, Mike.
<script src="js/three.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/ParallaxBarrierEffect.js"></script>
<script>
(function(){var script=document.createElement('script');script.onload=function(){var stats=new Stats();document.body.appendChild(stats.dom);requestAnimationFrame(function loop(){stats.update();requestAnimationFrame(loop)});};script.src='//rawgit.com/mrdoob/stats.js/master/build/stats.min.js';document.head.appendChild(script);})()
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', function ()
{
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
});
//var effect = new THREE.ParallaxBarrierEffect(renderer);
//effect.setSize(window.innerWidth, window.innerHeight);
controls = new THREE.OrbitControls(camera, renderer.domElement)
/* var loader = new THREE.ObjectLoader();
loader.load
(
'models/skull.json',
function(object)
{
scene.add(object);
}
);
*/
var geometry = new THREE.CubeGeometry(10000,10000,10000);
var cubeMaterials =
[
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/right.png'), side: THREE.DoubleSide}), // RIGHT SIDE
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/left.png'), side: THREE.DoubleSide}), // LEFT SIDE
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/top.png'), side: THREE.DoubleSide}), // TOP SIDE
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/bottom.png'), side: THREE.DoubleSide}), // BOTTOM SIDE
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/front.png'), side: THREE.DoubleSide}), // FRONT SIDE
new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('skybox/back.png'), side: THREE.DoubleSide}) // BACK SIDE
];
var cubeMaterial = new THREE.MeshFaceMaterial(cubeMaterials);
var cube = new THREE.Mesh(geometry, cubeMaterial);
scene.add(cube);
camera.position.z = 3;
var ambientLight = new THREE.AmbientLight(0xFFFFFF, 0.3);
scene.add(ambientLight);
var light1 = new THREE.PointLight(0xFF0040, 4, 5);
//scene.add(light1);
var light2 = new THREE.PointLight(0x0040FF, 2, 5);
//scene.add(light2);
var light3 = new THREE.PointLight(0x80FF80, 4, 5);
//scene.add(light3);
var directionalLight = new THREE.DirectionalLight(0xFFFFFF, 1);
directionalLight.position.set(0,1,0);
//scene.add(directionalLight);
var spotLight = new THREE.SpotLight(0xFF45F6, 200);
spotLight.position.set(0,3,3);
//scene.add(spotLight);
var update = function()
{
//cube.rotation.x += 0.01;
//cube.rotation.z += 0.005;
var time = Date.now() * 0.0005;
light1.position.x = Math.sin(time + 0.7) * 30;
light1.position.x = Math.cos(time + 0.5) * 40;
light1.position.x = Math.cos(time + 0.3) * 30;
light2.position.x = Math.cos(time + 0.3) * 30;
light2.position.x = Math.sin(time + 0.5) * 40;
light2.position.x = Math.sin(time + 0.7) * 30;
light3.position.x = Math.sin(time + 0.7) * 30;
light3.position.x = Math.cos(time + 0.3) * 40;
light3.position.x = Math.sin(time + 0.5) * 30;
};
var render = function()
{
renderer.render(scene, camera);
};
var GameLoop = function()
{
requestAnimationFrame(GameLoop);
update();
render();
};
GameLoop();
</script>
You can change the THREE.MeshFaceMaterial(cubeMaterials)for THREE.MeshBasicMaterial(cubeMaterials) if you are trying to create a skybox. However be aware that your perspective camera are rendering until 1000 and your box has 10000 units, so you will have to change your camera variable if you want to see the sky box.
Related
This is based off a codepen that I am working on and I simplified the code to work with the specific part I need. I haven't worked with applyMatrix and Matrix4 before. For some reason the info from the part using these functions are showing up in my console and causing my browser to crash. I don't completely understand what is going on. I can guess that the values are being reassigned nonstop but I don't see a resolution to it in the codepen even though this issue isn't in it. Here is my code and the link to the codepen for reference.
https://codepen.io/Mamboleoo/pen/Bppdda?editors=0010
This codepen is out of my league and I am trying to get a better grasp of it.
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
renderer.setClearColor(0x000000);
const spotLight = new THREE.SpotLight(0xFFFFFF);
scene.add(spotLight);
spotLight.position.set(0, 0, 100);
spotLight.castShadow = true;
spotLight.angle = 0.2;
spotLight.intensity = 0.2;
camera.position.set(0.27, 0, 500);
//Black center
var geom = new THREE.SphereGeometry(100, 32, 32);
var mat = new THREE.MeshPhongMaterial({
color: 0x000000
});
var core = new THREE.Mesh(geom, mat);
scene.add(core);
var geom = new THREE.SphereBufferGeometry(1, 15, 15);
var mat = new THREE.MeshBasicMaterial({
color: 0xffffff
});
var atoms = new THREE.Object3D();
scene.add(atoms);
for (var i = 0; i < 150; i++) {
var nucleus = new THREE.Mesh(geom, mat);
var size = Math.random() * 6 + 1.5;
nucleus.speedX = (Math.random() - 0.5) * 0.08;
nucleus.speedY = (Math.random() - 0.5) * 0.08;
nucleus.speedZ = (Math.random() - 0.5) * 0.08;
nucleus.applyMatrix(new THREE.Matrix4().makeScale(size, size, size));
nucleus.applyMatrix(new THREE.Matrix4().makeTranslation(0, 100 + Math.random() * 10, 0));
nucleus.applyMatrix(new THREE.Matrix4().makeRotationX(Math.random() * (Math.PI * 2)));
nucleus.applyMatrix(new THREE.Matrix4().makeRotationY(Math.random() * (Math.PI * 2)));
nucleus.applyMatrix(new THREE.Matrix4().makeRotationZ(Math.random() * (Math.PI * 2)));
atoms.add(nucleus);
}
function updateNucleus(a) {
for (var i = 0; i < atoms.children.length; i++) {
var part = atoms.children[i];
part.applyMatrix(new THREE.Matrix4().makeRotationX(part.speedX));
part.applyMatrix(new THREE.Matrix4().makeRotationY(part.speedY));
part.applyMatrix(new THREE.Matrix4().makeRotationZ(part.speedZ));
}
}
//Create scene
var necks = [];
var cubesObject = new THREE.Object3D();
scene.add(cubesObject);
function animate(a) {
requestAnimationFrame( animate );
updateNucleus(a);
renderer.render(scene,camera);
};
animate();
window.addEventListener('resize', function(){
camera.aspect = window.innerWidth / this.window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
})
part.applyMatrix(new THREE.Matrix4().makeRotationX(part.speedX));
The codepen uses an old version of three.js (r79). Since certain parts of the API have been renamed, the browser reports deprecation warnings every frame. With the latest version r138, the new code should look like so:
part.applyMatrix4(new THREE.Matrix4().makeRotationX(part.speedX));
Besides, it's recommended that you don't create instances of Matrix4 and other classes within the animation loop. Create the objects once outside of your loop and reuse them.
const _matrix = new THREE.Matrix4();
function updateNucleus(a) {
for (var i = 0; i < atoms.children.length; i++) {
var part = atoms.children[i];
part.applyMatrix4(_matrix.makeRotationX(part.speedX));
part.applyMatrix4(_matrix.makeRotationY(part.speedY));
part.applyMatrix4(_matrix.makeRotationZ(part.speedZ));
}
}
This question is more about Math, than about threejs but maybe there are usable Alternatives for my issue.
So what I want to do, is to go through every vertice in a Box Geometry and check weither it has to be moved down/up and move it then by a specific value. (it is only about the y-values of each vertice)
var width = 200,
height = 100,
depth = 50;
var roundCornerWidth = var roundCornerHeight = 10;
var helpWidth = width - 2*roundCornerWidth,
helpHeight = height - 2*roundCornerHeight;
var boxGeometry = new THREE.BoxGeometry(width, height, depth, 100, 50, 10);
boxGeometry.vertices.forEach(v => {
if(Math.abs(v.x)>helpWidth/2){
if(Math.abs(v.y)>helpHeight/2){
let helper = Math.abs(v.x)-helperWidth/2;
v.y = Math.sign(v.y)*(helperHeight + Math.cos(helper/roundWidth * Math.PI/2)*roundHeight);
}
}
});
The code above creates corners like you can see on the example image. Those aren't kind of beautiful! :( Another "function" than cos() is needed.
I've used a method without trigonometrical functions, as we can manipulate with vectors:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(50, 50, 150);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var radius = 10;
var width = 200,
height = 100;
var geometry = new THREE.BoxGeometry(width, height, 50, 100, 50, 10);
var v1 = new THREE.Vector3();
var w1 = (width - (radius * 2)) * 0.5,
h1 = (height - (radius * 2)) * 0.5;
var vTemp = new THREE.Vector3(),
vSign = new THREE.Vector3(),
vRad = new THREE.Vector3();
geometry.vertices.forEach(v => {
v1.set(w1, h1, v.z);
vTemp.multiplyVectors(v1, vSign.set(Math.sign(v.x), Math.sign(v.y), 1));
vRad.subVectors(v, vTemp);
if (Math.abs(v.x) > v1.x && Math.abs(v.y) > v1.y && vRad.length() > radius) {
vRad.setLength(radius).add(vTemp);
v.copy(vRad);
}
});
var mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
color: "aqua",
wireframe: true
}));
scene.add(mesh);
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/90/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
Disadvantage: you can't control the smoothness of the roundness without increasing the amount of width or height or depth segments.
EDIT: copied surrounding Code Blocks from prisoner849 to make result visbile for everyone.
I wanted to stay with the box Geometry, because I also deform the Geometry on the z-axis, so this is my solution:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(50, 50, 150);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var width = 200,
height = 100,
depth = 50;
var roundCornerWidth = roundCornerHeight = 10;
var helpWidth = width - 2*roundCornerWidth,
helpHeight = height - 2*roundCornerHeight;
var boxGeometry = new THREE.BoxGeometry(width, height, depth, 100, 50, 10);
boxGeometry.vertices.forEach(v => {
if(Math.abs(v.x)>helpWidth/2){
if(Math.abs(v.y)>helpHeight/2){
let helperX = Math.abs(v.x)-helpWidth/2;
let helperY2 = (Math.abs(v.y)-helpHeight/2)/roundCornerHeight;
let helperY = (1-helperX/roundCornerWidth) * roundCornerHeight * helperY2;
v.y = Math.sign(v.y)*((helpHeight/2 + helperY)+(Math.sin(helperX/roundCornerWidth * Math.PI)*(roundCornerHeight/4))*helperY2);
v.x = Math.sign(v.x)*(Math.abs(v.x)+(Math.sin(helperX/roundCornerWidth * Math.PI)*(roundCornerWidth/4))*helperY2);
}
}
});
var mesh = new THREE.Mesh(boxGeometry, new THREE.MeshBasicMaterial({
color: 0xffce00,
wireframe: true
}));
scene.add(mesh);
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/90/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
This worked for me perfectly and seems to be the simplest solution for my issue.
I have a working animation, just not the way I would like.
I would like the object to rotate 90 degrees with a delay (works) then continue to rotate 90 degrees, ultimately looping forever. No matter what I do, it always resets. Even if I set up 4 tweens taking me to 360, the last tween that resets back zero makes the whole object spin in the opposite direction.
Thanks
var width = 1000;
var height = 600;
var scene = new THREE.Scene();
var group = new THREE.Object3D(); //create an empty container
var camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, -500, 1000);
camera.position.x = 180;
camera.position.y = 180;
camera.position.z = 200;
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.setClearColor(0xf0f0f0);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BoxGeometry(300, 300, 300);
var material = new THREE.MeshLambertMaterial({
color: 0xffffff,
shading: THREE.SmoothShading,
overdraw: 0.5
});
var cube = new THREE.Mesh(geometry, material);
group.add(cube);
var canvas1 = document.createElement('canvas');
canvas1.width = 1000;
canvas1.height = 1000;
var context1 = canvas1.getContext('2d');
context1.font = "Bold 20px Helvetica";
context1.fillStyle = "rgba(0,0,0,0.95)";
context1.fillText('Text bit', 500, 500);
// canvas contents will be used for a texture
var texture1 = new THREE.Texture(canvas1)
texture1.needsUpdate = true;
var material1 = new THREE.MeshBasicMaterial({
map: texture1,
side: THREE.DoubleSide
});
material1.transparent = true;
var mesh1 = new THREE.Mesh(
new THREE.PlaneBufferGeometry(2000, 2000),
material1
);
mesh1.position.set(-150, 150, 151);
group.add(mesh1);
directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 0, 0)
scene.add(directionalLight);
directionalLight = new THREE.DirectionalLight(0x888888);
directionalLight.position.set(0, 1, 0)
scene.add(directionalLight);
directionalLight = new THREE.DirectionalLight(0xcccccc);
directionalLight.position.set(0, 0, 1)
scene.add(directionalLight);
scene.add(group)
// with help from https://github.com/tweenjs/tween.js/issues/14
var tween = new TWEEN.Tween(group.rotation).to({ y: -(90 * Math.PI / 180)}, 1000).delay(1000);
tween.onComplete(function() {
group.rotation.y = 0;
});
tween.chain(tween);
tween.start();
camera.lookAt(scene.position);
var render = function() {
requestAnimationFrame(render);
TWEEN.update();
renderer.render(scene, camera);
};
render();
=====EDIT=====
I got it working, not sure if this is the most efficient approach but I'm satisfied:
var start = {}
start.y = 0;
var targ = {};
targ.y = 90*Math.PI/180
function rot(s,t) {
start["y"] = s;
targ["y"] = t;
}
var cnt1 = 1;
var cnt2 = 2;
rot(0,90*Math.PI/180);
var tween = new TWEEN.Tween(start).to(targ, 1000).delay(1000);
tween.onUpdate(function() {
group.rotation.y = start.y;
})
tween.onComplete(function() {
_c = cnt1++;
_d = cnt2++;
rot((_c*90)*Math.PI/180,(_d*90)*Math.PI/180)
});
tween.chain(tween);
tween.start();
Simple call setTimeout when tween is end
( http://jsfiddle.net/bhpf4zvy/ ):
function tRotate( obj, angles, delay, pause ) {
new TWEEN.Tween(group.rotation)
.delay(pause)
.to( {
x: obj.rotation._x + angles.x,
y: obj.rotation._y + angles.y,
z: obj.rotation._z + angles.z
}, delay )
.onComplete(function() {
setTimeout( tRotate, pause, obj, angles, delay, pause );
})
.start();
}
tRotate(group, {x:0,y:-Math.PI/2,z:0}, 1000, 500 );
Upd: pfff, what nonsense am I??? Simple use relative animation (http://jsfiddle.net/vv06u6rs/7/):
var tween = new TWEEN.Tween(group.rotation)
.to({ y: "-" + Math.PI/2}, 1000) // relative animation
.delay(1000)
.onComplete(function() {
// Check that the full 360 degrees of rotation,
// and calculate the remainder of the division to avoid overflow.
if (Math.abs(group.rotation.y)>=2*Math.PI) {
group.rotation.y = group.rotation.y % (2*Math.PI);
}
})
.start();
tween.repeat(Infinity)
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 );
}
}