Error with renderer when add DirectionalLight - three.js

Here is my code:
function addLights() {
var ambiColor = "#ffffff";
var ambientLight = new THREE.AmbientLight(ambiColor, 0.5);
ambientLight.wrapAround = true;
scene.add(ambientLight);
var directionalLightColor = new THREE.Color(0xffffff);
var directionalLight = new THREE.DirectionalLight(directionalLightColor);
directionalLight.position.set(300, 80, -2000);
directionalLight.castShadow = true;
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 1300;
directionalLight.shadow.camera.left = -600;
directionalLight.shadow.camera.right = 600;
directionalLight.shadow.camera.top = 600;
directionalLight.shadow.camera.bottom = -600;
directionalLight.distance = 10;
directionalLight.intensity = 14.0;
directionalLight.shadow.mapSize.height = 1024;
directionalLight.shadow.mapSize.width = 1024;
//camera.add(directionalLight);
};
function init() {
createScene();
createRenderer();
addAureole();
addEarthTexture();
addEarthContour();
addEarthPoints();
addClouds();
addConnector();
addWire();
addLights();
};
function animate() {
requestAnimationFrame(animate);
Render();
};
function Render() {
renderer.autoClear = false;
renderer.clear();
renderer.render(backgroundScene , backgroundCamera );
renderer.render(scene, camera);
};
function onResize() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = (window.innerWidth / window.innerHeight);
camera.updateProjectionMatrix();
};
window.addEventListener('resize', onResize, false);
If I add: camera.add(directionalLight);
0.5s i have fine working page with adequately working directional light, and after that I get uncaught TypeError: Cannot read property 'direction' of undefined. And all work fine without directional light. Can anyone tell what went wrong?

Related

Display loaded OBJ model in wireframe mode in three.js

