UNPKG

meta-client

Version:
427 lines (331 loc) 10.2 kB
import config from '../../../config'; import log from '../../Utilities/log'; import {CubeGeometry, MeshBasicMaterial, Mesh, Box3} from 'three'; import Space from '../Space'; // import Physics from '../Physics/Physics'; import Graphics from './Graphics/Graphics'; import Existence from './Existence/Existence'; import * as OIMO from 'oimo'; const name = 'Meta'; let scope; let world = new OIMO.World(); let bodies = []; /** This class represents a Meta object. * @constructor * @param {Object} props * @param {String} props.life Represents the Meta object's lifecycle. * @param {String} props.graphics Represents the Meta object's visual appearance. * @param {String} props.physics Represents the Meta object's physics body. * @param {Array} lifes Includes the Meta object's lifes. * @param {Array} events Includes the Meta object's events. */ export default class Meta { constructor(props){ scope = this; this.name = 'Meta'; //lifes this.lifes = []; //events this.events = []; //states (TODO: merge into {state}) this._entered = null; this._touched = false; //props this.rotation = {x:0,y:0,z:0}; this.position = {x:0,y:0,z:0}; //e,g,p (existence, graphics, physics) this.existence = props!==undefined&&props.existence!==undefined?props.existence:new Existence(); this.graphics = props!==undefined&&props.graphics!==undefined?props.graphics:new Graphics(); this.physics = props!==undefined&&props.physics!==undefined?props.physics:true; //Set existence this.setExistence(); //Set graphics //this.setGraphics(); //Set physics //this.setPhysics(); //Start Presence this.setPresence(); return this; } setExistence(){ if(this.existence.start===null&&this.existence.end===null) Space.get().start(scope); } setPresence(){ Space.get().add(this); } o(eventName, callback){ return this.on(eventName, callback) } on(eventName, callback){ if(typeof(eventName)=="function"){ callback = eventName; eventName = 'p'; } if(eventName=='t') eventName='touch'; if(eventName=='r') eventName='release'; if(eventName=='p') eventName='point'; if(this.events[eventName]){ this.events[eventName].push(callback); }else{ this.events[eventName] = [callback]; } return this; } go(eventName, ...rest){ if(this.events[eventName]){ this.events[eventName].forEach(cb =>{ cb(...rest, this); }) } return this; } m(direction, amount){ return(this.move(direction, amount)) } move(direction, amount){ switch (direction) { default: case 0: case 'f': case 'forward': case 'forwards': this.setPosition({x:this.position.x,y:this.position.y,z:this.position.z+amount}) break; case 1: case 'b': case 'backward': case 'backwards': this.setPosition({x:this.position.x,y:this.position.y,z:this.position.z-amount}) break; case 2: case 'l': case 'left': this.setPosition({x:this.position.x-amount,y:this.position.y,z:this.position.z}) break; case 3: case 'r': case 'right': this.setPosition({x:this.position.x+amount,y:this.position.y,z:this.position.z}) break; case 4: case 'd': case 'down': this.setPosition({x:this.position.x,y:this.position.y-amount,z:this.position.z}) break; case 5: case 'u': case 'up': this.setPosition({x:this.position.x,y:this.position.y+amount,z:this.position.z}) break; } return this; } s(props){ return this.set(props) } set(position){ this.setPosition(position); return this; } setPosition(position){ this.graphics.setPosition(position) this.position = { x: this.graphics.mesh.position.x, y: this.graphics.mesh.position.y, z: this.graphics.mesh.position.z } log('[this.position]'+this.position) return this; } r(direction, amount){ return this.rotate(direction, amount); } rotate(direction, amount){ switch (direction) { default: case 0: case 'f': case 'forward': case 'forwards': this.setRotation({x:this.rotation.x+amount, y:0, z:0}); break; case 1: case 'b': case 'backward': case 'backwards': this.setRotation({x:this.rotation.x-amount, y:0, z:0}); break; case 2: case 'l': case 'left': this.setRotation({x:0, y:this.rotation.y-amount, z:0}); break; case 3: case 'r': case 'right': this.setRotation({x:0, y:this.rotation.y+amount, z:0}); break; case 4: case 'd': case 'down': this.setRotation({x:0, y: 0, z:this.rotation.z+amount}); break; case 5: case 'u': case 'up': this.setRotation({x:0, y: 0, z:this.rotation.z-amount}); break; } return this; } setRotation(rotation){ this.graphics.setRotation(rotation) this.rotation = { x: this.graphics.mesh.rotation.x, y: this.graphics.mesh.rotation.y, z: this.graphics.mesh.rotation.z } log(JSON.stringify(this.rotation), name) return this; } setSize(){ //Define Meta's Size According To Graphic's Dimensions let box3 = new Box3().setFromObject(this.graphics.mesh); let x = box3.max.x - box3.min.x; let y = box3.max.y - box3.min.y; let z = box3.max.z - box3.min.z; switch(this.graphics.type){ case 'box': this.size = [x,y,z] break; case 'sphere': this.size = [x/2] break; case 'cylinder': this.size = [x/2,y,z/2] break; } //console.log('[Size]'+this.size); } p(m){ return this.setPhysics(m); } setPhysics(physics){ this.setSize(); //If physics have been set already and the same parameter was passed leave directly if(this.body!==undefined&&physics===this.physics) return; physics = physics!==undefined?physics:this.physics; if(physics===null){ this.physics = null; return this; } let mode = physics; //Meaning it had physics before, which were stopped setting physics to false. if(this.body!==undefined){ this.body.remove(); ////console.log('[Meta].physics() - Already have a body, so set this.body = null to get a new one]') } // console.log('[Meta].physics()-this.physics:'+this.physics); // console.log('[Meta].physics()-_mode:'+mode); //alert(this.rotation.y) const body = { type: this.graphics.type, size: this.size, pos: [this.position.x,this.position.y,this.position.z], rot: [this.rotation.x,this.rotation.y,this.rotation.z], move: mode, density: mode!==undefined&&mode.density!==undefined?mode.density:1, friction: mode!==undefined&&mode.friction!==undefined?mode.friction:.5, restitution: mode!==undefined&&mode.restitution!==undefined?mode.restitution:.5, belongsTo: mode!==undefined&&mode.belongsTo!==undefined?mode.belongsTo:1, collidesWith: mode!==undefined&&mode.collidesWith!==undefined?mode.collidesWith:0xffffffff, } //log(body, name); //@todo Should be: Physics.add(body); this.body = world.add(body); //CLUE: This constantly add the current body position into this.body //IMPORTANT: Save the new state! this.physics = physics; return this; } //Add life to Meta's life. l(mode = 'on', life){ return this.live(mode = 'on', life); } live(mode = 'on', life){ switch(mode) { case 'on': case 'o': case 1: this.lifes.push(life); break; case 'again': case 'a': case 0: this.lifes = []; this.lifes.push(life); break; } return this; } appear(){return this.end()} start(){ Space.get().start(this); this.existence.started = true; } die(){return this.end()} disappear(){return this.end()} end(){ Space.get().end(this); this.existence.ended = true; } //A Meta's Life life(){ //Run ([E]existence, [G]raphics, [P]hysics) //Run Existence //start if(this.existence.start!==null) if(new Date(this.existence.start)<new Date()){ if(!this.existence.started) this.start() } //end if(this.existence.end!==null) if(new Date()>new Date(this.existence.start)){ if(new Date()>new Date(this.existence.end)){ if(!this.existence.ended) this.end(); } } } /* Color (set) */ c(color){return this.color(color);} color(color = Math.random()*0xffffff ){ switch(color){ case 0: case 'g': case 'gold': color = 0xffd700; break; case 1: case 'r': case 'red': color = 0xff0000; break; case 2: case 'g': case 'green': color = 0x00ff00; break; case 3: case 'b': case 'blue': color = 0x0000ff; break; case 4: case 'y': case 'yellow': color = 0xffff00; break; case 5: case 'w': case 'white': color = 0xffffff; break; } this.graphics.color(color); this._color = color; return this; } add(instance){ this.graphics = instance; } i(ms,f){return this.in(ms,f)} in(ms,f){ setTimeout(()=>{ f(); },ms) } e(ms,f){return this.every(ms,f)} ev(ms,f){return this.every(ms,f)} every(ms,f){ f(); setInterval(()=>{ f(); },ms) } static getWorld(){ return world; } static getBodies(){ return bodies; } static clear (){ bodies = []; world = new OIMO.World(); } }