提交 280a28df 编写于 作者: A alteredq

Merged with mrdoob's branch.

All examples work. Now just need to port Blender exporter changes to 2.58 version.
因为 它太大了无法显示 source diff 。你可以改为 查看blob
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -90,7 +90,7 @@
<script type="text/javascript" src="../src/extras/ShaderUtils.js"></script>
<script type="text/javascript" src="../src/extras/animation/AnimationHandler.js"></script>
<script type="text/javascript" src="../src/extras/animation/Animation.js"></script>
<script type="text/javascript" src="../src/extras/cameras/QuakeCamera.js"></script>
<script type="text/javascript" src="../src/extras/cameras/FPCamera.js"></script>
<script type="text/javascript" src="../src/extras/cameras/PathCamera.js"></script>
<script type="text/javascript" src="../src/extras/cameras/FlyCamera.js"></script>
<script type="text/javascript" src="../src/extras/cameras/RollCamera.js"></script>
......
......@@ -70,7 +70,7 @@
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2( 0x000000, 0.0035 );
camera = new THREE.QuakeCamera( {
camera = new THREE.FPCamera( {
fov: 50, aspect: window.innerWidth / window.innerHeight, near: 1, far: 10000,
movementSpeed: 70, lookSpeed: 0.05, noFly: true, lookVertical: false
} );
......
......@@ -91,7 +91,7 @@
<script type="text/javascript" src="../src/extras/ShaderUtils.js"></script>
<script type="text/javascript" src="../src/extras/animation/AnimationHandler.js"></script>
<script type="text/javascript" src="../src/extras/animation/Animation.js"></script>
<script type="text/javascript" src="../src/extras/cameras/QuakeCamera.js"></script>
<script type="text/javascript" src="../src/extras/cameras/FPCamera.js"></script>
<script type="text/javascript" src="../src/extras/cameras/PathCamera.js"></script>
<script type="text/javascript" src="../src/extras/cameras/FlyCamera.js"></script>
<script type="text/javascript" src="../src/extras/cameras/RollCamera.js"></script>
......
......@@ -44,7 +44,8 @@ body {
<script type="text/javascript">
var scene, camera, renderer, info, mouse2d, sun, cube;
var camera, scene, projector, renderer,
info, mouse = { x: 0, y: 0 }, sun, cube;
var bounce = 0;
......@@ -57,10 +58,11 @@ function init() {
camera = new THREE.Camera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = -500;
mouse2d = new THREE.Vector3( 0, 0, 1 );
scene = new THREE.Scene();
projector = new THREE.Projector();
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild(renderer.domElement);
......@@ -101,9 +103,8 @@ function createCube( s, p ) {
function onDocumentMouseMove( event ) {
event.preventDefault();
mouse2d.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse2d.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
mouse2d.z = 1;
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
};
......@@ -111,19 +112,16 @@ function animate() {
requestAnimationFrame( animate );
var r = new THREE.Ray();
r.origin.copy( mouse2d );
info.innerHTML = "";
var matrix = camera.matrixWorld.clone();
matrix.multiplySelf( THREE.Matrix4.makeInvert( camera.projectionMatrix ) );
matrix.multiplyVector3( r.origin );
r.direction = r.origin.clone().subSelf( camera.position );
var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
projector.unprojectVector( vector, camera );
info.innerHTML = "";
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var c = THREE.Collisions.rayCastNearest( r );
var c = THREE.Collisions.rayCastNearest( ray );
if( c ) {
if ( c ) {
info.innerHTML += "Found @ distance " + c.distance.toFixed(2);
c.mesh.materials[ 0 ].color.setHex( 0xaa0000 );
......
......@@ -45,18 +45,15 @@ body {
<script type="text/javascript">
var scene, camera, renderer, info, mouse2d, sun, loader, stats;
var camera, scene, projector, renderer,
info, mouse = { x: 0, y: 0 }, sun, loader, stats;
var meshes = [];
var theta = 0;
var camdist = 1500;
var totalFaces = 0;
var totalColliders = 0;
var ray = new THREE.Ray();
var matrix = new THREE.Matrix4(),
matrix2 = new THREE.Matrix4();
var totalFaces = 0, totalColliders = 0;
function init() {
......@@ -67,12 +64,13 @@ function init() {
camera = new THREE.Camera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = camdist;
mouse2d = new THREE.Vector3( 0, 0, 1 );
loader = new THREE.JSONLoader( );
scene = new THREE.Scene();
projector = new THREE.Projector();
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
......@@ -152,7 +150,7 @@ function loadCube(p) {
addCube( new THREE.Vector3( 0, -sy, -sz*2), geometry );
addCube( new THREE.Vector3( sx,-sy, -sz*2), geometry );
//info.innerHTML = "Total colliders: " + totalColliders + " (Faces: " + totalFaces + ")<br>";
// info.innerHTML = "Total colliders: " + totalColliders + " (Faces: " + totalFaces + ")<br>";
};
......@@ -186,9 +184,8 @@ function addCube( p, g) {
function onDocumentMouseMove( event ) {
event.preventDefault();
mouse2d.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse2d.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
mouse2d.z = 1;
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
};
......@@ -197,15 +194,6 @@ function animate() {
requestAnimationFrame( animate );
ray.origin.copy( mouse2d );
matrix.copy( camera.matrixWorld );
matrix.multiplySelf( THREE.Matrix4.makeInvert( camera.projectionMatrix, matrix2 ) );
matrix.multiplyVector3( ray.origin );
ray.direction.copy( ray.origin );
ray.direction.subSelf( camera.position );
if( meshes.length == 0 ) return;
var i, l = meshes.length;
......@@ -216,6 +204,10 @@ function animate() {
}
var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var c = THREE.Collisions.rayCastNearest( ray );
......
......@@ -45,18 +45,15 @@ body {
<script type="text/javascript">
var scene, camera, renderer, info, mouse2d, sun, loader, stats, line;
var camera, scene, projector, renderer,
info, mouse = { x: 0, y: 0 }, sun, loader, stats, line;
var meshes = [];
var theta = 0;
var camdist = 500;
var totalFaces = 0;
var totalColliders = 0;
var ray = new THREE.Ray();
var matrix = new THREE.Matrix4(),
matrix2 = new THREE.Matrix4();
var totalFaces = 0, totalColliders = 0;
function init() {
......@@ -67,12 +64,13 @@ function init() {
camera = new THREE.Camera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = camdist;
mouse2d = new THREE.Vector3( 0, 0, 1 );
loader = new THREE.JSONLoader( );
scene = new THREE.Scene();
projector = new THREE.Projector();
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
......@@ -139,9 +137,8 @@ function addCube( p, g) {
function onDocumentMouseMove( event ) {
event.preventDefault();
mouse2d.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse2d.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
mouse2d.z = 1;
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
};
......@@ -149,20 +146,13 @@ function onDocumentMouseMove( event ) {
function animate() {
requestAnimationFrame( animate );
ray.origin.copy( mouse2d );
matrix.copy( camera.matrixWorld );
matrix.multiplySelf( THREE.Matrix4.makeInvert( camera.projectionMatrix, matrix2 ) );
matrix.multiplyVector3( ray.origin );
ray.direction.copy( ray.origin );
ray.direction.subSelf( camera.position );
//var ray2 = new THREE.Ray();
//ray2.origin = ray.origin.clone();
var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
if( meshes.length == 0 ) return;
if ( meshes.length == 0 ) return;
var i, l = meshes.length;
......
......@@ -48,23 +48,26 @@
<script type="text/javascript">
var scene, camera, renderer, info, mouse2d, sun;
var camera, scene, projector, renderer,
info, mouse = { x: 0, y: 0 }, sun;
var theta = 0;
var camdist = 1500;
var geoms = [];
function init(){
function init () {
container = document.createElement('div');
document.body.appendChild(container);
info = document.getElementById("info");
camera = new THREE.Camera(40, window.innerWidth / window.innerHeight, 1, 10000);
mouse2d = new THREE.Vector3(0, 0, 1);
scene = new THREE.Scene();
projector = new THREE.Projector();
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
......@@ -137,23 +140,23 @@
}
function onDocumentMouseMove(event){
event.preventDefault();
mouse2d.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse2d.y = -(event.clientY / window.innerHeight) * 2 + 1;
mouse2d.z = 1;
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
function animate(){
requestAnimationFrame(animate);
var r = new THREE.Ray();
r.origin = mouse2d.clone();
var matrix = camera.matrixWorld.clone();
matrix.multiplySelf(THREE.Matrix4.makeInvert(camera.projectionMatrix));
matrix.multiplyVector3(r.origin);
r.direction = r.origin.clone().subSelf(camera.position);
requestAnimationFrame( animate );
for (var i = 0; i < geoms.length; i++) {
var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
for ( var i = 0; i < geoms.length; i++) {
geoms[i].materials[0].color = new THREE.Color(0x007700);
}
......@@ -162,14 +165,14 @@
// Raycast all
ts = new Date().getTime();
var cs = THREE.Collisions.rayCastAll( r );
var cs = THREE.Collisions.rayCastAll( ray );
tt = new Date().getTime() - ts;
if ( cs.length > 0 ) {
info.innerHTML = cs.length + " colliders found in " + tt;
for ( var i = 0; i < cs.length; i++ ) {
for ( var i = 0; i < cs.length; i ++ ) {
cs[ i ].mesh.materials[ 0 ].color.setHex( 0xaa0000 );
......@@ -186,7 +189,7 @@
// Raycast nearest
ts = new Date().getTime();
var c = THREE.Collisions.rayCastNearest( r );
var c = THREE.Collisions.rayCastNearest( ray );
tt = new Date().getTime() - ts;
if ( c ) {
......@@ -211,7 +214,8 @@
renderer.render( scene, camera );
stats.update();
stats.update();
}
function vts(v){
......
......@@ -48,7 +48,7 @@
</script>
<script type="text/javascript">
var scene, camera, renderer, info, mouse2d, sun, loader, sphere, debugNormal;
var camera, scene, renderer, info, mouse2d, sun, loader, sphere, debugNormal;
var range = 400;
var speed = 1;
......
......@@ -43,15 +43,14 @@ body {
<script type="text/javascript">
var scene, camera, renderer, info, mouse2d, sun, loader, sphere, ray;
var camera, scene, renderer,
info, mouse2d, sun, loader, sphere, ray;
var theta = 0;
var radius = 250;
var speed = 0.0015;
var sphereSize = 4;
var theta = 0, radius = 250, speed = 0.002, sphereSize = 4;
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
......@@ -71,7 +70,6 @@ function init() {
sphere = new THREE.Mesh( new THREE.SphereGeometry( sphereSize, 10, 10 ), new THREE.MeshLambertMaterial( { color: 0xff0000 } ) );
scene.addObject(sphere);
camera.target = sphere;
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
......@@ -123,11 +121,10 @@ function animate() {
//info.innerHTML = "No intersection";
}
theta += speed;
camera.target.position.copy( sphere.position );
renderer.render( scene, camera );
}
......
......@@ -50,14 +50,11 @@
<script type="text/javascript">
var scene, camera, renderer, info, mouse2d, sun, loader, sphere;
var camera, scene, renderer, info, mouse2d, sun, loader, sphere;
var range = 400;
var speed = 1;
var sphereSize = 4;
var cubes = [];
var range = 400, speed = 1, sphereSize = 4;
var cubes = [];
function init(){
container = document.createElement('div');
......
<!DOCTYPE html>
<html>
<title>three.js webgl - fly camera - earth</title>
<style type="text/css">
<style type="text/css">
body {
background:#000;
color: #eee;
......@@ -26,14 +26,14 @@
color: #0080ff;
}
b { color:orange }
</style>
<script type="text/javascript" src="../build/Three.js"></script>
</style>
<script type="text/javascript" src="../build/Three.js"></script>
<script type="text/javascript" src="js/Detector.js"></script>
<script type="text/javascript" src="js/RequestAnimationFrame.js"></script>
<script type="text/javascript" src="js/RequestAnimationFrame.js"></script>
<script type="text/javascript" src="js/Stats.js"></script>
</head>
......@@ -58,11 +58,11 @@
var MARGIN = 0;
var SCREEN_HEIGHT = window.innerHeight - MARGIN * 2;
var SCREEN_WIDTH = window.innerWidth;
var ENABLE_LENSFLARES = false;
var lensFlare, lensFlareRotate;
var container, stats;
var camera, scene, sceneCube, renderer;
var geometry, meshPlanet, meshClouds, meshMoon;
......@@ -72,18 +72,18 @@
var t, d, dPlanet, dMoon, dMoonVec = new THREE.Vector3();
var postprocessing = { enabled : true, bloom: false };
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
document.body.appendChild( container );
camera = new THREE.FlyCamera({
fov: 25,
fov: 25,
aspect: SCREEN_WIDTH / SCREEN_HEIGHT,
movementSpeed: 1000,
domElement: container,
......@@ -99,7 +99,7 @@
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2( 0x000000, 0.00000025 );
dirLight = new THREE.DirectionalLight( 0xffffff );
dirLight.position.set( -1, 0, 1 );
dirLight.position.normalize();
......@@ -108,7 +108,7 @@
pointLight = new THREE.PointLight( 0x000000 );
pointLight.position.set( -5000, 0, 5000 );
//scene.addLight( pointLight );
ambientLight = new THREE.AmbientLight( 0x000000 );
scene.addLight( ambientLight );
......@@ -132,34 +132,26 @@
uniforms[ "enableDiffuse" ].value = true;
uniforms[ "enableSpecular" ].value = true;
uniforms[ "uDirLightPos" ].value = dirLight.position;
uniforms[ "uDirLightColor" ].value = dirLight.color;
uniforms[ "uPointLightPos" ].value = pointLight.position;
uniforms[ "uPointLightColor" ].value = pointLight.color;
uniforms[ "uAmbientLightColor" ].value = ambientLight.color;
uniforms[ "uDiffuseColor" ].value.setHex( 0xffffff );
uniforms[ "uSpecularColor" ].value.setHex( 0xaaaaaa );
uniforms[ "uAmbientColor" ].value.setHex( 0x000000 );
uniforms[ "uShininess" ].value = 30;
var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms };
var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true };
var materialNormalMap = new THREE.MeshShaderMaterial( parameters );
// planet
// planet
geometry = new THREE.SphereGeometry( radius, 100, 50 );
geometry.computeTangents();
geometry.computeTangents();
meshPlanet = new THREE.Mesh( geometry, materialNormalMap );
meshPlanet.rotation.y = 1.3;
meshPlanet.rotation.z = tilt;
scene.addObject( meshPlanet );
// clouds
// clouds
var materialClouds = new THREE.MeshLambertMaterial( { color: 0xffffff, map: cloudsTexture, transparent:true } );
......@@ -171,17 +163,17 @@
// moon
var materialMoon = new THREE.MeshPhongMaterial( { color: 0xffffff, map: moonTexture } );
meshMoon = new THREE.Mesh( geometry, materialMoon );
meshMoon.position.set( radius * 5, 0, 0 );
meshMoon.scale.set( moonScale, moonScale, moonScale );
scene.addObject( meshMoon );
// stars
var i, r = radius,
starsGeometry = [ new THREE.Geometry(), new THREE.Geometry() ];
for ( i = 0; i < 250; ++i ) {
vector1 = new THREE.Vector3( Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1 );
......@@ -208,49 +200,49 @@
new THREE.ParticleBasicMaterial( { color: 0x1a1a1a, size: 2, sizeAttenuation: false } ),
new THREE.ParticleBasicMaterial( { color: 0x1a1a1a, size: 1, sizeAttenuation: false } )
];
for ( i = 10; i < 30; i ++) {
stars = new THREE.ParticleSystem( starsGeometry[ i % 2 ], starsMaterials[ i % 6 ] );
stars.rotation.x = Math.random() * 6;
stars.rotation.y = Math.random() * 6;
stars.rotation.z = Math.random() * 6;
s = i * 10;
stars.scale.set( s, s, s );
stars.matrixAutoUpdate = false;
stars.updateMatrix();
scene.addObject( stars );
}
if ( ENABLE_LENSFLARES ) {
lensFlare = new THREE.LensFlare( THREE.ImageUtils.loadTexture( "textures/lensflare/lensflare0.png" ), 700, 0.0, THREE.AdditiveBlending );
lensFlare.add( THREE.ImageUtils.loadTexture( "textures/lensflare/lensflare2.png" ), 512, 0.0, THREE.AdditiveBlending );
lensFlare.add( lensFlare.lensFlares[ 1 ].texture, 512, 0.0, THREE.AdditiveBlending );
lensFlare.add( lensFlare.lensFlares[ 1 ].texture, 512, 0.0, THREE.AdditiveBlending );
lensFlare.add( THREE.ImageUtils.loadTexture( "textures/lensflare/lensflare3.png" ), 60, 0.6, THREE.AdditiveBlending );
lensFlare.add( lensFlare.lensFlares[ 4 ].texture, 70, 0.7, THREE.AdditiveBlending );
lensFlare.add( lensFlare.lensFlares[ 4 ].texture, 120, 0.9, THREE.AdditiveBlending );
lensFlare.add( lensFlare.lensFlares[ 4 ].texture, 70, 1.0, THREE.AdditiveBlending );
lensFlare.customUpdateCallback = lensFlareUpdateCallback;
lensFlare.position.set( 0, 0, -99000 );
lensFlareRotate = new THREE.Object3D();
lensFlareRotate.addChild( lensFlare );
scene.addChild( lensFlareRotate );
lensFlareRotate.rotation.x = Math.PI;
lensFlareRotate.rotation.y = Math.PI / 2;
}
renderer = new THREE.WebGLRenderer( { clearAlpha: 1, clearColor: 0x000000 } );
......@@ -351,28 +343,28 @@
};
function cap_bottom( val, bottom ) {
return val < bottom ? bottom : val;
};
function lensFlareUpdateCallback( object ) {
var f, fl = object.lensFlares.length;
var flare;
var vecX = -object.positionScreen.x * 2;
var vecY = -object.positionScreen.y * 2;
var vecY = -object.positionScreen.y * 2;
for( f = 0; f < fl; f++ ) {
flare = object.lensFlares[ f ];
flare.x = object.positionScreen.x + vecX * flare.distance;
flare.y = object.positionScreen.y + vecY * flare.distance;
flare.rotation = 0;
flare.opacity = cap_bottom( 1 - 0.01 * d / radius, 0 );
}
......@@ -387,15 +379,15 @@
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
};
function cap( val, bottom ) {
return val > bottom ? val : bottom;
};
......@@ -406,34 +398,34 @@
t = this.getFrametime();
meshPlanet.rotation.y += rotationSpeed * t;
meshPlanet.rotation.y += rotationSpeed * t;
meshClouds.rotation.y += 1.25 * rotationSpeed * t;
// slow down as we approach the surface
dPlanet = camera.position.length();
dMoonVec.sub( camera.position, meshMoon.position );
dMoon = dMoonVec.length();
if ( dMoon < dPlanet ) {
d = ( dMoon - radius * moonScale * 1.01 );
} else {
d = ( dPlanet - radius * 1.01 );
}
camera.movementSpeed = 0.33 * d;
if ( ENABLE_LENSFLARES ) {
lensFlareRotate.position.set( camera.position.x, camera.position.y, camera.position.z );
}
if ( postprocessing.enabled ) {
renderer.clear();
......@@ -443,7 +435,7 @@
renderer.render( scene, camera, postprocessing.rtTexture1, true );
if ( postprocessing.bloom ) {
// Render quad with blured scene into texture (convolution pass 1)
postprocessing.quad.materials = [ postprocessing.materialConvolution ];
......@@ -470,7 +462,7 @@
renderer.render( postprocessing.scene, postprocessing.camera, postprocessing.rtTexture1, false );
}
// Render to screen
postprocessing.materialFilm.uniforms.time.value += 0.01;
......@@ -487,7 +479,7 @@
}
};
function getFrametime() {
var now = new Date().getTime();
......
......@@ -70,7 +70,7 @@
container = document.getElementById( 'container' );
camera = new THREE.QuakeCamera( {
camera = new THREE.FPCamera( {
fov: 60, aspect: window.innerWidth / window.innerHeight, near: 1, far: 20000,
movementSpeed: 500, lookSpeed: 0.1, noFly: false, lookVertical: true
......
......@@ -75,7 +75,7 @@
container = document.getElementById( 'container' );
camera = new THREE.QuakeCamera( {
camera = new THREE.FPCamera( {
fov: 60, aspect: window.innerWidth / window.innerHeight, near: 1, far: 20000,
movementSpeed: 1000, lookSpeed: 0.125, noFly: false, lookVertical: true
......
......@@ -83,7 +83,7 @@
container = document.getElementById( 'container' );
camera = new THREE.QuakeCamera( {
camera = new THREE.FPCamera( {
fov: 50, aspect: window.innerWidth / window.innerHeight, near: 1, far: 20000,
constrainVertical: true, verticalMin: 1.1, verticalMax: 2.2,
......
......@@ -67,7 +67,7 @@
container = document.getElementById( 'container' );
camera = new THREE.QuakeCamera( {
camera = new THREE.FPCamera( {
fov: 60, aspect: window.innerWidth / window.innerHeight, near: 1, far: 20000,
movementSpeed: 1000, lookSpeed: 0.1, noFly: false, lookVertical: true
......
......@@ -66,7 +66,7 @@
container = document.getElementById( 'container' );
camera = new THREE.QuakeCamera( {
camera = new THREE.FPCamera( {
fov: 60, aspect: window.innerWidth / window.innerHeight, near: 1, far: 10000,
movementSpeed: 150, lookSpeed: 0.1, noFly: false, lookVertical: true
......
......@@ -109,7 +109,7 @@
<script type="text/javascript" src="../src/extras/ShaderUtils.js"></script>
<script type="text/javascript" src="../src/extras/animation/AnimationHandler.js"></script>
<script type="text/javascript" src="../src/extras/animation/Animation.js"></script>
<script type="text/javascript" src="../src/extras/cameras/QuakeCamera.js"></script>
<script type="text/javascript" src="../src/extras/cameras/FPCamera.js"></script>
<script type="text/javascript" src="../src/extras/cameras/PathCamera.js"></script>
<script type="text/javascript" src="../src/extras/cameras/FlyCamera.js"></script>
<script type="text/javascript" src="../src/extras/cameras/RollCamera.js"></script>
......
......@@ -46,7 +46,6 @@
scene = new THREE.Scene();
// create sprites
var amount = 200;
......@@ -99,7 +98,6 @@
renderer = new THREE.WebGLRenderer();
renderer.setClearColorHex( 0x000000, 1 );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = true;
container.appendChild( renderer.domElement );
......
......@@ -165,27 +165,6 @@ THREE.Matrix4.prototype = {
b31 = b.n31, b32 = b.n32, b33 = b.n33, b34 = b.n34,
b41 = b.n41, b42 = b.n42, b43 = b.n43, b44 = b.n44;
this.n11 = a11 * b11 + a12 * b21 + a13 * b31;
this.n12 = a11 * b12 + a12 * b22 + a13 * b32;
this.n13 = a11 * b13 + a12 * b23 + a13 * b33;
this.n14 = a11 * b14 + a12 * b24 + a13 * b34 + a14;
this.n21 = a21 * b11 + a22 * b21 + a23 * b31;
this.n22 = a21 * b12 + a22 * b22 + a23 * b32;
this.n23 = a21 * b13 + a22 * b23 + a23 * b33;
this.n24 = a21 * b14 + a22 * b24 + a23 * b34 + a24;
this.n31 = a31 * b11 + a32 * b21 + a33 * b31;
this.n32 = a31 * b12 + a32 * b22 + a33 * b32;
this.n33 = a31 * b13 + a32 * b23 + a33 * b33;
this.n34 = a31 * b14 + a32 * b24 + a33 * b34 + a34;
this.n41 = a41 * b11 + a42 * b21 + a43 * b31;
this.n42 = a41 * b12 + a42 * b22 + a43 * b32;
this.n43 = a41 * b13 + a42 * b23 + a43 * b33;
this.n44 = a41 * b14 + a42 * b24 + a43 * b34 + a44;
/*
this.n11 = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
this.n12 = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
this.n13 = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
......@@ -205,7 +184,6 @@ THREE.Matrix4.prototype = {
this.n42 = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
this.n43 = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
this.n44 = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
*/
return this;
......@@ -532,30 +510,116 @@ THREE.Matrix4.prototype = {
},
setRotationFromEuler: function( v ) {
setRotationFromEuler: function( v, order ) {
var x = v.x, y = v.y, z = v.z,
a = Math.cos( x ), b = Math.sin( x ),
c = Math.cos( y ), d = Math.sin( y ),
e = Math.cos( z ), f = Math.sin( z ),
ad = a * d, bd = b * d;
e = Math.cos( z ), f = Math.sin( z );
this.n11 = c * e;
this.n12 = - c * f;
this.n13 = d;
switch ( order ) {
case 'YXZ':
var ce = c * e, cf = c * f, de = d * e, df = d * f;
this.n21 = bd * e + a * f;
this.n22 = - bd * f + a * e;
this.n23 = - b * c;
this.n11 = ce + df * b;
this.n12 = de * b - cf;
this.n13 = a * d;
this.n31 = - ad * e + b * f;
this.n32 = ad * f + b * e;
this.n33 = a * c;
this.n21 = a * f;
this.n22 = a * e;
this.n23 = - b;
this.n31 = cf * b - de;
this.n32 = df + ce * b;
this.n33 = a * c;
break;
case 'ZXY':
var ce = c * e, cf = c * f, de = d * e, df = d * f;
this.n11 = ce - df * b;
this.n12 = - a * f;
this.n13 = de + cf * b;
this.n21 = cf + de * b;
this.n22 = a * e;
this.n23 = df - ce * b;
this.n31 = - a * d;
this.n32 = b;
this.n33 = a * c;
break;
case 'ZYX':
var ae = a * e, af = a * f, be = b * e, bf = b * f;
this.n11 = c * e;
this.n12 = be * d - af;
this.n13 = ae * d + bf;
this.n21 = c * f;
this.n22 = bf * d + ae;
this.n23 = af * d - be;
this.n31 = - d;
this.n32 = b * c;
this.n33 = a * c;
break;
case 'YZX':
var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
this.n11 = c * e;
this.n12 = bd - ac * f;
this.n13 = bc * f + ad;
this.n21 = f;
this.n22 = a * e;
this.n23 = - b * e;
this.n31 = - d * e;
this.n32 = ad * f + bc;
this.n33 = ac - bd * f;
break;
case 'XZY':
var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
this.n11 = c * e;
this.n12 = - f;
this.n13 = d * e;
this.n21 = ac * f + bd;
this.n22 = a * e;
this.n23 = ad * f - bc;
this.n31 = bc * f - ad;
this.n32 = b * e;
this.n33 = bd * f + ac;
break;
default: // 'XYZ'
var ae = a * e, af = a * f, be = b * e, bf = b * f;
this.n11 = c * e;
this.n12 = - c * f;
this.n13 = d;
this.n21 = af + be * d;
this.n22 = ae - bf * d;
this.n23 = - b * c;
this.n31 = bf - ae * d;
this.n32 = be + af * d;
this.n33 = a * c;
break;
}
return this;
},
setRotationFromQuaternion: function( q ) {
var x = q.x, y = q.y, z = q.z, w = q.w,
......
......@@ -13,6 +13,7 @@ THREE.Object3D = function() {
this.position = new THREE.Vector3();
this.rotation = new THREE.Vector3();
this.eulerOrder = 'XYZ';
this.scale = new THREE.Vector3( 1, 1, 1 );
this.dynamic = false; // when true it retains arrays so they can be updated with __dirty*
......@@ -20,6 +21,8 @@ THREE.Object3D = function() {
this.doubleSided = false;
this.flipSided = false;
this.renderDepth = null;
this.rotationAutoUpdate = true;
this.matrix = new THREE.Matrix4();
......@@ -173,7 +176,7 @@ THREE.Object3D.prototype = {
} else {
this.matrix.setRotationFromEuler( this.rotation );
this.matrix.setRotationFromEuler( this.rotation, this.eulerOrder );
}
......
......@@ -150,17 +150,17 @@ THREE.Ray.prototype = {
function distanceFromIntersection( origin, direction, object ) {
var vector, dot, intersect, distance;
var vector, dot, intersect, distance,
position = object.matrixWorld.getPosition();
vector = object.position.clone().subSelf( origin );
vector = position.clone().subSelf( origin );
dot = vector.dot( direction );
// TODO: Double check this
// if ( dot < 0 ) return false; // Object is behind origin
intersect = origin.clone().addSelf( direction.clone().multiplyScalar( dot ) );
distance = object.position.distanceTo( intersect );
distance = position.distanceTo( intersect );
// TODO: Check if distance is negative (object behind camera).
return distance;
}
......
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
* @author paulirish / http://paulirish.com/
*
* parameters = {
* fov: <float>,
* aspect: <float>,
* near: <float>,
* far: <float>,
* target: <THREE.Object3D>,
* movementSpeed: <float>,
* lookSpeed: <float>,
* noFly: <bool>,
* lookVertical: <bool>,
* autoForward: <bool>,
* constrainVertical: <bool>,
* verticalMin: <float>,
* verticalMax: <float>,
* heightSpeed: <bool>,
* heightCoef: <float>,
* heightMin: <float>,
* heightMax: <float>,
* domElement: <HTMLElement>,
* }
*/
THREE.FPCamera = function ( parameters ) {
THREE.Camera.call( this, parameters.fov, parameters.aspect, parameters.near, parameters.far, parameters.target );
this.movementSpeed = 1.0;
this.lookSpeed = 0.005;
this.noFly = false;
this.lookVertical = true;
this.autoForward = false;
this.activeLook = true;
this.heightSpeed = false;
this.heightCoef = 1.0;
this.heightMin = 0.0;
this.constrainVertical = false;
this.verticalMin = 0;
this.verticalMax = 3.14;
this.domElement = document;
this.lastUpdate = new Date().getTime();
this.tdiff = 0;
if ( parameters ) {
if ( parameters.movementSpeed !== undefined ) this.movementSpeed = parameters.movementSpeed;
if ( parameters.lookSpeed !== undefined ) this.lookSpeed = parameters.lookSpeed;
if ( parameters.noFly !== undefined ) this.noFly = parameters.noFly;
if ( parameters.lookVertical !== undefined ) this.lookVertical = parameters.lookVertical;
if ( parameters.autoForward !== undefined ) this.autoForward = parameters.autoForward;
if ( parameters.activeLook !== undefined ) this.activeLook = parameters.activeLook;
if ( parameters.heightSpeed !== undefined ) this.heightSpeed = parameters.heightSpeed;
if ( parameters.heightCoef !== undefined ) this.heightCoef = parameters.heightCoef;
if ( parameters.heightMin !== undefined ) this.heightMin = parameters.heightMin;
if ( parameters.heightMax !== undefined ) this.heightMax = parameters.heightMax;
if ( parameters.constrainVertical !== undefined ) this.constrainVertical = parameters.constrainVertical;
if ( parameters.verticalMin !== undefined ) this.verticalMin = parameters.verticalMin;
if ( parameters.verticalMax !== undefined ) this.verticalMax = parameters.verticalMax;
if ( parameters.domElement !== undefined ) this.domElement = parameters.domElement;
}
this.autoSpeedFactor = 0.0;
this.mouseX = 0;
this.mouseY = 0;
this.lat = 0;
this.lon = 0;
this.phi = 0;
this.theta = 0;
this.moveForward = false;
this.moveBackward = false;
this.moveLeft = false;
this.moveRight = false;
this.freeze = false;
this.mouseDragOn = false;
this.windowHalfX = window.innerWidth / 2;
this.windowHalfY = window.innerHeight / 2;
this.onMouseDown = function ( event ) {
event.preventDefault();
event.stopPropagation();
if ( this.activeLook ) {
switch ( event.button ) {
case 0: this.moveForward = true; break;
case 2: this.moveBackward = true; break;
}
}
this.mouseDragOn = true;
};
this.onMouseUp = function ( event ) {
event.preventDefault();
event.stopPropagation();
if ( this.activeLook ) {
switch ( event.button ) {
case 0: this.moveForward = false; break;
case 2: this.moveBackward = false; break;
}
}
this.mouseDragOn = false;
};
this.onMouseMove = function ( event ) {
this.mouseX = event.clientX - this.windowHalfX;
this.mouseY = event.clientY - this.windowHalfY;
};
this.onKeyDown = function ( event ) {
switch( event.keyCode ) {
case 38: /*up*/
case 87: /*W*/ this.moveForward = true; break;
case 37: /*left*/
case 65: /*A*/ this.moveLeft = true; break;
case 40: /*down*/
case 83: /*S*/ this.moveBackward = true; break;
case 39: /*right*/
case 68: /*D*/ this.moveRight = true; break;
case 81: this.freeze = !this.freeze; break;
}
};
this.onKeyUp = function ( event ) {
switch( event.keyCode ) {
case 38: /*up*/
case 87: /*W*/ this.moveForward = false; break;
case 37: /*left*/
case 65: /*A*/ this.moveLeft = false; break;
case 40: /*down*/
case 83: /*S*/ this.moveBackward = false; break;
case 39: /*right*/
case 68: /*D*/ this.moveRight = false; break;
}
};
this.update = function() {
var now = new Date().getTime();
this.tdiff = ( now - this.lastUpdate ) / 1000;
this.lastUpdate = now;
if ( !this.freeze ) {
if ( this.heightSpeed ) {
var y = clamp( this.position.y, this.heightMin, this.heightMax ),
delta = y - this.heightMin;
this.autoSpeedFactor = this.tdiff * ( delta * this.heightCoef );
} else {
this.autoSpeedFactor = 0.0;
}
var actualMoveSpeed = this.tdiff * this.movementSpeed;
if ( this.moveForward || ( this.autoForward && !this.moveBackward ) ) this.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) );
if ( this.moveBackward ) this.translateZ( actualMoveSpeed );
if ( this.moveLeft ) this.translateX( - actualMoveSpeed );
if ( this.moveRight ) this.translateX( actualMoveSpeed );
var actualLookSpeed = this.tdiff * this.lookSpeed;
if ( !this.activeLook ) {
actualLookSpeed = 0;
}
this.lon += this.mouseX * actualLookSpeed;
if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed;
this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
this.phi = ( 90 - this.lat ) * Math.PI / 180;
this.theta = this.lon * Math.PI / 180;
var targetPosition = this.target.position,
position = this.position;
targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
targetPosition.y = position.y + 100 * Math.cos( this.phi );
targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
}
this.lon += this.mouseX * actualLookSpeed;
if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed;
this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
this.phi = ( 90 - this.lat ) * Math.PI / 180;
this.theta = this.lon * Math.PI / 180;
if ( this.constrainVertical ) {
this.phi = map_linear( this.phi, 0, 3.14, this.verticalMin, this.verticalMax );
}
var targetPosition = this.target.position,
position = this.position;
targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
targetPosition.y = position.y + 100 * Math.cos( this.phi );
targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
this.supr.update.call( this );
};
this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false );
this.domElement.addEventListener( 'mousedown', bind( this, this.onMouseDown ), false );
this.domElement.addEventListener( 'mouseup', bind( this, this.onMouseUp ), false );
this.domElement.addEventListener( 'keydown', bind( this, this.onKeyDown ), false );
this.domElement.addEventListener( 'keyup', bind( this, this.onKeyUp ), false );
function bind( scope, fn ) {
return function () {
fn.apply( scope, arguments );
};
};
function map_linear( x, sa, sb, ea, eb ) {
return ( x - sa ) * ( eb - ea ) / ( sb - sa ) + ea;
};
function clamp_bottom( x, a ) {
return x < a ? a : x;
};
function clamp( x, a, b ) {
return x < a ? a : ( x > b ? b : x );
};
};
THREE.FPCamera.prototype = new THREE.Camera();
THREE.FPCamera.prototype.constructor = THREE.FPCamera;
THREE.FPCamera.prototype.supr = THREE.Camera.prototype;
THREE.FPCamera.prototype.translate = function ( distance, axis ) {
this.matrix.rotateAxis( axis );
if ( this.noFly ) {
axis.y = 0;
}
this.position.addSelf( axis.multiplyScalar( distance ) );
this.target.position.addSelf( axis.multiplyScalar( distance ) );
};
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
* @author paulirish / http://paulirish.com/
* @author chriskillpack / http://chriskillpack.com/
*
* parameters = {
* fov: <float>,
* aspect: <float>,
* near: <float>,
* far: <float>,
* target: <THREE.Object3D>,
* movementSpeed: <float>,
* lookSpeed: <float>,
* noFly: <bool>,
* lookVertical: <bool>,
* autoForward: <bool>,
* constrainVertical: <bool>,
* verticalMin: <float>,
* verticalMax: <float>,
* heightSpeed: <bool>,
* heightCoef: <float>,
* heightMin: <float>,
* heightMax: <float>,
* domElement: <HTMLElement>,
* }
* QuakeCamera has been renamed FPCamera. This property exists for backwards
* compatibility only.
*/
THREE.QuakeCamera = function ( parameters ) {
THREE.Camera.call( this, parameters.fov, parameters.aspect, parameters.near, parameters.far, parameters.target );
this.movementSpeed = 1.0;
this.lookSpeed = 0.005;
this.noFly = false;
this.lookVertical = true;
this.autoForward = false;
this.activeLook = true;
this.heightSpeed = false;
this.heightCoef = 1.0;
this.heightMin = 0.0;
this.constrainVertical = false;
this.verticalMin = 0;
this.verticalMax = 3.14;
this.domElement = document;
this.lastUpdate = new Date().getTime();
this.tdiff = 0;
if ( parameters ) {
if ( parameters.movementSpeed !== undefined ) this.movementSpeed = parameters.movementSpeed;
if ( parameters.lookSpeed !== undefined ) this.lookSpeed = parameters.lookSpeed;
if ( parameters.noFly !== undefined ) this.noFly = parameters.noFly;
if ( parameters.lookVertical !== undefined ) this.lookVertical = parameters.lookVertical;
if ( parameters.autoForward !== undefined ) this.autoForward = parameters.autoForward;
if ( parameters.activeLook !== undefined ) this.activeLook = parameters.activeLook;
if ( parameters.heightSpeed !== undefined ) this.heightSpeed = parameters.heightSpeed;
if ( parameters.heightCoef !== undefined ) this.heightCoef = parameters.heightCoef;
if ( parameters.heightMin !== undefined ) this.heightMin = parameters.heightMin;
if ( parameters.heightMax !== undefined ) this.heightMax = parameters.heightMax;
if ( parameters.constrainVertical !== undefined ) this.constrainVertical = parameters.constrainVertical;
if ( parameters.verticalMin !== undefined ) this.verticalMin = parameters.verticalMin;
if ( parameters.verticalMax !== undefined ) this.verticalMax = parameters.verticalMax;
if ( parameters.domElement !== undefined ) this.domElement = parameters.domElement;
}
this.autoSpeedFactor = 0.0;
this.mouseX = 0;
this.mouseY = 0;
this.lat = 0;
this.lon = 0;
this.phi = 0;
this.theta = 0;
this.moveForward = false;
this.moveBackward = false;
this.moveLeft = false;
this.moveRight = false;
this.freeze = false;
this.mouseDragOn = false;
this.windowHalfX = window.innerWidth / 2;
this.windowHalfY = window.innerHeight / 2;
this.onMouseDown = function ( event ) {
event.preventDefault();
event.stopPropagation();
if ( this.activeLook ) {
switch ( event.button ) {
case 0: this.moveForward = true; break;
case 2: this.moveBackward = true; break;
}
}
this.mouseDragOn = true;
};
this.onMouseUp = function ( event ) {
event.preventDefault();
event.stopPropagation();
if ( this.activeLook ) {
switch ( event.button ) {
case 0: this.moveForward = false; break;
case 2: this.moveBackward = false; break;
}
}
this.mouseDragOn = false;
};
this.onMouseMove = function ( event ) {
this.mouseX = event.clientX - this.windowHalfX;
this.mouseY = event.clientY - this.windowHalfY;
};
this.onKeyDown = function ( event ) {
switch( event.keyCode ) {
case 38: /*up*/
case 87: /*W*/ this.moveForward = true; break;
case 37: /*left*/
case 65: /*A*/ this.moveLeft = true; break;
case 40: /*down*/
case 83: /*S*/ this.moveBackward = true; break;
case 39: /*right*/
case 68: /*D*/ this.moveRight = true; break;
case 81: this.freeze = !this.freeze; break;
}
};
this.onKeyUp = function ( event ) {
switch( event.keyCode ) {
case 38: /*up*/
case 87: /*W*/ this.moveForward = false; break;
case 37: /*left*/
case 65: /*A*/ this.moveLeft = false; break;
case 40: /*down*/
case 83: /*S*/ this.moveBackward = false; break;
case 39: /*right*/
case 68: /*D*/ this.moveRight = false; break;
}
};
this.update = function() {
var now = new Date().getTime();
this.tdiff = ( now - this.lastUpdate ) / 1000;
this.lastUpdate = now;
if ( !this.freeze ) {
if ( this.heightSpeed ) {
var y = clamp( this.position.y, this.heightMin, this.heightMax ),
delta = y - this.heightMin;
this.autoSpeedFactor = this.tdiff * ( delta * this.heightCoef );
} else {
this.autoSpeedFactor = 0.0;
}
var actualMoveSpeed = this.tdiff * this.movementSpeed;
if ( this.moveForward || ( this.autoForward && !this.moveBackward ) ) this.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) );
if ( this.moveBackward ) this.translateZ( actualMoveSpeed );
if ( this.moveLeft ) this.translateX( - actualMoveSpeed );
if ( this.moveRight ) this.translateX( actualMoveSpeed );
var actualLookSpeed = this.tdiff * this.lookSpeed;
if ( !this.activeLook ) {
actualLookSpeed = 0;
}
this.lon += this.mouseX * actualLookSpeed;
if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed;
this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
this.phi = ( 90 - this.lat ) * Math.PI / 180;
this.theta = this.lon * Math.PI / 180;
var targetPosition = this.target.position,
position = this.position;
targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
targetPosition.y = position.y + 100 * Math.cos( this.phi );
targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
}
this.lon += this.mouseX * actualLookSpeed;
if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed;
this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
this.phi = ( 90 - this.lat ) * Math.PI / 180;
this.theta = this.lon * Math.PI / 180;
if ( this.constrainVertical ) {
this.phi = map_linear( this.phi, 0, 3.14, this.verticalMin, this.verticalMax );
}
var targetPosition = this.target.position,
position = this.position;
targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
targetPosition.y = position.y + 100 * Math.cos( this.phi );
targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
this.supr.update.call( this );
};
this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false );
this.domElement.addEventListener( 'mousedown', bind( this, this.onMouseDown ), false );
this.domElement.addEventListener( 'mouseup', bind( this, this.onMouseUp ), false );
this.domElement.addEventListener( 'keydown', bind( this, this.onKeyDown ), false );
this.domElement.addEventListener( 'keyup', bind( this, this.onKeyUp ), false );
function bind( scope, fn ) {
return function () {
fn.apply( scope, arguments );
};
};
function map_linear( x, sa, sb, ea, eb ) {
return ( x - sa ) * ( eb - ea ) / ( sb - sa ) + ea;
};
function clamp_bottom( x, a ) {
return x < a ? a : x;
};
function clamp( x, a, b ) {
return x < a ? a : ( x > b ? b : x );
};
};
THREE.QuakeCamera.prototype = new THREE.Camera();
THREE.QuakeCamera.prototype.constructor = THREE.QuakeCamera;
THREE.QuakeCamera.prototype.supr = THREE.Camera.prototype;
THREE.QuakeCamera.prototype.translate = function ( distance, axis ) {
this.matrix.rotateAxis( axis );
if ( this.noFly ) {
axis.y = 0;
}
this.position.addSelf( axis.multiplyScalar( distance ) );
this.target.position.addSelf( axis.multiplyScalar( distance ) );
};
THREE.QuakeCamera = THREE.FPCamera;
/**
* @author mrdoob / http://mrdoob.com/
* @author marklundin / http://mark-lundin.com/
*/
if ( THREE.WebGLRenderer ) {
THREE.AnaglyphWebGLRenderer = function ( parameters ) {
THREE.AnaglyphWebGLRenderer = function ( parameters ) {
THREE.WebGLRenderer.call( this, parameters );
var _this = this, _setSize = this.setSize, _render = this.render;
var _cameraL = new THREE.Camera(), _cameraR = new THREE.Camera();
var eyeRight = new THREE.Matrix4(),
eyeLeft = new THREE.Matrix4(),
focalLength = 125,
aspect, near, fov;
_cameraL.useTarget = _cameraR.useTarget = false;
_cameraL.matrixAutoUpdate = _cameraR.matrixAutoUpdate = false;
var _params = { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
var _renderTargetL = new THREE.WebGLRenderTarget( 512, 512, _params ), _renderTargetR = new THREE.WebGLRenderTarget( 512, 512, _params );
......@@ -76,21 +84,64 @@ if ( THREE.WebGLRenderer ) {
};
this.render = function ( scene, camera, renderTarget, forceClear ) {
_cameraL.projectionMatrix = camera.projectionMatrix;
/*
* Renderer now uses an asymmetric perspective projection (http://paulbourke.net/miscellaneous/stereographics/stereorender/).
* Each camera is offset by the eye seperation and its projection matrix is also skewed asymetrically back to converge on the same
* projection plane. Added a focal length parameter to, this is where the parallax is equal to 0.
*/
this.render = function ( scene, camera, renderTarget, forceClear ) {
camera.update( null, true );
var hasCameraChanged = aspect !== camera.aspect || near !== camera.near || fov !== camera.fov;
if( hasCameraChanged ) {
aspect = camera.aspect;
near = camera.near;
fov = camera.fov;
var projectionMatrix = camera.projectionMatrix.clone(),
eyeSep = focalLength / 30 * 0.5,
eyeSepOnProjection = eyeSep * near / focalLength,
ymax = near * Math.tan( fov * Math.PI / 360 ),
xmin, xmax;
//translate xOffset
eyeRight.n14 = eyeSep;
eyeLeft.n14 = -eyeSep;
//For left eye
xmin = -ymax * aspect + eyeSepOnProjection;
xmax = ymax * aspect + eyeSepOnProjection;
projectionMatrix.n11 = 2 * near / ( xmax - xmin );
projectionMatrix.n13 = ( xmax + xmin ) / ( xmax - xmin );
_cameraL.projectionMatrix = projectionMatrix.clone();
//for right eye
xmin = -ymax * aspect - eyeSepOnProjection;
xmax = ymax * aspect - eyeSepOnProjection;
projectionMatrix.n11 = 2 * near / ( xmax - xmin );
projectionMatrix.n13 = ( xmax + xmin ) / ( xmax - xmin );
_cameraR.projectionMatrix = projectionMatrix.clone();
}
_cameraL.matrix = camera.matrixWorld.clone().multiplySelf( eyeLeft );
_cameraL.update(null, true);
_cameraL.position.copy( camera.position );
_cameraL.target.position.copy( camera.target.position );
_cameraL.translateX( - 10 );
_cameraL.near = near;
_cameraL.far = camera.far;
_render.call( _this, scene, _cameraL, _renderTargetL, true );
_cameraR.projectionMatrix = camera.projectionMatrix;
_cameraR.matrix = camera.matrixWorld.clone().multiplySelf( eyeRight );
_cameraR.update(null, true);
_cameraR.position.copy( camera.position );
_cameraR.target.position.copy( camera.target.position );
_cameraR.translateX( 10 );
_render.call( _this, scene, _cameraL, _renderTargetL, true );
_cameraR.near = near;
_cameraR.far = camera.far;
_render.call( _this, scene, _cameraR, _renderTargetR, true );
_render.call( _this, _scene, _camera );
};
......
......@@ -14,6 +14,9 @@ THREE.Material = function ( parameters ) {
this.blending = parameters.blending !== undefined ? parameters.blending : THREE.NormalBlending;
this.depthTest = parameters.depthTest !== undefined ? parameters.depthTest : true;
this.polygonOffset = parameters.polygonOffset !== undefined ? parameters.polygonOffset : false;
this.polygonOffsetFactor = parameters.polygonOffsetFactor !== undefined ? parameters.polygonOffsetFactor : 0;
this.polygonOffsetUnits = parameters.polygonOffsetUnits !== undefined ? parameters.polygonOffsetUnits : 0;
}
......
......@@ -23,6 +23,7 @@ THREE.Sprite = function( parameters ) {
this.useScreenCoordinates = parameters.useScreenCoordinates !== undefined ? parameters.useScreenCoordinates : true;
this.mergeWith3D = parameters.mergeWith3D !== undefined ? parameters.mergeWith3D : !this.useScreenCoordinates;
this.affectedByDistance = parameters.affectedByDistance !== undefined ? parameters.affectedByDistance : !this.useScreenCoordinates;
this.scaleByViewport = parameters.scaleByViewport !== undefined ? parameters.scaleByViewport : !this.affectedByDistance;
this.alignment = parameters.alignment instanceof THREE.Vector2 ? parameters.alignment : THREE.SpriteAlignment.center;
this.rotation3d = this.rotation;
......
......@@ -32,6 +32,9 @@ THREE.WebGLRenderer = function ( parameters ) {
_oldFlipSided = null,
_oldBlending = null,
_oldDepth = null,
_oldPolygonOffset = null,
_oldPolygonOffsetFactor = null,
_oldPolygonOffsetUnits = null,
_cullEnabled = true,
_viewportX = 0,
......@@ -2999,6 +3002,35 @@ THREE.WebGLRenderer = function ( parameters ) {
};
function setPolygonOffset ( polygonoffset, factor, units ) {
if ( _oldPolygonOffset != polygonoffset ) {
if ( polygonoffset ) {
_gl.enable( _gl.POLYGON_OFFSET_FILL );
} else {
_gl.disable( _gl.POLYGON_OFFSET_FILL );
}
_oldPolygonOffset = polygonoffset;
}
if ( polygonoffset && ( _oldPolygonOffsetFactor != factor || _oldPolygonOffsetUnits != units ) ) {
_gl.polygonOffset( factor, units );
_oldPolygonOffsetFactor = factor;
_oldPolygonOffsetUnits = units;
}
};
function computeFrustum( m ) {
_frustum[ 0 ].set( m.n41 - m.n11, m.n42 - m.n12, m.n43 - m.n13, m.n44 - m.n14 );
......@@ -3157,10 +3189,18 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( this.sortObjects ) {
_vector3.copy( object.position );
_projScreenMatrix.multiplyVector3( _vector3 );
if ( webglObject.object.renderDepth ) {
webglObject.z = webglObject.object.renderDepth;
} else {
webglObject.z = _vector3.z;
_vector3.copy( object.position );
_projScreenMatrix.multiplyVector3( _vector3 );
webglObject.z = _vector3.z;
}
}
......@@ -3268,6 +3308,7 @@ THREE.WebGLRenderer = function ( parameters ) {
material = opaque.list[ i ];
setDepthTest( material.depthTest );
setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
renderBuffer( camera, lights, fog, material, buffer, object );
}
......@@ -3294,6 +3335,7 @@ THREE.WebGLRenderer = function ( parameters ) {
material = opaque.list[ i ];
setDepthTest( material.depthTest );
setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
program = setProgram( camera, lights, fog, material, object );
object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
......@@ -3324,6 +3366,7 @@ THREE.WebGLRenderer = function ( parameters ) {
setBlending( material.blending );
setDepthTest( material.depthTest );
setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
renderBuffer( camera, lights, fog, material, buffer, object );
......@@ -3352,6 +3395,7 @@ THREE.WebGLRenderer = function ( parameters ) {
setBlending( material.blending );
setDepthTest( material.depthTest );
setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
program = setProgram( camera, lights, fog, material, object );
object.render( function( object ) { renderBufferImmediate( object, program, material.shading ); } );
......@@ -3637,7 +3681,7 @@ THREE.WebGLRenderer = function ( parameters ) {
}
size = object.map.image.width / ( object.affectedByDistance ? 1 : _viewportHeight );
size = object.map.image.width / ( object.scaleByViewport ? _viewportHeight : 1 );
scale[ 0 ] = size * invAspect * object.scale.x;
scale[ 1 ] = size * object.scale.y;
......
......@@ -89,11 +89,12 @@ EXTRAS_FILES = [
'extras/ShaderUtils.js',
'extras/animation/AnimationHandler.js',
'extras/animation/Animation.js',
'extras/cameras/QuakeCamera.js',
'extras/cameras/FPCamera.js',
'extras/cameras/PathCamera.js',
'extras/cameras/FlyCamera.js',
'extras/cameras/RollCamera.js',
'extras/cameras/TrackballCamera.js',
'extras/cameras/QuakeCamera.js',
'extras/geometries/CubeGeometry.js',
'extras/geometries/CylinderGeometry.js',
'extras/geometries/IcosahedronGeometry.js',
......
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# ################################################################
# Init
# ################################################################
# To support reload properly, try to access a package var,
# if it's there, reload everything
bl_info = {
"name": "three.js format",
"author": "mrdoob, kikko, alteredq, remoe",
"version": (1, 0),
"blender": (2, 5, 7),
"api": 35622,
"location": "File > Import-Export",
"description": "Import-Export three.js meshes",
"warning": "",
"wiki_url": "https://github.com/mrdoob/three.js/tree/master/utils/exporters/blender",
"tracker_url": "https://github.com/mrdoob/three.js/issues",
"category": "Import-Export"}
if "bpy" in locals():
import imp
if "export_threejs" in locals():
imp.reload(export_threejs)
if "import_threejs" in locals():
imp.reload(import_threejs)
import bpy
from bpy.props import *
from bpy_extras.io_utils import ExportHelper, ImportHelper
# ################################################################
# Custom properties
# ################################################################
bpy.types.Object.THREE_castsShadow = bpy.props.BoolProperty()
bpy.types.Object.THREE_meshCollider = bpy.props.BoolProperty()
bpy.types.Object.THREE_exportGeometry = bpy.props.BoolProperty(default = True)
THREE_trigger_types = [("None", "None", "None"), ("Small", "Small", "Small"), ("Large", "Large", "Large")]
bpy.types.Object.THREE_triggerType = EnumProperty(name = "Trigger type", description = "Trigger type", items = THREE_trigger_types, default = "None")
bpy.types.Material.THREE_useVertexColors = bpy.props.BoolProperty()
THREE_material_types = [("Basic", "Basic", "Basic"), ("Phong", "Phong", "Phong"), ("Lambert", "Lambert", "Lambert")]
bpy.types.Material.THREE_materialType = EnumProperty(name = "Material type", description = "Material type", items = THREE_material_types, default = "Lambert")
class OBJECT_PT_hello( bpy.types.Panel ):
bl_label = "THREE"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
def draw(self, context):
layout = self.layout
obj = context.object
row = layout.row()
row.label(text="Selected object: " + obj.name )
row = layout.row()
row.prop( obj, "THREE_exportGeometry", text="Export geometry" )
row = layout.row()
row.prop( obj, "THREE_castsShadow", text="Casts shadow" )
row = layout.row()
row.prop( obj, "THREE_meshCollider", text="Mesh collider" )
row = layout.row()
row.prop( obj, "THREE_triggerType", text="Trigger type" )
class MATERIAL_PT_hello( bpy.types.Panel ):
bl_label = "THREE"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "material"
def draw(self, context):
layout = self.layout
mat = context.material
row = layout.row()
row.label(text="Selected material: " + mat.name )
row = layout.row()
row.prop( mat, "THREE_materialType", text="Material type" )
row = layout.row()
row.prop( mat, "THREE_useVertexColors", text="Use vertex colors" )
# ################################################################
# Importer
# ################################################################
class ImportTHREEJS(bpy.types.Operator, ImportHelper):
'''Load a Three.js ASCII JSON model'''
bl_idname = "import.threejs"
bl_label = "Import Three.js"
filename_ext = ".js"
filter_glob = StringProperty(default="*.js", options={'HIDDEN'})
option_flip_yz = BoolProperty(name="Flip YZ", description="Flip YZ", default=True)
recalculate_normals = BoolProperty(name="Recalculate normals", description="Recalculate vertex normals", default=True)
def execute(self, context):
import io_mesh_threejs.import_threejs
return io_mesh_threejs.import_threejs.load(self, context, **self.properties)
def draw(self, context):
layout = self.layout
row = layout.row()
row.prop(self.properties, "option_flip_yz")
row = layout.row()
row.prop(self.properties, "recalculate_normals")
# ################################################################
# Exporter - settings
# ################################################################
SETTINGS_FILE_EXPORT = "threejs_settings_export.js"
import os
import json
def file_exists(filename):
"""Return true if file exists and accessible for reading.
Should be safer than just testing for existence due to links and
permissions magic on Unix filesystems.
@rtype: boolean
"""
try:
f = open(filename, 'r')
f.close()
return True
except IOError:
return False
def get_settings_fullpath():
return os.path.join(bpy.app.tempdir, SETTINGS_FILE_EXPORT)
def save_settings_export(properties):
settings = {
"option_export_scene" : properties.option_export_scene,
"option_embed_meshes" : properties.option_embed_meshes,
"option_lights" : properties.option_lights,
"option_cameras" : properties.option_cameras,
"option_flip_yz" : properties.option_flip_yz,
"option_materials" : properties.option_materials,
"option_normals" : properties.option_normals,
"option_colors" : properties.option_colors,
"option_uv_coords" : properties.option_uv_coords,
"option_edges" : properties.option_edges,
"option_faces" : properties.option_faces,
"option_vertices" : properties.option_vertices,
"option_vertices_truncate" : properties.option_vertices_truncate,
"option_scale" : properties.option_scale,
"align_model" : properties.align_model
}
fname = get_settings_fullpath()
f = open(fname, "w")
json.dump(settings, f)
def restore_settings_export(properties):
settings = {}
fname = get_settings_fullpath()
if file_exists(fname):
f = open(fname, "r")
settings = json.load(f)
properties.option_vertices = settings.get("option_vertices", True)
properties.option_vertices_truncate = settings.get("option_vertices_truncate", False)
properties.option_faces = settings.get("option_faces", True)
properties.option_normals = settings.get("option_normals", True)
properties.option_edges = settings.get("option_edges", False)
properties.option_colors = settings.get("option_colors", True)
properties.option_uv_coords = settings.get("option_uv_coords", True)
properties.option_materials = settings.get("option_materials", True)
properties.align_model = settings.get("align_model", "None")
properties.option_scale = settings.get("option_scale", 1.0)
properties.option_flip_yz = settings.get("option_flip_yz", True)
properties.option_export_scene = settings.get("option_export_scene", False)
properties.option_embed_meshes = settings.get("option_embed_meshes", True)
properties.option_lights = settings.get("option_lights", False)
properties.option_cameras = settings.get("option_cameras", False)
# ################################################################
# Exporter
# ################################################################
class ExportTHREEJS(bpy.types.Operator, ExportHelper):
'''Export selected object / scene for Three.js (ASCII JSON format).'''
bl_idname = "export.threejs"
bl_label = "Export Three.js"
filename_ext = ".js"
option_vertices = BoolProperty(name = "Vertices", description = "Export vertices", default = True)
option_vertices_deltas = BoolProperty(name = "Deltas", description = "Delta vertices", default = False)
option_vertices_truncate = BoolProperty(name = "Truncate", description = "Truncate vertices", default = False)
option_faces = BoolProperty(name = "Faces", description = "Export faces", default = True)
option_faces_deltas = BoolProperty(name = "Deltas", description = "Delta faces", default = False)
option_normals = BoolProperty(name = "Normals", description = "Export normals", default = True)
option_edges = BoolProperty(name = "Edges", description = "Export edges", default = False)
option_colors = BoolProperty(name = "Colors", description = "Export vertex colors", default = True)
option_uv_coords = BoolProperty(name = "UVs", description = "Export texture coordinates", default = True)
option_materials = BoolProperty(name = "Materials", description = "Export materials", default = True)
align_types = [("None","None","None"), ("Center","Center","Center"), ("Bottom","Bottom","Bottom"), ("Top","Top","Top")]
align_model = EnumProperty(name = "Align model", description = "Align model", items = align_types, default = "None")
option_scale = FloatProperty(name = "Scale", description = "Scale vertices", min = 0.01, max = 1000.0, soft_min = 0.01, soft_max = 1000.0, default = 1.0)
option_flip_yz = BoolProperty(name = "Flip YZ", description = "Flip YZ", default = True)
option_export_scene = BoolProperty(name = "Scene", description = "Export scene", default = False)
option_embed_meshes = BoolProperty(name = "Embed", description = "Embed meshes", default = True)
option_lights = BoolProperty(name = "Lights", description = "Export default scene lights", default = False)
option_cameras = BoolProperty(name = "Cameras", description = "Export default scene cameras", default = False)
def invoke(self, context, event):
restore_settings_export(self.properties)
return ExportHelper.invoke(self, context, event)
@classmethod
def poll(cls, context):
return context.active_object != None
def execute(self, context):
print("Selected: " + context.active_object.name)
if not self.properties.filepath:
raise Exception("filename not set")
save_settings_export(self.properties)
filepath = self.filepath
import io_mesh_threejs.export_threejs
return io_mesh_threejs.export_threejs.save(self, context, **self.properties)
def draw(self, context):
layout = self.layout
row = layout.row()
row.label(text="Geometry:")
row = layout.row()
row.prop(self.properties, "option_vertices")
# row = layout.row()
# row.enabled = self.properties.option_vertices
# row.prop(self.properties, "option_vertices_deltas")
row.prop(self.properties, "option_vertices_truncate")
layout.separator()
row = layout.row()
row.prop(self.properties, "option_faces")
row = layout.row()
row.enabled = self.properties.option_faces
# row.prop(self.properties, "option_faces_deltas")
layout.separator()
row = layout.row()
row.prop(self.properties, "option_normals")
layout.separator()
row = layout.row()
row.prop(self.properties, "option_edges")
layout.separator()
row = layout.row()
row.label(text="Materials:")
row = layout.row()
row.prop(self.properties, "option_uv_coords")
row.prop(self.properties, "option_colors")
row = layout.row()
row.prop(self.properties, "option_materials")
layout.separator()
row = layout.row()
row.label(text="Settings:")
row = layout.row()
row.prop(self.properties, "align_model")
row = layout.row()
row.prop(self.properties, "option_flip_yz")
row.prop(self.properties, "option_scale")
layout.separator()
row = layout.row()
row.label(text="Beta:")
row = layout.row()
row.prop(self.properties, "option_export_scene")
row.prop(self.properties, "option_lights")
row.prop(self.properties, "option_cameras")
row = layout.row()
row.prop(self.properties, "option_embed_meshes")
layout.separator()
# ################################################################
# Common
# ################################################################
def menu_func_export(self, context):
default_path = bpy.data.filepath.replace(".blend", ".js")
self.layout.operator(ExportTHREEJS.bl_idname, text="Three.js (.js)").filepath = default_path
def menu_func_import(self, context):
self.layout.operator(ImportTHREEJS.bl_idname, text="Three.js (.js)")
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_file_export.append(menu_func_export)
bpy.types.INFO_MT_file_import.append(menu_func_import)
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_export.remove(menu_func_export)
bpy.types.INFO_MT_file_import.remove(menu_func_import)
if __name__ == "__main__":
register()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册