Three.js polygon/polyhedron name or title - javascript

Here is a sample code of my page. I want to get name of object, when user clicks it. And it works well with cube or sphere, but fails with polygon.
You may watch console logs to see clicks responds.
What should I do to get polygon name on click?
<html>
<head>
<title>Моё 3</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<div id="ThreeJS" style="position: absolute; left:0px; top:0px"></div>
<script src="http://stemkoski.github.io/Three.js/js/Three.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/Detector.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/Stats.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/OrbitControls.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/THREEx.KeyboardState.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/THREEx.FullScreen.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/THREEx.WindowResize.js"></script>
<script>
/*
Three.js "tutorials by example"
Author: Lee Stemkoski
Date: July 2013 (three.js v59dev)
*/
// MAIN
var polyhedronShape, polyhedronPts = [], cube, mesh;
// standard global variables
var container, scene, camera, renderer, controls, stats;
var keyboard = new THREEx.KeyboardState();
var clock = new THREE.Clock();
// custom global variables
var targetList = [];
var projector, mouse = { x: 0, y: 0 };
init();
animate();
// FUNCTIONS
function init()
{
// SCENE
scene = new THREE.Scene();
// CAMERA
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
scene.add(camera);
camera.position.set(0,150,400);
camera.lookAt(scene.position);
// RENDERER
if ( Detector.webgl )
renderer = new THREE.WebGLRenderer( {antialias:true} );
else
renderer = new THREE.CanvasRenderer();
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
container = document.getElementById( 'ThreeJS' );
container.appendChild( renderer.domElement );
// EVENTS
THREEx.WindowResize(renderer, camera);
THREEx.FullScreen.bindKey({ charCode : 'm'.charCodeAt(0) });
// CONTROLS
controls = new THREE.OrbitControls( camera, renderer.domElement );
// STATS
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.bottom = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
// LIGHT
var light = new THREE.PointLight(0xffffff);
light.position.set(0,250,0);
scene.add(light);
// FLOOR
var floorTexture = new THREE.ImageUtils.loadTexture( 'images/checkerboard.jpg' );
floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
floorTexture.repeat.set( 10, 10 );
var floorMaterial = new THREE.MeshBasicMaterial( { map: floorTexture, side: THREE.DoubleSide } );
var floorGeometry = new THREE.PlaneGeometry(1000, 1000, 10, 10);
var floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.position.y = -0.5;
floor.rotation.x = Math.PI / 2;
scene.add(floor);
// SKYBOX/FOG
var skyBoxGeometry = new THREE.CubeGeometry( 10000, 10000, 10000 );
var skyBoxMaterial = new THREE.MeshBasicMaterial( { color: 0x9999ff, side: THREE.BackSide } );
var skyBox = new THREE.Mesh( skyBoxGeometry, skyBoxMaterial );
scene.add(skyBox);
////////////
// CUSTOM //
////////////
//////////////////////////////////////////////////////////////////////
// this material causes a mesh to use colors assigned to faces
var faceColorMaterial = new THREE.MeshBasicMaterial(
{ color: 0xffffff, vertexColors: THREE.FaceColors } );
var sphereGeometry = new THREE.SphereGeometry( 80, 32, 16 );
for ( var i = 0; i < sphereGeometry.faces.length; i++ )
{
face = sphereGeometry.faces[ i ];
face.color.setRGB( 0, 0, 0.8 * Math.random() + 0.2 );
}
var sphere = new THREE.Mesh( sphereGeometry, faceColorMaterial );
sphere.name = "Sphere";
sphere.title = "Magic sphere";
sphere.position.set(0, 50, 0);
scene.add(sphere);
targetList.push(sphere);
// Create an array of materials to be used in a cube, one for each side
var cubeMaterialArray = [];
// order to add materials: x+,x-,y+,y-,z+,z-
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0xff3333 } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0xff8800 } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0xffff33 } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0x33ff33 } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0x3333ff } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0x8833ff } ) );
var cubeMaterials = new THREE.MeshFaceMaterial( cubeMaterialArray );
// Cube parameters: width (x), height (y), depth (z),
// (optional) segments along x, segments along y, segments along z
var cubeGeometry = new THREE.CubeGeometry( 100, 100, 100, 1, 1, 1 );
// using THREE.MeshFaceMaterial() in the constructor below
// causes the mesh to use the materials stored in the geometry
cube = new THREE.Mesh( cubeGeometry, cubeMaterials );
cube.name = "Cube";
cube.title = "Cube to do";
cube.position.set(-100, 50, -50);
scene.add( cube );
targetList.push(cube);
// polyhedron
polyhedronPts.push( new THREE.Vector2 ( -100, 600 ) );
polyhedronPts.push( new THREE.Vector2 ( 300, 600 ) );
polyhedronPts.push( new THREE.Vector2 ( 600, -100 ) );
polyhedronShape = new THREE.Shape( polyhedronPts );
var extrudeSettings = {amount: 20}; // bevelSegments: 2, steps: 2 , bevelSegments: 5, bevelSize: 8, bevelThickness:5
var geometry = new THREE.ExtrudeGeometry( polyhedronShape, extrudeSettings );
polyhedron = THREE.SceneUtils.createMultiMaterialObject( geometry, [ new THREE.MeshBasicMaterial( { color: 0x00cc00 } ), new THREE.MeshBasicMaterial( { color: 0xff3333, wireframe: true, transparent: true } ) ] );
//geometry.computeVertexNormals();
polyhedron.name = "Polyhedron";
polyhedron.title = "Polyhedron is nice";
polyhedron.position.set( 0, -333, 0 );
//polyhedron.rotation.set( 0, 0, 100 );
//polyhedron.scale.set( 1, 1, 1 );
scene.add(polyhedron);
targetList.push(polyhedron);
//////////////////////////////////////////////////////////////////////
// initialize object to perform world/screen calculations
projector = new THREE.Projector();
// when the mouse moves, call the given function
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function onDocumentMouseDown( event )
{
// the following line would stop any other event handler from firing
// (such as the mouse's TrackballControls)
// event.preventDefault();
//console.log("Click.");
// update the mouse variable
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
// find intersections
// create a Ray with origin at the mouse position
// and direction into the scene (camera direction)
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
// create an array containing all objects in the scene with which the ray intersects
var intersects = ray.intersectObjects( targetList, true );
// if there is one (or more) intersections
if ( intersects.length > 0 )
{
console.log(intersects[0]);
//console.log("Hit # " + toString( intersects[0].point ) );
console.log("Hit # " + intersects[0].object.name);
// change the color of the closest face.
intersects[ 0 ].face.color.setRGB( 0.8 * Math.random() + 0.2, 0, 0 );
intersects[ 0 ].object.geometry.colorsNeedUpdate = true;
}
}
function toString(v) { return "[ " + v.x + ", " + v.y + ", " + v.z + " ]"; }
function animate()
{
requestAnimationFrame( animate );
render();
update();
}
function update()
{
if ( keyboard.pressed("z") )
{
// do something
}
controls.update();
stats.update();
}
function render()
{
renderer.render( scene, camera );
}
</script>
</body>
</html>

