UNPKG

matrix-engine

Version:

basic_timeline improved, VT func setup vide html element id with name arg.- DISABLE RAYCAST DEBUG TEST [2.3.3] Fix for GUI win desktop [2.3.0] DestrucMesh solution & loading convex objs for physics BASIC, SpriteAnimation CPU/texture solution added, Improv

1,058 lines (993 loc) 38.4 kB
/** * @description Usage of raycaster, ObjectLoader, * FirstPersonController. * This will be part of new lib file `lib/controllers/fps.js` * * Example API calls Usage: * * - Deeply integrated to the top level scene object with name `player`. * App.scene.player.updateEnergy(4); * Predefined from 0 to the 8 energy value. * * @class First Person Shooter example */ import App from '../program/manifest'; import * as CANNON from 'cannon'; import {ENUMERATORS, ORBIT_FROM_ARRAY, OSCILLATOR, isMobile, randomFloatFromTo, scriptManager} from '../lib/utility'; import {RCSAccount} from "./rocket-crafting-server/rocket-crafting-account.js"; import {createPauseScreen} from './rocket-crafting-server/dom.js'; export var runThis = (world) => { const useRCSAccount = true; const RCSAccountDomain = 'https://maximumroulette.com'; addEventListener('onTitle', (e) => { document.title = e.detail }) // You can use import also. matrixEngine.utility.notify.hideTime = 100; matrixEngine.utility.notify.showTime = 1200; let notify = matrixEngine.utility.notify; let byId = matrixEngine.utility.byId; let ENUMERATORS = matrixEngine.utility.ENUMERATORS; let isMobile = matrixEngine.utility.isMobile; let randomFloatFromTo = matrixEngine.utility.randomFloatFromTo; let App = matrixEngine.App; let SYS = App.sys; setTimeout(() => document.querySelector('.button2').click(), 2000) // Camera canvas.style.cursor = 'none'; App.camera.FirstPersonController = true; matrixEngine.Events.camera.fly = false; App.camera.speedAmp = 0.02; matrixEngine.Events.camera.yPos = 10; // Keyboard event addEventListener('hit.keyDown', (e) => { if(e.detail.origin.key == "Escape" || e.detail.keyCode == 27) { console.log(`%cPAUSE SCREEN`, REDLOG) byId('pauseScreen').style.display = 'flex'; } }) // Audio effects App.sounds.createAudio('shoot', 'res/music/single-gunshot.mp3', 5); // Prevent right click context menu window.addEventListener("contextmenu", (e) => {e.preventDefault()}); // Only for mobile - Mobile player controller UI if(isMobile() == true) { byId('fps').style.display = 'none'; byId('debugBox').style.display = 'none'; matrixEngine.utility.createDomFPSController(); } // Activate networking matrixEngine.Engine.activateNet2(undefined, { sessionName: 'hang3d-matrix', resolution: '240x160' }); // Override mouse up - example how to use App.events.CALCULATE_TOUCH_UP_OR_MOUSE_UP = () => { App.scene.FPSTarget.glBlend.blendParamSrc = matrixEngine.utility.ENUMERATORS.glBlend.param[4]; App.scene.FPSTarget.glBlend.blendParamDest = matrixEngine.utility.ENUMERATORS.glBlend.param[4]; App.scene.FPSTarget.geometry.setScale(0.1); App.scene.xrayTarget.visible = false; }; // Override right mouse down matrixEngine.Events.SYS.MOUSE.ON_RIGHT_BTN_PRESSED = (e) => { App.scene.FPSTarget.geometry.setScale(0.6); App.scene.FPSTarget.glBlend.blendParamSrc = matrixEngine.utility.ENUMERATORS.glBlend.param[5]; App.scene.FPSTarget.glBlend.blendParamDest = matrixEngine.utility.ENUMERATORS.glBlend.param[5]; App.scene.xrayTarget.visible = true; }; App.events.multiTouch = function(ev, e) { if(e.length > 1) { // second touch detected wip mobile // e[1].pageX matrixEngine.raycaster.checkingProcedure(ev, { clientX: ev.target.width / 2, clientY: ev.target.height / 2 }); App.sounds.play('shoot'); } } if(isMobile() == true) { // Attach for mobile contrller also for desktop default // Mobile // For mobile i need to make interval calls on 10 ms // and incrase App.camera.yawRate from 1 to 6. App.camera.yawRate = 6; var MY_TIMERS = { TIMERLEFT: null, TIMERRIGHT: null, TIMERUP: null, TIMERDOWN: null, }; matrixEngine.Events.camera.preventSpeedZero = true; byId('mobLeft').addEventListener('touchmove', (e) => {e.preventDefault()}) byId('mobLeft').addEventListener('touchstart', (e) => { e.preventDefault() MY_TIMERS.TIMERLEFT = setInterval(() => {matrixEngine.Events.camera.yawRate = App.camera.yawRate;}, 10) }) byId('mobLeft').addEventListener('touchend', () => { clearInterval(MY_TIMERS.TIMERLEFT) MY_TIMERS.TIMERLEFT = null; }) byId('mobRight').addEventListener('touchmove', (e) => {e.preventDefault()}) byId('mobRight').addEventListener('touchstart', (e) => { e.preventDefault() MY_TIMERS.TIMERRIGHT = setInterval(() => {matrixEngine.Events.camera.yawRate = -App.camera.yawRate;}, 10) }) byId('mobRight').addEventListener('touchend', (e) => { clearInterval(MY_TIMERS.TIMERRIGHT) MY_TIMERS.TIMERRIGHT = null; }) byId('mobUp').addEventListener('touchmove', (e) => {e.preventDefault()}) byId('mobUp').addEventListener('touchstart', (e) => { e.preventDefault() MY_TIMERS.TIMERUP = setInterval(() => {matrixEngine.Events.camera.speed = App.camera.speedAmp;}, 10) }) byId('mobUp').addEventListener('touchend', (e) => { matrixEngine.Events.camera.speed = 0 clearInterval(MY_TIMERS.TIMERUP) MY_TIMERS.TIMERUP = null; }) byId('mobDown').addEventListener('touchmove', (e) => {e.preventDefault()}) byId('mobDown').addEventListener('touchstart', (e) => { e.preventDefault() MY_TIMERS.TIMERDOWN = setInterval(() => {matrixEngine.Events.camera.speed = -App.camera.speedAmp;}, 10) }) byId('mobDown').addEventListener('touchend', (e) => { matrixEngine.Events.camera.speed = 0 clearInterval(MY_TIMERS.TIMERDOWN) MY_TIMERS.TIMERDOWN = null; }) // For any case byId('mobDown').addEventListener('touchcancel', (e) => { matrixEngine.Events.camera.speed = 0 clearInterval(MY_TIMERS.TIMERDOWN) MY_TIMERS.TIMERDOWN = null; clearInterval(MY_TIMERS.TIMERUP) MY_TIMERS.TIMERUP = null; clearInterval(MY_TIMERS.TIMERRIGHT) MY_TIMERS.TIMERRIGHT = null; }) // Disable default App.events.CALCULATE_TOUCH_MOVE_OR_MOUSE_MOVE = () => {} // byId('domAngleAxis').style.width = innerWidth / 100 * 30 + "px"; // byId('domAngleAxis').style.height = innerHeight / 100 * 30 + "px"; byId('domAngleAxis').addEventListener('touchmove', (e) => { e.preventDefault() var center_x = window.innerWidth / 2; var center_y = window.innerHeight / 2; // Formula for adapting Axis controller var t = innerWidth / 2 - (e.target.offsetLeft + e.target.offsetWidth) + e.target.offsetWidth / 2; var t1 = innerHeight / 2 - (e.target.offsetTop + e.target.offsetHeight) + e.target.offsetHeight / 2; SYS.MOUSE.x = (e.changedTouches[0].clientX - center_x) + t; SYS.MOUSE.y = (e.changedTouches[0].clientY - center_y) + t1; //check to make sure there is data to compare against if(typeof SYS.MOUSE.LAST_POSITION.x != 'undefined') { //get the change from last position to this position var deltaX = SYS.MOUSE.LAST_POSITION.x - SYS.MOUSE.x, deltaY = SYS.MOUSE.LAST_POSITION.y - SYS.MOUSE.y; } if(App.camera.SceneController === true && keyboardPress.getKeyStatus(16) || App.camera.FirstPersonController === true) { // console.log('works for both now deltaX', deltaX) matrixEngine.Events.camera.pitchRate += deltaY * 10; matrixEngine.Events.camera.yawRate += deltaX * 2; if(SYS.MOUSE.x < App.camera.edgeMarginValue - center_x) { App.camera.leftEdge = true; } else { App.camera.leftEdge = false; } if(SYS.MOUSE.x > center_x - App.camera.edgeMarginValue) { App.camera.rightEdge = true; } else { App.camera.rightEdge = false; } } (SYS.MOUSE.LAST_POSITION.x = SYS.MOUSE.x), (SYS.MOUSE.LAST_POSITION.y = SYS.MOUSE.y); }) byId('mobFire').addEventListener('touchstart', (ev) => { ev.preventDefault() // fake it ev.target.width = window.innerWidth; ev.target.height = window.innerHeight; matrixEngine.raycaster.checkingProcedure(ev, { clientX: window.innerWidth / 2, clientY: window.innerHeight / 2 }); App.sounds.play('shoot'); }) } else { // Override mouse down App.events.CALCULATE_TOUCH_DOWN_OR_MOUSE_DOWN = (ev, mouse) => { if(isMobile() == false) { // `checkingProcedure` gets secound optimal argument // For custom ray origin target. if(mouse.BUTTON_PRESSED == 'RIGHT') { // Zoom } else { // This call represent `SHOOT` Action. And it is center of screen! matrixEngine.raycaster.checkingProcedure(ev, { clientX: ev.target.width / 2, clientY: ev.target.height / 2 }); App.sounds.play('shoot'); } } else { // Mobile IF WE WANT SHOT FROM ANY WHERE // This call represent `SHOOT` Action. And it is center of screen! } }; } // Receive data from network addEventListener('network-data', (e) => { console.log("receive:", e.detail) if(e.detail.damage) { console.log("damage from ", e.detail.damage.from, " to ", e.detail.damage.to) if(e.detail.damage.to == App.scene.playerCollisonBox.position.netObjId) { console.log("<my damage - here is catch who kills on both net sides>") notify.error(`${e.detail.damage.from} shot you!`) App.scene.player.energy.value -= (0.25 - (App.scene.player.items.armor ? App.scene.player.items.armor.preventDamage : 0)); // pre check for 0 if(App.scene.player.energy.value <= 0) { // killed by matrixEngine.Engine.net.connection.send({ kills: { killer: e.detail.damage.from, killed: e.detail.damage.to } }) // send it to spawn from space matrixEngine.Events.camera.xPos = 0; matrixEngine.Events.camera.zPos = 0; matrixEngine.Events.camera.yPos = 300; App.scene.playerCollisonBox. physics.currentBody.position.set( 0, 0, 300); } App.scene.player.updateEnergy(App.scene.player.energy.value); } } else if(e.detail.kills) { console.log("Killer: ", e.detail.kills.killer, " Killed: ", e.detail.kills.killed) if(e.detail.kills.killer == App.scene.playerCollisonBox.position.netObjId) { notify.show('You kill ' + e.detail.kills.killed) } else if(e.detail.kills.killed != App.scene.playerCollisonBox.position.netObjId) { notify.show(`${e.detail.kills.killer} kills ${e.detail.kills.killed}`) } } }) var preventFlagDouble = false; addEventListener('ray.hit.event', (ev) => { console.log(`%cYou shoot the object: ${ev.detail.hitObject}`, REDLOG); if(ev.detail.hitObject.name.indexOf('con_') == -1) { return; } if(preventFlagDouble == false) { preventFlagDouble = true; setTimeout(() => { preventFlagDouble = false; }, 100) } else { return; } notify.error(`Nice shoot`) if(ev.detail.hitObject.LightsData) { ev.detail.hitObject.LightsData.ambientLight.set( randomFloatFromTo(0, 2), randomFloatFromTo(0, 2), randomFloatFromTo(0, 2)); } matrixEngine.Engine.net.connection.send({ damage: { from: matrixEngine.Engine.net.connection.connectionId, to: ev.detail.hitObject.name } }); }) // Load obj seq animation const createObjSequence = (objName) => { let preventDoubleJump = null; function onLoadObj(meshes) { for(let key in meshes) { matrixEngine.objLoader.initMeshBuffers(world.GL.gl, meshes[key]); } var textuteImageSamplers2 = { source: ["res/bvh-skeletal-base/swat-guy/gun2.png"], mix_operation: "multiply" }; var animArg = { id: objName, meshList: meshes, currentAni: 0, animations: { active: 'walk', walk: { from: 0, to: 20, speed: 3 } } }; // WEAPON world.Add("obj", 1, objName, textuteImageSamplers2, meshes['player']); App.scene.player.position.setPosition(0.5, -0.7, -3); App.scene.player.isHUD = true; // Fix object orientation - this can be fixed also in blender. matrixEngine.Events.camera.yaw = 0; // Not in use but can be used function bodiesAreInContact(bodyA, bodyB) { for(var i = 0;i < world.contacts.length;i++) { var c = world.contacts[i]; if((c.bi === bodyA && c.bj === bodyB) || (c.bi === bodyB && c.bj === bodyA)) { return true; } } return false; } // Add collision cube to the local player. world.Add("cube", 0.2, "playerCollisonBox"); var collisionBox = new CANNON.Body({ mass: 7, linearDamping: 0.01, position: new CANNON.Vec3(0, 4, 0), shape: new CANNON.Box(new CANNON.Vec3(1, 1, 2)) }); // This is custom param added. collisionBox._name = 'collisionBox'; physics.world.addBody(collisionBox); App.scene.playerCollisonBox.physics.currentBody = collisionBox; App.scene.playerCollisonBox.physics.enabled = true; App.scene.playerCollisonBox.physics.currentBody.fixedRotation = true; App.scene.playerCollisonBox.geometry.setScale(0.02); App.scene.playerCollisonBox.glBlend.blendEnabled = true; App.scene.playerCollisonBox.glBlend.blendParamSrc = ENUMERATORS.glBlend.param[0]; App.scene.playerCollisonBox.glBlend.blendParamDest = ENUMERATORS.glBlend.param[0]; App.scene.playerCollisonBox.visible = false; // Test custom flag for collide moment App.scene.playerCollisonBox.iamInCollideRegime = false; // simple logic but also not perfect App.scene.playerCollisonBox.pingpong = true; collisionBox.addEventListener("collide", function(e) { // const contactNormal = new CANNON.Vec3(); // var relativeVelocity = e.contact.getImpactVelocityAlongNormal(); // console.log("playerCollisonBox collide with", e); preventDoubleJump = null; if(e.contact.bj._name == 'floor' || e.contact.bi._name == 'floor') { preventDoubleJump = null; return; } if(e.contact.bi._name == 'damage') { console.log("Trigger damage!"); //. 4x fix App.scene.player.energy.value -= (0.25 - (App.scene.player.items.armor ? App.scene.player.items.armor.preventDamage : 0)); App.scene.player.updateEnergy(App.scene.player.energy.value); } if(e.contact.bj._name == 'item-armor' || e.contact.bi._name == 'item-armor') { console.log("Trigger armor:", e.contact); // Make some enery restore App.scene.player.energy.value += 0.25; App.scene.player.updateEnergy(App.scene.player.energy.value); App.scene.player.items.armor = { preventDamage: 0.15 } if(App.scene['armor']) { App.scene['armor'].physics.enabled = false; App.scene['armor'].isHUD = true; App.scene.armor.position.setPosition(1.2, 1.1, -3); App.scene.armor.mesh.setScale(0.1) // Can be destroyed also App.scene['armor'].selfDestroy(1) } if(e.body._name == 'item-armor') { console.log("Trigger armor collect!"); physics.world.removeBody(e.body); } } }); // Mobile support if(isMobile() == true) { byId('mobSpace').addEventListener('touchstart', (e) => { // Jump if(preventDoubleJump == null) { preventDoubleJump = setTimeout(() => { App.scene.playerCollisonBox.physics.currentBody.mass = 1; App.scene.playerCollisonBox.physics.currentBody.velocity.set(0, 0, 25); // preventDoubleJump = null; for ever }, 250); } }) } else { // Matrix-engine key event DESKTOP addEventListener('hit.keyDown', (e) => { // Jump if(e.detail.keyCode == 32) { if(preventDoubleJump == null) { preventDoubleJump = setTimeout(() => { console.log('JUMP: ', e.detail.keyCode); App.scene.playerCollisonBox.physics.currentBody.mass = 1; App.scene.playerCollisonBox.physics.currentBody.velocity.set(0, 0, 25); // preventDoubleJump = null; for ever }, 250); } } }) } var handlerTimeout = null, handlerTimeout2 = null; var playerUpdater = { sendRotEvery: 5, sendRotValue: 0, UPDATE: () => { var detPitch; var limit = 2; if(matrixEngine.Events.camera.pitch < limit && matrixEngine.Events.camera.pitch > -limit) { detPitch = matrixEngine.Events.camera.pitch * 2; } else if(matrixEngine.Events.camera.pitch > limit) { detPitch = limit * 2; } else if(matrixEngine.Events.camera.pitch < -(limit + 2)) { detPitch = -(limit + 2) * 2; } handlerTimeout = null; // Make more stable situation App.scene.playerCollisonBox.physics.currentBody.mass = 10; App.scene.playerCollisonBox.physics.currentBody.quaternion.setFromEuler(0, 0, 0); // Cannonjs object set Switched Z - Y if(App.scene.playerCollisonBox.pingpong == true) { matrixEngine.Events.camera.xPos = App.scene.playerCollisonBox.physics.currentBody.position.x; matrixEngine.Events.camera.zPos = App.scene.playerCollisonBox.physics.currentBody.position.y; matrixEngine.Events.camera.yPos = App.scene.playerCollisonBox.physics.currentBody.position.z; App.scene.playerCollisonBox.pingpong = false; } else { handlerTimeout2 = 0; App.scene.playerCollisonBox. physics.currentBody.position.set( matrixEngine.Events.camera.xPos, matrixEngine.Events.camera.zPos, matrixEngine.Events.camera.yPos); App.scene.playerCollisonBox.pingpong = true; } // Player Look if(playerUpdater.sendRotValue > playerUpdater.sendRotEvery && matrixEngine.Engine.net.connection != null) { if(typeof App.scene.playerCollisonBox.position.netObjId === undefined) {return;} matrixEngine.Engine.net.connection.send({ netRot: {y: matrixEngine.Events.camera.yaw + 180}, netObjId: App.scene.playerCollisonBox.position.netObjId, }) playerUpdater.sendRotValue = 0; } playerUpdater.sendRotValue++; } }; App.updateBeforeDraw.push(playerUpdater); // Player Energy status App.scene.player.energy = {}; // Collector for items App.scene.player.items = {}; for(let key in App.scene.player.meshList) { App.scene.player.meshList[key].setScale(1.85); } // Target scene object var texTarget = { source: [ "res/bvh-skeletal-base/swat-guy/target.png", "res/bvh-skeletal-base/swat-guy/target.png" ], mix_operation: "multiply", }; world.Add("squareTex", 0.25, 'FPSTarget', texTarget); App.scene.FPSTarget.position.setPosition(0, 0, -4); App.scene.FPSTarget.glBlend.blendEnabled = true; App.scene.FPSTarget.glBlend.blendParamSrc = matrixEngine.utility.ENUMERATORS.glBlend.param[4]; App.scene.FPSTarget.glBlend.blendParamDest = matrixEngine.utility.ENUMERATORS.glBlend.param[4]; App.scene.FPSTarget.isHUD = true; App.scene.FPSTarget.geometry.setScale(0.1); // Energy active bar - Custom generic textures. Micro Drawing. // Example for arg shema square for now only. var options = { squareShema: [8, 8], pixels: new Uint8Array(8 * 8 * 4) }; // options.pixels.fill(0); App.scene.player.energy.value = 8; App.scene.player.updateEnergy = function(v) { this.energy.value = v; var t = App.scene.energyBar.preparePixelsTex(App.scene.energyBar.specialValue); App.scene.energyBar.textures.pop() App.scene.energyBar.textures.push(App.scene.energyBar.createPixelsTex(t)); if(this.energy.value <= 0) { notify.error("YOU DIE...") } }; function preparePixelsTex(options) { var I = 0, R = 0, G = 0, B = 0, localCounter = 0; for(var funny = 0;funny < 8 * 8 * 4;funny += 4) { if(localCounter > 7) { localCounter = 0; } if(localCounter < App.scene.player.energy.value) { I = 128; if(App.scene.player.energy.value < 3) { R = 255; G = 0; B = 0; I = 0; } else if(App.scene.player.energy.value > 2 && App.scene.player.energy.value < 5) { R = 255; G = 255; B = 0; } else { R = 0; G = 255; B = 0; } } else { I = 0; R = 0; G = 0; B = 0; } options.pixels[funny] = R; options.pixels[funny + 1] = G; options.pixels[funny + 2] = B; options.pixels[funny + 3] = 0; localCounter++; } return options; } var tex2 = { source: ["res/images/hud/energy-bar.png", "res/images/hud/energy-bar.png"], mix_operation: "multiply", }; world.Add("squareTex", 1, 'energyBar', tex2); App.scene.energyBar.glBlend.blendEnabled = true; App.scene.energyBar.glBlend.blendParamSrc = matrixEngine.utility.ENUMERATORS.glBlend.param[5]; App.scene.energyBar.glBlend.blendParamDest = matrixEngine.utility.ENUMERATORS.glBlend.param[5]; App.scene.energyBar.isHUD = true; // App.scene.energy.visible = false; App.scene.energyBar.position.setPosition(0, 1.1, -3); App.scene.energyBar.geometry.setScaleByX(1) App.scene.energyBar.geometry.setScaleByY(0.05) App.scene.energyBar.preparePixelsTex = preparePixelsTex; options = preparePixelsTex(options); App.scene.energyBar.textures.push(App.scene.energyBar.createPixelsTex(options)); App.scene.energyBar.specialValue = options; } matrixEngine.objLoader.downloadMeshes({player: "res/bvh-skeletal-base/swat-guy/gun2.obj"}, onLoadObj ); }; let promiseAllGenerated = []; const objGenerator = (n) => { var texStone = { source: [ "res/images/n-stone.png", ], mix_operation: "multiply", }; for(var j = 0;j < n;j++) { promiseAllGenerated.push(new Promise((resolve) => { setTimeout(() => { world.Add("cubeLightTex", 1, "CUBE" + j, texStone); var b2 = new CANNON.Body({ mass: 0.1, linearDamping: 0.01, position: new CANNON.Vec3(1, -14.5, 15), shape: new CANNON.Box(new CANNON.Vec3(1, 1, 1)) }); physics.world.addBody(b2); App.scene['CUBE' + j].physics.currentBody = b2; App.scene['CUBE' + j].physics.enabled = true; resolve(); }, 1000 * j); })); } } // objGenerator(2); createObjSequence('player'); // Promise.all(promiseAllGenerated).then((what) => { // // console.info(`Waiting for runtime generation of scene objects, // // then swap scene array index for scene draw-index -> // // must be manual setup for now!`, what); // // swap(5, 19, matrixEngine.matrixWorld.world.contentList); // // console.log('promise all') // }); // Add ground for physics bodies. var tex = { source: ["res/images/complex_texture_1/diffuse.webp"], mix_operation: "multiply", params: { TEXTURE_MAG_FILTER: world.GL.gl.NEAREST, TEXTURE_MIN_FILTER: world.GL.gl.LINEAR_MIPMAP_NEAREST } }; var texNoMipmap = { source: [ "res/images/RustPaint.jpg", ], mix_operation: "multiply", params: { TEXTURE_MAG_FILTER: world.GL.gl.NEAREST, TEXTURE_MIN_FILTER: world.GL.gl.NEAREST } }; // Load Physics world. let gravityVector = [0, 0, -29.82]; let physics = world.loadPhysics(gravityVector); // Add ground - mass == 0 makes the body static var groundBody = new CANNON.Body({ mass: 0, position: new CANNON.Vec3(0, -15, -2) }); var groundShape = new CANNON.Plane(); groundBody.addShape(groundShape); groundBody._name = 'floor'; physics.world.addBody(groundBody); // Matrix engine visual scene object world.Add("squareTex", 1, "FLOOR_STATIC", tex); App.scene.FLOOR_STATIC.geometry.setScaleByX(200); App.scene.FLOOR_STATIC.geometry.setScaleByY(200); App.scene.FLOOR_STATIC.position.SetY(-2); App.scene.FLOOR_STATIC.position.SetZ(-15); App.scene.FLOOR_STATIC.rotation.rotx = 90; App.scene.FLOOR_STATIC.geometry.setTexCoordScaleFactor(20); // Target x-ray AIM // See through the objects. // In webGL context it is object how was drawn before others. var texTarget = { source: [ "res/bvh-skeletal-base/swat-guy/target-night.png" ], mix_operation: "multiply", }; world.Add("squareTex", 0.18, 'xrayTarget', texTarget); App.scene.xrayTarget.glBlend.blendEnabled = true; App.scene.xrayTarget.glBlend.blendParamSrc = matrixEngine.utility.ENUMERATORS.glBlend.param[5]; App.scene.xrayTarget.glBlend.blendParamDest = matrixEngine.utility.ENUMERATORS.glBlend.param[5]; App.scene.xrayTarget.isHUD = true; App.scene.xrayTarget.visible = false; App.scene.xrayTarget.position.setPosition(-0.3, 0.27, -4); // Energy var tex1 = { source: ["res/images/hud/energy.png"], mix_operation: "multiply", }; world.Add("squareTex", 0.5, 'energy', tex1); App.scene.energy.glBlend.blendEnabled = true; App.scene.energy.glBlend.blendParamSrc = matrixEngine.utility.ENUMERATORS.glBlend.param[5]; App.scene.energy.glBlend.blendParamDest = matrixEngine.utility.ENUMERATORS.glBlend.param[5]; App.scene.energy.isHUD = true; // App.scene.energy.visible = false; App.scene.energy.position.setPosition(-1, 1.15, -3); App.scene.energy.geometry.setScaleByX(0.35) App.scene.energy.geometry.setScaleByY(0.1) // good for fix rotation in future world.Add("cubeLightTex", 2, "FLOOR2", tex); var b2 = new CANNON.Body({ mass: 0, linearDamping: 0.01, position: new CANNON.Vec3(0, -14.5, -2), shape: new CANNON.Box(new CANNON.Vec3(2, 2, 2)) }); physics.world.addBody(b2); App.scene['FLOOR2'].position.setPosition(0, -2, -14.5) // App.scene['FLOOR2'].geometry.setScaleByX(3); App.scene['FLOOR2'].physics.currentBody = b2; App.scene['FLOOR2'].physics.enabled = true; App.scene.FLOOR2.LightsData.ambientLight.set(0,0,0) world.Add("cubeLightTex", 2, "FLOOR3", tex); var b3 = new CANNON.Body({ mass: 0, linearDamping: 0.01, position: new CANNON.Vec3(0, -19, 0), shape: new CANNON.Box(new CANNON.Vec3(3, 3, 3)) }); physics.world.addBody(b3); App.scene['FLOOR3'].position.setPosition(0, 0, -19) App.scene['FLOOR3'].physics.currentBody = b3; App.scene['FLOOR3'].physics.enabled = true; // Big wall world.Add("cubeLightTex", 5, "WALL_BLOCK", tex); var b5 = new CANNON.Body({ mass: 0, linearDamping: 0.01, position: new CANNON.Vec3(10, -19, 0), shape: new CANNON.Box(new CANNON.Vec3(5, 5, 5)) }); physics.world.addBody(b5); App.scene['WALL_BLOCK'].position.setPosition(10, 0, -19) App.scene['WALL_BLOCK'].physics.currentBody = b5; App.scene['WALL_BLOCK'].physics.enabled = true; // Big wall CUSTOM SHADERS world.Add("sphereLightTex", 1, "WALL_BLOCK2", texNoMipmap); var b6 = new CANNON.Body({ mass: 0, linearDamping: 0.01, position: new CANNON.Vec3(30, -10, 0), shape: new CANNON.Sphere(1) // new CANNON.Box(new CANNON.Vec3(5, 5, 5)) }); physics.world.addBody(b6); App.scene['WALL_BLOCK2'].position.setPosition(30, -10, 19) App.scene['WALL_BLOCK2'].physics.currentBody = b6; App.scene['WALL_BLOCK2'].physics.enabled = true; // Networking addEventListener(`LOCAL-STREAM-READY`, (e) => { // console.log('LOCAL-STREAM-READY [app level] ', e.detail.streamManager.id) console.log(`%cLOCAL-STREAM-READY [app level] ${e.detail.connection.connectionId}`, REDLOG) // test first dispatchEvent(new CustomEvent(`onTitle`, {detail: `🕸️${e.detail.connection.connectionId}🕸️`})) notify.show(`Connected 🕸️${e.detail.connection.connectionId}🕸️`) var name = e.detail.connection.connectionId; // byId('netHeaderTitle').click() console.log('LOCAL-STREAM-READY [SETUP FAKE UNIQNAME POSITION] ', e.detail.connection.connectionId); // Make relation for net players App.scene.playerCollisonBox.position.netObjId = e.detail.connection.connectionId; App.scene.playerCollisonBox.position.yNetOffset = -2; App.scene.playerCollisonBox.net.enable = true; // CAMERA VIEW FOR SELF LOCAL CAM // world.Add("squareTex", 1, name, tex); // App.scene[name].position.x = 0; // App.scene[name].position.z = -20; // App.scene[name].LightsData.ambientLight.set(1, 0, 0); // App.scene[name].net.enable = true; // App.scene[name].streamTextures = matrixEngine.Engine.DOM_VT(byId(e.detail.streamManager.id)) }) var ONE_TIME = 0; addEventListener('streamPlaying', (e) => { if(ONE_TIME == 0) { ONE_TIME = 1; // console.log('REMOTE-STREAM- streamPlaying [app level] ', e.detail.target.videos[0]); // DIRECT REMOTE var name = e.detail.target.stream.connection.connectionId; // createNetworkPlayerCharacter(name) // App.scene[name].net.active = true; // matrixEngine.Engine.net.multiPlayer.init // App.scene[name].streamTextures = matrixEngine.Engine.DOM_VT(e.detail.target.videos[0].video) } }) addEventListener('onStreamCreated', (e) => { if(matrixEngine.Engine.net.connection == null) { // local console.log('MY CONNECTION IS NULL') setTimeout(() => { // test if(typeof matrixEngine.Engine.net.connection === 'undefined') return; if(e.detail.event.stream.connection.connectionId != matrixEngine.Engine.net.connection.connectionId) { console.log('++ 2 sec++++++REMOTE-STREAM-READY [app level] ', e.detail.event.stream.connection.connectionId); var name = e.detail.event.stream.connection.connectionId; createNetworkPlayerCharacter(name) } }, 2500) return; } if(e.detail.event.stream.connection.connectionId != matrixEngine.Engine.net.connection.connectionId) { console.log('REMOTE-STREAM-READY [app level] ', e.detail.event.stream.connection.connectionId); var name = e.detail.event.stream.connection.connectionId; createNetworkPlayerCharacter(name) } }) addEventListener('net-ready', (e) => { // Star on load if (byId('buttonCloseSession')) byId('buttonCloseSession').remove(); matrixEngine.Engine.net.joinSessionUI.click() createPauseScreen() // Next implementation RocketCrafringServer calls. let profile = document.createElement('div') profile.id = 'profile'; profile.innerHTML = ` Status: free for all `; byId('session').appendChild(profile) let leaderboardBtn = document.createElement('div') leaderboardBtn.id = 'Leaderboard'; leaderboardBtn.innerHTML = ` <button id="leaderboardBtn" class="btn">Leaderboard</button> `; byId('session').appendChild(leaderboardBtn) if(useRCSAccount == true) { let myAccounts = new RCSAccount(RCSAccountDomain); myAccounts.createDOM(); notify.show("You can reg/login on GamePlay ROCK platform. Welcome my friends.") console.log(`%c<RocketCraftingServer [Account]> ${myAccounts}`, REDLOG); } }) addEventListener('connectionDestroyed', (e) => { console.log(`%c connectionDestroyed ${e.detail}`, REDLOG); if(App.scene[e.detail.connectionId] !== 'undefined' && typeof e.detail.connectionId !== 'undefined') { try { App.scene[e.detail.connectionId].selfDestroy(1) } catch(err) { console.log('Old session user...') } } }) // Graphics - Damage object test world.Add("cubeLightTex", 1, "LAVA", tex); var b4 = new CANNON.Body({ mass: 0, linearDamping: 0.01, position: new CANNON.Vec3(-6, -16.5, -1), shape: new CANNON.Box(new CANNON.Vec3(1, 1, 1)) }); b4._name = 'damage'; physics.world.addBody(b4); App.scene.LAVA.position.setPosition(-6, -1, -16.5) // App.scene.LAVA.geometry.setScaleByX(1); App.scene.LAVA.physics.currentBody = b4; App.scene.LAVA.physics.enabled = true; App.scene.LAVA.LightsData.ambientLight.set(0, 0, 0); App.scene.LAVA.streamTextures = new matrixEngine.Engine.VT( "res/video-texture/lava1.mkv" ); // How to load obj and give him gameplay item props loadObj({ name: "armor", path: "res/3d-objects/armor.obj", position: [-10, 0, -10], activeRotation: [0, 20, 0], rotation: [0, 0, 0], scale: 2.1, textures: ["res/images/armor.webp"], shadows: false, gamePlayItem: 'item-armor' }) loadObj({ name: "munition", path: "res/3d-objects/env/ammo.obj", position: [-10, 0, -20], activeRotation: [0, 20, 0], rotation: [0, 0, 0], scale: 1.1, textures: ["res/images/complex_texture_1/normalmap.webp"], shadows: false, gamePlayItem: 'item-munition' }) // Handler for obj function loadObj(n) { function onLoadObj(meshes) { var tex = {source: n.textures, mix_operation: "multiply"} for(let key in meshes) { matrixEngine.objLoader.initMeshBuffers(world.GL.gl, meshes[key]) world.Add("obj", n.scale, n.name, tex, meshes[key]); } App.scene[n.name].position.x = n.position[0]; App.scene[n.name].position.y = n.position[1]; App.scene[n.name].position.z = n.position[2]; App.scene[n.name].rotation.rotationSpeed.x = n.activeRotation[0]; App.scene[n.name].rotation.rotationSpeed.y = n.activeRotation[1]; App.scene[n.name].rotation.rotationSpeed.z = n.activeRotation[2]; App.scene[n.name].rotation.rotx = n.rotation[0]; App.scene[n.name].rotation.roty = n.rotation[1]; App.scene[n.name].rotation.rotz = n.rotation[2]; // App.scene[n.name].LightsData.ambientLight.set(1, 1, 1); App.scene[n.name].mesh.setScale(n.scale) var b44 = new CANNON.Body({ mass: 0.1, linearDamping: 0.01, position: new CANNON.Vec3(n.position[0], n.position[2], n.position[1]), shape: new CANNON.Box(new CANNON.Vec3(1, 1, 1)) }); b44._name = n.gamePlayItem; physics.world.addBody(b44); // App.scene.LAVA.geometry.setScaleByX(1); App.scene[n.name].physics.currentBody = b44; App.scene[n.name].physics.enabled = true; if(n.shadows == true) setTimeout(() => { App.scene[n.name].activateShadows('spot') }, 100) } var arg = {}; arg[n.name] = n.path; matrixEngine.objLoader.downloadMeshes(arg, onLoadObj) } }; const createNetworkPlayerCharacter = (objName) => { if(typeof App.scene[objName] !== 'undefined') { console.log('Prevent double net player.') return; } function onLoadObj(meshes) { App.meshes = meshes; for(let key in meshes) { matrixEngine.objLoader.initMeshBuffers(matrixEngine.matrixWorld.world.GL.gl, meshes[key]); } var textuteImageSamplers2 = { source: ["res/bvh-skeletal-base/swat-guy/textures/Ch15_1001_Diffuse.png", "res/bvh-skeletal-base/swat-guy/textures/Ch15_1001_Diffuse.png"], mix_operation: "multiply", // ENUM : multiply , divide }; setTimeout(function() { var animArg = { id: objName, meshList: meshes, // sumOfAniFrames: 61, No need if `animations` exist! currentAni: 0, // speed: 3, No need if `animations` exist! animations: { active: 'walk', walk: { from: 0, // to: 35, to: 20, speed: 3 }, walkPistol: { from: 36, to: 60, speed: 3 } } }; matrixEngine.matrixWorld.world.Add("obj", 1, objName, textuteImageSamplers2, meshes[objName], animArg ); App.scene[objName].position.y = 2; App.scene[objName].position.z = 2; // From 2.0.14 only for obj seq -> scaleAll App.scene[objName].scaleAll(2.4) }, 1); } matrixEngine.objLoader.downloadMeshes( matrixEngine.objLoader.makeObjSeqArg({ id: objName, path: "res/bvh-skeletal-base/swat-guy/seq-walk-pistol/low/swat-walk-pistol", from: 1, to: 20 }), onLoadObj ); }; export var REDLOG = "background:black;color: lime;font-size:25px;text-shadow: 1px 1px 15px red, -4px -4px 15px orangered"; // export function createPauseScreen () { // var root = document.createElement('div') // root.id = 'pauseScreen'; // // root.style = ''; // function hidePauseScreen () { // byId('pauseScreen').style.display = 'none'; // } // root.innerHTML = ` // <h2 class="pauseScreenText"> // Hang3d Matrix // <button id="pauseGame" class='btn'>PLAY</button> // <div style="font-size:15px;">Powered by matrix-engine</div> // <div style="display: grid;font-size:15px;">Source code: <a href="https://github.com/zlatnaspirala">github/zlatnaspirala</a></div> // </h2> // `; // document.body.appendChild(root) // byId('pauseGame').addEventListener('click', hidePauseScreen, {passive: true}) // } // /** // * @description Hang3d reborn // * @author Nikola Lukic // * @email zlatnaspirala@gmail.com // */ // export var ROCK_RANK = { // getRank : (points) => { // points = parseInt(points); // if (points < 1001) { // return "junior"; // } else if (points < 2000) { // return "senior"; // } else if (points < 3000) { // return "captain"; // } else if (points < 5000) { // return "general"; // } else { // return "ultimate-killer"; // } // }, // getRankMedalImg: (rank) => { // if (rank == 'junior') { // return `<img style="height: 60px" src="./res/icons/medals/1.png" />`; // } else if (points == 'senior') { // return `<img style="height: 60px" src="./res/icons/medals/2.png" />`; // } else if (points == 'captain') { // return `<img style="height: 60px" src="./res/icons/medals/3.png" />`; // } else if (points == 'general') { // return `<img style="height: 60px" src="./res/icons/medals/4.png" />`; // } else { // return `<img style="height: 60px" src="./res/icons/medals/5.png" />`; // } // } // };