Upgrade to Pro — share decks privately, control downloads, hide ads and more …

three.jsとRapierでレースゲームが3日でできた話

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for yomotsu yomotsu
October 21, 2023

 three.jsとRapierでレースゲームが3日でできた話

Avatar for yomotsu

yomotsu

October 21, 2023
Tweet

More Decks by yomotsu

Other Decks in Programming

Transcript

  1. terrainMesh.updateWorldMatrix( true, true ); terrainMesh.traverse( ( object ) => {

    if ( ! object.isMesh ) return; const geometry = object.geometry.clone(); geometry.applyMatrix4( object.matrix ); geometry.computeVertexNormals(); const vertices = new Float32Array( geometry.attributes.position.array ); const indices = new Uint32Array( geometry.index.array ); const groundColliderDesc = RAPIER.ColliderDesc.trimesh( new Float32Array(vertices), new Uint32Array(indices) ) .setActiveEvents( RAPIER.ActiveEvents.COLLISION_EVENTS ); const groundCollider = world.createCollider( groundColliderDesc ); } ); QPTJUJPO΍SPUBUJPO͕ ద༻͞Ε͍ͯΔ৔߹͸ ࣄલʹߦྻʹ൓ө͢Δ ʢ௨ৗ͸SFOEFS࣌ʹద༻͞ΕΔʣ
  2. terrainMesh.updateWorldMatrix( true, true ); terrainMesh.traverse( ( object ) => {

    if ( ! object.isMesh ) return; const geometry = object.geometry.clone(); geometry.applyMatrix4( object.matrix ); geometry.computeVertexNormals(); const vertices = new Float32Array( geometry.attributes.position.array ); const indices = new Uint32Array( geometry.index.array ); const groundColliderDesc = RAPIER.ColliderDesc.trimesh( new Float32Array(vertices), new Uint32Array(indices) ) .setActiveEvents( RAPIER.ActiveEvents.COLLISION_EVENTS ); const groundCollider = world.createCollider( groundColliderDesc ); } ); .FTI಺ͷ શδΦϝτϦʔʹରͯ͠ʜ
  3. terrainMesh.updateWorldMatrix( true, true ); terrainMesh.traverse( ( object ) => {

    if ( ! object.isMesh ) return; const geometry = object.geometry.clone(); geometry.applyMatrix4( object.matrix ); geometry.computeVertexNormals(); const vertices = new Float32Array( geometry.attributes.position.array ); const indices = new Uint32Array( geometry.index.array ); const groundColliderDesc = RAPIER.ColliderDesc.trimesh( new Float32Array(vertices), new Uint32Array(indices) ) .setActiveEvents( RAPIER.ActiveEvents.COLLISION_EVENTS ); const groundCollider = world.createCollider( groundColliderDesc ); } ); ίϐʔͨ͠δΦϝτϦΛ ഁյૢ࡞͍ͯ͘͠
  4. terrainMesh.updateWorldMatrix( true, true ); terrainMesh.traverse( ( object ) => {

    if ( ! object.isMesh ) return; const geometry = object.geometry.clone(); geometry.applyMatrix4( object.matrix ); geometry.computeVertexNormals(); const vertices = new Float32Array( geometry.attributes.position.array ); const indices = new Uint32Array( geometry.index.array ); const groundColliderDesc = RAPIER.ColliderDesc.trimesh( new Float32Array(vertices), new Uint32Array(indices) ) .setActiveEvents( RAPIER.ActiveEvents.COLLISION_EVENTS ); const groundCollider = world.createCollider( groundColliderDesc ); } ); ม׵ߦྻΛ௖఺ʹম͖෇͚Δ
  5. terrainMesh.updateWorldMatrix( true, true ); terrainMesh.traverse( ( object ) => {

    if ( ! object.isMesh ) return; const geometry = object.geometry.clone(); geometry.applyMatrix4( object.matrix ); geometry.computeVertexNormals(); const vertices = new Float32Array( geometry.attributes.position.array ); const indices = new Uint32Array( geometry.index.array ); const groundColliderDesc = RAPIER.ColliderDesc.trimesh( new Float32Array(vertices), new Uint32Array(indices) ) .setActiveEvents( RAPIER.ActiveEvents.COLLISION_EVENTS ); const groundCollider = world.createCollider( groundColliderDesc ); } ); UISFFKTͷHFPNFUSZ͔Β ಺༰ΛऔΓग़ͯ͠
  6. terrainMesh.updateWorldMatrix( true, true ); terrainMesh.traverse( ( object ) => {

    if ( ! object.isMesh ) return; const geometry = object.geometry.clone(); geometry.applyMatrix4( object.matrix ); geometry.computeVertexNormals(); const vertices = new Float32Array( geometry.attributes.position.array ); const indices = new Uint32Array( geometry.index.array ); const groundColliderDesc = RAPIER.ColliderDesc.trimesh( new Float32Array(vertices), new Uint32Array(indices) ) .setActiveEvents( RAPIER.ActiveEvents.COLLISION_EVENTS ); const groundCollider = world.createCollider( groundColliderDesc ); } ); ௖఺഑ྻ͔Β 3BQJFSͷ߶ମΛ࡞ΕΔ
  7. w UISFFKT w %ඳըػೳ w ೚ҙϞσϧͷಡΈࠐΈʢHM5'ʣ w 3BQJFS w ೚ҙϝογϡ͔Β߶ମΛ࡞Δ

    w ࣗಈं෺ཧγϛϡϨʔγϣϯʢ*TBBD͞Μ੡ʣ ཁ݅ୡ੒ʹඞཁͳػೳ
  8. // 物理 const gravity = { x: 0, y: -9.81,

    z: 0 }; const world = new RAPIER.World( gravity ); world.timestep = 0.016; // 表示 const width = window.innerWidth; const height = window.innerHeight; const clock = new THREE.Clock(); const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 60, width / height, 0.01, 100 ); const renderer = new THREE.WebGLRenderer(); renderer.setSize( width, height ); document.body.appendChild( renderer.domElement ); https://github.com/yomotsu/rapier-tryout ෺ཧγϛϡϨʔγϣϯೖΕ෺XPSME දࣔͷೖΕ෺TDFOF
  9. const radius = 1; // 表示 const ballMesh = new

    Mesh( new SphereGeometry( radius, 16, 16 ), new MeshNormalMaterial( { wireframe: true } ) ); scene.add( ballMesh ); // 物理 const rigidBodyDesc = RAPIER.RigidBodyDesc.dynamic() .setLinearDamping( 0.1 ) .setTranslation( 0, 3, 0 ); const rigidBody = world.createRigidBody( rigidBodyDesc ); const colliderDesc = RAPIER.ColliderDesc.ball( radius ) .setFriction( 0.1 ) .setFrictionCombineRule( RAPIER.CoefficientCombineRule.Max ) .setRestitution( 0.6 ) .setRestitutionCombineRule( RAPIER.CoefficientCombineRule.Max ); world.createCollider( colliderDesc, rigidBody ); https://github.com/yomotsu/rapier-tryout ൒ܘ̍ͷٿମͷϝογϡ ൒ܘ̍ͷٿମͷ߶ମ TDFOF಺ʹ഑ஔ XPSME಺ʹ഑ஔ
  10. ( function gameLoop() { world.step(); ballMesh.position.copy( rigidBody.translation() ); ballMesh.quaternion.copy( rigidBody.rotation()

    ); setTimeout( gameLoop, world.timestep ); } )(); https://github.com/yomotsu/rapier-tryout UJNFTUFQ͸ඵͰݻఆࡁΈ ෺ཧ͸S"'Λ࢖Θͣɺݻఆඵϧʔϓͤ͞Δ ෺ཧγϛϡϨʔγϣϯ݁ՌΛ දࣔҐஔʹίϐʔ
  11. ( function renderLoop () { requestAnimationFrame( renderLoop ); renderer.render( scene,

    camera ); } )(); https://github.com/yomotsu/rapier-tryout දࣔ͸S"'Ͱɺ σόΠεෛՙʹԠͨ͡ϧʔϓΛͤ͞Δ
  12. const curvePath: THREE.CurvePath<THREE.Vector3> = new THREE.CurvePath(); curvePath.add( new THREE.CatmullRomCurve3( [

    new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, 0.1 ), new THREE.Vector3( 0, 0, 10 ), new THREE.Vector3( 0, 18, 50 ), new THREE.Vector3( 20, 18, 60 ), new THREE.Vector3( 20, 18, 0 ), new THREE.Vector3( 0, 18, 0 ), new THREE.Vector3( - 10, 18, 0 ), new THREE.Vector3( - 50, 0, - 50 ), new THREE.Vector3( 0, 0, - 50 ), new THREE.Vector3( 0, 0, - 10 ), ] ) );