The call to THREE.SceneUtils.createMultiMaterialObject() (to create your polyhedron) returns a THREE.Object3D where the call to THREE.Mesh() (to create your sphere and cube) returns a THREE.Mesh. So they are different entities but you treat them the same. If instead you call:
polyhedron = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: 0x00cc00 } ) );
then you can get the name of your polyhedron, since now polyhedron is of type THREE.Mesh()
Otherwise you would have to parse the children of the polyhedron (since it is a THREE.Object3D())

Related

How to reflect an object in itself?

Is it possible that an object reflects in itself?
I like to receive a self reflection on a metallic object.
So basicially, the two rings of the mechanism should be reflected in the lower part.
Thank you very much in advance!
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container;
var loader;
var camera, cameraTarget, controls, scene, renderer;
init();
animate();
function init() {
var previewDiv = document.getElementById("preview");
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 15 );
camera.position.set( 3, 0.15, 3 );
cameraTarget = new THREE.Vector3( 0, -0.25, 0 );
controls = new THREE.OrbitControls( camera );
controls.maxPolarAngle = Math.PI / 2.2;
controls.minDistance = 1;
controls.maxDistance = 8;
controls.noPan = false;
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0xdae1e6, 2, 15 );
// Ground
var plane = new THREE.Mesh(
new THREE.PlaneBufferGeometry( 40, 40 ),
new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } )
);
plane.rotation.x = -Math.PI/2;
plane.position.y = -0.5;
scene.add( plane );
plane.receiveShadow = true;
// feinleinen
var feinleinentexture = THREE.ImageUtils.loadTexture( 'textures/feinleinen.jpg' );
feinleinentexture.anisotropy = 16;
feinleinentexture.wrapS = feinleinentexture.wrapT = THREE.RepeatWrapping;
feinleinentexture.repeat.set( 5, 5 );
var feinleinen = new THREE.MeshPhongMaterial( { color: 0xffffff, map: feinleinentexture } );
// Chrome
var path = "textures/chrome/";
var format = '.jpg';
var urls = [
path + 'px' + format, path + 'nx' + format,
path + 'py' + format, path + 'ny' + format,
path + 'pz' + format, path + 'nz' + format
];
var envMap = THREE.ImageUtils.loadTextureCube( urls, THREE.CubeReflectionMapping );
var chrome = new THREE.MeshPhongMaterial( {
color : 0x151515,
specular : 0xffffff,
shininess : 200,
envMap : envMap,
combine : THREE.MixOperation, // or THREE.AddOperation, THREE.MultiplyOperation
reflectivity : 0.8
} );
// basis
var basisGeometry = new THREE.BoxGeometry(1.8,0.012,3);
var basis = new THREE.Mesh(basisGeometry, feinleinen);
basis.castShadow = false;
basis.receiveShadow = true;
basis.position.set( 0, -0.47, 0 );
scene.add(basis);
// 2 Ring
var loader = new THREE.JSONLoader();
loader.load('/models/2ring.js', function(geo, mat){
var mesh = new THREE.Mesh(geo, chrome);
mesh.position.set( 0.08, - 0.477, -0.2 );
mesh.rotation.set( 0, - Math.PI / 0.67, 0 );
mesh.scale.set( 0.1, 0.1, 0.1 );
mesh.castShadow = true;
mesh.receiveShadow = true;
loadJson(mesh );
});
function loadJson(mesh){
scene.add( mesh );
}
// Lights
scene.add( new THREE.AmbientLight( 0x777777 ) );
addShadowedLight( 1, 1, 1, 0xffffff, 1.35 );
addShadowedLight( 0.5, 1, -1, 0xffffff, 1 );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setClearColor( scene.fog.color );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
renderer.shadowMapCullFace = THREE.CullFaceBack;
previewDiv.appendChild (renderer.domElement);
// resize
window.addEventListener( 'resize', onWindowResize, false );
}
function addShadowedLight( x, y, z, color, intensity ) {
var directionalLight = new THREE.DirectionalLight( color, intensity );
directionalLight.position.set( x, y, z )
scene.add( directionalLight );
directionalLight.castShadow = true;
// directionalLight.shadowCameraVisible = true;
var d = 1;
directionalLight.shadowCameraLeft = -d;
directionalLight.shadowCameraRight = d;
directionalLight.shadowCameraTop = d;
directionalLight.shadowCameraBottom = -d;
directionalLight.shadowCameraNear = 1;
directionalLight.shadowCameraFar = 4;
directionalLight.shadowMapWidth = 2048;
directionalLight.shadowMapHeight = 2048;
directionalLight.shadowBias = -0.005;
directionalLight.shadowDarkness = 0.15;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
camera.lookAt( cameraTarget );
controls.update();
renderer.render( scene, camera );
}
</script>
You want an object to reflect itself when using a three.js renderer.
Environment mapping, which you have implemented, is based on an approximation that the environment being reflected is (infinitely) far away.
Even if you used a CubeCamera for your environment map, as in this example, you would have the same problem.
The solution using three.js is to use a form of raytracing. three.js has a RaytracingRenderer, and a simple demo, but that renderer is currently not highly-supported, nor does it run at real-time frame rates.
three.js r.71

