threex
Version:
Game Extensions for three.js http://www.threejsgames.com/extensions/
145 lines (135 loc) • 4.48 kB
HTML
<script src="../../../vendor/three.js/build/three.min.js"></script>
<script src="../../threex.loop/THREEx.Loop.js"></script>
<body style='margin: 0px; background-color: #bbbbbb;overflow: hidden;'><script>
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var updateFcts = [];
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 3;
var loop = new THREEx.Loop().start();
var geometry = new THREE.TorusGeometry( 0.35, 0.15 );
var material = new THREE.MeshNormalMaterial();
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
mesh.position.y = -0.5;
mesh.rotation.x = Math.PI/2;
var position = new THREE.Vector3
var emitter = new BlackSmoke(scene).start(mesh.position)
loop.hook(function(delta, now){ emitter.update(delta, now) })
loop.hook(function(delta, now){
renderer.render( scene, camera );
})
//////////////////////////////////////////////////////////////////////////////////
// comment //
//////////////////////////////////////////////////////////////////////////////////
function BlackSmoke(container){
var updateFcts = []
var texture = THREE.ImageUtils.loadTexture('images/cloud10.png')
var center = new THREE.Vector3(0,-0.8, 0)
var maxAge = 1.5;
var age2Friction= (function(){
var gradient = createLinearGradient([
{x : 0.00, y: 1.00}, {x : 0.50, y: 1.00},
{x : 0.70, y: 0.90}, {x : 1.00, y: 0.90}
]);
return function(age, maxAge){
return gradient(age/maxAge)
}
})();
var age2Opacity = createTweenMidi(maxAge, 0.05*maxAge, 0.4*maxAge);
this.emit = function(position){
// init sprite material
var material = new THREE.SpriteMaterial({
map : texture,
useScreenCoordinates : false,
})
// init sprite
var sprite = new THREE.Sprite(material)
sprite.position.copy(position)
sprite.position.x += (Math.random()-0.5)*0.1
sprite.position.y += (Math.random()-0.5)*0.0001
sprite.position.z += (Math.random()-0.5)*0.1
container.add(sprite)
// set velocity
var velocity = new THREE.Vector3(0, 1, 0)
velocity.x += (Math.random()-0.5)*0.3;
velocity.y += (Math.random()-0.5)*0.1;
velocity.z += (Math.random()-0.5)*0.3;
velocity.setLength(1.15 + (Math.random()-0.5)*0.3)
// init patterm
material.color.setHex( 0x010101*Math.floor(255*(Math.random()*0.1+0.3)) );
sprite.scale.set(1,1,1).multiplyScalar(0.8 + Math.random()*0.2)
sprite.rotation = Math.random() * Math.PI*2
material.opacity= age2Opacity(0)
var birthDate = Date.now()/1000;
updateFcts.push(function callback(delta, now){
var age = now - birthDate;
if( age >= maxAge ){
sprite.parent.remove(sprite)
updateFcts.splice(updateFcts.indexOf(callback),1)
return;
}
// handle friction
velocity.multiplyScalar( age2Friction(age, maxAge) )
// move by velocity
sprite.position.add( velocity.clone().multiplyScalar(delta) )
// make it grow
sprite.scale.multiplyScalar( 1.005 )
material.opacity = age2Opacity(age)
})
}
var _loopCb = null;
this.start = function(position, rate){
rate = rate !== undefined ? rate : 5;
var lastEmit = 0;
updateFcts.push(_loopCb = function(delta, now){
// rate limiter emition
if( rate === 0 || now - lastEmit < 1/rate ) return;
lastEmit = now;
this.emit(position)
}.bind(this))
return this;
}
this.stop = function(){
updateFcts.splice(updateFcts.indexOf(_loopCb),1)
return this;
}
this.update = function(delta, now){
updateFcts.forEach(function(updateFct){
updateFct(delta, now)
})
}
function createTweenMidi(maxAge, attackTime, releaseTime){
return function(age){
if( age < attackTime ){
return age / attackTime
}else if( age < maxAge - releaseTime ){
return 1;
}else{
return (maxAge - age) / releaseTime
}
}
}
function createLinearGradient(keyPoints){
return function(x){
// find the keyPoints
for( var i = 0; i < keyPoints.length; i++ ){
if( x <= keyPoints[i].x ) break;
}
if( i === 0 ) return keyPoints[0].y;
// sanity check
console.assert(i < keyPoints.length );
// compute the y
var previous = keyPoints[i-1];
var next = keyPoints[i];
var ratio = (x - previous.x) / (next.x - previous.x)
var y = previous.y + ratio * (next.y - previous.y)
// return y
return y;
}
}
}
</script></body>