mirror of
https://github.com/zhigang1992/DefinitelyTyped.git
synced 2026-05-12 19:59:02 +08:00
237 lines
7.8 KiB
TypeScript
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;
|