Rotate the mergeometry object at its center in Three.js

I am struggling to find the way to rotate the object at its center. At the moment i am able to rotate the scene, but when i do the rotation, the object goes away from the user. I look into the some the already asked questions in the same line on the forum, but couldn't able to get it work. Below is the part of the html/three.js file i am using /attached you will find the complete working example.Any help is greatly appreciated
<script src="../build/three.min.js"></script>
<script src="js/controls/TrackballControls.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
var container, stats;
var camera, controls, scene, renderer;
var pickingData = [], pickingTexture, pickingScene;
var objects = [];
var highlightBox;
var splitCoord;
var avStdProp;
var mouse = new THREE.Vector2();
var offset = new THREE.Vector3( 10, 10, 10 );
var geom = new THREE.BoxGeometry(0.005, 0.005, 0.005 );
geom.colorsNeedUpdate = true;
init();
animate();
function init() {
container = document.getElementById( "container" );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.x=250;
camera.position.y=300;
camera.position.z=400;
renderer = new THREE.WebGLRenderer( { antialias: true } );
controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 4;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
scene = new THREE.Scene();
pickingScene = new THREE.Scene();
pickingTexture = new THREE.WebGLRenderTarget(800, 800);
pickingTexture.minFilter = THREE.LinearFilter;
pickingTexture.generateMipmaps = false;
scene.add( new THREE.AmbientLight( 0x555555 ) );
var light = new THREE.SpotLight( 0xffffff, 1.5 );
light.position.set( 0, 500, 2000 );
scene.add( light );
var geometry = new THREE.Geometry(),
pickingGeometry = new THREE.Geometry(),
pickingMaterial = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } ),
defaultMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors } );
function applyVertexColors( g, c ) {
g.faces.forEach( function( f ) {
var n = ( f instanceof THREE.Face3 ) ? 3 : 4;
for( var j = 0; j < n; j ++ ) {
f.vertexColors[ j ] = c;
}
} );
}
var color = new THREE.Color();
var matrix = new THREE.Matrix4();
var quaternion = new THREE.Quaternion();
var coord="219_163_189;130_173_179;161_113_231;92_103_176;169_193_180;161_165_187;262_163_166;198_143_155;161_189_155;125_121_107";
splitCoord=coord.split(";");
var coordColr="0_255_255;255_255_0;0_0_255;0_255_0;255_255_0;0_255_0;0_0_255;0_255_255;255_255_0;210_210_45";
var splitCoordColor=coordColr.split(";");
var avgStd="1_0;3_0;0_0;2_0;3_0;2_0;0_0;1_0;3_0;3_0.35";
avStdProp=avgStd.split(";");
for ( var i = 0; i < splitCoord.length; i++ ) {
var position = new THREE.Vector3();
var xyz=splitCoord[i].split("_");
var col=splitCoordColor[i].split("_");
position.x = xyz[0];
position.y = xyz[1];
position.z = xyz[2];
var rotation = new THREE.Euler();
rotation.x = 0
rotation.y = 0;
rotation.z = 0;
var scale = new THREE.Vector3();
scale.x = 200 + 100;
scale.y = 200 + 100;
scale.z = 200 + 100;
quaternion.setFromEuler( rotation, false );
matrix.compose( position, quaternion, scale );
// give the geom's vertices a random color, to be displayed
col[0]=col[0]/255;
col[1]=col[1]/255;
col[2]=col[2]/255;
applyVertexColors(geom, color.setRGB(col[0], col[1], col[2]));
geometry.merge( geom, matrix );
// give the geom's vertices a color corresponding to the "id"
applyVertexColors( geom, color.setHex( i ) );
pickingGeometry.merge( geom, matrix );
pickingData[ i ] = {
position: position,
rotation: rotation,
scale: scale
};
}
var drawnObject = new THREE.Mesh( geometry, defaultMaterial );
scene.add( drawnObject );
pickingScene.add( new THREE.Mesh( pickingGeometry, pickingMaterial ) );
highlightBox = new THREE.Mesh(
new THREE.BoxGeometry( 0.009, 0.009, 0.009 ),
new THREE.MeshLambertMaterial( { color: 0xffffff }
) );
scene.add( highlightBox );
//renderer.setClearColor( 0xffffff );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(800,800);
renderer.sortObjects = false;
container.appendChild( renderer.domElement );
renderer.domElement.addEventListener( 'mousemove', onMouseMove );
}
//
function onMouseMove( e ) {
mouse.x = e.clientX;
mouse.y = e.clientY;
}
function pick() {
//render the picking scene off-screen
renderer.render( pickingScene, camera, pickingTexture );
//create buffer for reading single pixel
var pixelBuffer = new Uint8Array( 4 );
//read the pixel under the mouse from the texture
renderer.readRenderTargetPixels(pickingTexture, mouse.x+window.pageXOffset, pickingTexture.height - (mouse.y+window.pageYOffset), 1, 1, pixelBuffer);
//interpret the pixel as an ID
var id = ( pixelBuffer[0] << 16 ) | ( pixelBuffer[1] << 8 ) | ( pixelBuffer[2]);
var data = pickingData[ id ];
if (data) {
//move our highlightBox so that it surrounds the picked object
if (data.position && data.rotation && data.scale && controls.enabled){
highlightBox.position.copy( data.position );
highlightBox.rotation.copy( data.rotation );
highlightBox.scale.copy( data.scale ).add( offset );
highlightBox.visible = true;
}
}
else {
highlightBox.visible = false;
}
}
function animate() {
requestAnimationFrame( animate );
render();
//stats.update();
}
function render() {
controls.update();
pick();
renderer.render(scene, camera);
}
any help?
You can set your objects geometry to center, so the center of the mesh will then be at position (0,0,0) and it wont "move away" while rotating.
Do it like this:
geometry.center();
var drawnObject = new THREE.Mesh( geometry, defaultMaterial );
scene.add( drawnObject );
Update
Because you want to use picking in an unusual way by saving your geometrys coordinates into an array, centering the geometry doesnt help you. Your question was "Rotate the mergeometry object at its center", but it seems like you want to rotate the camera around your geometrys center.
Calculate the bounding sphere of your geometry and set the controls target to its position:
drawnObject.geometry.computeBoundingSphere();
controls.target = drawnObject.geometry.boundingSphere.center;

