UNPKG

matrix-engine-wgpu

Version:

+HOTFIX raycast, webGPU powered pwa application. Crazy fast rendering with AmmoJS physics support. Simple raycaster hit object added.

463 lines (412 loc) 13.5 kB
import MatrixEngineWGPU from "./src/world.js"; import {downloadMeshes} from './src/engine/loader-obj.js'; import {LOG_FUNNY, LOG_INFO, LOG_MATRIX, randomFloatFromTo, randomIntFromTo} from "./src/engine/utils.js"; import {dices, myDom} from "./examples/games/jamb/jamb.js"; import {MatrixSounds} from "./src/sounds/sounds.js"; import {addRaycastListener, touchCoordinate, rayIntersectsSphere, getRayFromMouse} from "./src/engine/raycast.js"; export let application = new MatrixEngineWGPU({ useSingleRenderPass: true, canvasSize: 'fullscreen', mainCameraParams: { type: 'WASD', responseCoef: 1000 } }, () => { // Dom operations application.myDom = myDom; myDom.createJamb(); myDom.createBlocker(); application.dices = dices; // this code must be on top application.matrixAmmo.detectCollision = function() { this.lastRoll = ''; this.presentScore = ''; let dispatcher = this.dynamicsWorld.getDispatcher(); let numManifolds = dispatcher.getNumManifolds(); for(let i = 0;i < numManifolds;i++) { let contactManifold = dispatcher.getManifoldByIndexInternal(i); // let numContacts = contactManifold.getNumContacts(); if(this.ground.kB == contactManifold.getBody0().kB || this.ground.kB == contactManifold.getBody1().kB) { // console.log(this.ground ,'GROUND IS IN CONTACT WHO IS BODY1 ', contactManifold.getBody1()) // CHECK ROTATION BEST WAY - VISAL PART IS NOT INTEREST NOW if(this.ground.kB == contactManifold.getBody0().kB) { var MY_DICE_NAME = this.getNameByBody(contactManifold.getBody1()); var testR = contactManifold.getBody1().getWorldTransform().getRotation(); } if(this.ground.kB == contactManifold.getBody1().kB) { var MY_DICE_NAME = this.getNameByBody(contactManifold.getBody0()); var testR = contactManifold.getBody0().getWorldTransform().getRotation(); } var passed = false; if(Math.abs(testR.y()) < 0.00001) { this.lastRoll = "3"; this.presentScore += 4; passed = true; } if(Math.abs(testR.x()) < 0.00001) { this.lastRoll = "5"; this.presentScore += 3; passed = true; } if(testR.x().toString().substring(0, 5) == testR.y().toString().substring(1, 6)) { this.lastRoll = "6"; this.presentScore += 2; passed = true; } if(testR.x().toString().substring(0, 5) == testR.y().toString().substring(0, 5)) { this.lastRoll = "2"; this.presentScore += 1; passed = true; } if(testR.z().toString().substring(0, 5) == testR.y().toString().substring(1, 6)) { this.lastRoll = "4"; this.presentScore += 6; passed = true; } if(testR.z().toString().substring(0, 5) == testR.y().toString().substring(0, 5)) { this.lastRoll = "1"; this.presentScore += 5; passed = true; } if(passed == true) dispatchEvent(new CustomEvent(`dice-${this.lastRoll}`, { detail: { result: `dice-${this.lastRoll}`, cubeId: MY_DICE_NAME } })) } } } addRaycastListener(); addEventListener("ray.hit.event", (e) => { console.log("hit cube ", e.detail.hitObject.name) if(application.dices.STATUS == "FREE_TO_PLAY") { console.log("hit cube status free to play prevent pick. ", e.detail.hitObject.name) } else if(application.dices.STATUS == "SELECT_DICES_1") { console.log("hit cube status SELECT1 pick.", e.detail.hitObject.name) application.dices.pickDice(e.detail.hitObject.name) } }); // OR add manual see readme addEventListener('mousemove', (e) => { // console.log('only on click') touchCoordinate.enabled = true; }) // Sounds application.matrixSounds.createAudio('start', 'res/audios/start.mp3', 1) application.matrixSounds.createAudio('block', 'res/audios/block.mp3', 6) application.matrixSounds.createAudio('dice1', 'res/audios/dice1.mp3', 6) application.matrixSounds.createAudio('dice2', 'res/audios/dice2.mp3', 6) addEventListener('AmmoReady', () => { downloadMeshes({ cube: "./res/meshes/jamb/dice.obj", }, onLoadObj, {scale: [1, 1, 1], swap: [null]}) downloadMeshes({ bg: "./res/meshes/jamb/bg.obj", }, onLoadObjFloor, {scale: [3, 1, 3], swap: [null]}) downloadMeshes({ mainTitle: "./res/meshes/jamb/jamb-title.obj", }, onLoadObjOther, {scale: [3, 2, 3], swap: [null]}) downloadMeshes({ cube: "./res/meshes/jamb/dice.obj", }, onLoadObjWallCenter, {scale: [50, 10, 10], swap: [null]}) downloadMeshes({ cube: "./res/meshes/jamb/dice.obj", }, (m) => { for(var key in m) { // console.log(`%c Loaded objs -> : ${key} `, LOG_MATRIX); } // right application.addMeshObj({ position: {x: 25, y: 5.5, z: -25}, rotation: {x: 0, y: -22, z: 0}, scale: [25, 10, 4], texturesPaths: ['./res/meshes/jamb/text.png'], name: 'wallRight', mesh: m.cube, physics: { mass: 0, enabled: true, geometry: "Cube" } }) application.addMeshObj({ position: {x: -25, y: 5.5, z: -25}, rotation: {x: 0, y: 22, z: 0}, scale: [25, 10, 4], texturesPaths: ['./res/meshes/jamb/text.png'], name: 'wallLeft', mesh: m.cube, physics: { mass: 0, enabled: true, geometry: "Cube" } }) }, {scale: [25, 10, 4], swap: [null]}) }) function onLoadObjWallCenter(m) { application.myLoadedMeshesWalls = m; for(var key in m) { // console.log(`%c Loaded objs -> : ${key} `, LOG_MATRIX); } // WALLS Center application.addMeshObj({ position: {x: 0, y: 5, z: -45}, rotation: {x: 0, y: 0, z: 0}, scale: [50, 10, 10], texturesPaths: ['./res/meshes/jamb/text.png'], name: 'wallCenter', mesh: m.cube, physics: { mass: 0, enabled: true, geometry: "Cube" } }) } function onLoadObjOther(m) { application.myLoadedMeshes = m; for(var key in m) { // console.log(`%c Loaded objs -> : ${key} `, LOG_MATRIX); } // Add logo text top application.addMeshObj({ position: {x: 0, y: 6, z: -15}, rotation: {x: 0, y: 0, z: 0}, texturesPaths: ['./res/meshes/jamb/text.png'], name: 'mainTitle', mesh: m.mainTitle, physics: { mass: 0, enabled: true, geometry: "Cube" } }) // console.log('camera set') // application.cameras.WASD.pitch = 0.2 setTimeout(() => { app.cameras.WASD.velocity[1] = 18 // BODY , x, y, z, rotX, rotY, RotZ app.matrixAmmo.setKinematicTransform( app.matrixAmmo.getBodyByName('mainTitle'), 0, 0, 0, 1) app.matrixAmmo.setKinematicTransform( app.matrixAmmo.getBodyByName('bg'), 0, -10, 0, 0, 0, 0) // Better access getBodyByName console.log(' app.matrixAmmo. ', app.matrixAmmo.getBodyByName('CubePhysics1')) }, 1225) } function onLoadObjFloor(m) { application.myLoadedMeshes = m; for(var key in m) { // console.log(`%c Loaded objs -> : ${key} `, LOG_MATRIX); } application.addMeshObj({ scale: [10, 0.1, 0.1], position: {x: 0, y: 6, z: -10}, rotation: {x: 0, y: 0, z: 0}, // rotationSpeed: {x: 0, y: 0, z: 0}, texturesPaths: ['./res/meshes/jamb/bg.png'], name: 'bg', mesh: m.bg, physics: { collide: false, mass: 0, enabled: true, geometry: "Cube" } }) } function onLoadObj(m) { application.myLoadedMeshes = m; for(var key in m) { // console.log(`%c Loaded objs -> : ${key} `, LOG_MATRIX); } // Add dices application.addMeshObj({ position: {x: 0, y: 6, z: -10}, rotation: {x: 0, y: 0, z: 0}, rotationSpeed: {x: 0, y: 0, z: 0}, texturesPaths: ['./res/meshes/jamb/dice.png'], useUVShema4x2: true, name: 'CubePhysics1', mesh: m.cube, raycast: {enabled: true, radius: 2}, physics: { enabled: true, geometry: "Cube" } }) application.addMeshObj({ position: {x: -5, y: 4, z: -14}, rotation: {x: 0, y: 0, z: 0}, rotationSpeed: {x: 0, y: 0, z: 0}, texturesPaths: ['./res/meshes/jamb/dice.png'], useUVShema4x2: true, name: 'CubePhysics2', mesh: m.cube, raycast: {enabled: true, radius: 2}, physics: { enabled: true, geometry: "Cube" } }) application.addMeshObj({ position: {x: 4, y: 8, z: -10}, rotation: {x: 0, y: 0, z: 0}, rotationSpeed: {x: 0, y: 0, z: 0}, texturesPaths: ['./res/meshes/jamb/dice.png'], useUVShema4x2: true, name: 'CubePhysics3', mesh: m.cube, raycast: {enabled: true, radius: 2}, physics: { enabled: true, geometry: "Cube" } }) application.addMeshObj({ position: {x: 3, y: 4, z: -10}, rotation: {x: 0, y: 0, z: 0}, rotationSpeed: {x: 0, y: 0, z: 0}, texturesPaths: ['./res/meshes/jamb/dice.png'], useUVShema4x2: true, name: 'CubePhysics4', mesh: m.cube, raycast: {enabled: true, radius: 2}, physics: { enabled: true, geometry: "Cube" } }) application.addMeshObj({ position: {x: -2, y: 4, z: -13}, rotation: {x: 0, y: 0, z: 0}, rotationSpeed: {x: 0, y: 0, z: 0}, texturesPaths: ['./res/meshes/jamb/dice.png'], useUVShema4x2: true, name: 'CubePhysics5', mesh: m.cube, raycast: {enabled: true,radius: 2}, physics: { enabled: true, geometry: "Cube" } }) application.addMeshObj({ position: {x: -4, y: 6, z: -9}, rotation: {x: 0, y: 0, z: 0}, rotationSpeed: {x: 0, y: 0, z: 0}, texturesPaths: ['./res/meshes/jamb/dice.png'], useUVShema4x2: true, name: 'CubePhysics6', mesh: m.cube, raycast: {enabled: true, radius: 2}, physics: { enabled: true, geometry: "Cube" } }) application.TOLERANCE = 0; let allDiceDoneProcedure = () => { console.log("ALL DONE") application.TOLERANCE++; if(application.TOLERANCE >= 1) { removeEventListener('dice-1', dice1Click) removeEventListener('dice-2', dice2Click) removeEventListener('dice-3', dice3Click) removeEventListener('dice-4', dice4Click) removeEventListener('dice-5', dice5Click) removeEventListener('dice-6', dice6Click) console.log('FINAL >>>> ', dices.R) application.TOLERANCE = 0; app.cameras.WASD.yaw = 0.01; app.cameras.WASD.pitch = -1.26; app.cameras.WASD.position[2] = -18; app.cameras.WASD.position[1] = 19; // dices.STATUS = "PLACE_RESULT"; dices.STATUS = "SELECT_DICES_1"; // application.dices.STATUS = "FREE_TO_PLAY"; } }; addEventListener('all-done', allDiceDoneProcedure) addEventListener('FREE_TO_PLAY', () => { // setup againt 3d space loc console.info(' setup againt 3d space loc make some logic for pos ...') app.matrixAmmo.getBodyByName('CubePhysics1').setLinearVelocity(new Ammo.btVector3(2, 2, 12)) app.matrixAmmo.getBodyByName('CubePhysics2').setLinearVelocity(new Ammo.btVector3(2, 2, 12)) app.matrixAmmo.getBodyByName('CubePhysics3').setLinearVelocity(new Ammo.btVector3(2, 2, 12)) app.matrixAmmo.getBodyByName('CubePhysics4').setLinearVelocity(new Ammo.btVector3(2, 2, 12)) app.matrixAmmo.getBodyByName('CubePhysics5').setLinearVelocity(new Ammo.btVector3(2, 2, 12)) app.matrixAmmo.getBodyByName('CubePhysics6').setLinearVelocity(new Ammo.btVector3(2, 2, 12)) }) // ACTIONS let dice1Click = (e) => { // console.info('DICE 1', e.detail) dices.R[e.detail.cubeId] = '1'; dices.checkAll() }; // addEventListener('dice-1', dice1Click) let dice2Click = (e) => { // console.info('DICE 2', e.detail) dices.R[e.detail.cubeId] = '2'; dices.checkAll() }; // addEventListener('dice-2', dice2Click) let dice3Click = (e) => { // console.info('DICE 3', e.detail) dices.R[e.detail.cubeId] = '3'; dices.checkAll() }; // addEventListener('dice-3', dice3Click) let dice4Click = (e) => { // console.info('DICE 4', e.detail) dices.R[e.detail.cubeId] = '4'; dices.checkAll() } // addEventListener('dice-4', dice4Click) let dice5Click = (e) => { // console.info('DICE 5', e.detail) dices.R[e.detail.cubeId] = '5'; dices.checkAll() } // addEventListener('dice-5', dice5Click) let dice6Click = (e) => { // console.info('DICE 6', e.detail) dices.R[e.detail.cubeId] = '6'; dices.checkAll() } // addEventListener('dice-6', dice6Click) let rollProcedure = () => { if(dices.STATUS == "FREE_TO_PLAY") { app.matrixSounds.play('start') dices.STATUS = "IN_PLAY"; addEventListener('dice-1', dice1Click) addEventListener('dice-2', dice2Click) addEventListener('dice-3', dice3Click) addEventListener('dice-4', dice4Click) addEventListener('dice-5', dice5Click) addEventListener('dice-6', dice6Click) function shootDice(x) { setTimeout(() => { app.matrixAmmo.getBodyByName(`CubePhysics${x}`).setAngularVelocity(new Ammo.btVector3( randomFloatFromTo(3, 12), 9, 9 )) app.matrixAmmo.getBodyByName(`CubePhysics${x}`).setLinearVelocity(new Ammo.btVector3( randomFloatFromTo(-5, 5), 15, -20 )) }, 200 * x) } for(var x = 1;x < 7;x++) { shootDice(x) } } } addEventListener('DICE.ROLL', rollProcedure) app.ROLL = () => { dispatchEvent(new CustomEvent('DICE.ROLL', {})) } } }) window.app = application