Files
DefinitelyTyped/physijs/tests/jenga.ts
2015-09-03 20:56:43 +09:00

237 lines
7.8 KiB
TypeScript

/// <reference path="../../stats/stats.d.ts" />
/// <reference path="../physijs.d.ts" />
/// <reference path="../../threejs/three-projector.d.ts" />
Physijs.scripts.worker = '../physijs_worker.js';
Physijs.scripts.ammo = 'examples/js/ammo.js';
var initScene, initEventHandling, render, createTower,
renderer, render_stats, physics_stats, scene, dir_light, am_light, camera,
table, blocks = [], table_material, block_material, intersect_plane, _i,
selected_block = null, mouse_pos = new THREE.Vector3(), block_offset = new THREE.Vector3(), _v3 = new THREE.Vector3();
initScene = function() {
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
document.getElementById( 'viewport' ).appendChild( renderer.domElement );
render_stats = new Stats();
render_stats.domElement.style.position = 'absolute';
render_stats.domElement.style.top = '1px';
render_stats.domElement.style.zIndex = 100;
document.getElementById( 'viewport' ).appendChild( render_stats.domElement );
physics_stats = new Stats();
physics_stats.domElement.style.position = 'absolute';
physics_stats.domElement.style.top = '50px';
physics_stats.domElement.style.zIndex = 100;
document.getElementById( 'viewport' ).appendChild( physics_stats.domElement );
scene = new Physijs.Scene({ fixedTimeStep: 1 / 120 });
scene.setGravity(new THREE.Vector3( 0, -30, 0 ));
scene.addEventListener(
'update',
function() {
if ( selected_block !== null ) {
_v3.copy( mouse_pos ).add( block_offset ).sub( selected_block.position ).multiplyScalar( 5 );
_v3.y = 0;
selected_block.setLinearVelocity( _v3 );
// Reactivate all of the blocks
_v3.set( 0, 0, 0 );
for ( _i = 0; _i < blocks.length; _i++ ) {
blocks[_i].applyCentralImpulse( _v3 );
}
}
scene.simulate( undefined, 1 );
physics_stats.update();
}
);
camera = new THREE.PerspectiveCamera(
35,
window.innerWidth / window.innerHeight,
1,
1000
);
camera.position.set( 25, 20, 25 );
camera.lookAt(new THREE.Vector3( 0, 7, 0 ));
scene.add( camera );
// ambient light
am_light = new THREE.AmbientLight( 0x444444 );
scene.add( am_light );
// directional light
dir_light = new THREE.DirectionalLight( 0xFFFFFF );
dir_light.position.set( 20, 30, -5 );
dir_light.target.position.copy( scene.position );
dir_light.castShadow = true;
dir_light.shadowCameraLeft = -30;
dir_light.shadowCameraTop = -30;
dir_light.shadowCameraRight = 30;
dir_light.shadowCameraBottom = 30;
dir_light.shadowCameraNear = 20;
dir_light.shadowCameraFar = 200;
dir_light.shadowBias = -.001
dir_light.shadowMapWidth = dir_light.shadowMapHeight = 2048;
dir_light.shadowDarkness = .5;
scene.add( dir_light );
// Materials
table_material = Physijs.createMaterial(
new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture( 'images/wood.jpg' ) }),
.9, // high friction
.2 // low restitution
);
table_material.map.wrapS = table_material.map.wrapT = THREE.RepeatWrapping;
table_material.map.repeat.set( 5, 5 );
block_material = Physijs.createMaterial(
new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture( 'images/plywood.jpg' ) }),
.4, // medium friction
.4 // medium restitution
);
block_material.map.wrapS = block_material.map.wrapT = THREE.RepeatWrapping;
block_material.map.repeat.set( 1, .5 );
// Table
table = new Physijs.BoxMesh(
new THREE.BoxGeometry(50, 1, 50),
table_material,
0
);
table.position.y = -.5;
table.receiveShadow = true;
scene.add( table );
createTower();
intersect_plane = new THREE.Mesh(
new THREE.PlaneGeometry( 150, 150 ),
new THREE.MeshBasicMaterial({ opacity: 0, transparent: true })
);
intersect_plane.rotation.x = Math.PI / -2;
scene.add( intersect_plane );
initEventHandling();
requestAnimationFrame( render );
scene.simulate();
};
render = function() {
requestAnimationFrame( render );
renderer.render( scene, camera );
render_stats.update();
};
createTower = (function() {
var block_length = 6, block_height = 1, block_width = 1.5, block_offset = 2,
block_geometry = new THREE.BoxGeometry( block_length, block_height, block_width );
return function() {
var i, j, rows = 16,
block;
for ( i = 0; i < rows; i++ ) {
for ( j = 0; j < 3; j++ ) {
block = new Physijs.BoxMesh( block_geometry, block_material );
block.position.y = (block_height / 2) + block_height * i;
if ( i % 2 === 0 ) {
block.rotation.y = Math.PI / 2.01; // #TODO: There's a bug somewhere when this is to close to 2
block.position.x = block_offset * j - ( block_offset * 3 / 2 - block_offset / 2 );
} else {
block.position.z = block_offset * j - ( block_offset * 3 / 2 - block_offset / 2 );
}
block.receiveShadow = true;
block.castShadow = true;
scene.add( block );
blocks.push( block );
}
}
}
})();
initEventHandling = (function() {
var _vector = new THREE.Vector3,
projector = new THREE.Projector(),
handleMouseDown, handleMouseMove, handleMouseUp;
handleMouseDown = function( evt ) {
var ray, intersections;
_vector.set(
( evt.clientX / window.innerWidth ) * 2 - 1,
-( evt.clientY / window.innerHeight ) * 2 + 1,
1
);
projector.unprojectVector( _vector, camera );
ray = new THREE.Raycaster( camera.position, _vector.sub( camera.position ).normalize() );
intersections = ray.intersectObjects( blocks );
if ( intersections.length > 0 ) {
selected_block = intersections[0].object;
_vector.set( 0, 0, 0 );
selected_block.setAngularFactor( _vector );
selected_block.setAngularVelocity( _vector );
selected_block.setLinearFactor( _vector );
selected_block.setLinearVelocity( _vector );
mouse_pos.copy( intersections[0].point );
block_offset.subVectors( selected_block.position, mouse_pos );
intersect_plane.position.y = mouse_pos.y;
}
};
handleMouseMove = function( evt ) {
var ray, intersection,
i, scalar;
if ( selected_block !== null ) {
_vector.set(
( evt.clientX / window.innerWidth ) * 2 - 1,
-( evt.clientY / window.innerHeight ) * 2 + 1,
1
);
projector.unprojectVector( _vector, camera );
ray = new THREE.Raycaster( camera.position, _vector.sub( camera.position ).normalize() );
intersection = ray.intersectObject( intersect_plane );
mouse_pos.copy( intersection[0].point );
}
};
handleMouseUp = function( evt ) {
if ( selected_block !== null ) {
_vector.set( 1, 1, 1 );
selected_block.setAngularFactor( _vector );
selected_block.setLinearFactor( _vector );
selected_block = null;
}
};
return function() {
renderer.domElement.addEventListener( 'mousedown', handleMouseDown );
renderer.domElement.addEventListener( 'mousemove', handleMouseMove );
renderer.domElement.addEventListener( 'mouseup', handleMouseUp );
};
})();
window.onload = initScene;