Three.js: polyhedron rounded corners (faces)

I've created a polyhedron and it has rounded corners (or even faces - I don't know which explanation is correct). How can I set border-radius?
Is it possible to remove rounding and make usual corners?
Code is below.
<html>
<head
>
<title>Моё 3</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<div id="ThreeJS" style="position: absolute; left:0px; top:0px"></div>
<script src="http://stemkoski.github.io/Three.js/js/Three.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/Detector.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/Stats.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/OrbitControls.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/THREEx.KeyboardState.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/THREEx.FullScreen.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/THREEx.WindowResize.js"></script>
<script>
/*
Three.js "tutorials by example"
Author: Lee Stemkoski
Date: July 2013 (three.js v59dev)
*/
// MAIN
var polyhedronShape, polyhedronPts = [], cube, mesh;
// standard global variables
var container, scene, camera, renderer, controls, stats;
var keyboard = new THREEx.KeyboardState();
var clock = new THREE.Clock();
// custom global variables
var targetList = [];
var projector, mouse = { x: 0, y: 0 };
init();
animate();
// FUNCTIONS
function init()
{
// SCENE
scene = new THREE.Scene();
// CAMERA
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
scene.add(camera);
camera.position.set(0,150,400);
camera.lookAt(scene.position);
// RENDERER
if ( Detector.webgl )
renderer = new THREE.WebGLRenderer( {antialias:true} );
else
renderer = new THREE.CanvasRenderer();
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
container = document.getElementById( 'ThreeJS' );
container.appendChild( renderer.domElement );
// EVENTS
THREEx.WindowResize(renderer, camera);
THREEx.FullScreen.bindKey({ charCode : 'm'.charCodeAt(0) });
// CONTROLS
controls = new THREE.OrbitControls( camera, renderer.domElement );
// STATS
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.bottom = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
// LIGHT
var light = new THREE.PointLight(0xffffff);
light.position.set(0,250,0);
scene.add(light);
// FLOOR
var floorTexture = new THREE.ImageUtils.loadTexture( 'images/checkerboard.jpg' );
floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
floorTexture.repeat.set( 10, 10 );
var floorMaterial = new THREE.MeshBasicMaterial( { map: floorTexture, side: THREE.DoubleSide } );
var floorGeometry = new THREE.PlaneGeometry(1000, 1000, 10, 10);
var floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.position.y = -0.5;
floor.rotation.x = Math.PI / 2;
scene.add(floor);
// SKYBOX/FOG
var skyBoxGeometry = new THREE.CubeGeometry( 10000, 10000, 10000 );
var skyBoxMaterial = new THREE.MeshBasicMaterial( { color: 0x9999ff, side: THREE.BackSide } );
var skyBox = new THREE.Mesh( skyBoxGeometry, skyBoxMaterial );
scene.add(skyBox);
////////////
// CUSTOM //
////////////
//////////////////////////////////////////////////////////////////////
// this material causes a mesh to use colors assigned to faces
var faceColorMaterial = new THREE.MeshBasicMaterial(
{ color: 0xffffff, vertexColors: THREE.FaceColors } );
var sphereGeometry = new THREE.SphereGeometry( 80, 32, 16 );
for ( var i = 0; i < sphereGeometry.faces.length; i++ )
{
face = sphereGeometry.faces[ i ];
face.color.setRGB( 0, 0, 0.8 * Math.random() + 0.2 );
}
var sphere = new THREE.Mesh( sphereGeometry, faceColorMaterial );
sphere.position.set(0, 50, 0);
scene.add(sphere);
targetList.push(sphere);
// Create an array of materials to be used in a cube, one for each side
var cubeMaterialArray = [];
// order to add materials: x+,x-,y+,y-,z+,z-
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0xff3333 } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0xff8800 } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0xffff33 } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0x33ff33 } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0x3333ff } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0x8833ff } ) );
var cubeMaterials = new THREE.MeshFaceMaterial( cubeMaterialArray );
// Cube parameters: width (x), height (y), depth (z),
// (optional) segments along x, segments along y, segments along z
var cubeGeometry = new THREE.CubeGeometry( 100, 100, 100, 1, 1, 1 );
// using THREE.MeshFaceMaterial() in the constructor below
// causes the mesh to use the materials stored in the geometry
cube = new THREE.Mesh( cubeGeometry, cubeMaterials );
cube.position.set(-100, 50, -50);
scene.add( cube );
targetList.push(cube);
// polyhedron
polyhedronPts.push( new THREE.Vector2 ( -100, 600 ) );
polyhedronPts.push( new THREE.Vector2 ( 300, 600 ) );
polyhedronPts.push( new THREE.Vector2 ( 600, -100 ) );
polyhedronShape = new THREE.Shape( polyhedronPts );
var extrudeSettings = {amount: 20}; // bevelSegments: 2, steps: 2 , bevelSegments: 5, bevelSize: 8, bevelThickness:5
var geometry = new THREE.ExtrudeGeometry( polyhedronShape, extrudeSettings );
mesh = THREE.SceneUtils.createMultiMaterialObject( geometry, [ new THREE.MeshBasicMaterial( { color: 0x00cc00 } ), new THREE.MeshBasicMaterial( { color: 0xff3333, wireframe: true, transparent: true } ) ] );
mesh.position.set( -50, 50, 300 );
mesh.rotation.set( 300, 0, 0 );
//mesh.scale.set( 1, 1, 1 );
scene.add( mesh );
targetList.push(mesh);
//////////////////////////////////////////////////////////////////////
// initialize object to perform world/screen calculations
projector = new THREE.Projector();
// when the mouse moves, call the given function
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function onDocumentMouseDown( event )
{
// the following line would stop any other event handler from firing
// (such as the mouse's TrackballControls)
// event.preventDefault();
//console.log("Click.");
// update the mouse variable
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
// find intersections
// create a Ray with origin at the mouse position
// and direction into the scene (camera direction)
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
// create an array containing all objects in the scene with which the ray intersects
var intersects = ray.intersectObjects( targetList );
// if there is one (or more) intersections
if ( intersects.length > 0 )
{
console.log("Hit # " + toString( intersects[0].point ) );
// change the color of the closest face.
intersects[ 0 ].face.color.setRGB( 0.8 * Math.random() + 0.2, 0, 0 );
intersects[ 0 ].object.geometry.colorsNeedUpdate = true;
}
}
function toString(v) { return "[ " + v.x + ", " + v.y + ", " + v.z + " ]"; }
function animate()
{
requestAnimationFrame( animate );
render();
update();
}
function update()
{
if ( keyboard.pressed("z") )
{
// do something
}
controls.update();
stats.update();
}
function render()
{
renderer.render( scene, camera );
}
</script>
</body>
</html>
Do you mean smooth faces?
The way to make your edges 'hard' is to first add this to your material options:
shading: THREE.FlatShading,
And then possibly:
geometry.computeVertexNormals()

