From d9ada3076f601e05a8fb85eee418ced6ba545e26 Mon Sep 17 00:00:00 2001 From: satoru kimura Date: Sun, 3 Aug 2014 13:13:23 +0900 Subject: [PATCH] update to three.js r68. --- threejs/tests/canvas/canvas_geometry_cube.ts | 2 +- .../canvas/canvas_interactive_cubes_tween.ts | 1 + .../tests/canvas/canvas_lights_pointlights.ts | 43 +- threejs/tests/canvas/canvas_materials.ts | 19 +- threejs/tests/css3d/css3d_sprites.ts | 20 +- threejs/tests/math/test_unit_math.ts | 640 ++++++++++++---- .../webgl/webgl_animation_skinning_morph.ts | 297 ++++++++ threejs/tests/webgl/webgl_buffergeometry.ts | 18 +- threejs/tests/webgl/webgl_camera.ts | 2 +- ...webgl_interactive_raycasting_pointcloud.ts | 335 +++++++++ threejs/tests/webgl/webgl_lensflares.ts | 2 +- threejs/tests/webgl/webgl_materials.ts | 10 +- .../tests/webgl/webgl_particles_billboards.ts | 4 +- threejs/tests/webgl/webgl_postprocessing.ts | 2 - threejs/three-tests.ts | 3 + threejs/three.d.ts | 710 ++++++++++++------ 16 files changed, 1653 insertions(+), 455 deletions(-) create mode 100644 threejs/tests/webgl/webgl_animation_skinning_morph.ts create mode 100644 threejs/tests/webgl/webgl_interactive_raycasting_pointcloud.ts diff --git a/threejs/tests/canvas/canvas_geometry_cube.ts b/threejs/tests/canvas/canvas_geometry_cube.ts index 00c3b0426f..bf5f9ae99f 100644 --- a/threejs/tests/canvas/canvas_geometry_cube.ts +++ b/threejs/tests/canvas/canvas_geometry_cube.ts @@ -43,7 +43,7 @@ // Cube - var geometry = new THREE.CubeGeometry(200, 200, 200); + var geometry = new THREE.BoxGeometry(200, 200, 200); for (var i = 0; i < geometry.faces.length; i += 2) { diff --git a/threejs/tests/canvas/canvas_interactive_cubes_tween.ts b/threejs/tests/canvas/canvas_interactive_cubes_tween.ts index 8fbd7c2cf7..865e070234 100644 --- a/threejs/tests/canvas/canvas_interactive_cubes_tween.ts +++ b/threejs/tests/canvas/canvas_interactive_cubes_tween.ts @@ -1,5 +1,6 @@ /// /// +/// // https://github.com/mrdoob/three.js/blob/master/examples/canvas_interactive_cubes_tween.html diff --git a/threejs/tests/canvas/canvas_lights_pointlights.ts b/threejs/tests/canvas/canvas_lights_pointlights.ts index 1b6a6663ff..ad1a103d5f 100644 --- a/threejs/tests/canvas/canvas_lights_pointlights.ts +++ b/threejs/tests/canvas/canvas_lights_pointlights.ts @@ -7,7 +7,6 @@ // ------- variable definitions that does not exist in the original code. These are for typescript. // ------- var camera, scene, renderer, - particle1, particle2, particle3, light1, light2, light3, loader, mesh; @@ -43,14 +42,14 @@ } - particle1 = new THREE.Sprite(new THREE.SpriteCanvasMaterial({ color: 0xff0040, program: program })); - scene.add(particle1); + var sprite = new THREE.Sprite( new THREE.SpriteCanvasMaterial( { color: 0xff0040, program: program } ) ); + light1.add( sprite ); - particle2 = new THREE.Sprite(new THREE.SpriteCanvasMaterial({ color: 0x0040ff, program: program })); - scene.add(particle2); + var sprite = new THREE.Sprite( new THREE.SpriteCanvasMaterial( { color: 0x0040ff, program: program } ) ); + light2.add( sprite ); - particle3 = new THREE.Sprite(new THREE.SpriteCanvasMaterial({ color: 0x80ff80, program: program })); - scene.add(particle3); + var sprite = new THREE.Sprite( new THREE.SpriteCanvasMaterial( { color: 0x80ff80, program: program } ) ); + light3.add( sprite ); loader = new THREE.JSONLoader(); loader.load('obj/WaltHeadLo.js', function (geometry) { @@ -94,29 +93,17 @@ if (mesh) mesh.rotation.y -= 0.01; - particle1.position.x = Math.sin(time * 0.7) * 30; - particle1.position.y = Math.cos(time * 0.5) * 40; - particle1.position.z = Math.cos(time * 0.3) * 30; + light1.position.x = Math.sin( time * 0.7 ) * 30; + light1.position.y = Math.cos( time * 0.5 ) * 40; + light1.position.z = Math.cos( time * 0.3 ) * 30; - light1.position.x = particle1.position.x; - light1.position.y = particle1.position.y; - light1.position.z = particle1.position.z; + light2.position.x = Math.cos( time * 0.3 ) * 30; + light2.position.y = Math.sin( time * 0.5 ) * 40; + light2.position.z = Math.sin( time * 0.7 ) * 30; - particle2.position.x = Math.cos(time * 0.3) * 30; - particle2.position.y = Math.sin(time * 0.5) * 40; - particle2.position.z = Math.sin(time * 0.7) * 30; - - light2.position.x = particle2.position.x; - light2.position.y = particle2.position.y; - light2.position.z = particle2.position.z; - - particle3.position.x = Math.sin(time * 0.7) * 30; - particle3.position.y = Math.cos(time * 0.3) * 40; - particle3.position.z = Math.sin(time * 0.5) * 30; - - light3.position.x = particle3.position.x; - light3.position.y = particle3.position.y; - light3.position.z = particle3.position.z; + light3.position.x = Math.sin( time * 0.7 ) * 30; + light3.position.y = Math.cos( time * 0.3 ) * 40; + light3.position.z = Math.sin( time * 0.5 ) * 30; renderer.render(scene, camera); diff --git a/threejs/tests/canvas/canvas_materials.ts b/threejs/tests/canvas/canvas_materials.ts index 23524098ae..a39a780ca9 100644 --- a/threejs/tests/canvas/canvas_materials.ts +++ b/threejs/tests/canvas/canvas_materials.ts @@ -11,7 +11,7 @@ var container, stats; var camera, scene, renderer, objects; - var particleLight, pointLight; + var pointLight; init(); animate(); @@ -103,10 +103,6 @@ } - particleLight = new THREE.Sprite(new THREE.SpriteCanvasMaterial({ color: 0xffffff, program: program })); - particleLight.scale.x = particleLight.scale.y = 8; - scene.add(particleLight); - // Lights scene.add(new THREE.AmbientLight(Math.random() * 0x202020)); @@ -121,6 +117,10 @@ pointLight = new THREE.PointLight(0xffffff, 1); scene.add(pointLight); + var sprite = new THREE.Sprite( new THREE.SpriteCanvasMaterial( { color: 0xffffff, program: program } ) ); + sprite.scale.set( 8, 8, 8 ); + pointLight.add( sprite ); + renderer = new THREE.CanvasRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); container.appendChild(renderer.domElement); @@ -198,13 +198,10 @@ } - particleLight.position.x = Math.sin(timer * 7) * 300; - particleLight.position.y = Math.cos(timer * 5) * 400; - particleLight.position.z = Math.cos(timer * 3) * 300; + pointLight.position.x = Math.sin( timer * 7 ) * 300; + pointLight.position.y = Math.cos( timer * 5 ) * 400; + pointLight.position.z = Math.cos( timer * 3 ) * 300; - pointLight.position.x = particleLight.position.x; - pointLight.position.y = particleLight.position.y; - pointLight.position.z = particleLight.position.z; renderer.render(scene, camera); diff --git a/threejs/tests/css3d/css3d_sprites.ts b/threejs/tests/css3d/css3d_sprites.ts index 20760735a0..0b69a85bff 100644 --- a/threejs/tests/css3d/css3d_sprites.ts +++ b/threejs/tests/css3d/css3d_sprites.ts @@ -1,5 +1,6 @@ /// /// +/// // https://github.com/mrdoob/three.js/blob/master/examples/css3d_sprites.html @@ -26,23 +27,16 @@ scene = new THREE.Scene(); - var sprite = document.createElement('img'); - sprite.addEventListener('load', function (event) { + var image = document.createElement( 'img' ); + image.addEventListener( 'load', function ( event ) { - for (var i = 0, j = 0; i < particlesTotal; i++, j += 3) { + for ( var i = 0; i < particlesTotal; i ++ ) { - var canvas = document.createElement('canvas'); - canvas.width = sprite.width; - canvas.height = sprite.height; - - var context = canvas.getContext('2d'); - context.drawImage(sprite, 0, 0); - - var object = new THREE.CSS3DSprite(canvas); + var object = new THREE.CSS3DSprite( image.cloneNode() ); object.position.x = Math.random() * 4000 - 2000, object.position.y = Math.random() * 4000 - 2000, object.position.z = Math.random() * 4000 - 2000 - scene.add(object); + scene.add(object); objects.push(object); @@ -51,7 +45,7 @@ transition(); }, false); - sprite.src = 'textures/sprite.png'; + image.src = 'textures/sprite.png'; // Plane diff --git a/threejs/tests/math/test_unit_math.ts b/threejs/tests/math/test_unit_math.ts index f1c3818ccc..a30e60dcdd 100644 --- a/threejs/tests/math/test_unit_math.ts +++ b/threejs/tests/math/test_unit_math.ts @@ -6,6 +6,7 @@ // https://github.com/mrdoob/three.js/tree/master/test/unit/math ()=>{ + // -------------------------------------------- Constants var x = 2; var y = 3; var z = 4; @@ -25,8 +26,7 @@ var one3 = new THREE.Vector3( 1, 1, 1 ); var two3 = new THREE.Vector3( 2, 2, 2 ); - (QUnit.module)( "Box2" ); - + // -------------------------------------------- Box2 test( "constructor", function() { var a = new THREE.Box2(); ok( a.min.equals( posInf2 ), "Passed!" ); @@ -62,6 +62,21 @@ ok( a.max.equals( one2 ), "Passed!" ); }); + test( "setFromPoints", function() { + var a = new THREE.Box2(); + + a.setFromPoints( [ zero2, one2, two2 ] ); + ok( a.min.equals( zero2 ), "Passed!" ); + ok( a.max.equals( two2 ), "Passed!" ); + + a.setFromPoints( [ one2 ] ); + ok( a.min.equals( one2 ), "Passed!" ); + ok( a.max.equals( one2 ), "Passed!" ); + + a.setFromPoints( [] ); + ok( a.empty(), "Passed!" ); + }); + test( "empty/makeEmpty", function() { var a = new THREE.Box2(); @@ -197,21 +212,6 @@ ok( b.distanceToPoint( new THREE.Vector2( -2, -2 ) ) == Math.sqrt( 2 ), "Passed!" ); }); - test( "distanceToPoint", function() { - var a = new THREE.Box2( zero2.clone(), zero2.clone() ); - var b = new THREE.Box2( one2.clone().negate(), one2.clone() ); - - ok( a.distanceToPoint( new THREE.Vector2( 0, 0 ) ) == 0, "Passed!" ); - ok( a.distanceToPoint( new THREE.Vector2( 1, 1 ) ) == Math.sqrt( 2 ), "Passed!" ); - ok( a.distanceToPoint( new THREE.Vector2( -1, -1 ) ) == Math.sqrt( 2 ), "Passed!" ); - - ok( b.distanceToPoint( new THREE.Vector2( 2, 2 ) ) == Math.sqrt( 2 ), "Passed!" ); - ok( b.distanceToPoint( new THREE.Vector2( 1, 1 ) ) == 0, "Passed!" ); - ok( b.distanceToPoint( new THREE.Vector2( 0, 0 ) ) == 0, "Passed!" ); - ok( b.distanceToPoint( new THREE.Vector2( -1, -1 ) ) == 0, "Passed!" ); - ok( b.distanceToPoint( new THREE.Vector2( -2, -2 ) ) == Math.sqrt( 2 ), "Passed!" ); - }); - test( "isIntersectionBox", function() { var a = new THREE.Box2( zero2.clone(), zero2.clone() ); var b = new THREE.Box2( zero2.clone(), one2.clone() ); @@ -267,6 +267,7 @@ ok( b.clone().translate( one2.clone().negate() ).equals( d ), "Passed!" ); }); + // -------------------------------------------- Box3 test( "constructor", function() { var a = new THREE.Box3(); ok( a.min.equals( posInf3 ), "Passed!" ); @@ -302,6 +303,21 @@ ok( a.max.equals( one3 ), "Passed!" ); }); + test( "setFromPoints", function() { + var a = new THREE.Box3(); + + a.setFromPoints( [ zero3, one3, two3 ] ); + ok( a.min.equals( zero3 ), "Passed!" ); + ok( a.max.equals( two3 ), "Passed!" ); + + a.setFromPoints( [ one3 ] ); + ok( a.min.equals( one3 ), "Passed!" ); + ok( a.max.equals( one3 ), "Passed!" ); + + a.setFromPoints( [] ); + ok( a.empty(), "Passed!" ); + }); + test( "empty/makeEmpty", function() { var a = new THREE.Box3(); @@ -508,7 +524,7 @@ var compareBox = function ( a, b, threshold? ) { threshold = threshold || 0.0001; return ( a.min.distanceTo( b.min ) < threshold && - a.max.distanceTo( b.max ) < threshold ); + a.max.distanceTo( b.max ) < threshold ); }; test( "applyMatrix4", function() { @@ -538,11 +554,19 @@ ok( b.clone().translate( one3.clone().negate() ).equals( d ), "Passed!" ); }); + // -------------------------------------------- Color test( "constructor", function(){ var c = new THREE.Color(); ok( c.r, "Red: " + c.r ); ok( c.g, "Green: " + c.g ); - ok( c.b, "Blue: " + c.g ); + ok( c.b, "Blue: " + c.b ); + }); + + test( "rgb constructor", function(){ + var c = new THREE.Color( 1, 1, 1 ); + ok( c.r == 1, "Passed" ); + ok( c.g == 1, "Passed" ); + ok( c.b == 1, "Passed" ); }); test( "copyHex", function(){ @@ -560,48 +584,48 @@ }); test( "setRGB", function(){ - var c = new THREE.Color() - c.setRGB(255, 2, 1); - ok( c.r == 255, "Red: " + c.r ); - ok( c.g == 2, "Green: " + c.g ); - ok( c.b == 1, "Blue: " + c.b ); + var c = new THREE.Color(); + c.setRGB(1, 0.2, 0.1); + ok( c.r == 1, "Red: " + c.r ); + ok( c.g == 0.2, "Green: " + c.g ); + ok( c.b == 0.1, "Blue: " + c.b ); }); test( "copyGammaToLinear", function(){ var c = new THREE.Color(); var c2 = new THREE.Color(); - c2.setRGB(2, 4, 8) - c.copyGammaToLinear(c2) - ok( c.r == 4, "Red c: " + c.r + " Red c2: " + c2.r); - ok( c.g == 16, "Green c: " + c.g + " Green c2: " + c2.g); - ok( c.b == 64, "Blue c: " + c.b + " Blue c2: " + c2.b); + c2.setRGB(0.3, 0.5, 0.9); + c.copyGammaToLinear(c2); + ok( c.r == 0.09, "Red c: " + c.r + " Red c2: " + c2.r); + ok( c.g == 0.25, "Green c: " + c.g + " Green c2: " + c2.g); + ok( c.b == 0.81, "Blue c: " + c.b + " Blue c2: " + c2.b); }); test( "copyLinearToGamma", function(){ var c = new THREE.Color(); var c2 = new THREE.Color(); - c2.setRGB(4, 9, 16) - c.copyLinearToGamma(c2) - ok( c.r == 2, "Red c: " + c.r + " Red c2: " + c2.r); - ok( c.g == 3, "Green c: " + c.g + " Green c2: " + c2.g); - ok( c.b == 4, "Blue c: " + c.b + " Blue c2: " + c2.b); + c2.setRGB(0.09, 0.25, 0.81); + c.copyLinearToGamma(c2); + ok( c.r == 0.3, "Red c: " + c.r + " Red c2: " + c2.r); + ok( c.g == 0.5, "Green c: " + c.g + " Green c2: " + c2.g); + ok( c.b == 0.9, "Blue c: " + c.b + " Blue c2: " + c2.b); }); test( "convertGammaToLinear", function(){ var c = new THREE.Color(); - c.setRGB(2, 4, 8) - c.convertGammaToLinear() - ok( c.r == 4, "Red: " + c.r ); - ok( c.g == 16, "Green: " + c.g ); - ok( c.b == 64, "Blue: " + c.b ); + c.setRGB(0.3, 0.5, 0.9); + c.convertGammaToLinear(); + ok( c.r == 0.09, "Red: " + c.r ); + ok( c.g == 0.25, "Green: " + c.g ); + ok( c.b == 0.81, "Blue: " + c.b ); }); test( "convertLinearToGamma", function(){ var c = new THREE.Color(); - c.setRGB(4, 9, 16) - c.convertLinearToGamma() + c.setRGB(4, 9, 16); + c.convertLinearToGamma(); ok( c.r == 2, "Red: " + c.r ); ok( c.g == 3, "Green: " + c.g ); ok( c.b == 4, "Blue: " + c.b ); @@ -611,8 +635,8 @@ var c = new THREE.Color(); c.set(0xFF0000); ok( c.r == 1, "Red: " + c.r ); - ok( c.g == 0, "Green: " + c.g ); - ok( c.b == 0, "Blue: " + c.b ); + ok( c.g === 0, "Green: " + c.g ); + ok( c.b === 0, "Blue: " + c.b ); }); @@ -633,11 +657,11 @@ var c = new THREE.Color(); var c2 = new THREE.Color(); c.setRGB(0, 0, 0); - c.lerp(c2, 2); - ok( c.r == 2, "Red: " + c.r ); - ok( c.g == 2, "Green: " + c.g ); - ok( c.b == 2, "Blue: " + c.b ); - + c.lerp(c2, 0.2); + ok( c.r == 0.2, "Red: " + c.r ); + ok( c.g == 0.2, "Green: " + c.g ); + ok( c.b == 0.2, "Blue: " + c.b ); + }); @@ -645,8 +669,16 @@ var c = new THREE.Color(); c.setStyle('rgb(255,0,0)'); ok( c.r == 1, "Red: " + c.r ); - ok( c.g == 0, "Green: " + c.g ); - ok( c.b == 0, "Blue: " + c.b ); + ok( c.g === 0, "Green: " + c.g ); + ok( c.b === 0, "Blue: " + c.b ); + }); + + test( "setStyleRGBRedWithSpaces", function(){ + var c = new THREE.Color(); + c.setStyle('rgb(255, 0, 0)'); + ok( c.r == 1, "Red: " + c.r ); + ok( c.g === 0, "Green: " + c.g ); + ok( c.b === 0, "Blue: " + c.b ); }); test( "setStyleRGBPercent", function(){ @@ -657,6 +689,14 @@ ok( c.b == 0.1, "Blue: " + c.b ); }); + test( "setStyleRGBPercentWithSpaces", function(){ + var c = new THREE.Color(); + c.setStyle('rgb(100%,50%,10%)'); + ok( c.r == 1, "Red: " + c.r ); + ok( c.g == 0.5, "Green: " + c.g ); + ok( c.b == 0.1, "Blue: " + c.b ); + }); + test( "setStyleHexSkyBlue", function(){ var c = new THREE.Color(); c.setStyle('#87CEEB'); @@ -706,10 +746,7 @@ ok( hsl.h == 0.5, "hue: " + hsl.h ); ok( hsl.s == 1.0, "saturation: " + hsl.s ); - - - //ok( (Math.round(parseFloat(hsl.l)*100)/100) == 0.75, "lightness: " + hsl.l ); - ok( (Math.round(hsl.l*100)/100) == 0.75, "lightness: " + hsl.l ); + ok( (Math.round(parseFloat(hsl.l.toString())*100)/100) == 0.75, "lightness: " + hsl.l ); }); test( "setHSL", function () { @@ -722,6 +759,98 @@ ok( hsl.l == 0.25, "lightness: " + hsl.l ); }); + // -------------------------------------------- Euler + + var eulerZero = new THREE.Euler( 0, 0, 0, "XYZ" ); + var eulerAxyz = new THREE.Euler( 1, 0, 0, "XYZ" ); + var eulerAzyx = new THREE.Euler( 0, 1, 0, "ZYX" ); + + var matrixEquals4 = function( a, b ) { + var tolerance = 0.0001; + if( a.elements.length != b.elements.length ) { + return false; + } + for( var i = 0, il = a.elements.length; i < il; i ++ ) { + var delta = a.elements[i] - b.elements[i]; + if( delta > tolerance ) { + return false; + } + } + return true; + }; + + test( "constructor/equals", function() { + var a = new THREE.Euler(); + ok( a.equals( eulerZero ), "Passed!" ); + ok( ! a.equals( eulerAxyz ), "Passed!" ); + ok( ! a.equals( eulerAzyx ), "Passed!" ); + }); + + test( "clone/copy/equals", function() { + var a = eulerAxyz.clone(); + ok( a.equals( eulerAxyz ), "Passed!" ); + ok( ! a.equals( eulerZero ), "Passed!" ); + ok( ! a.equals( eulerAzyx ), "Passed!" ); + + a.copy( eulerAzyx ); + ok( a.equals( eulerAzyx ), "Passed!" ); + ok( ! a.equals( eulerAxyz ), "Passed!" ); + ok( ! a.equals( eulerZero ), "Passed!" ); + + }); + + test( "set", function() { + var a = new THREE.Euler(); + + a.set( 0, 1, 0, "ZYX" ); + ok( a.equals( eulerAzyx ), "Passed!" ); + ok( ! a.equals( eulerAxyz ), "Passed!" ); + ok( ! a.equals( eulerZero ), "Passed!" ); + }); + + test( "Quaternion.setFromEuler/Euler.fromQuaternion", function() { + var testValues = [ eulerZero, eulerAxyz, eulerAzyx ]; + for( var i = 0; i < testValues.length; i ++ ) { + var v = testValues[i]; + var q = new THREE.Quaternion().setFromEuler( v ); + + var v2 = new THREE.Euler().setFromQuaternion( q, v.order ); + var q2 = new THREE.Quaternion().setFromEuler( v2 ); + ok( q.equals( q2 ), "Passed!" ); + } + }); + + + test( "Matrix4.setFromEuler/Euler.fromRotationMatrix", function() { + var testValues = [ eulerZero, eulerAxyz, eulerAzyx ]; + for( var i = 0; i < testValues.length; i ++ ) { + var v = testValues[i]; + var m = new THREE.Matrix4().makeRotationFromEuler( v ); + + var v2 = new THREE.Euler().setFromRotationMatrix( m, v.order ); + var m2 = new THREE.Matrix4().makeRotationFromEuler( v2 ); + ok( matrixEquals4( m, m2 ), "Passed!" ); + } + }); + + test( "reorder", function() { + var testValues = [ eulerZero, eulerAxyz, eulerAzyx ]; + for( var i = 0; i < testValues.length; i ++ ) { + var v = testValues[i]; + var q = new THREE.Quaternion().setFromEuler( v ); + + v.reorder( 'YZX' ); + var q2 = new THREE.Quaternion().setFromEuler( v ); + ok( q.equals( q2 ), "Passed!" ); + + v.reorder( 'ZXY' ); + var q3 = new THREE.Quaternion().setFromEuler( v ); + ok( q.equals( q3 ), "Passed!" ); + } + }); + + // -------------------------------------------- Frustum + var unit3 = new THREE.Vector3( 1, 0, 0 ); var planeEquals = function ( a, b, tolerance ) { @@ -873,6 +1002,7 @@ ok( b.planes[0].equals( p0 ), "Passed!" ); }); + // -------------------------------------------- Line3 test( "constructor/equals", function() { var a = new THREE.Line3(); @@ -925,7 +1055,6 @@ // nearby the ray ok( a.closestPointToPointParameter( zero3.clone(), false ) == -1, "Passed!" ); var b2 = a.closestPointToPoint( zero3.clone(), false ); - console.log( b2 ); ok( b2.distanceTo( new THREE.Vector3( 1, 1, 0 ) ) < 0.0001, "Passed!" ); // nearby the ray @@ -939,7 +1068,7 @@ ok( c.distanceTo( one3.clone() ) < 0.0001, "Passed!" ); }); - + // -------------------------------------------- Matrix3 var matrixEquals3 = function( a, b, tolerance? ) { tolerance = tolerance || 0.0001; @@ -1081,15 +1210,13 @@ var identity = new THREE.Matrix4(); var a = new THREE.Matrix4(); var b = new THREE.Matrix3( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); - - //var c = new THREE.Matrix4( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); - var c = new THREE.Matrix4( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + var c = new THREE.Matrix4( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); ok( ! matrixEquals3( a, b ), "Passed!" ); b.getInverse( a, false ); ok( matrixEquals3( b, new THREE.Matrix3() ), "Passed!" ); - try { + try { b.getInverse( c, true ); ok( false, "Passed!" ); // should never get here. } @@ -1106,7 +1233,7 @@ new THREE.Matrix4().makeRotationZ( -0.3 ), new THREE.Matrix4().makeScale( 1, 2, 3 ), new THREE.Matrix4().makeScale( 1/8, 1/2, 1/3 ) - ]; + ]; for( var i = 0, il = testMatrices.length; i < il; i ++ ) { var m = testMatrices[i]; @@ -1131,9 +1258,9 @@ b = new THREE.Matrix3( 0, 1, 2, 3, 4, 5, 6, 7, 8 ); var c = b.clone().transpose(); - ok( ! matrixEquals3( b, c ), "Passed!" ); + ok( ! matrixEquals3( b, c ), "Passed!" ); c.transpose(); - ok( matrixEquals3( b, c ), "Passed!" ); + ok( matrixEquals3( b, c ), "Passed!" ); }); test( "clone", function() { @@ -1147,8 +1274,10 @@ ok( ! matrixEquals3( a, b ), "Passed!" ); }); - var matrixEquals4 = function( a, b, tolerance? ) { - tolerance = tolerance || 0.0001; + // -------------------------------------------- Matrix4 + + var matrixEquals4 = function (a, b) { + var tolerance = 0.0001; if( a.elements.length != b.elements.length ) { return false; } @@ -1310,7 +1439,7 @@ b.getInverse( a, false ); ok( matrixEquals4( b, new THREE.Matrix4() ), "Passed!" ); - try { + try { b.getInverse( c, true ); ok( false, "Passed!" ); // should never get here. } @@ -1330,15 +1459,21 @@ new THREE.Matrix4().makeFrustum( -1, 1, -1, 1, 1, 1000 ), new THREE.Matrix4().makeFrustum( -16, 16, -9, 9, 0.1, 10000 ), new THREE.Matrix4().makeTranslation( 1, 2, 3 ) - ]; + ]; for( var i = 0, il = testMatrices.length; i < il; i ++ ) { var m = testMatrices[i]; var mInverse = new THREE.Matrix4().getInverse( m ); + var mSelfInverse = m.clone(); + mSelfInverse.getInverse( mSelfInverse ); + + + // self-inverse should the same as inverse + ok( matrixEquals4( mSelfInverse, mInverse ), "Passed!" ); // the determinant of the inverse should be the reciprocal - ok( Math.abs( m.determinant() * mInverse.determinant() - 1 ) < 0.0001, "Passed!" ); + ok( Math.abs( m.determinant() * mInverse.determinant() - 1 ) < 0.0001, "Passed!" ); var mProduct = new THREE.Matrix4().multiplyMatrices( m, mInverse ); @@ -1355,9 +1490,9 @@ b = new THREE.Matrix4( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ); var c = b.clone().transpose(); - ok( ! matrixEquals4( b, c ), "Passed!" ); + ok( ! matrixEquals4( b, c ), "Passed!" ); c.transpose(); - ok( matrixEquals4( b, c ), "Passed!" ); + ok( matrixEquals4( b, c ), "Passed!" ); }); test( "clone", function() { @@ -1372,10 +1507,75 @@ }); + test( "compose/decompose", function() { + var tValues = [ + new THREE.Vector3(), + new THREE.Vector3( 3, 0, 0 ), + new THREE.Vector3( 0, 4, 0 ), + new THREE.Vector3( 0, 0, 5 ), + new THREE.Vector3( -6, 0, 0 ), + new THREE.Vector3( 0, -7, 0 ), + new THREE.Vector3( 0, 0, -8 ), + new THREE.Vector3( -2, 5, -9 ), + new THREE.Vector3( -2, -5, -9 ) + ]; + + var sValues = [ + new THREE.Vector3( 1, 1, 1 ), + new THREE.Vector3( 2, 2, 2 ), + new THREE.Vector3( 1, -1, 1 ), + new THREE.Vector3( -1, 1, 1 ), + new THREE.Vector3( 1, 1, -1 ), + new THREE.Vector3( 2, -2, 1 ), + new THREE.Vector3( -1, 2, -2 ), + new THREE.Vector3( -1, -1, -1 ), + new THREE.Vector3( -2, -2, -2 ) + ]; + + var rValues = [ + new THREE.Quaternion(), + new THREE.Quaternion().setFromEuler( new THREE.Euler( 1, 1, 0 ) ), + new THREE.Quaternion().setFromEuler( new THREE.Euler( 1, -1, 1 ) ), + new THREE.Quaternion( 0, 0.9238795292366128, 0, 0.38268342717215614 ) + ]; + + + for( var ti = 0; ti < tValues.length; ti ++ ) { + for( var si = 0; si < sValues.length; si ++ ) { + for( var ri = 0; ri < rValues.length; ri ++ ) { + var t = tValues[ti]; + var s = sValues[si]; + var r = rValues[ri]; + + var m = new THREE.Matrix4().compose( t, r, s ); + var t2 = new THREE.Vector3(); + var r2 = new THREE.Quaternion(); + var s2 = new THREE.Vector3(); + + m.decompose( t2, r2, s2 ); + + var m2 = new THREE.Matrix4().compose( t2, r2, s2 ); + + var matrixIsSame = matrixEquals4( m, m2 ); + /* debug code + if( ! matrixIsSame ) { + console.log( t, s, r ); + console.log( t2, s2, r2 ); + console.log( m, m2 ); + }*/ + ok( matrixEquals4( m, m2 ), "Passed!" ); + + } + } + } + }); + + // -------------------------------------------- Plane + var comparePlane = function ( a, b, threshold? ) { threshold = threshold || 0.0001; return ( a.normal.distanceTo( b.normal ) < threshold && - Math.abs( a.constant - b.constant ) < threshold ); + Math.abs( a.constant - b.constant ) < threshold ); }; @@ -1564,6 +1764,8 @@ ok( comparePlane( a.clone().applyMatrix4( m ), a.clone().translate( new THREE.Vector3( 1, 1, 1 ) ) ), "Passed!" ); }); + // -------------------------------------------- Quaternion + var orders = [ 'XYZ', 'YXZ', 'ZXY', 'ZYX', 'YZX', 'XZY' ]; var eulerAngles = new THREE.Euler( 0.1, -0.3, 0.25 ); @@ -1658,12 +1860,9 @@ // ensure euler conversion to/from Quaternion matches. for( var i = 0; i < orders.length; i ++ ) { for( var j = 0; j < angles.length; j ++ ) { - var eulers2 = new THREE.Euler().setFromQuaternion( - new THREE.Quaternion().setFromEuler(new THREE.Euler(angles[j].x, angles[j].y, angles[j].z, orders[i])), - orders[i] - ); - var v = new THREE.Vector3().applyEuler(eulers2); - ok( v.distanceTo( angles[j] ) < 0.001, "Passed!" ); + var eulers2 = new THREE.Euler().setFromQuaternion( new THREE.Quaternion().setFromEuler( new THREE.Euler( angles[j].x, angles[j].y, angles[j].z, orders[i] ) ), orders[i] ); + var newAngle = new THREE.Vector3( eulers2.x, eulers2.y, eulers2.z ); + ok( newAngle.distanceTo( angles[j] ) < 0.001, "Passed!" ); } } @@ -1673,7 +1872,7 @@ // ensure euler conversion for Quaternion matches that of Matrix4 for( var i = 0; i < orders.length; i ++ ) { - var q = new THREE.Quaternion().setFromEuler( eulerAngles ); + var q = new THREE.Quaternion().setFromEuler( eulerAngles, false ); var m = new THREE.Matrix4().makeRotationFromEuler( eulerAngles ); var q2 = new THREE.Quaternion().setFromRotationMatrix( m ); @@ -1716,17 +1915,17 @@ test( "multiplyQuaternions/multiply", function() { - var angles = [ new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, 0, 1 ) ]; + var angles = [ new THREE.Euler( 1, 0, 0 ), new THREE.Euler( 0, 1, 0 ), new THREE.Euler( 0, 0, 1 ) ]; - var q1 = new THREE.Quaternion().setFromEuler( new THREE.Euler(angles[0].x, angles[0].y, angles[0].z) ); - var q2 = new THREE.Quaternion().setFromEuler( new THREE.Euler(angles[1].x, angles[1].y, angles[1].z) ); - var q3 = new THREE.Quaternion().setFromEuler( new THREE.Euler(angles[2].x, angles[2].y, angles[2].z) ); + var q1 = new THREE.Quaternion().setFromEuler( angles[0], false ); + var q2 = new THREE.Quaternion().setFromEuler( angles[1], false ); + var q3 = new THREE.Quaternion().setFromEuler( angles[2], false ); var q = new THREE.Quaternion().multiplyQuaternions( q1, q2 ).multiply( q3 ); - var m1 = new THREE.Matrix4().makeRotationFromEuler( new THREE.Euler(angles[0].x, angles[0].y, angles[0].z) ); - var m2 = new THREE.Matrix4().makeRotationFromEuler( new THREE.Euler(angles[1].x, angles[1].y, angles[1].z) ); - var m3 = new THREE.Matrix4().makeRotationFromEuler( new THREE.Euler(angles[2].x, angles[2].y, angles[2].z) ); + var m1 = new THREE.Matrix4().makeRotationFromEuler( angles[0] ); + var m2 = new THREE.Matrix4().makeRotationFromEuler( angles[1] ); + var m3 = new THREE.Matrix4().makeRotationFromEuler( angles[2] ); var m = new THREE.Matrix4().multiplyMatrices( m1, m2 ).multiply( m3 ); @@ -1737,13 +1936,13 @@ test( "multiplyVector3", function() { - var angles = [ new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, 0, 1 ) ]; + var angles = [ new THREE.Euler( 1, 0, 0 ), new THREE.Euler( 0, 1, 0 ), new THREE.Euler( 0, 0, 1 ) ]; // ensure euler conversion for Quaternion matches that of Matrix4 for( var i = 0; i < orders.length; i ++ ) { for( var j = 0; j < angles.length; j ++ ) { - var q = new THREE.Quaternion().setFromEuler( new THREE.Euler(angles[j].x, angles[j].y, angles[j].z, orders[i]) ); - var m = new THREE.Matrix4().makeRotationFromEuler( new THREE.Euler(angles[j].x, angles[j].y, angles[j].z, orders[i]) ); + var q = new THREE.Quaternion().setFromEuler( angles[j], false ); + var m = new THREE.Matrix4().makeRotationFromEuler( angles[j] ); var v0 = new THREE.Vector3(1, 0, 0); var qv = v0.clone().applyQuaternion( q ); @@ -1773,6 +1972,7 @@ ok( b.equals( a ), "Passed!" ); }); + // -------------------------------------------- Ray test( "constructor/equals", function() { var a = new THREE.Ray(); @@ -1834,25 +2034,33 @@ test( "closestPointToPoint", function() { var a = new THREE.Ray( one3.clone(), new THREE.Vector3( 0, 0, 1 ) ); - // nearby the ray + // behind the ray var b = a.closestPointToPoint( zero3 ); - ok( b.equals( new THREE.Vector3( 1, 1, 0 ) ), "Passed!" ); + ok( b.equals( one3 ), "Passed!" ); + + // front of the ray + var c = a.closestPointToPoint( new THREE.Vector3( 0, 0, 50 ) ); + ok( c.equals( new THREE.Vector3( 1, 1, 50 ) ), "Passed!" ); // exactly on the ray - var c = a.closestPointToPoint( one3 ); - ok( c.equals( one3 ), "Passed!" ); + var d = a.closestPointToPoint( one3 ); + ok( d.equals( one3 ), "Passed!" ); }); test( "distanceToPoint", function() { var a = new THREE.Ray( one3.clone(), new THREE.Vector3( 0, 0, 1 ) ); - // nearby the ray + // behind the ray var b = a.distanceToPoint( zero3 ); - ok( b == Math.sqrt( 2 ), "Passed!" ); + ok( b === Math.sqrt( 3 ), "Passed!" ); + + // front of the ray + var c = a.distanceToPoint( new THREE.Vector3( 0, 0, 50 ) ); + ok( c === Math.sqrt( 2 ), "Passed!" ); // exactly on the ray - var c = a.distanceToPoint( one3 ); - ok( c == 0, "Passed!" ); + var d = a.distanceToPoint( one3 ); + ok( d === 0, "Passed!" ); }); test( "isIntersectionSphere", function() { @@ -1864,16 +2072,75 @@ var f = new THREE.Sphere( two3, 1 ); ok( ! a.isIntersectionSphere( b ), "Passed!" ); - ok( a.isIntersectionSphere( c ), "Passed!" ); + ok( ! a.isIntersectionSphere( c ), "Passed!" ); ok( a.isIntersectionSphere( d ), "Passed!" ); ok( ! a.isIntersectionSphere( e ), "Passed!" ); ok( ! a.isIntersectionSphere( f ), "Passed!" ); }); + test( "intersectSphere", function() { + + var TOL = 0.0001; + + // ray a0 origin located at ( 0, 0, 0 ) and points outward in negative-z direction + var a0 = new THREE.Ray( zero3.clone(), new THREE.Vector3( 0, 0, -1 ) ); + // ray a1 origin located at ( 1, 1, 1 ) and points left in negative-x direction + var a1 = new THREE.Ray( one3.clone(), new THREE.Vector3( -1, 0, 0 ) ); + + // sphere (radius of 2) located behind ray a0, should result in null + var b = new THREE.Sphere( new THREE.Vector3( 0, 0, 3 ), 2 ); + ok( a0.intersectSphere( b ) === null, "Passed!" ); + + // sphere (radius of 2) located in front of, but too far right of ray a0, should result in null + var b = new THREE.Sphere( new THREE.Vector3( 3, 0, -1 ), 2 ); + ok( a0.intersectSphere( b ) === null, "Passed!" ); + + // sphere (radius of 2) located below ray a1, should result in null + var b = new THREE.Sphere( new THREE.Vector3( 1, -2, 1 ), 2 ); + ok( a1.intersectSphere( b ) === null, "Passed!" ); + + // sphere (radius of 1) located to the left of ray a1, should result in intersection at 0, 1, 1 + var b = new THREE.Sphere( new THREE.Vector3( -1, 1, 1 ), 1 ); + ok( a1.intersectSphere( b ).distanceTo( new THREE.Vector3( 0, 1, 1 ) ) < TOL, "Passed!" ); + + // sphere (radius of 1) located in front of ray a0, should result in intersection at 0, 0, -1 + var b = new THREE.Sphere( new THREE.Vector3( 0, 0, -2 ), 1 ); + ok( a0.intersectSphere( b ).distanceTo( new THREE.Vector3( 0, 0, -1 ) ) < TOL, "Passed!" ); + + // sphere (radius of 2) located in front & right of ray a0, should result in intersection at 0, 0, -1, or left-most edge of sphere + var b = new THREE.Sphere( new THREE.Vector3( 2, 0, -1 ), 2 ); + ok( a0.intersectSphere( b ).distanceTo( new THREE.Vector3( 0, 0, -1 ) ) < TOL, "Passed!" ); + + // same situation as above, but move the sphere a fraction more to the right, and ray a0 should now just miss + var b = new THREE.Sphere( new THREE.Vector3( 2.01, 0, -1 ), 2 ); + ok( a0.intersectSphere( b ) === null, "Passed!" ); + + // following tests are for situations where the ray origin is inside the sphere + + // sphere (radius of 1) center located at ray a0 origin / sphere surrounds the ray origin, so the first intersect point 0, 0, 1, + // is behind ray a0. Therefore, second exit point on back of sphere will be returned: 0, 0, -1 + // thus keeping the intersection point always in front of the ray. + var b = new THREE.Sphere( zero3.clone(), 1 ); + ok( a0.intersectSphere( b ).distanceTo( new THREE.Vector3( 0, 0, -1 ) ) < TOL, "Passed!" ); + + // sphere (radius of 4) center located behind ray a0 origin / sphere surrounds the ray origin, so the first intersect point 0, 0, 5, + // is behind ray a0. Therefore, second exit point on back of sphere will be returned: 0, 0, -3 + // thus keeping the intersection point always in front of the ray. + var b = new THREE.Sphere( new THREE.Vector3( 0, 0, 1 ), 4 ); + ok( a0.intersectSphere( b ).distanceTo( new THREE.Vector3( 0, 0, -3 ) ) < TOL, "Passed!" ); + + // sphere (radius of 4) center located in front of ray a0 origin / sphere surrounds the ray origin, so the first intersect point 0, 0, 3, + // is behind ray a0. Therefore, second exit point on back of sphere will be returned: 0, 0, -5 + // thus keeping the intersection point always in front of the ray. + var b = new THREE.Sphere( new THREE.Vector3( 0, 0, -1 ), 4 ); + ok( a0.intersectSphere( b ).distanceTo( new THREE.Vector3( 0, 0, -5 ) ) < TOL, "Passed!" ); + + }); + test( "isIntersectionPlane", function() { var a = new THREE.Ray( one3.clone(), new THREE.Vector3( 0, 0, 1 ) ); - // parallel plane behind + // parallel plane in front of the ray var b = new THREE.Plane().setFromNormalAndCoplanarPoint( new THREE.Vector3( 0, 0, 1 ), one3.clone().sub( new THREE.Vector3( 0, 0, -1 ) ) ); ok( a.isIntersectionPlane( b ), "Passed!" ); @@ -1881,9 +2148,9 @@ var c = new THREE.Plane().setFromNormalAndCoplanarPoint( new THREE.Vector3( 0, 0, 1 ), one3.clone().sub( new THREE.Vector3( 0, 0, 0 ) ) ); ok( a.isIntersectionPlane( c ), "Passed!" ); - // parallel plane infront + // parallel plane behind the ray var d = new THREE.Plane().setFromNormalAndCoplanarPoint( new THREE.Vector3( 0, 0, 1 ), one3.clone().sub( new THREE.Vector3( 0, 0, 1 ) ) ); - ok( a.isIntersectionPlane( d ), "Passed!" ); + ok( ! a.isIntersectionPlane( d ), "Passed!" ); // perpendical ray that overlaps exactly var e = new THREE.Plane().setFromNormalAndCoplanarPoint( new THREE.Vector3( 1, 0, 0 ), one3 ); @@ -1899,15 +2166,15 @@ // parallel plane behind var b = new THREE.Plane().setFromNormalAndCoplanarPoint( new THREE.Vector3( 0, 0, 1 ), new THREE.Vector3( 1, 1, -1 ) ); - ok( a.intersectPlane( b ).equals( new THREE.Vector3( 1, 1, -1 ) ), "Passed!" ); + ok( a.intersectPlane( b ) === null, "Passed!" ); // parallel plane coincident with origin var c = new THREE.Plane().setFromNormalAndCoplanarPoint( new THREE.Vector3( 0, 0, 1 ), new THREE.Vector3( 1, 1, 0 ) ); - ok( a.intersectPlane( c ).equals( new THREE.Vector3( 1, 1, 0 ) ), "Passed!" ); + ok( a.intersectPlane( c ) === null, "Passed!" ); // parallel plane infront var d = new THREE.Plane().setFromNormalAndCoplanarPoint( new THREE.Vector3( 0, 0, 1 ), new THREE.Vector3( 1, 1, 1 ) ); - ok( a.intersectPlane( d ).equals( new THREE.Vector3( 1, 1, 1 ) ), "Passed!" ); + ok( a.intersectPlane( d ).equals( a.origin ), "Passed!" ); // perpendical ray that overlaps exactly var e = new THREE.Plane().setFromNormalAndCoplanarPoint( new THREE.Vector3( 1, 0, 0 ), one3 ); @@ -1915,21 +2182,21 @@ // perpendical ray that doesn't overlap var f = new THREE.Plane().setFromNormalAndCoplanarPoint( new THREE.Vector3( 1, 0, 0 ), zero3 ); - ok( a.intersectPlane( f ) === undefined, "Passed!" ); + ok( a.intersectPlane( f ) === null, "Passed!" ); }); test( "applyMatrix4", function() { var a = new THREE.Ray( one3.clone(), new THREE.Vector3( 0, 0, 1 ) ); - var m = new THREE.Matrix4().identity(); + var m = new THREE.Matrix4(); ok( a.clone().applyMatrix4( m ).equals( a ), "Passed!" ); a = new THREE.Ray( zero3.clone(), new THREE.Vector3( 0, 0, 1 ) ); - m.makeRotationAxis( new THREE.Vector3( 0, 0, 1 ), Math.PI ); + m.makeRotationZ( Math.PI ); ok( a.clone().applyMatrix4( m ).equals( a ), "Passed!" ); - m.identity().makeRotationX( Math.PI ); + m.makeRotationX( Math.PI ); var b = a.clone(); b.direction.negate(); var a2 = a.clone().applyMatrix4( m ); @@ -1944,6 +2211,80 @@ }); + test( "distanceSqToSegment", function() { + var a = new THREE.Ray( one3.clone(), new THREE.Vector3( 0, 0, 1 ) ); + var ptOnLine = new THREE.Vector3(); + var ptOnSegment = new THREE.Vector3(); + + //segment in front of the ray + var v0 = new THREE.Vector3( 3, 5, 50 ); + var v1 = new THREE.Vector3( 50, 50, 50 ); // just a far away point + var distSqr = a.distanceSqToSegment( v0, v1, ptOnLine, ptOnSegment ); + + ok( ptOnSegment.distanceTo( v0 ) < 0.0001, "Passed!" ); + ok( ptOnLine.distanceTo( new THREE.Vector3(1, 1, 50) ) < 0.0001, "Passed!" ); + // ((3-1) * (3-1) + (5-1) * (5-1) = 4 + 16 = 20 + ok( Math.abs( distSqr - 20 ) < 0.0001, "Passed!" ); + + //segment behind the ray + v0 = new THREE.Vector3( -50, -50, -50 ); // just a far away point + v1 = new THREE.Vector3( -3, -5, -4 ); + distSqr = a.distanceSqToSegment( v0, v1, ptOnLine, ptOnSegment ); + + ok( ptOnSegment.distanceTo( v1 ) < 0.0001, "Passed!" ); + ok( ptOnLine.distanceTo( one3 ) < 0.0001, "Passed!" ); + // ((-3-1) * (-3-1) + (-5-1) * (-5-1) + (-4-1) + (-4-1) = 16 + 36 + 25 = 77 + ok( Math.abs( distSqr - 77 ) < 0.0001, "Passed!" ); + + //exact intersection between the ray and the segment + v0 = new THREE.Vector3( -50, -50, -50 ); + v1 = new THREE.Vector3( 50, 50, 50 ); + distSqr = a.distanceSqToSegment( v0, v1, ptOnLine, ptOnSegment ); + + ok( ptOnSegment.distanceTo( one3 ) < 0.0001, "Passed!" ); + ok( ptOnLine.distanceTo( one3 ) < 0.0001, "Passed!" ); + ok( distSqr < 0.0001, "Passed!" ); + }); + + test( "intersectBox", function() { + + var TOL = 0.0001; + + var box = new THREE.Box3( new THREE.Vector3( -1, -1, -1 ), new THREE.Vector3( 1, 1, 1 ) ); + + var a = new THREE.Ray( new THREE.Vector3( -2, 0, 0 ), new THREE.Vector3( 1, 0, 0) ); + //ray should intersect box at -1,0,0 + ok( a.isIntersectionBox(box) === true, "Passed!" ); + ok( a.intersectBox(box).distanceTo( new THREE.Vector3( -1, 0, 0 ) ) < TOL, "Passed!" ); + + var b = new THREE.Ray( new THREE.Vector3( -2, 0, 0 ), new THREE.Vector3( -1, 0, 0) ); + //ray is point away from box, it should not intersect + ok( b.isIntersectionBox(box) === false, "Passed!" ); + ok( b.intersectBox(box) === null, "Passed!" ); + + var c = new THREE.Ray( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 1, 0, 0) ); + // ray is inside box, should return exit point + ok( c.isIntersectionBox(box) === true, "Passed!" ); + ok( c.intersectBox(box).distanceTo( new THREE.Vector3( 1, 0, 0 ) ) < TOL, "Passed!" ); + + var d = new THREE.Ray( new THREE.Vector3( 0, 2, 1 ), new THREE.Vector3( 0, -1, -1).normalize() ); + //tilted ray should intersect box at 0,1,0 + ok( d.isIntersectionBox(box) === true, "Passed!" ); + ok( d.intersectBox(box).distanceTo( new THREE.Vector3( 0, 1, 0 ) ) < TOL, "Passed!" ); + + var e = new THREE.Ray( new THREE.Vector3( 1, -2, 1 ), new THREE.Vector3( 0, 1, 0).normalize() ); + //handle case where ray is coplanar with one of the boxes side - box in front of ray + ok( e.isIntersectionBox(box) === true, "Passed!" ); + ok( e.intersectBox(box).distanceTo( new THREE.Vector3( 1, -1, 1 ) ) < TOL, "Passed!" ); + + var f = new THREE.Ray( new THREE.Vector3( 1, -2, 0 ), new THREE.Vector3( 0, -1, 0).normalize() ); + //handle case where ray is coplanar with one of the boxes side - box behind ray + ok( f.isIntersectionBox(box) === false, "Passed!" ); + ok( f.intersectBox(box) == null, "Passed!" ); + + }); + + // -------------------------------------------- Sphere test( "constructor", function() { var a = new THREE.Sphere(); ok( a.center.equals( zero3 ), "Passed!" ); @@ -2040,6 +2381,8 @@ ok( a.center.equals( zero3 ), "Passed!" ); }); + // -------------------------------------------- Triangle + test( "constructor", function() { var a = new THREE.Triangle(); ok( a.a.equals( zero3 ), "Passed!" ); @@ -2195,7 +2538,7 @@ ok( ! a.containsPoint( new THREE.Vector3( -1, -1, -1 ) ), "Passed!" ); }); - + // -------------------------------------------- Vector2 test( "constructor", function() { var a = new THREE.Vector2(); ok( a.x == 0, "Passed!" ); @@ -2316,6 +2659,32 @@ c.clamp( b, a ); ok( c.x == -x, "Passed!" ); ok( c.y == y, "Passed!" ); + + c.set(-2*x, 2*x); + c.clampScalar( -x, x ); + equal( c.x, -x, "scalar clamp x" ); + equal( c.y, x, "scalar clamp y" ); + }); + + test( "rounding", function() { + deepEqual( new THREE.Vector2( -0.1, 0.1 ).floor(), new THREE.Vector2( -1, 0 ), "floor .1" ); + deepEqual( new THREE.Vector2( -0.5, 0.5 ).floor(), new THREE.Vector2( -1, 0 ), "floor .5" ); + deepEqual( new THREE.Vector2( -0.9, 0.9 ).floor(), new THREE.Vector2( -1, 0 ), "floor .9" ); + + deepEqual( new THREE.Vector2( -0.1, 0.1 ).ceil(), new THREE.Vector2( 0, 1 ), "ceil .1" ); + deepEqual( new THREE.Vector2( -0.5, 0.5 ).ceil(), new THREE.Vector2( 0, 1 ), "ceil .5" ); + deepEqual( new THREE.Vector2( -0.9, 0.9 ).ceil(), new THREE.Vector2( 0, 1 ), "ceil .9" ); + + deepEqual( new THREE.Vector2( -0.1, 0.1 ).round(), new THREE.Vector2( 0, 0 ), "round .1" ); + deepEqual( new THREE.Vector2( -0.5, 0.5 ).round(), new THREE.Vector2( 0, 1 ), "round .5" ); + deepEqual( new THREE.Vector2( -0.9, 0.9 ).round(), new THREE.Vector2( -1, 1 ), "round .9" ); + + deepEqual( new THREE.Vector2( -0.1, 0.1 ).roundToZero(), new THREE.Vector2( 0, 0 ), "roundToZero .1" ); + deepEqual( new THREE.Vector2( -0.5, 0.5 ).roundToZero(), new THREE.Vector2( 0, 0 ), "roundToZero .5" ); + deepEqual( new THREE.Vector2( -0.9, 0.9 ).roundToZero(), new THREE.Vector2( 0, 0 ), "roundToZero .9" ); + deepEqual( new THREE.Vector2( -1.1, 1.1 ).roundToZero(), new THREE.Vector2( -1, 1 ), "roundToZero 1.1" ); + deepEqual( new THREE.Vector2( -1.5, 1.5 ).roundToZero(), new THREE.Vector2( -1, 1 ), "roundToZero 1.5" ); + deepEqual( new THREE.Vector2( -1.9, 1.9 ).roundToZero(), new THREE.Vector2( -1, 1 ), "roundToZero 1.9" ); }); test( "negate", function() { @@ -2427,7 +2796,7 @@ ok( b.equals( a ), "Passed!" ); }); - + // -------------------------------------------- Vector3 test( "constructor", function() { var a = new THREE.Vector3(); ok( a.x == 0, "Passed!" ); @@ -2700,18 +3069,19 @@ }); test( "reflect", function() { - var a = new THREE.Vector3( 1, 0, 0 ); - var normal = new THREE.Vector3( 1, 0, 0 ); - var b = new THREE.Vector3( 0, 0, 0 ); + var a = new THREE.Vector3(); + var normal = new THREE.Vector3( 0, 1, 0 ); + var b = new THREE.Vector3(); - ok( b.copy( a ).reflect( normal ).equals( new THREE.Vector3( 1, 0, 0 ) ), "Passed!" ); + a.set( 0, -1, 0 ); + ok( b.copy( a ).reflect( normal ).equals( new THREE.Vector3( 0, 1, 0 ) ), "Passed!" ); a.set( 1, -1, 0 ); ok( b.copy( a ).reflect( normal ).equals( new THREE.Vector3( 1, 1, 0 ) ), "Passed!" ); a.set( 1, -1, 0 ); normal.set( 0, -1, 0 ); - ok( b.copy( a ).reflect( normal ).equals( new THREE.Vector3( -1, -1, 0 ) ), "Passed!" ); + ok( b.copy( a ).reflect( normal ).equals( new THREE.Vector3( 1, 1, 0 ) ), "Passed!" ); }); test( "angleTo", function() { @@ -2768,7 +3138,7 @@ ok( b.equals( a ), "Passed!" ); }); - + // -------------------------------------------- Vector4 test( "constructor", function() { var a = new THREE.Vector4(); ok( a.x == 0, "Passed!" ); @@ -2897,9 +3267,9 @@ b.multiplyScalar( -2 ); ok( b.x == 2*x, "Passed!" ); - ok( b.y == 2*y, "Passed!" ); - ok( b.z == 2*z, "Passed!" ); - ok( b.w == 2*w, "Passed!" ); + ok( b.y == 2*y, "Passed!" ); + ok( b.z == 2*z, "Passed!" ); + ok( b.w == 2*w, "Passed!" ); a.divideScalar( -2 ); ok( a.x == x, "Passed!" ); @@ -3008,26 +3378,26 @@ }); /* - test( "distanceTo/distanceToSquared", function() { - var a = new THREE.Vector4( x, 0, 0, 0 ); - var b = new THREE.Vector4( 0, -y, 0, 0 ); - var c = new THREE.Vector4( 0, 0, z, 0 ); - var d = new THREE.Vector4( 0, 0, 0, -w ); - var e = new THREE.Vector4(); - - ok( a.distanceTo( e ) == x, "Passed!" ); - ok( a.distanceToSquared( e ) == x*x, "Passed!" ); + test( "distanceTo/distanceToSquared", function() { + var a = new THREE.Vector4( x, 0, 0, 0 ); + var b = new THREE.Vector4( 0, -y, 0, 0 ); + var c = new THREE.Vector4( 0, 0, z, 0 ); + var d = new THREE.Vector4( 0, 0, 0, -w ); + var e = new THREE.Vector4(); - ok( b.distanceTo( e ) == y, "Passed!" ); - ok( b.distanceToSquared( e ) == y*y, "Passed!" ); + ok( a.distanceTo( e ) == x, "Passed!" ); + ok( a.distanceToSquared( e ) == x*x, "Passed!" ); - ok( c.distanceTo( e ) == z, "Passed!" ); - ok( c.distanceToSquared( e ) == z*z, "Passed!" ); + ok( b.distanceTo( e ) == y, "Passed!" ); + ok( b.distanceToSquared( e ) == y*y, "Passed!" ); - ok( d.distanceTo( e ) == w, "Passed!" ); - ok( d.distanceToSquared( e ) == w*w, "Passed!" ); - }); - */ + ok( c.distanceTo( e ) == z, "Passed!" ); + ok( c.distanceToSquared( e ) == z*z, "Passed!" ); + + ok( d.distanceTo( e ) == w, "Passed!" ); + ok( d.distanceToSquared( e ) == w*w, "Passed!" ); + }); + */ test( "setLength", function() { diff --git a/threejs/tests/webgl/webgl_animation_skinning_morph.ts b/threejs/tests/webgl/webgl_animation_skinning_morph.ts new file mode 100644 index 0000000000..ab588fad3e --- /dev/null +++ b/threejs/tests/webgl/webgl_animation_skinning_morph.ts @@ -0,0 +1,297 @@ +/// +/// + +// https://github.com/mrdoob/three.js/blob/master/examples/webgl_sprites.html + +() => { + // ------- variable definitions that does not exist in the original code. These are for typescript. + var material: THREE.SpriteMaterial; + var geometry: THREE.JSonLoaderResultGeometry; + var dat:any; + // ------- + + var SCREEN_WIDTH = window.innerWidth; + var SCREEN_HEIGHT = window.innerHeight; + var FLOOR = -250; + + var container,stats; + + var camera, scene; + var renderer; + + var mesh, helper; + + var mouseX = 0, mouseY = 0; + + var windowHalfX = window.innerWidth / 2; + var windowHalfY = window.innerHeight / 2; + + var clock = new THREE.Clock(); + + document.addEventListener( 'mousemove', onDocumentMouseMove, false ); + + init(); + animate(); + + function init() { + + container = document.getElementById( 'container' ); + + camera = new THREE.PerspectiveCamera( 30, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 ); + camera.position.z = 2200; + + scene = new THREE.Scene(); + + scene.fog = new THREE.Fog( 0xffffff, 2000, 10000 ); + + scene.add( camera ); + + // GROUND + + var groundMaterial = new THREE.MeshPhongMaterial( { emissive: 0xbbbbbb } ); + var planeGeometry = new THREE.PlaneGeometry( 16000, 16000 ); + + var ground = new THREE.Mesh( planeGeometry, groundMaterial ); + ground.position.set( 0, FLOOR, 0 ); + ground.rotation.x = -Math.PI/2; + scene.add( ground ); + + ground.receiveShadow = true; + + + // LIGHTS + + var ambient = new THREE.AmbientLight( 0x222222 ); + scene.add( ambient ); + + + var light = new THREE.DirectionalLight( 0xebf3ff, 1.6 ); + light.position.set( 0, 140, 500 ).multiplyScalar( 1.1 ); + scene.add( light ); + + light.castShadow = true; + + light.shadowMapWidth = 2048; + light.shadowMapHeight = 2048; + + var d = 390; + + light.shadowCameraLeft = -d * 2; + light.shadowCameraRight = d * 2; + light.shadowCameraTop = d * 1.5; + light.shadowCameraBottom = -d; + + light.shadowCameraFar = 3500; + //light.shadowCameraVisible = true; + + // + + var light = new THREE.DirectionalLight( 0x497f13, 1 ); + light.position.set( 0, -1, 0 ); + scene.add( light ); + + // RENDERER + + renderer = new THREE.WebGLRenderer( { antialias: true } ); + renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT ); + renderer.domElement.style.position = "relative"; + + renderer.setClearColor( scene.fog.color, 1 ); + + container.appendChild( renderer.domElement ); + + renderer.gammaInput = true; + renderer.gammaOutput = true; + + renderer.shadowMapEnabled = true; + + + // STATS + + stats = new Stats(); + container.appendChild( stats.domElement ); + + // + + var loader = new THREE.JSONLoader(); + loader.load( "models/skinned/knight.js", function ( geometry, materials ) { + + createScene( geometry, materials, 0, FLOOR, -300, 60 ) + + } ); + + // GUI + + initGUI(); + + // + + window.addEventListener( 'resize', onWindowResize, false ); + + } + + 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 ensureLoop( animation ) { + + for ( var i = 0; i < animation.hierarchy.length; i ++ ) { + + var bone = animation.hierarchy[ i ]; + + var first = bone.keys[ 0 ]; + var last = bone.keys[ bone.keys.length - 1 ]; + + last.pos = first.pos; + last.rot = first.rot; + last.scl = first.scl; + + } + + } + + function createScene( geometry, materials, x, y, z, s ) { + + ensureLoop( geometry.animation ); + + geometry.computeBoundingBox(); + var bb = geometry.boundingBox; + + var path = "textures/cube/Park2/"; + var format = '.jpg'; + var urls = [ + path + 'posx' + format, path + 'negx' + format, + path + 'posy' + format, path + 'negy' + format, + path + 'posz' + format, path + 'negz' + format + ]; + + + //var envMap = THREE.ImageUtils.loadTextureCube( urls ); + + //var map = THREE.ImageUtils.loadTexture( "textures/UV_Grid_Sm.jpg" ); + + //var bumpMap = THREE.ImageUtils.generateDataTexture( 1, 1, new THREE.Color() ); + //var bumpMap = THREE.ImageUtils.loadTexture( "textures/water.jpg" ); + + for ( var i = 0; i < materials.length; i ++ ) { + + var m = materials[ i ]; + m.skinning = true; + m.morphTargets = true; + + m.specular.setHSL( 0, 0, 0.1 ); + + m.color.setHSL( 0.6, 0, 0.6 ); + m.ambient.copy( m.color ); + + //m.map = map; + //m.envMap = envMap; + //m.bumpMap = bumpMap; + //m.bumpScale = 2; + + //m.combine = THREE.MixOperation; + //m.reflectivity = 0.75; + + m.wrapAround = true; + + } + + mesh = new THREE.SkinnedMesh( geometry, new THREE.MeshFaceMaterial( materials ) ); + mesh.position.set( x, y - bb.min.y * s, z ); + mesh.scale.set( s, s, s ); + scene.add( mesh ); + + mesh.castShadow = true; + mesh.receiveShadow = true; + + helper = new THREE.SkeletonHelper( mesh ); + helper.material.linewidth = 3; + helper.visible = false; + scene.add( helper ); + + var animation = new THREE.Animation( mesh, geometry.animation ); + animation.play(); + + } + + function initGUI() { + + var API = { + 'show model' : true, + 'show skeleton' : false + }; + + var gui = new dat.GUI(); + + gui.add( API, 'show model' ).onChange( function() { mesh.visible = API[ 'show model' ]; } ); + + gui.add( API, 'show skeleton' ).onChange( function() { helper.visible = API[ 'show skeleton' ]; } ); + + } + + function onDocumentMouseMove( event ) { + + mouseX = ( event.clientX - windowHalfX ); + mouseY = ( event.clientY - windowHalfY ); + + } + + // + + function animate() { + + requestAnimationFrame( animate ); + + render(); + stats.update(); + + } + + function render() { + + var delta = 0.75 * clock.getDelta(); + + camera.position.x += ( mouseX - camera.position.x ) * .05; + camera.position.y = THREE.Math.clamp( camera.position.y + ( - mouseY - camera.position.y ) * .05, 0, 1000 ); + + camera.lookAt( scene.position ); + + // update skinning + + THREE.AnimationHandler.update( delta ); + + if ( helper !== undefined ) helper.update(); + + // update morphs + + if ( mesh ) { + + var time = Date.now() * 0.001; + + // mouth + + mesh.morphTargetInfluences[ 1 ] = ( 1 + Math.sin( 4 * time ) ) / 2; + + // frown ? + + mesh.morphTargetInfluences[ 2 ] = ( 1 + Math.sin( 2 * time ) ) / 2; + + // eyes + + mesh.morphTargetInfluences[ 3 ] = ( 1 + Math.cos( 4 * time ) ) / 2; + + } + + renderer.render( scene, camera ); + + } +} \ No newline at end of file diff --git a/threejs/tests/webgl/webgl_buffergeometry.ts b/threejs/tests/webgl/webgl_buffergeometry.ts index f8d4559324..de4ad2aee4 100644 --- a/threejs/tests/webgl/webgl_buffergeometry.ts +++ b/threejs/tests/webgl/webgl_buffergeometry.ts @@ -49,11 +49,6 @@ var geometry = new THREE.BufferGeometry(); - geometry.addAttribute('index', new Uint16Array(triangles * 3), 1); - geometry.addAttribute('position', new Float32Array(triangles * 3 * 3), 3); - geometry.addAttribute('normal', new Float32Array(triangles * 3 * 3), 3); - geometry.addAttribute('color', new Float32Array(triangles * 3 * 3), 3); - // break geometry into // chunks of 21,845 triangles (3 unique vertices per triangle) // for indices to fit into 16 bit integer number @@ -61,7 +56,7 @@ var chunkSize = 21845; - var indices = geometry.getAttribute('index').array; + var indices = new Uint16Array( triangles * 3 ); for (var i = 0; i < indices.length; i++) { @@ -69,9 +64,9 @@ } - var positions = geometry.getAttribute('position').array; - var normals = geometry.getAttribute('normal').array; - var colors = geometry.getAttribute('color').array; + var positions = new Float32Array( triangles * 3 * 3 ); + var normals = new Float32Array( triangles * 3 * 3 ); + var colors = new Float32Array( triangles * 3 * 3 ); var color = new THREE.Color(); @@ -167,6 +162,11 @@ } + geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) ); + geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); + geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); + geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) ); + var offsets = triangles / chunkSize; for (var i = 0; i < offsets; i++) { diff --git a/threejs/tests/webgl/webgl_camera.ts b/threejs/tests/webgl/webgl_camera.ts index 4bf35883cc..531d97fc41 100644 --- a/threejs/tests/webgl/webgl_camera.ts +++ b/threejs/tests/webgl/webgl_camera.ts @@ -85,7 +85,7 @@ } - var particles = new THREE.ParticleSystem(geometry, new THREE.ParticleSystemMaterial({ color: 0x888888 })); + var particles = new THREE.PointCloud( geometry, new THREE.PointCloudMaterial( { color: 0x888888 } ) ); scene.add(particles); // diff --git a/threejs/tests/webgl/webgl_interactive_raycasting_pointcloud.ts b/threejs/tests/webgl/webgl_interactive_raycasting_pointcloud.ts new file mode 100644 index 0000000000..330abd001b --- /dev/null +++ b/threejs/tests/webgl/webgl_interactive_raycasting_pointcloud.ts @@ -0,0 +1,335 @@ +/// +/// + +// https://github.com/mrdoob/three.js/blob/master/examples/webgl_sprites.html + +() => { + // ------- variable definitions that does not exist in the original code. These are for typescript. + var material: THREE.SpriteMaterial; + var intersection: THREE.Intersection; + var container: HTMLElement; + var pcBuffer: THREE.PointCloud; + var v: any; + // ------- + + if ( ! Detector.webgl ) Detector.addGetWebGLMessage(); + + var renderer, scene, camera, stats; + var pointclouds; + var projector, raycaster, intersects; + var mouse = { x: 1, y: 1 }; + var vector = new THREE.Vector3(); + intersection = null; + var spheres = []; + var spheresIndex = 0; + var clock; + + var threshold = 0.1; + var pointSize = 0.01; + var width = 150; + var length = 150; + var rotateY = new THREE.Matrix4().makeRotationY( 0.005 ); + + init(); + animate(); + + function generatePointCloudGeometry( color, width, length ){ + + var geometry = new THREE.BufferGeometry(); + var numPoints = width*length; + + var positions = new Float32Array( numPoints*3 ); + var colors = new Float32Array( numPoints*3 ); + + var k = 0; + + for( var i = 0; i < width; i++ ) { + + for( var j = 0; j < length; j++ ) { + + var u = i / width; + var v = j / length; + var x = u - 0.5; + var y = ( Math.cos( u * Math.PI * 8 ) + Math.sin( v * Math.PI * 8 ) ) / 20; + var z = v - 0.5; + + positions[ 3 * k ] = x; + positions[ 3 * k + 1 ] = y; + positions[ 3 * k + 2 ] = z; + + var intensity = ( y + 0.1 ) * 5; + colors[ 3 * k ] = color.r * intensity; + colors[ 3 * k + 1 ] = color.g * intensity; + colors[ 3 * k + 2 ] = color.b * intensity; + + k++; + + } + + } + + geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); + geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) ); + geometry.computeBoundingBox(); + + return geometry; + + } + + function generatePointcloud( color, width, length ) { + + var geometry = generatePointCloudGeometry( color, width, length ); + + var material = new THREE.PointCloudMaterial( { size: pointSize, vertexColors: THREE.VertexColors } ); + var pointcloud = new THREE.PointCloud( geometry, material ); + + return pointcloud; + + } + + function generateIndexedPointcloud( color, width, length ) { + + var geometry = generatePointCloudGeometry( color, width, length ); + var numPoints = width * length; + var indices = new Uint16Array( numPoints ); + + var k = 0; + + for( var i = 0; i < width; i++ ) { + + for( var j = 0; j < length; j++ ) { + + indices[ k ] = k; + k++; + + } + + } + + geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) ); + + var material = new THREE.PointCloudMaterial( { size: pointSize, vertexColors: THREE.VertexColors } ); + var pointcloud = new THREE.PointCloud( geometry, material ); + + return pointcloud; + + } + + function generateIndexedWithOffsetPointcloud( color, width, length ){ + + var geometry = generatePointCloudGeometry( color, width, length ); + var numPoints = width * length; + var indices = new Uint16Array( numPoints ); + + var k = 0; + + for( var i = 0; i < width; i++ ){ + + for( var j = 0; j < length; j++ ) { + + indices[ k ] = k; + k++; + + } + + } + + geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) ); + + var offset = { start: 0, count: indices.length, index: 0 }; + geometry.offsets.push( offset ); + + var material = new THREE.PointCloudMaterial( { size: pointSize, vertexColors: THREE.VertexColors } ); + var pointcloud = new THREE.PointCloud( geometry, material ); + + return pointcloud; + + } + + function generateRegularPointcloud( color, width, length ) { + + var geometry = new THREE.Geometry(); + var numPoints = width * length; + + var colors = []; + + var k = 0; + + for( var i = 0; i < width; i++ ) { + + for( var j = 0; j < length; j++ ) { + + var u = i / width; + v = j / length; + var x = u - 0.5; + var y = ( Math.cos( u * Math.PI * 8 ) + Math.sin( v * Math.PI * 8) ) / 20; + var z = v - 0.5; + v = new THREE.Vector3( x,y,z ); + + var intensity = ( y + 0.1 ) * 7; + colors[ 3 * k ] = color.r * intensity; + colors[ 3 * k + 1 ] = color.g * intensity; + colors[ 3 * k + 2 ] = color.b * intensity; + + geometry.vertices.push( v ); + colors[ k ] = ( color.clone().multiplyScalar( intensity ) ); + + k++; + + } + + } + + geometry.colors = colors; + geometry.computeBoundingBox(); + + var material = new THREE.PointCloudMaterial( { size: pointSize, vertexColors: THREE.VertexColors } ); + var pointcloud = new THREE.PointCloud( geometry, material ); + + return pointcloud; + + } + + function init() { + + container = document.getElementById( 'container' ); + + scene = new THREE.Scene(); + + clock = new THREE.Clock(); + + camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 ); + camera.applyMatrix( new THREE.Matrix4().makeTranslation( 0,0,20 ) ); + camera.applyMatrix( new THREE.Matrix4().makeRotationX( -0.5 ) ); + + // + + pcBuffer = generatePointcloud( new THREE.Color( 1,0,0 ), width, length ); + pcBuffer.scale.set( 10,10,10 ); + pcBuffer.position.set( -5,0,5 ); + scene.add( pcBuffer ); + + var pcIndexed = generateIndexedPointcloud( new THREE.Color( 0,1,0 ), width, length ); + pcIndexed.scale.set( 10,10,10 ); + pcIndexed.position.set( 5,0,5 ); + scene.add( pcIndexed ); + + var pcIndexedOffset = generateIndexedWithOffsetPointcloud( new THREE.Color( 0,1,1 ), width, length ); + pcIndexedOffset.scale.set( 10,10,10 ); + pcIndexedOffset.position.set( 5,0,-5 ); + scene.add( pcIndexedOffset ); + + var pcRegular = generateRegularPointcloud( new THREE.Color( 1,0,1 ), width, length ); + pcRegular.scale.set( 10,10,10 ); + pcRegular.position.set( -5,0,-5 ); + scene.add( pcRegular ); + + pointclouds = [ pcBuffer, pcIndexed, pcIndexedOffset, pcRegular ]; + + // + + var sphereGeometry = new THREE.SphereGeometry( 0.1, 32, 32 ); + var sphereMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, shading: THREE.FlatShading } ); + + for ( var i = 0; i < 40; i++ ) { + + var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); + scene.add( sphere ); + spheres.push( sphere ); + + } + + // + + renderer = new THREE.WebGLRenderer(); + renderer.setSize( window.innerWidth, window.innerHeight ); + + container.appendChild( renderer.domElement ); + + // + + projector = new THREE.Projector(); + raycaster = new THREE.Raycaster(); + raycaster.params.PointCloud.threshold = threshold; + + // + + stats = new Stats(); + stats.domElement.style.position = 'absolute'; + stats.domElement.style.top = '0px'; + container.appendChild( stats.domElement ); + + // + + window.addEventListener( 'resize', onWindowResize, false ); + document.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 = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + + renderer.setSize( window.innerWidth, window.innerHeight ); + + } + + function animate() { + + requestAnimationFrame( animate ); + + render(); + stats.update(); + + } + + var toggle = 0; + + function render() { + + camera.applyMatrix( rotateY ); + camera.updateMatrixWorld( true ); + + vector.set( mouse.x, mouse.y, 0.1 ); + + projector.unprojectVector( vector, camera ); + + raycaster.ray.set( camera.position, vector.sub( camera.position ).normalize() ); + + var intersections = raycaster.intersectObjects( pointclouds ); + intersection = ( intersections.length ) > 0 ? intersections[ 0 ] : null; + + if ( toggle > 0.02 && intersection !== null) { + + spheres[ spheresIndex ].position.copy( intersection.point ); + spheres[ spheresIndex ].scale.set( 1, 1, 1 ); + spheresIndex = ( spheresIndex + 1 ) % spheres.length; + + toggle = 0; + + } + + for ( var i = 0; i < spheres.length; i++ ) { + + var sphere = spheres[ i ]; + sphere.scale.multiplyScalar( 0.98 ); + sphere.scale.clampScalar( 0.01, 1 ); + + } + + toggle += clock.getDelta(); + + renderer.render( scene, camera ); + + } +} \ No newline at end of file diff --git a/threejs/tests/webgl/webgl_lensflares.ts b/threejs/tests/webgl/webgl_lensflares.ts index c8e1bfed49..bb99d701c0 100644 --- a/threejs/tests/webgl/webgl_lensflares.ts +++ b/threejs/tests/webgl/webgl_lensflares.ts @@ -116,7 +116,7 @@ lensFlare.add(textureFlare3, 70, 1.0, THREE.AdditiveBlending); lensFlare.customUpdateCallback = lensFlareUpdateCallback; - lensFlare.position = light.position; + lensFlare.position.copy( light.position ); scene.add(lensFlare); diff --git a/threejs/tests/webgl/webgl_materials.ts b/threejs/tests/webgl/webgl_materials.ts index 1f1dab70c7..da1c311dae 100644 --- a/threejs/tests/webgl/webgl_materials.ts +++ b/threejs/tests/webgl/webgl_materials.ts @@ -12,7 +12,7 @@ var container, stats; var camera, scene, renderer, objects; - var particleLight, pointLight; + var particleLight; var materials = []; @@ -130,8 +130,8 @@ scene.add(directionalLight); - pointLight = new THREE.PointLight(0xffffff, 1); - scene.add(pointLight); + var pointLight = new THREE.PointLight(0xffffff, 1); + particleLight.add(pointLight); // @@ -228,10 +228,6 @@ particleLight.position.y = Math.cos(timer * 5) * 400; particleLight.position.z = Math.cos(timer * 3) * 300; - pointLight.position.x = particleLight.position.x; - pointLight.position.y = particleLight.position.y; - pointLight.position.z = particleLight.position.z; - renderer.render(scene, camera); } diff --git a/threejs/tests/webgl/webgl_particles_billboards.ts b/threejs/tests/webgl/webgl_particles_billboards.ts index 8e786303d7..a2f62fc6a2 100644 --- a/threejs/tests/webgl/webgl_particles_billboards.ts +++ b/threejs/tests/webgl/webgl_particles_billboards.ts @@ -42,10 +42,10 @@ } - material = new THREE.ParticleSystemMaterial({ size: 35, sizeAttenuation: false, map: sprite, transparent: true }); + material = new THREE.PointCloudMaterial({ size: 35, sizeAttenuation: false, map: sprite, transparent: true }); material.color.setHSL(1.0, 0.3, 0.7); - particles = new THREE.ParticleSystem(geometry, material); + particles = new THREE.PointCloud(geometry, material); particles.sortParticles = true; scene.add(particles); diff --git a/threejs/tests/webgl/webgl_postprocessing.ts b/threejs/tests/webgl/webgl_postprocessing.ts index e3aaff31ad..707804c28b 100644 --- a/threejs/tests/webgl/webgl_postprocessing.ts +++ b/threejs/tests/webgl/webgl_postprocessing.ts @@ -80,8 +80,6 @@ requestAnimationFrame(animate); - var time = Date.now(); - object.rotation.x += 0.005; object.rotation.y += 0.01; diff --git a/threejs/three-tests.ts b/threejs/three-tests.ts index 4ff78b618f..46a563a6dd 100644 --- a/threejs/three-tests.ts +++ b/threejs/three-tests.ts @@ -26,12 +26,14 @@ THE SOFTWARE. // webGL renderer test. /// +/// /// /// /// /// /// /// +/// /// /// /// @@ -54,3 +56,4 @@ THE SOFTWARE. /// /// /// + diff --git a/threejs/three.d.ts b/threejs/three.d.ts index 7489001666..41a07f32ba 100644 --- a/threejs/three.d.ts +++ b/threejs/three.d.ts @@ -1,4 +1,4 @@ -// Type definitions for three.js r67 +// Type definitions for three.js r68 // Project: http://mrdoob.github.com/three.js/ // Definitions by: Kon , Satoru Kimura // Definitions: https://github.com/borisyankov/DefinitelyTyped @@ -174,6 +174,15 @@ declare module THREE { clone(camera?: Camera): Camera; } + export class CubeCamera extends Object3D { + constructor( near?: number, far?: number, cubeResolution?: number); + + renderTarget: WebGLRenderTargetCube; + + updateCubeMap( renderer: Renderer, scene: Scene ): void; + + } + /** * Camera with orthographic projection * @@ -326,43 +335,64 @@ declare module THREE { // Core /////////////////////////////////////////////////////////////////////////////////////////////// export class BufferAttribute { - constructor(); + constructor(array: any, itemSize: number); - set(value: number): void; - setX(index: number, x: number): void; - setY(index: number, y: number): void; - setZ(index: number, z: number): void; - setXY(index: number, x: number, y: number): void; - setXYZ(index: number, x: number, y: number, z: number): void; - setXYZW(index: number, x: number, y: number, z: number, w: number): void; + array: any; + itemSize: number; + length: number; + + set(value: number): BufferAttribute; + setX(index: number, x: number): BufferAttribute; + setY(index: number, y: number): BufferAttribute; + setZ(index: number, z: number): BufferAttribute; + setXY(index: number, x: number, y: number): BufferAttribute; + setXYZ(index: number, x: number, y: number, z: number): BufferAttribute; + setXYZW(index: number, x: number, y: number, z: number, w: number): BufferAttribute; } + // deprecated export class Int8Attribute extends BufferAttribute{ - constructor(size: number, itemSize: number); + constructor(data: any[], itemSize: number); } + + // deprecated export class Uint8Attribute extends BufferAttribute { - constructor(size: number, itemSize: number); + constructor(data: any[], itemSize: number); } + + // deprecated export class Uint8ClampedAttribute extends BufferAttribute { - constructor(size: number, itemSize: number); + constructor(data: any[], itemSize: number); } + + // deprecated export class Int16Attribute extends BufferAttribute { - constructor(size: number, itemSize: number); + constructor(data: any[], itemSize: number); } + + // deprecated export class Uint16Attribute extends BufferAttribute { - constructor(size: number, itemSize: number); + constructor(data: any[], itemSize: number); } + + // deprecated export class Int32Attribute extends BufferAttribute { - constructor(size: number, itemSize: number); + constructor(data: any[], itemSize: number); } + + // deprecated export class Uint32Attribute extends BufferAttribute { - constructor(size: number, itemSize: number); + constructor(data: any[], itemSize: number); } + + // deprecated export class Float32Attribute extends BufferAttribute { - constructor(size: number, itemSize: number); + constructor(data: any[], itemSize: number); } + + // deprecated export class Float64Attribute extends BufferAttribute { - constructor(size: number, itemSize: number); + constructor(data: any[], itemSize: number); } /** @@ -401,6 +431,8 @@ declare module THREE { */ applyMatrix(matrix: Matrix4): void; + fromGeometry( geometry: Geometry, settings?: any ): BufferGeometry; + /** * Computes bounding box of the geometry, updating Geometry.boundingBox attribute. * Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are null. @@ -639,7 +671,7 @@ declare module THREE { export interface MorphColor { name: string; - color: Color[]; + colors: Color[]; } export interface MorphNormals { @@ -758,6 +790,11 @@ declare module THREE { */ skinIndices: number[]; + /** + * + */ + lineDistances: number[]; + /** * Bounding box. */ @@ -823,13 +860,18 @@ declare module THREE { /** * */ - lineDistances: number[]; + groupsNeedUpdate: boolean; /** * Bakes matrix transform directly into vertex coordinates. */ applyMatrix(matrix: Matrix4): void; + /** + * + */ + center(): Vector3; + /** * Computes face normals. */ @@ -899,6 +941,11 @@ declare module THREE { */ id: number; + /** + * + */ + uuid: number; + /** * Optional name of the object (doesn't need to be unique). */ @@ -914,6 +961,11 @@ declare module THREE { */ children: Object3D[]; + /** + * Up direction. + */ + up: Vector3; + /** * Object's local position. */ @@ -925,10 +977,9 @@ declare module THREE { rotation: Euler; /** - * Order of axis for Euler angles. + * Global rotation. */ - eulerOrder: string; - // eulerOrder:EulerOrder; + quaternion: Quaternion; /** * Object's local scale. @@ -936,9 +987,14 @@ declare module THREE { scale: Vector3; /** - * Up direction. + * Override depth-sorting order if non null. */ - up: Vector3; + renderDepth: number; + + /** + * When this is set, then the rotationMatrix gets calculated every frame. + */ + rotationAutoUpdate: boolean; /** * Local transform. @@ -946,19 +1002,19 @@ declare module THREE { matrix: Matrix4; /** - * Global rotation. + * The global transform of the object. If the Object3d has no parent, then it's identical to the local transform. */ - quaternion: Quaternion; + matrixWorld: Matrix4; /** - * Use quaternion instead of Euler angles for specifying local rotation. + * When this is set, it calculates the matrix of position, (rotation or quaternion) and scale every frame and also recalculates the matrixWorld property. */ - useQuaternion: boolean; + matrixAutoUpdate: boolean; /** - * Override depth-sorting order if non null. + * When this is set, it calculates the matrixWorld in that frame and resets this property to false. */ - renderDepth: number; + matrixWorldNeedsUpdate: boolean; /** * Object gets rendered if true. @@ -980,54 +1036,95 @@ declare module THREE { */ frustumCulled: boolean; - /** - * When this is set, it calculates the matrix of position, (rotation or quaternion) and scale every frame and also recalculates the matrixWorld property. - */ - matrixAutoUpdate: boolean; - - /** - * When this is set, it calculates the matrixWorld in that frame and resets this property to false. - */ - matrixWorldNeedsUpdate: boolean; - - /** - * When this is set, then the rotationMatrix gets calculated every frame. - */ - rotationAutoUpdate: boolean; - /** * An object that can be used to store custom data about the Object3d. It should not hold references to functions as these will not be cloned. */ userData: any; /** - * The global transform of the object. If the Object3d has no parent, then it's identical to the local transform. + * */ - matrixWorld: Matrix4; + static DefaultUp: Vector3; + /** + * Order of axis for Euler angles. + */ + eulerOrder: string; + // eulerOrder:EulerOrder; + + /** + * Use quaternion instead of Euler angles for specifying local rotation. + */ + useQuaternion: boolean; + /** * This updates the position, rotation and scale with the matrix. */ applyMatrix(matrix: Matrix4): void; + /** + * + */ + setRotationFromAxisAngle(axis: Vector3, angle: number): void; + + /** + * + */ + setRotationFromEuler(euler: Euler ): void; + + /** + * + */ + setRotationFromMatrix(m: Matrix4): void; + + /** + * + */ + setRotationFromQuaternion( q: Quaternion ): void; + + /** + * + * @param angle + */ + rotateX(angle: number): Object3D; + + /** + * + * @param angle + */ + rotateY(angle: number): Object3D; + + /** + * + * @param angle + */ + rotateZ(angle: number): Object3D; + + /** + * + * @param distance + * @param axis + */ + translate( distance: number, axis: Vector3 ): Object3D; + /** * Translates object along x axis by distance. * @param distance Distance. */ - translateX(distance: number): void; + translateX(distance: number): Object3D; /** * Translates object along y axis by distance. * @param distance Distance. */ - translateY(distance: number): void; + translateY(distance: number): Object3D; /** * Translates object along z axis by distance. * @param distance Distance. */ - translateZ(distance: number): void; + translateZ(distance: number): Object3D; /** * Updates the vector from local space to world space. @@ -1057,6 +1154,11 @@ declare module THREE { */ remove(object: Object3D): void; + /** + * + */ + raycast(raycaster: Raycaster, intersects: any): void; + /** * Translates object along arbitrary axis by distance. * @param distance Distance. @@ -1065,10 +1167,22 @@ declare module THREE { traverse(callback: (object: Object3D) => any): void; /** - * Searches whole subgraph recursively to add all objects in the array. - * @param array optional argument that returns the the array with descendants. + * Searches through the object's children and returns the first with a matching id, optionally recursive. + * @param id Unique number of the object instance + * @param recursive Boolean whether to search through the children's children. Default is false. */ - getDescendants(array?: Object3D[]): Object3D[]; + getObjectById(id: string, recursive: boolean): Object3D; + + + /** + * Searches through the object's children and returns the first with a matching name, optionally recursive. + * @param name String to match to the children's Object3d.name property. + * @param recursive Boolean whether to search through the children's children. Default is false. + */ + getObjectByName(name: string, recursive: boolean): Object3D; + + + getChildByName( name: string, recursive: boolean ): Object3D; /** * Updates local transform. @@ -1080,22 +1194,13 @@ declare module THREE { */ updateMatrixWorld(force: boolean): void; + /** + * + * @param object + * @param recursive + */ clone(object?: Object3D, recursive?: boolean): Object3D; - /** - * Searches through the object's children and returns the first with a matching name, optionally recursive. - * @param name String to match to the children's Object3d.name property. - * @param recursive Boolean whether to search through the children's children. Default is false. - */ - getObjectByName(name: string, recursive: boolean): Object3D; - - /** - * Searches through the object's children and returns the first with a matching id, optionally recursive. - * @param id Unique number of the object instance - * @param recursive Boolean whether to search through the children's children. Default is false. - */ - getObjectById(id: string, recursive: boolean): Object3D; - /** * @param axis A normalized vector in object space. * @param distance The distance to translate. @@ -1148,12 +1253,22 @@ declare module THREE { object: Object3D; } + export interface RaycasterParameters { + Sprite?: any; + Mesh?: any; + PointCloud?: any; + LOD?: any; + Line?: any; + } + export class Raycaster { constructor(origin?: Vector3, direction?: Vector3, near?: number, far?: number); ray: Ray; near: number; far: number; + params: RaycasterParameters; precision: number; + linePrecision: number; set(origin: Vector3, direction: Vector3): void; intersectObject(object: Object3D, recursive?: boolean): Intersection[]; intersectObjects(objects: Object3D[], recursive?: boolean): Intersection[]; @@ -1609,17 +1724,34 @@ declare module THREE { initMaterials(materials: Material[], texturePath: string): Material[]; extractUrlBase(url: string): string; addStatusElement(): HTMLElement; + + static Handlers:LoaderHandler; + } + + export interface LoaderHandler{ + handlers:any[]; + add(regex:string, loader:Loader):void; + get(file: string):Loader; } export class BufferGeometryLoader { constructor(manager?: LoadingManager); - load(url: string, onLoad: (bufferGeometry: BufferGeometry) => void): void; + load(url: string, onLoad: (bufferGeometry: BufferGeometry) => void, onProgress?: (event: any) => void, onError?: (event: any) => void): void; setCrossOrigin(crossOrigin: string): void; parse(json: any): BufferGeometry; } + export class GeometryLoader { + constructor(manager?: LoadingManager); + + load(url: string, onLoad: (bufferGeometry: BufferGeometry) => void, onProgress?: (event: any) => void, onError?: (event: any) => void): void; + setCrossOrigin(crossOrigin: string): void; + parse(json: any): Geometry; + + } + export class Cache{ constructor(); @@ -1659,12 +1791,16 @@ declare module THREE { * @param callback. This function will be called with the loaded model as an instance of geometry when the load is completed. * @param texturePath If not specified, textures will be assumed to be in the same folder as the Javascript model file. */ - load(url: string, callback: (geometry: Geometry, materials: Material[]) => void , texturePath?: string): void; + load(url: string, callback: (geometry: JSonLoaderResultGeometry, materials: Material[]) => void , texturePath?: string): void; parse(json:string, texturePath:string): any; loadAjaxJSON(context: JSONLoader, url: string, callback: (geometry: Geometry, materials: Material[]) => void , texturePath?: string, callbackProgress?: (progress: Progress) => void ): void; } + export class JSonLoaderResultGeometry extends Geometry { + animation: AnimationData; + } + /** * Handles and keeps track of loaded and pending data. */ @@ -1713,76 +1849,6 @@ declare module THREE { parseObject(data: any, geometries: any[], materials: Material[]): T; } - interface SceneLoaderResult{ - scene: Scene; - geometries: {[id:string]:Geometry;}; - face_materials: {[id:string]:Material;}; - materials: {[id:string]:Material;}; - textures: {[id:string]:Texture;}; - objects: {[id:string]:Object3D;}; - cameras: {[id:string]:Camera;}; - lights: {[id:string]:Light;}; - fogs: {[id:string]:IFog;}; - empties: {[id:string]:any;}; - groups: {[id:string]:any;}; - } - - interface SceneLoaderProgress{ - totalModels: number; - totalTextures: number; - loadedModels: number; - loadedTextures: number; - } - - /** - * A loader for loading a complete scene out of a JSON file. - */ - export class SceneLoader { - constructor(); - - /** - * Will be called when load starts. - * The default is a function with empty body. - */ - onLoadStart: () => void; - - /** - * Will be called while load progresses. - * The default is a function with empty body. - */ - onLoadProgress: () => void; - - /** - * Will be called when each element in the scene completes loading. - * The default is a function with empty body. - */ - onLoadComplete: () => void; - - /** - * Will be called when load completes. - * The default is a function with empty body. - */ - callbackSync: (result: SceneLoaderResult) => void; - - /** - * Will be called as load progresses. - * The default is a function with empty body. - */ - callbackProgress: (progress: SceneLoaderProgress, result: SceneLoaderResult) => void; - hierarchyHandlers: any; - geometryHandlers: any; - - /** - * @param url - * @param callbackFinished This function will be called with the loaded model as an instance of scene when the load is completed. - */ - load(url: string, onLoad: (result: SceneLoaderResult) => void): void; - setCrossOrigin(crossOrigin: string): void; - addHierarchyHandler(typeID: string, loaderClass: any): void; - parse(json: any, callbackFinished: (result: SceneLoaderResult) => void, url: string): void; - addGeometryHandler(typeID: string, loaderClass: any): void; - } - /** * Class for loading a texture. * Unlike other loaders, this one emits events instead of using predefined callbacks. So if you're interested in getting notified when things happen, you need to add listeners to the object. @@ -1804,9 +1870,11 @@ declare module THREE { cache: Cache; crossOrigin: string; + responseType: string; load(url: string, onLoad?: (responseText: string) => void, onProgress?: (event: any) => void, onError?: (event: any) => void): void; setCrossOrigin(crossOrigin: string): void; + setResponseType(responseType: string): void; } // Materials ////////////////////////////////////////////////////////////////////////////////// @@ -1977,6 +2045,7 @@ declare module THREE { fog?: boolean; lightMap?: Texture; specularMap?: Texture; + alphaMap?: Texture; envMap?: Texture; skinning?: boolean; morphTargets?: boolean; @@ -1999,6 +2068,7 @@ declare module THREE { fog: boolean; lightMap: Texture; specularMap: Texture; + alphaMap: Texture; envMap: Texture; skinning: boolean; morphTargets: boolean; @@ -2044,6 +2114,7 @@ declare module THREE { map?: Texture; lightMap?: Texture; specularMap?: Texture; + alphaMap?: Texture; envMap?: Texture; reflectivity?: number; refractionRatio?: number; @@ -2070,6 +2141,7 @@ declare module THREE { map: Texture; lightMap: Texture; specularMap: Texture; + alphaMap: Texture; envMap: Texture; reflectivity: number; refractionRatio: number; @@ -2116,6 +2188,7 @@ declare module THREE { map?: Texture; lightMap?: Texture; specularMap?: Texture; + alphaMap?: Texture; envMap?: Texture; reflectivity?: number; refractionRatio?: number; @@ -2150,6 +2223,7 @@ declare module THREE { map: Texture; lightMap: Texture; specularMap: Texture; + alphaMap: Texture; envMap: Texture; reflectivity: number; refractionRatio: number; @@ -2169,17 +2243,17 @@ declare module THREE { clone(): MeshPhongMaterial; } - export interface ParticleSystemMaterialParameters { + export interface PointCloudMaterialParameters { color?: number; map?: Texture; size?: number; sizeAttenuation?: boolean; - vertexColors?: boolean; + vertexColors?: Colors; fog?: boolean; } - export class ParticleSystemMaterial extends Material { - constructor(parameters?: ParticleSystemMaterialParameters); + export class PointCloudMaterial extends Material { + constructor(parameters?: PointCloudMaterialParameters); color: Color; map: Texture; size: number; @@ -2187,7 +2261,17 @@ declare module THREE { vertexColors: boolean; fog: boolean; - clone(): ParticleSystemMaterial; + clone(): PointCloudMaterial; + } + + // deprecated + export class ParticleBasicMaterial extends PointCloudMaterial{ + + } + + // deprecated + export class ParticleSystemMaterial extends PointCloudMaterial{ + } export class RawShaderMaterial extends ShaderMaterial { @@ -2337,6 +2421,7 @@ declare module THREE { distanceToPoint(point: Vector3): number; containsPoint(point: Vector3): boolean; setFromCenterAndSize(center: Vector3, size: number): Box3; + setFromObject(object: Object3D): Box3; } export interface HSL { @@ -2466,6 +2551,157 @@ declare module THREE { clone(): Color; } + export class ColorKeywords { + static test2: string; + static aliceblue: string; + static antiquewhite: string; + static aqua: string; + static aquamarine: string; + static azure: string; + static beige: string; + static bisque: string; + static black: string; + static blanchedalmond: string; + static blue: string; + static blueviolet: string; + static brown: string; + static burlywood: string; + static cadetblue: string; + static chartreuse: string; + static chocolate: string; + static coral: string; + static cornflowerblue: string; + static cornsilk: string; + static crimson: string; + static cyan: string; + static darkblue: string; + static darkcyan: string; + static darkgoldenrod: string; + static darkgray: string; + static darkgreen: string; + static darkgrey: string; + static darkkhaki: string; + static darkmagenta: string; + static darkolivegreen: string; + static darkorange: string; + static darkorchid: string; + static darkred: string; + static darksalmon: string; + static darkseagreen: string; + static darkslateblue: string; + static darkslategray: string; + static darkslategrey: string; + static darkturquoise: string; + static darkviolet: string; + static deeppink: string; + static deepskyblue: string; + static dimgray: string; + static dimgrey: string; + static dodgerblue: string; + static firebrick: string; + static floralwhite: string; + static forestgreen: string; + static fuchsia: string; + static gainsboro: string; + static ghostwhite: string; + static gold: string; + static goldenrod: string; + static gray: string; + static green: string; + static greenyellow: string; + static grey: string; + static honeydew: string; + static hotpink: string; + static indianred: string; + static indigo: string; + static ivory: string; + static khaki: string; + static lavender: string; + static lavenderblush: string; + static lawngreen: string; + static lemonchiffon: string; + static lightblue: string; + static lightcoral: string; + static lightcyan: string; + static lightgoldenrodyellow: string; + static lightgray: string; + static lightgreen: string; + static lightgrey: string; + static lightpink: string; + static lightsalmon: string; + static lightseagreen: string; + static lightskyblue: string; + static lightslategray: string; + static lightslategrey: string; + static lightsteelblue: string; + static lightyellow: string; + static lime: string; + static limegreen: string; + static linen: string; + static magenta: string; + static maroon: string; + static mediumaquamarine: string; + static mediumblue: string; + static mediumorchid: string; + static mediumpurple: string; + static mediumseagreen: string; + static mediumslateblue: string; + static mediumspringgreen: string; + static mediumturquoise: string; + static mediumvioletred: string; + static midnightblue: string; + static mintcream: string; + static mistyrose: string; + static moccasin: string; + static navajowhite: string; + static navy: string; + static oldlace: string; + static olive: string; + static olivedrab: string; + static orange: string; + static orangered: string; + static orchid: string; + static palegoldenrod: string; + static palegreen: string; + static paleturquoise: string; + static palevioletred: string; + static papayawhip: string; + static peachpuff: string; + static peru: string; + static pink: string; + static plum: string; + static powderblue: string; + static purple: string; + static red: string; + static rosybrown: string; + static royalblue: string; + static saddlebrown: string; + static salmon: string; + static sandybrown: string; + static seagreen: string; + static seashell: string; + static sienna: string; + static silver: string; + static skyblue: string; + static slateblue: string; + static slategray: string; + static slategrey: string; + static snow: string; + static springgreen: string; + static steelblue: string; + static tan: string; + static teal: string; + static thistle: string; + static tomato: string; + static turquoise: string; + static violet: string; + static wheat: string; + static white: string; + static whitesmoke: string; + static yellow: string; + static yellowgreen: string; + } + export class Euler { constructor(x?: number, y?: number, z?: number, order?: string); @@ -2701,17 +2937,10 @@ declare module THREE { * m.multiply( m3 ); */ export class Matrix4 implements Matrix { - - /** - * Creates an identity matrix. - */ - constructor(); - - /** * Initialises the matrix with the supplied n11..n44 values. */ - constructor(n11: number, n12: number, n13: number, n14: number, n21: number, n22: number, n23: number, n24: number, n31: number, n32: number, n33: number, n34: number, n41: number, n42: number, n43: number, n44: number); + constructor(n11?: number, n12?: number, n13?: number, n14?: number, n21?: number, n22?: number, n23?: number, n24?: number, n31?: number, n32?: number, n33?: number, n34?: number, n41?: number, n42?: number, n43?: number, n44?: number); /** * Float32Array with matrix values. @@ -2936,11 +3165,11 @@ declare module THREE { * Copies values of q to this quaternion. */ copy(q: Quaternion): Quaternion; - setFromEuler(euler: Euler, update?: boolean): Quaternion; + /** * Sets this quaternion from rotation specified by Euler angles. */ - setFromEuler(v: Vector3, order: string): Quaternion; + setFromEuler(euler: Euler, update?: boolean): Quaternion; /** * Sets this quaternion from rotation specified by axis and angle. @@ -2997,6 +3226,8 @@ declare module THREE { equals(v: Quaternion): boolean; + dot(v: Vector3): number; + lengthSq(): number; fromArray(n: number[]): Quaternion; @@ -3021,10 +3252,12 @@ declare module THREE { equals(ray: Ray): boolean; intersectBox(box: Box3, optionalTarget?: Vector3): Vector3; intersectPlane(plane: Plane, optionalTarget?: Vector3): Vector3; + intersectSphere(sphere: Sphere, optionalTarget?: Vector3): Vector3; intersectTriangle(a: Vector3, b: Vector3, c: Vector3, backfaceCulling: boolean, optionalTarget?: Vector3): Vector3; isIntersectionBox(box: Box3): boolean; isIntersectionPlane(plane: Plane): boolean; isIntersectionSphere(sphere: Sphere): boolean; + recast(t: number): Ray; set(origin: Vector3, direction: Vector3): Ray; } @@ -3296,6 +3529,8 @@ declare module THREE { */ negate(): Vector2; + + /** * Computes dot product of this vector and v. */ @@ -3715,14 +3950,13 @@ declare module THREE { export class Bone extends Object3D { constructor(belongsToSkin: SkinnedMesh); - skinMatrix: Matrix4; skin: SkinnedMesh; accumulatedRotWeight: number; accumulatedPosWeight: number; accumulatedSclWeight: number; - update(parentSkinMatrix?: Matrix4, forceUpdate?: boolean): void; + update(forceUpdate?: boolean): void; } export class Line extends Object3D { @@ -3733,8 +3967,10 @@ declare module THREE { constructor(geometry?: BufferGeometry, material?: LineBasicMaterial, type?: number); constructor(geometry?: BufferGeometry, material?: ShaderMaterial, type?: number); geometry: Geometry; - material: Material; + material: LineBasicMaterial; type: LineType; + + raycast(raycaster: Raycaster, intersects: any): void; clone(object?: Line): Line; } @@ -3748,6 +3984,7 @@ declare module THREE { objects: any[]; addLevel(object: Object3D, distance?: number): void; getObjectForDistance(distance: number): Object3D; + raycast(raycaster: Raycaster, intersects: any): void; update(camera: Camera): void; clone(): LOD; } @@ -3761,6 +3998,7 @@ declare module THREE { getMorphTargetIndexByName(name: string): number; updateMorphTargets(): void; + raycast(raycaster: Raycaster, intersects: any): void; clone(object?: Mesh): Mesh; } @@ -3791,7 +4029,7 @@ declare module THREE { parseAnimations(): void; updateAnimation(delta: number): void; setAnimationLabel(label: string, start: number, end: number): void; - + interpolateTargets( a: number, b: number, t: number ): void; clone(object?: MorphAnimMesh): MorphAnimMesh; } @@ -3800,15 +4038,15 @@ declare module THREE { * * @see src/objects/ParticleSystem.js */ - export class ParticleSystem extends Object3D { + export class PointCloud extends Object3D { /** * @param geometry An instance of Geometry. * @param material An instance of Material (optional). */ - constructor(geometry: Geometry, material?: ParticleSystemMaterial); + constructor(geometry: Geometry, material?: PointCloudMaterial); constructor(geometry: Geometry, material?: ShaderMaterial); - constructor(geometry: BufferGeometry, material?: ParticleSystemMaterial); + constructor(geometry: BufferGeometry, material?: PointCloudMaterial); constructor(geometry: BufferGeometry, material?: ShaderMaterial); /** @@ -3821,24 +4059,21 @@ declare module THREE { */ material: Material; - /** - * Specifies whether the particle system will be culled if it's outside the camera's frustum. By default this is set to false. - */ - frustrumCulled: boolean; - sortParticles: boolean; - clone(object?: ParticleSystem): ParticleSystem; + raycast(raycaster: Raycaster, intersects: any): void; + clone(object?: PointCloud): PointCloud; } export class Skeleton extends Mesh { - constructor(boneList: Bone[], useVertexTexture: boolean); + constructor(bones: Bone[], boneInverses?: Matrix4[], useVertexTexture?: boolean); bones: Bone[]; useVertexTexture: boolean; boneMatrices: Float32Array; - addBone(bone: Bone): Bone; calculateInverses(bone: Bone): void; + pose(): void; + update(): void; } export class SkinnedMesh extends Mesh { @@ -3850,10 +4085,14 @@ declare module THREE { constructor(geometry?: Geometry, material?: MeshPhongMaterial, useVertexTexture?: boolean); constructor(geometry?: Geometry, material?: ShaderMaterial, useVertexTexture?: boolean); - identityMatrix: Matrix4; + bindMode: string; + bindMatrix: Matrix4; + bindMatrixInverse: Matrix4; + bind( skeleton: Skeleton, bindMatrix?: Matrix4 ): void; pose(): void; normalizeSkinWeights(): void; + updateMatrixWorld(force?: boolean): void; clone(object?: SkinnedMesh): SkinnedMesh; } @@ -3863,6 +4102,7 @@ declare module THREE { geometry: BufferGeometry; material: SpriteMaterial; + raycast(raycaster: Raycaster, intersects: any): void; updateMatrix(): void; clone(object?: Sprite): Sprite; } @@ -3899,6 +4139,8 @@ declare module THREE { supportsVertexTextures(): void; setSize(width: number, height: number, updateStyle?: boolean): void; setClearColorHex(hex: number, alpha?: number): void; + getClearColor(): Color; + getClearAlpha(): number; setViewport(x: number, y: number, width: number, height: number): void; } @@ -4319,6 +4561,7 @@ declare module THREE { copy(vertex: RenderableVertex): void; } + // Renderers / Shaders ///////////////////////////////////////////////////////////////////// // Renderers / Shaders ///////////////////////////////////////////////////////////////////// export interface ShaderChunk { [name: string]: string; @@ -4514,6 +4757,24 @@ declare module THREE { clone(): CompressedTexture; } + export class CubeTexture extends Texture { + constructor( + images: any[], // HTMLImageElement or HTMLCanvasElement + mapping?: Mapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: TextureFilter, + minFilter?: TextureFilter, + format?: PixelFormat, + type?: TextureDataType, + anisotropy?: number + ); + + images: any[]; + + clone(texture?: CubeTexture): CubeTexture; + } + export class DataTexture extends Texture { constructor( data: ImageData, @@ -4601,6 +4862,9 @@ declare module THREE { clone(): Texture; dispose(): void; + + DEFAULT_IMAGE: any; + DEFAULT_MAPPING: any; } // Extras ///////////////////////////////////////////////////////////////////// @@ -4634,12 +4898,11 @@ declare module THREE { export var GeometryUtils: { // DEPRECATED merge(geometry1: Geometry, object2: Mesh, materialIndexOffset?: number): void; + // DEPRECATED merge(geometry1: Geometry, object2: Geometry, materialIndexOffset?: number): void; - randomPointInTriangle(vectorA: Vector3, vectorB: Vector3, vectorC: Vector3): Vector3; - randomPointInFace(face: Face3, geometry: Geometry, useCachedAreas: boolean): Vector3; - randomPointsInGeometry(geometry: Geometry, points: number): Vector3; - triangleArea(vectorA: Vector3, vectorB: Vector3, vectorC: Vector3): number; + + // DEPRECATED center(geometry: Geometry): Vector3; }; @@ -4647,12 +4910,9 @@ declare module THREE { crossOrigin: string; generateDataTexture(width: number, height: number, color: Color): DataTexture; - parseDDS(buffer: ArrayBuffer, loadMipmaps: boolean): { mipmaps: { data: Uint8Array; width: number; height: number; }[]; width: number; height: number; format: number; mipmapCount: number; }; - loadCompressedTexture(url: string, mapping?: Mapping, onLoad?: (texture: Texture) => void, onError?: (message: string) => void): Texture; loadTexture(url: string, mapping?: Mapping, onLoad?: (texture: Texture) => void, onError?: (message: string) => void): Texture; - getNormalMap(image: HTMLImageElement, depth?: number): HTMLCanvasElement; - loadCompressedTextureCube(array: string[], mapping?: Mapping, onLoad?: () => void, onError?: (message: string) => void): Texture; loadTextureCube(array: string[], mapping?: Mapping, onLoad?: () => void , onError?: (message: string) => void ): Texture; + getNormalMap(image: HTMLImageElement, depth?: number): HTMLCanvasElement; }; export var SceneUtils: { @@ -4684,7 +4944,7 @@ declare module THREE { } export class Animation { - constructor(root: Mesh, name: string); + constructor(root: Mesh, data: AnimationData); root: Mesh; data: AnimationData; @@ -4692,37 +4952,37 @@ declare module THREE { currentTime: number; timeScale: number; isPlaying: boolean; - isPaused: boolean; loop: boolean; weight: number; - interpolationType: AnimationInterpolation; keyTypes: string[]; play(startTime?: number, weight?: number): void; - pause(): void; stop(): void; reset(): void; update(deltaTimeMS: number): void; - interpolateCatmullRom(points: Vector3[], scale: number): Vector3[]; - interpolate(p0: number, p1: number, p2: number, p3: number, t: number, t2: number, t3: number): number; - getNextKeyWith(type: string, h: number, key: number): KeyFrame; // ???? + getNextKeyWith(type: string, h: number, key: number): KeyFrame; getPrevKeyWith(type: string, h: number, key: number): KeyFrame; } - export class AnimationInterpolation { } - export var AnimationHandler: { - CATMULLROM: AnimationInterpolation; - CATMULLROM_FORWARD: AnimationInterpolation; - LINEAR: AnimationInterpolation; + LINEAR: number; + CATMULLROM: number; + CATMULLROM_FORWARD: number; - remove(name: string): void; - removeFromUpdate(animation: Animation): void; - get(name: string): AnimationData; - update(deltaTimeMS: number): void; + animations: any[]; + + init(data: Animation): void; parse(root: Mesh): Object3D[]; + play(animation: Animation): void; + stop(animation: Animation): void; + update(deltaTimeMS: number): void; + + // deprecated add(data: AnimationData): void; - addToUpdate(animation: Animation): void; + // deprecated + get(name: string): AnimationData; + // deprecated + remove(name: string): void; }; export class MorphAnimation { @@ -4741,7 +5001,7 @@ declare module THREE { } export class KeyFrameAnimation { - constructor(root: Mesh, data: any, JITCompile?: boolean); + constructor(data: any); root: Mesh; data: Object; @@ -4753,55 +5013,13 @@ declare module THREE { loop: number; JITCompile: boolean; - play(loop?: number, startTimeMS?: number): void; - pause(): void; + play(startTime?: number): void; stop(): void; - update(deltaTimeMS: number): void; - interpolateCatmullRom(points: Vector3[], scale: number): Vector3[]; - getNextKeyWith(type: string, h: number, key: number): KeyFrame; // ???? + update(delta: number): void; + getNextKeyWith(type: string, h: number, key: number): KeyFrame; getPrevKeyWith(type: string, h: number, key: number): KeyFrame; } - // Extras / Cameras ///////////////////////////////////////////////////////////////////// - - export class CombinedCamera extends Camera { - constructor(width: number, height: number, fov: number, near: number, far: number, orthoNear: number, orthoFar: number); - - fov: number; - right: number; - bottom: number; - cameraP: PerspectiveCamera; - top: number; - zoom: number; - far: number; - near: number; - inPerspectiveMode: boolean; - cameraO: OrthographicCamera; - inOrthographicMode: boolean; - left: number; - - toBottomView(): void; - setFov(fov: number): void; - toBackView(): void; - setZoom(zoom: number): void; - setLens(focalLength: number, frameHeight?: number): number; - toFrontView(): void; - toLeftView(): void; - updateProjectionMatrix(): void; - toTopView(): void; - toOrthographic(): void; - setSize(width: number, height: number): void; - toPerspective(): void; - toRightView(): void; - } - - export class CubeCamera extends Object3D { - constructor(near: number, far: number, cubeResolution: number); - - renderTarget: WebGLRenderTargetCube; - updateCubeMap(renderer: Renderer, scene: Scene): void; - } - // Extras / Curves ///////////////////////////////////////////////////////////////////// export class ArcCurve extends EllipseCurve { constructor(aX: number, aY: number, xRadius: number, yRadius: number, aStartAngle: number, aEndAngle: number, aClockwise: boolean ); @@ -5310,11 +5528,13 @@ declare module THREE { } export class SkeletonHelper extends Line { - constructor(bone: Bone); + constructor(bone: Object3D); - skeleton: Skeleton; + bones: Bone[]; + root: Object3D; + matrixWorld: Matrix4; matrixAutoUpdate: boolean; - + getBoneList(object: Object3D): Bone[]; update(): void; }