I am working with ThreeJS to create a solar system. I have a sun in the middle and 8 orbits around it. Now I want to get the nearest ring poisiton when the users clicks anywhere on the map!
Here is an image to describe it visually what I mean
The arrows stands for the "click" of the user, then there should be a function to get the nearest orbit and its coordinates (the white dots) where the line between the click point and middle collides.
I tried many different functions I found here, but non of them gave me the result I want.
Thanks for your help!
The code looks currently like this:
var container, stats, parent, pivots, domEvents, twins, planets, sun, fleets, raycaster, mouse;
var camera, controls, scene, renderer;
var cross;
planets = new Array();
init();
animate();
function init()
{
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
//init
camera = new THREE.PerspectiveCamera(10, 1, 1, 4000);
camera.position.z = 200;
camera.position.x = 200;
camera.position.y = 200;
controls = new THREE.OrbitControls(camera);
controls.addEventListener('change', render);
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x000000, 0);
// renderer
renderer = new THREE.WebGLRenderer({antialias: false, alpha: true});
renderer.setSize(document.getElementById('canvasreference').offsetWidth, document.getElementById('canvasreference').offsetWidth);
renderer.setClearColor(0x787878, 0.5); // the default
container = document.getElementById('canvasreference');
container.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize, false);
domEvents = new THREEx.DomEvents(camera, renderer.domElement);
//axihelper
scene.add(new THREE.AxisHelper(130));
// parent
parent = new THREE.Object3D();
scene.add(parent);
//arrays
orbits = new Array();
addOrbit();
window.addEventListener('click', onMouseMove, false);
}
function onMouseMove(event) {
canvas = renderer.domElement;
raycaster = new THREE.Raycaster();
mousePosition = new THREE.Vector2();
canvasPosition = $("#canvasreference canvas").position();
console.log(canvasPosition);
mousePosition.x = ((event.clientX - canvasPosition.left) / canvas.width) * 2 - 1;
mousePosition.y = -((event.clientY - canvasPosition.top) / canvas.height) * 2 + 1;
raycaster.setFromCamera(mousePosition, camera);
var geometry = new THREE.Geometry();
var origin = new THREE.Vector3(raycaster.ray.origin.x, 0, raycaster.ray.origin.y);
geometry.vertices.push(origin);
var vektor = new THREE.Vector3(raycaster.ray.direction.x, 0, raycaster.ray.direction.y);
for (var i = 0; i < 1000; i++)
{
origin.add(vektor);
geometry.vertices.push(vektor);
}
var material = new THREE.LineBasicMaterial({
color: 0xffffff, linewidth: 20
});
var line = new THREE.Line(geometry, material);
scene.add(line);
renderer.render(scene, camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(600, 600);
render();
}
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
function render() {
renderer.render(scene, camera);
}
/**
* add Orbit line
* #param {type} orbit
* #returns {undefined}
*/
function addOrbit(orbit)
{
for (var i = 0; i < 8; i++)
{
//make orbit line
var orbit = new THREE.EllipseCurve(
0, 0, // ax, aY
i * 10 + 30, i * 10 + 30, // xRadius, yRadius
0, 2 * Math.PI, // aStartAngle, aEndAngle
false, // aClockwise
0 // aRotation
);
var path = new THREE.Path(orbit.getPoints(100));
var geometry = path.createPointsGeometry(100);
var material = new THREE.LineBasicMaterial({color: 0xffffff});
var ellipse = new THREE.Line(geometry, material);
ellipse.rotation.x = 1.5708;
scene.add(ellipse);
}
}
</script>
Cast a ray from your camera to a point where your mouse is. Then check closest distance from that ray to the middle of you solar system using distanceToPoint function. The length of output vector will be the radius of a sphere to which your ray is tangent. Using this length you can determine how close you are to a sphere that is an orbit and if it should be selected. Here's some pseudo code of that check:
var length = getDistanceToCenter(...);
var closestSphere = _(orbits).min(function(orbit) { return Math.abs(length - orbit.radius); });
if (Math.abs(closestSphere.radius - length) < EPSILON) {
selectOrbit(closestSphere);
}
Related
I am trying to create spheres and assign them a random color at the vertices of the rectangle (It can be other geometrical from like triangles or hexagons and so forth, for simplicity in this example I want to use a rectangle). http://jsfiddle.net/ElmerCC/ja6zL0k1/
let scene, camera, renderer;
let controls;
let widthWindow = window.innerWidth;
let heightWindow = window.innerHeight;
let aspect = widthWindow / heightWindow;
let mouse = new THREE.Vector2();
let raycaster = new THREE.Raycaster();
let intersect;
let elements = [];
let elementsNew = [];
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 10000);
camera.up.set(0, 0, 1);
camera.position.set(-500, -500, 400);
scene.add(camera);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(widthWindow, heightWindow);
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
let p = [];
p[0] = new THREE.Vector3(-100, -100, 0);
p[1] = new THREE.Vector3(100, -100, 0);
p[2] = new THREE.Vector3(100, 100, 0);
p[3] = new THREE.Vector3(-100, 100, 0);
//dibujar los nodos
for (let cont = 0; cont < 4; cont++) {
let obj = drawJoint(p[cont], 10, 0x666666, 0, true);
elements.push(obj);
scene.add(obj);
}
var geometry = new THREE.PlaneGeometry(200, 200);
var material = new THREE.MeshBasicMaterial({
color: 0x666666,
side: THREE.DoubleSide
});
var plane = new THREE.Mesh(geometry, material);
scene.add(plane);
//document.addEventListener("mousemove", moveMouse);
document.addEventListener("mousedown", downMouse);
}
function downMouse(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
let intersected = raycaster.intersectObjects(elements);
if (intersected.length > 0) {
intersect = intersected[0].object;
let center = intersect.position;
let n = drawJoint(center, 15, Math.random() * 0xffffff, 1, true);
elementsNew.push(n);
scene.add(n);
}
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
controls.update();
renderer.render(scene, camera);
}
function drawJoint(
JtCenter,
JtRadius,
Jtcolor,
JtOpacity,
JtTransparency
) {
let JtMaterial = new THREE.MeshBasicMaterial({
color: Jtcolor,
opacity: JtOpacity,
transparent: JtTransparency
});
let JtGeom = new THREE.SphereGeometry(JtRadius, 10, 10);
let Joint = new THREE.Mesh(JtGeom, JtMaterial);
JtGeom .computeBoundingSphere();
Joint.position.copy(JtCenter);
return Joint;
}
How can I detect the intersection of two sphere objects to avoid overlapping one another?
Spheres are the easiest objects for which you can test intersection.
Note that a Sphere is a mathematical representation, and is different than a Mesh with sphere geometry. (You can still get the mathematical bounding sphere of a Mesh with the boundingSphere property.)
Here is how you'd check if two spheres touch/intersect (you can send this function two boundingSphere properties to check other non-sphere objects).
function spheresIntersect(sphere1, sphere1position, sphere2, sphere2position){
return sphere1position.distanceTo(sphere2position) <= (sphere1.radius + sphere2.radius)
}
I have to generate a huge number of objects that I can drag individually. Also these objects are limited to a plane form (e.g. rect or circle).
At first I worked with simple CircleGeometries, that are placed inside another geometrie (plane). Also dragging them is very easy but as expected the performance is very very poor for about 200000 of them.
I then decided to use points /particleSystem. The positioning inside a plane works very well but I can't get it managed to make the individual points of the particle system draggable. I found the interactive particles example in the threejs documentation but still have no clou, how to combine them with dragcontrols.
This is my code for creating the particle system and fill a plane with these points:
//Create a plane geometrie, that is later filled with points
var geometry2 = new THREE.CircleGeometry(30,32);
var material2 = new THREE.MeshBasicMaterial( {color: 0x666666, side: THREE.DoubleSide, wireframe:true} );
var mat1 = new THREE.MeshBasicMaterial( {color: 0x00ff00, wireframe:false} );
var plane1 = new THREE.Mesh(geometry2, material2);
geometries.push(plane1); //push to object for draggable elements
scene.add(plane1);
var positionsX;
positionsX = inGeometry.inGeometry(plane1.geometry, 200000); // get positions for points inside plane1
var geometry = new THREE.Geometry();
for (var i = 0; i < positionsX.length; i++) {
geometry.vertices.push(positionsX[i]); //add positions to vertices
}
console.log(geometry);
//Create Particle system
var material = new THREE.PointsMaterial({ size:0.02, color: 0xffffff });
particleSystem = new THREE.Points(geometry, material);
scene.add(particleSystem);
console.log(particleSystem);
var dragGeo = new DragControls(geometries, camera, container); //dragging
Can anybody please help?
Thanks
Just a rough example of how you can drag points:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(1.25, 7, 7);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.PlaneBufferGeometry(10, 10, 10, 10);
geometry.rotateX(-Math.PI * 0.5);
var plane = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
wireframe: true,
color: "red"
}));
scene.add(plane);
var points = new THREE.Points(geometry, new THREE.PointsMaterial({
size: 0.25,
color: "yellow"
}));
scene.add(points);
var raycaster = new THREE.Raycaster();
raycaster.params.Points.threshold = 0.25;
var mouse = new THREE.Vector2();
var intersects = null;
var plane = new THREE.Plane();
var planeNormal = new THREE.Vector3();
var currentIndex = null;
var planePoint = new THREE.Vector3();
var dragging = false;
window.addEventListener("mousedown", mouseDown, false);
window.addEventListener("mousemove", mouseMove, false);
window.addEventListener("mouseup", mouseUp, false);
function mouseDown(event) {
setRaycaster(event);
getIndex();
dragging = true;
}
function mouseMove(event) {
if (dragging && currentIndex !== null) {
setRaycaster(event);
raycaster.ray.intersectPlane(plane, planePoint);
geometry.attributes.position.setXYZ(currentIndex, planePoint.x, planePoint.y, planePoint.z);
geometry.attributes.position.needsUpdate = true;
}
}
function mouseUp(event) {
dragging = false;
currentIndex = null;
}
function getIndex() {
intersects = raycaster.intersectObject(points);
if (intersects.length === 0) {
currentIndex = null;
return;
}
currentIndex = intersects[0].index;
setPlane(intersects[0].point);
}
function setPlane(point) {
planeNormal.subVectors(camera.position, point).normalize();
plane.setFromNormalAndCoplanarPoint(planeNormal, point);
}
function setRaycaster(event) {
getMouse(event);
raycaster.setFromCamera(mouse, camera);
}
function getMouse(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.min.js"></script>
Ok I understand it seems I did not try hard enough but I am really new to this
and I get no errors what so ever in Dreamweaver.
I deleted my old example and this is what I have now, trying to integrate
the look at function with the OBJ loader, camera and lights.
I think I understand what is happening more or less in the code,
but it's still not working, I assume it's because there is a code for
window resize but the look at function dose not take that into account,
thus it's not working since the function assume a fixed window size,
Am I right here?
Also I am not sure I need the two commented lines in the obj loader
object.rotateX(Math.PI / 2); and object.lookAt(new THREE.Vector3(0, 0, 0));
since this is just to get the starting position?
if I put these tow lines back, it will just rotate the object into an initial pose but the object will not turn relative to mouse position.
I am really not sure what is conflicting here
I changed the code now to this:
<script>
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var camera, scene;
var canvasRenderer, webglRenderer;
var container, mesh, geometry, plane;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1500);
camera.position.x = 0;
camera.position.z = 100;
camera.position.y = 0;
camera.lookAt({
x: 0,
y: 0,
z: 0,
});
scene = new THREE.Scene();
// LIGHTS
scene.add(new THREE.AmbientLight(0x666666, 0.23));
var light;
light = new THREE.DirectionalLight(0xffc1c1, 2.20);
light.position.set(0, 100, 0);
light.position.multiplyScalar(1.2);
light.castShadow = true;
light.shadowCameraVisible = true;
light.shadowMapWidth = 512;
light.shadowMapHeight = 512;
var d = 50000;
light.shadowCameraLeft = -d;
light.shadowCameraRight = d;
light.shadowCameraTop = d;
light.shadowCameraBottom = -d;
light.shadowcameranear = 0.5;
light.shadowCameraFar = 1000;
//light.shadowcamerafov = 30;
light.shadowDarkness = 0.1;
scene.add(light);
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( 'model/' );
mtlLoader.load( 'rope.mtl', function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( 'model/' );
objLoader.load( 'rope.obj', function ( object ) {
var positionX = 0;
var positionY = 0;
var positionZ = 0;
object.position.x = positionX;
object.position.y = positionY;
object.position.z = positionZ;
object.scale.x = 1;
object.scale.y = 1;
object.scale.z = 1;
//object.rotateX(Math.PI / 2);
//object.lookAt(new THREE.Vector3(0, 0, 0));
// castshow setting for object loaded by THREE.OBJLoader()
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.castShadow = true;
child.receiveShadow = true;
}
});
scene.add(object);
});
});
// RENDERER
//webglRenderer = new THREE.WebGLRenderer();
webglRenderer = new THREE.WebGLRenderer({
antialias: true
});
webglRenderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
webglRenderer.domElement.style.position = "relative";
webglRenderer.shadowMapEnabled = true;
webglRenderer.shadowMapSoft = true;
//webglRenderer.antialias: true;
container.appendChild(webglRenderer.domElement);
window.addEventListener('resize', onWindowResize, false);
}
window.addEventListener("mousemove", onmousemove, false);
var plane = new THREE.Plane(new THREE.Vector3(0, 0, 0), 0);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersectPoint = new THREE.Vector3();
function onmousemove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
raycaster.ray.intersectPlane(plane, intersectPoint);
object.lookAt(intersectPoint);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
webglRenderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.lookAt(scene.position);
webglRenderer.render(scene, camera);
}
</script>
I took your code and adapted so it doesn't require a obj and put it into this codepen. The main problem seems to be that your intersection plane was defined incorrectly. The first argument is the normal vector which needs to be of length 1. Yours is 0. Therefore there are no meaningful intersections.
var plane = new THREE.Plane(new THREE.Vector3(0, 0, 0), 0);
If you change it to
var plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 10);
the intersections are more meaningful and the object actually rotates.
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