Three.js: polyhedron click (raycaster intersect)

I'm making a Three.js application and I want to catch clicks on objects. When I create cube or sphere everything is ok, but I fail with polyhedron - Raycaster.intersectObjects() returns empty result.
My code is below (see click events in console.log()).
What can I do to make it work? Are there other ways to create polyhedrons?
<html>
<head>
<title>Моё 3</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<div id="ThreeJS" style="position: absolute; left:0px; top:0px"></div>
<script src="http://stemkoski.github.io/Three.js/js/Three.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/Detector.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/Stats.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/OrbitControls.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/THREEx.KeyboardState.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/THREEx.FullScreen.js"></script>
<script src="http://stemkoski.github.io/Three.js/js/THREEx.WindowResize.js"></script>
<script>
/*
Three.js "tutorials by example"
Author: Lee Stemkoski
Date: July 2013 (three.js v59dev)
*/
// MAIN
var polyhedronShape, polyhedronPts = [], cube, mesh;
// standard global variables
var container, scene, camera, renderer, controls, stats;
var keyboard = new THREEx.KeyboardState();
var clock = new THREE.Clock();
// custom global variables
var targetList = [];
var projector, mouse = { x: 0, y: 0 };
init();
animate();
// FUNCTIONS
function init()
{
// SCENE
scene = new THREE.Scene();
// CAMERA
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
scene.add(camera);
camera.position.set(0,150,400);
camera.lookAt(scene.position);
// RENDERER
if ( Detector.webgl )
renderer = new THREE.WebGLRenderer( {antialias:true} );
else
renderer = new THREE.CanvasRenderer();
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
container = document.getElementById( 'ThreeJS' );
container.appendChild( renderer.domElement );
// EVENTS
THREEx.WindowResize(renderer, camera);
THREEx.FullScreen.bindKey({ charCode : 'm'.charCodeAt(0) });
// CONTROLS
controls = new THREE.OrbitControls( camera, renderer.domElement );
// STATS
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.bottom = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
// LIGHT
var light = new THREE.PointLight(0xffffff);
light.position.set(0,250,0);
scene.add(light);
// FLOOR
var floorTexture = new THREE.ImageUtils.loadTexture( 'images/checkerboard.jpg' );
floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
floorTexture.repeat.set( 10, 10 );
var floorMaterial = new THREE.MeshBasicMaterial( { map: floorTexture, side: THREE.DoubleSide } );
var floorGeometry = new THREE.PlaneGeometry(1000, 1000, 10, 10);
var floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.position.y = -0.5;
floor.rotation.x = Math.PI / 2;
scene.add(floor);
// SKYBOX/FOG
var skyBoxGeometry = new THREE.CubeGeometry( 10000, 10000, 10000 );
var skyBoxMaterial = new THREE.MeshBasicMaterial( { color: 0x9999ff, side: THREE.BackSide } );
var skyBox = new THREE.Mesh( skyBoxGeometry, skyBoxMaterial );
scene.add(skyBox);
////////////
// CUSTOM //
////////////
//////////////////////////////////////////////////////////////////////
// this material causes a mesh to use colors assigned to faces
var faceColorMaterial = new THREE.MeshBasicMaterial(
{ color: 0xffffff, vertexColors: THREE.FaceColors } );
var sphereGeometry = new THREE.SphereGeometry( 80, 32, 16 );
for ( var i = 0; i < sphereGeometry.faces.length; i++ )
{
face = sphereGeometry.faces[ i ];
face.color.setRGB( 0, 0, 0.8 * Math.random() + 0.2 );
}
var sphere = new THREE.Mesh( sphereGeometry, faceColorMaterial );
sphere.position.set(0, 50, 0);
scene.add(sphere);
targetList.push(sphere);
// Create an array of materials to be used in a cube, one for each side
var cubeMaterialArray = [];
// order to add materials: x+,x-,y+,y-,z+,z-
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0xff3333 } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0xff8800 } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0xffff33 } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0x33ff33 } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0x3333ff } ) );
cubeMaterialArray.push( new THREE.MeshBasicMaterial( { color: 0x8833ff } ) );
var cubeMaterials = new THREE.MeshFaceMaterial( cubeMaterialArray );
// Cube parameters: width (x), height (y), depth (z),
// (optional) segments along x, segments along y, segments along z
var cubeGeometry = new THREE.CubeGeometry( 100, 100, 100, 1, 1, 1 );
// using THREE.MeshFaceMaterial() in the constructor below
// causes the mesh to use the materials stored in the geometry
cube = new THREE.Mesh( cubeGeometry, cubeMaterials );
cube.position.set(-100, 50, -50);
scene.add( cube );
targetList.push(cube);
// polyhedron
polyhedronPts.push( new THREE.Vector2 ( -100, 600 ) );
polyhedronPts.push( new THREE.Vector2 ( 300, 600 ) );
polyhedronPts.push( new THREE.Vector2 ( 600, -100 ) );
polyhedronShape = new THREE.Shape( polyhedronPts );
var extrudeSettings = {amount: 20}; // bevelSegments: 2, steps: 2 , bevelSegments: 5, bevelSize: 8, bevelThickness:5
var geometry = new THREE.ExtrudeGeometry( polyhedronShape, extrudeSettings );
mesh = THREE.SceneUtils.createMultiMaterialObject( geometry, [ new THREE.MeshBasicMaterial( { color: 0x00cc00 } ), new THREE.MeshBasicMaterial( { color: 0xff3333, wireframe: true, transparent: true } ) ] );
mesh.position.set( -50, 50, 300 );
mesh.rotation.set( 300, 0, 0 );
//mesh.scale.set( 1, 1, 1 );
scene.add( mesh );
targetList.push(mesh);
//////////////////////////////////////////////////////////////////////
// initialize object to perform world/screen calculations
projector = new THREE.Projector();
// when the mouse moves, call the given function
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function onDocumentMouseDown( event )
{
// the following line would stop any other event handler from firing
// (such as the mouse's TrackballControls)
// event.preventDefault();
//console.log("Click.");
// update the mouse variable
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
// find intersections
// create a Ray with origin at the mouse position
// and direction into the scene (camera direction)
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
// create an array containing all objects in the scene with which the ray intersects
var intersects = ray.intersectObjects( targetList );
// if there is one (or more) intersections
if ( intersects.length > 0 )
{
console.log("Hit # " + toString( intersects[0].point ) );
// change the color of the closest face.
intersects[ 0 ].face.color.setRGB( 0.8 * Math.random() + 0.2, 0, 0 );
intersects[ 0 ].object.geometry.colorsNeedUpdate = true;
}
}
function toString(v) { return "[ " + v.x + ", " + v.y + ", " + v.z + " ]"; }
function animate()
{
requestAnimationFrame( animate );
render();
update();
}
function update()
{
if ( keyboard.pressed("z") )
{
// do something
}
controls.update();
stats.update();
}
function render()
{
renderer.render( scene, camera );
}
</script>
</body>
</html>

