坂とスーパーボール

「坂とスーパーボール」の編集履歴(バックアップ)一覧はこちら

坂とスーパーボール」(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> }} //.

表示オプション

横に並べて表示:
変化行の前後のみ表示: