「坂とスーパーボール」の編集履歴(バックアップ)一覧はこちら
「坂とスーパーボール」(2013/05/04 (土) 00:46:43) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
#divclass(modif){更新日:&date(), r58}
#divclass(hd){#hr()}
#divid(d0){}
SonyのBRAVIAのアレ。
cannon.jsとパーティクル。
THREE.ParticleSystemでvertices変更、THREE.Spriteでposition変更 + THREE.Object3Dでグループ、平面Meshでposition変更 + THREE.Object3Dでグループ、を比較したところ、パーティクルが一番速かった。
テクスチャをCanvasで描くのと画像読み込みで速さに差はなかった。
#javascript(){{
<script type="text/javascript" src="http://cdn56.atwikiimg.com/threejs/pub/three.min.js"></script>
<script type="text/javascript" src="http://cdn56.atwikiimg.com/threejs/pub/Detector.js"></script>
<script type="text/javascript" src="http://cdn56.atwikiimg.com/threejs/pub/cannon.min.js"></script>
<script type="text/javascript"><!--
$(function(){
var fps = 20;
var world, timeStep=1/fps, renderer, camera, scene;
var groundBody,groundMesh;
var particleBodyArr, particleSys, particleAmount = 150;
var width = 320, height = 240;
function sinit(){
initThree();
initCannon();
animate();
}
function initCannon() {
world = new CANNON.World();
world.gravity.set(0,-100,0);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 1;
particleBodyArr = [];
var mass = 0.5;
var particlePhysMat = new CANNON.Material();
for(var i=0; i<particleAmount; i++){
var particleBody = new CANNON.Particle(mass, particlePhysMat);
particleBody.position.set((Math.random()-0.5)*160, 120+Math.random()*20, (Math.random()-0.5)*150-220);
particleBodyArr[i] = particleBody;
world.add(particleBody);
}
var groundPhysMat = new CANNON.Material();
var groundShape = new CANNON.Plane( new CANNON.Vec3(0,0,1) );
groundBody = new CANNON.RigidBody(0, groundShape, groundPhysMat);
groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1,0,0), -Math.PI/2*0.8);
world.add(groundBody);
var particle_ground = new CANNON.ContactMaterial(particlePhysMat,groundPhysMat, 0.3, 1.0);
world.addContactMaterial(particle_ground);
}
function initThree() {
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 45, width / height, 1, 10000 );
camera.position.set(0, -40, 300);
camera.lookAt(new THREE.Vector3(0, -40, 0));
// light
var light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set(1, 4, 1).normalize();
scene.add( light );
// particle system
particleSysGeo = new THREE.Geometry();
for ( i = 0; i < particleAmount; i ++ ) {
var vertex = new THREE.Vector3();
particleSysGeo.vertices.push( vertex );
var color = new THREE.Color();
color.setHSL(Math.random(), 1, 0.5);
particleSysGeo.colors.push( color );
}
// texture canvas for a particle
var particleTexCanvas = document.createElement('canvas');
particleTexCanvas.width = 128, particleTexCanvas.height = 128;
var ctx = particleTexCanvas.getContext('2d');
var grd = ctx.createRadialGradient(80,40, 10, 64,64, 60);
grd.addColorStop(0, "#ffffff");
grd.addColorStop(1, "#333333");
ctx.arc(64,64, 60, 0,Math.PI*2);
ctx.fillStyle = grd;
ctx.fill();
// texture
particleTex = new THREE.Texture( particleTexCanvas );
particleTex.needsUpdate = true;
particleMat = new THREE.ParticleBasicMaterial( {
color:0xffffff, size: 10, map: particleTex, transparent: true, vertexColors:true
} );
particleSys = new THREE.ParticleSystem( particleSysGeo, particleMat );
particleSys.sortParticles = true;
scene.add( particleSys );
// floor
var oneWidth = 60, oneHeight = 60, wUnits = 3, hUnits = 11;
var groundGeo = new THREE.PlaneGeometry(oneWidth*wUnits, oneHeight*hUnits, wUnits, hUnits);
for(var i=0, len = groundGeo.faces.length, f=-1; i<len; i++){
f = -1;
if((i/wUnits | 0)%2==1){ f = ~f; }
if((i%wUnits)%2==1){ f = ~f; }
groundGeo.faces[i].materialIndex = f+1;
}
groundMesh = new THREE.Mesh(
groundGeo,
new THREE.MeshFaceMaterial([
new THREE.MeshBasicMaterial({color: 0x999999 }),
new THREE.MeshBasicMaterial({color: 0x4d4d4d })
])
);
groundMesh.useQuaternion = true;
scene.add(groundMesh);
//right wall
var kabeGeo = new THREE.PlaneGeometry(600, 200, 15, 5);
var kabeMat = new THREE.MeshBasicMaterial({color: 0x999999, wireframe:true });
var kabeMesh = new THREE.Mesh( kabeGeo, kabeMat );
kabeMesh.rotation.y = Math.PI/2;
kabeMesh.position.x = 90;
scene.add(kabeMesh);
//left wall
kabeMesh = new THREE.Mesh( kabeGeo, kabeMat );
kabeMesh.rotation.y = Math.PI/2;
kabeMesh.position.x = -90;
scene.add(kabeMesh);
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( width, height );
var container = $('#d0');
container.empty();
container.append( renderer.domElement );
container.after(
$('<button>').text('落とす').click(function(){
for(var i=0; i<particleAmount; i++){
// Copy FROM Cannon.js TO Three.js
var c = particleBodyArr[i];
c.position.set((Math.random()-0.5)*160, 120+Math.random()*20, (Math.random()-0.5)*150-220);
c.velocity.set(0,0,0);
}
})
);
}
function animate() {
updatePhysics();
render();
setTimeout(animate, 1000/fps);
}
function render() {
renderer.render( scene, camera );
}
function updatePhysics() {
// Step the physics world
world.step(timeStep);
for(var i=0; i<particleAmount; i++){
// Copy FROM Cannon.js TO Three.js
var c = particleBodyArr[i];
if(c.position.z > 300){
c.position.z -= 180;
c.position.y = 5+Math.random()*5;
c.velocity.set(0, c.velocity.y, 90);
}
c.position.copy(particleSys.geometry.vertices[i]);
}
// particleSys.geometry.verticesNeedUpdate = true; // sortParticles trueなので要らない
groundBody.position.copy(groundMesh.position);
groundBody.quaternion.copy(groundMesh.quaternion);
}
if ( Detector.webgl ){
sinit();
}else{
$('#d0').html('<span style="color:red;">あなたが使用中のブラウザはWebGL非対応もしくはWebGLが有効になっていません。</span>');
}
});
//--></script>
}}
//.
#divclass(modif){更新日:&date(), r58}
#divclass(hd){#hr()}
#divid(d0){}
SonyのBRAVIAのアレ。
cannon.jsとパーティクル。
(1) THREE.ParticleSystemのvertices変更、(2) THREE.Spriteのposition変更 + THREE.Object3Dでグループ、(3) 平面Meshのposition変更 + THREE.Object3Dでグループ、を比較したところ、パーティクルが一番速かった。
テクスチャをCanvasで描くのと画像読み込みで速さに差はなかった。
#javascript(){{
<script type="text/javascript" src="http://cdn56.atwikiimg.com/threejs/pub/three.min.js"></script>
<script type="text/javascript" src="http://cdn56.atwikiimg.com/threejs/pub/Detector.js"></script>
<script type="text/javascript" src="http://cdn56.atwikiimg.com/threejs/pub/cannon.min.js"></script>
<script type="text/javascript"><!--
$(function(){
var fps = 20;
var world, timeStep=1/fps, renderer, camera, scene;
var groundBody,groundMesh;
var particleBodyArr, particleSys, particleAmount = 150;
var width = 320, height = 240;
function sinit(){
initThree();
initCannon();
animate();
}
function initCannon() {
world = new CANNON.World();
world.gravity.set(0,-100,0);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 1;
particleBodyArr = [];
var mass = 0.5;
var particlePhysMat = new CANNON.Material();
for(var i=0; i<particleAmount; i++){
var particleBody = new CANNON.Particle(mass, particlePhysMat);
particleBody.position.set((Math.random()-0.5)*160, 120+Math.random()*20, (Math.random()-0.5)*150-220);
particleBodyArr[i] = particleBody;
world.add(particleBody);
}
var groundPhysMat = new CANNON.Material();
var groundShape = new CANNON.Plane( new CANNON.Vec3(0,0,1) );
groundBody = new CANNON.RigidBody(0, groundShape, groundPhysMat);
groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1,0,0), -Math.PI/2*0.8);
world.add(groundBody);
var particle_ground = new CANNON.ContactMaterial(particlePhysMat,groundPhysMat, 0.3, 1.0);
world.addContactMaterial(particle_ground);
}
function initThree() {
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 45, width / height, 1, 10000 );
camera.position.set(0, -40, 300);
camera.lookAt(new THREE.Vector3(0, -40, 0));
// light
var light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set(1, 4, 1).normalize();
scene.add( light );
// particle system
particleSysGeo = new THREE.Geometry();
for ( i = 0; i < particleAmount; i ++ ) {
var vertex = new THREE.Vector3();
particleSysGeo.vertices.push( vertex );
var color = new THREE.Color();
color.setHSL(Math.random(), 1, 0.5);
particleSysGeo.colors.push( color );
}
// texture canvas for a particle
var particleTexCanvas = document.createElement('canvas');
particleTexCanvas.width = 128, particleTexCanvas.height = 128;
var ctx = particleTexCanvas.getContext('2d');
var grd = ctx.createRadialGradient(80,40, 10, 64,64, 60);
grd.addColorStop(0, "#ffffff");
grd.addColorStop(1, "#333333");
ctx.arc(64,64, 60, 0,Math.PI*2);
ctx.fillStyle = grd;
ctx.fill();
// texture
particleTex = new THREE.Texture( particleTexCanvas );
particleTex.needsUpdate = true;
particleMat = new THREE.ParticleBasicMaterial( {
color:0xffffff, size: 10, map: particleTex, transparent: true, vertexColors:true
} );
particleSys = new THREE.ParticleSystem( particleSysGeo, particleMat );
particleSys.sortParticles = true;
scene.add( particleSys );
// floor
var oneWidth = 60, oneHeight = 60, wUnits = 3, hUnits = 11;
var groundGeo = new THREE.PlaneGeometry(oneWidth*wUnits, oneHeight*hUnits, wUnits, hUnits);
for(var i=0, len = groundGeo.faces.length, f=-1; i<len; i++){
f = -1;
if((i/wUnits | 0)%2==1){ f = ~f; }
if((i%wUnits)%2==1){ f = ~f; }
groundGeo.faces[i].materialIndex = f+1;
}
groundMesh = new THREE.Mesh(
groundGeo,
new THREE.MeshFaceMaterial([
new THREE.MeshBasicMaterial({color: 0x999999 }),
new THREE.MeshBasicMaterial({color: 0x4d4d4d })
])
);
groundMesh.useQuaternion = true;
scene.add(groundMesh);
//right wall
var kabeGeo = new THREE.PlaneGeometry(600, 200, 15, 5);
var kabeMat = new THREE.MeshBasicMaterial({color: 0x999999, wireframe:true });
var kabeMesh = new THREE.Mesh( kabeGeo, kabeMat );
kabeMesh.rotation.y = Math.PI/2;
kabeMesh.position.x = 90;
scene.add(kabeMesh);
//left wall
kabeMesh = new THREE.Mesh( kabeGeo, kabeMat );
kabeMesh.rotation.y = Math.PI/2;
kabeMesh.position.x = -90;
scene.add(kabeMesh);
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( width, height );
var container = $('#d0');
container.empty();
container.append( renderer.domElement );
container.after(
$('<button>').text('落とす').click(function(){
for(var i=0; i<particleAmount; i++){
// Copy FROM Cannon.js TO Three.js
var c = particleBodyArr[i];
c.position.set((Math.random()-0.5)*160, 120+Math.random()*20, (Math.random()-0.5)*150-220);
c.velocity.set(0,0,0);
}
})
);
}
function animate() {
updatePhysics();
render();
setTimeout(animate, 1000/fps);
}
function render() {
renderer.render( scene, camera );
}
function updatePhysics() {
// Step the physics world
world.step(timeStep);
for(var i=0; i<particleAmount; i++){
// Copy FROM Cannon.js TO Three.js
var c = particleBodyArr[i];
if(c.position.z > 300){
c.position.z -= 180;
c.position.y = 5+Math.random()*5;
c.velocity.set(0, c.velocity.y, 90);
}
c.position.copy(particleSys.geometry.vertices[i]);
}
// particleSys.geometry.verticesNeedUpdate = true; // sortParticles trueなので要らない
groundBody.position.copy(groundMesh.position);
groundBody.quaternion.copy(groundMesh.quaternion);
}
if ( Detector.webgl ){
sinit();
}else{
$('#d0').html('<span style="color:red;">あなたが使用中のブラウザはWebGL非対応もしくはWebGLが有効になっていません。</span>');
}
});
//--></script>
}}
//.