Three.js, no shadow rendered (.stl files)

I'm using three.js and I'm trying to make a good viewer for .stl files.
But I have a big problem with the shadow, for some files it's ok and for some other it's just horrible. (Most of the time, it's stl file that come from Blender that don't work).
Here are the two different render with a "normal" file and the same file import/export with Blender.
Images : http://imageup.fr/uploads/1367501292.jpeg & http://imageup.fr/uploads/1367501311.jpeg
Here is the code:
<script src="scripts/three.min.js"></script>
<script src="three/js/loaders/STLLoader.js"></script>
<script src="three/js/Detector.js"></script>
<script src="three/js/controls/TrackballControls.js"></script>
<div id='3d' style='width:400px;height:300px;margin:auto;position:relative;border:5px solid white;border-radius:5px;'>
<script>
var modele = document.getElementById('modele3d').value;
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, cameraTarget, scene, renderer;
init();
animate();
function init() {
container = document.getElementById('3d');
camera = new THREE.PerspectiveCamera( 45, 400 / 300, 0.1, 10000 );
camera.position.set( 200, 200, 200 );
cameraTarget = new THREE.Vector3( 0, 0, 0 );
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0x1875cd, 0, 100000 );
var material = new THREE.MeshPhongMaterial( { ambient: 0xaeadad, color: 0xfefcfc, specular: 0x111111, shininess: 200} );
var loader = new THREE.STLLoader();
loader.addEventListener( 'load', function ( event ) {
var geometry = event.content;
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 0, 0, 0 );
mesh.rotation.set( - Math.PI / 2, 0, 0 );
// Recherche et envoi des tailles //
geometry.computeBoundingBox();
var largeur = (mesh.geometry.boundingBox.max.x)-(mesh.geometry.boundingBox.min.x);
var hauteur = (mesh.geometry.boundingBox.max.y)-(mesh.geometry.boundingBox.min.y);
var profondeur = (mesh.geometry.boundingBox.max.z)-(mesh.geometry.boundingBox.min.z);
var tailles = largeur + " " + hauteur + " " + profondeur;
var prix = document.getElementById('prototype_prix').value;
if(prix==0){
document.getElementById('prototype_taille1').value = Math.round(largeur);
document.getElementById('prototype_taille2').value = Math.round(hauteur);
document.getElementById('prototype_taille3').value = Math.round(profondeur);
document.getElementById('prototype_taille1_base').value = largeur;
document.getElementById('prototype_taille2_base').value = hauteur;
document.getElementById('prototype_taille3_base').value = profondeur;
}
geometry.computeBoundingSphere();
var radius = mesh.geometry.boundingSphere.radius;
mesh.position.set( 0, -radius/2, 0 );
var d = 300/(2*radius);
mesh.scale.set( d, d, d );
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add( mesh );
} );
loader.load( 'images/'+modele);
// Lights
scene.add( new THREE.AmbientLight( 0x777777 ) );
addShadowedLight( 1, 1, 1, 0xffffff, 0.8 );
addShadowedLight( 0.5, 1, -1, 0xfcd891, 0.6 );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true, alpha: false } );
renderer.setSize( 400, 300);
renderer.setClearColor( scene.fog.color, 1 );
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.physicallyBasedShading = true;
renderer.shadowMapEnabled = true;
renderer.shadowMapCullFace = THREE.CullFaceBack;
container.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
// Trackball
enhanced_control = new THREE.TrackballControls(camera,renderer.domElement);
}
function addShadowedLight( x, y, z, color, intensity ) {
var directionalLight = new THREE.DirectionalLight( color, intensity );
directionalLight.position.set( x, y, z );
scene.add( directionalLight );
directionalLight.castShadow = true;
directionalLight.shadowCameraVisible = true;
directionalLight.shadowCameraNear = 0;
directionalLight.shadowCameraFar = 20;
directionalLight.shadowMapWidth = 1024;
directionalLight.shadowMapHeight = 1024;
directionalLight.shadowBias = -0.005;
directionalLight.shadowDarkness = 0.15;
}
function onWindowResize() {
camera.aspect = 400 / 300;
renderer.setSize( 400, 300);
}
function animate() {
requestAnimationFrame( animate );
enhanced_control.update();
render();
}
function render() {
var timer = Date.now() * 0.0005;
camera.lookAt( cameraTarget );
renderer.render( scene, camera );
}
</script>
<p style='position:relative;margin-top:-310px;margin-left:3px;float:left;color:white;text-shadow:1px 1px 1px #135da4'>Rendu 3D :</p>
</div>
I hope you can help me, I have already passed a lot of time trying to make the render works :s

Categories

Resources