I wanted to display my loaded .obj file in wireframe mode..
I got to know about the WireFrameGeometry But for somereason the .mtl texture only gets display .
Below is the code ..
/* Model */
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setBaseUrl('assets/');
mtlLoader.setPath('assets/');
mtlLoader.load('materialfile.mtl', function(materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('assets/');
objLoader.load('Objectfile.obj', function(object) {
object.traverse(function(child) {
if (child.isMesh) {
var wireframeGeomtry = new THREE.WireframeGeometry(child.geometry);
var wireframeMaterial = new THREE.LineBasicMaterial({
color: 0xffffff
});
var wireframe = new THREE.LineSegments(wireframeGeomtry, wireframeMaterial);
child.add(wireframe);
}
});
scene.add(object);
});
});
I only want the wireframe of the model without any fill..
Thanks in advance.
The entire code is below...
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="three.js"></script>
<script src="TrackballControls.js"></script>
<script src="cannon.js"></script>
<script src="Detector.js"></script>
<script src="OrbitControls.js"></script>
<script src="OBJLoader.js"></script>
<script src="MTLLoader.js"></script>
</head>
<body>
<script>
if (!Detector.webgl) {
Detector.addGetWebGLMessage();
}
var container;
var camera, controls, scene, renderer;
var lighting, ambient, keyLight, fillLight, backLight;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
/* Camera */
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 50;
/* Scene */
scene = new THREE.Scene();
lighting = false;
ambient = new THREE.AmbientLight(0xffffff, 1.0);
scene.add(ambient);
// keyLight = new THREE.DirectionalLight(new THREE.Color('hsl(30, 100%, 75%)'), 1.0);
// keyLight.position.set(-100, 0, 100);
// fillLight = new THREE.DirectionalLight(new THREE.Color('hsl(240, 100%, 75%)'), 0.75);
// fillLight.position.set(100, 0, 100);
// backLight = new THREE.DirectionalLight(0xffffff, 1.0);
// backLight.position.set(100, 0, -100).normalize();
/* Model */
// var mtlLoader = new THREE.MTLLoader();
// mtlLoader.setBaseUrl('assets/');
// mtlLoader.setPath('assets/');
// mtlLoader.load('mtlfile.mtl', function(materials) {
// materials.preload();
// materials.materials.default.map.magFilter = THREE.NearestFilter;
// materials.materials.default.map.minFilter = THREE.LinearFilter;
var objLoader = new THREE.OBJLoader();
// objLoader.setMaterials(materials);
objLoader.setPath('assets/');
objLoader.load('objectfile.obj', function(object) {
object.traverse(function(child) {
if (child.isMesh) {
var wireframeGeomtry = new THREE.WireframeGeometry(child.geometry);
var wireframeMaterial = new THREE.LineBasicMaterial({
color: 0xeeeeee
});
var wireframe = new THREE.LineSegments(wireframeGeomtry, wireframeMaterial);
// add to child so we get same orientation
child.add(wireframe);
// to parent of child. Using attach keeps our orietation
child.parent.attach(wireframe);
// remove child (we don't want child)
child.parent.remove(child);
}
});
scene.add(object);
});
// });
/* Renderer */
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color("hsl(0, 0%, 10%)"));
container.appendChild(renderer.domElement);
/* Controls */
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = true;
controls.autoRotate = true;
/* Events */
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);
controls.update();
render();
}
function render() {
renderer.render(scene, camera);
}
</script>
</body>
</html>
So this is the entire code..
Its just the basic obj loader ..
I don't know whether the problem is in the code or model .
It shows as a fully filled white model
object.traverse(function(child) {
if (child.isMesh) {
child.material.wireframe = true;
}
}
This worked for me
objLoader.load('Objectfile.obj', function(object) {
object.traverse(function(child) {
if (child.isMesh) {
var wireframeGeomtry = new THREE.WireframeGeometry(child.geometry);
var wireframeMaterial = new THREE.LineBasicMaterial({
color: 0xffffff
});
var wireframe = new THREE.LineSegments(wireframeGeomtry, wireframeMaterial);
// add to child so we get same orientation
child.add(wireframe);
// to parent of child. Using attach keeps our orietation
child.parent.attach(wireframe);
// remove child (we don't want child)
child.parent.remove(child);
}
});
scene.add(object);
});
Example:
html, body {
margin: 0;
height: 100%;
}
#c {
width: 100%;
height: 100%;
display: block;
}
<canvas id="c"></canvas>
<script type="module">
import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/build/three.module.js';
import {OrbitControls} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/controls/OrbitControls.js';
import {OBJLoader2} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/loaders/OBJLoader2.js';
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
const fov = 45;
const aspect = 2; // the canvas default
const near = 0.1;
const far = 100;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 10, 20);
const controls = new OrbitControls(camera, canvas);
controls.target.set(0, 5, 0);
controls.update();
const scene = new THREE.Scene();
scene.background = new THREE.Color('black');
{
const objLoader = new OBJLoader2();
objLoader.load('https://threejsfundamentals.org/threejs/resources/models/windmill/windmill.obj', (root) => {
root.traverse(child => {
if (child.isMesh) {
var wireframeGeomtry = new THREE.WireframeGeometry(child.geometry);
var wireframeMaterial = new THREE.LineBasicMaterial({
color: 0xffffff
});
var wireframe = new THREE.LineSegments(wireframeGeomtry, wireframeMaterial);
child.add(wireframe);
child.parent.attach(wireframe);
child.parent.remove(child);
}
});
scene.add(root);
});
}
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render() {
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
main();
</script>
You can also do it the way manthrax suggested except you need to check if child.material is an array or not, then for each material remove the map (so the texture is not used) and set emissive to some color (you might also want to set color to black)`.
html, body {
margin: 0;
height: 100%;
}
#c {
width: 100%;
height: 100%;
display: block;
}
<canvas id="c"></canvas>
<script type="module">
import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/build/three.module.js';
import {OrbitControls} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/controls/OrbitControls.js';
import {OBJLoader2} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/loaders/OBJLoader2.js';
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
const fov = 45;
const aspect = 2; // the canvas default
const near = 0.1;
const far = 100;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 10, 20);
const controls = new OrbitControls(camera, canvas);
controls.target.set(0, 5, 0);
controls.update();
const scene = new THREE.Scene();
scene.background = new THREE.Color('black');
function makeWireframe(material) {
material.wireframe = true;
material.emissive.set('#0FF');
material.map = undefined;
}
{
const objLoader = new OBJLoader2();
objLoader.load('https://threejsfundamentals.org/threejs/resources/models/windmill/windmill.obj', (root) => {
root.traverse(child => {
if (child.isMesh) {
if (Array.isArray(child.material)) {
child.material.forEach(makeWireframe);
} else {
makeWireframe(child.material)
}
}
});
scene.add(root);
});
}
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render() {
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
main();
</script>

Three.js destroy on new page load

I'm helping a friend to set up a Three.js scene on a page in Wordpress that's running on the Lay theme. The theme is using some kind of page transition script that doesn't reload the site when navigating to a different page, creating a new initialization of the Three.js scene each time a new page is injected on the site.
I'm looking for ways to completely remove the whole instance of Three.js when a new page is loaded. So that it gets created from scratch when The Lay theme has this function window.laytheme.on("newpageshown", function(layoutObj, type, obj){} that kind of works as a substitute for window.onload.
I've tried different methods in order to remove everything, but as my Three.js code unfortunately is a mixed result of copy and pasting from different demos and examples, I'm not quite sure what exactly that needs to be destroyed and how to do it. To be honest I'm not entirely sure how the code is setup and I have very little experience with Three.js and it's lifecycle.
Here's the code creating the scene:
(function($) {
var base_url = window.location.origin;
var container, stats;
var camera, scene, renderer, controls, manager, loader, texture;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var $currentModel;
var modelName;
var initialGridPosition;
var initialScale;
window.laytheme.on("newpageshown", function(layoutObj, type, obj){
modelName = $(".modelLink.is-active").data("model-name");
initialScale = $(".modelLink.is-active").data("model-scale");
initialGridPosition = $(".modelLink.is-active").data("model-grid-position");
init();
animate();
});
function init() {
container = document.createElement('div');
container.id = "threejs-container";
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 300;
camera.position.y = 100;
// scene
scene = new THREE.Scene();
var ambientLight = new THREE.AmbientLight(0xffffff, 0.7);
scene.add(ambientLight);
var pointLight = new THREE.PointLight( 0xffffff, 0.3 );
camera.add( pointLight );
scene.add(camera);
// model
var onProgress = function(xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
$("#domLoader").show();
$("#domLoader").text(Math.round(percentComplete, 2) + '%');
}
};
// texture
manager = new THREE.LoadingManager();
manager.onProgress = function(item, loaded, total) {
if (total == loaded) {
$("#domLoader").hide();
$(".col--row").removeClass("is-hidden");
$currentModel = $(".modelLink.is-active");
$("#meta-title").text('stevns_klint_' + $currentModel.data("model-name"));
$("#meta-vertices").text($currentModel.data("model-vertices"));
$("#meta-faces").text($currentModel.data("model-faces"));
$("#meta-coordinates").text($currentModel.data("model-coordinates"));
$("#meta-coordinates-url").attr("href", $currentModel.data("model-coordinates-url"));
$("#meta-date").text($currentModel.data("model-date"));
$("#meta-images").text($currentModel.data("model-images"));
}
console.log(item, loaded, total);
};
texture = new THREE.Texture();
var onProgress = function(xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log(Math.round(percentComplete, 2) + '% downloaded');
$("#domLoader").show();
$("#domLoader").text(Math.round(percentComplete, 2) + '%');
}
};
var onError = function() {};
// Create initial model
loader = new THREE.ImageLoader(manager)
loader.setPath(base_url + '/assets/' + modelName +'/').load('texture.jpg', function(image) {
texture.image = image;
texture.needsUpdate = true;
});
loader = new THREE.OBJLoader(manager);
loader.setPath(base_url + '/assets/' + modelName +'/').load('model.obj', function(object) {
object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.map = texture;
}
if( child.material ) {
child.material.side = THREE.DoubleSide;
}
});
object.scale.x = initialScale;
object.scale.y = initialScale;
object.scale.z = initialScale;
object.name = "mainModel";
scene.add(object);
}, onProgress, onError);
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xffffff, 1);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
var size = 300;
var divisions = 30;
var gridHelper = new THREE.GridHelper( size, divisions, 0x000000, 0x000000 );
scene.add( gridHelper );
gridHelper.position.y = initialGridPosition;
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.screenSpacePanning = true;
controls.minDistance = 150;
controls.maxDistance = 300;
controls.target.set(0, 0, 0);
controls.enableDamping = true;
controls.enablePan = false;
controls.autoRotate = true;
controls.enableKeys = false;
controls.autoRotateSpeed = 0.04;
controls.dampingFactor = 0.07;
controls.rotateSpeed = 0.04;
controls.update();
window.addEventListener('resize', onWindowResize, false);
// Change model on model link click
$(".modelLink").on("click", function(){
$(".modelLink").removeClass("is-active");
$(this).addClass("is-active");
$(".col--row").addClass("is-hidden");
var modelName = $(this).data("model-name");
var modelScale = Number($(this).data("model-scale"));
var modelGridPosition = $(this).data("model-grid-position");
loader = new THREE.ImageLoader(manager)
loader.setPath(base_url + '/assets/' + modelName +'/').load('texture.jpg', function(image) {
texture.image = image;
texture.needsUpdate = true;
});
loader = new THREE.OBJLoader(manager);
loader.setPath(base_url + '/assets/' + modelName + '/').load('model.obj', function(object) {
object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.map = texture;
}
if( child.material ) {
child.material.side = THREE.DoubleSide;
}
});
object.scale.x = modelScale;
object.scale.y = modelScale;
object.scale.z = modelScale;
var selectedObject = scene.getObjectByName("mainModel");
scene.remove( selectedObject );
object.name = "mainModel";
gridHelper.position.y = modelGridPosition;
scene.add(object);
}, onProgress, onError);
})
}
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);
controls.update();
render();
}
function render() {
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
})( jQuery );
There code might be some code in there that's irrelevant and have nothing to do with Three.js. But I would appreciate if someone with more experience in the Three.js structure and lifecycle could help me with reading through the script and tell me what parts of the code related to Three.js that needs to be destroyed and how this would be done.

Three JS: CTM file not loading

Here I tried to load a .ctm file in three JS using CTM Loader. But the CTM file is not getting loaded and the object is not visible in the screen, whereas when I load the js file with geometry properties it gets loaded and the object is visible on the screen. So, when I tried to load a ctm file the object is not visible and when I load a js file with geometry properties the object gets loaded.
I have attached the code below
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var FLOOR = -250;
var container;
var camera, scene, controls;
var renderer;
var mesh;
var textureCube;
var mouseX = 0, mouseY = 0;
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(30, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000);
camera.position.set(185, 40, 170);
controls = new THREE.OrbitControls(camera);
controls.maxPolarAngle = Math.PI / 2;
controls.minDistance = 150;
controls.maxDistance = 500;
scene = new THREE.Scene();
scene.background = textureCube;
var light = new THREE.PointLight(0xffffff, 1);
light.position.set(2, 5, 1);
light.position.multiplyScalar(30);
scene.add(light);
var light = new THREE.PointLight(0xffffff, 0.75);
light.position.set(-12, 4.6, 2.4);
light.position.multiplyScalar(30);
scene.add(light);
scene.add(new THREE.AmbientLight(0x050505));
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
renderer.domElement.style.position = "relative";
container.appendChild(renderer.domElement);
renderer.gammaInput = true;
renderer.gammaOutput = true;
window.addEventListener('resize', onWindowResize, false);
window.addEventListener('mousemove', onDocumentMouseMove, false);
var start = Date.now();
var position = new THREE.Vector3(-105, -78, -30);
var scale = new THREE.Vector3(30, 30, 30);
var loader = new THREE.CTMLoader(true);
// loader.loadParts("models/ctm/camaro/camaro.js", function (geometries, materials) {
loader.load("models/ctm/camaro/camaro.ctm", function (geometries, materials) {
for (var i = 0; i < geometries.length; i++) {
var mesh = new THREE.Mesh(geometries[i], materials[i]);
mesh.name = "camaro car"
mesh.position.copy(position);
mesh.scale.copy(scale);
scene.add(mesh);
}
var end = Date.now();
console.log("load time:", end - start, "ms");
}, { useWorker: true });
}
function onWindowResize(event) {
SCREEN_WIDTH = window.innerWidth;
SCREEN_HEIGHT = window.innerHeight;
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
camera.updateProjectionMatrix();
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX);
mouseY = (event.clientY - windowHalfY);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}

Three.js Cannot find Obj

I am using the file from three.js and used the OBJloader and render with canvas. Except that I cannot find the object even when I scale the object by 1000 and set the camera to 2. The code is as below.
<script src="../mrdoob/build/three.min.js"></script>
<script src="../mrdoob/examples/js/loaders/OBJLoader.js"></script>
<script src="../mrdoob/examples/js/renderers/CanvasRenderer.js"></script>
<script src="../mrdoob/examples/js/renderers/Projector.js"></script>
<script>
var container;
var camera, scene, renderer;
var mouseX = 0, mouseY = 0;
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(45, window.innerWidth / window.innerHeight, 1, 2000);
//camera.position.z = 100;
camera.position.z = 2;
// scene
scene = new THREE.Scene();
var ambient = new THREE.AmbientLight(0x101030);
scene.add(ambient);
var directionalLight = new THREE.DirectionalLight(0xffeedd);
directionalLight.position.set(0, 0, 1);
scene.add(directionalLight);
// texture
var manager = new THREE.LoadingManager();
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
var texture = new THREE.Texture();
var onProgress = function (xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log(Math.round(percentComplete, 2) + '% downloaded');
}
};
var onError = function (xhr) {
alert(xhr);
};
alert("hi");
var loader = new THREE.ImageLoader(manager);
loader.load('../mrdoob/examples/textures/UV_Grid_Sm.jpg', function (image) {
texture.image = image;
texture.needsUpdate = true;
});
// model
alert("hi2");
var loader = new THREE.OBJLoader();
loader.load('../mrdoob/examples/obj/male02/male02.obj', function (object) {
object.scale = new THREE.Vector3(1000, 1000, 1000);
alert(object.position.y);
scene.add(object);
});
//
alert("hi3");
renderer = new THREE.CanvasRenderer();
renderer.setClearColor(0xf0f0f0);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener('mousemove', onDocumentMouseMove, false);
//
window.addEventListener('resize', onWindowResize, false);
alert("hi4");
}
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 onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}
//
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * .05;
camera.position.y += (-mouseY - camera.position.y) * .05;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
</script>
I did an alert on the object and the position turns out to be zero, so I am not sure if the object is correctly loaded. If someone can tell me how to look for the object would be good.
It may cause if the camera located inside your object, then it always see the back faces of your object and ignore it.
Please provide jsfiddle live example.

two collada object colliding

I am trying to use Ray intersect to find out if 2 collada object collide.
But so far no success :(
my code http://jsfiddle.net/XqQzF/
object.updateMatrix();
// ray
var f_vector = new THREE.Vector3( 0, 0, -1 );
var b_vector = new THREE.Vector3( 0, 0, 1 );
var l_vector = new THREE.Vector3( -1, 0, 0 );
var r_vector = new THREE.Vector3( 1, 0, 0 );
everytime i use something its removed from the newest three.js revision.
Can you help me on the way ?
I recently update my three.js examples collection to be compatible with the latest version (v56 at time of writing), and this includes an example of collision detection. Check out http://stemkoski.github.com/Three.js/Collision-Detection.html (see http://stemkoski.github.com/Three.js/#collision-detection for instructions).
The main difference in your case will be choosing a central point of your model as an origin point for the rays, and choosing a set of vertices of your model to use as endpoints for the rays, as rays are what is used for collision detection.
Hope this helps!
#Lee Stemkoski answer is ok, when we doesn't use collada data.
First what I know is that we need min. 2 Mesh objects. So I took all Mesh objects from collada object. I wrote two scripts - first tried colliding 2 collada objects. Second tried to collide collada object with wall(simple Mesh). In both cases script it doesn't recognize colliding 😕. So how i should write it?
At last I tried to detect mouse on collada object. It's not about this topic but it's similar problem so I write it here.
Dae file was generated by SketchUp.
Code for two collada objects:
var container;
var meshs = [];
var camera, scene, renderer, raycaster;
var controls;
var mouse = new THREE.Vector2();
var dae, dae2;
var collidableMeshList = [];
var clock = new THREE.Clock();
var keyboard = new THREEx.KeyboardState();
$(document).ready(function() {
init();
animate();
});
function init() {
container = document.createElement('div');
$('.container').append(container);
camera = new THREE.PerspectiveCamera(45, 500 / 500, 1, 1000);
group = new THREE.Group();
scene = new THREE.Scene();
scene.add(camera);
camera.position.set(10 * 10, 12 * 10, 16 * 10);
camera.lookAt(scene.position);
// Lights
group.add(new THREE.AmbientLight(0x777777));
var light = new THREE.DirectionalLight(0xdfebff, 1.25);
light.position.set(300, 400, 50);
light.position.multiplyScalar(1.3);
light.castShadow = true;
group.add(light);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setClearColor(0xcccccc, 1);
renderer.setSize(500, 500);
container.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load('./sample.dae', loadDae);
function loadDae(collada) {
dae = collada.scene;
dae.scale.x = 0.5;
dae.scale.y = 0.3;
dae.scale.z = 0.3;
dae.updateMatrix();
group.add(dae);
}
var wallGeometry = new THREE.CubeGeometry(10, 10, 20, 1, 1, 1);
var wallMaterial = new THREE.MeshBasicMaterial({
color: 0x8888ff
});
var wireMaterial = new THREE.MeshBasicMaterial({
color: 0x000000,
wireframe: true
});
loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load('./sample.dae', loadDae2);
function loadDae2(collada) {
dae2 = collada.scene;
dae2.scale.x = 0.5;
dae2.scale.y = 0.3;
dae2.scale.z = 0.3;
dae2.updateMatrix();
dae2.position.set(-40, 0, 0);
dae2.traverse(function(child) {
if (child instanceof THREE.Mesh) {
collidableMeshList.push(child);
}
});
group.add(dae2);
}
group.translateX(-20);
scene.add(group);
raycaster = new THREE.Raycaster();
window.addEventListener('resize', onWindowResize, false);
window.addEventListener('mousemove', onDocumentMouseMove, false);
}
function onDocumentMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
function onWindowResize() {
camera.aspect = 500 / 500;
camera.updateProjectionMatrix();
renderer.setSize(500, 500);
}
function update() {
var delta = clock.getDelta();
var moveDistance = 200 * delta;
var rotateAngle = Math.PI / 2 * delta;
if (keyboard.pressed("A"))
dae.rotation.y += rotateAngle;
if (keyboard.pressed("D"))
dae.rotation.y -= rotateAngle;
if (keyboard.pressed("left"))
dae.translateX(-moveDistance);
if (keyboard.pressed("right"))
dae.translateX(moveDistance);
if (keyboard.pressed("up"))
dae.translateZ(-moveDistance);
if (keyboard.pressed("down"))
dae.translateZ(moveDistance);
meshs = [];
if (typeof dae !== 'undefined') {
dae.traverse(function(child) {
if (child instanceof THREE.Mesh) {
meshs.push(child);
}
});
$.each(meshs, function(number_mesh, mesh) {
var originPoint = mesh.position.clone();
for (var vertexIndex = 0; vertexIndex < mesh.geometry.vertices.length; vertexIndex++) {
var localVertex = mesh.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4(mesh.matrix);
var directionVector = globalVertex.sub(mesh.position);
var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize());
var collisionResults = ray.intersectObjects(collidableMeshList);
if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) {
console.log(" Hit ");
}
}
});
}
controls.update();
}
function animate() {
requestAnimationFrame(animate);
render();
update();
}
function render() {
renderer.render(scene, camera);
}
Code for collada + wall(Mesh):
var container;
var meshs = [];
var camera, scene, renderer, raycaster;
var controls;
var mouse = new THREE.Vector2();
var dae;
var collidableMeshList = [];
var clock = new THREE.Clock();
var keyboard = new THREEx.KeyboardState();
$(document).ready(function() {
init();
animate();
});
function init() {
container = document.createElement('div');
$('.container').append(container);
camera = new THREE.PerspectiveCamera(45, 500 / 500, 1, 1000);
group = new THREE.Group();
scene = new THREE.Scene();
scene.add(camera);
camera.position.set(10 * 10, 12 * 10, 16 * 10);
camera.lookAt(scene.position);
// Lights
group.add(new THREE.AmbientLight(0x777777));
var light = new THREE.DirectionalLight(0xdfebff, 1.25);
light.position.set(300, 400, 50);
light.position.multiplyScalar(1.3);
light.castShadow = true;
group.add(light);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setClearColor(0xcccccc, 1);
renderer.setSize(500, 500);
container.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load('./sample.dae', loadDae);
function loadDae(collada) {
dae = collada.scene;
dae.scale.x = 0.5;
dae.scale.y = 0.3;
dae.scale.z = 0.3;
dae.updateMatrix();
group.add(dae);
}
var wallGeometry = new THREE.CubeGeometry(10, 10, 20, 1, 1, 1);
var wallMaterial = new THREE.MeshBasicMaterial({
color: 0x8888ff
});
var wireMaterial = new THREE.MeshBasicMaterial({
color: 0x000000,
wireframe: true
});
var wall = new THREE.Mesh(wallGeometry, wallMaterial);
wall.position.set(-40, 5, -10);
group.add(wall);
collidableMeshList.push(wall);
var wall = new THREE.Mesh(wallGeometry, wireMaterial);
wall.position.set(-40, 5, -10);
group.add(wall);
group.translateX(-20);
scene.add(group);
raycaster = new THREE.Raycaster();
window.addEventListener('resize', onWindowResize, false);
window.addEventListener('mousemove', onDocumentMouseMove, false);
}
function onDocumentMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
function onWindowResize() {
camera.aspect = 500 / 500;
camera.updateProjectionMatrix();
renderer.setSize(500, 500);
}
function update() {
var delta = clock.getDelta();
var moveDistance = 200 * delta;
var rotateAngle = Math.PI / 2 * delta;
if (keyboard.pressed("A"))
dae.rotation.y += rotateAngle;
if (keyboard.pressed("D"))
dae.rotation.y -= rotateAngle;
if (keyboard.pressed("left"))
dae.translateX(-moveDistance);
if (keyboard.pressed("right"))
dae.translateX(moveDistance);
if (keyboard.pressed("up"))
dae.translateZ(-moveDistance);
if (keyboard.pressed("down"))
dae.translateZ(moveDistance);
meshs = [];
if (typeof dae !== 'undefined') {
dae.traverse(function(child) {
if (child instanceof THREE.Mesh) {
meshs.push(child);
}
});
$.each(meshs, function(number_mesh, mesh) {
var originPoint = mesh.position.clone();
for (var vertexIndex = 0; vertexIndex < mesh.geometry.vertices.length; vertexIndex++) {
var localVertex = mesh.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4(mesh.matrix);
var directionVector = globalVertex.sub(mesh.position);
var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize());
var collisionResults = ray.intersectObjects(collidableMeshList);
if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) {
console.log(" Hit ");
}
}
});
}
controls.update();
}
function animate() {
requestAnimationFrame(animate);
render();
update();
}
function render() {
renderer.render(scene, camera);
}
Detect mouse on collada object. Short code version:
var meshs = [],
raycaster,
mouse = new THREE.Vector2();
...
function init() {
...
function loadDae(collada) {
dae = collada.scene;
dae.scale.x = 0.5;
dae.scale.y = 0.3;
dae.scale.z = 0.3;
dae.updateMatrix();
group.add(dae);
dae.traverse(function(child) {
if (child instanceof THREE.Mesh) {
meshs.push(child);
}
});
}
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load('./sample.dae', loadDae);
raycaster = new THREE.Raycaster();
window.addEventListener('mousemove', onDocumentMouseMove, false);
...
}
...
function onDocumentMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
function render() {
raycaster.setFromCamera(mouse, camera);
if (group.children.length === 5) {
var intersects = raycaster.intersectObjects(meshs);
if (intersects.length > 0) {
console.log(" Hit ");
}
}
renderer.render(scene, camera);
}
...
General - yes, it works, but throw errors with some $meshs 😕.
TypeError: undefined is not an object (evaluating 'O')
three.min.js:8304
cthree.min.js:3544
intersectObjectsthree.min.js:3609:144
Why and how to recognize which mesh is correct for intersectObjects and which not?

Resources