├── _Rogue ├── Engine │ ├── Controller │ │ ├── OldAssetManager.d.ts │ │ ├── Input │ │ │ ├── Keyboard.d.ts │ │ │ ├── Input.d.ts │ │ │ ├── Touch.d.ts │ │ │ └── Mouse.d.ts │ │ ├── Functions.d.ts │ │ ├── Decorators.d.ts │ │ ├── RuntimeController.d.ts │ │ ├── Debug.d.ts │ │ ├── ComponentsManager.d.ts │ │ ├── Events.d.ts │ │ ├── App.d.ts │ │ └── AssetManager.d.ts │ └── Model │ │ ├── Lifecycle.d.ts │ │ ├── Prefab.d.ts │ │ ├── PropertyHandler.d.ts │ │ ├── AudioAsset.d.ts │ │ ├── Component.d.ts │ │ ├── SceneController.d.ts │ │ └── Skybox.d.ts └── rogue-engine.d.ts ├── webpack.config.user.js ├── tsconfig.json ├── tsconfig.user.json ├── Assets ├── Models │ ├── Bomb.glb │ ├── Block.glb │ ├── Block2.glb │ ├── basketball.glb │ ├── world_Bomb.glb │ └── basketball court.glb ├── Prefabs │ ├── Point.roguePrefab.meta │ ├── BombTimer.roguePrefab.meta │ ├── Point.roguePrefab │ └── BombTimer.roguePrefab ├── Textures │ ├── 3042.jpg │ ├── box.jpeg │ ├── Albedo.jpg │ ├── Metal.jpg │ ├── Normal.jpg │ ├── Rough.jpg │ ├── point.png │ ├── noCameraConnected.jpg │ ├── 3042.jpg.meta │ ├── box.jpeg.meta │ ├── Albedo.jpg.meta │ ├── Metal.jpg.meta │ ├── Normal.jpg.meta │ ├── Rough.jpg.meta │ ├── point.png.meta │ └── noCameraConnected.jpg.meta ├── rogue_packages │ └── rogue-cannon │ │ ├── Prefabs │ │ └── CannonRaycastVehicle.roguePrefab.meta │ │ ├── Lib │ │ └── RogueCannon.ts │ │ ├── Components │ │ ├── Shapes │ │ │ ├── CannonSphere.re.ts │ │ │ ├── CannonBox.re.ts │ │ │ ├── CannonCylinder.re.ts │ │ │ ├── CannonTrimesh.re.ts │ │ │ └── CannonShape.ts │ │ ├── Constraints │ │ │ ├── CannonConstraint.ts │ │ │ ├── CannonLockConstraint.re.ts │ │ │ ├── CannonDistanceConstraint.re.ts │ │ │ ├── CannonPointToPointConstraint.re.ts │ │ │ └── CannonHingeConstraint.re.ts │ │ ├── Material │ │ │ ├── SetCannonMaterial.re.ts │ │ │ ├── CannonMaterial.re.ts │ │ │ └── CannonContactMaterial.re.ts │ │ ├── CannonConfig.re.ts │ │ ├── Objects │ │ │ ├── CannonRaycastVehicle.re.ts │ │ │ ├── CannonSpring.re.ts │ │ │ └── CannonWheel.re.ts │ │ ├── Controllers │ │ │ ├── CannonSimpleCharacterController.re.ts │ │ │ └── CannonVehicleController.re.ts │ │ ├── CannonBody.re.ts │ │ └── _Editor │ │ │ └── CannonBodyWireframe.ts │ │ └── Scenes │ │ ├── CharacterExample.rogueScene │ │ └── CannonExample.rogueScene ├── Components │ ├── FixColdStart.re.ts │ ├── UiManager.re.ts │ ├── CameraController.re.ts │ ├── SceneManager.re.ts │ ├── WebcamTexture.re.ts │ ├── BombTimer.re.ts │ ├── WebcamController.re.ts │ ├── Bomb.re.ts │ ├── Explodable.re.ts │ ├── BasketballController.re.ts │ ├── Static │ │ └── DeviceUtils.ts │ └── ProjectileObject.re.ts └── Materials │ ├── timerBar_mat_sm.rogueMaterial │ ├── timerProgress_mat_sm.rogueMaterial │ ├── point_mat_sp.rogueMaterial │ ├── background_mat_mbm.rogueMaterial │ ├── blackTV_mat_msm.rogueMaterial │ ├── white_mat_msm.rogueMaterial │ ├── box_mat_msm.rogueMaterial │ ├── videoBlock_mat_msm.rogueMaterial │ ├── fuze_mat_msm.rogueMaterial │ └── metal_mat_msm.rogueMaterial ├── .gitignore ├── webpack.config.js ├── rogue-config.json ├── package.json ├── README.md ├── tsconfig.rogue.json ├── Static └── ui.html ├── index.html ├── webpack.config.rogue.js └── file-server.js /_Rogue/Engine/Controller/OldAssetManager.d.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /webpack.config.user.js: -------------------------------------------------------------------------------- 1 | module.exports = {} 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.user.json" 3 | } 4 | -------------------------------------------------------------------------------- /tsconfig.user.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.rogue.json", 3 | } 4 | -------------------------------------------------------------------------------- /Assets/Models/Bomb.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Models/Bomb.glb -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | build/ 4 | dist/* 5 | BUILD/ 6 | rogue_builds/ 7 | raw/git -------------------------------------------------------------------------------- /Assets/Models/Block.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Models/Block.glb -------------------------------------------------------------------------------- /Assets/Models/Block2.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Models/Block2.glb -------------------------------------------------------------------------------- /Assets/Prefabs/Point.roguePrefab.meta: -------------------------------------------------------------------------------- 1 | {"uuid":"9252DBAA-A39F-4EA7-AE06-F35B29707138","type":"Prefab"} -------------------------------------------------------------------------------- /Assets/Textures/3042.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Textures/3042.jpg -------------------------------------------------------------------------------- /Assets/Textures/box.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Textures/box.jpeg -------------------------------------------------------------------------------- /Assets/Prefabs/BombTimer.roguePrefab.meta: -------------------------------------------------------------------------------- 1 | {"uuid":"F444618A-066C-4BFD-ADBC-82DFEF229C09","type":"Prefab"} -------------------------------------------------------------------------------- /Assets/Textures/Albedo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Textures/Albedo.jpg -------------------------------------------------------------------------------- /Assets/Textures/Metal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Textures/Metal.jpg -------------------------------------------------------------------------------- /Assets/Textures/Normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Textures/Normal.jpg -------------------------------------------------------------------------------- /Assets/Textures/Rough.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Textures/Rough.jpg -------------------------------------------------------------------------------- /Assets/Textures/point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Textures/point.png -------------------------------------------------------------------------------- /Assets/Models/basketball.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Models/basketball.glb -------------------------------------------------------------------------------- /Assets/Models/world_Bomb.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Models/world_Bomb.glb -------------------------------------------------------------------------------- /Assets/Models/basketball court.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Models/basketball court.glb -------------------------------------------------------------------------------- /Assets/Textures/noCameraConnected.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdkt/Angry-Bomb/HEAD/Assets/Textures/noCameraConnected.jpg -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Prefabs/CannonRaycastVehicle.roguePrefab.meta: -------------------------------------------------------------------------------- 1 | {"uuid":"12BD2422-0E4B-4B35-955D-9C9C753FCF13","type":"Prefab"} -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const rogueConfig = require('./webpack.config.rogue'); 3 | const userConfig = require('./webpack.config.user'); 4 | 5 | module.exports = merge(rogueConfig, userConfig); 6 | -------------------------------------------------------------------------------- /rogue-config.json: -------------------------------------------------------------------------------- 1 | {"title":"Project","scenes":[{"name":"AngryBomb","uuid":"a2793bba-fec4-42c6-a5ae-abb45fa76035"},{"name":"VideoBlocks","uuid":"fabf81d6-3784-4933-85f3-0641f365e01b"},{"name":"Basket","uuid":"5be947ac-95fa-4fc1-b9ac-511edecc82d1"}],"projectVersion":12,"useHttps":true} 2 | -------------------------------------------------------------------------------- /_Rogue/Engine/Model/Lifecycle.d.ts: -------------------------------------------------------------------------------- 1 | export default abstract class Lifecycle { 2 | protected abstract awake(): void; 3 | protected abstract start(): void; 4 | protected abstract beforeUpdate(): void; 5 | protected abstract update(): void; 6 | protected abstract afterUpdate(): void; 7 | } 8 | -------------------------------------------------------------------------------- /_Rogue/Engine/Model/Prefab.d.ts: -------------------------------------------------------------------------------- 1 | import { Object3D } from 'three'; 2 | export declare class Prefab { 3 | private _uuid; 4 | constructor(uuid: any); 5 | get uuid(): string; 6 | get path(): string; 7 | get name(): string; 8 | instantiate(parent?: Object3D): Object3D; 9 | } 10 | -------------------------------------------------------------------------------- /_Rogue/Engine/Controller/Input/Keyboard.d.ts: -------------------------------------------------------------------------------- 1 | export declare class Keyboard { 2 | private _upKeys; 3 | private _downKeys; 4 | private _pressedKeys; 5 | init(): void; 6 | getKeyDown(keyCode: string): boolean; 7 | getKeyPressed(keyCode: string): boolean; 8 | getKeyUp(keyCode: string): boolean; 9 | } 10 | -------------------------------------------------------------------------------- /_Rogue/Engine/Controller/Functions.d.ts: -------------------------------------------------------------------------------- 1 | import { Object3D } from 'three'; 2 | export declare function isDev(): boolean; 3 | export declare function getStaticPath(path: string): string; 4 | export declare function loadComponentsRecursive(object: Object3D): void; 5 | export declare function loadAudioListeners(object: Object3D): void; 6 | export declare function dispose(object: Object3D): void; 7 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Lib/RogueCannon.ts: -------------------------------------------------------------------------------- 1 | import * as CANNON from 'cannon-es'; 2 | 3 | export type CollisionEvent = {body: CANNON.Body, target: CANNON.Body, contact: CANNON.ContactEquation}; 4 | 5 | let world: CANNON.World = new CANNON.World(); 6 | 7 | export function getWorld() { 8 | return world; 9 | } 10 | 11 | export function setWorld(newWorld: CANNON.World) { 12 | world = newWorld; 13 | } 14 | -------------------------------------------------------------------------------- /_Rogue/Engine/Controller/Decorators.d.ts: -------------------------------------------------------------------------------- 1 | declare type propType = 'String' | 'Number' | 'Boolean' | 'Select' | 'Vector2' | 'Vector3' | 'Object3D' | 'Prefab' | 'Texture' | 'Material' | 'Component' | 'Audio' | 'PositionalAudio' | 'Color'; 2 | export declare function Prop(type: propType): (target: Object, propertyKey: string) => void; 3 | export declare function PropList(type: propType): (target: Object, propertyKey: string) => void; 4 | export {}; 5 | -------------------------------------------------------------------------------- /_Rogue/Engine/Controller/Input/Input.d.ts: -------------------------------------------------------------------------------- 1 | import { Mouse } from './Mouse'; 2 | import { Keyboard } from './Keyboard'; 3 | import { TouchController } from './Touch'; 4 | export declare abstract class Input { 5 | private static _mouse; 6 | private static _keyboard; 7 | private static _touch; 8 | static get mouse(): Mouse; 9 | static get keyboard(): Keyboard; 10 | static get touch(): TouchController; 11 | } 12 | -------------------------------------------------------------------------------- /Assets/Textures/3042.jpg.meta: -------------------------------------------------------------------------------- 1 | {"uuid":"7C7DE5E1-F851-48CC-9C36-90F33A98AE46","type":"Texture","object":{"metadata":{"version":4.5,"type":"Texture","generator":"Texture.toJSON"},"uuid":"7C7DE5E1-F851-48CC-9C36-90F33A98AE46","name":"3042.jpg","mapping":300,"repeat":[1,1],"offset":[0,0],"center":[0,0],"rotation":0,"wrap":[1001,1001],"format":1023,"type":1009,"encoding":3000,"minFilter":1006,"magFilter":1006,"anisotropy":1,"flipY":true,"premultiplyAlpha":false,"unpackAlignment":4,"image":"AF3D3A01-C7F4-4040-81A1-4D7AB7201005"}} -------------------------------------------------------------------------------- /Assets/Textures/box.jpeg.meta: -------------------------------------------------------------------------------- 1 | {"uuid":"3361F96B-7A28-4805-9E1F-A35B44C3EA58","type":"Texture","object":{"metadata":{"version":4.5,"type":"Texture","generator":"Texture.toJSON"},"uuid":"3361F96B-7A28-4805-9E1F-A35B44C3EA58","name":"box.jpeg","mapping":300,"repeat":[1,1],"offset":[0,0],"center":[0,0],"rotation":0,"wrap":[1001,1001],"format":1023,"type":1009,"encoding":3000,"minFilter":1006,"magFilter":1006,"anisotropy":1,"flipY":true,"premultiplyAlpha":false,"unpackAlignment":4,"image":"828DE83B-3B91-4313-BB81-D6889C34B5C8"}} -------------------------------------------------------------------------------- /Assets/Textures/Albedo.jpg.meta: -------------------------------------------------------------------------------- 1 | {"uuid":"77E0C83C-AE44-4504-AC09-C7DD8AD49945","type":"Texture","object":{"metadata":{"version":4.5,"type":"Texture","generator":"Texture.toJSON"},"uuid":"77E0C83C-AE44-4504-AC09-C7DD8AD49945","name":"Albedo.jpg","mapping":300,"repeat":[1,1],"offset":[0,0],"center":[0,0],"rotation":0,"wrap":[1000,1000],"format":1023,"type":1009,"encoding":3000,"minFilter":1006,"magFilter":1006,"anisotropy":1,"flipY":false,"premultiplyAlpha":false,"unpackAlignment":4,"image":"4D97AC44-E3FF-4D67-AFBC-7B2072C598F6"}} -------------------------------------------------------------------------------- /Assets/Textures/Metal.jpg.meta: -------------------------------------------------------------------------------- 1 | {"uuid":"D4AC8378-96A4-4C4D-AC4A-E10AFD744F78","type":"Texture","object":{"metadata":{"version":4.5,"type":"Texture","generator":"Texture.toJSON"},"uuid":"D4AC8378-96A4-4C4D-AC4A-E10AFD744F78","name":"Metal.jpg","mapping":300,"repeat":[1,1],"offset":[0,0],"center":[0,0],"rotation":0,"wrap":[1000,1000],"format":1023,"type":1009,"encoding":3000,"minFilter":1006,"magFilter":1006,"anisotropy":1,"flipY":true,"premultiplyAlpha":false,"unpackAlignment":4,"image":"881AFE0C-78FD-4C90-A5C7-44A5A6416AA5"}} -------------------------------------------------------------------------------- /Assets/Textures/Normal.jpg.meta: -------------------------------------------------------------------------------- 1 | {"uuid":"56AD550F-D2AE-4843-B7D6-7B43705EEAA9","type":"Texture","object":{"metadata":{"version":4.5,"type":"Texture","generator":"Texture.toJSON"},"uuid":"56AD550F-D2AE-4843-B7D6-7B43705EEAA9","name":"Normal.jpg","mapping":300,"repeat":[1,1],"offset":[0,0],"center":[0,0],"rotation":0,"wrap":[1000,1000],"format":1023,"type":1009,"encoding":3000,"minFilter":1006,"magFilter":1006,"anisotropy":1,"flipY":false,"premultiplyAlpha":false,"unpackAlignment":4,"image":"1AF00F1B-0C27-49DC-AC00-8FBBC689E37D"}} -------------------------------------------------------------------------------- /Assets/Textures/Rough.jpg.meta: -------------------------------------------------------------------------------- 1 | {"uuid":"AFAAE389-483A-4096-B964-9D43B209E58F","type":"Texture","object":{"metadata":{"version":4.5,"type":"Texture","generator":"Texture.toJSON"},"uuid":"AFAAE389-483A-4096-B964-9D43B209E58F","name":"Rough.jpg","mapping":300,"repeat":[1,1],"offset":[0,0],"center":[0,0],"rotation":0,"wrap":[1000,1000],"format":1023,"type":1009,"encoding":3000,"minFilter":1006,"magFilter":1006,"anisotropy":1,"flipY":true,"premultiplyAlpha":false,"unpackAlignment":4,"image":"BF543837-8BC1-4C6C-85F6-20F21D04AA8C"}} -------------------------------------------------------------------------------- /Assets/Textures/point.png.meta: -------------------------------------------------------------------------------- 1 | {"uuid":"E165F1A4-B7E2-40E4-9263-C011FE25279C","type":"Texture","object":{"metadata":{"version":4.5,"type":"Texture","generator":"Texture.toJSON"},"uuid":"E165F1A4-B7E2-40E4-9263-C011FE25279C","name":"point.png","mapping":300,"repeat":[1,1],"offset":[0,0],"center":[0,0],"rotation":0,"wrap":[1000,1000],"format":1023,"type":1009,"encoding":3000,"minFilter":1006,"magFilter":1006,"anisotropy":1,"flipY":true,"premultiplyAlpha":false,"unpackAlignment":4,"image":"A6055B3E-1F7D-4285-9ED7-2A49645790A5"}} -------------------------------------------------------------------------------- /Assets/Textures/noCameraConnected.jpg.meta: -------------------------------------------------------------------------------- 1 | {"uuid":"02716EE0-105D-4407-A99F-E758964EA9F1","type":"Texture","object":{"metadata":{"version":4.5,"type":"Texture","generator":"Texture.toJSON"},"uuid":"02716EE0-105D-4407-A99F-E758964EA9F1","name":"noCameraConnected.jpg","mapping":300,"repeat":[1,1],"offset":[0,0],"center":[0,0],"rotation":0,"wrap":[1000,1000],"format":1023,"type":1009,"encoding":3000,"minFilter":1006,"magFilter":1006,"anisotropy":1,"flipY":true,"premultiplyAlpha":false,"unpackAlignment":4,"image":"EFE7392B-1659-4684-BC92-B2874BD2466A"}} -------------------------------------------------------------------------------- /_Rogue/Engine/Model/PropertyHandler.d.ts: -------------------------------------------------------------------------------- 1 | export interface IPropertyHandler { 2 | component: string; 3 | options?: Object; 4 | } 5 | export interface ITextFieldHandler extends IPropertyHandler { 6 | coomponent: "TextField"; 7 | options: ITextFieldOptions; 8 | } 9 | interface ITextFieldOptions { 10 | } 11 | export interface IRangeHandler extends IPropertyHandler { 12 | coomponent: "Range"; 13 | options: IRangedOptions; 14 | } 15 | interface IRangedOptions { 16 | min: number; 17 | max: number; 18 | } 19 | export {}; 20 | -------------------------------------------------------------------------------- /_Rogue/Engine/Model/AudioAsset.d.ts: -------------------------------------------------------------------------------- 1 | import { Audio, PositionalAudio } from "three"; 2 | export declare class AudioAsset { 3 | private _uuid; 4 | private _buffer; 5 | userData: { 6 | __ASSET__: string; 7 | }; 8 | constructor(params: { 9 | uuid: string; 10 | buffer?: AudioBuffer; 11 | }); 12 | get uuid(): string; 13 | get path(): string; 14 | get name(): string; 15 | getAudio(): Audio; 16 | getPositionalAudio(): PositionalAudio; 17 | static fromFile(filePath: string, onProgress?: () => void, onError?: () => void): Promise; 18 | } 19 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Shapes/CannonSphere.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as THREE from 'three'; 3 | import * as CANNON from 'cannon-es'; 4 | import CannonShape from './CannonShape'; 5 | 6 | export default class CannonSphere extends CannonShape { 7 | @RE.Prop("Number") radiusOffset: number = 1; 8 | shape: CANNON.Sphere; 9 | bbox: THREE.Box3; 10 | 11 | protected createShape() { 12 | const scale = this.object3d.scale; 13 | const maxSide = Math.max(scale.x, scale.y, scale.z); 14 | 15 | this.shape = new CANNON.Sphere( 16 | this.radiusOffset * (maxSide) 17 | ); 18 | } 19 | } 20 | 21 | RE.registerComponent(CannonSphere); 22 | -------------------------------------------------------------------------------- /Assets/Components/FixColdStart.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | 3 | export default class FixColdStart extends RE.Component { 4 | 5 | /* 6 | Sometimes, especially in Firefox, if RogueCannon starts before the scene (or viceversa, I'm not really sure) 7 | the CannonBodies won't initialize correctly and the objects won't be displayed on the screen. 8 | I don't like to use a timeout but I haven't figured out the event to wait for to initialize everything. 9 | */ 10 | 11 | awake() { 12 | RE.Runtime.pause(); 13 | } 14 | 15 | start() { 16 | setTimeout(() => { 17 | RE.Runtime.play(RE.Runtime.scene); 18 | }, 1000); 19 | } 20 | 21 | } 22 | 23 | RE.registerComponent(FixColdStart); 24 | -------------------------------------------------------------------------------- /_Rogue/Engine/Controller/Input/Touch.d.ts: -------------------------------------------------------------------------------- 1 | export declare type TouchInteraction = { 2 | id: string; 3 | touch: Touch; 4 | x: number; 5 | y: number; 6 | deltaX: number; 7 | deltaY: number; 8 | }; 9 | export declare class TouchController { 10 | private _startTouches; 11 | private _endTouches; 12 | private _touches; 13 | private _enabled; 14 | get startTouches(): TouchInteraction[]; 15 | get endTouches(): TouchInteraction[]; 16 | get touches(): TouchInteraction[]; 17 | get enabled(): boolean; 18 | set enabled(value: boolean); 19 | init(): void; 20 | private onTouchStart; 21 | private onTouchEnd; 22 | private onTouchMove; 23 | private getCurrentTouchIndexById; 24 | private setTouchValues; 25 | } 26 | -------------------------------------------------------------------------------- /Assets/Components/UiManager.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | 3 | export default class UiManager extends RE.Component { 4 | 5 | private onUILoadedCallbacks: (() => void)[] = []; 6 | 7 | awake() { 8 | this.initUI(); 9 | } 10 | 11 | async initUI() { 12 | 13 | const htmlPath = RE.getStaticPath("ui.html"); 14 | 15 | RE.Runtime.uiContainer.innerHTML = await (await fetch(htmlPath)).text(); 16 | 17 | this.runOnUILoadedCallbacks(); 18 | } 19 | 20 | start() { 21 | 22 | } 23 | 24 | onUILoaded(callback: () => void) { 25 | this.onUILoadedCallbacks.push(callback); 26 | } 27 | 28 | private runOnUILoadedCallbacks() { 29 | for (const callback of this.onUILoadedCallbacks) { 30 | callback(); 31 | } 32 | } 33 | } 34 | 35 | RE.registerComponent(UiManager); 36 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Shapes/CannonBox.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as THREE from 'three'; 3 | import * as CANNON from 'cannon-es'; 4 | import CannonShape from './CannonShape'; 5 | 6 | export default class CannonBox extends CannonShape { 7 | shape: CANNON.Box; 8 | @RE.Prop("Vector3") sizeOffset: THREE.Vector3 = new THREE.Vector3(1, 1, 1); 9 | 10 | worldScale = new THREE.Vector3(); 11 | 12 | protected createShape() { 13 | this.object3d.getWorldScale(this.worldScale); 14 | 15 | this.shape = new CANNON.Box( 16 | new CANNON.Vec3( 17 | this.sizeOffset.x * (this.worldScale.x/2), 18 | this.sizeOffset.y * (this.worldScale.y/2), 19 | this.sizeOffset.z * (this.worldScale.z/2) 20 | ) 21 | ); 22 | } 23 | } 24 | 25 | RE.registerComponent(CannonBox); 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "roguetemplateproject", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "cross-env NODE_ENV=production webpack --progress" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@types/three": "0.134.0", 14 | "cannon-es": "^0.18.0", 15 | "cors": "^2.8.5", 16 | "express": "^4.17.1", 17 | "glob": "^7.1.6", 18 | "mkcert": "^1.4.0", 19 | "three": "0.134.0" 20 | }, 21 | "devDependencies": { 22 | "cross-env": "^5.2.1", 23 | "fork-ts-checker-webpack-plugin": "^6.1.0", 24 | "tslib": "^1.9.3", 25 | "typescript": "^3.9.7", 26 | "webpack": "^5.20.1", 27 | "webpack-cli": "^4.5.0", 28 | "esbuild-loader": "^2.13.0", 29 | "webpack-merge": "^5.7.3" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Assets/Prefabs/Point.roguePrefab: -------------------------------------------------------------------------------- 1 | {"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"materials":[{"uuid":"177B0547-01BF-4AD1-92AE-3F1CEC6D6587","type":"MeshStandardMaterial","color":16777215,"roughness":1,"metalness":0,"emissive":0,"envMapIntensity":1,"refractionRatio":0.98,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680}],"object":{"uuid":"9252DBAA-A39F-4EA7-AE06-F35B29707138","type":"Sprite","name":"Point","userData":{"__IS_ADDING__":false,"__REF__":"94E9892D-151C-4502-8DB2-46619BF5ECD0","__ASSET__":"9252DBAA-A39F-4EA7-AE06-F35B29707138","__MATERIAL__":"3488DD94-9DAE-4EF4-8B64-A0B5C96B735B","components":[]},"layers":1,"matrix":[0.15,0,0,0,0,0.15,0,0,0,0,0.15,0,0.6519001662959453,0.32288415599042697,0,1],"material":"177B0547-01BF-4AD1-92AE-3F1CEC6D6587"}} -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Constraints/CannonConstraint.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import { Object3D } from 'three'; 3 | import * as CANNON from 'cannon-es'; 4 | import CannonBody from '../CannonBody.re'; 5 | import * as RogueCannon from '../../Lib/RogueCannon'; 6 | 7 | export default class CannonConstraint extends RE.Component { 8 | constraint: CANNON.Constraint; 9 | targetBody: CANNON.Body; 10 | 11 | start() { 12 | this.createConstraint(); 13 | } 14 | 15 | protected getCannonBodyComponent(object3d: Object3D): CannonBody { 16 | const cannonBody = RE.getComponent(CannonBody, object3d); 17 | 18 | if (!cannonBody) { 19 | throw "CannonHinge targets must have a Cannon Body Component" 20 | } 21 | 22 | return cannonBody; 23 | } 24 | 25 | protected createConstraint() {} 26 | 27 | onRemoved() { 28 | RogueCannon.getWorld().removeConstraint(this.constraint); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Shapes/CannonCylinder.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as THREE from 'three'; 3 | import * as CANNON from 'cannon-es'; 4 | import CannonShape from './CannonShape'; 5 | 6 | export default class CannonCylinder extends CannonShape { 7 | shape: CANNON.Cylinder; 8 | 9 | @RE.Prop("Number") radiusTopOffset = 1; 10 | @RE.Prop("Number") radiusBottomOffset = 1; 11 | @RE.Prop("Number") heightOffset = 1; 12 | @RE.Prop("Number") segments = 100; 13 | 14 | worldScale = new THREE.Vector3(); 15 | 16 | protected createShape() { 17 | this.object3d.getWorldScale(this.worldScale); 18 | 19 | this.shape = new CANNON.Cylinder( 20 | this.radiusTopOffset * this.worldScale.x, 21 | this.radiusBottomOffset * this.worldScale.x, 22 | this.heightOffset * this.worldScale.y, 23 | this.segments 24 | ); 25 | } 26 | } 27 | 28 | RE.registerComponent(CannonCylinder); 29 | -------------------------------------------------------------------------------- /_Rogue/Engine/Controller/RuntimeController.d.ts: -------------------------------------------------------------------------------- 1 | import Component from '../Model/Component'; 2 | import SceneController from '../Model/SceneController'; 3 | import { WebGLRenderer, Scene } from 'three'; 4 | export declare class RuntimeController extends SceneController { 5 | uiContainer: HTMLDivElement; 6 | private onPlayCbsFlaggedForRemoval; 7 | private onStopCbsFlaggedForRemoval; 8 | play(scene: Scene, renderer?: WebGLRenderer, componentsToLoad?: any): void; 9 | onPlay(callback: () => any): { 10 | stop: () => void; 11 | }; 12 | onStop(callback: () => any): { 13 | stop: () => void; 14 | }; 15 | stop(): void; 16 | private createUIContainer; 17 | private removeUIContainer; 18 | protected afterUpdate(): void; 19 | protected traverseSceneComponents(callback: (component: Component) => void): void; 20 | protected beginUpdateCycle(): void; 21 | } 22 | export declare const Runtime: RuntimeController; 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angry-Bomb 2 | Projectile motion examples made with Rogue Engine, a ThreeJS based game engine created by [@BeardScript](https://github.com/BeardScript) 3 | 4 | ![AngryBomb Sample](https://user-images.githubusercontent.com/3352700/149187364-a3280dfb-80d6-4184-9ae6-1e4f5d4ae175.gif) 5 | 6 | # DEMO 7 | https://39558918.servicio-online.net/angryBomb/ 8 | 9 | # Instructions 10 | * Clone this project. 11 | * Open Rogue Engine. 12 | * Select open project. 13 | * Navigate to the project folder. 14 | * Select it and click open. 15 | * In the project view, go to Assets/Scenes/ 16 | * Open AngryBomb, VideoBlocks or Basket.rogueScene 17 | * Enjoy! 18 | 19 | # Notes 20 | * To view the camera use the browser (not the Rogue Editor) in HTTPS 21 | * Tested on Chrome, Safari, Firefox, Opera & Edge (Desktop, iOS & Android) 22 | * AngryBomb background model from LowPoly Platformer Pack by quaternius 23 | 24 | # Rogue Engine 25 | https://rogueengine.io/ 26 | 27 | 28 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Constraints/CannonLockConstraint.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as CANNON from 'cannon-es'; 3 | import * as THREE from 'three'; 4 | import CannonConstraint from './CannonConstraint'; 5 | import * as RogueCannon from '../../Lib/RogueCannon'; 6 | 7 | export default class CannonLockConstraint extends CannonConstraint { 8 | constraint: CANNON.LockConstraint; 9 | 10 | @RE.Prop("Object3D") target: THREE.Object3D; 11 | @RE.Prop("Number") maxForce: number = 1e6; 12 | 13 | protected createConstraint() { 14 | if (!this.target) throw "CannonHinge requires a target"; 15 | 16 | const bodyA = this.getCannonBodyComponent(this.object3d).body; 17 | const bodyB = this.getCannonBodyComponent(this.target).body; 18 | 19 | this.constraint = new CANNON.LockConstraint(bodyA, bodyB, { 20 | maxForce: this.maxForce 21 | }); 22 | 23 | RogueCannon.getWorld().addConstraint(this.constraint); 24 | } 25 | } 26 | 27 | RE.registerComponent(CannonLockConstraint); 28 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Material/SetCannonMaterial.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as CANNON from 'cannon-es'; 3 | import CannonBody from '../CannonBody.re'; 4 | import * as RogueCannon from '../../Lib/RogueCannon'; 5 | 6 | export default class SetCannonMaterial extends RE.Component { 7 | material: CANNON.Material; 8 | 9 | @RE.Prop("String") materialName: string; 10 | 11 | start() { 12 | this.setMaterial(); 13 | } 14 | 15 | private getMaterial() { 16 | return RogueCannon.getWorld().materials.find(material => material.name === this.materialName) 17 | } 18 | 19 | private setMaterial() { 20 | const material = this.getMaterial(); 21 | 22 | if (!material) return; 23 | 24 | this.material = material; 25 | 26 | const cannonBody = RE.getComponent(CannonBody, this.object3d); 27 | 28 | if (cannonBody) { 29 | cannonBody.body.shapes.forEach(shape => (shape.material = this.material)); 30 | } 31 | } 32 | } 33 | 34 | RE.registerComponent(SetCannonMaterial); 35 | -------------------------------------------------------------------------------- /tsconfig.rogue.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "experimentalDecorators": true, 4 | "baseUrl": ".", 5 | "outDir": "build/", 6 | "module": "esnext", 7 | "target": "es5", 8 | "lib": ["es6", "dom", "es2015"], 9 | "allowJs": true, 10 | "moduleResolution": "node", 11 | "rootDir": "./", 12 | "forceConsistentCasingInFileNames": true, 13 | "noImplicitReturns": true, 14 | "noImplicitThis": true, 15 | "noImplicitAny": false, 16 | "importHelpers": true, 17 | "strictNullChecks": true, 18 | "suppressImplicitAnyIndexErrors": true, 19 | "noUnusedLocals": false, 20 | "paths": { 21 | "rogue-engine": [ "_Rogue/rogue-engine" ], 22 | } 23 | }, 24 | "include": [ 25 | "_Rogue/**/*", 26 | "Assets/**/*", 27 | ], 28 | "exclude": [ 29 | "node_modules", 30 | "build", 31 | "scripts", 32 | "acceptance-tests", 33 | "webpack", 34 | "jest", 35 | "dist", 36 | "src/setupTests.ts", 37 | "public/MainProcess", 38 | "src/MainProcess" 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Constraints/CannonDistanceConstraint.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as THREE from 'three'; 3 | import * as CANNON from 'cannon-es'; 4 | import CannonConstraint from './CannonConstraint'; 5 | import * as RogueCannon from '../../Lib/RogueCannon'; 6 | export default class CannonDistanceConstraint extends CannonConstraint { 7 | constraint: CANNON.DistanceConstraint; 8 | 9 | @RE.Prop("Object3D") target: THREE.Object3D; 10 | @RE.Prop("Number") distance: number = 1; 11 | @RE.Prop("Number") maxForce: number = 1e6; 12 | 13 | protected createConstraint() { 14 | if (!this.target) throw "CannonHinge requires a target"; 15 | 16 | const bodyA = this.getCannonBodyComponent(this.object3d).body; 17 | const bodyB = this.getCannonBodyComponent(this.target).body; 18 | 19 | this.constraint = new CANNON.DistanceConstraint(bodyA, bodyB, this.distance, this.maxForce); 20 | 21 | RogueCannon.getWorld().addConstraint(this.constraint); 22 | } 23 | } 24 | 25 | RE.registerComponent(CannonDistanceConstraint); 26 | -------------------------------------------------------------------------------- /_Rogue/Engine/Controller/Debug.d.ts: -------------------------------------------------------------------------------- 1 | export declare class Debug { 2 | static maxLogs: number; 3 | static logs: Log[]; 4 | private static _onAddLogCallbacks; 5 | private static _onClearLogsCallbacks; 6 | static clear(): void; 7 | static log(message: string): void; 8 | static logError(message: string): void; 9 | static logWarning(message: string): void; 10 | private static addLog; 11 | static onAddLog(callback: (log: Log) => void): { 12 | stop: () => void; 13 | }; 14 | static onClearLogs(callback: () => void): { 15 | stop: () => void; 16 | }; 17 | private static flushOnAddLogCallbacks; 18 | private static flushOnClearLogsCallbacks; 19 | } 20 | export declare class Log { 21 | message: string; 22 | protected _type: 'Log' | 'Error' | 'Warning'; 23 | get type(): "Log" | "Error" | "Warning"; 24 | constructor(message: string); 25 | } 26 | export declare class Error extends Log { 27 | constructor(message: string); 28 | } 29 | export declare class Warning extends Log { 30 | constructor(message: string); 31 | } 32 | -------------------------------------------------------------------------------- /Assets/Components/CameraController.re.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * CameraController.re 3 | * Manage the camera movement 4 | */ 5 | 6 | import * as RE from 'rogue-engine'; 7 | import { MathUtils, Object3D } from 'three'; 8 | const { Prop } = RE; 9 | 10 | export default class CameraController extends RE.Component { 11 | 12 | // Public component fields 13 | @Prop("Object3D") target: Object3D; 14 | @Prop("Number") offset: number = 1; 15 | @Prop("Number") smooth: number = 0.1; 16 | @Prop("Number") limitZ: number = 1; 17 | @Prop("Number") maxCameraX: number = 1.6; 18 | @Prop("Number") minCameraX: number = 0.16; 19 | 20 | 21 | update() { 22 | 23 | if (this.target) { 24 | 25 | const newX = this.target.position.x + this.offset; // Add an offset to the target position 26 | const smoothX = MathUtils.lerp(this.target.position.x, newX, this.smooth); // Smooth Lerp movement 27 | const clampedX = MathUtils.clamp(smoothX, this.minCameraX, this.maxCameraX); // Clamp movement 28 | this.object3d.position.x = clampedX; // Set new Z pos 29 | 30 | } 31 | 32 | } 33 | } 34 | 35 | RE.registerComponent(CameraController); 36 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Material/CannonMaterial.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as CANNON from 'cannon-es'; 3 | import CannonBody from '../CannonBody.re'; 4 | import * as RogueCannon from '../../Lib/RogueCannon'; 5 | 6 | export default class CannonMaterial extends RE.Component { 7 | material: CANNON.Material; 8 | 9 | @RE.Prop("Number") friction: number; 10 | @RE.Prop("Number") restitution: number; 11 | 12 | awake() { 13 | this.createMaterial(); 14 | } 15 | 16 | start() { 17 | this.setMaterial(); 18 | } 19 | 20 | protected createMaterial() { 21 | this.material = new CANNON.Material(this.name); 22 | 23 | // if (this.friction < 0) 24 | this.material.friction = this.friction; 25 | // if (this.restitution < 0) 26 | this.material.restitution = this.restitution; 27 | 28 | RogueCannon.getWorld().addMaterial(this.material); 29 | } 30 | 31 | private setMaterial() { 32 | const cannonBody = RE.getComponent(CannonBody, this.object3d); 33 | 34 | if (cannonBody) { 35 | cannonBody.body.shapes.forEach(shape => shape.material = this.material); 36 | } 37 | } 38 | } 39 | 40 | RE.registerComponent(CannonMaterial); 41 | -------------------------------------------------------------------------------- /Assets/Materials/timerBar_mat_sm.rogueMaterial: -------------------------------------------------------------------------------- 1 | {"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"geometries":[{"uuid":"DEDA9118-6F64-4C80-A652-03DFE7FD5393","type":"BufferGeometry","data":{"attributes":{}}}],"materials":[{"uuid":"9FFAD76A-606D-4CE3-8F03-A92E0B6ABE1F","type":"SpriteMaterial","name":"timerBar_mat_sm","color":16711680,"sizeAttenuation":true,"transparent":true,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"userData":{"__ASSET__":"9FFAD76A-606D-4CE3-8F03-A92E0B6ABE1F"},"fog":true,"blending":1,"side":0,"vertexColors":false,"opacity":1,"format":1023,"blendSrc":204,"blendDst":205,"blendEquation":100,"clipIntersection":false,"clipShadows":false,"polygonOffset":false,"polygonOffsetFactor":0,"polygonOffsetUnits":0,"dithering":false,"alphaToCoverage":false,"premultipliedAlpha":false,"visible":true,"toneMapped":true,"version":0,"_alphaTest":0,"rotation":0}],"object":{"uuid":"836E9346-017B-467C-88D4-2D703D9D3AC8","type":"Mesh","userData":{"__IS_MATERIAL__":true},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"geometry":"DEDA9118-6F64-4C80-A652-03DFE7FD5393","material":"9FFAD76A-606D-4CE3-8F03-A92E0B6ABE1F"},"images":[]} -------------------------------------------------------------------------------- /Assets/Materials/timerProgress_mat_sm.rogueMaterial: -------------------------------------------------------------------------------- 1 | {"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"geometries":[{"uuid":"D5DC67A6-85D6-4ABE-94D8-5B51130EDCEF","type":"BufferGeometry","data":{"attributes":{}}}],"materials":[{"uuid":"05AA2CF3-42AF-4F7B-B197-B76DC747321C","type":"SpriteMaterial","name":"timerProgress_mat_sm","color":1179392,"sizeAttenuation":true,"transparent":true,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"userData":{"__ASSET__":"05AA2CF3-42AF-4F7B-B197-B76DC747321C"},"fog":true,"blending":1,"side":0,"vertexColors":false,"opacity":1,"format":1023,"blendSrc":204,"blendDst":205,"blendEquation":100,"clipIntersection":false,"clipShadows":false,"polygonOffset":false,"polygonOffsetFactor":0,"polygonOffsetUnits":0,"dithering":false,"alphaToCoverage":false,"premultipliedAlpha":false,"visible":true,"toneMapped":true,"version":0,"_alphaTest":0,"rotation":0}],"object":{"uuid":"03CD9DB8-F66A-420C-B85D-B9FC0C22F5B3","type":"Mesh","userData":{"__IS_MATERIAL__":true},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"geometry":"D5DC67A6-85D6-4ABE-94D8-5B51130EDCEF","material":"05AA2CF3-42AF-4F7B-B197-B76DC747321C"},"images":[]} -------------------------------------------------------------------------------- /Assets/Materials/point_mat_sp.rogueMaterial: -------------------------------------------------------------------------------- 1 | {"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"geometries":[{"uuid":"BD34B22F-3C69-49F3-A38F-5139BE41D0DC","type":"BufferGeometry","data":{"attributes":{}}}],"materials":[{"uuid":"3488DD94-9DAE-4EF4-8B64-A0B5C96B735B","type":"SpriteMaterial","name":"point_mat_sp","color":16777215,"map":"E165F1A4-B7E2-40E4-9263-C011FE25279C","sizeAttenuation":true,"transparent":true,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"userData":{"__ASSET__":"3488DD94-9DAE-4EF4-8B64-A0B5C96B735B"},"fog":true,"blending":1,"side":0,"vertexColors":false,"opacity":1,"format":1023,"blendSrc":204,"blendDst":205,"blendEquation":100,"clipIntersection":false,"clipShadows":false,"polygonOffset":false,"polygonOffsetFactor":0,"polygonOffsetUnits":0,"dithering":false,"alphaToCoverage":false,"premultipliedAlpha":false,"visible":true,"toneMapped":true,"version":1,"_alphaTest":0,"rotation":0}],"textures":["E165F1A4-B7E2-40E4-9263-C011FE25279C"],"images":[],"object":{"uuid":"0A2ECA67-74A5-4451-9099-37DD870327E1","type":"Mesh","userData":{"__IS_MATERIAL__":true},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"geometry":"BD34B22F-3C69-49F3-A38F-5139BE41D0DC","material":"3488DD94-9DAE-4EF4-8B64-A0B5C96B735B"}} -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Constraints/CannonPointToPointConstraint.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as THREE from 'three'; 3 | import * as CANNON from 'cannon-es'; 4 | import CannonConstraint from './CannonConstraint'; 5 | import * as RogueCannon from '../../Lib/RogueCannon'; 6 | 7 | export default class CannonPointToPointConstraint extends CannonConstraint { 8 | constraint: CANNON.PointToPointConstraint; 9 | 10 | @RE.Prop("Object3D") target: THREE.Object3D; 11 | @RE.Prop("Vector3") privotA: THREE.Vector3 = new THREE.Vector3(); 12 | @RE.Prop("Vector3") privotB: THREE.Vector3 = new THREE.Vector3(); 13 | @RE.Prop("Number") maxForce: number = 1e6; 14 | 15 | protected createConstraint() { 16 | if (!this.target) throw "CannonHinge requires a target"; 17 | 18 | const bodyA = this.getCannonBodyComponent(this.object3d).body; 19 | const bodyB = this.getCannonBodyComponent(this.target).body; 20 | 21 | this.constraint = new CANNON.PointToPointConstraint( 22 | bodyA, 23 | new CANNON.Vec3(this.privotA.x, this.privotA.y, this.privotA.z), 24 | bodyB, 25 | new CANNON.Vec3(this.privotB.x, this.privotB.y, this.privotB.z), 26 | this.maxForce 27 | ); 28 | 29 | RogueCannon.getWorld().addConstraint(this.constraint); 30 | } 31 | } 32 | 33 | RE.registerComponent(CannonPointToPointConstraint); 34 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Material/CannonContactMaterial.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as CANNON from 'cannon-es'; 3 | import * as RogueCannon from '../../Lib/RogueCannon'; 4 | 5 | export default class CannonContactMaterial extends RE.Component { 6 | contactMaterial: CANNON.ContactMaterial; 7 | 8 | @RE.Prop("String") materialA: string; 9 | @RE.Prop("String") materialB: string; 10 | @RE.Prop("Number") friction: number; 11 | @RE.Prop("Number") restitution: number; 12 | 13 | start() { 14 | this.createContactMaterial(); 15 | } 16 | 17 | private getMaterial(materialName: string) { 18 | return RogueCannon.getWorld().materials.find(material => material.name === materialName) 19 | } 20 | 21 | private createContactMaterial() { 22 | const cannonMaterialA = this.getMaterial(this.materialA); 23 | const cannonMaterialB = this.getMaterial(this.materialB); 24 | 25 | if (!cannonMaterialA || !cannonMaterialB) return; 26 | 27 | this.contactMaterial = new CANNON.ContactMaterial(cannonMaterialA, cannonMaterialB, { 28 | friction: this.friction, 29 | restitution: this.restitution, 30 | }); 31 | 32 | this.contactMaterial.friction = this.friction; 33 | this.contactMaterial.restitution = this.restitution; 34 | 35 | RogueCannon.getWorld().addContactMaterial(this.contactMaterial); 36 | } 37 | } 38 | 39 | RE.registerComponent(CannonContactMaterial); 40 | -------------------------------------------------------------------------------- /Assets/Materials/background_mat_mbm.rogueMaterial: -------------------------------------------------------------------------------- 1 | {"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"geometries":[{"uuid":"DC81F416-B163-4F66-8F6B-EF6E186DE4D9","type":"BufferGeometry","data":{"attributes":{}}}],"materials":[{"uuid":"1BFE2755-84C0-4BE1-BAB2-BFA918459969","type":"MeshBasicMaterial","name":"background_mat_mbm","color":16777215,"map":"7C7DE5E1-F851-48CC-9C36-90F33A98AE46","reflectivity":1,"refractionRatio":0.98,"transparent":true,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"userData":{"__ASSET__":"1BFE2755-84C0-4BE1-BAB2-BFA918459969"},"fog":true,"blending":1,"side":0,"vertexColors":false,"opacity":1,"format":1023,"blendSrc":204,"blendDst":205,"blendEquation":100,"clipIntersection":false,"clipShadows":false,"polygonOffset":false,"polygonOffsetFactor":0,"polygonOffsetUnits":0,"dithering":false,"alphaToCoverage":false,"premultipliedAlpha":false,"visible":true,"toneMapped":true,"version":0,"_alphaTest":0,"lightMapIntensity":1,"aoMapIntensity":1,"combine":0,"wireframe":false,"wireframeLinewidth":1,"wireframeLinecap":"round","wireframeLinejoin":"round"}],"textures":["7C7DE5E1-F851-48CC-9C36-90F33A98AE46"],"images":[],"object":{"uuid":"FA995E66-5CBA-4053-9A78-F7D290229ACF","type":"Mesh","userData":{"__IS_MATERIAL__":true},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"geometry":"DC81F416-B163-4F66-8F6B-EF6E186DE4D9","material":"1BFE2755-84C0-4BE1-BAB2-BFA918459969"}} -------------------------------------------------------------------------------- /Assets/Materials/blackTV_mat_msm.rogueMaterial: -------------------------------------------------------------------------------- 1 | {"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"geometries":[{"uuid":"B1785BAC-C5C7-4A7D-B509-CD22C654880C","type":"BufferGeometry","data":{"attributes":{}}}],"materials":[{"uuid":"0616E97E-B4A1-49BF-ABFB-D8C2CD6CF484","type":"MeshStandardMaterial","name":"blackTV_mat_msm","color":0,"roughness":1,"metalness":0,"emissive":0,"envMapIntensity":1,"refractionRatio":0.98,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"userData":{"__ASSET__":"0616E97E-B4A1-49BF-ABFB-D8C2CD6CF484"},"fog":true,"blending":1,"side":0,"vertexColors":false,"opacity":1,"format":1023,"transparent":false,"blendSrc":204,"blendDst":205,"blendEquation":100,"clipIntersection":false,"clipShadows":false,"polygonOffset":false,"polygonOffsetFactor":0,"polygonOffsetUnits":0,"dithering":false,"alphaToCoverage":false,"premultipliedAlpha":false,"visible":true,"toneMapped":true,"version":0,"_alphaTest":0,"lightMapIntensity":1,"aoMapIntensity":1,"emissiveIntensity":1,"bumpScale":1,"normalMapType":0,"normalScale":[1,1],"displacementScale":1,"displacementBias":0,"wireframe":false,"wireframeLinewidth":1,"wireframeLinecap":"round","wireframeLinejoin":"round","flatShading":false}],"object":{"uuid":"82C89E08-FDFC-4D72-995D-F7680E03DE1B","type":"Mesh","userData":{"__IS_MATERIAL__":true},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"geometry":"B1785BAC-C5C7-4A7D-B509-CD22C654880C","material":"0616E97E-B4A1-49BF-ABFB-D8C2CD6CF484"},"images":[]} -------------------------------------------------------------------------------- /Assets/Materials/white_mat_msm.rogueMaterial: -------------------------------------------------------------------------------- 1 | {"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"geometries":[{"uuid":"7E2D3924-EE05-4D40-B05E-482D56029D7F","type":"BufferGeometry","data":{"attributes":{}}}],"materials":[{"uuid":"D2FDA8E0-3FD7-4451-81C2-575E3250F8AF","type":"MeshStandardMaterial","name":"white_mat_msm","color":16777215,"roughness":1,"metalness":0,"emissive":0,"envMapIntensity":1,"refractionRatio":0.98,"depthFunc":2,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"userData":{"__ASSET__":"D2FDA8E0-3FD7-4451-81C2-575E3250F8AF"},"fog":true,"blending":1,"side":0,"vertexColors":false,"opacity":1,"format":1023,"transparent":false,"blendSrc":204,"blendDst":205,"blendEquation":100,"clipIntersection":false,"clipShadows":false,"polygonOffset":false,"polygonOffsetFactor":0,"polygonOffsetUnits":0,"dithering":false,"alphaToCoverage":false,"premultipliedAlpha":false,"visible":true,"toneMapped":true,"version":0,"_alphaTest":0,"lightMapIntensity":1,"aoMapIntensity":1,"emissiveIntensity":1,"bumpScale":1,"normalMapType":0,"normalScale":[1,1],"displacementScale":1,"displacementBias":0,"wireframe":false,"wireframeLinewidth":1,"wireframeLinecap":"round","wireframeLinejoin":"round","flatShading":false}],"object":{"uuid":"C59AF1ED-F7DB-4ECC-9A4C-FEF04899553B","type":"Mesh","userData":{"__IS_MATERIAL__":true},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"geometry":"7E2D3924-EE05-4D40-B05E-482D56029D7F","material":"D2FDA8E0-3FD7-4451-81C2-575E3250F8AF"},"images":[]} -------------------------------------------------------------------------------- /_Rogue/rogue-engine.d.ts: -------------------------------------------------------------------------------- 1 | export { AssetManager } from './Engine/Controller/AssetManager'; 2 | export { AudioAsset } from './Engine/Model/AudioAsset'; 3 | export { Prefab } from './Engine/Model/Prefab'; 4 | export { default as Component } from "./Engine/Model/Component"; 5 | import { ComponentInterface as CInterface } from "./Engine/Model/Component"; 6 | export declare type ComponentInterface = CInterface; 7 | export { Skybox } from './Engine/Model/Skybox'; 8 | export { Input } from './Engine/Controller/Input/Input'; 9 | import { TouchInteraction as TouchInteractionType } from './Engine/Controller/Input/Touch'; 10 | export declare type TouchInteraction = TouchInteractionType; 11 | export { traverseComponents, registerComponent, components, editorComponents, serializeComponents, initComponents, initEditorComponents, clearComponents, loadComponents, addComponent, removeComponent, removeComponents, getComponent, getComponents, getComponentByName, getObjectComponents, getComponentPrototypes, copyObjectComponents, } from "./Engine/Controller/ComponentsManager"; 12 | export { App } from './Engine/Controller/App'; 13 | export { default as SceneController } from './Engine/Model/SceneController'; 14 | export { Runtime, RuntimeController } from './Engine/Controller/RuntimeController'; 15 | export { Debug, Log, Error, Warning } from './Engine/Controller/Debug'; 16 | export { onObjectAdded, onComponentAdded, onComponentLoaded, onComponentRemoved, onObjectRemoved, onBeforeUpdate, onUpdate, onAfterUpdate, onNextFrame, } from './Engine/Controller/Events'; 17 | export { isDev, getStaticPath, dispose } from './Engine/Controller/Functions'; 18 | export { Prop, PropList } from './Engine/Controller/Decorators'; 19 | -------------------------------------------------------------------------------- /Assets/Materials/box_mat_msm.rogueMaterial: -------------------------------------------------------------------------------- 1 | {"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"geometries":[{"uuid":"4AC39380-2EF1-4475-A41F-EF118CBF31DC","type":"BufferGeometry","data":{"attributes":{}}}],"materials":[{"uuid":"38E38081-27F9-4FCD-B558-EE664E56E672","type":"MeshStandardMaterial","name":"box_mat_msm","color":16777215,"roughness":1,"metalness":0,"emissive":0,"map":"3361F96B-7A28-4805-9E1F-A35B44C3EA58","envMapIntensity":1,"refractionRatio":0.98,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"userData":{"__ASSET__":"38E38081-27F9-4FCD-B558-EE664E56E672"},"fog":true,"blending":1,"side":0,"vertexColors":false,"opacity":1,"format":1023,"transparent":false,"blendSrc":204,"blendDst":205,"blendEquation":100,"clipIntersection":false,"clipShadows":false,"polygonOffset":false,"polygonOffsetFactor":0,"polygonOffsetUnits":0,"dithering":false,"alphaToCoverage":false,"premultipliedAlpha":false,"visible":true,"toneMapped":true,"version":1,"_alphaTest":0,"lightMapIntensity":1,"aoMapIntensity":1,"emissiveIntensity":1,"bumpScale":1,"normalMapType":0,"normalScale":[1,1],"displacementScale":1,"displacementBias":0,"wireframe":false,"wireframeLinewidth":1,"wireframeLinecap":"round","wireframeLinejoin":"round","flatShading":false}],"textures":["3361F96B-7A28-4805-9E1F-A35B44C3EA58"],"images":[],"object":{"uuid":"FCDFD1DB-D4C7-4893-AAE8-CC8431F2E31A","type":"Mesh","userData":{"__IS_MATERIAL__":true},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"geometry":"4AC39380-2EF1-4475-A41F-EF118CBF31DC","material":"38E38081-27F9-4FCD-B558-EE664E56E672"}} -------------------------------------------------------------------------------- /Assets/Materials/videoBlock_mat_msm.rogueMaterial: -------------------------------------------------------------------------------- 1 | {"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"geometries":[{"uuid":"CCC0C59A-D9EB-4973-8FE7-735DBED9AD75","type":"BufferGeometry","data":{"attributes":{}}}],"materials":[{"uuid":"89B6BF4D-3150-48C3-88D8-90DCA3195D51","type":"MeshStandardMaterial","name":"videoBlock_mat_msm","color":16777215,"roughness":1,"metalness":0,"emissive":4013373,"map":"02716EE0-105D-4407-A99F-E758964EA9F1","envMapIntensity":1,"refractionRatio":0.98,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"userData":{"__ASSET__":"89B6BF4D-3150-48C3-88D8-90DCA3195D51"},"fog":true,"blending":1,"side":0,"vertexColors":false,"opacity":1,"format":1023,"transparent":false,"blendSrc":204,"blendDst":205,"blendEquation":100,"clipIntersection":false,"clipShadows":false,"polygonOffset":false,"polygonOffsetFactor":0,"polygonOffsetUnits":0,"dithering":false,"alphaToCoverage":false,"premultipliedAlpha":false,"visible":true,"toneMapped":true,"version":0,"_alphaTest":0,"lightMapIntensity":1,"aoMapIntensity":1,"emissiveIntensity":1,"bumpScale":1,"normalMapType":0,"normalScale":[1,1],"displacementScale":1,"displacementBias":0,"wireframe":false,"wireframeLinewidth":1,"wireframeLinecap":"round","wireframeLinejoin":"round","flatShading":false}],"textures":["02716EE0-105D-4407-A99F-E758964EA9F1"],"images":[],"object":{"uuid":"5F026BA9-15F5-4A76-B961-C11D624CB514","type":"Mesh","userData":{"__IS_MATERIAL__":true},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"geometry":"CCC0C59A-D9EB-4973-8FE7-735DBED9AD75","material":"89B6BF4D-3150-48C3-88D8-90DCA3195D51"}} -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/CannonConfig.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as CANNON from 'cannon-es'; 3 | import * as THREE from 'three'; 4 | import * as RogueCannon from '../Lib/RogueCannon'; 5 | 6 | export default class CannonConfig extends RE.Component { 7 | private _defaultFriction = 0.01; 8 | private _defaultRestitution = 0; 9 | 10 | @RE.Prop("Number") maxSubSteps: number = 1; 11 | 12 | @RE.Prop("Number") 13 | get defaultFriction() { 14 | return this._defaultFriction; 15 | } 16 | 17 | set defaultFriction(value: number) { 18 | this._defaultFriction = value; 19 | RogueCannon.getWorld().defaultContactMaterial.friction = value; 20 | } 21 | 22 | @RE.Prop("Number") 23 | get defaultRestitution() { 24 | return this._defaultRestitution; 25 | } 26 | 27 | set defaultRestitution(value: number) { 28 | this._defaultRestitution = value; 29 | RogueCannon.getWorld().defaultContactMaterial.restitution = value; 30 | } 31 | 32 | @RE.Prop("Vector3") gravity: THREE.Vector3 = new THREE.Vector3(0, -9.82, 0); 33 | 34 | awake() { 35 | RogueCannon.setWorld(new CANNON.World()); 36 | RogueCannon.getWorld().gravity.set(this.gravity.x, this.gravity.y, this.gravity.z); 37 | RogueCannon.getWorld().broadphase = new CANNON.NaiveBroadphase(); 38 | RogueCannon.getWorld().defaultContactMaterial.friction = this.defaultFriction; 39 | RogueCannon.getWorld().defaultContactMaterial.restitution = this.defaultRestitution; 40 | } 41 | 42 | beforeUpdate() { 43 | RogueCannon.getWorld().step(RE.Runtime.deltaTime, RE.Runtime.deltaTime, this.maxSubSteps || 1); 44 | } 45 | } 46 | 47 | RE.registerComponent( CannonConfig ); 48 | -------------------------------------------------------------------------------- /Static/ui.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /Assets/Components/SceneManager.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import DeviceUtils from './Static/DeviceUtils'; 3 | import UiManager from './UiManager.re'; 4 | 5 | export default class SceneManager extends RE.Component { 6 | 7 | private reloadBtn: HTMLElement; 8 | private nextSceneBtn: HTMLElement; 9 | 10 | start() { 11 | 12 | const uiManager = RE.getComponent(UiManager) as UiManager; 13 | 14 | // On Firefox we have to wait for the UI to be loaded to be able to access the video tag 15 | uiManager.onUILoaded(() => { 16 | 17 | this.reloadBtn = document.getElementById('reload-button') as HTMLVideoElement; 18 | 19 | this.reloadBtn.addEventListener(DeviceUtils.getClickEventName(), (event) => { 20 | // Stop the event from reaching screen 21 | event.stopPropagation(); 22 | // Get index of current scene so scene name is always empty 23 | const indexScene = RE.App.scenes.map(function (e) { return e.uuid; }).indexOf(RE.App.currentScene.uuid); 24 | RE.App.loadScene(indexScene); 25 | }) 26 | 27 | 28 | this.nextSceneBtn = document.getElementById('next-button') as HTMLVideoElement; 29 | 30 | this.nextSceneBtn.addEventListener(DeviceUtils.getClickEventName(), (event) => { 31 | // Stop the event from reaching screen 32 | event.stopPropagation(); 33 | // Get index of current scene so scene name is always empty 34 | const indexScene = RE.App.scenes.map(function (e) { return e.uuid; }).indexOf(RE.App.currentScene.uuid); 35 | const newSceneIndex = (indexScene < RE.App.scenes.length - 1) ? indexScene + 1 : 0; 36 | RE.App.loadScene(newSceneIndex); 37 | }) 38 | }) 39 | 40 | } 41 | } 42 | 43 | RE.registerComponent(SceneManager); 44 | -------------------------------------------------------------------------------- /Assets/Components/WebcamTexture.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import { LinearFilter, RGBFormat, MeshLambertMaterial, Mesh, VideoTexture, RepeatWrapping, Vector2 } from 'three'; 3 | import WebcamController from './WebcamController.re'; 4 | 5 | const { Prop } = RE; 6 | 7 | export default class WebcamTexture extends RE.Component { 8 | 9 | @Prop("Vector2") offset: Vector2 = new Vector2(0,0); // Offset for webcam texture 10 | 11 | private repeat: Vector2 = new Vector2(0.25, 0.33); // 0.25 = 4 horizontal blocks, 0.33 = 3 vertical blocks 12 | private webcamController: WebcamController; 13 | 14 | awake() { 15 | this.webcamController = RE.getComponent(WebcamController) as WebcamController; 16 | } 17 | 18 | start() { 19 | // We have to wait for the webcam stream to use its texture 20 | this.webcamController.onWebcamReady(() => { 21 | this.setWebcamTexture(); 22 | }); 23 | 24 | } 25 | 26 | setWebcamTexture() { 27 | 28 | const video = document.getElementById('video') as HTMLVideoElement; 29 | 30 | const texture = new VideoTexture(video); 31 | 32 | texture.minFilter = LinearFilter; 33 | texture.magFilter = LinearFilter; 34 | texture.repeat = this.repeat; 35 | texture.center = this.offset; 36 | texture.format = RGBFormat; 37 | texture.generateMipmaps = false; 38 | texture.needsUpdate = true; 39 | 40 | const parameters = { color: 0xffffff, map: texture }; 41 | const material_base = new MeshLambertMaterial(parameters); 42 | 43 | if (this.object3d instanceof Mesh) { // We avoid errors with Type Assertions getting object.material 44 | this.object3d.material = material_base; 45 | } 46 | } 47 | 48 | update() { 49 | 50 | } 51 | } 52 | 53 | RE.registerComponent(WebcamTexture); 54 | -------------------------------------------------------------------------------- /Assets/Components/BombTimer.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import { Object3D } from 'three'; 3 | 4 | const { Prop } = RE; 5 | 6 | export default class BombTimer extends RE.Component { 7 | 8 | // External dependencies 9 | @Prop("Object3D") timerProgress: Object3D; 10 | @Prop("Number") duration: number; 11 | 12 | // Private variables 13 | private endTime: number; 14 | private timerStarted: boolean = false; 15 | private onTimerEndCallbacks: (() => void)[] = []; 16 | 17 | awake() { 18 | this.object3d.visible = false; // Bombtimer is only visible when it starts counting 19 | } 20 | 21 | startCount() { 22 | this.object3d.visible = true; 23 | this.endTime = RE.Runtime.clock.elapsedTime + this.duration; 24 | this.timerStarted = true; 25 | } 26 | 27 | update() { 28 | 29 | if (this.timerStarted) { 30 | 31 | const now = RE.Runtime.clock.elapsedTime; 32 | 33 | if (now > this.endTime) { 34 | 35 | this.timerStarted = false; 36 | this.runTimeEndCallbacks(); 37 | 38 | } else { 39 | 40 | const w = (this.endTime - now) / this.duration; 41 | // Resize progress bar 42 | this.timerProgress.position.setX(-0.5 + w * 0.5); 43 | // Adjust the X axis of the progress bar because the horizontal scale changes from the center of sprite 44 | this.timerProgress.scale.setX(w); 45 | 46 | } 47 | 48 | } 49 | 50 | } 51 | 52 | // Register a new callback 53 | onTimerEnds(callback: () => void) { 54 | this.onTimerEndCallbacks.push(callback); 55 | } 56 | 57 | // Fire all calbacks registered 58 | private runTimeEndCallbacks() { 59 | for (const callback of this.onTimerEndCallbacks) { 60 | callback(); 61 | } 62 | } 63 | } 64 | 65 | RE.registerComponent(BombTimer); 66 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Constraints/CannonHingeConstraint.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as THREE from 'three'; 3 | import * as CANNON from 'cannon-es'; 4 | import CannonConstraint from './CannonConstraint'; 5 | import * as RogueCannon from '../../Lib/RogueCannon'; 6 | 7 | export default class CannonHingeConstraint extends CannonConstraint { 8 | constraint: CANNON.HingeConstraint; 9 | 10 | @RE.Prop("Object3D") target: THREE.Object3D; 11 | @RE.Prop("Vector3") pivotA: THREE.Vector3 = new THREE.Vector3(0.1, 0, 0); 12 | @RE.Prop("Vector3") axisA: THREE.Vector3 = new THREE.Vector3(0, 1, 0); 13 | @RE.Prop("Vector3") pivotB: THREE.Vector3 = new THREE.Vector3(-1, 0, 0); 14 | @RE.Prop("Vector3") axisB: THREE.Vector3 = new THREE.Vector3(0, 1, 0); 15 | @RE.Prop("Boolean") collideConnected: boolean; 16 | @RE.Prop("Number") maxForce: number = 1e6; 17 | 18 | protected createConstraint() { 19 | if (!this.target) throw "CannonHinge requires a target"; 20 | 21 | const bodyA = this.getCannonBodyComponent(this.object3d).body; 22 | const bodyB = this.getCannonBodyComponent(this.target).body; 23 | 24 | this.constraint = new CANNON.HingeConstraint(bodyA, bodyB, { 25 | pivotA: new CANNON.Vec3(this.pivotA.x, this.pivotA.y, this.pivotA.z), 26 | axisA: new CANNON.Vec3(this.axisA.x, this.axisA.y, this.axisA.z), 27 | pivotB: new CANNON.Vec3(this.pivotB.x, this.pivotB.y, this.pivotB.z), 28 | axisB: new CANNON.Vec3(this.axisB.x, this.axisB.y, this.axisB.z), 29 | collideConnected: this.collideConnected, 30 | maxForce: this.maxForce, 31 | }); 32 | 33 | RogueCannon.getWorld().addConstraint(this.constraint); 34 | } 35 | } 36 | 37 | RE.registerComponent(CannonHingeConstraint); 38 | -------------------------------------------------------------------------------- /Assets/Materials/fuze_mat_msm.rogueMaterial: -------------------------------------------------------------------------------- 1 | {"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"geometries":[{"uuid":"577F9C31-A036-43F5-B101-9D9BFDAFDFB3","type":"BufferGeometry","data":{"attributes":{}}}],"materials":[{"uuid":"91C060A4-3941-4210-85F2-888C35B22948","type":"MeshStandardMaterial","name":"fuze_mat_msm","color":16777215,"roughness":1,"metalness":0,"emissive":0,"map":"77E0C83C-AE44-4504-AC09-C7DD8AD49945","normalMap":"56AD550F-D2AE-4843-B7D6-7B43705EEAA9","normalMapType":0,"normalScale":[1,1],"envMapIntensity":1,"refractionRatio":0.98,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"userData":{"__ASSET__":"91C060A4-3941-4210-85F2-888C35B22948"},"fog":true,"blending":1,"side":0,"vertexColors":false,"opacity":1,"format":1023,"transparent":false,"blendSrc":204,"blendDst":205,"blendEquation":100,"clipIntersection":false,"clipShadows":false,"polygonOffset":false,"polygonOffsetFactor":0,"polygonOffsetUnits":0,"dithering":false,"alphaToCoverage":false,"premultipliedAlpha":false,"visible":true,"toneMapped":true,"version":4,"_alphaTest":0,"lightMapIntensity":1,"aoMapIntensity":1,"emissiveIntensity":1,"bumpScale":1,"displacementScale":1,"displacementBias":0,"wireframe":false,"wireframeLinewidth":1,"wireframeLinecap":"round","wireframeLinejoin":"round","flatShading":false}],"textures":["77E0C83C-AE44-4504-AC09-C7DD8AD49945","56AD550F-D2AE-4843-B7D6-7B43705EEAA9"],"images":[],"object":{"uuid":"48670E92-4F0E-49BA-884D-E36B62F87F56","type":"Mesh","userData":{"__IS_MATERIAL__":true},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"geometry":"577F9C31-A036-43F5-B101-9D9BFDAFDFB3","material":"91C060A4-3941-4210-85F2-888C35B22948"}} -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Objects/CannonRaycastVehicle.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as THREE from 'three'; 3 | import * as CANNON from 'cannon-es'; 4 | import CannonBody from '../CannonBody.re'; 5 | import * as RogueCannon from '../../Lib/RogueCannon'; 6 | 7 | export default class CannonRaycastVehicle extends RE.Component { 8 | @RE.Prop("Object3D") chasis: THREE.Object3D; 9 | @RE.Prop("Number") mass = 500; 10 | @RE.Prop("Number") suspensionStiffness = 30; 11 | @RE.Prop("Number") suspensionRestLength = 0.1; 12 | @RE.Prop("Number") frictionSlip = 0.7; 13 | @RE.Prop("Number") dampingRelaxation: 2.3; 14 | @RE.Prop("Number") dampingCompression: 4.4; 15 | @RE.Prop("Number") maxSuspensionForce: 100000; 16 | @RE.Prop("Number") rollInfluence: 0.01; 17 | @RE.Prop("Number") maxSuspensionTravel = 0.2; 18 | @RE.Prop("Number") customSlidingRotationalSpeed = -30; 19 | @RE.Prop("Boolean") useCustomSlidingRotationalSpeed = true; 20 | 21 | vehicle: CANNON.RaycastVehicle; 22 | 23 | start() { 24 | if (!RogueCannon.getWorld()) return; 25 | 26 | let body = RE.getComponent(CannonBody, this.object3d); 27 | 28 | if (!body) { 29 | body = new CannonBody("CarBody", this.object3d); 30 | body.mass = this.mass; 31 | RE.addComponent(body); 32 | } 33 | 34 | if (!this.chasis) return; 35 | 36 | const chassisBody = RE.getComponent(CannonBody, this.chasis); 37 | 38 | if (!(chassisBody instanceof CannonBody)) return; 39 | 40 | this.vehicle = new CANNON.RaycastVehicle({ 41 | chassisBody: body.body, 42 | indexForwardAxis: 2, 43 | indexUpAxis: 1, 44 | indexRightAxis: 0, 45 | }); 46 | 47 | this.vehicle.addToWorld(RogueCannon.getWorld()); 48 | } 49 | } 50 | 51 | RE.registerComponent(CannonRaycastVehicle); 52 | -------------------------------------------------------------------------------- /Assets/Materials/metal_mat_msm.rogueMaterial: -------------------------------------------------------------------------------- 1 | {"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"geometries":[{"uuid":"14316639-739E-4A41-8A96-634BBA8107DB","type":"BufferGeometry","data":{"attributes":{}}}],"materials":[{"uuid":"821FA357-BAF5-4FE3-837B-CED50500B029","type":"MeshStandardMaterial","name":"metal_mat_msm","color":16777215,"roughness":0.5,"metalness":0,"emissive":0,"map":"77E0C83C-AE44-4504-AC09-C7DD8AD49945","normalMap":"56AD550F-D2AE-4843-B7D6-7B43705EEAA9","normalMapType":0,"normalScale":[1,1],"roughnessMap":"AFAAE389-483A-4096-B964-9D43B209E58F","envMapIntensity":1,"refractionRatio":0.98,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680,"userData":{"__ASSET__":"821FA357-BAF5-4FE3-837B-CED50500B029"},"fog":true,"blending":1,"side":0,"vertexColors":false,"opacity":1,"format":1023,"transparent":false,"blendSrc":204,"blendDst":205,"blendEquation":100,"clipIntersection":false,"clipShadows":false,"polygonOffset":false,"polygonOffsetFactor":0,"polygonOffsetUnits":0,"dithering":false,"alphaToCoverage":false,"premultipliedAlpha":false,"visible":true,"toneMapped":true,"version":0,"_alphaTest":0,"lightMapIntensity":1,"aoMapIntensity":1,"emissiveIntensity":1,"bumpScale":1,"displacementScale":1,"displacementBias":0,"wireframe":false,"wireframeLinewidth":1,"wireframeLinecap":"round","wireframeLinejoin":"round","flatShading":false}],"textures":["77E0C83C-AE44-4504-AC09-C7DD8AD49945","56AD550F-D2AE-4843-B7D6-7B43705EEAA9","AFAAE389-483A-4096-B964-9D43B209E58F"],"images":[],"object":{"uuid":"E7F668A5-9001-4AF8-9EF6-4B07AC20CCFF","type":"Mesh","userData":{"__IS_MATERIAL__":true},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"geometry":"14316639-739E-4A41-8A96-634BBA8107DB","material":"821FA357-BAF5-4FE3-837B-CED50500B029"}} -------------------------------------------------------------------------------- /_Rogue/Engine/Controller/ComponentsManager.d.ts: -------------------------------------------------------------------------------- 1 | import { Object3D, Scene } from 'three'; 2 | import Component from '../Model/Component'; 3 | export declare let components: { 4 | [objectId: string]: Component[]; 5 | }; 6 | export declare let editorComponents: { 7 | [objectId: string]: Component[]; 8 | }; 9 | export declare function getComponentPrototypes(): { 10 | [className: string]: typeof Component; 11 | }; 12 | export declare function clearComponents(): void; 13 | export declare function registerComponent(ComponentClass: new (...args: any[]) => T): void; 14 | export declare const initComponents: (scene: Scene, componentsToLoad?: Object | undefined) => void; 15 | export declare const initEditorComponents: (scene: Scene) => void; 16 | export declare function traverseComponents(fn: (component: Component, objectUUID: string, index: number) => void): void; 17 | export declare const loadComponents: (object: Object3D, objectComponents: Component[]) => void; 18 | export declare const setSerializedComponents: (componentsJSON: any) => void; 19 | export declare const serializeComponents: () => {}; 20 | export declare const addComponent: (component: Component) => void; 21 | export declare function copyObjectComponents(object: Object3D, target: Object3D): void; 22 | export declare const removeComponent: (component: Component) => boolean | undefined; 23 | export declare const removeComponents: (object3d: Object3D, recursive?: boolean | undefined) => void; 24 | export declare function getComponentByName(name: string, object3d?: Object3D): Component | undefined; 25 | export declare const getComponent: (ComponentClass: new (...args: any[]) => T, object3d?: Object3D | undefined) => T | undefined; 26 | export declare const getComponents: (ComponentClass: new (...args: any[]) => T) => T[]; 27 | export declare const getObjectComponents: (object3d: Object3D) => Component[]; 28 | -------------------------------------------------------------------------------- /Assets/Components/WebcamController.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import UiManager from './UiManager.re'; 3 | 4 | const { Prop } = RE; 5 | 6 | export default class WebcamController extends RE.Component { 7 | 8 | // External dependencies 9 | @Prop("String") videoFallback: string = ""; 10 | 11 | // Callback 12 | private onWebcamReadyCb: (() => void)[] = []; 13 | 14 | 15 | awake() { 16 | const uiManager = RE.getComponent(UiManager) as UiManager; 17 | // On Firefox we have to wait for the UI to be loaded to be able to access the video tag 18 | uiManager.onUILoaded(() => { 19 | this.setupWebcamTexture(); 20 | }) 21 | 22 | } 23 | 24 | setupWebcamTexture() { 25 | 26 | const video = document.getElementById('video') as HTMLVideoElement; 27 | 28 | if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { 29 | 30 | navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => { // If camera is OK: 31 | video.srcObject = stream; 32 | // Video is loaded and can be played 33 | video.addEventListener('loadeddata', () => { 34 | this.runEnabledCallbacks(); 35 | }, false); 36 | video.play(); 37 | 38 | }).catch((err) => { // If camera is not present, show video stream 39 | 40 | if (this.videoFallback != "") { 41 | video.src = this.videoFallback; 42 | video.crossOrigin = "anonymous"; 43 | video.load(); 44 | // Video is loaded and can be played 45 | video.addEventListener('loadeddata', () => { 46 | this.runEnabledCallbacks(); 47 | }, false); 48 | video.play(); 49 | } 50 | }); 51 | } 52 | 53 | 54 | } 55 | 56 | onWebcamReady(callback: () => void) { 57 | this.onWebcamReadyCb.push(callback); 58 | } 59 | 60 | private runEnabledCallbacks() { 61 | for (const callback of this.onWebcamReadyCb) { 62 | callback(); 63 | } 64 | } 65 | } 66 | 67 | RE.registerComponent(WebcamController); 68 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Shapes/CannonTrimesh.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as THREE from 'three'; 3 | import * as CANNON from 'cannon-es'; 4 | import CannonShape from './CannonShape'; 5 | 6 | export default class CannonTrimesh extends CannonShape { 7 | shape: CANNON.Trimesh; 8 | @RE.Prop("Vector3") sizeOffset: THREE.Vector3 = new THREE.Vector3(1, 1, 1); 9 | 10 | worldScale = new THREE.Vector3(); 11 | worldPos = new THREE.Vector3(); 12 | 13 | tmpVec0 = new CANNON.Vec3(); 14 | tmpVec1 = new CANNON.Vec3(); 15 | tmpVec2 = new CANNON.Vec3(); 16 | tmpQuat0 = new CANNON.Vec3(); 17 | 18 | createShape() { 19 | if (!(this.object3d instanceof THREE.Mesh)) return; 20 | 21 | this.object3d.updateWorldMatrix(true, true); 22 | 23 | this.object3d.getWorldScale(this.worldScale); 24 | this.object3d.getWorldPosition(this.worldPos); 25 | this.object3d.getWorldQuaternion(this.worldQuaternion); 26 | 27 | const mesh = this.object3d; 28 | let geometry = (mesh.geometry as THREE.BufferGeometry); 29 | 30 | geometry.computeBoundingSphere(); 31 | geometry.normalizeNormals(); 32 | 33 | if (geometry.index !== null) { 34 | const nonIndexedGeo = geometry.toNonIndexed(); 35 | geometry.copy(nonIndexedGeo); 36 | } 37 | 38 | const vertices = this.getVertices(geometry); 39 | 40 | if (!vertices.length) return; 41 | 42 | const indices = Object.keys(vertices).map(Number); 43 | this.shape = new CANNON.Trimesh(vertices as unknown as number[], indices); 44 | } 45 | 46 | getVertices (geometry: THREE.BufferGeometry) { 47 | const position = geometry.attributes.position; 48 | const vertices = new Float32Array(position.count * 3); 49 | for (let i = 0; i < position.count; i++) { 50 | vertices[i * 3] = position.getX(i) * this.worldScale.x; 51 | vertices[i * 3 + 1] = position.getY(i) * this.worldScale.y; 52 | vertices[i * 3 + 2] = position.getZ(i) * this.worldScale.z; 53 | } 54 | return vertices; 55 | } 56 | } 57 | 58 | RE.registerComponent(CannonTrimesh); 59 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Objects/CannonSpring.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as THREE from 'three'; 3 | import * as CANNON from 'cannon-es'; 4 | import CannonBody from '../CannonBody.re'; 5 | import * as RogueCannon from '../../Lib/RogueCannon'; 6 | 7 | export default class CannonSpring extends RE.Component { 8 | spring: CANNON.Spring; 9 | targetBody: CANNON.Body; 10 | 11 | @RE.Prop("Object3D") target: THREE.Object3D; 12 | @RE.Prop("Vector3") anchorA: THREE.Vector3 = new THREE.Vector3(); 13 | @RE.Prop("Vector3") anchorB: THREE.Vector3 = new THREE.Vector3(); 14 | @RE.Prop("Number") restLength: number = 0; 15 | @RE.Prop("Number") stiffness: number = 50; 16 | @RE.Prop("Number") damping: number = 1; 17 | 18 | start() { 19 | this.createSpring(); 20 | } 21 | 22 | private getCannonBodyComponent(object3d: THREE.Object3D): CannonBody { 23 | const cannonBody = RE.getComponent(CannonBody, object3d); 24 | 25 | if (!cannonBody) { 26 | throw "CannonSpring targets must have a Cannon Body Component" 27 | } 28 | 29 | return cannonBody; 30 | } 31 | 32 | applyForce = () => { 33 | this.spring.applyForce(); 34 | } 35 | 36 | private createSpring() { 37 | if (!this.target) throw "CannonSpring requires a target"; 38 | 39 | const bodyA = this.getCannonBodyComponent(this.object3d).body; 40 | const bodyB = this.getCannonBodyComponent(this.target).body; 41 | 42 | this.spring = new CANNON.Spring(bodyA, bodyB, { 43 | localAnchorA: new CANNON.Vec3(this.anchorA.x, this.anchorA.y, this.anchorA.z), 44 | localAnchorB: new CANNON.Vec3(this.anchorB.x, this.anchorB.y, this.anchorB.z), 45 | restLength: this.restLength, 46 | stiffness: this.stiffness, 47 | damping: this.damping, 48 | }); 49 | 50 | RogueCannon.getWorld().addEventListener('postStep', this.applyForce) 51 | } 52 | 53 | onBeforeRemoved() { 54 | RogueCannon.getWorld().removeEventListener('postStep', this.applyForce); 55 | } 56 | } 57 | 58 | RE.registerComponent(CannonSpring); 59 | -------------------------------------------------------------------------------- /_Rogue/Engine/Controller/Events.d.ts: -------------------------------------------------------------------------------- 1 | import { Object3D } from 'three'; 2 | import Component from '../Model/Component'; 3 | import SceneController from '../Model/SceneController'; 4 | export declare function onObjectAdded(callback: (object: Object3D, target: Object3D) => void): { 5 | stop: () => void; 6 | }; 7 | export declare function onObjectRemoved(callback: (object: Object3D, target: Object3D) => void): { 8 | stop: () => void; 9 | }; 10 | export declare function objectAdded(object: Object3D, target: Object3D): void; 11 | export declare function objectRemoved(object: Object3D, target: Object3D): void; 12 | export declare function onComponentAdded(callback: (component: Component, target: Object3D) => void): { 13 | stop: () => void; 14 | }; 15 | export declare function onComponentLoaded(callback: (component: Component, target: Object3D) => void): { 16 | stop: () => void; 17 | }; 18 | export declare function onComponentRemoved(callback: (component: Component, target: Object3D) => void): { 19 | stop: () => void; 20 | }; 21 | export declare function componentAdded(component: Component, target: Object3D): void; 22 | export declare function componentLoaded(component: Component, target: Object3D): void; 23 | export declare function componentRemoved(component: Component, target: Object3D): void; 24 | export declare function onBeforeUpdate(callback: (sceneController: SceneController) => void): { 25 | stop: () => void; 26 | }; 27 | export declare function onUpdate(callback: (sceneController: SceneController) => void): { 28 | stop: () => void; 29 | }; 30 | export declare function onAfterUpdate(callback: (sceneController: SceneController) => void): { 31 | stop: () => void; 32 | }; 33 | export declare function onNextFrame(callback: (sceneController: SceneController) => void): void; 34 | export declare function runBeforeUpdate(sceneController: SceneController): void; 35 | export declare function runUpdate(sceneController: SceneController): void; 36 | export declare function runAfterUpdate(sceneController: SceneController): void; 37 | export declare function runNextFrame(sceneController: SceneController): void; 38 | -------------------------------------------------------------------------------- /Assets/Components/Bomb.re.ts: -------------------------------------------------------------------------------- 1 | import CannonBody from 'Assets/rogue_packages/rogue-cannon/Components/CannonBody.re'; 2 | import * as RE from 'rogue-engine'; 3 | import { Object3D } from 'three'; 4 | import BombTimer from './BombTimer.re'; 5 | import Explodable from './Explodable.re'; 6 | import ProjectileObject from './ProjectileObject.re'; 7 | 8 | 9 | 10 | const { Prop } = RE; 11 | 12 | export default class Bomb extends RE.Component { 13 | 14 | // External dependencies 15 | @Prop("Prefab") bombTimerPrefab: RE.Prefab; 16 | @Prop("Number") explosionForce: number = 100; 17 | 18 | // Private variables 19 | private bombBody: CannonBody; 20 | private bombTimer: Object3D; 21 | private bombTimerController: BombTimer; 22 | private projectileController: ProjectileObject; 23 | 24 | 25 | awake() { 26 | this.bombBody = RE.getComponent(CannonBody, this.object3d) as CannonBody; 27 | this.projectileController = RE.getComponent(ProjectileObject, this.object3d) as ProjectileObject; 28 | } 29 | 30 | start() { 31 | 32 | // Instantiate bomb timer 33 | this.bombTimer = this.bombTimerPrefab.instantiate(); 34 | this.bombTimerController = RE.getComponent(BombTimer, this.bombTimer) as BombTimer; 35 | 36 | // Callback when bomb timer ends: 37 | this.bombTimerController.onTimerEnds(() => { 38 | // All objects that will react to the explosion belong to the Explodable class 39 | Explodable.addForce(this.bombBody.body.position, this.explosionForce); 40 | // Remove bomb and timer 41 | this.object3d.parent?.remove(this.object3d); 42 | this.bombTimer.parent?.remove(this.bombTimer); 43 | }) 44 | 45 | // Callback when projectile in launched 46 | this.projectileController.onLaunch(() => { 47 | // Start bomb timer 48 | this.bombTimerController.startCount(); 49 | }) 50 | 51 | } 52 | 53 | update() { 54 | 55 | // Bombtimer is not a bomb's child to prevent its rotation... However, we have to synchronize the position. 56 | if (this.bombTimer) 57 | this.bombTimer.position.copy(this.object3d.position); 58 | 59 | } 60 | 61 | 62 | 63 | } 64 | 65 | RE.registerComponent(Bomb); 66 | -------------------------------------------------------------------------------- /_Rogue/Engine/Model/Component.d.ts: -------------------------------------------------------------------------------- 1 | import Lifecycle from './Lifecycle'; 2 | import { Object3D } from 'three'; 3 | export default class Component extends Lifecycle { 4 | private _name; 5 | private _object3d; 6 | private _isReady; 7 | uuid: string; 8 | interface: ComponentInterface; 9 | enabled: boolean; 10 | constructor(name: string, object3d: Object3D); 11 | /** 12 | * The name by which to search a component. 13 | * 14 | * For best results, make sure you don't 15 | * repeat them within the same Object3D. 16 | */ 17 | get name(): string; 18 | set name(newName: string); 19 | /** 20 | * Reference to the Object3D asociated to this component. 21 | * 22 | * Caution!! It can only be set internally by the engine 23 | */ 24 | get object3d(): Object3D; 25 | /** 26 | * The 'ready' status of the component. This property will 27 | * be true once all the assets referenced in the 'interface' 28 | * of this component are loaded. 29 | */ 30 | get isReady(): boolean; 31 | toJSON(): { 32 | name: string; 33 | componentPrototypeName: string; 34 | interface: ComponentInterface; 35 | interfaceRefs: { 36 | [propName: string]: any; 37 | }; 38 | }; 39 | fromJSON(json: any): void; 40 | private serializePropRef; 41 | private serializeInterfaceRefs; 42 | private loadInterfaceRefs; 43 | private readyNotifier; 44 | loadPropRef(interfaceRefs: Object, key: string | number, object: Object, readyProps: Object, propGI: string, actualProp?: string): void; 45 | awake(): void; 46 | start(): void; 47 | beforeUpdate(): void; 48 | update(): void; 49 | afterUpdate(): void; 50 | onBeforeRemoved(): void; 51 | onRemoved(): void; 52 | onBeforeObjetRemoved(): void; 53 | onObjectRemoved(): void; 54 | } 55 | export declare type ComponentInterface = { 56 | [propName: string]: 'String' | 'Number' | 'Boolean' | 'Select' | 'Vector2' | 'Vector3' | 'Object3D' | 'Prefab' | 'Texture' | 'Material' | 'Component' | 'Audio' | 'Color' | 'PositionalAudio'; 57 | }; 58 | -------------------------------------------------------------------------------- /_Rogue/Engine/Controller/Input/Mouse.d.ts: -------------------------------------------------------------------------------- 1 | import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls'; 2 | export declare class Mouse { 3 | private _x; 4 | private _y; 5 | private _movementX; 6 | private _movementY; 7 | private _isMoving; 8 | private _mouseStopTimer; 9 | private _isLeftButtonDown; 10 | private _isLeftButtonPressed; 11 | private _isLeftButtonUp; 12 | private _isRightButtonDown; 13 | private _isRightButtonPressed; 14 | private _isRightButtonUp; 15 | private _isMidButtonDown; 16 | private _isMidButtonPressed; 17 | private _isMidButtonUp; 18 | private _buttonDown; 19 | private _buttonPressed; 20 | private _buttonUp; 21 | private _wheelY; 22 | private _wheelX; 23 | private _wheelTimeout; 24 | private _enabled; 25 | private _pointerLock; 26 | get pointerLock(): PointerLockControls; 27 | get x(): number; 28 | get y(): number; 29 | get movementX(): number; 30 | get movementY(): number; 31 | get isMoving(): boolean; 32 | get isLeftButtonDown(): boolean; 33 | get isLeftButtonPressed(): boolean; 34 | get isLeftButtonUp(): boolean; 35 | get isRightButtonDown(): boolean; 36 | get isRightButtonPressed(): boolean; 37 | get isRightButtonUp(): boolean; 38 | get isMidButtonDown(): boolean; 39 | get isMidButtonPressed(): boolean; 40 | get isMidButtonUp(): boolean; 41 | get buttonDown(): number | undefined; 42 | get buttonPressed(): number | undefined; 43 | get buttonUp(): number | undefined; 44 | get wheelY(): number; 45 | get wheelX(): number; 46 | get enabled(): boolean; 47 | set enabled(value: boolean); 48 | init(): void; 49 | getButtonDown(button: number): boolean; 50 | getButtonPressed(button: number): boolean; 51 | getButtonUp(button: number): boolean; 52 | lock(): void; 53 | private unlockFunction; 54 | unlock(): void; 55 | private onMouseMove; 56 | private setMouseMovement; 57 | private resetMouseMovement; 58 | private onMouseDown; 59 | private onMouseUp; 60 | private onWheelMove; 61 | } 62 | -------------------------------------------------------------------------------- /Assets/Prefabs/BombTimer.roguePrefab: -------------------------------------------------------------------------------- 1 | {"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"materials":[{"uuid":"041432C6-9841-493C-A6B0-1AA6E9338247","type":"MeshStandardMaterial","color":16777215,"roughness":1,"metalness":0,"emissive":0,"envMapIntensity":1,"refractionRatio":0.98,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680},{"uuid":"23D4C476-A4E9-436B-86DE-5A2F31C138B2","type":"MeshStandardMaterial","color":16777215,"roughness":1,"metalness":0,"emissive":0,"envMapIntensity":1,"refractionRatio":0.98,"depthFunc":3,"depthTest":true,"depthWrite":true,"colorWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680}],"object":{"uuid":"F444618A-066C-4BFD-ADBC-82DFEF229C09","type":"Object3D","name":"BombTimer","userData":{"__IS_ADDING__":false,"__REF__":"B50E53B6-8C8C-4378-A0C0-4C351725A33B","__ASSET__":"F444618A-066C-4BFD-ADBC-82DFEF229C09","components":[{"uuid":"765581c0-2d72-41e5-bcba-6dd3650059d2","name":"BombTimer","componentPrototypeName":"BombTimer","interface":{"timerProgress":"Object3D","duration":"Number"},"interfaceRefs":{"timerProgress":"76ADEA4F-CF28-4D9B-BC91-12CB78D60C1F","duration":3},"enabled":true}]},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,-5.872399798458792,0,0,1],"children":[{"uuid":"7A54EC46-5383-401B-A155-99D7CBDC8371","type":"Sprite","name":"TimerBar","userData":{"__IS_ADDING__":false,"__MATERIAL__":"9FFAD76A-606D-4CE3-8F03-A92E0B6ABE1F","__REF__":"A71685E6-0456-47E3-874A-1569B068C402","components":[]},"layers":1,"matrix":[0.38375358453393343,0,0,0,0,0.035145367939049973,0,0,0,0,1,0,0,0.24800282118899342,0,1],"material":"041432C6-9841-493C-A6B0-1AA6E9338247","children":[{"uuid":"FDD86B68-398F-4288-A8F6-FC8216BC777D","type":"Sprite","name":"TimerProgress","userData":{"__IS_ADDING__":false,"__MATERIAL__":"05AA2CF3-42AF-4F7B-B197-B76DC747321C","__REF__":"76ADEA4F-CF28-4D9B-BC91-12CB78D60C1F","components":[]},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"material":"23D4C476-A4E9-436B-86DE-5A2F31C138B2"}]}]}} -------------------------------------------------------------------------------- /_Rogue/Engine/Controller/App.d.ts: -------------------------------------------------------------------------------- 1 | import { Scene, Object3D } from 'three'; 2 | import SceneController from '../Model/SceneController'; 3 | export declare class App { 4 | private static _title; 5 | private static _settings; 6 | private static _currentScene; 7 | private static _activeCamera; 8 | private static _scenes; 9 | private static _sceneController; 10 | private static _lanIP; 11 | private constructor(); 12 | static get activeCamera(): string; 13 | static set activeCamera(cameraId: string); 14 | static get settings(): any; 15 | static get title(): string; 16 | static set title(title: string); 17 | static get currentScene(): Scene; 18 | static set currentScene(scene: Scene); 19 | static get scenes(): { 20 | name: string; 21 | uuid: string; 22 | }[]; 23 | static get sceneController(): SceneController; 24 | static set sceneController(value: SceneController); 25 | static get lanIP(): string; 26 | static toJSON(assetPaths: { 27 | [uuid: string]: string; 28 | }): { 29 | title: string; 30 | scenes: { 31 | name: string; 32 | uuid: string; 33 | }[]; 34 | lanIP: string; 35 | assetPaths: { 36 | [uuid: string]: string; 37 | }; 38 | }; 39 | static fromJSON(json: { 40 | title: string; 41 | scenes: { 42 | name: string; 43 | uuid: string; 44 | }[]; 45 | assetPaths: { 46 | [uuid: string]: string; 47 | }; 48 | lanIP?: string; 49 | }): void; 50 | static play(config: { 51 | title: string; 52 | scenes: { 53 | name: string; 54 | uuid: string; 55 | }[]; 56 | assetPaths: { 57 | [uuid: string]: string; 58 | }; 59 | }): void; 60 | static loadScene(name: string | number): Promise; 61 | private static loadSceneFunc; 62 | static clone(object: Object3D, parent?: Object3D): Object3D; 63 | private static loadComponentsRecursive; 64 | private static loadAudioListeners; 65 | } 66 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Rogue LAN Player 9 | 10 | 22 | 23 | 24 | 27 |
28 | 29 | 30 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /_Rogue/Engine/Model/SceneController.d.ts: -------------------------------------------------------------------------------- 1 | import { WebGLRenderer, Scene, Object3D, Camera, Clock } from 'three'; 2 | import Lifecycle from './Lifecycle'; 3 | import Component from '../Model/Component'; 4 | export default abstract class SceneController extends Lifecycle { 5 | renderFunc: () => void; 6 | private _clock; 7 | private _onPlayCallbacks; 8 | private _onStopCallbacks; 9 | private _throttledAdjustCameraAndRenderer; 10 | protected _scene: Scene; 11 | protected _containerId: string; 12 | protected _rogueDOMContainer: HTMLElement; 13 | protected _camera: Camera; 14 | protected _renderer: WebGLRenderer; 15 | protected _isRunning: boolean; 16 | protected _isPaused: boolean; 17 | protected _width: number; 18 | protected _height: number; 19 | protected _isOffscreen: boolean; 20 | protected _request: number; 21 | protected _stop: () => void; 22 | private _deltaTime; 23 | private _pageVisibilityHandler; 24 | constructor(); 25 | get defaultRenderFunc(): () => void; 26 | get deltaTime(): number; 27 | get height(): number; 28 | get width(): number; 29 | get containerId(): string; 30 | get camera(): Camera; 31 | set camera(value: Camera); 32 | get scene(): Scene; 33 | get renderer(): WebGLRenderer; 34 | get isRunning(): boolean; 35 | get isPaused(): boolean; 36 | get rogueDOMContainer(): HTMLElement; 37 | get clock(): Clock; 38 | onPlay(callback: () => any): { 39 | stop: () => void; 40 | }; 41 | onStop(callback: () => any): { 42 | stop: () => void; 43 | }; 44 | private loadMaterials; 45 | play(scene: Scene, renderer?: WebGLRenderer, componentsToLoad?: any): void; 46 | stop(): void; 47 | private updateEvensHandler; 48 | pause(): void; 49 | resume(): void; 50 | togglePause(): void; 51 | protected traverseObject3d(object: Object3D, callback: (object3d: Object3D) => void): void; 52 | protected abstract traverseSceneComponents(callback: (component: Component) => void): void; 53 | protected awake(): void; 54 | protected start(): void; 55 | protected beforeUpdate(): void; 56 | protected update(): void; 57 | protected afterUpdate(): void; 58 | protected startRenderer(renderer?: WebGLRenderer): void; 59 | setSceneDimensions(width: number, height: number): void; 60 | private setCameraDimensions; 61 | protected adjustCameraAndRenderer(force?: boolean): void; 62 | protected beginUpdateCycle(): void; 63 | } 64 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Controllers/CannonSimpleCharacterController.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as CANNON from 'cannon-es'; 3 | import CannonBody from '../CannonBody.re'; 4 | 5 | export default class CannonSimpleCharacterController extends RE.Component { 6 | @RE.Prop("Number") fwdSpeed = 3; 7 | @RE.Prop("Number") jumpSpeed = 5; 8 | 9 | rigidbody: CannonBody | undefined; 10 | canJump = false; 11 | 12 | private contactNormal = new CANNON.Vec3(); 13 | private upAxis = new CANNON.Vec3(0, 1, 0); 14 | 15 | private inputAngularVelocity = new CANNON.Vec3(); 16 | private inputVelocity = new CANNON.Vec3(); 17 | 18 | awake() { 19 | this.rigidbody = RE.getComponent(CannonBody, this.object3d); 20 | // this.stick = RE.getComponent(TouchStick, this.object3d); 21 | this.rigidbody?.onCollide(event => { 22 | event.contact.ni.negate(this.contactNormal); 23 | 24 | if (this.contactNormal.dot(this.upAxis) > 0.5) { 25 | this.canJump = true 26 | } 27 | }); 28 | 29 | if (!this.rigidbody) return; 30 | 31 | this.rigidbody.body.type = CANNON.Body.DYNAMIC; 32 | } 33 | 34 | update() { 35 | if (!this.rigidbody) return; 36 | 37 | this.inputVelocity.setZero(); 38 | 39 | if (RE.Input.keyboard.getKeyPressed("KeyW")) { 40 | this.inputVelocity.z = -1; 41 | } 42 | else if (RE.Input.keyboard.getKeyPressed("KeyS")) { 43 | this.inputVelocity.z = 1; 44 | } 45 | else { 46 | this.inputVelocity.z = 0; 47 | } 48 | 49 | if (RE.Input.keyboard.getKeyPressed("KeyA")) { 50 | this.inputVelocity.x = -1; 51 | } 52 | else if (RE.Input.keyboard.getKeyPressed("KeyD")) { 53 | this.inputVelocity.x = 1; 54 | } 55 | else { 56 | this.inputVelocity.x = 0; 57 | } 58 | 59 | this.inputVelocity.normalize(); 60 | this.inputVelocity.scale(this.fwdSpeed, this.inputVelocity); 61 | 62 | if (this.canJump && RE.Input.keyboard.getKeyDown("Space")) { 63 | this.rigidbody.body.velocity.y = this.jumpSpeed; 64 | this.canJump = false; 65 | } 66 | 67 | this.rigidbody.body.angularVelocity.y = this.inputAngularVelocity.y; 68 | 69 | this.rigidbody.body.vectorToWorldFrame(this.inputVelocity, this.inputVelocity); 70 | 71 | if (!this.canJump) return; 72 | 73 | this.rigidbody.body.velocity.x = this.inputVelocity.x; 74 | this.rigidbody.body.velocity.z = this.inputVelocity.z; 75 | } 76 | } 77 | 78 | RE.registerComponent(CannonSimpleCharacterController); 79 | -------------------------------------------------------------------------------- /Assets/Components/Explodable.re.ts: -------------------------------------------------------------------------------- 1 | import CannonBody from 'Assets/rogue_packages/rogue-cannon/Components/CannonBody.re'; 2 | import { Vec3 } from 'cannon-es'; 3 | import * as RE from 'rogue-engine'; 4 | 5 | const { Prop } = RE; 6 | 7 | export default class Explodable extends RE.Component { 8 | 9 | // External dependencies 10 | @Prop("Boolean") enableMassWhenExplodes: Boolean = true; 11 | 12 | // Private variables 13 | private cannonBody: CannonBody; 14 | private _mass: number; 15 | 16 | // Static variables 17 | static layerCollision: number = 3; 18 | static explodables: Explodable[] = []; 19 | 20 | awake() { 21 | this.cannonBody = RE.getComponent(CannonBody, this.object3d) as CannonBody; 22 | // Not related to an explodable object, but when mass is applied to an object on start sometimes it bounces weirdly. 23 | // We cancel the mass and apply it with a timeout, it is not very nice, but it works for testing. 24 | // TODO: I guess we should have to wait for a Cannon or scene "OnReady-like" event to do this. 25 | this._mass = this.cannonBody.mass; 26 | this.cannonBody.mass = 0; 27 | } 28 | 29 | start() { 30 | 31 | // Add this component in explodables array. Later (in static addForce method) we can iterate the static array to react to the explosion 32 | Explodable.explodables.push(this); 33 | 34 | if (!this.enableMassWhenExplodes) { 35 | setTimeout(() => { 36 | this.enableMass(); 37 | }, 2500); 38 | } 39 | } 40 | 41 | enableMass() { 42 | this.cannonBody.mass = this._mass; 43 | } 44 | 45 | addForce(vector: Vec3, force: number) { 46 | 47 | // Get the direction of the projection from vector force 48 | const impulseDirection = this.cannonBody.body.position.vsub(vector); 49 | // Get the impulse force taking into account the distance from explosion 50 | const distanceFromForceVector = this.cannonBody.body.position.distanceTo(vector); 51 | // The greater the (square of) distance, the smaller the reaction 52 | const scaleImpulse = 1 / (distanceFromForceVector * distanceFromForceVector); 53 | // Scale impulseDirection 54 | const vImpulse = impulseDirection.scale(scaleImpulse).scale(force); 55 | 56 | this.enableMassWhenExplodes && this.enableMass(); 57 | 58 | this.cannonBody.body.applyForce(vImpulse); 59 | } 60 | 61 | static addForce = (vector: Vec3, force: number) => { 62 | 63 | for (let i = 0, l = Explodable.explodables.length; i < l; i++) { 64 | Explodable.explodables[i].addForce(vector, force); 65 | } 66 | }; 67 | 68 | } 69 | 70 | RE.registerComponent(Explodable); 71 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Shapes/CannonShape.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as CANNON from 'cannon-es'; 3 | import * as THREE from 'three'; 4 | import CannonBody from '../CannonBody.re'; 5 | 6 | export default class CannonShape extends RE.Component { 7 | shape: CANNON.Shape; 8 | body: CANNON.Body | undefined; 9 | bodyComponent: CannonBody | undefined; 10 | 11 | localPos: THREE.Vector3 = new THREE.Vector3(); 12 | worldPos = new THREE.Vector3(); 13 | 14 | localRot = new THREE.Quaternion(); 15 | worldQuaternion = new THREE.Quaternion(); 16 | 17 | private matrixA = new THREE.Matrix4(); 18 | private matrixB = new THREE.Matrix4(); 19 | private matrixC = new THREE.Matrix4(); 20 | 21 | awake() { 22 | this.createShape(); 23 | } 24 | 25 | start() { 26 | if (!this.shape) return; 27 | 28 | this.bodyComponent = this.getBodyComponent(this.object3d); 29 | 30 | if (!this.bodyComponent) return; 31 | 32 | this.body = this.bodyComponent.body; 33 | 34 | const bodyIsShape = this.object3d === this.bodyComponent.object3d; 35 | 36 | this.object3d.getWorldPosition(this.worldPos); 37 | this.localPos.copy(this.worldPos); 38 | this.bodyComponent.object3d.updateWorldMatrix(true, true); 39 | this.bodyComponent.object3d.worldToLocal(this.localPos); 40 | 41 | let position = new CANNON.Vec3( 42 | this.localPos.x, 43 | this.localPos.y, 44 | this.localPos.z, 45 | ); 46 | 47 | this.object3d.updateWorldMatrix(true, true); 48 | this.object3d.getWorldQuaternion(this.worldQuaternion); 49 | 50 | this.matrixA.makeRotationFromQuaternion(this.worldQuaternion); 51 | this.object3d.updateWorldMatrix(true, true); 52 | this.matrixB.copy(this.bodyComponent.object3d.matrixWorld).invert(); 53 | this.matrixC.extractRotation(this.matrixB); 54 | this.matrixA.premultiply(this.matrixC); 55 | this.localRot.setFromRotationMatrix(this.matrixA); 56 | 57 | let rotation = new CANNON.Quaternion( 58 | this.localRot.x, 59 | this.localRot.y, 60 | this.localRot.z, 61 | this.localRot.w, 62 | ); 63 | 64 | if (bodyIsShape) { 65 | this.body.addShape(this.shape); 66 | } else { 67 | this.body.addShape(this.shape, position, rotation); 68 | } 69 | } 70 | 71 | private getBodyComponent(object3d: THREE.Object3D): CannonBody | undefined { 72 | const bodyComponent = RE.getComponent(CannonBody, object3d); 73 | 74 | if (bodyComponent) { 75 | return bodyComponent; 76 | } 77 | 78 | if (!object3d.parent) return; 79 | 80 | return this.getBodyComponent(object3d.parent as THREE.Object3D); 81 | } 82 | 83 | protected createShape(): void {}; 84 | } 85 | -------------------------------------------------------------------------------- /Assets/Components/BasketballController.re.ts: -------------------------------------------------------------------------------- 1 | import CannonBody from 'Assets/rogue_packages/rogue-cannon/Components/CannonBody.re'; 2 | import { Vec3 } from 'cannon-es'; 3 | import * as RE from 'rogue-engine'; 4 | import { MathUtils, Vector3 } from 'three'; 5 | import ProjectileObject from './ProjectileObject.re'; 6 | 7 | const { Prop } = RE; 8 | 9 | export default class BasketballController extends RE.Component { 10 | 11 | // External dependencies 12 | @Prop("Vector3") maxBoundaries: Vector3; 13 | @Prop("Vector3") minBoundaries: Vector3; 14 | @Prop("Vector3") maxInitPosition: Vector3; 15 | @Prop("Vector3") minInitPosition: Vector3; 16 | 17 | private cannonBody: CannonBody; 18 | private projectileController: ProjectileObject; 19 | private isOutOfRange: Boolean = false; 20 | 21 | 22 | awake() { 23 | this.cannonBody = RE.getComponent(CannonBody, this.object3d) as CannonBody; 24 | this.projectileController = RE.getComponent(ProjectileObject, this.object3d) as ProjectileObject; 25 | } 26 | 27 | start() { 28 | 29 | } 30 | 31 | isOutOfBoundaries() { 32 | 33 | const position = this.cannonBody.body.position; 34 | 35 | // Maybe there is a wonderful Vector3 method to check if one coordinate of a vector exceeds a value without having to do this mess? 36 | return (position.x > this.maxBoundaries.x || position.x < this.minBoundaries.x || 37 | position.y > this.maxBoundaries.y || position.y < this.minBoundaries.y || 38 | position.z > this.maxBoundaries.z || position.z < this.minBoundaries.z); 39 | } 40 | 41 | resetPosition() { 42 | // Disable projectile mass: 43 | this.projectileController.setMassEnabled(false); 44 | 45 | // Reset position: 46 | this.cannonBody.body.velocity.setZero(); 47 | const newPos = this.getNewPosition(); 48 | this.cannonBody.body.position = newPos; 49 | 50 | // Reset rotation, from: https://github.com/schteppe/cannon.js/issues/215 51 | this.cannonBody.body.angularVelocity.setZero(); 52 | this.cannonBody.body.quaternion.set(0, 0, 0, 1); 53 | this.cannonBody.body.initQuaternion.set(0, 0, 0, 1); 54 | this.cannonBody.body.previousQuaternion.set(0, 0, 0, 1); 55 | this.cannonBody.body.interpolatedQuaternion.set(0, 0, 0, 1); 56 | 57 | // Projectile object can be dragged again: 58 | this.projectileController.isDragEnabled = true; 59 | 60 | // Enable check ball position again 61 | this.isOutOfRange = false; 62 | } 63 | 64 | getNewPosition(): Vec3 { 65 | const newX = MathUtils.randFloat(this.minInitPosition.x, this.maxInitPosition.x); 66 | const newY = MathUtils.randFloat(this.minInitPosition.y, this.maxInitPosition.y); 67 | const newZ = MathUtils.randFloat(this.minInitPosition.z, this.maxInitPosition.z); 68 | 69 | return new Vec3(newX, newY, newZ); 70 | } 71 | 72 | update() { 73 | 74 | if (this.isOutOfBoundaries() && !this.isOutOfRange) { 75 | 76 | this.isOutOfRange = true; 77 | 78 | setTimeout(() => { 79 | this.resetPosition(); 80 | }, 1000); 81 | 82 | } 83 | 84 | } 85 | } 86 | 87 | RE.registerComponent(BasketballController); 88 | -------------------------------------------------------------------------------- /_Rogue/Engine/Model/Skybox.d.ts: -------------------------------------------------------------------------------- 1 | import { Mesh, Texture } from "three"; 2 | declare class SkyboxClass { 3 | private _enabled; 4 | private _mode; 5 | private _sky; 6 | private _cubemapSky; 7 | private _directionalLight; 8 | private _showSun; 9 | private _inclination; 10 | private _azimuth; 11 | private _sunSphere; 12 | private _serializedSkybox; 13 | private _onUpdate; 14 | private _onStop; 15 | private _onPlay; 16 | private _cubemapTop; 17 | private _cubemapBottom; 18 | private _cubemapFront; 19 | private _cubemapBack; 20 | private _cubemapRight; 21 | private _cubemapLeft; 22 | private _cubeTexture; 23 | private _layers; 24 | sunSpeed: number; 25 | get layers(): number; 26 | set layers(layers: number); 27 | get sky(): any; 28 | get cubemapSky(): Mesh; 29 | get enabled(): boolean; 30 | set enabled(value: boolean); 31 | get mode(): 'procedural' | 'cubemap' | '360'; 32 | set mode(value: 'procedural' | 'cubemap' | '360'); 33 | get cubemapTop(): Texture; 34 | set cubemapTop(value: Texture); 35 | get cubemapBottom(): Texture; 36 | set cubemapBottom(value: Texture); 37 | get cubemapFront(): Texture; 38 | set cubemapFront(value: Texture); 39 | get cubemapBack(): Texture; 40 | set cubemapBack(value: Texture); 41 | get cubemapRight(): Texture; 42 | set cubemapRight(value: Texture); 43 | get cubemapLeft(): Texture; 44 | set cubemapLeft(value: Texture); 45 | get mieDirectionalG(): number; 46 | set mieDirectionalG(value: number); 47 | get mieCoefficient(): number; 48 | set mieCoefficient(value: number); 49 | get turbidity(): number; 50 | set turbidity(value: number); 51 | get rayleigh(): number; 52 | set rayleigh(value: number); 53 | get luminance(): number; 54 | set luminance(value: number); 55 | get inclination(): number; 56 | set inclination(value: number); 57 | get azimuth(): number; 58 | set azimuth(value: number); 59 | get showSun(): boolean; 60 | set showSun(value: boolean); 61 | init(json?: SkyboxSerialization): void; 62 | private initProceduralSkybox; 63 | private initCubemapSkybox; 64 | toJSON(): SkyboxSerialization; 65 | fromJSON(json: SkyboxSerialization): void; 66 | private initWithDefaultValues; 67 | private getDefaultJSON; 68 | private setSunPosition; 69 | } 70 | export declare let Skybox: SkyboxClass; 71 | export declare type SkyboxSerialization = { 72 | _enabled: boolean; 73 | _mode: 'procedural' | 'cubemap' | '360'; 74 | layers: number; 75 | _showSun?: boolean; 76 | inclination?: number; 77 | azimuth?: number; 78 | mieDirectionalG?: number; 79 | mieCoefficient?: number; 80 | turbidity?: number; 81 | rayleigh?: number; 82 | luminance?: number; 83 | _sunSpeed?: number; 84 | _cubemapTop?: Texture | undefined; 85 | _cubemapBottom?: Texture | undefined; 86 | _cubemapFront?: Texture | undefined; 87 | _cubemapBack?: Texture | undefined; 88 | _cubemapRight?: Texture | undefined; 89 | _cubemapLeft?: Texture | undefined; 90 | }; 91 | export {}; 92 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Objects/CannonWheel.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as THREE from 'three'; 3 | import * as CANNON from 'cannon-es'; 4 | import CannonRaycastVehicle from './CannonRaycastVehicle.re'; 5 | import * as RogueCannon from '../../Lib/RogueCannon'; 6 | 7 | export default class CannonWheel extends RE.Component { 8 | @RE.Prop("Object3D") wheel: THREE.Object3D; 9 | 10 | connectionPoint = new THREE.Vector3(0, 0, 0); 11 | raycastVehicle: CannonRaycastVehicle; 12 | wheelInfo: CANNON.WheelInfo; 13 | 14 | private matrixA = new THREE.Matrix4(); 15 | private matrixB = new THREE.Matrix4(); 16 | private matrixC = new THREE.Matrix4(); 17 | 18 | start() { 19 | this.raycastVehicle = RE.getComponent(CannonRaycastVehicle, this.object3d) as CannonRaycastVehicle; 20 | 21 | if (!(this.raycastVehicle instanceof CannonRaycastVehicle)) return; 22 | 23 | let radius = 0.3; 24 | 25 | if (this.wheel) { 26 | this.connectionPoint.copy(this.wheel.position); 27 | 28 | const bbox = new THREE.Box3().setFromObject(this.wheel); 29 | radius = bbox.max.x - bbox.min.x; 30 | } 31 | 32 | this.wheelInfo = new CANNON.WheelInfo({ 33 | radius, 34 | directionLocal: new CANNON.Vec3(0, -1, 0), 35 | suspensionStiffness: this.raycastVehicle.suspensionStiffness, 36 | suspensionRestLength: this.raycastVehicle.suspensionRestLength, 37 | frictionSlip: this.raycastVehicle.frictionSlip, 38 | dampingRelaxation: this.raycastVehicle.dampingRelaxation, 39 | dampingCompression: this.raycastVehicle.dampingCompression, 40 | maxSuspensionForce: this.raycastVehicle.maxSuspensionForce, 41 | rollInfluence: this.raycastVehicle.rollInfluence, 42 | axleLocal: new CANNON.Vec3(-1, 0, 0), 43 | chassisConnectionPointLocal: new CANNON.Vec3(this.connectionPoint.x, this.connectionPoint.y, this.connectionPoint.z), 44 | maxSuspensionTravel: this.raycastVehicle.maxSuspensionTravel, 45 | customSlidingRotationalSpeed: this.raycastVehicle.customSlidingRotationalSpeed, 46 | useCustomSlidingRotationalSpeed: this.raycastVehicle.useCustomSlidingRotationalSpeed, 47 | }); 48 | 49 | this.raycastVehicle.vehicle.wheelInfos.push(this.wheelInfo); 50 | 51 | if (!this.wheel) return; 52 | 53 | if (!RogueCannon.getWorld()) return; 54 | 55 | RogueCannon.getWorld().addEventListener('postStep', this.postStep); 56 | } 57 | 58 | postStep = () => { 59 | if (!this.wheel) return; 60 | 61 | const wheel = this.wheelInfo; 62 | 63 | if (!wheel) return; 64 | 65 | const pos = wheel.worldTransform.position; 66 | const rot = wheel.worldTransform.quaternion; 67 | 68 | this.wheel.position.set(pos.x, pos.y, pos.z); 69 | this.wheel.parent?.worldToLocal(this.wheel.position); 70 | 71 | this.wheel.quaternion.set(rot.x, rot.y, rot.z, rot.w); 72 | 73 | this.matrixA.makeRotationFromQuaternion(this.wheel.quaternion); 74 | this.wheel.updateMatrixWorld(); 75 | this.matrixB.copy((this.wheel.parent as THREE.Object3D).matrixWorld).invert(); 76 | this.matrixC.extractRotation(this.matrixB); 77 | this.matrixA.premultiply(this.matrixC); 78 | this.wheel.quaternion.setFromRotationMatrix(this.matrixA); 79 | } 80 | 81 | onBeforeRemoved() { 82 | RogueCannon.getWorld().removeEventListener('postStep', this.postStep); 83 | } 84 | } 85 | 86 | RE.registerComponent(CannonWheel); 87 | -------------------------------------------------------------------------------- /_Rogue/Engine/Controller/AssetManager.d.ts: -------------------------------------------------------------------------------- 1 | import { Object3D, Material, Texture } from 'three'; 2 | import { AudioAsset } from '../Model/AudioAsset'; 3 | declare type AssetConfig = { 4 | preload?: boolean; 5 | keepLoaded?: boolean; 6 | override?: boolean; 7 | }; 8 | declare class AssetManagerClass { 9 | private _assets; 10 | private _assetConfigs; 11 | private _assetPaths; 12 | private _loadingAssets; 13 | get assets(): { 14 | [uuid: string]: Object3D | Texture | Material | AudioAsset; 15 | }; 16 | get assetConfigs(): { 17 | [uuid: string]: AssetConfig; 18 | }; 19 | get assetPaths(): { 20 | [uuid: string]: string; 21 | }; 22 | onRegisterAsset(callback: (asset: Object3D | AudioAsset | Material | Texture) => void): { 23 | stop: () => void; 24 | }; 25 | onRemoveAsset(callback: (asset: Object3D | AudioAsset | Material | Texture) => void): { 26 | stop: () => void; 27 | }; 28 | onClearAssets(callback: (asset: Object3D | AudioAsset | Material | Texture) => void): { 29 | stop: () => void; 30 | }; 31 | onSetAssetConfig(callback: (uuid: string, config: AssetConfig) => void): { 32 | stop: () => void; 33 | }; 34 | onRemoveAssetConfig(callback: (uuid: string, config: AssetConfig) => void): { 35 | stop: () => void; 36 | }; 37 | onLoadAssetConfigs(callback: (uuid: string, config: AssetConfig) => void): { 38 | stop: () => void; 39 | }; 40 | onSetAssetPath(callback: (uuid: string, assetPath: string) => void): { 41 | stop: () => void; 42 | }; 43 | onSetAssetPaths(callback: (paths: { 44 | [uuid: string]: string; 45 | }) => void): { 46 | stop: () => void; 47 | }; 48 | onRemoveAssetPath(callback: (uuid: string, assetPath: string) => void): { 49 | stop: () => void; 50 | }; 51 | setAssetConfig(uuid: string, config: { 52 | preload?: boolean; 53 | keepLoaded?: boolean; 54 | override?: boolean; 55 | }): void; 56 | getAssetConfig(uuid: string): AssetConfig; 57 | removeAssetConfig(uuid: string): void; 58 | setAssetPath(uuid: string, assetPath: string): void; 59 | removeAssetPath(uuid: string): void; 60 | setAssetPaths(paths: { 61 | [uuid: string]: string; 62 | }): void; 63 | getAssetPath(uuid: string): string | undefined; 64 | registerAsset(asset: Object3D | AudioAsset | Material | Texture): void; 65 | loadAsset(uuid: string): Promise | Texture | Material | AudioAsset | undefined>; 66 | private getExtension; 67 | getAsset(uuid: string): Object3D | Texture | Material | AudioAsset; 68 | private loadObject; 69 | private loadObjectFunction; 70 | private loadNestedPrefabs; 71 | private loadAudio; 72 | private loadAudioFunction; 73 | private loadMaterial; 74 | private loadMaterialFunction; 75 | private loadTexture; 76 | private loadTextureFunction; 77 | private loadTextureFile; 78 | removeAsset(uuid: string): void; 79 | clear(): void; 80 | assetIsOrphan(uuid: string): boolean; 81 | loadAssetConfigs(configs?: { 82 | [uuid: string]: AssetConfig; 83 | }): void; 84 | /** 85 | * Load all assets set to preload if not loaded already 86 | */ 87 | preloadAssets(): Promise; 88 | } 89 | export declare let AssetManager: AssetManagerClass; 90 | export {}; 91 | -------------------------------------------------------------------------------- /webpack.config.rogue.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const glob = require("glob"); 3 | const webpack = require("webpack"); 4 | const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); 5 | 6 | function resolve (dir) { 7 | return path.join(__dirname, dir) 8 | } 9 | 10 | function getDevFiles() { 11 | const files = glob.sync(path.resolve("./Assets") + "/**/*.@(ts|js)", { 12 | ignore: [ 13 | "**/*/_Editor/**/*", 14 | "**/*.d.ts", 15 | ] 16 | }); 17 | return files; 18 | } 19 | 20 | function getEditorFiles() { 21 | const files = glob.sync( resolve("./Assets") + "/**/*.@(ts|js)", { 22 | ignore: [ 23 | "**/*.d.ts", 24 | ] 25 | }); 26 | return files; 27 | } 28 | 29 | function getEntry() { 30 | const entry = {}; 31 | 32 | const devFiles = getDevFiles(); 33 | const editorFiles = getEditorFiles(); 34 | 35 | if (devFiles.length > 0) { 36 | entry["rogue-engine-user-scripts"] = devFiles; 37 | } 38 | 39 | if (editorFiles.length > 0) { 40 | entry["rogue-editor-user-scripts"] = { 41 | import: editorFiles, 42 | dependOn: "rogue-engine-user-scripts", 43 | } 44 | } 45 | 46 | return entry; 47 | } 48 | 49 | module.exports = { 50 | mode: "development", 51 | entry: getEntry(), 52 | output: { 53 | path: path.resolve(__dirname, "./dist"), 54 | filename: "[name].js", 55 | library: "[name]", 56 | libraryTarget: "umd", 57 | }, 58 | externals: { 59 | "rogue-engine": { 60 | commonjs: "rogue-engine", 61 | commonjs2: "rogue-engine", 62 | amd: "rogue-engine", 63 | root: "rogue-engine" 64 | }, 65 | "rogue-editor": { 66 | commonjs: "rogue-editor", 67 | commonjs2: "rogue-editor", 68 | amd: "rogue-editor", 69 | root: "rogue-editor" 70 | }, 71 | three: { 72 | commonjs: "three", 73 | commonjs2: "three", 74 | amd: "three", 75 | root: "three" 76 | }, 77 | }, 78 | resolve: { 79 | extensions: [".ts", ".js", ".json", "*"], 80 | modules: [ 81 | resolve("node_modules"), 82 | resolve("_Rogue") 83 | ], 84 | alias: { 85 | "Assets": resolve("Assets"), 86 | "rogue-engine": resolve("_Rogue/rogue-engine"), 87 | }, 88 | fallback: { "path": false, "fs": false } 89 | }, 90 | module: { 91 | rules: [ 92 | { 93 | test: /\.(js|ts)$/u, 94 | exclude: [/node_modules/, /_Rogue\/test/, /Assets\/test/, /\.d.ts?$/], 95 | use: { 96 | loader: "esbuild-loader", 97 | options: { 98 | loader: 'ts', 99 | target: "es2020", 100 | keepNames: true, 101 | }, 102 | }, 103 | } 104 | ] 105 | }, 106 | devServer: { 107 | historyApiFallback: true, 108 | noInfo: false, 109 | overlay: true, 110 | disableHostCheck: true, 111 | clientLogLevel: "warning" 112 | }, 113 | performance: { 114 | hints: false 115 | }, 116 | devtool: "source-map", 117 | plugins: [new ForkTsCheckerWebpackPlugin()] 118 | } 119 | 120 | if (process.env.NODE_ENV === "production") { 121 | module.exports.devtool = "source-map"; 122 | 123 | module.exports.plugins = (module.exports.plugins || []).concat([ 124 | new webpack.DefinePlugin({ 125 | "process.env": { 126 | NODE_ENV: '"production"' 127 | } 128 | }), 129 | 130 | new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), 131 | 132 | new webpack.LoaderOptionsPlugin({ 133 | minimize: false 134 | }), 135 | ]); 136 | } 137 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/Controllers/CannonVehicleController.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import CannonRaycastVehicle from '../Objects/CannonRaycastVehicle.re'; 3 | 4 | export default class CannonVehicleController extends RE.Component { 5 | @RE.Prop("Number") maxForce = 200; 6 | @RE.Prop("Number") reverseForce = 50; 7 | @RE.Prop("Number") breakForce = 250; 8 | @RE.Prop("Number") maxSteering = 0.5; 9 | 10 | raycastVehicle: CannonRaycastVehicle; 11 | 12 | start() { 13 | this.raycastVehicle = RE.getComponentByName("CannonRaycastVehicle", this.object3d) as CannonRaycastVehicle; 14 | } 15 | 16 | update() { 17 | if (!(this.raycastVehicle instanceof CannonRaycastVehicle)) return; 18 | 19 | // Acceleration 20 | 21 | if (RE.Input.keyboard.getKeyPressed("KeyW")) { 22 | this.releaseBreaks(); 23 | this.raycastVehicle.vehicle.applyEngineForce(this.maxForce, 2); 24 | this.raycastVehicle.vehicle.applyEngineForce(this.maxForce, 3); 25 | } 26 | 27 | if (RE.Input.keyboard.getKeyPressed("KeyS")) { 28 | const speed = -this.raycastVehicle.vehicle.currentVehicleSpeedKmHour; 29 | 30 | if (speed <= 0 ) { 31 | this.releaseBreaks(); 32 | this.raycastVehicle.vehicle.applyEngineForce(-this.reverseForce, 2); 33 | this.raycastVehicle.vehicle.applyEngineForce(-this.reverseForce, 3); 34 | } 35 | 36 | else if (speed > 0.05) { 37 | // this.releaseBreaks(); 38 | this.raycastVehicle.vehicle.applyEngineForce(-this.maxForce, 2); 39 | this.raycastVehicle.vehicle.applyEngineForce(-this.maxForce, 3); 40 | // this.break(); 41 | } 42 | 43 | // else if (speed > 0.1) { 44 | // this.break(); 45 | // } 46 | } 47 | 48 | if (RE.Input.keyboard.getKeyUp("KeyW")) { 49 | this.raycastVehicle.vehicle.applyEngineForce(0, 2); 50 | this.raycastVehicle.vehicle.applyEngineForce(0, 3); 51 | } 52 | 53 | if (RE.Input.keyboard.getKeyUp("KeyS")) { 54 | const speed = Math.abs(this.raycastVehicle.vehicle.currentVehicleSpeedKmHour); 55 | 56 | this.raycastVehicle.vehicle.applyEngineForce(0, 2); 57 | this.raycastVehicle.vehicle.applyEngineForce(0, 3); 58 | 59 | if (speed < 1) { 60 | this.break(); 61 | } 62 | else { 63 | this.releaseBreaks(); 64 | } 65 | } 66 | 67 | // Steering 68 | 69 | if (RE.Input.keyboard.getKeyPressed("KeyA")) { 70 | this.raycastVehicle.vehicle.setSteeringValue(this.maxSteering, 0); 71 | this.raycastVehicle.vehicle.setSteeringValue(this.maxSteering, 1); 72 | } 73 | 74 | if (RE.Input.keyboard.getKeyPressed("KeyD")) { 75 | this.raycastVehicle.vehicle.setSteeringValue(-this.maxSteering, 0); 76 | this.raycastVehicle.vehicle.setSteeringValue(-this.maxSteering, 1); 77 | } 78 | 79 | if (RE.Input.keyboard.getKeyUp("KeyA")) { 80 | this.raycastVehicle.vehicle.setSteeringValue(0, 0); 81 | this.raycastVehicle.vehicle.setSteeringValue(0, 1); 82 | } 83 | 84 | if (RE.Input.keyboard.getKeyUp("KeyD")) { 85 | this.raycastVehicle.vehicle.setSteeringValue(0, 0); 86 | this.raycastVehicle.vehicle.setSteeringValue(0, 1); 87 | } 88 | } 89 | 90 | break() { 91 | this.raycastVehicle.vehicle.setBrake(this.breakForce, 0); 92 | this.raycastVehicle.vehicle.setBrake(this.breakForce, 1); 93 | this.raycastVehicle.vehicle.setBrake(this.breakForce, 2); 94 | this.raycastVehicle.vehicle.setBrake(this.breakForce, 3); 95 | } 96 | 97 | releaseBreaks() { 98 | this.raycastVehicle.vehicle.setBrake(0, 0); 99 | this.raycastVehicle.vehicle.setBrake(0, 1); 100 | this.raycastVehicle.vehicle.setBrake(0, 2); 101 | this.raycastVehicle.vehicle.setBrake(0, 3); 102 | } 103 | } 104 | 105 | RE.registerComponent(CannonVehicleController); 106 | -------------------------------------------------------------------------------- /file-server.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const app = express(); 3 | const port = 3110; 4 | const router = express.Router(); 5 | const cors = require("cors"); 6 | const fs = require("fs"); 7 | const https = require("https"); 8 | const mkcert = require("mkcert"); 9 | const path = require("path"); 10 | 11 | const rogueConfig = require("./rogue-config.json"); 12 | const useHttps = rogueConfig.useHttps; 13 | 14 | let refreshCount = 0; 15 | 16 | (async () => { 17 | 18 | if (useHttps) { 19 | let certificateExists = fs.existsSync(path.join(__dirname, "/node_modules/.cache/rogue-engine-local/server.crt")); 20 | 21 | if (certificateExists) { 22 | const certificateTtl = 1000 * 60 * 60 * 24; 23 | const certificateStat = fs.statSync(path.join(__dirname, "/node_modules/.cache/rogue-engine-local/server.crt")); 24 | 25 | const now = new Date(); 26 | 27 | // if cert is old, remove it. 28 | if ((now - certificateStat.ctime) / certificateTtl > 30) { 29 | fs.unlinkSync(path.join(__dirname, "/node_modules/.cache/rogue-engine-local/server.crt")) 30 | 31 | certificateExists = false; 32 | } 33 | } 34 | 35 | if (!certificateExists) { 36 | 37 | const cacheDirExists = fs.existsSync(path.join(__dirname, "/node_modules/.cache")); 38 | 39 | if (!cacheDirExists) { 40 | fs.mkdirSync(path.join(__dirname, "/node_modules/.cache")); 41 | } 42 | 43 | const reLocalDirExists = fs.existsSync(path.join(__dirname, "/node_modules/.cache/rogue-engine-local")); 44 | 45 | if (!reLocalDirExists) { 46 | fs.mkdirSync(path.join(__dirname, "/node_modules/.cache/rogue-engine-local")); 47 | } 48 | 49 | const ca = await mkcert.createCA({ 50 | organization: "Vortalix", 51 | countryCode: "UK", 52 | state: "Merseyside", 53 | locality: "Liverpool", 54 | validityDays: 35 55 | }); 56 | 57 | const cert = await mkcert.createCert({ 58 | domains: ["127.0.0.1", "localhost", "192.168.0.*"], 59 | validityDays: 35, 60 | caKey: ca.key, 61 | caCert: ca.cert 62 | }); 63 | 64 | fs.writeFileSync(path.join(__dirname, "/node_modules/.cache/rogue-engine-local/ca.key"), ca.key); 65 | fs.writeFileSync(path.join(__dirname, "/node_modules/.cache/rogue-engine-local/ca.crt"), ca.cert); 66 | fs.writeFileSync(path.join(__dirname, "/node_modules/.cache/rogue-engine-local/server.key"), cert.key); 67 | fs.writeFileSync(path.join(__dirname, "/node_modules/.cache/rogue-engine-local/server.crt"), `${cert.cert}\n${ca.cert}`); 68 | } 69 | } 70 | 71 | let config = { 72 | title: "", 73 | scenes: [], 74 | sceneJson: {}, 75 | assetPaths: {}, 76 | } 77 | 78 | app.use(cors()); 79 | 80 | app.use(express.static(`${__dirname}/dist`)); 81 | 82 | app.use("/", router); 83 | 84 | router.use(express.json({limit: "10000mb"})); 85 | router.use(express.urlencoded({limit: "10000mb", extended: false })); 86 | 87 | router.post("/setScenePlayerConfig", (req, res, next) => { 88 | config = req.body; 89 | res.send("Ok"); 90 | }); 91 | 92 | let setScenePlayerConfigOK = () => {}; 93 | 94 | router.get("/getScenePlayerConfig", (req, res, next) => { 95 | setScenePlayerConfigOK = () => { 96 | res.send(config); 97 | }; 98 | 99 | process.send("getScenePlayerConfig"); 100 | }); 101 | 102 | router.post("/addRefreshCount", (req, res, next) => { 103 | refreshCount += 1; 104 | res.send("Ok"); 105 | }); 106 | 107 | router.get("/getRefreshCount", (req, res, next) => { 108 | res.send(refreshCount.toString()); 109 | }); 110 | 111 | router.get("*", (req, res, next) => { 112 | req.url = replaceEscapeCharacters(req.url); 113 | req.path = replaceEscapeCharacters(req.path); 114 | // use req.path, instead of req.url, to discard any query parameter (like webpack hashes) 115 | res.sendFile(`${__dirname}` + req.url); 116 | }); 117 | 118 | const replaceEscapeCharacters = ( text ) => { 119 | text = text.replace( '%20', ' ' ); 120 | if( text.includes('%20') ) 121 | return replaceEscapeCharacters( text ); 122 | else 123 | return text; 124 | } 125 | 126 | process.on("message", (message) => { 127 | if (message === "setScenePlayerConfigOK") { 128 | setScenePlayerConfigOK(); 129 | } 130 | }); 131 | 132 | if (useHttps) { 133 | let privateKey = fs.readFileSync(path.join(__dirname, "/node_modules/.cache/rogue-engine-local/server.key"), "utf8"); 134 | let certificate = fs.readFileSync(path.join(__dirname, "/node_modules/.cache/rogue-engine-local/server.crt"), "utf8"); 135 | 136 | const customKeyPath = path.join(__dirname, "Certificates", "server.key"); 137 | const customCertPath = path.join(__dirname, "Certificates", "server.crt"); 138 | 139 | const customKeyExists = fs.existsSync(customKeyPath); 140 | const customCertExists = fs.existsSync(customCertPath); 141 | 142 | if (customKeyExists && customCertExists) { 143 | privateKey = fs.readFileSync(customKeyPath, "utf8"); 144 | certificate = fs.readFileSync(customCertPath, "utf8"); 145 | } 146 | 147 | const credentials = {key: privateKey, cert: certificate}; 148 | 149 | const server = https.createServer(credentials, app); 150 | server.listen(port); 151 | } else { 152 | app.listen(port); 153 | } 154 | 155 | })(); 156 | -------------------------------------------------------------------------------- /Assets/Components/Static/DeviceUtils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * DeviceUtils 3 | * Manage the different device behaviours. 4 | * It's a static class and can be used without instantiating. 5 | */ 6 | 7 | export default class DeviceUtils { 8 | 9 | static clickEventName = DeviceUtils.isMobile() ? "touchstart" : "click"; 10 | 11 | static rtime: Date; 12 | static timeout: boolean = false; 13 | static delta: number = 600; 14 | 15 | static onResizeCompleteCb: (() => void)[] = []; // Array of callbacks to fire when window size has changed 16 | 17 | // Wait the end of window resize event. 18 | // Taken from https://stackoverflow.com/questions/5489946/how-to-wait-for-the-end-of-resize-event-and-only-then-perform-an-action 19 | static onResizeComplete(cb: () => void) { 20 | 21 | this.onResizeCompleteCb.push(cb); 22 | 23 | // Auto-initialization of the event. When it detects at least one callback, it listens to the window event 24 | if (this.onResizeCompleteCb.length == 1) { 25 | 26 | window.addEventListener("resize", () => { 27 | 28 | this.rtime = new Date(); 29 | 30 | // block this event until a delta time has passed 31 | if (this.timeout === false) { 32 | this.timeout = true; 33 | setTimeout(() => { this.resizeend(); }, this.delta); 34 | } 35 | }); 36 | } 37 | } 38 | 39 | static resizeend() { 40 | 41 | const newTime = new Date(); 42 | 43 | const diff = newTime.getTime() - this.rtime.getTime(); 44 | 45 | if (diff < this.delta) { 46 | 47 | setTimeout(() => { this.resizeend() }, this.delta); 48 | 49 | } else { 50 | 51 | this.timeout = false; 52 | 53 | for (let i = 0; i < this.onResizeCompleteCb.length; i++) { 54 | 55 | this.onResizeCompleteCb[i](); 56 | } 57 | } 58 | } 59 | 60 | // Get if screen orientation is Portrait 61 | static isPortrait() { 62 | return window.innerWidth <= window.innerHeight; 63 | } 64 | 65 | // Get if screen orientation is Landscape 66 | static isLandscape() { 67 | return window.innerWidth > window.innerHeight; 68 | } 69 | 70 | // Get if device is mobile 71 | static isMobile() { 72 | let check = false; 73 | (function (a) { if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true; })(navigator.userAgent || navigator.vendor); 74 | return check; 75 | }; 76 | 77 | static getRogueCanvas() { 78 | return (document.getElementById("rogue-ui") as HTMLElement); 79 | } 80 | 81 | static getAspectRatio() { 82 | return window.innerWidth / window.innerHeight; 83 | } 84 | 85 | static getClickEventName() { 86 | return DeviceUtils.isMobile() ? "touchstart" : "click"; 87 | } 88 | 89 | static isNavigator(browser) { 90 | return navigator.userAgent.indexOf(browser) > -1; 91 | } 92 | 93 | static isSafariMobile() { 94 | return (!this.isNavigator("Chrome") && this.isNavigator("Safari")) && this.isMobile(); 95 | } 96 | 97 | static isRogueEditor() { 98 | return this.isNavigator("RogueEngine"); 99 | } 100 | 101 | static isiOS() { 102 | return [ 103 | 'iPad Simulator', 104 | 'iPhone Simulator', 105 | 'iPod Simulator', 106 | 'iPad', 107 | 'iPhone', 108 | 'iPod' 109 | ].includes(navigator.platform) || (navigator.userAgent.includes("Mac") && "ontouchend" in document) 110 | } 111 | 112 | static isValidBrowser() { 113 | 114 | var isChromeOnDesktop = this.isNavigator("Chrome") && !this.isMobile(); 115 | var isFirefoxOnDesktop = this.isNavigator("Firefox") && !this.isMobile(); 116 | var isOperaOnDesktop = this.isNavigator("OPR") && !this.isMobile(); 117 | var isEdgeOnDesktop = this.isNavigator("Edg") && !this.isMobile(); 118 | 119 | return (isChromeOnDesktop || isFirefoxOnDesktop || isOperaOnDesktop || isEdgeOnDesktop); 120 | } 121 | 122 | } 123 | 124 | -------------------------------------------------------------------------------- /Assets/Components/ProjectileObject.re.ts: -------------------------------------------------------------------------------- 1 | 2 | import CannonBody from 'Assets/rogue_packages/rogue-cannon/Components/CannonBody.re'; 3 | import { Vec3 } from 'cannon-es'; 4 | import * as RE from 'rogue-engine'; 5 | import { MathUtils, Object3D, Raycaster, Vector2, Vector3 } from 'three'; 6 | import DeviceUtils from './Static/DeviceUtils'; 7 | 8 | 9 | const { Prop } = RE; 10 | 11 | export default class ProjectileObject extends RE.Component { 12 | 13 | // External dependencies 14 | @Prop("Prefab") pointPrefab: RE.Prefab; 15 | @Prop("Number") numPoints: number = 10; 16 | @Prop("Number") launchForce: number = 0.05; 17 | @Prop("String") targetName: string = ""; 18 | @Prop("Boolean") dragOnTouchScreen: Boolean = false; 19 | 20 | // Private variables 21 | private raycaster: Raycaster; 22 | private target: Vector2 = new Vector2(0, 0); 23 | private useTouches: Boolean = false; 24 | private rogueDOMrect: any; 25 | private inputCoordinates: Vector2 = new Vector2(0, 0); 26 | private startInputCoords: Vector2 = new Vector2(); 27 | private isValidTouch: Boolean = false; 28 | private isTouched: Boolean = false; 29 | private trajectoryPoints: Object3D[] = []; 30 | private body: CannonBody; 31 | private onLaunchCB: (() => void)[] = []; 32 | private _mass: number = 1; 33 | 34 | // Public variables 35 | public isDragEnabled: Boolean = true; 36 | 37 | awake() { 38 | this.useTouches = DeviceUtils.isMobile(); 39 | this.body = RE.getComponent(CannonBody, this.object3d) as CannonBody; 40 | this._mass = this.body.mass; 41 | 42 | // We remove the mass of the object as soon as we start so that it does not move until launch event 43 | this.setMassEnabled(false); 44 | } 45 | 46 | start() { 47 | // Instantiate points for trajectory path 48 | for (let i = 0; i < this.numPoints; i++) { 49 | const point = this.pointPrefab.instantiate(this.object3d); 50 | this.trajectoryPoints.push(point); 51 | } 52 | 53 | // Create raycast and rogueDomRect to detect bomb touches 54 | this.raycaster = new Raycaster(); 55 | this.rogueDOMrect = RE.Runtime.rogueDOMContainer.getBoundingClientRect(); 56 | 57 | // Update rogueDOMrect size if window size is changed 58 | DeviceUtils.onResizeComplete(() => { this.resizeWindowRect() }); 59 | } 60 | 61 | resizeWindowRect() { 62 | this.rogueDOMrect = RE.Runtime.rogueDOMContainer.getBoundingClientRect(); 63 | } 64 | 65 | // Manage input coordinates either desktop or mobile 66 | setInputCoordinates() { 67 | if (this.useTouches) { 68 | if (RE.Input.touch.touches.length > 0) 69 | this.inputCoordinates.set(RE.Input.touch.touches[0].x, RE.Input.touch.touches[0].y); 70 | } 71 | else { 72 | this.inputCoordinates.set(RE.Input.mouse.x, RE.Input.mouse.y); 73 | } 74 | } 75 | 76 | // Reset the points of the trajectory 77 | resetPoints() { 78 | for (let i = 0, l = this.trajectoryPoints.length; i < l; i++) { 79 | this.trajectoryPoints[i].position.set(0, 0, 0); 80 | } 81 | } 82 | 83 | isKeyPressed() { 84 | return (this.useTouches) ? RE.Input.touch.startTouches.length > 0 : RE.Input.mouse.isLeftButtonDown; 85 | } 86 | 87 | isKeyReleased() { 88 | return (this.useTouches) ? RE.Input.touch.touches.length == 0 : RE.Input.mouse.isLeftButtonUp; 89 | } 90 | 91 | setMassEnabled(enabled: boolean) { 92 | this.body.mass = enabled ? this._mass : 0; 93 | } 94 | 95 | 96 | update() { 97 | 98 | if (!this.isDragEnabled) 99 | return; 100 | 101 | this.setInputCoordinates(); 102 | 103 | // Is input coords touching the bomb? 104 | this.isValidTouch = (this.dragOnTouchScreen) ? true : this.isOverTarget(this.inputCoordinates.x, this.inputCoordinates.y); 105 | 106 | // Touchstart 107 | if (this.isValidTouch && this.isKeyPressed()) { 108 | this.isTouched = true; 109 | this.startInputCoords.copy(this.inputCoordinates); 110 | } 111 | 112 | // Touchmove 113 | if (this.isTouched) { 114 | this.moveTrajectory(); 115 | } 116 | 117 | // Touchend 118 | if (this.isTouched && this.isKeyReleased()) { 119 | this.isTouched = false; 120 | this.isValidTouch = false; 121 | this.resetPoints(); 122 | this.launch(); 123 | } 124 | } 125 | 126 | moveTrajectory() { 127 | 128 | // Calc distance and angle between bomb and touch 129 | const force = this.startInputCoords.distanceTo(this.inputCoordinates) * this.launchForce; 130 | const angle = MathUtils.radToDeg(Math.atan2(this.inputCoordinates.y - this.startInputCoords.y, this.inputCoordinates.x - this.startInputCoords.x)); 131 | const spacing = 0.1; // Space between points 132 | 133 | // Calc points trjectory 134 | for (let i = 0, l = this.trajectoryPoints.length; i < l; i++) { 135 | const element = this.trajectoryPoints[i]; 136 | const spacingElement = spacing * i; 137 | const x = force * Math.cos(Math.PI / 180 * angle) * spacingElement; 138 | const y = force * Math.sin(Math.PI / 180 * angle) * spacingElement - 0.5 * 10 * (spacingElement * spacingElement); 139 | const posPoint = new Vector3(-x, y, 0); 140 | element.position.copy(posPoint); 141 | } 142 | } 143 | 144 | 145 | launch() { 146 | // Get vector impulse 147 | const vectorImpulse = this.inputCoordinates.sub(this.startInputCoords); 148 | // Enable mass 149 | this.setMassEnabled(true); 150 | // Scale vector with launch force and create a Cannon Vec3 151 | const vec3Impulse = new Vec3(-vectorImpulse.x, vectorImpulse.y, 0).scale(this.body.mass * this.launchForce); 152 | // Apply bomb impulse 153 | this.body.body.applyImpulse(vec3Impulse); 154 | // Disable more draggings: 155 | this.isDragEnabled = false; 156 | // Run callbacks on launch 157 | this.runOnLaunchCallbacks(); 158 | } 159 | 160 | isOverTarget(x: number, y: number): Boolean { 161 | // Calculate mouse/touch position in normalized device coordinates 162 | this.target.set(((x - this.rogueDOMrect.left) / this.rogueDOMrect.width) * 2 - 1, -((y - this.rogueDOMrect.top) / this.rogueDOMrect.height) * 2 + 1); 163 | 164 | // Valid for Ortographic Camera 165 | this.raycaster.setFromCamera(this.target, RE.Runtime.camera); 166 | 167 | // Get children intersection 168 | var intersects = this.raycaster.intersectObjects(RE.Runtime.scene.children); 169 | 170 | if (intersects.length == 0) 171 | return false; 172 | 173 | let isIntersecting = false; 174 | 175 | intersects.forEach(element => { 176 | if (element.object.name == this.targetName) { 177 | isIntersecting = true; 178 | } 179 | }); 180 | 181 | return isIntersecting; 182 | } 183 | 184 | onLaunch(callback: () => void) { 185 | this.onLaunchCB.push(callback); 186 | } 187 | 188 | private runOnLaunchCallbacks() { 189 | for (const callback of this.onLaunchCB) { 190 | callback(); 191 | } 192 | } 193 | } 194 | 195 | RE.registerComponent(ProjectileObject); 196 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/CannonBody.re.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as CANNON from 'cannon-es'; 3 | import * as THREE from 'three'; 4 | import * as RogueCannon from '../Lib/RogueCannon'; 5 | 6 | export default class CannonBody extends RE.Component { 7 | protected _isTrigger = false; 8 | protected _angularDamping = 0; 9 | protected _linearDamping = 0; 10 | protected _angularFactor = new THREE.Vector3(1, 1, 1); 11 | protected _linearFactor = new THREE.Vector3(1, 1, 1); 12 | protected _mass = 1; 13 | protected _useDefaultMass = true; 14 | protected _type = 0; 15 | protected typeOptions = [ 16 | "Dynamic", 17 | "Static", 18 | "Kinematic", 19 | ]; 20 | 21 | @RE.Prop("Select") 22 | get type() { 23 | return this._type; 24 | } 25 | 26 | set type(value: number) { 27 | this._type = value; 28 | 29 | let type: CANNON.BodyType = 1; 30 | 31 | if (value === 0) type = 1; 32 | if (value === 1) type = 2; 33 | if (value === 2) type = 4; 34 | 35 | this.body && (this.body.type = type); 36 | } 37 | 38 | @RE.Prop("Number") 39 | get angularDamping() { 40 | return this._angularDamping; 41 | } 42 | 43 | set angularDamping(value: number) { 44 | this._angularDamping = value; 45 | this.body && (this.body.angularDamping = value); 46 | } 47 | 48 | @RE.Prop("Number") 49 | get linearDamping() { 50 | return this._linearDamping; 51 | } 52 | 53 | set linearDamping(value: number) { 54 | this._linearDamping = value; 55 | this.body && (this.body.linearDamping = value); 56 | } 57 | 58 | @RE.Prop("Number") 59 | get mass() { 60 | return this._mass; 61 | } 62 | 63 | set mass(value: number) { 64 | this._mass = value; 65 | this.body && (this.body.mass = value); 66 | this.body && this.body.updateMassProperties(); 67 | } 68 | 69 | @RE.Prop("Vector3") 70 | get linearFactor() { 71 | return this._linearFactor; 72 | } 73 | 74 | set linearFactor(value: THREE.Vector3) { 75 | this._linearFactor = value; 76 | this.body && (this.body.linearFactor.set(value.x, value.y, value.z)); 77 | } 78 | 79 | @RE.Prop("Vector3") 80 | get angularFactor() { 81 | return this._angularFactor; 82 | } 83 | 84 | set angularFactor(value: THREE.Vector3) { 85 | this._angularFactor = value; 86 | this.body && (this.body.angularFactor.set(value.x, value.y, value.z)); 87 | } 88 | 89 | @RE.Prop("Boolean") 90 | get isTrigger() { 91 | return this._isTrigger; 92 | } 93 | 94 | set isTrigger(value: boolean) { 95 | this._isTrigger = value; 96 | this.body && (this.body.isTrigger = value); 97 | } 98 | 99 | body: CANNON.Body; 100 | 101 | private worldPos = new THREE.Vector3(); 102 | private worldRot = new THREE.Quaternion(); 103 | private newBodyPos = new CANNON.Vec3(); 104 | private newBodyRot = new CANNON.Quaternion(); 105 | 106 | private newPos = new THREE.Vector3(); 107 | private newRot = new THREE.Quaternion(); 108 | private matrixA = new THREE.Matrix4(); 109 | private matrixB = new THREE.Matrix4(); 110 | private matrixC = new THREE.Matrix4(); 111 | 112 | private onCollideCB: (event: {other: CANNON.Body, contact: CANNON.ContactEquation}) => void | undefined; 113 | 114 | private triggerCollision; 115 | 116 | static findByBody(body: CANNON.Body) { 117 | let bodyComponent: undefined | CannonBody; 118 | 119 | RE.traverseComponents(component => { 120 | if (bodyComponent) return; 121 | 122 | if (component instanceof CannonBody && component.body === body) { 123 | bodyComponent = component; 124 | } 125 | }); 126 | 127 | return bodyComponent; 128 | } 129 | 130 | awake() { 131 | this.createBody(); 132 | 133 | RE.Runtime.onStop(() => { 134 | this.handleOnCollide && this.body.removeEventListener('collide', this.handleOnCollide); 135 | }); 136 | } 137 | 138 | start() { 139 | RogueCannon.getWorld().addBody(this.body); 140 | this.copyObjectTransform(); 141 | } 142 | 143 | update() { 144 | if (this.body.mass !== this._mass) { 145 | this.mass = this._mass; 146 | } 147 | 148 | this.body && (this.body.type = this.getBodyType()) 149 | 150 | this.body.type !== CANNON.BODY_TYPES.STATIC && this.updatePhysics(); 151 | } 152 | 153 | afterUpdate() { 154 | if (this.triggerCollision !== undefined && this.onCollideCB) { 155 | this.onCollideCB(this.triggerCollision); 156 | this.triggerCollision = undefined; 157 | } 158 | } 159 | 160 | onBeforeRemoved() { 161 | RogueCannon.getWorld().removeBody(this.body); 162 | } 163 | 164 | onCollide(callback: (event: {other: CANNON.Body, contact: CANNON.ContactEquation}) => void) { 165 | this.onCollideCB = callback; 166 | 167 | this.body.removeEventListener('collide', this.handleOnCollide); 168 | this.body.addEventListener('collide', this.handleOnCollide); 169 | } 170 | 171 | private handleOnCollide = (event: {body: CANNON.Body, target: CANNON.Body, contact: CANNON.ContactEquation}) => { 172 | const bj = event.contact.bj; 173 | const bi = event.contact.bi; 174 | 175 | const collision = { 176 | other: bj !== this.body ? bj : bi, 177 | contact: event.contact, 178 | } 179 | 180 | this.triggerCollision = collision; 181 | } 182 | 183 | private getBodyType() { 184 | let type: CANNON.BodyType = 1; 185 | 186 | if (this._type === 0) type = 1; 187 | if (this._type === 1) type = 2; 188 | if (this._type === 2) type = 4; 189 | 190 | return type; 191 | } 192 | 193 | private createBody() { 194 | this.body = new CANNON.Body({ 195 | type: this.getBodyType(), 196 | angularDamping: this.angularDamping, 197 | linearDamping: this.linearDamping, 198 | linearFactor: new CANNON.Vec3(this.linearFactor.x, this.linearFactor.y, this.linearFactor.z), 199 | angularFactor: new CANNON.Vec3(this.angularFactor.x, this.angularFactor.y, this.angularFactor.z), 200 | isTrigger: this.isTrigger, 201 | mass: this._mass, 202 | }); 203 | 204 | this.copyObjectTransform(); 205 | } 206 | 207 | protected createShape(): void {}; 208 | 209 | protected copyObjectTransform() { 210 | this.object3d.parent?.updateMatrixWorld(true); 211 | 212 | this.object3d.getWorldPosition(this.worldPos); 213 | this.object3d.getWorldQuaternion(this.worldRot); 214 | 215 | this.newBodyPos.set( 216 | this.worldPos.x, 217 | this.worldPos.y, 218 | this.worldPos.z 219 | ); 220 | 221 | this.newBodyRot.set( 222 | this.worldRot.x, 223 | this.worldRot.y, 224 | this.worldRot.z, 225 | this.worldRot.w 226 | ); 227 | 228 | this.body.quaternion.copy(this.newBodyRot); 229 | this.body.position.copy(this.newBodyPos); 230 | } 231 | 232 | protected copyBodyTransform() { 233 | this.copyBodyPosition(); 234 | this.copyBodyRotation(); 235 | } 236 | 237 | private copyBodyPosition() { 238 | this.newPos.set( 239 | this.body.position.x, 240 | this.body.position.y, 241 | this.body.position.z 242 | ); 243 | 244 | if (!this.object3d.parent) return; 245 | 246 | this.object3d.parent?.worldToLocal(this.newPos); 247 | this.object3d.position.copy(this.newPos); 248 | } 249 | 250 | private copyBodyRotation() { 251 | this.newRot.set( 252 | this.body.quaternion.x, 253 | this.body.quaternion.y, 254 | this.body.quaternion.z, 255 | this.body.quaternion.w 256 | ); 257 | 258 | this.matrixA.makeRotationFromQuaternion(this.newRot); 259 | this.object3d.updateMatrixWorld(); 260 | this.matrixB.copy((this.object3d.parent as THREE.Object3D).matrixWorld).invert(); 261 | this.matrixC.extractRotation(this.matrixB); 262 | this.matrixA.premultiply(this.matrixC); 263 | this.object3d.quaternion.setFromRotationMatrix(this.matrixA); 264 | } 265 | 266 | private updatePhysics() { 267 | this.copyBodyTransform(); 268 | } 269 | } 270 | 271 | RE.registerComponent(CannonBody); 272 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Components/_Editor/CannonBodyWireframe.ts: -------------------------------------------------------------------------------- 1 | import * as RE from 'rogue-engine'; 2 | import * as THREE from 'three'; 3 | 4 | import CannonBox from '../Shapes/CannonBox.re'; 5 | import CannonSphere from '../Shapes/CannonSphere.re'; 6 | import CannonShape from '../Shapes/CannonShape'; 7 | import CannonCylinder from '../Shapes/CannonCylinder.re'; 8 | import CannonTrimesh from '../Shapes/CannonTrimesh.re'; 9 | 10 | export default class CannonBodyWireframe extends RE.Component { 11 | static isEditorComponent = true; 12 | 13 | selectedObjects: THREE.Object3D[] = []; 14 | colliders: THREE.Object3D[] = []; 15 | wireframeMaterial = new THREE.MeshStandardMaterial({wireframe: true, emissive: new THREE.Color("#00FF00"), color: new THREE.Color("#000000")}); 16 | 17 | private handleOnComponentAdded = {stop: () => {}}; 18 | private handleOnComponentRemoved = {stop: () => {}}; 19 | 20 | private handleOnPlay = {stop: () => {}}; 21 | 22 | private resetHandler = (component: RE.Component) => { 23 | component instanceof CannonShape && this.setupImpostors(); 24 | } 25 | 26 | start() { 27 | this.handleOnComponentAdded.stop(); 28 | this.handleOnComponentRemoved.stop(); 29 | this.handleOnPlay.stop(); 30 | 31 | this.handleOnComponentAdded = RE.onComponentAdded(this.resetHandler); 32 | this.handleOnComponentRemoved = RE.onComponentRemoved(this.resetHandler); 33 | 34 | this.handleOnPlay = RE.Runtime.onPlay(() => { 35 | this.handleOnComponentAdded.stop(); 36 | this.handleOnComponentRemoved.stop(); 37 | this.cleanupImpostors(); 38 | }); 39 | } 40 | 41 | afterUpdate() { 42 | const selectedObjects = window["rogue-editor"].Project.selectedObjects as THREE.Object3D[]; 43 | 44 | if (!this.arraysAreEqual(selectedObjects, this.selectedObjects)) { 45 | this.selectedObjects = selectedObjects.slice(0); 46 | this.setupImpostors(); 47 | } 48 | 49 | if (this.selectedObjects.length === 0) return; 50 | 51 | this.updateImpostors(); 52 | } 53 | 54 | private updateImpostors() { 55 | this.colliders.forEach(impostor => { 56 | this.updateColliderMesh(impostor.userData.cannonShape, impostor as THREE.Mesh); 57 | }); 58 | } 59 | 60 | private cleanupImpostors() { 61 | this.colliders.forEach(impostor => { 62 | impostor.userData.cannonShape = null; 63 | RE.App.currentScene.remove(impostor); 64 | RE.dispose(impostor); 65 | }); 66 | 67 | this.colliders = []; 68 | } 69 | 70 | private setupImpostors() { 71 | this.cleanupImpostors(); 72 | 73 | this.selectedObjects.forEach(selected => { 74 | selected.traverse(object => { 75 | const objComponents = RE.components[object.uuid]; 76 | 77 | if (!objComponents) return; 78 | 79 | objComponents.forEach(component => { 80 | if (!(component instanceof CannonShape)) return; 81 | 82 | let impostor = RE.App.currentScene.getObjectByName("EDITOR_OBJECT_BB_" + object.uuid); 83 | 84 | if (impostor) return; 85 | 86 | impostor = this.getColliderMesh(component); 87 | 88 | if (impostor) { 89 | impostor.name = "EDITOR_OBJECT_BB_" + object.uuid; 90 | impostor.userData.isEditorObject = true; 91 | RE.App.currentScene.add(impostor); 92 | } else { 93 | return; 94 | } 95 | 96 | impostor.userData.cannonShape = component; 97 | this.colliders.push(impostor); 98 | }); 99 | }); 100 | }); 101 | } 102 | 103 | private arraysAreEqual(array1: any[], array2: any[]) { 104 | if (array1.length !== array2.length) return false; 105 | 106 | return array1.every((element, i) => { 107 | return array2[i] === element; 108 | }); 109 | } 110 | 111 | private getColliderMesh(component: CannonShape): THREE.Mesh | undefined { 112 | if (component instanceof CannonBox) { 113 | return new THREE.Mesh( 114 | new THREE.BoxBufferGeometry(), 115 | this.wireframeMaterial, 116 | ); 117 | } 118 | 119 | if (component instanceof CannonCylinder) { 120 | const radiusTop = component.radiusTopOffset * component.object3d.scale.x; 121 | const radiusBottom = component.radiusBottomOffset * component.object3d.scale.x; 122 | const height = component.heightOffset * component.object3d.scale.y; 123 | return new THREE.Mesh( 124 | new THREE.CylinderBufferGeometry(radiusTop, radiusBottom, height, component.segments), 125 | this.wireframeMaterial, 126 | ); 127 | } 128 | 129 | if (component instanceof CannonSphere) { 130 | const scale = component.object3d.scale; 131 | const maxSide = Math.max(scale.x, scale.y, scale.z); 132 | 133 | const radius = component.radiusOffset * (maxSide); 134 | const compensatedRadius = radius + (radius * 0.01); 135 | const segments = 15; 136 | 137 | return new THREE.Mesh( 138 | new THREE.SphereBufferGeometry(compensatedRadius, segments, segments), 139 | this.wireframeMaterial, 140 | ); 141 | } 142 | 143 | if (component instanceof CannonTrimesh) { 144 | 145 | if (!component.shape) component.createShape(); 146 | 147 | if (component.shape) { 148 | const geometry = new THREE.BufferGeometry(); 149 | const mesh = new THREE.Mesh(geometry, this.wireframeMaterial); 150 | 151 | const points: THREE.Vector3[] = []; 152 | 153 | for (let i = 0; i < component.shape.vertices.length; i+=3) { 154 | const point = new THREE.Vector3( 155 | component.shape.vertices[i], 156 | component.shape.vertices[i + 1], 157 | component.shape.vertices[i + 2] 158 | ); 159 | 160 | points.push(point); 161 | } 162 | 163 | geometry.setFromPoints(points); 164 | 165 | return mesh; 166 | } 167 | } 168 | 169 | return; 170 | } 171 | 172 | private updateColliderMesh(component: CannonShape, mesh: THREE.Mesh) { 173 | if (component instanceof CannonBox) { 174 | component.object3d.getWorldScale(mesh.scale); 175 | 176 | mesh.scale.set( 177 | component.sizeOffset.x * (mesh.scale.x), 178 | component.sizeOffset.y * (mesh.scale.y), 179 | component.sizeOffset.z * (mesh.scale.z) 180 | ); 181 | } 182 | 183 | if (component instanceof CannonCylinder) { 184 | component.object3d.getWorldScale(mesh.scale); 185 | 186 | const radiusTop = component.radiusTopOffset * mesh.scale.x 187 | const radiusBottom = component.radiusBottomOffset * mesh.scale.x; 188 | const height = component.heightOffset * mesh.scale.y; 189 | 190 | if (mesh.geometry instanceof THREE.CylinderBufferGeometry) { 191 | if ( 192 | mesh.geometry.parameters.radiusTop !== radiusTop || 193 | mesh.geometry.parameters.radiusBottom !== radiusBottom || 194 | mesh.geometry.parameters.height !== height || 195 | mesh.geometry.parameters.radialSegments !== component.segments 196 | ) { 197 | mesh.geometry.dispose(); 198 | mesh.geometry = new THREE.CylinderBufferGeometry(radiusTop, radiusBottom, height, component.segments); 199 | } 200 | } 201 | } 202 | 203 | if (component instanceof CannonSphere) { 204 | const scale = component.object3d.scale; 205 | const maxSide = Math.max(scale.x, scale.y, scale.z); 206 | 207 | const radius = component.radiusOffset * (maxSide); 208 | 209 | if (mesh.geometry instanceof THREE.SphereBufferGeometry) { 210 | if (mesh.geometry.parameters.radius !== radius) { 211 | let segments = 10 * radius; 212 | 213 | if (segments < 15) segments = 15; 214 | 215 | if (segments > 50) segments = 50; 216 | 217 | mesh.geometry.dispose(); 218 | mesh.geometry = new THREE.SphereBufferGeometry(radius, segments, segments); 219 | } 220 | } 221 | } 222 | 223 | component.object3d.getWorldPosition(mesh.position); 224 | component.object3d.getWorldQuaternion(mesh.quaternion); 225 | } 226 | 227 | onBeforeRemoved() { 228 | this.handleOnComponentAdded.stop(); 229 | this.handleOnComponentRemoved.stop(); 230 | this.handleOnPlay.stop(); 231 | this.cleanupImpostors(); 232 | } 233 | } 234 | 235 | RE.registerComponent(CannonBodyWireframe); 236 | -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Scenes/CharacterExample.rogueScene: -------------------------------------------------------------------------------- 1 | {"assetConfigs":{},"scene":{"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"geometries":[{"uuid":"4FCFE552-A3E5-412D-97E2-F31474916183","type":"BoxBufferGeometry","width":1,"height":1,"depth":1,"widthSegments":1,"heightSegments":1,"depthSegments":1},{"uuid":"25C23DE5-3D1A-44E2-A178-033725477147","type":"BoxBufferGeometry","width":1,"height":1,"depth":1,"widthSegments":1,"heightSegments":1,"depthSegments":1},{"uuid":"FAE5A806-E3A9-4759-BE8D-CAE09A7D2B74","type":"BoxBufferGeometry","width":1,"height":1,"depth":1,"widthSegments":1,"heightSegments":1,"depthSegments":1},{"uuid":"37D04FF8-7C3F-4AE1-8489-6FFB545729B0","type":"SphereBufferGeometry","radius":1,"widthSegments":8,"heightSegments":6,"phiStart":0,"phiLength":6.283185307179586,"thetaStart":0,"thetaLength":3.141592653589793},{"uuid":"3CFCBD66-3006-466F-A430-523BA9734280","type":"SphereBufferGeometry","radius":1,"widthSegments":8,"heightSegments":6,"phiStart":0,"phiLength":6.283185307179586,"thetaStart":0,"thetaLength":3.141592653589793},{"uuid":"EF881319-5277-403D-BB1F-B0FA530C37ED","type":"SphereBufferGeometry","radius":1,"widthSegments":8,"heightSegments":6,"phiStart":0,"phiLength":6.283185307179586,"thetaStart":0,"thetaLength":3.141592653589793},{"uuid":"EB34B760-C0BC-454C-A955-2BF921D90E25","type":"BoxBufferGeometry","width":1,"height":1,"depth":1,"widthSegments":1,"heightSegments":1,"depthSegments":1},{"uuid":"80F52323-58A0-4184-87DF-6664EE3BA417","type":"BoxBufferGeometry","width":1,"height":1,"depth":1,"widthSegments":1,"heightSegments":1,"depthSegments":1}],"materials":[{"uuid":"4F621BB1-886C-4899-87BB-628B679DBBA6","type":"MeshStandardMaterial","color":11836651,"roughness":1,"metalness":0,"emissive":0,"depthFunc":3,"depthTest":true,"depthWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680},{"uuid":"8AABD3F1-BBF9-42D0-AE77-3D96AA161D13","type":"MeshStandardMaterial","color":9170929,"roughness":1,"metalness":0,"emissive":0,"depthFunc":3,"depthTest":true,"depthWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680}],"object":{"uuid":"7c554a70-e242-4322-a79e-d67ae3a79a2f","type":"Scene","layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"children":[{"uuid":"CE75AEE7-915F-4652-BFC5-CA4AB6EAC443","type":"Object3D","name":"Config","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]},{"uuid":"20BF965B-8023-4132-B7F6-367508462743","type":"AmbientLight","name":"Ambient Light","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"color":16777215,"intensity":0.7},{"uuid":"1FA10599-BFC4-45CB-944E-DA58CBB91476","type":"PerspectiveCamera","name":"Main Camera","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,3.197636628808884,14.699141030612537,1],"children":[{"uuid":"87A6C56A-4415-46BE-8137-2314A2413B7B","type":"Object3D","name":"AudioListener","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}],"fov":50,"zoom":1,"near":0.1,"far":100,"focus":10,"aspect":1.973919094903491,"filmGauge":35,"filmOffset":0},{"uuid":"DA5BA9C0-6959-4174-96A9-8A4996AE2376","type":"Mesh","name":"Cube","castShadow":true,"receiveShadow":true,"userData":{"__IS_ADDING__":false,"components":[{"name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"angularDamping":"Number","linearDamping":"Number","mass":"Number"},"interfaceRefs":{"angularDamping":0,"linearDamping":0,"mass":0},"enabled":true},{"name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true}]},"layers":1,"matrix":[20,0,0,0,0,0.5,0,0,0,0,20,0,0,0,0,1],"geometry":"4FCFE552-A3E5-412D-97E2-F31474916183","material":"4F621BB1-886C-4899-87BB-628B679DBBA6"},{"uuid":"DDA713D9-4CDA-40BC-803F-1EE50B6AE85F","type":"DirectionalLight","name":"SUNLIGHT","castShadow":true,"userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,5.5109105961630896e-15,10.157074638613345,-89.42501794680075,1],"color":16777215,"intensity":1,"shadow":{"camera":{"uuid":"5BAEF1E8-6857-4556-8B55-5F3BBEC45132","type":"OrthographicCamera","layers":1,"zoom":1,"left":-5,"right":5,"top":5,"bottom":-5,"near":0.5,"far":500}}},{"uuid":"B34E8F4E-054C-495C-9F2E-5E1DB559509A","type":"Mesh","name":"Cube","castShadow":true,"receiveShadow":true,"userData":{"__IS_ADDING__":false},"layers":1,"matrix":[4.134415419169694,-1.7215990416230964,0,0,0.17702428801998263,0.4251233465298268,0,0,0,0,3.4047522272259463,0,-1.2065411687493324,0,0,1],"geometry":"25C23DE5-3D1A-44E2-A178-033725477147","material":"4F621BB1-886C-4899-87BB-628B679DBBA6"},{"uuid":"1F607071-2261-423C-83D2-122C3F45728F","type":"Mesh","name":"Cube","castShadow":true,"receiveShadow":true,"userData":{"__IS_ADDING__":false,"components":[{"name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"angularDamping":"Number","linearDamping":"Number","mass":"Number"},"interfaceRefs":{"angularDamping":0,"linearDamping":0,"mass":0},"enabled":true},{"name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true}]},"layers":1,"matrix":[4.651174257492724,0,0,0,0,1.9131884459888033,0,0,0,0,10.694120313312697,0,-5.487892015006867,0.129899124381762,0,1],"geometry":"FAE5A806-E3A9-4759-BE8D-CAE09A7D2B74","material":"4F621BB1-886C-4899-87BB-628B679DBBA6"},{"uuid":"2DBABB8A-8FD0-4554-8D7A-E9D859FCA6A0","type":"Object3D","name":"Player","castShadow":true,"receiveShadow":true,"userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,3.637542782467465,0,1],"children":[{"uuid":"119BE00D-3723-4E82-8F41-FA689F39D425","type":"Mesh","name":"Sphere","castShadow":true,"receiveShadow":true,"userData":{"__IS_ADDING__":false,"components":[{"name":"CannonSphere","componentPrototypeName":"CannonSphere","interface":{"radiusOffset":"Number"},"interfaceRefs":{"radiusOffset":1},"enabled":true}]},"layers":1,"matrix":[0.5,0,0,0,0,0.5,0,0,0,0,0.5,0,0,0,0,1],"geometry":"37D04FF8-7C3F-4AE1-8489-6FFB545729B0","material":"8AABD3F1-BBF9-42D0-AE77-3D96AA161D13"},{"uuid":"E376666F-9D6F-49D6-BE00-D4E626E2AD23","type":"Mesh","name":"Sphere","castShadow":true,"receiveShadow":true,"userData":{"__IS_ADDING__":false,"components":[{"name":"CannonSphere","componentPrototypeName":"CannonSphere","interface":{"radiusOffset":"Number"},"interfaceRefs":{"radiusOffset":1},"enabled":true}]},"layers":1,"matrix":[0.5,0,0,0,0,0.5,0,0,0,0,0.5,0,0,0.5,0,1],"geometry":"3CFCBD66-3006-466F-A430-523BA9734280","material":"8AABD3F1-BBF9-42D0-AE77-3D96AA161D13"},{"uuid":"3B3DE558-0B56-44DD-B540-7C9F6A75E3F7","type":"Mesh","name":"Sphere","castShadow":true,"receiveShadow":true,"userData":{"__IS_ADDING__":false},"layers":1,"matrix":[0.5,0,0,0,0,0.5,0,0,0,0,0.5,0,0,1,0,1],"geometry":"EF881319-5277-403D-BB1F-B0FA530C37ED","material":"8AABD3F1-BBF9-42D0-AE77-3D96AA161D13"}]},{"uuid":"59FA0750-6CFC-4FCC-A22C-0C8D99754A8C","type":"Mesh","name":"Cube","castShadow":true,"receiveShadow":true,"userData":{"__IS_ADDING__":false,"components":[{"name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"angularDamping":"Number","linearDamping":"Number","mass":"Number"},"interfaceRefs":{"angularDamping":0,"linearDamping":0,"mass":0},"enabled":true},{"name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true}]},"layers":1,"matrix":[4.651174257492724,0,0,0,0,1.9131884459888033,0,0,0,0,10.694120313312697,0,3.161079856311641,0.129899124381762,0.9019157056374478,1],"geometry":"EB34B760-C0BC-454C-A955-2BF921D90E25","material":"4F621BB1-886C-4899-87BB-628B679DBBA6"},{"uuid":"8A67223C-58E0-4751-AFBA-BF3A11C81E63","type":"Mesh","name":"Cube","castShadow":true,"receiveShadow":true,"userData":{"__IS_ADDING__":false},"layers":1,"matrix":[2.762719365190388,0,0,0,0,1.9131884459888033,0,0,0,0,2.8420294820815415,0,3.5080785446494027,1.1823928144584956,0.9019157056374478,1],"geometry":"80F52323-58A0-4184-87DF-6664EE3BA417","material":"4F621BB1-886C-4899-87BB-628B679DBBA6"},{"uuid":"193994BA-7EA3-4FE5-81DD-D2FE86C95ED8","type":"HemisphereLight","name":"Hemisphere Light","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,6.740057389379886,-5.298840360228972,1],"color":16777215,"intensity":0.5,"groundColor":1}]}},"skybox":{"_enabled":true,"_mode":"cubemap","_showSun":false,"inclination":0.464,"azimuth":0.25,"mieDirectionalG":0,"mieCoefficient":0,"turbidity":0,"rayleigh":0,"luminance":0,"_sunSpeed":0,"_cubemapTop":false,"_cubemapBottom":false,"_cubemapFront":false,"_cubemapBack":false,"_cubemapRight":false,"_cubemapLeft":false},"components":{"DA5BA9C0-6959-4174-96A9-8A4996AE2376":[{"name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":"1","angularDamping":0,"linearDamping":0,"mass":0,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true}],"CE75AEE7-915F-4652-BFC5-CA4AB6EAC443":[{"name":"CannonConfig","componentPrototypeName":"CannonConfig","interface":{"step":"Number","defaultFriction":"Number","defaultRestitution":"Number","gravity":"Vector3"},"interfaceRefs":{"step":0.016666666666666666,"defaultFriction":0,"defaultRestitution":0,"gravity":[0,-9.82,0]},"enabled":true}],"B34E8F4E-054C-495C-9F2E-5E1DB559509A":[{"name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":"1","angularDamping":0,"linearDamping":0,"mass":0,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true}],"1F607071-2261-423C-83D2-122C3F45728F":[{"name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":"1","angularDamping":0,"linearDamping":0,"mass":0,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true}],"2DBABB8A-8FD0-4554-8D7A-E9D859FCA6A0":[{"name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":0,"angularDamping":0,"linearDamping":0,"mass":4,"linearFactor":[1,1,1],"angularFactor":[0,1,0],"isTrigger":false},"enabled":true},{"name":"CannonSimpleCharacterController","componentPrototypeName":"CannonSimpleCharacterController","interface":{"fwdSpeed":"Number","jumpSpeed":"Number"},"interfaceRefs":{"fwdSpeed":3,"jumpSpeed":5},"enabled":true}],"119BE00D-3723-4E82-8F41-FA689F39D425":[{"name":"CannonSphere","componentPrototypeName":"CannonSphere","interface":{"radiusOffset":"Number"},"interfaceRefs":{"radiusOffset":1},"enabled":true}],"59FA0750-6CFC-4FCC-A22C-0C8D99754A8C":[{"name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":"1","angularDamping":0,"linearDamping":0,"mass":0,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true}],"8A67223C-58E0-4751-AFBA-BF3A11C81E63":[{"name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":"1","angularDamping":0,"linearDamping":0,"mass":0,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true}],"E376666F-9D6F-49D6-BE00-D4E626E2AD23":[{"name":"CannonSphere","componentPrototypeName":"CannonSphere","interface":{"radiusOffset":"Number"},"interfaceRefs":{"radiusOffset":1},"enabled":true}],"3B3DE558-0B56-44DD-B540-7C9F6A75E3F7":[{"name":"CannonSphere","componentPrototypeName":"CannonSphere","interface":{"radiusOffset":"Number"},"interfaceRefs":{"radiusOffset":1},"enabled":true}]}} -------------------------------------------------------------------------------- /Assets/rogue_packages/rogue-cannon/Scenes/CannonExample.rogueScene: -------------------------------------------------------------------------------- 1 | {"assetConfigs":{},"scene":{"metadata":{"version":4.5,"type":"Object","generator":"Object3D.toJSON"},"geometries":[{"uuid":"7E241583-0D6A-4721-8F8A-4685E01833D4","type":"BoxBufferGeometry","width":1,"height":1,"depth":1,"widthSegments":1,"heightSegments":1,"depthSegments":1},{"uuid":"0FF94EF3-93F0-47C7-BE03-A6EBE9461558","type":"BoxBufferGeometry","width":1,"height":1,"depth":1,"widthSegments":1,"heightSegments":1,"depthSegments":1},{"uuid":"A16A4CEA-9492-4EC2-B88D-7A948D430E91","type":"SphereBufferGeometry","radius":0.5,"widthSegments":8,"heightSegments":6,"phiStart":0,"phiLength":6.283185307179586,"thetaStart":0,"thetaLength":3.141592653589793},{"uuid":"58ADFFFA-B844-4661-89B8-7FDEF5AC12C5","type":"CylinderBufferGeometry","radiusTop":1,"radiusBottom":1,"height":1,"radialSegments":16,"heightSegments":0,"openEnded":false,"thetaStart":0,"thetaLength":6.283185307179586},{"uuid":"08354A13-27C0-4D10-A826-015736CE505C","type":"SphereBufferGeometry","radius":0.5,"widthSegments":8,"heightSegments":6,"phiStart":0,"phiLength":6.283185307179586,"thetaStart":0,"thetaLength":3.141592653589793},{"uuid":"1133CF82-90D1-48A3-8875-A6A5B3B4965C","type":"BoxBufferGeometry","width":1,"height":1,"depth":1,"widthSegments":1,"heightSegments":1,"depthSegments":1},{"uuid":"FCB5ACAD-E64E-4B29-8229-6025DC75F9E2","type":"BoxBufferGeometry","width":1,"height":1,"depth":1,"widthSegments":1,"heightSegments":1,"depthSegments":1},{"uuid":"0B3E8D3A-3C1C-4A2A-A35C-4C61987DD587","type":"SphereBufferGeometry","radius":1,"widthSegments":8,"heightSegments":6,"phiStart":0,"phiLength":6.283185307179586,"thetaStart":0,"thetaLength":3.141592653589793},{"uuid":"0CBAF0D7-34A1-4770-9B0A-1C8AA9D01BAF","type":"SphereBufferGeometry","radius":0.5,"widthSegments":8,"heightSegments":6,"phiStart":0,"phiLength":6.283185307179586,"thetaStart":0,"thetaLength":3.141592653589793},{"uuid":"2D80CB24-20AE-443C-B46D-5CC8327BAE6D","type":"SphereBufferGeometry","radius":0.5,"widthSegments":8,"heightSegments":6,"phiStart":0,"phiLength":6.283185307179586,"thetaStart":0,"thetaLength":3.141592653589793},{"uuid":"9B0E6A57-7401-4B05-8144-42120E238C90","type":"SphereBufferGeometry","radius":0.5,"widthSegments":8,"heightSegments":6,"phiStart":0,"phiLength":6.283185307179586,"thetaStart":0,"thetaLength":3.141592653589793},{"uuid":"2B18F7A4-913D-41EE-85D7-0BA84BC6CE63","type":"BoxBufferGeometry","width":1,"height":1,"depth":1,"widthSegments":1,"heightSegments":1,"depthSegments":1},{"uuid":"BEB19F44-9509-4DEC-9726-59C4E46F60DA","type":"SphereBufferGeometry","radius":1,"widthSegments":8,"heightSegments":6,"phiStart":0,"phiLength":6.283185307179586,"thetaStart":0,"thetaLength":3.141592653589793},{"uuid":"90E212E2-7AE3-48FD-8D94-51589671256E","type":"BoxBufferGeometry","width":1,"height":1,"depth":1,"widthSegments":1,"heightSegments":1,"depthSegments":1}],"materials":[{"uuid":"8C38E16B-3DBC-4AE3-BC79-591619611079","type":"MeshStandardMaterial","color":3055072,"roughness":1,"metalness":0,"emissive":0,"depthFunc":3,"depthTest":true,"depthWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680},{"uuid":"FE411F32-EB5C-40BE-98DF-4B00284B2B2A","type":"MeshStandardMaterial","color":16777215,"roughness":1,"metalness":0,"emissive":0,"depthFunc":3,"depthTest":true,"depthWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680},{"uuid":"51A311B5-178C-4E66-9096-039B831F3A3C","type":"MeshStandardMaterial","color":5364123,"roughness":1,"metalness":0,"emissive":0,"depthFunc":3,"depthTest":true,"depthWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680},{"uuid":"453165B8-8A71-4B04-B3D9-8365F3FC3718","type":"MeshStandardMaterial","color":14376595,"roughness":1,"metalness":0,"emissive":0,"depthFunc":3,"depthTest":true,"depthWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680},{"uuid":"BF9D8D63-8D66-4159-A47D-8931AE6940BF","type":"MeshStandardMaterial","color":11513707,"roughness":1,"metalness":0,"emissive":0,"depthFunc":3,"depthTest":true,"depthWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680},{"uuid":"403122F4-2F38-4E40-AFB3-C443622357B2","type":"MeshStandardMaterial","color":15239027,"roughness":1,"metalness":0,"emissive":0,"depthFunc":3,"depthTest":true,"depthWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680},{"uuid":"412ED74D-25F5-4A1C-BB4B-3AEF2983D366","type":"MeshStandardMaterial","color":5548956,"roughness":1,"metalness":0,"emissive":0,"depthFunc":3,"depthTest":true,"depthWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680},{"uuid":"18F6A989-DF37-4DC6-BB64-7432BB46C0A9","type":"MeshStandardMaterial","color":5548956,"roughness":1,"metalness":0,"emissive":0,"depthFunc":3,"depthTest":true,"depthWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680},{"uuid":"93556BAE-00BE-4351-A791-164B78780926","type":"MeshStandardMaterial","color":12944325,"roughness":1,"metalness":0,"emissive":0,"depthFunc":3,"depthTest":true,"depthWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680},{"uuid":"379999AB-51C2-41CD-96A3-58ED64231A92","type":"MeshStandardMaterial","color":8217258,"roughness":1,"metalness":0,"emissive":0,"depthFunc":3,"depthTest":true,"depthWrite":true,"stencilWrite":false,"stencilWriteMask":255,"stencilFunc":519,"stencilRef":0,"stencilFuncMask":255,"stencilFail":7680,"stencilZFail":7680,"stencilZPass":7680}],"object":{"uuid":"E13DA977-B584-4A08-AF6C-C1079C4CDE41","type":"Scene","layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"children":[{"uuid":"31DB754A-37CA-49E7-ACF3-E45B667EB88F","type":"AmbientLight","name":"Ambient Light","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"color":16777215,"intensity":0.7},{"uuid":"5FF8F4C9-ADB5-42FF-B1E0-6C6F52C6ABB9","type":"PerspectiveCamera","name":"Main Camera","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,0.9707378675584202,-0.24014160923948727,0,0,0.24014160923948727,0.9707378675584202,0,0,4.476594007704376,9.42096099820463,1],"children":[{"uuid":"5EF38779-AE4F-4717-89E5-95CB9DE53212","type":"Object3D","name":"AudioListener","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}],"fov":50,"zoom":1,"near":0.1,"far":100,"focus":10,"aspect":1,"filmGauge":35,"filmOffset":0},{"uuid":"79A40AE9-1238-466F-B0CD-827E82326450","type":"DirectionalLight","name":"SUNLIGHT","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,5.5109105961630896e-15,10.157074638613345,-89.42501794680075,1],"color":16777215,"intensity":1,"shadow":{"camera":{"uuid":"4B11B32B-8A89-4F82-9CC9-1F07C8721FE1","type":"OrthographicCamera","layers":1,"zoom":1,"left":-5,"right":5,"top":5,"bottom":-5,"near":0.5,"far":500}}},{"uuid":"D9208548-8A37-4C10-9675-A4B3249856B1","type":"Object3D","name":"Config","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]},{"uuid":"750E4C50-84F3-4CBA-BC8E-8594C785DECA","type":"Mesh","name":"Cube","userData":{"__IS_ADDING__":false,"components":[{"name":"CannonBoxBody","componentPrototypeName":"CannonBoxBody","interface":{"angularDamping":"Number","linearDamping":"Number","mass":"Number","sizeOffset":"Vector3"},"interfaceRefs":{"angularDamping":0,"linearDamping":0,"mass":2,"sizeOffset":[1,1,1]}}]},"layers":1,"matrix":[0.942779322071135,0.3334173808833168,0,0,-0.3334173808833168,0.942779322071135,0,0,0,0,1,0,3.1420349718020293,3.2105380056017516,-3.073424444539409,1],"geometry":"7E241583-0D6A-4721-8F8A-4685E01833D4","material":"8C38E16B-3DBC-4AE3-BC79-591619611079"},{"uuid":"14F9C3A0-D17F-4662-9273-636BAD34525E","type":"Mesh","name":"Box","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[20,0,0,0,0,0.49880230742789355,0.034586964374011986,0,0,-1.3834785749604794,19.95209229711574,0,0,-0.2622214866028467,0,1],"geometry":"0FF94EF3-93F0-47C7-BE03-A6EBE9461558","material":"FE411F32-EB5C-40BE-98DF-4B00284B2B2A"},{"uuid":"FA9285DA-837B-4027-AE75-A10A09322F29","type":"Mesh","name":"Sphere","userData":{"__IS_ADDING__":false,"components":[{"name":"CannonSphereBody","componentPrototypeName":"CannonSphereBody","interface":{"angularDamping":"Number","linearDamping":"Number","mass":"Number","radiusOffset":"Number"},"interfaceRefs":{"angularDamping":0,"linearDamping":0,"mass":1,"radiusOffset":0.5}}]},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,-2.2351476365390193,3.9862222421578064,0,1],"geometry":"A16A4CEA-9492-4EC2-B88D-7A948D430E91","material":"51A311B5-178C-4E66-9096-039B831F3A3C"},{"uuid":"76608646-2613-45CD-B56B-5C11A2A4FA8D","type":"Mesh","name":"Cylinder","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[2.220446049250313e-16,1,0,0,-1.260562396499988,2.799010793141905e-16,0,0,0,0,1,0,0.22850111577183974,5.894508723304153,0,1],"geometry":"58ADFFFA-B844-4661-89B8-7FDEF5AC12C5","material":"453165B8-8A71-4B04-B3D9-8365F3FC3718"},{"uuid":"82C0C817-6464-401D-8523-A3E94FDB4053","type":"Mesh","name":"Sphere","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,-2.2810640747270186,5.092508291200368,0,1],"geometry":"08354A13-27C0-4D10-A826-015736CE505C","material":"51A311B5-178C-4E66-9096-039B831F3A3C"},{"uuid":"A8C652DA-1778-466E-BFA6-508B1739BA69","type":"Mesh","name":"Box","userData":{"__IS_ADDING__":false,"components":[]},"layers":1,"matrix":[0.2,0,0,0,0,2,0,0,0,0,0.2,0,-1.490210940734488,1.5,2.7491911283211046,1],"geometry":"1133CF82-90D1-48A3-8875-A6A5B3B4965C","material":"BF9D8D63-8D66-4159-A47D-8931AE6940BF"},{"uuid":"40E7B1DB-6FC2-484B-8A0F-A835F9CC7D02","type":"Mesh","name":"Box","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[2,0,0,0,0,2,0,0,0,0,0.2,0,-0.33788888807732076,1.5,2.7491911283211046,1],"geometry":"FCB5ACAD-E64E-4B29-8229-6025DC75F9E2","material":"BF9D8D63-8D66-4159-A47D-8931AE6940BF"},{"uuid":"B69FB92A-38AB-4D66-A445-91C88CA48FE8","type":"Mesh","name":"Sphere","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,-2.2116045509749216,8.960785813095363,-3.9540108693725653,1],"geometry":"0B3E8D3A-3C1C-4A2A-A35C-4C61987DD587","material":"403122F4-2F38-4E40-AFB3-C443622357B2"},{"uuid":"20EE5F99-D8B3-4F13-A44C-9598AB37355D","type":"Mesh","name":"Sphere","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,5.94320647988227,6.863334969741521,-1.5116916680150112,1],"geometry":"0CBAF0D7-34A1-4770-9B0A-1C8AA9D01BAF","material":"412ED74D-25F5-4A1C-BB4B-3AEF2983D366"},{"uuid":"31E68B82-FA6C-4C56-9254-8BBDF0F58113","type":"Mesh","name":"Sphere","userData":{"__IS_ADDING__":false,"components":[]},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,4.229332087539629,6.836284334402412,-2.5845035496255666,1],"geometry":"2D80CB24-20AE-443C-B46D-5CC8327BAE6D","material":"18F6A989-DF37-4DC6-BB64-7432BB46C0A9"},{"uuid":"8AE46247-C7A0-462B-9EBD-D58324EB203A","type":"Mesh","name":"Sphere","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,2.445170336361403,6.854867608397868,-3.1170818553432995,1],"geometry":"9B0E6A57-7401-4B05-8144-42120E238C90","material":"18F6A989-DF37-4DC6-BB64-7432BB46C0A9"},{"uuid":"668A865E-28C3-40EC-8CDF-821495737A32","type":"Mesh","name":"Box","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[0.5,0,0,0,0,0.5,0,0,0,0,0.5,0,-4.875840309965067,5.594673777227959,0,1],"geometry":"2B18F7A4-913D-41EE-85D7-0BA84BC6CE63","material":"93556BAE-00BE-4351-A791-164B78780926"},{"uuid":"191FBCF3-0BD9-46E7-AA64-0101004C37E6","type":"Mesh","name":"Sphere","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[0.5,0,0,0,0,0.5,0,0,0,0,0.5,0,-6.255409130640745,3.9237675802916017,0,1],"geometry":"BEB19F44-9509-4DEC-9726-59C4E46F60DA","material":"379999AB-51C2-41CD-96A3-58ED64231A92"},{"uuid":"C7008126-05C1-42FA-A6E2-31CFBCC8AA6B","type":"HemisphereLight","name":"Hemisphere Light","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0.8501991980217896,1],"color":16777215,"intensity":0.5,"groundColor":1},{"uuid":"CCEC84D6-4FA9-4D5B-80F5-B50DC3CF53B7","type":"Object3D","name":"Object3D","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],"children":[{"uuid":"304AD8A2-3DD8-4459-8544-15F8B6A9637A","type":"Mesh","name":"Cube","userData":{"__IS_ADDING__":false},"layers":1,"matrix":[1,0,0,0,0,1,0,0,0,0,1,0,4.818552715078176,3.2105380056017516,-3.073424444539409,1],"geometry":"90E212E2-7AE3-48FD-8D94-51589671256E","material":"8C38E16B-3DBC-4AE3-BC79-591619611079"}]}]}},"skybox":{"_enabled":true,"_mode":"cubemap","layers":1,"_showSun":false,"inclination":0.464,"azimuth":0.25,"mieDirectionalG":0,"mieCoefficient":0,"turbidity":0,"rayleigh":0,"luminance":0,"_sunSpeed":0,"_cubemapTop":false,"_cubemapBottom":false,"_cubemapFront":false,"_cubemapBack":false,"_cubemapRight":false,"_cubemapLeft":false},"components":{"D9208548-8A37-4C10-9675-A4B3249856B1":[{"uuid":"02dd5eac-85f4-4e7e-8148-ef50e24159a9","name":"CannonConfig","componentPrototypeName":"CannonConfig","interface":{"maxSubSteps":"Number","defaultFriction":"Number","defaultRestitution":"Number","gravity":"Vector3"},"interfaceRefs":{"maxSubSteps":1,"defaultFriction":0.01,"defaultRestitution":0,"gravity":[0,-9.82,0]},"enabled":true},{"uuid":"96985ddb-207c-4056-88c3-803779aeaa3f","name":"BallMaterial","componentPrototypeName":"CannonMaterial","interface":{"friction":"Number","restitution":"Number"},"interfaceRefs":{"friction":-1,"restitution":-1},"enabled":true},{"uuid":"919c3967-ef72-40b7-b1c3-2b453290ec85","name":"GroundMaterial","componentPrototypeName":"CannonMaterial","interface":{"friction":"Number","restitution":"Number"},"interfaceRefs":{"friction":-1,"restitution":-1},"enabled":true},{"uuid":"5dd088f0-0857-47c2-b8ad-24a671aa336b","name":"CannonContactMaterial","componentPrototypeName":"CannonContactMaterial","interface":{"materialA":"String","materialB":"String","friction":"Number","restitution":"Number"},"interfaceRefs":{"materialA":"BallMaterial","materialB":"BallMaterial","friction":1,"restitution":0.2},"enabled":true},{"uuid":"dc264eb3-af88-4ed9-b724-6ab381cc2ec8","name":"CannonContactMaterial","componentPrototypeName":"CannonContactMaterial","interface":{"materialA":"String","materialB":"String","friction":"Number","restitution":"Number"},"interfaceRefs":{"materialA":"BallMaterial","materialB":"GroundMaterial","friction":1,"restitution":0.6},"enabled":true}],"750E4C50-84F3-4CBA-BC8E-8594C785DECA":[{"uuid":"2500931f-d969-4e09-b1b8-c5b44137c410","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":0,"angularDamping":0,"linearDamping":0,"mass":2,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"uuid":"44aff64e-fe55-4b93-83ea-b485c1cf52ee","name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true}],"14F9C3A0-D17F-4662-9273-636BAD34525E":[{"uuid":"05190512-c187-4c0e-a39f-8d84dd4a013a","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":"1","angularDamping":0,"linearDamping":0,"mass":0,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"uuid":"02c79044-9e33-42da-84e0-a0b77d96067a","name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true},{"uuid":"b3ecbc13-4174-4ecc-9321-9e8d36949852","name":"SetCannonMaterial","componentPrototypeName":"SetCannonMaterial","interface":{"materialName":"String"},"interfaceRefs":{"materialName":"GroundMaterial"},"enabled":true}],"FA9285DA-837B-4027-AE75-A10A09322F29":[{"uuid":"2b7aa26f-4514-4e71-8fc6-9bd2025b428d","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":0,"angularDamping":0,"linearDamping":0,"mass":1,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"uuid":"6140fc4c-153e-4ccb-a0f9-ab17e03025dd","name":"CannonSphere","componentPrototypeName":"CannonSphere","interface":{"radiusOffset":"Number"},"interfaceRefs":{"radiusOffset":0.5},"enabled":true}],"76608646-2613-45CD-B56B-5C11A2A4FA8D":[{"uuid":"32f9abfc-4ce0-4111-9d1e-a89fc5f7d1ae","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":0,"angularDamping":0,"linearDamping":0,"mass":4,"linearFactor":[1,1,1],"angularFactor":[1,0,1],"isTrigger":false},"enabled":true},{"uuid":"bbb732f1-1423-48c9-94e3-6c68c4160dae","name":"CannonCylinder","componentPrototypeName":"CannonCylinder","interface":{"radiusTopOffset":"Number","radiusBottomOffset":"Number","heightOffset":"Number","segments":"Number"},"interfaceRefs":{"radiusTopOffset":1,"radiusBottomOffset":1,"heightOffset":1,"segments":100},"enabled":true}],"82C0C817-6464-401D-8523-A3E94FDB4053":[{"uuid":"6b4c0bad-3c91-4934-8619-78d612ba1ed5","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":0,"angularDamping":0,"linearDamping":0,"mass":0,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"uuid":"a3211ebe-af4d-4ae2-9a75-5adc795eadee","name":"CannonSphere","componentPrototypeName":"CannonSphere","interface":{"radiusOffset":"Number"},"interfaceRefs":{"radiusOffset":0.5},"enabled":true},{"uuid":"f509b29d-c4d0-4348-9282-dd71b644f8f4","name":"CannonSpring","componentPrototypeName":"CannonSpring","interface":{"target":"Object3D","anchorA":"Vector3","anchorB":"Vector3","restLength":"Number","stiffness":"Number","damping":"Number"},"interfaceRefs":{"target":"FA9285DA-837B-4027-AE75-A10A09322F29","anchorA":[0,-2,0],"anchorB":[0,0,0],"restLength":0,"stiffness":50,"damping":1},"enabled":true}],"40E7B1DB-6FC2-484B-8A0F-A835F9CC7D02":[{"uuid":"4f4e38bc-89f3-4a90-bf61-290783d05131","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":0,"angularDamping":0,"linearDamping":0.5,"mass":0.05,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"uuid":"be89afd4-1719-4b29-8a93-e081bc029671","name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true}],"A8C652DA-1778-466E-BFA6-508B1739BA69":[{"uuid":"8dab1a7b-367b-4cc3-b46d-958cdfab636c","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":"1","angularDamping":0,"linearDamping":0,"mass":0,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"uuid":"4f41c4eb-9bc2-4d6f-b434-3a0e3bd0fbef","name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true},{"uuid":"ce895ac1-e213-4e1c-a9d1-b039661aa2a7","name":"CannonHingeConstraint","componentPrototypeName":"CannonHingeConstraint","interface":{"target":"Object3D","pivotA":"Vector3","axisA":"Vector3","pivotB":"Vector3","axisB":"Vector3","collideConnected":"Boolean","maxForce":"Number"},"interfaceRefs":{"target":"40E7B1DB-6FC2-484B-8A0F-A835F9CC7D02","pivotA":[0.1,0,0],"axisA":[0,1,0],"pivotB":[-1,0,0],"axisB":[0,1,0],"collideConnected":false,"maxForce":1000000},"enabled":true}],"B69FB92A-38AB-4D66-A445-91C88CA48FE8":[{"uuid":"cb866f87-c5f6-46b0-9bd9-065b52b8661f","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":0,"angularDamping":0,"linearDamping":0,"mass":0.45,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"uuid":"3111f090-43cb-4347-b3ca-c98986bce4d8","name":"CannonSphere","componentPrototypeName":"CannonSphere","interface":{"radiusOffset":"Number"},"interfaceRefs":{"radiusOffset":1},"enabled":true},{"uuid":"9b0c11dc-28dc-414a-a5cf-69ea63e3c0cf","name":"SetCannonMaterial","componentPrototypeName":"SetCannonMaterial","interface":{"materialName":"String"},"interfaceRefs":{"materialName":"BallMaterial"},"enabled":true}],"8AE46247-C7A0-462B-9EBD-D58324EB203A":[{"uuid":"e10d37bd-99bd-4822-be65-63977329e6c4","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":0,"angularDamping":0,"linearDamping":0,"mass":1,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"uuid":"12be8cca-5902-468e-8152-007eb4c9d75e","name":"CannonSphere","componentPrototypeName":"CannonSphere","interface":{"radiusOffset":"Number"},"interfaceRefs":{"radiusOffset":0.5},"enabled":true},{"uuid":"5bec0d29-8a85-4420-9503-c50d41af72df","name":"CannonDistanceConstraint","componentPrototypeName":"CannonDistanceConstraint","interface":{"target":"Object3D","distance":"Number","maxForce":"Number"},"interfaceRefs":{"target":"31E68B82-FA6C-4C56-9254-8BBDF0F58113","distance":2,"maxForce":1000000},"enabled":true}],"31E68B82-FA6C-4C56-9254-8BBDF0F58113":[{"uuid":"eef62193-ef5c-49f4-9c93-72da4517312b","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":0,"angularDamping":0,"linearDamping":0,"mass":1,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"uuid":"6d33bbfa-72dd-45c2-9a9e-b1571c503a3c","name":"CannonSphere","componentPrototypeName":"CannonSphere","interface":{"radiusOffset":"Number"},"interfaceRefs":{"radiusOffset":0.5},"enabled":true},{"uuid":"90360a8f-506e-4ff9-976d-7a437707cdef","name":"CannonDistanceConstraint","componentPrototypeName":"CannonDistanceConstraint","interface":{"target":"Object3D","distance":"Number","maxForce":"Number"},"interfaceRefs":{"target":"20EE5F99-D8B3-4F13-A44C-9598AB37355D","distance":2,"maxForce":1000000},"enabled":true},{"uuid":"ddcb8312-643e-49dc-adaf-58b2203d1819","name":"SetCannonMaterial","componentPrototypeName":"SetCannonMaterial","interface":{"materialName":"String"},"interfaceRefs":{"materialName":"BallMaterial"},"enabled":true}],"20EE5F99-D8B3-4F13-A44C-9598AB37355D":[{"uuid":"9ebc7a05-5db1-4fb7-b011-619f9dc574cc","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":0,"angularDamping":0,"linearDamping":0,"mass":1,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"uuid":"d58536cb-5d44-4f89-b619-25d0e863bc08","name":"CannonSphere","componentPrototypeName":"CannonSphere","interface":{"radiusOffset":"Number"},"interfaceRefs":{"radiusOffset":0.5},"enabled":true},{"uuid":"9b37c487-d3bb-4642-a325-54b0541d1c4a","name":"SetCannonMaterial","componentPrototypeName":"SetCannonMaterial","interface":{"materialName":"String"},"interfaceRefs":{"materialName":"BallMaterial"},"enabled":true}],"668A865E-28C3-40EC-8CDF-821495737A32":[{"uuid":"730c6b5a-b676-4cd2-90c5-f02bd8bfa004","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":0,"angularDamping":0,"linearDamping":0,"mass":0,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"uuid":"41c1b5fc-b6f0-4f5f-b7ce-a9ef8aae7278","name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true},{"uuid":"e414f68f-d104-4c94-a069-0414ea669c53","name":"CannonPointToPointConstraint","componentPrototypeName":"CannonPointToPointConstraint","interface":{"target":"Object3D","privotA":"Vector3","privotB":"Vector3","maxForce":"Number"},"interfaceRefs":{"target":"191FBCF3-0BD9-46E7-AA64-0101004C37E6","privotA":[0,0,0],"privotB":[0,3,0],"maxForce":1000000},"enabled":true}],"191FBCF3-0BD9-46E7-AA64-0101004C37E6":[{"uuid":"4589eb78-e0a9-4323-bd7b-d8bf457c4235","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":0,"angularDamping":0,"linearDamping":0,"mass":1,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"uuid":"3bdbcb4b-ff6e-40ec-81b8-cfa124168015","name":"CannonSphere","componentPrototypeName":"CannonSphere","interface":{"radiusOffset":"Number"},"interfaceRefs":{"radiusOffset":1},"enabled":true}],"304AD8A2-3DD8-4459-8544-15F8B6A9637A":[{"uuid":"7ad1f834-3cd9-45d5-b8ed-f5a337a2ca59","name":"CannonBody","componentPrototypeName":"CannonBody","interface":{"type":"Select","angularDamping":"Number","linearDamping":"Number","mass":"Number","linearFactor":"Vector3","angularFactor":"Vector3","isTrigger":"Boolean"},"interfaceRefs":{"type":0,"angularDamping":0,"linearDamping":0,"mass":2,"linearFactor":[1,1,1],"angularFactor":[1,1,1],"isTrigger":false},"enabled":true},{"uuid":"cd23f434-8573-4e49-88ab-57e14413f1cf","name":"CannonBox","componentPrototypeName":"CannonBox","interface":{"sizeOffset":"Vector3"},"interfaceRefs":{"sizeOffset":[1,1,1]},"enabled":true},{"uuid":"6248c45c-f3c3-4901-a40e-0ef59b3e6eb0","name":"CannonLockConstraint","componentPrototypeName":"CannonLockConstraint","interface":{"target":"Object3D","maxForce":"Number"},"interfaceRefs":{"target":"750E4C50-84F3-4CBA-BC8E-8594C785DECA","maxForce":1000000},"enabled":true}]},"initialCameraId":"5FF8F4C9-ADB5-42FF-B1E0-6C6F52C6ABB9"} --------------------------------------------------------------------------------