diff --git a/.gitignore b/.gitignore index c2658d7..b38db2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules/ +build/ diff --git a/build/game-lib-min.js b/build/game-lib-min.js deleted file mode 100644 index 462bd20..0000000 --- a/build/game-lib-min.js +++ /dev/null @@ -1,14 +0,0 @@ -function GameLib(){}var __DATE__="Tue Dec 12 2017 11:44:47 GMT+0100 (CET)";if(void 0===GameLib.D3&&(GameLib.D3=function(){}),void 0===GameLib.D3.API&&(GameLib.D3.API=function(){}),void 0===GameLib.API&&(GameLib.API=function(){}),void 0===GameLib.D3.Runtime&&(GameLib.D3.Runtime=function(){}),void 0===Q){if("undefined"==typeof require)throw console.warn("You need the Q promise library for the GameLib.D3"),new Error("You need the Q promise library for the GameLib.D3");var Q=require("q")}if(void 0===_){if("undefined"==typeof require)throw console.warn("You need the lodash library for the GameLib.D3"),new Error("You need the lodash library for the GameLib.D3");var _=require("lodash")}console.log("Loading GameLib compiled at: "+__DATE__),GameLib.Event=function(){},GameLib.Event.Subscriptions={},GameLib.Event.OnceSubscriptions={},GameLib.Event.WINDOW_RESIZE=1,GameLib.Event.PARENT_SCENE_CHANGE=2,GameLib.Event.PARENT_ENTITY_CHANGE=3,GameLib.Event.INSTANCE_CLONED=4,GameLib.Event.LOAD_IMAGE=5,GameLib.Event.NEW_ENTITY=6,GameLib.Event.MATERIAL_TYPE_CHANGED=7,GameLib.Event.SAVE_COMPONENT=8,GameLib.Event.SAVE_COMPONENT_ERROR=9,GameLib.Event.COMPONENT_SAVED=10,GameLib.Event.LOAD_COMPONENT=11,GameLib.Event.LOAD_COMPONENT_ERROR=12,GameLib.Event.LOGGED_IN=13,GameLib.Event.COMPONENT_CREATED=14,GameLib.Event.COMPONENT_CLONED=15,GameLib.Event.TEXTURE_ANIMATED_CHANGE=16,GameLib.Event.ANIMATE_TEXTURE_INSTANCE=17,GameLib.Event.REMOVE_PARTICLE_ENGINE=18,GameLib.Event.GAME_PAUSE=19,GameLib.Event.TEXTURE_INSTANCE_UPDATED=20,GameLib.Event.PLAY_AUDIO=21,GameLib.Event.MATERIAL_INSTANCE_UPDATED=22,GameLib.Event.PAUSE_AUDIO=23,GameLib.Event.MESH_INSTANCE_UPDATED=24,GameLib.Event.STOP_AUDIO=25,GameLib.Event.LIGHT_INSTANCE_UPDATED=26,GameLib.Event.DELETE_COMPONENT=27,GameLib.Event.COMPONENT_DOWNLOAD_COMPLETE=28,GameLib.Event.COMPONENTS_LINKED=29,GameLib.Event.UNRESOLVED_DEPENDENCIES_UPDATE=30,GameLib.Event.REGISTER_UPDATE=31,GameLib.Event.BUILD_GUI=32,GameLib.Event.REMOVE_MESH=33,GameLib.Event.MESH_SELECTED=34,GameLib.Event.MESH_DESELECTED=35,GameLib.Event.COMPONENT_REGISTER=36,GameLib.Event.IMAGE_NOT_FOUND=37,GameLib.Event.BLENDER_DATA_RECEIVED=38,GameLib.Event.IMAGE_UPLOAD_COMPLETE=39,GameLib.Event.REMOVE_COMPONENT=40,GameLib.Event.KEY_DOWN=41,GameLib.Event.KEY_UP=42,GameLib.Event.RENDER=43,GameLib.Event.EVENT_LIST=44,GameLib.Event.COMPILE_SUCCESS=45,GameLib.Event.COMPILE_FAILED=46,GameLib.Event.IMAGE_CHANGED=47,GameLib.Event.PARENT_ENTITY_CHANGED=48,GameLib.Event.MATERIAL_TEXTURES_UPDATED=49,GameLib.Event.DELETE_COMPONENT_ERROR=50,GameLib.Event.COMPONENT_DELETED=51,GameLib.Event.COMPONENT_TYPES_FETCHED=52,GameLib.Event.AUDIO_ENDED=53,GameLib.Event.COMPONENT_LINKED=54,GameLib.Event.DONE_SAVING=55,GameLib.Event.BEFORE_RENDER=56,GameLib.Event.AFTER_RENDER=57,GameLib.Event.ARRAY_ITEM_ADDED=58,GameLib.Event.INSTANCE_CREATED=59,GameLib.Event.VISUALIZE=60,GameLib.Event.STOP_VISUALIZE=61,GameLib.Event.FETCH_COMPONENT_TYPES=62,GameLib.Event.FETCH_COMPONENTS=63,GameLib.Event.GET_API_URL=64,GameLib.Event.GET_RUNTIME=65,GameLib.Event.PARENT_WORLD_CHANGE=66,GameLib.Event.ANIMATE=67,GameLib.Event.ANIMATION_COMPILE_SUCCESS=68,GameLib.Event.ANIMATION_COMPILE_FAILED=69,GameLib.Event.SAVING=70,GameLib.Event.GAME_OVER=71,GameLib.Event.GAME_START=72,GameLib.Event.TOUCH_START=73,GameLib.Event.TOUCH_END=74,GameLib.Event.TOUCH_MOVE=75,GameLib.Event.TOUCH_CANCEL=76,GameLib.Event.GET_REMOTE_API_URL=77,GameLib.Event.COMPONENT_TYPES_UPDATE=78,GameLib.Event.DELAYED_INSTANCE_ENCOUNTERED=79,GameLib.Event.CAST_SOURCE_CHANGED=80,GameLib.Event.ANIMATION_MESH_ADDED=81,GameLib.Event.ANIMATION_MESH_REMOVED=82,GameLib.Event.GET_SCENE=83,GameLib.Event.CUSTOM_CODE_WINDOW_RESIZE=84,GameLib.Event.LOAD_FONT=85,GameLib.Event.FONT_NOT_FOUND=86,GameLib.Event.STOP_ALL_AUDIO=87,GameLib.Event.REGISTER_DEPENDENCIES=88,GameLib.Event.GAME_LOADED=89,GameLib.Event.COMPONENT_UPDATE=90,GameLib.Event.LOAD_PROGRESS=91,GameLib.Event.ENTITY_LOADED=92,GameLib.Event.MOUSE_DOWN=93,GameLib.Event.MOUSE_MOVE=94,GameLib.Event.MOUSE_WHEEL=95,GameLib.Event.MOUSE_UP=96,GameLib.Event.PARTICLE_INSTANCE_UPDATED=97,GameLib.Event.GAME_DATA=98,GameLib.Event.PAUSE_ALL_AUDIO=99,GameLib.Event.CONTINUE_ALL_AUDIO=100,GameLib.Event.MUTE_AUDIO=101,GameLib.Event.GAME_STARTED=102,GameLib.Event.GAME_PAUSED=103,GameLib.Event.GAME_RESUMED=104,GameLib.Event.CUSTOM_GAME_START=105,GameLib.Event.AUDIO_MUTED=106,GameLib.Event.AUDIO_UNMUTED=107,GameLib.Event.RECEIVE_DESTINATION_CHANGED=108,GameLib.Event.GetEventName=function(e){switch(e){case 1:return"window_resize";case 2:return"parent_scene_change";case 3:return"parent_entity_change";case 4:return"instance_cloned";case 5:return"load_image";case 6:return"new_entity";case 7:return"material_type_changed";case 8:return"save_component";case 9:return"save_component_error";case 10:return"component_saved";case 11:return"load_component";case 12:return"load_component_error";case 13:return"logged_in";case 14:return"component_created";case 15:return"component_cloned";case 16:return"texture_animated_change";case 17:return"animate_texture_instance";case 18:return"remove_particle_engine";case 19:return"pause";case 20:return"texture_instance_updated";case 21:return"play_audio";case 22:return"material_instance_updated";case 23:return"pause_audio";case 24:return"mesh_instance_updated";case 25:return"stop_audio";case 26:return"light_instance_updated";case 27:return"delete_component";case 28:return"component_download_complete";case 29:return"components_linked";case 30:return"unresolved_dependencies_update";case 31:return"register_update";case 32:return"build_gui";case 33:return"remove_mesh";case 34:return"mesh_selected";case 35:return"mesh_deselected";case 36:return"component_register";case 37:return"image_not_found";case 38:return"blender_data_received";case 39:return"image_upload_complete";case 40:return"remove_component";case 41:return"key_down";case 42:return"key_up";case 43:return"render";case 44:return"event_list";case 45:return"compile_success";case 46:return"compile_failed";case 47:return"image_changed";case 48:return"parent_entity_changed";case 49:return"material_textures_updated";case 50:return"delete_component_error";case 51:return"component_deleted";case 52:return"component_types_updated";case 53:return"audio_ended";case 54:return"component_linked";case 55:return"done_saving";case 56:return"before_render";case 57:return"after_render";case 58:return"array_item_added";case 59:return"instance_created";case 60:return"visualize";case 61:return"stop_visualize";case 62:return"fetch_component_types";case 63:return"fetch_components";case 64:return"get_api_url";case 65:return"get_runtime";case 66:return"parent_world_change";case 67:return"animate";case 68:return"animation_compile_success";case 69:return"animation_compile_failed";case 70:return"saving";case 71:return"game_over";case 72:return"game_start";case 73:return"touch_start";case 74:return"touch_end";case 75:return"touch_move";case 76:return"touch_cancel";case 77:return"get_remote_api_url";case 78:return"component_types_update";case 79:return"delayed_instance_encountered";case 80:return"cast_source_changed";case 81:return"animation_mesh_added";case 82:return"animation_mesh_removed";case 83:return"get_scene";case 84:return"custom_code_window_resize";case 85:return"load_font";case 86:return"font_not_found";case 87:return"stop_all_audio";case 88:return"register_dependencies";case 89:return"game_loaded";case 90:return"component_update";case 91:return"load_progress";case 92:return"entity_loaded";case 93:return"mouse_down";case 94:return"mouse_move";case 95:return"mouse_wheel";case 96:return"mouse_up";case 97:return"particle_instance_updated";case 98:return"game_data";case 99:return"pause_all_audio";case 100:return"continue_all_audio";case 101:return"mute_audio";case 102:return"game_started";case 103:return"game_paused";case 104:return"game_resumed";case 105:return"custom_game_start";case 106:return"audio_muted";case 107:return"audio_unmuted";case 108:return"receive_destination_changed"}throw new error("unknown event id: "+e)},GameLib.Event.prototype.subscribe=function(e,t){return GameLib.Event.Subscribe(e,t.bind(this))},GameLib.Event.prototype.publish=function(e,t,i,n){return GameLib.Event.Emit(e,t,i,n)},GameLib.Event.Emit=function(e,t,i,n){var a=0;return GameLib.Event.Subscriptions.hasOwnProperty(e)?(0===GameLib.Event.Subscriptions[e].length&&(i&&i(),n&&n({message:"No subscriptions for event "+e})),GameLib.Event.Subscriptions[e].map(function(e){e&&(e(t,i,n),a++)})):(i&&i(),n&&n({message:"No subscriptions for event "+e})),a},GameLib.Event.Subscribe=function(e,t){return GameLib.Event.Subscriptions.hasOwnProperty(e)?GameLib.Event.Subscriptions[e].push(t):(GameLib.Event.Subscriptions[e]=[],GameLib.Event.Subscriptions[e].push(t)),{fn:t,remove:function(){var i=GameLib.Event.Subscriptions[e].indexOf(t);if(-1===i)throw new Error("could not remove subscription");GameLib.Event.Subscriptions[e].splice(i,1)}}},GameLib.Utils=function(){},GameLib.Utils.StripImageExtension=function(e){return e.replace(/(\.png$|\.gif$|\.jpeg$|\.jpg$)/,"")},GameLib.Utils.BuildVectorSource=function(e,t,i){return 2===i?(e[t]={},e[t].x=!1,void(e[t].y=!1)):3===i?(e[t]={},e[t].x=!1,e[t].y=!1,void(e[t].y=!1)):4===i?(e[t]={},e[t].x=!1,e[t].y=!1,e[t].z=!1,void(e[t].w=!1)):void console.warn("unknown dimension : "+i)},GameLib.Utils.BuildQuaternionSource=function(e,t){e[t]={},e[t].axis={},e[t].axis.x=!1,e[t].axis.y=!1,e[t].axis.z=!1,e[t].angle=!1,e[t].x=!1,e[t].y=!1,e[t].z=!1,e[t].w=!1},GameLib.Utils.ObjectPropertiesAsBoolean=function(e){return Object.keys(e).reduce(function(t,i){return"function"==typeof e[i]?t:(t[i]=!1,t)}.bind(this),{})},GameLib.Utils.ObjectIdWithNameInArray=function(e,t){return t.reduce(function(t,i){return t||(e===i.name?i.id:null)},null)},GameLib.Utils.LoadIdsFromArrayToIdObject=function(e,t){},GameLib.Utils.LoadIdsFromObjectToIdObject=function(e,t){},GameLib.Utils.GetRandomInt=function(e,t){return e=Math.ceil(e),t=Math.floor(t),Math.floor(Math.random()*(t-e))+e},GameLib.Utils.GetRandomIntInclusive=function(e,t){return e=Math.ceil(e),t=Math.floor(t),Math.floor(Math.random()*(t-e+1))+e},GameLib.Utils.InterpolateArray=function(e,t){var i=[],n=Number((e.length-1)/(t-1));i[0]=e[0];for(var a=1;aMath.PI;)e-=2*Math.PI;for(;e<-Math.PI;)e+=2*Math.PI;i=e}}},GameLib.Utils.IdArrayOrEmptyArray=function(e){return GameLib.Utils.UndefinedOrNull(e)?[]:e.map(function(e){if(GameLib.Utils.UndefinedOrNull(e.id))throw new Error("No ID found while trying to store IDs to array");return e.id})},GameLib.Utils.Link=function(e,t,i,n){GameLib.Utils.UndefinedOrNull(i[e])||(t.hasOwnProperty(n)||console.warn("Linking failed for object:"+i.name),i[e]=t[n])},GameLib.Utils.RandomId=function(e){return GameLib.Utils.UndefinedOrNull(e)&&(e=10),Math.random().toString(36).substr(2,e)},GameLib.Utils.InvertWindingOrder=function(e){for(var t=0;t0;){var a=i.pop();if(a.triangle.v0index===a.edge.x&&a.triangle.v1index===a.edge.y||a.triangle.v1index===a.edge.x&&a.triangle.v2index===a.edge.y||a.triangle.v2index===a.edge.x&&a.triangle.v0index===a.edge.y){var s=a.triangle.v1index;a.triangle.v1index=a.triangle.v2index,a.triangle.v2index=s;var o=a.triangle.uvs[0][1];a.triangle.uvs[0][1]=a.triangle.uvs[0][2],a.triangle.uvs[0][2]=o}n.push(a);for(var r=[new GameLib.API.Vector2(a.triangle.v0index,a.triangle.v1index),new GameLib.API.Vector2(a.triangle.v1index,a.triangle.v2index),new GameLib.API.Vector2(a.triangle.v2index,a.triangle.v0index)],c=0;c9||console.log("The vertices are not in the right length : "+e.length);for(var i=[],n=new GameLib.API.Quaternion.Points,a=0;ae&&t.splice(0,1);var n=0;for(var a in t)n+=t[a];var s=e;return t.lengthe.length&&(i=t,t=e,e=i),e.filter(function(e){return t.indexOf(e)>-1}).filter(function(e,t,i){return i.indexOf(e)===t})},GameLib.Utils.Difference=function(e,t){var i;return t.length>e.length&&(i=t,t=e,e=i),e.filter(function(e){return-1===t.indexOf(e)}).filter(function(e,t,i){return i.indexOf(e)===t})},GameLib.Utils.PushUnique=function(e,t){-1===e.indexOf(t)&&e.push(t)},GameLib.Utils.IsEmpty=function(e){return 0===Object.keys(e).length&&e.constructor===Object},GameLib.Utils.isString=function(e){return"string"==typeof e},GameLib.Utils.isBoolean=function(e){return!0===e||!1===e},GameLib.Utils.isColor=function(e){return e instanceof GameLib.Color},GameLib.Utils.isNumber=function(e){return"number"==typeof e},GameLib.Utils.isVector2=function(e){return e instanceof GameLib.API.Vector2||e instanceof GameLib.Vector2},GameLib.Utils.isVector3=function(e){return e instanceof GameLib.API.Vector3||e instanceof GameLib.Vector3},GameLib.Utils.isVector4=function(e){return e instanceof GameLib.API.Vector4||e instanceof GameLib.Vector4||e instanceof GameLib.API.Quaternion||e instanceof GameLib.Quaternion},GameLib.Utils.LowerUnderscore=function(e){return e.toLowerCase().replace(/\s+/,"_")},GameLib.Utils.UpperCaseWordsSpaces=function(e){return e.replace(/[-_]/g," ").split(" ").reduce(function(e,t){return(e+=t[0].toUpperCase()+t.substr(1))+" "},"").trim()},GameLib.Utils.UpperCaseUnderscore=function(e){var t="";return e.split("").map(function(e){e==e.toUpperCase()?t+="_"+e:t+=e.toUpperCase()}),t=t.replace(new RegExp("^_"),"")},GameLib.API.Component=function(e,t){this.componentType=e,GameLib.Utils.UndefinedOrNull(t)&&(t=null),this.parentEntity=t},GameLib.API.Component.prototype=Object.create(GameLib.Event.prototype),GameLib.API.Component.prototype.constructor=GameLib.API.Component,GameLib.Component=function(e,t){GameLib.Utils.UndefinedOrNull(e)&&(e={}),this.linkedObjects=e,this.linkedObjects.parentEntity=GameLib.Entity,this.idToObject={},this.selected=!1,this.building=!1,this.loaded=!1,this.linked=!1,this.cloneNumber=0,this.isClone=!1,GameLib.Utils.UndefinedOrNull(t)&&(t=!1),this.delayed=t,this.dependencies=this.getDependencies(),GameLib.Event.Emit(GameLib.Event.COMPONENT_REGISTER,{component:this}),0===this.dependencies.length?this.performInstanceCreation():GameLib.Event.Emit(GameLib.Event.REGISTER_DEPENDENCIES,{component:this})},GameLib.Component.prototype=Object.create(GameLib.API.Component.prototype),GameLib.Component.prototype.constructor=GameLib.Component,GameLib.Component.prototype.performInstanceCreation=function(){var e=!0;if(GameLib.Utils.UndefinedOrNull(this.dependencies)&&(e=!1),this.dependencies&&this.dependencies instanceof Array&&0===this.dependencies.length&&(e=!1),e)throw new Error("performInstanceCreation called while this object still has dependencies");if(delete this.dependencies,this.buildIdToObject(),this.linked)if(this.delayed)GameLib.Event.Emit(GameLib.Event.DELAYED_INSTANCE_ENCOUNTERED,{component:this});else try{this.createInstance()}catch(e){console.error(e)}},GameLib.Component.prototype.createInstance=function(){this.delayed=!1,this.instance&&(this.loaded=!0,GameLib.Event.Emit(GameLib.Event.INSTANCE_CREATED,{component:this})),this instanceof GameLib.Entity&&GameLib.Event.Emit(GameLib.Event.ENTITY_LOADED,{entity:this})},GameLib.Component.prototype.getDependencies=function(){var e=[];for(var t in this.linkedObjects)this.linkedObjects.hasOwnProperty(t)&&0!==t.indexOf("parent")&&this.hasOwnProperty(t)&&("string"==typeof this[t]&&GameLib.Utils.PushUnique(e,this[t]),this[t]instanceof Array&&this[t].map(function(t){"string"==typeof t&&GameLib.Utils.PushUnique(e,t),t&&t instanceof GameLib.Component&&GameLib.Utils.PushUnique(e,t.id)}),this[t]&&this[t]instanceof GameLib.Component&&GameLib.Utils.PushUnique(e,this[t].id));return e},GameLib.Component.prototype.toString=function(){return this.id},GameLib.Component.SOCKET_RECEIVE=1,GameLib.Component.MATERIAL=2,GameLib.Component.RENDERER=3,GameLib.Component.SERVER=4,GameLib.Component.CAMERA=5,GameLib.Component.SOCKET=6,GameLib.Component.MESH=7,GameLib.Component.SPLINE=8,GameLib.Component.LIGHT=9,GameLib.Component.COMPOSER=11,GameLib.Component.RENDER_TARGET=12,GameLib.Component.PASS=13,GameLib.Component.SCENE=14,GameLib.Component.RAYCASTER=15,GameLib.Component.VIEWPORT=18,GameLib.Component.SYSTEM=19,GameLib.Component.GRAPHICS=20,GameLib.Component.HELPER=21,GameLib.Component.CUSTOM_CODE=22,GameLib.Component.MOUSE=23,GameLib.Component.SKELETON=24,GameLib.Component.TEXTURE=25,GameLib.Component.ENTITY_MANAGER=26,GameLib.Component.DOM_ELEMENT=27,GameLib.Component.STATS=29,GameLib.Component.GUI=30,GameLib.Component.IMAGE=31,GameLib.Component.ENTITY=32,GameLib.Component.MESH_SPHERE=33,GameLib.Component.MESH_PLANE=34,GameLib.Component.MESH_CURVE=35,GameLib.Component.PHYSICS_WORLD=36,GameLib.Component.BROADPHASE=37,GameLib.Component.SOLVER=38,GameLib.Component.RIGID_BODY=39,GameLib.Component.SHAPE=40;GameLib.Component.SHAPE_BOX=41,GameLib.Component.SHAPE_SPHERE=42,GameLib.Component.SHAPE_TRI_MESH=43,GameLib.Component.SHAPE_CONVEX_HULL=44,GameLib.Component.SHAPE_CONVEX_HULL_CYLINDER=45,GameLib.Component.SHAPE_HEIGHT_MAP=46,GameLib.Component.SHAPE_PLANE=47,GameLib.Component.CONTROLS=48,GameLib.Component.CONTROLS_EDITOR=49,GameLib.Component.CONTROLS_TOUCH=50,GameLib.Component.FRICTION_MATERIAL=51,GameLib.Component.FRICTION_CONTACT_MATERIAL=52,GameLib.Component.RAYCAST_VEHICLE=53,GameLib.Component.RAYCAST_WHEEL=54,GameLib.Component.CLOCK=55,GameLib.Component.ANIMATION=56,GameLib.Component.CONTROLS_KEYBOARD=57,GameLib.Component.CONTROLS_MOUSE=58,GameLib.Component.MESH_TEXT=59,GameLib.Component.FONT=60,GameLib.Component.CANVAS=61,GameLib.Component.BONE=62,GameLib.Component.MESH_BOX=63,GameLib.Component.MESH_CYLINDER=64,GameLib.Component.SYSTEM_ANIMATION=65,GameLib.Component.SYSTEM_CUSTOM_CODE=66,GameLib.Component.SYSTEM_GUI=67,GameLib.Component.SYSTEM_INPUT=68,GameLib.Component.SYSTEM_LINKING=69,GameLib.Component.SYSTEM_PHYSICS=70,GameLib.Component.SYSTEM_RENDER=71,GameLib.Component.SYSTEM_STORAGE=72,GameLib.Component.SYSTEM_VISUALIZATION=73,GameLib.Component.FOG=80,GameLib.Component.MESH_LINE=81,GameLib.Component.PARTICLE_ENGINE=82,GameLib.Component.SYSTEM_PARTICLE=83,GameLib.Component.PARTICLE=84,GameLib.Component.AUDIO=85,GameLib.Component.SYSTEM_AUDIO=86,GameLib.Component.SOCKET_CAST=87,GameLib.Component.MAX_COMPONENTS=88,GameLib.Component.GRAPHICS_RUNTIME=1,GameLib.Component.PHYSICS_RUNTIME=2,GameLib.Component.SOCKET_RUNTIME=3,GameLib.Component.STATISTICS_RUNTIME=4,GameLib.Component.DEFAULT_RUNTIME=5,GameLib.Component.GUI_RUNTIME=6,GameLib.Component.CODER_RUNTIME=7,GameLib.Component.GetCompentTypes=function(e){GameLib.Component},GameLib.Component.GetComponentInfo=function(e){switch(e){case 1:return{name:"GameLib.Socket.Receive",runtime:GameLib.Component.SOCKET_RUNTIME,constructor:GameLib.Socket.Receive,apiConstructor:GameLib.API.Socket.Receive};case 2:return{name:"GameLib.D3.Material",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Material,apiConstructor:GameLib.D3.API.Material};case 3:return{name:"GameLib.D3.Renderer",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Renderer,apiConstructor:GameLib.D3.API.Renderer};case 4:return{name:"GameLib.Server",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.Server,apiConstructor:GameLib.API.Server};case 5:return{name:"GameLib.D3.Camera",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Camera,apiConstructor:GameLib.D3.API.Camera};case 6:return{name:"GameLib.Socket",runtime:GameLib.Component.SOCKET_RUNTIME,constructor:GameLib.Socket,apiConstructor:GameLib.API.Socket};case 7:return{name:"GameLib.D3.Mesh",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Mesh,apiConstructor:GameLib.D3.API.Mesh};case 8:return{name:"GameLib.D3.Spline",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Spline,apiConstructor:GameLib.D3.API.Spline};case 9:return{name:"GameLib.D3.Light",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Light,apiConstructor:GameLib.D3.API.Light};case 10:return null;case 11:return{name:"GameLib.D3.Composer",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Composer,apiConstructor:GameLib.D3.API.Composer};case 12:return{name:"GameLib.D3.RenderTarget",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.RenderTarget,apiConstructor:GameLib.D3.API.RenderTarget};case 13:return{name:"GameLib.D3.Pass",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Pass,apiConstructor:GameLib.D3.API.Pass};case 14:return{name:"GameLib.D3.Scene",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Scene};case 15:return{name:"GameLib.D3.Raycaster",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Raycaster,apiConstructor:GameLib.D3.API.Raycaster};case 16:case 17:return null;case 18:return{name:"GameLib.D3.Viewport",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Viewport,apiConstructor:GameLib.D3.API.Viewport};case 19:return{name:"GameLib.System",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.System,apiConstructor:GameLib.API.System};case 20:return{name:"GameLib.GraphicsRuntime",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.GraphicsRuntime};case 21:return{name:"GameLib.D3.Helper",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Helper};case 22:return{name:"GameLib.CustomCode",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.CustomCode,apiConstructor:GameLib.API.CustomCode};case 23:return{name:"GameLib.Mouse",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.Mouse,apiConstructor:GameLib.API.Mouse};case 24:return{name:"GameLib.D3.Skeleton",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Skeleton,apiConstructor:GameLib.D3.API.Skeleton};case 25:return{name:"GameLib.D3.Texture",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Texture,apiConstructor:GameLib.D3.API.Texture};case 26:return{name:"GameLib.EntityManager",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.EntityManager,apiConstructor:GameLib.API.EntityManager};case 27:return{name:"GameLib.DomElement",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.DomElement,apiConstructor:GameLib.API.DomElement};case 28:return null;case 29:return{name:"GameLib.Stats",runtime:GameLib.Component.STATISTICS_RUNTIME,constructor:GameLib.Stats,apiConstructor:GameLib.API.Stats};case 30:return{name:"GameLib.GUI",runtime:GameLib.Component.GUI_RUNTIME,constructor:GameLib.GUI,apiConstructor:GameLib.API.GUI};case 31:return{name:"GameLib.Image",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.Image};case 32:return{name:"GameLib.Entity",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.Entity,apiConstructor:GameLib.API.Entity};case 33:return{name:"GameLib.D3.Mesh.Sphere",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Mesh.Sphere,apiConstructor:GameLib.D3.API.Mesh};case 34:return{name:"GameLib.D3.Mesh.Plane",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Mesh.Plane,apiConstructor:GameLib.D3.API.Mesh};case 35:return{name:"GameLib.D3.Mesh.Curve",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Mesh.Curve,apiConstructor:GameLib.D3.API.Mesh};case 36:return{name:"GameLib.D3.PhysicsWorld",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.PhysicsWorld,apiConstructor:GameLib.D3.API.PhysicsWorld};case 37:return{name:"GameLib.D3.Broadphase",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.Broadphase,apiConstructor:GameLib.D3.API.Broadphase};case 38:return{name:"GameLib.D3.Solver",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.Solver,apiConstructor:GameLib.D3.API.Solver};case 39:return{name:"GameLib.D3.RigidBody",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.RigidBody,apiConstructor:GameLib.D3.API.RigidBody};case 40:return{name:"GameLib.D3.Shape",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.Shape,apiConstructor:GameLib.D3.API.Shape};case 41:return{name:"GameLib.D3.Shape.Box",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.Shape.Box,apiConstructor:GameLib.D3.API.Shape};case 42:return{name:"GameLib.D3.Shape.Sphere",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.Shape.Sphere,apiConstructor:GameLib.D3.API.Shape};case 43:return{name:"GameLib.D3.Shape.TriMesh",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.Shape.TriMesh,apiConstructor:GameLib.D3.API.Shape};case 44:return{name:"GameLib.D3.Shape.ConvexHull",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.Shape.ConvexHull,apiConstructor:GameLib.D3.API.Shape};case 45:return{name:"GameLib.D3.Shape.ConvexHull.Cylinder",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.Shape.ConvexHull.Cylinder,apiConstructor:GameLib.D3.API.Shape};case 46:return{name:"GameLib.D3.Shape.HeightMap",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.D3.Shape.HeightMap,apiConstructor:GameLib.D3.API.Shape};case 47:return{name:"GameLib.D3.Shape.Plane",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.Shape.Plane,apiConstructor:GameLib.D3.API.Shape};case 48:return{name:"GameLib.Controls",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.Controls,apiConstructor:GameLib.API.Controls};case 49:return{name:"GameLib.Controls.D3.Editor",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.Controls.D3.Editor,apiConstructor:GameLib.API.Controls};case 50:return{name:"GameLib.Controls.Touch",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.Controls.Touch,apiConstructor:GameLib.API.Controls};case 51:return{name:"GameLib.D3.FrictionMaterial",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.FrictionMaterial,apiConstructor:GameLib.D3.API.FrictionMaterial};case 52:return{name:"GameLib.D3.FrictionContactMaterial",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.FrictionContactMaterial,apiConstructor:GameLib.D3.API.FrictionContactMaterial};case 53:return{name:"GameLib.D3.RaycastVehicle",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.RaycastVehicle,apiConstructor:GameLib.D3.API.RaycastVehicle};case 54:return{name:"GameLib.D3.RaycastWheel",runtime:GameLib.Component.PHYSICS_RUNTIME,constructor:GameLib.D3.RaycastWheel,apiConstructor:GameLib.D3.API.RaycastWheel};case 55:return{name:"GameLib.Clock",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.Clock,apiConstructor:GameLib.API.Clock};case 56:return{name:"GameLib.D3.Animation",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.D3.Animation,apiConstructor:GameLib.D3.API.Animation};case 57:return{name:"GameLib.Controls.Keyboard",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.Controls.Keyboard,apiConstructor:GameLib.API.Controls};case 58:return{name:"GameLib.Controls.Mouse",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.Controls.Mouse,apiConstructor:GameLib.API.Controls};case 59:return{name:"GameLib.D3.Mesh.Text",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Mesh.Text,apiConstructor:GameLib.D3.API.Mesh};case 60:return{name:"GameLib.D3.Font",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Font,apiConstructor:GameLib.D3.API.Font};case 61:return{name:"GameLib.Canvas",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.Canvas,apiConstructor:GameLib.API.Canvas};case 62:return{name:"GameLib.D3.Bone",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Bone,apiConstructor:GameLib.D3.API.Bone};case 63:return{name:"GameLib.D3.Mesh.Box",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Mesh.Box,apiConstructor:GameLib.D3.API.Mesh};case 64:return{name:"GameLib.D3.Mesh.Cylinder",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Mesh.Cylinder,apiConstructor:GameLib.D3.API.Mesh};case 65:return{name:"GameLib.System.Animation",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.System.Animation,apiConstructor:GameLib.API.System};case 66:return{name:"GameLib.System.CustomCode",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.System.CustomCode,apiConstructor:GameLib.API.System};case 67:return{name:"GameLib.System.GUI",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.System.GUI,apiConstructor:GameLib.API.System};case 68:return{name:"GameLib.System.Input",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.System.Input,apiConstructor:GameLib.API.System};case 69:return{name:"GameLib.System.Linking",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.System.Linking,apiConstructor:GameLib.API.System};case 70:return{name:"GameLib.System.Physics",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.System.Physics,apiConstructor:GameLib.API.System};case 71:return{name:"GameLib.System.Render",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.System.Render,apiConstructor:GameLib.API.System};case 72:return{name:"GameLib.System.Storage",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.System.Storage,apiConstructor:GameLib.API.System};case 73:return{name:"GameLib.System.Visualization",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.System.Visualization,apiConstructor:GameLib.API.System};case 80:return{name:"GameLib.D3.Fog",runtime:GameLib.Component.GRAPHICS_RUNTIME, -constructor:GameLib.D3.Fog,apiConstructor:GameLib.D3.API.Fog};case 81:return{name:"GameLib.D3.Mesh.Line",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Mesh.Line,apiConstructor:GameLib.D3.API.Mesh};case 82:return{name:"GameLib.D3.ParticleEngine",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.ParticleEngine,apiConstructor:GameLib.D3.API.ParticleEngine};case 83:return{name:"GameLib.System.Particle",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.System.Particle,apiConstructor:GameLib.API.System};case 84:return{name:"GameLib.D3.Particle",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Particle,apiConstructor:GameLib.D3.API.Particle};case 85:return{name:"GameLib.D3.Audio",runtime:GameLib.Component.GRAPHICS_RUNTIME,constructor:GameLib.D3.Audio,apiConstructor:GameLib.D3.API.Audio};case 86:return{name:"GameLib.System.Audio",runtime:GameLib.Component.DEFAULT_RUNTIME,constructor:GameLib.System.Audio,apiConstructor:GameLib.API.System};case 87:return{name:"GameLib.Socket.Cast",runtime:GameLib.Component.SOCKET_RUNTIME,constructor:GameLib.Socket.Cast,apiConstructor:GameLib.API.Socket.Cast}}throw new Error("Unknown component type: "+e)},GameLib.Component.GetRuntimeName=function(e){return e===GameLib.Component.GRAPHICS_RUNTIME?"Graphics":e===GameLib.Component.PHYSICS_RUNTIME?"Physics":e===GameLib.Component.GUI_RUNTIME?"GUI":e===GameLib.Component.STATISTICS_RUNTIME?"Statistics":e===GameLib.Component.SOCKET_RUNTIME?"Sockets":e===GameLib.Component.CODER_RUNTIME?"Coder":"Default"},GameLib.Component.GetComponentName=function(e){var t=GameLib.Component.GetComponentInfo(e);return t?t.name:"unused"},GameLib.Component.GetComponentRuntime=function(e){var t=GameLib.Component.GetComponentInfo(e);return t?t.runtime:null},GameLib.Component.GetComponentConstructor=function(e){var t=GameLib.Component.GetComponentInfo(e);return t?t.constructor:null},GameLib.Component.prototype.toApiObject=function(){return this.id},GameLib.Component.prototype.processComponent=function(e){if(e instanceof GameLib.Component){e.buildIdToObject(),e.linked||(this.linked=!1);var t=e.idToObject;for(var i in t)t.hasOwnProperty(i)&&(this.idToObject[i]=t[i]);e.id?this.idToObject[e.id]=e:console.warn("Object with no ID passed: "+e)}else"string"==typeof e?this.linked=!1:console.warn("Unhandled type of object: ",e)},GameLib.Component.prototype.buildIdToObject=function(){if(!this.building){this.building=!0,this.linked=!0,this.idToObject={};for(var e in this.linkedObjects)this.linkedObjects.hasOwnProperty(e)&&this.hasOwnProperty(e)&&this[e]&&0!==e.indexOf("parent")&&(this.linkedObjects[e]instanceof Array?(this[e]=this[e].filter(function(e){return null!==e||(console.log("null object found and removed"),!1)}),this[e].map(function(e){this.processComponent(e)}.bind(this))):this.processComponent(this[e]));this instanceof GameLib.D3.Scene&&(this.storeClones||this.clones.map(function(e){this.idToObject.hasOwnProperty(e.id)&&delete this.idToObject[e.id]}.bind(this))),this.idToObject[this.id]=this,this.building=!1}},GameLib.Component.prototype.generateNewIds=function(){this.buildIdToObject();var e=GameLib.EntityManager.Instance.queryComponents(GameLib.Component.CUSTOM_CODE);for(var t in this.idToObject)if(this.idToObject.hasOwnProperty(t)){var i=this.idToObject[t].id,n=GameLib.Utils.RandomId();this.idToObject[t].id=n,this.idToObject[t].name=this.idToObject[t].name.replace(i,n),e.map(function(e){e.code=e.code.replace(i,n)})}},GameLib.Component.prototype.remove=function(){this.buildIdToObject(),this.getDependencies().map(function(e){var t=this.idToObject[e];t instanceof GameLib.Component&&t.remove()}.bind(this)),GameLib.Event.Emit(GameLib.Event.REMOVE_COMPONENT,{component:this})},GameLib.Component.prototype.clone=function(){var e=this.toApiObject();this.cloneNumber+=1,e.id=GameLib.Utils.RandomId(),e.name=this.name+" Clone ("+this.cloneNumber+")";var t=GameLib.Component.ConstructFromObject(e);return t.isClone=!0,GameLib.Event.Emit(GameLib.Event.COMPONENT_CLONED,{parent:this,component:t}),t.parentEntity=null,t},GameLib.Component.prototype.cloneInstance=function(){var e=null;return this.instance&&this.instance.clone&&(this.instance.clone,!0)&&(e=this.instance.clone(),GameLib.Event.Emit(GameLib.Event.INSTANCE_CLONED,{component:this,instance:e})),e},GameLib.Component.prototype.saveToRemoteAPI=function(){this.save(!0)},GameLib.Component.prototype.save=function(e){var t=[],i=[],n=[];if(this.buildIdToObject(),this.saveSubscription||this.saveErrorSubscription)return void console.warn("another save is in progress");GameLib.Event.Emit(GameLib.Event.SAVING,{component:this}),this.saveSubscription=GameLib.Event.Subscribe(GameLib.Event.COMPONENT_SAVED,function(e){i.push(e.component),n.length+i.length===t.length&&(this.saveSubscription.remove(),this.saveSubscription=null,this.saveErrorSubscription.remove(),this.saveErrorSubscription=null,GameLib.Event.Emit(GameLib.Event.DONE_SAVING,{failed:n,saved:i}))}.bind(this)),this.saveErrorSubscription=GameLib.Event.Subscribe(GameLib.Event.SAVE_COMPONENT_ERROR,function(e){n.push(e.component),n.length+i.length===t.length&&(this.saveSubscription.remove(),this.saveSubscription=null,this.saveErrorSubscription.remove(),this.saveErrorSubscription=null,GameLib.Event.Emit(GameLib.Event.DONE_SAVING,{failed:n,saved:i}))}.bind(this));for(var a in this.idToObject)if(this.idToObject.hasOwnProperty(a)&&this.idToObject[a]instanceof GameLib.Component){var s=this.idToObject[a].toApiObject();t.push(s),this.publish(GameLib.Event.SAVE_COMPONENT,{apiObject:s,remote:e})}},GameLib.Component.GetRuntimeObject=function(e){var t=null;return GameLib.Event.Emit(GameLib.Event.GET_RUNTIME,null,function(e){t=e}),e===GameLib.Component.GRAPHICS_RUNTIME?GameLib.Utils.UndefinedOrNull(t.graphics)?(console.warn("no runtime graphics"),null):t.graphics:e===GameLib.Component.PHYSICS_RUNTIME?GameLib.Utils.UndefinedOrNull(t.physics)?(console.warn("no runtime physics"),null):t.physics:e===GameLib.Component.GUI_RUNTIME?GameLib.Utils.UndefinedOrNull(t.gui)?(console.warn("no runtime gui"),null):t.gui:e===GameLib.Component.SOCKET_RUNTIME?GameLib.Utils.UndefinedOrNull(t.sockets)?(console.warn("no runtime sockets"),null):t.sockets:e===GameLib.Component.STATISTICS_RUNTIME?GameLib.Utils.UndefinedOrNull(t.statistics)?(console.warn("no runtime statistics"),null):t.statistics:(e===GameLib.Component.DEFAULT_RUNTIME||console.log("unknown runtime object found : "+info.runtime),null)},GameLib.Component.Construct=function(e){var t=GameLib.Component.GetComponentInfo(e),i=t.constructor,n=GameLib.Component.GetRuntimeObject(t.runtime);return n?new i(n):new i},GameLib.Component.ConstructFromObject=function(e){var t=null,i=GameLib.Component.GetComponentInfo(e.componentType),n=i.constructor,a=n.FromObject;if(e.componentType===GameLib.Component.ENTITY)t=a(e,GameLib.EntityManager.Instance);else{var s=GameLib.Component.GetRuntimeObject(i.runtime);t=s?a(s,e):a(e)}return t},GameLib.API.Canvas=function(e,t,i,n,a){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Canvas ("+e+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=512),this.width=i,GameLib.Utils.UndefinedOrNull(n)&&(n=512),this.height=n,GameLib.API.Component.call(this,GameLib.Component.CANVAS,a)},GameLib.API.Canvas.prototype=Object.create(GameLib.Component.prototype),GameLib.API.Canvas.prototype.constructor=GameLib.API.Canvas,GameLib.API.Canvas.FromObject=function(e){return new GameLib.API.Canvas(e.id,e.name,e.width,e.height,e.parentEntity)},GameLib.API.Clock=function(e,t,i){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Clock ("+this.id+")"),this.name=t,GameLib.API.Component.call(this,GameLib.Component.CLOCK,i)},GameLib.API.Clock.prototype=Object.create(GameLib.Component.prototype),GameLib.API.Clock.prototype.constructor=GameLib.API.Clock,GameLib.API.Clock.FromObject=function(e){return new GameLib.API.Clock(e.id,e.name,e.parentEntity)},GameLib.API.Color=function(e,t,i,n){GameLib.Utils.UndefinedOrNull(e)&&(e=1),this.r=e,GameLib.Utils.UndefinedOrNull(t)&&(t=1),this.g=t,GameLib.Utils.UndefinedOrNull(i)&&(i=1),this.b=i,GameLib.Utils.UndefinedOrNull(n)&&(n=0),this.a=n},GameLib.API.Color.FromObject=function(e){return GameLib.Utils.UndefinedOrNull(e)&&(e={}),new GameLib.API.Color(e.r,e.g,e.b,e.a)},GameLib.API.Color.prototype.toHex=function(){this.r<0&&(this.r=0),this.g<0&&(this.g=0),this.b<0&&(this.b=0),this.r>1&&(this.r=1),this.g>1&&(this.g=1),this.b>1&&(this.b=1);var e=Math.floor(this.r>=1?255:256*this.r).toString(16),t=Math.floor(this.g>=1?255:256*this.g).toString(16),i=Math.floor(this.b>=1?255:256*this.b).toString(16);return e.length<2&&(e="0"+e),t.length<2&&(t="0"+t),i.length<2&&(i="0"+i),"#"+e+t+i},GameLib.API.Color.prototype.fromHex=function(e){var t=e.match(new RegExp("#+(..)(..)(..)"));this.r=parseInt(t[1],16)/255,this.g=parseInt(t[2],16)/255,this.b=parseInt(t[3],16)/255},GameLib.API.Controls=function(e,t,i,n,a){if(GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(this instanceof GameLib.Controls.D3.Editor&&(t=GameLib.Controls.CONTROLS_TYPE_EDITOR),this instanceof GameLib.Controls.Touch&&(t=GameLib.Controls.CONTROLS_TYPE_TOUCH),this instanceof GameLib.Controls.Keyboard&&(t=GameLib.Controls.CONTROLS_TYPE_KEYBOARD),this instanceof GameLib.Controls.Mouse&&(t=GameLib.Controls.CONTROLS_TYPE_MOUSE),GameLib.Utils.UndefinedOrNull(t)))throw new Error("Could not determine controls type from this");this.controlsType=t,GameLib.Utils.UndefinedOrNull(i)&&(t===GameLib.Controls.CONTROLS_TYPE_EDITOR&&(i="Editing Controls"),t===GameLib.Controls.CONTROLS_TYPE_TOUCH&&(i="Touch Controls"),t===GameLib.Controls.CONTROLS_TYPE_KEYBOARD&&(i="Keyboard Controls"),t===GameLib.Controls.CONTROLS_TYPE_MOUSE&&(i="Mouse Controls"),i+=" ("+this.id+")"),this.name=i,GameLib.Utils.UndefinedOrNull(n)&&(n=null),this.domElement=n;var s=GameLib.Component.CONTROLS;this.controlsType===GameLib.Controls.CONTROLS_TYPE_EDITOR&&(s=GameLib.Component.CONTROLS_EDITOR),this.controlsType===GameLib.Controls.CONTROLS_TYPE_TOUCH&&(s=GameLib.Component.CONTROLS_TOUCH),this.controlsType===GameLib.Controls.CONTROLS_TYPE_KEYBOARD&&(s=GameLib.Component.CONTROLS_KEYBOARD),this.controlsType===GameLib.Controls.CONTROLS_TYPE_MOUSE&&(s=GameLib.Component.CONTROLS_MOUSE),GameLib.API.Component.call(this,s,a)},GameLib.API.Controls.prototype=Object.create(GameLib.Component.prototype),GameLib.API.Controls.prototype.constructor=GameLib.API.Controls,GameLib.API.Controls.FromObject=function(e){return new GameLib.API.Controls(e.id,e.controlsType,e.name,e.domElement,e.parentEntity)},GameLib.API.CustomCode=function(e,t,i,n,a){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="CustomCode ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=42),this.eventId=i,GameLib.Utils.UndefinedOrNull(n)&&(n="return null;\n//@ sourceURL="+this.name+".js"),this.code=n,GameLib.API.Component.call(this,GameLib.Component.CUSTOM_CODE,a)},GameLib.API.CustomCode.prototype=Object.create(GameLib.Component.prototype),GameLib.API.CustomCode.prototype.constructor=GameLib.API.CustomCode,GameLib.API.CustomCode.FromObject=function(e){return new GameLib.API.CustomCode(e.id,e.name,e.eventId,e.code,e.parentEntity)},GameLib.API.DomElement=function(e,t,i,n){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="DOM Element ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=""),this.domElementId=i,GameLib.API.Component.call(this,GameLib.Component.DOM_ELEMENT,n)},GameLib.API.DomElement.prototype=Object.create(GameLib.Component.prototype),GameLib.API.DomElement.prototype.constructor=GameLib.API.DomElement,GameLib.API.DomElement.FromObject=function(e){return new GameLib.API.DomElement(e.id,e.name,e.domElementId,e.parentEntity)},GameLib.API.EntityManager=function(e,t,i,n,a,s){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Entity Manager ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=[]),this.entities=i,GameLib.Utils.UndefinedOrNull(n)&&(n=null),this.defaultEntity=n,GameLib.Utils.UndefinedOrNull(a)&&(a=null),this.defaultRenderer=a,GameLib.API.Component.call(this,GameLib.Component.ENTITY_MANAGER,s)},GameLib.API.EntityManager.prototype=Object.create(GameLib.Component.prototype),GameLib.API.EntityManager.prototype.constructor=GameLib.API.EntityManager,GameLib.API.EntityManager.FromObject=function(e){var t=e.entities.map(function(e){return GameLib.API.Entity.FromObject(e)});return new GameLib.API.EntityManager(e.id,e.name,t,e.defaultEntity,e.defaultRenderer,e.parentEntity)},GameLib.API.Entity=function(e,t,i,n,a){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Entity ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=[]),this.components=i,GameLib.API.Component.call(this,GameLib.Component.ENTITY,n),GameLib.Utils.UndefinedOrNull(a)&&(a=null),this.parentEntityManager=a,this.activeComponent=null},GameLib.API.Entity.prototype=Object.create(GameLib.Component.prototype),GameLib.API.Entity.prototype.constructor=GameLib.API.Entity,GameLib.API.Entity.FromObject=function(e){return new GameLib.API.Entity(e.id,e.name,e.components,e.parentEntity,e.parentEntityManager)},GameLib.API.GUI=function(e,t,i,n){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="GUI ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=null),this.domElement=i,GameLib.API.Component.call(this,GameLib.Component.GUI,n)},GameLib.API.GUI.prototype=Object.create(GameLib.Component.prototype),GameLib.API.GUI.prototype.constructor=GameLib.API.GUI,GameLib.API.GUI.FromObject=function(e){var t=null;return e.domElement&&(t=e.domElement instanceof Object?GameLib.API.DomElement.FromObject(e.domElement):e.domElement),new GameLib.API.GUI(e.id,e.name,t,e.parentEntity)},GameLib.API.Image=function(e,t,i,n,a,s,o,r){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Image "+e),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=GameLib.Utils.LowerUnderscore(t)),this.fileName=i,GameLib.Utils.UndefinedOrNull(n)&&(n=".unknown"),this.extension=n,GameLib.Utils.UndefinedOrNull(a)&&(a="/"),this.path=a,GameLib.Utils.UndefinedOrNull(s)&&(s="application/octet-stream",this.extension.match(/(png)$/i)&&(s="image/png"),this.extension.match(/(jpg|jpeg)$/i)&&(s="image/jpeg"),this.extension.match(/(gif)$/i)&&(s="image/gif")),this.contentType=s,GameLib.Utils.UndefinedOrNull(o)&&(o=0),this.size=o,GameLib.API.Component.call(this,GameLib.Component.IMAGE,r)},GameLib.API.Image.prototype=Object.create(GameLib.Component.prototype),GameLib.API.Image.prototype.constructor=GameLib.API.Image,GameLib.API.Image.FromObject=function(e){return new GameLib.API.Image(e.id,e.name,e.fileName,e.extension,e.path,e.contentType,e.size,e.parentEntity)},GameLib.API.Matrix4=function(e,t,i,n){this.rows=[],GameLib.Utils.UndefinedOrNull(e)&&(e=new GameLib.API.Vector4(1,0,0,0)),this.rows[0]=e,GameLib.Utils.UndefinedOrNull(t)&&(t=new GameLib.API.Vector4(0,1,0,0)),this.rows[1]=t,GameLib.Utils.UndefinedOrNull(i)&&(i=new GameLib.API.Vector4(0,0,1,0)),this.rows[2]=i,GameLib.Utils.UndefinedOrNull(n)&&(n=new GameLib.API.Vector4(0,0,0,1)),this.rows[3]=n,this.temp=[],this.temp.push(new GameLib.API.Vector4),this.temp.push(new GameLib.API.Vector4),this.temp.push(new GameLib.API.Vector4),this.temp.push(new GameLib.API.Vector4),this.forward=new GameLib.API.Vector4,this.left=new GameLib.API.Vector4,this.up=new GameLib.API.Vector4},GameLib.API.Matrix4.FromObject=function(e){if(e.rows)return new GameLib.API.Matrix4(GameLib.API.Vector4.FromObject(e.rows[0]),GameLib.API.Vector4.FromObject(e.rows[1]),GameLib.API.Vector4.FromObject(e.rows[2]),GameLib.API.Vector4.FromObject(e.rows[3]));if(e instanceof Array)return new GameLib.API.Matrix4(GameLib.API.Vector4.FromObject(e[0]),GameLib.API.Vector4.FromObject(e[1]),GameLib.API.Vector4.FromObject(e[2]),GameLib.API.Vector4.FromObject(e[3]));throw console.warn("Unsupported object matrix type - whats your DB version?"),new Error("Unsupported object matrix type - whats your DB version?")},GameLib.API.Matrix4.prototype.rotationMatrixX=function(e){return this.identity(),this.rows[1]=new GameLib.API.Vector4(0,Math.cos(e),-1*Math.sin(e),0),this.rows[2]=new GameLib.API.Vector4(0,Math.sin(e),Math.cos(e),0),this},GameLib.API.Matrix4.prototype.rotationMatrixY=function(e){return this.identity(),this.rows[0]=new GameLib.API.Vector4(Math.cos(e),0,Math.sin(e),0),this.rows[2]=new GameLib.API.Vector4(-1*Math.sin(e),0,Math.cos(e),0),this},GameLib.API.Matrix4.prototype.rotationMatrixZ=function(e){return this.identity(),this.rows[0]=new GameLib.API.Vector4(Math.cos(e),-1*Math.sin(e),0,0),this.rows[1]=new GameLib.API.Vector4(Math.sin(e),Math.cos(e),0,0),this},GameLib.API.Matrix4.prototype.rotateX=function(e,t){return this.identity(),this.rotationMatrixX(e),this.multiply(t)},GameLib.API.Matrix4.prototype.rotateY=function(e,t){return this.identity(),this.rotationMatrixY(e),this.multiply(t)},GameLib.API.Matrix4.prototype.rotateZ=function(e,t){return this.identity(),this.rotationMatrixZ(e),this.multiply(t)},GameLib.API.Matrix4.prototype.multiply=function(e){return e instanceof GameLib.API.Quaternion||e instanceof GameLib.API.Vector4?new GameLib.API.Quaternion(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z+this.rows[0].w*e.w,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z+this.rows[1].w*e.w,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z+this.rows[2].w*e.w,this.rows[3].x*e.x+this.rows[3].y*e.y+this.rows[3].z*e.z+this.rows[3].w*e.w):e instanceof GameLib.API.Vector3?new GameLib.API.Vector3(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z):void 0},GameLib.API.Matrix4.prototype.identity=function(){this.rows=[new GameLib.API.Vector4(1,0,0,0),new GameLib.API.Vector4(0,1,0,0),new GameLib.API.Vector4(0,0,1,0),new GameLib.API.Vector4(0,0,0,1)]},GameLib.API.Mouse=function(e,t,i,n,a){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Mouse ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=0),this.x=i,GameLib.Utils.UndefinedOrNull(n)&&(n=0),this.y=n,GameLib.API.Component.call(this,GameLib.Component.MOUSE,a)},GameLib.API.Mouse.prototype=Object.create(GameLib.Component.prototype),GameLib.API.Mouse.prototype.constructor=GameLib.API.Mouse,GameLib.API.Mouse.FromObject=function(e){return new GameLib.API.Mouse(e.id,e.name,e.x,e.y,e.parentEntity)},GameLib.API.Quaternion=function(e,t,i,n,a,s){GameLib.Utils.UndefinedOrNull(e)&&(e=0),this.x=e,GameLib.Utils.UndefinedOrNull(t)&&(t=0),this.y=t,GameLib.Utils.UndefinedOrNull(i)&&(i=0),this.z=i,GameLib.Utils.UndefinedOrNull(n)&&(n=1),this.w=n,GameLib.Utils.UndefinedOrNull(a)&&(a=new GameLib.API.Vector3),this.axis=a,GameLib.Utils.UndefinedOrNull(s)&&(s=0),this.angle=s},GameLib.API.Quaternion.prototype.translate=function(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this},GameLib.API.Quaternion.prototype.copy=function(){return new GameLib.API.Quaternion(this.x,this.y,this.z,this.w)},GameLib.API.Quaternion.prototype.normalize=function(){var e=this.x*this.x+this.y*this.y+this.z*this.z;if(e<1e-6)return this;var t=1/Math.sqrt(e);this.x*=t,this.y*=t,this.z*=t},GameLib.API.Quaternion.prototype.multiply=function(e){var t,i,n,a,s=e,o=this;if(e instanceof GameLib.API.Matrix4)return t=s.rows[0].x*o.x+s.rows[0].y*o.y+s.rows[0].z*o.z+s.rows[0].w*o.w,i=s.rows[1].x*o.x+s.rows[1].y*o.y+s.rows[1].z*o.z+s.rows[1].w*o.w,n=s.rows[2].x*o.x+s.rows[2].y*o.y+s.rows[2].z*o.z+s.rows[2].w*o.w,a=s.rows[3].x*o.x+s.rows[3].y*o.y+s.rows[3].z*o.z+s.rows[3].w*o.w,this.x=t,this.y=i,this.z=n,this.w=a,this;if(e instanceof GameLib.API.Quaternion)return t=s.x*o.x-s.y*o.y-s.z*o.z-s.w*s.w,i=s.x*o.y+s.y*o.x-s.z*o.w+s.w*s.z,n=s.x*o.z+s.y*o.w+s.z*o.x-s.w*s.y,a=s.x*o.w-s.y*o.z+s.z*o.y+s.w*s.x,this.x=t,this.y=i,this.z=n,this.w=a,this;throw console.log("This functionality not implemented - please do this"),new Error("This functionality not implemented - please do this")},GameLib.API.Quaternion.prototype.setFromAngle=function(e){return this.instance.setFromAxisAngle(this.axis.instance,e),this.x=this.instance.x,this.y=this.instance.y,this.z=this.instance.z,this.w=this.instance.w,this},GameLib.API.Quaternion.prototype.subtract=function(e){return e instanceof GameLib.API.Vector3&&(this.x-=e.x,this.y-=e.y,this.z-=e.z),e instanceof GameLib.API.Quaternion&&(this.x-=e.x,this.y-=e.y,this.z-=e.z,this.w-=e.w),this},GameLib.API.Quaternion.prototype.magnitude=function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},GameLib.API.Quaternion.prototype.normalize=function(){var e=this.magnitude();return e<1e-6?this:(this.x*=e,this.y*=e,this.z*=e,this.w*=e,this)},GameLib.API.Quaternion.prototype.setFromRotationMatrix=function(e){this.instance.setFromRotationMatrix(e.instance),this.x=this.instance.x,this.y=this.instance.y,this.z=this.instance.z,this.w=this.instance.w},GameLib.API.Quaternion.prototype.slerp=function(e,t){return this.updateInstance(),this.instance.slerp(e.instance,t),this.x=this.instance.x,this.y=this.instance.y,this.z=this.instance.z,this.w=this.instance.w,this},GameLib.API.Quaternion.FromObject=function(e){var t=null;return e.axis&&(t=GameLib.API.Vector3.FromObject(e.axis)),new GameLib.API.Quaternion(e.x,e.y,e.z,e.w,t,e.angle)},GameLib.API.Quaternion.Points=function(){this.vectors=[]},GameLib.API.Quaternion.Points.prototype.add=function(e){if(e instanceof GameLib.API.Vector3&&(e=new GameLib.API.Quaternion(e.x,e.y,e.z,1)),!e instanceof GameLib.API.Quaternion)throw console.warn("Vector needs to be of type Quaternion"),new Error("Vector needs to be of type Quaternion");return this.vectors.push(e),this},GameLib.API.Quaternion.Points.prototype.copy=function(){for(var e=[],t=0;ts&&(s=c.x,n=t*e)}this.vectors=a;for(var m=(new GameLib.API.Matrix4).rotationMatrixY(n),h=0;hs&&(s=c.y,n=t*e)}this.vectors=a;for(var m=(new GameLib.API.Matrix4).rotationMatrixX(n),h=0;hn&&(n=this.vectors[o].x),this.vectors[o].y>a&&(a=this.vectors[o].y),this.vectors[o].z>s&&(s=this.vectors[o].z);return new GameLib.API.Vector3(Math.abs(n-e),Math.abs(a-t),Math.abs(a-i))},GameLib.API.Quaternion.Points.prototype.average=function(){for(var e=0,t=0,i=0,n=0;n0},GameLib.API.Vector3.normal=function(e,t,i){var n=t.copy(),a=i.copy();return n.subtract(e).cross(a.subtract(e))},GameLib.API.Vector3.prototype.lookAt=function(e,t){var i=GameLib.API.Matrix4.lookAt(this,e,t);return this.multiply(i)},GameLib.API.Vector3.prototype.translate=function(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this},GameLib.API.Vector3.prototype.add=function(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this},GameLib.API.Vector3.prototype.squared=function(){return this.x*this.x+this.y*this.y+this.z*this.z},GameLib.API.Vector3.prototype.copy=function(){return new GameLib.API.Vector3(this.x,this.y,this.z)},GameLib.API.Vector3.prototype.set=function(e,t,i){this.x=e,this.y=t,this.z=i},GameLib.API.Vector3.prototype.lerp=function(e,t){return new GameLib.API.Vector3(this.x+(e.x-this.x)*t,this.y+(e.y-this.y)*t,this.z+(e.z-this.z)*t)},GameLib.API.Vector3.prototype.distanceTo=function(e){var t=this.x-e.x,i=this.y-e.y,n=this.z-e.z;return Math.sqrt(t*t+i*i+n*n)},GameLib.API.Vector3.AngleDirection=function(e,t,i){var n=e.cross(t),a=n.dot(i);return a>0?1:a<0?-1:0},GameLib.API.Vector3.prototype.multiply=function(e,t){var i,n,a,s=e,o=this;if(GameLib.Utils.UndefinedOrNull(t)&&(t=!1),"number"==typeof e)return t?(this.x*=e,this.y*=e,this.z*=e,this):this.x*e+this.y*e+this.z*e;if(e instanceof GameLib.API.Vector3)return t?(i=s.y*o.z-s.z*o.y,n=s.z*o.x-s.x*o.z,a=s.x*o.y-s.y*o.x,this.x=i,this.y=n,this.z=a,this):this.x*e.x+this.y*e.y+this.z*e.z;throw console.log("functionality not implemented - please do this"),new Error("not implemented")},GameLib.API.Vector3.prototype.dot=function(e){return this.x*e.x+this.y*e.y+this.z*e.z},GameLib.API.Vector3.prototype.normalize=function(){var e=this.squared();if(e<1e-6)return this;var t=1/Math.sqrt(e);return new GameLib.API.Vector3(this.x*t,this.y*t,this.z*t)};GameLib.API.Vector3.prototype.clone=function(){return new GameLib.API.Vector3(this.x,this.y,this.z)},GameLib.API.Vector3.prototype.applyQuaternion=function(e){var t=this.x,i=this.y,n=this.z,a=e.x,s=e.y,o=e.z,r=e.w,c=r*t+s*n-o*i,m=r*i+o*t-a*n,h=r*n+a*i-s*t,l=-a*t-s*i-o*n;return this.x=c*r+l*-a+m*-o-h*-s,this.y=m*r+l*-s+h*-a-c*-o,this.z=h*r+l*-o+c*-s-m*-a,this},GameLib.API.Vector3.prototype.clamp=function(e,t){return this.x=Math.max(e.x,Math.min(t.x,this.x)),this.y=Math.max(e.y,Math.min(t.y,this.y)),this.z=Math.max(e.z,Math.min(t.z,this.z)),this},GameLib.API.Vector3.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},GameLib.API.Vector3.prototype.reflect=function(e){return this.sub(v1.copy(e).multiply(2*this.dot(e)))},GameLib.API.Vector3.prototype.angleTo=function(e){var t=this.dot(e)/Math.sqrt(this.lengthSq()*e.lengthSq());return Math.acos(exports.Math.clamp(t,-1,1))},GameLib.API.Vector3.FromObject=function(e){return new GameLib.API.Vector3(e.x,e.y,e.z)},GameLib.API.Vector4=function(e,t,i,n){GameLib.Utils.UndefinedOrNull(e)&&(e=0),this.x=e,GameLib.Utils.UndefinedOrNull(t)&&(t=0),this.y=t,GameLib.Utils.UndefinedOrNull(i)&&(i=0),this.z=i,GameLib.Utils.UndefinedOrNull(n)&&(n=1),this.w=n},GameLib.API.Vector4.prototype.equals=function(e){return this.x===e.x&&this.y===e.y&&this.z===e.z&&this.w===e.w},GameLib.API.Vector4.FromObject=function(e){return new GameLib.API.Vector4(e.x,e.y,e.z,e.w)},GameLib.Canvas=function(e){if(GameLib.Utils.UndefinedOrNull(e)&&(e={}),e instanceof GameLib.Canvas)return e;GameLib.API.Canvas.call(this,e.id,e.name,e.width,e.height,e.parentEntity),GameLib.Component.call(this)},GameLib.Canvas.prototype=Object.create(GameLib.API.Canvas.prototype),GameLib.Canvas.prototype.constructor=GameLib.Canvas,GameLib.Canvas.prototype.createInstance=function(){this.instance=document.createElement("canvas"),this.instance.width=this.width,this.instance.height=this.height,GameLib.Component.prototype.createInstance.call(this)},GameLib.Canvas.prototype.updateInstance=function(e){GameLib.Utils.UndefinedOrNull(e)&&console.warn("unknown property update for Canvas: "+e),"width"===e&&(this.instance.width=this.width),"height"===e&&(this.instance.height=this.height)},GameLib.Canvas.prototype.toApiObject=function(){return new GameLib.API.Canvas(this.id,this.name,this.width,this.height,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.Canvas.FromObject=function(e){return new GameLib.Canvas(GameLib.API.Canvas.FromObject(e))},GameLib.Clock=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.Clock)return t;GameLib.API.Clock.call(this,t.id,t.name,t.parentEntity),GameLib.Component.call(this)},GameLib.Clock.prototype=Object.create(GameLib.API.Clock.prototype),GameLib.Clock.prototype.constructor=GameLib.Clock,GameLib.Clock.prototype.createInstance=function(){this.instance=new THREE.Clock,GameLib.Component.prototype.createInstance.call(this)},GameLib.Clock.prototype.updateInstance=function(){},GameLib.Clock.prototype.getDelta=function(){var e=this.instance.getDelta();return e>1/30&&(e=1/30),e},GameLib.Clock.prototype.toApiObject=function(){return new GameLib.API.Clock(this.id,this.name,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.Clock.FromObject=function(e,t){var i=GameLib.API.Clock.FromObject(t);return new GameLib.Clock(e,i)},GameLib.CoderRuntime=function(e,t,i){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Coder ("+e+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=GameLib.CoderRuntime.TYPE_CODE_MIRROR),this.coderType=i,this.createInstance()},GameLib.CoderRuntime.TYPE_CODE_MIRROR=1,GameLib.CoderRuntime.prototype.createInstance=function(){this.coderType===GameLib.CoderRuntime.TYPE_CODE_MIRROR?this.instance=CodeMirror:this.instance=null},GameLib.CoderRuntime.prototype.updateInstance=function(e){"coderType"===e&&this.createInstance()},GameLib.CoderRuntime.prototype.isNotCodeMirrorThrow=function(){if(this.instance!==CodeMirror)throw console.error("Only CodeMirror supported"),new Error("Only CodeMirror supported")},GameLib.Color=function(e,t,i,n){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.Color)return t;GameLib.API.Color.call(this,t.r,t.g,t.b,t.a),GameLib.Utils.UndefinedOrNull(i)&&(i=null),this.parentObject=i,GameLib.Utils.UndefinedOrNull(n)&&(n=.001),this.grain=n,this.createInstance()},GameLib.Color.prototype=Object.create(GameLib.API.Color.prototype),GameLib.Color.prototype.constructor=GameLib.Color,GameLib.Color.prototype.createInstance=function(){this.instance=new THREE.Color(this.r,this.g,this.b)},GameLib.Color.prototype.updateInstance=function(e){this.instance.r=this.r,this.instance.g=this.g,this.instance.b=this.b,this.parentObject&&this.parentObject.updateInstance&&this.parentObject.updateInstance(e)},GameLib.Color.prototype.toApiObject=function(){return new GameLib.API.Color(this.r,this.g,this.b,this.a)},GameLib.Controls=function(e){if(GameLib.Utils.UndefinedOrNull(e)&&(e={}),e instanceof GameLib.Controls)return e;GameLib.API.Controls.call(this,e.id,e.controlsType,e.name,e.domElement,e.parentEntity);var t={domElement:GameLib.DomElement},i=!1;this.controlsType===GameLib.Controls.CONTROLS_TYPE_EDITOR&&(t.raycaster=GameLib.D3.Raycaster,t.camera=GameLib.D3.Camera,i=!0),GameLib.Component.call(this,t,i)},GameLib.Controls.prototype=Object.create(GameLib.API.Controls.prototype),GameLib.Controls.prototype.constructor=GameLib.Controls,GameLib.Controls.D3=function(){},GameLib.Controls.CONTROLS_TYPE_EDITOR=0,GameLib.Controls.CONTROLS_TYPE_TOUCH=1,GameLib.Controls.CONTROLS_TYPE_KEYBOARD=2,GameLib.Controls.CONTROLS_TYPE_MOUSE=3,GameLib.Controls.prototype.createInstance=function(){GameLib.Component.prototype.createInstance.call(this)},GameLib.Controls.prototype.updateInstance=function(){console.log("default controls update instance")},GameLib.Controls.prototype.toApiObject=function(){return new GameLib.API.Controls(this.id,this.controlsType,this.name,GameLib.Utils.IdOrNull(this.domElement),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.Controls.FromObject=function(e){var t=GameLib.API.Controls.FromObject(e);return new GameLib.Controls(t)},GameLib.Controls.D3.Editor=function(e,t,i,n){this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(i)&&(i=null),this.raycaster=i,GameLib.Utils.UndefinedOrNull(n)&&(n=null),this.camera=n,this.raycaster instanceof GameLib.D3.API.Raycaster&&(this.raycaster=new GameLib.D3.Raycaster(this.graphics,this.raycaster)),this.camera instanceof GameLib.D3.API.Camera&&(this.camera=new GameLib.D3.Camera(this.graphics,this.camera)),GameLib.Controls.call(this,t)},GameLib.Controls.D3.Editor.prototype=Object.create(GameLib.Controls.prototype),GameLib.Controls.D3.Editor.prototype.constructor=GameLib.Controls.D3.Editor,GameLib.Controls.D3.Editor.prototype.createInstance=function(){if(!this.camera||!this.camera.instance)throw new Error("No camera at time of instance");if(!this.domElement||!this.domElement.instance)throw new Error("No dom element at time of instance");this.instance=new THREE.EditorControls(this.camera.instance,this.domElement.instance),GameLib.Controls.prototype.createInstance.call(this)},GameLib.Controls.D3.Editor.prototype.updateInstance=function(){console.warn("an update instance was called on editor controls - which, if not called from within a running system at the right time will affect the order of input event handling and cause system instability"),GameLib.Controls.prototype.updateInstance.call(this)},GameLib.Controls.D3.Editor.prototype.toApiObject=function(){var e=GameLib.Controls.prototype.toApiObject.call(this);return e.raycaster=GameLib.Utils.IdOrNull(this.raycaster),e.camera=GameLib.Utils.IdOrNull(this.camera),e},GameLib.Controls.D3.Editor.FromObject=function(e,t){var i=GameLib.API.Controls.FromObject(t);return new GameLib.Controls.D3.Editor(e,i,t.raycaster,t.camera)},GameLib.Controls.Keyboard=function(e){GameLib.Controls.call(this,e)},GameLib.Controls.Keyboard.prototype=Object.create(GameLib.Controls.prototype),GameLib.Controls.Keyboard.prototype.constructor=GameLib.Controls.Keyboard,GameLib.Controls.Keyboard.prototype.createInstance=function(){this.instance=!0,GameLib.Controls.prototype.createInstance.call(this)},GameLib.Controls.Keyboard.prototype.updateInstance=function(){GameLib.Controls.prototype.updateInstance.call(this)},GameLib.Controls.Keyboard.prototype.toApiObject=function(){return GameLib.Controls.prototype.toApiObject.call(this)},GameLib.Controls.Keyboard.FromObject=function(e){var t=GameLib.API.Controls.FromObject(e);return new GameLib.Controls.Keyboard(t)},GameLib.Controls.Mouse=function(e){GameLib.Controls.call(this,e)},GameLib.Controls.Mouse.prototype=Object.create(GameLib.Controls.prototype),GameLib.Controls.Mouse.prototype.constructor=GameLib.Controls.Mouse,GameLib.Controls.Mouse.prototype.createInstance=function(){this.instance=!0,GameLib.Controls.prototype.createInstance.call(this)},GameLib.Controls.Mouse.prototype.updateInstance=function(){GameLib.Controls.prototype.updateInstance.call(this)},GameLib.Controls.Mouse.prototype.toApiObject=function(){return GameLib.Controls.prototype.toApiObject.call(this)},GameLib.Controls.Mouse.FromObject=function(e){var t=GameLib.API.Controls.FromObject(e);return new GameLib.Controls.Mouse(t)},GameLib.Controls.Touch=function(e,t){GameLib.Utils.UndefinedOrNull(t)&&(t=5),this.sensitivity=t,GameLib.Controls.call(this,e)},GameLib.Controls.Touch.prototype=Object.create(GameLib.Controls.prototype),GameLib.Controls.Touch.prototype.constructor=GameLib.Controls.Touch,GameLib.Controls.Touch.prototype.createInstance=function(){this.instance=!0,GameLib.Controls.prototype.createInstance.call(this)},GameLib.Controls.Touch.prototype.updateInstance=function(){GameLib.Controls.prototype.updateInstance.call(this)},GameLib.Controls.Touch.prototype.toApiObject=function(){var e=GameLib.Controls.prototype.toApiObject.call(this);return e.sensitivity=this.sensitivity,e},GameLib.Controls.Touch.FromObject=function(e){var t=GameLib.API.Controls.FromObject(e);return new GameLib.Controls.Touch(t,e.sensitivity)},GameLib.CustomCode=function(e){if(GameLib.Utils.UndefinedOrNull(e)&&(e={}),e instanceof GameLib.CustomCode)return e;GameLib.API.CustomCode.call(this,e.id,e.name,e.eventId,e.code,e.parentEntity),this.editor=null,GameLib.Component.call(this)},GameLib.CustomCode.prototype=Object.create(GameLib.API.CustomCode.prototype),GameLib.CustomCode.prototype.constructor=GameLib.CustomCode,GameLib.CustomCode.prototype.createInstance=function(){try{this.instance=new Function("data",this.code).bind(this)}catch(e){this.instance=new Function("data","console.log('compilation failed for : "+this.name+"');").bind(this)}GameLib.Component.prototype.createInstance.call(this)},GameLib.CustomCode.prototype.updateInstance=function(){try{this.instance=new Function("data",this.code).bind(this),this.publish(GameLib.Event.COMPILE_SUCCESS,{component:this})}catch(e){this.instance=new Function("data","console.log('compilation update failed for : "+this.name+"');").bind(this),this.publish(GameLib.Event.COMPILE_FAILED,{component:this})}},GameLib.CustomCode.prototype.toApiObject=function(){return new GameLib.API.CustomCode(this.id,this.name,this.eventId,this.code,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.CustomCode.FromObject=function(e){var t=GameLib.API.CustomCode.FromObject(e);return new GameLib.CustomCode(t)},GameLib.CustomCode.prototype.launchEditor=function(){GameLib.Event.Emit(GameLib.Event.GET_RUNTIME,null,function(e){this.coder=e.coder,this.coder.isNotCodeMirrorThrow()}.bind(this)),this.editor=this.coder.instance(document.body,{value:this.code,mode:"javascript",lineNumbers:!0,scrollbarStyle:"overlay",indentWithTabs:!0,indentUnit:4}),this.editor.on("change",function(){this.code=this.editor.getValue(),this.updateInstance()}.bind(this))},GameLib.CustomCode.prototype.closeEditor=function(){var e=this.editor.getWrapperElement();e.parentElement.removeChild(e)},GameLib.D3.API.Animation=function(e,t,i,n,a,s,o,r,c,m,h,l){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Animation ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=0),this.rotationSpeed=i,GameLib.Utils.UndefinedOrNull(n)&&(n=0),this.translationSpeed=n,GameLib.Utils.UndefinedOrNull(a)&&(a=0),this.scaleSpeed=a,GameLib.Utils.UndefinedOrNull(s)&&(s=null),this.rotationFn=s,GameLib.Utils.UndefinedOrNull(o)&&(o=null),this.translationFn=o,GameLib.Utils.UndefinedOrNull(r)&&(r=null),this.scaleFn=r,GameLib.Utils.UndefinedOrNull(c)&&(c={position:!1,rotation:!0,scale:!1}),this.blocking=c,GameLib.Utils.UndefinedOrNull(m)&&(m=!0),this.applyToMeshWhenDone=m,GameLib.Utils.UndefinedOrNull(h)&&(h=[]),this.meshes=h,GameLib.API.Component.call(this,GameLib.Component.ANIMATION,l)},GameLib.D3.API.Animation.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Animation.prototype.constructor=GameLib.D3.API.Animation,GameLib.D3.API.Animation.FromObject=function(e){return new GameLib.D3.API.Animation(e.id,e.name,e.rotationSpeed,e.translationSpeed,e.scaleSpeed,e.rotationFn,e.translationFn,e.scaleFn,e.blocking,e.applyToMeshWhenDone,e.meshes,e.parentEntity)},GameLib.D3.API.Audio=function(e,t,i,n,a,s,o,r,c){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Audio ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=""),this.path=i,GameLib.Utils.UndefinedOrNull(n)&&(n=!1),this.loop=n,GameLib.Utils.UndefinedOrNull(a)&&(a=.5),this.volume=a,GameLib.Utils.UndefinedOrNull(s)&&(s=null),this.camera=s,GameLib.Utils.UndefinedOrNull(o)&&(o=!1),this.overplay=o,GameLib.Utils.UndefinedOrNull(r)&&(r=!1),this.paused=r,GameLib.API.Component.call(this,GameLib.Component.AUDIO,c)},GameLib.D3.API.Audio.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Audio.prototype.constructor=GameLib.D3.API.Audio,GameLib.D3.API.Audio.FromObject=function(e){var t=null;return e.camera&&(t=e.camera instanceof Object?GameLib.D3.API.Camera.FromObject(e.camera):e.camera),new GameLib.D3.API.Audio(e.id,e.name,e.path,e.loop,e.volume,t,e.overplay,e.paused,e.parentEntity)},GameLib.D3.API.BoneWeight=function(e,t){this.boneIndex=e,this.weight=t},GameLib.D3.API.BoneWeight.FromObject=function(e){return new GameLib.D3.API.BoneWeight(e.boneIndex,e.weight)},GameLib.D3.API.Bone=function(e,t,i,n,a,s,o,r,c){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Bone ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=[]),this.childBoneIds=i,GameLib.Utils.UndefinedOrNull(n)&&(n=[]),this.parentBoneIds=n,GameLib.Utils.UndefinedOrNull(a)&&(a=new GameLib.API.Vector3),this.position=a,GameLib.Utils.UndefinedOrNull(s)&&(s=new GameLib.API.Quaternion),this.quaternion=s,GameLib.Utils.UndefinedOrNull(o)&&(o=new GameLib.API.Vector3(1,1,1)),this.scale=o,GameLib.Utils.UndefinedOrNull(r)&&(r=new GameLib.API.Vector3(0,1,0)),this.up=r,GameLib.API.Component.call(this,GameLib.Component.BONE,c)},GameLib.D3.API.Bone.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Bone.prototype.constructor=GameLib.D3.API.Bone,GameLib.D3.API.Bone.FromObject=function(e){return new GameLib.D3.API.Bone(e.id,e.name,e.childBoneIds,e.parentBoneIds,GameLib.API.Vector3.FromObject(e.position),GameLib.API.Quaternion.FromObject(e.quaternion),GameLib.API.Vector3.FromObject(e.scale),GameLib.API.Vector3.FromObject(e.up),e.parentEntity)},GameLib.D3.API.Broadphase=function(e,t,i,n){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Broadphase ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE),this.broadphaseType=i,GameLib.API.Component.call(this,GameLib.Component.BROADPHASE,n)},GameLib.D3.API.Broadphase.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Broadphase.prototype.constructor=GameLib.D3.API.Broadphase,GameLib.D3.API.Broadphase.FromObject=function(e){return new GameLib.D3.API.Broadphase(e.id,e.name,e.broadphaseType,e.parentEntity)},GameLib.D3.API.Camera=function(e,t,i,n,a,s,o,r,c,m,h,l,p,u,b,d,L,G,E,f,y){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t=GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE),this.cameraType=t,GameLib.Utils.UndefinedOrNull(i)&&(i="Camera ("+this.id+")"),this.name=i,GameLib.Utils.UndefinedOrNull(n)&&(n=75),this.fov=n,GameLib.Utils.UndefinedOrNull(a)&&(a=window.innerWidth/window.innerHeight),this.aspect=a,GameLib.Utils.UndefinedOrNull(s)&&(s=.01),this.near=s,GameLib.Utils.UndefinedOrNull(o)&&(o=1e3),this.far=o,GameLib.Utils.UndefinedOrNull(r)&&(r=new GameLib.API.Vector3(15,15,15)),this.position=r,GameLib.Utils.UndefinedOrNull(G)&&(G=new GameLib.API.Quaternion),this.quaternion=G,GameLib.Utils.UndefinedOrNull(c)&&(c=new GameLib.API.Vector3(0,0,0)),this.lookAt=c,GameLib.Utils.UndefinedOrNull(m)&&(m=-100),this.minX=m,GameLib.Utils.UndefinedOrNull(h)&&(h=100),this.maxX=h,GameLib.Utils.UndefinedOrNull(l)&&(l=-100),this.minY=l,GameLib.Utils.UndefinedOrNull(p)&&(p=100),this.maxY=p,GameLib.Utils.UndefinedOrNull(u)&&(u=-100),this.minZ=u,GameLib.Utils.UndefinedOrNull(b)&&(b=100),this.maxZ=b,GameLib.Utils.UndefinedOrNull(d)&&(d=0),this.offsetX=d,GameLib.Utils.UndefinedOrNull(L)&&(L=0),this.offsetY=L,GameLib.Utils.UndefinedOrNull(E)&&(E=30),this.eyeSeparation=E,GameLib.Utils.UndefinedOrNull(f)&&(f=150),this.focalLength=f,GameLib.API.Component.call(this,GameLib.Component.CAMERA,y)},GameLib.D3.API.Camera.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Camera.prototype.constructor=GameLib.D3.API.Camera,GameLib.D3.API.Camera.FromObject=function(e){return new GameLib.D3.API.Camera(e.id,e.cameraType,e.name,e.fov,e.aspect,e.near,e.far,GameLib.API.Vector3.FromObject(e.position),GameLib.API.Vector3.FromObject(e.lookAt),e.minX,e.maxX,e.minY,e.maxY,e.minZ,e.maxZ,e.offsetX,e.offsetY,GameLib.API.Quaternion.FromObject(e.quaternion),e.eyeSeparation,e.focalLength,e.parentEntity)},GameLib.D3.API.Composer=function(e,t,i,n,a,s){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Composer ("+e+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=null),this.renderer=i,GameLib.Utils.UndefinedOrNull(n)&&(n=null),this.renderTarget=n,GameLib.Utils.UndefinedOrNull(a)&&(a=[]),this.passes=a,GameLib.API.Component.call(this,GameLib.Component.COMPOSER,s)},GameLib.D3.API.Composer.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Composer.prototype.constructor=GameLib.D3.API.Composer,GameLib.D3.API.Composer.FromObject=function(e){return new GameLib.D3.API.Composer(e.id,e.name,e.renderer,e.renderTarget,e.passes,e.parentEntity)},GameLib.D3.API.Face=function(e,t,i,n,a,s,o,r,c,m,h){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Face "+e),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=-1),this.v0index=i,GameLib.Utils.UndefinedOrNull(n)&&(n=-1),this.v1index=n,GameLib.Utils.UndefinedOrNull(a)&&(a=-1),this.v2index=a,GameLib.Utils.UndefinedOrNull(s)&&(s=-1),this.materialIndex=s,GameLib.Utils.UndefinedOrNull(o)&&(o=[[]]),this.uvs=o,GameLib.Utils.UndefinedOrNull(r)&&(r=null),this.color=r,GameLib.Utils.UndefinedOrNull(c)&&(c=[]),this.vertexColors=c,GameLib.Utils.UndefinedOrNull(m)&&(m=[]),this.vertexNormals=m,GameLib.Utils.UndefinedOrNull(h)&&(h=null),this.normal=h},GameLib.D3.API.Face.FromObject=function(e){var t=e.uvs.reduce(function(e,t,i){return e[i]=t.reduce(function(e,t){return e.push(GameLib.API.Vector2.FromObject(t)),e},[]),e},[]),i=e.vertexColors.map(function(e){return GameLib.API.Color.FromObject(e)}),n=null;e.color&&(n=GameLib.API.Color.FromObject(e.color));var a=e.vertexNormals.map(function(e){return GameLib.API.Vector3.FromObject(e)}),s=null;return e.normal&&(s=GameLib.API.Vector3.FromObject(e.normal)),new GameLib.D3.API.Face(e.id,e.name,e.v0index,e.v1index,e.v2index,e.materialIndex,t,n,i,a,s)},GameLib.D3.API.Face.prototype.clone=function(){return new GameLib.D3.API.Face(this.id,this.name,this.v0index,this.v1index,this.v2index,this.materialIndex,this.uvs,this.color,this.vertexColors,this.vertexNormals,this.normal)},GameLib.D3.API.Face.prototype.equals=function(e){return this.v0index===e.v0index&&this.v1index===e.v1index&&this.v2index===e.v2index||this.v0index===e.v0index&&this.v1index===e.v2index&&this.v2index===e.v1index||this.v0index===e.v1index&&this.v1index===e.v0index&&this.v2index===e.v2index||this.v0index===e.v1index&&this.v1index===e.v2index&&this.v2index===e.v0index||this.v0index===e.v2index&&this.v1index===e.v0index&&this.v2index===e.v1index||this.v0index===e.v2index&&this.v1index===e.v1index&&this.v2index===e.v0index},GameLib.D3.API.Fog=function(e,t,i,n,a,s,o,r){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Fog ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=!1),this.exponential=i,GameLib.Utils.UndefinedOrNull(n)&&(n=new GameLib.API.Color(1,1,1,1)),this.color=n,GameLib.Utils.UndefinedOrNull(a)&&(a=1),this.near=a,GameLib.Utils.UndefinedOrNull(s)&&(s=1e3),this.far=s,GameLib.Utils.UndefinedOrNull(o)&&(o=25e-5),this.density=o,GameLib.API.Component.call(this,GameLib.Component.FOG,r)},GameLib.D3.API.Fog.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Fog.prototype.constructor=GameLib.D3.API.Fog,GameLib.D3.API.Fog.FromObject=function(e){return new GameLib.D3.API.Fog(e.id,e.name,e.exponential,e.color,e.near,e.far,e.density,e.parentEntity)},GameLib.D3.API.Font=function(e,t,i,n){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Font ("+e+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i="/apiRelative/path/to/font"),this.url=i,GameLib.API.Component.call(this,GameLib.Component.FONT,n)},GameLib.D3.API.Font.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Font.prototype.constructor=GameLib.D3.API.Font,GameLib.D3.API.Font.FromObject=function(e){return new GameLib.D3.API.Font(e.id,e.name,e.url,e.parentEntity)},GameLib.D3.API.FrictionContactMaterial=function(e,t,i,n,a,s,o,r,c,m){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Friction Material ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=[]),this.materials=i,GameLib.Utils.UndefinedOrNull(n)&&(n=.3),this.friction=n,GameLib.Utils.UndefinedOrNull(a)&&(a=.3),this.restitution=a,GameLib.Utils.UndefinedOrNull(s)&&(s=1e7),this.contactEquationStiffness=s,GameLib.Utils.UndefinedOrNull(o)&&(o=3),this.contactEquationRelaxation=o,GameLib.Utils.UndefinedOrNull(r)&&(r=1e7),this.frictionEquationStiffness=r,GameLib.Utils.UndefinedOrNull(c)&&(c=3),this.frictionEquationRelaxation=c,GameLib.API.Component.call(this,GameLib.Component.FRICTION_CONTACT_MATERIAL,m)},GameLib.D3.API.FrictionContactMaterial.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.FrictionContactMaterial.prototype.constructor=GameLib.D3.API.FrictionContactMaterial,GameLib.D3.API.FrictionContactMaterial.FromObject=function(e){return new GameLib.D3.API.FrictionContactMaterial(e.id,e.name,e.materials,e.friction,e.restitution,e.contactEquationStiffness,e.contactEquationRelaxation,e.frictionEquationStiffness,e.frictionEquationRelaxation,e.parentEntity)},GameLib.D3.API.FrictionMaterial=function(e,t,i,n,a){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Friction Material ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=-1),this.friction=i,GameLib.Utils.UndefinedOrNull(n)&&(n=-1),this.restitution=n,GameLib.API.Component.call(this,GameLib.Component.FRICTION_MATERIAL,a)},GameLib.D3.API.FrictionMaterial.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.FrictionMaterial.prototype.constructor=GameLib.D3.API.FrictionMaterial,GameLib.D3.API.FrictionMaterial.FromObject=function(e){return new GameLib.D3.API.FrictionMaterial(e.id,e.name,e.friction,e.restitution,e.parentEntity)},GameLib.D3.API.Light=function(e,t,i,n,a,s,o,r,c,m,h,l,p,u,b,d,L){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t=GameLib.D3.Light.LIGHT_TYPE_AMBIENT),this.lightType=t,GameLib.Utils.UndefinedOrNull(i)&&(this.lightType===GameLib.D3.Light.LIGHT_TYPE_AMBIENT&&(i="Ambient "),this.lightType===GameLib.D3.Light.LIGHT_TYPE_DIRECTIONAL&&(i="Directional "),this.lightType===GameLib.D3.Light.LIGHT_TYPE_POINT&&(i="Point "),this.lightType===GameLib.D3.Light.LIGHT_TYPE_SPOT&&(i="Spot "),i+="Light ("+e+")"),this.name=i,GameLib.Utils.UndefinedOrNull(n)&&(n=new GameLib.API.Color(1,1,1,1)),this.color=n,GameLib.Utils.UndefinedOrNull(a)&&(a=1),this.intensity=a,GameLib.Utils.UndefinedOrNull(s)&&(s=new GameLib.API.Vector3(10,10,10)),this.position=s,GameLib.Utils.UndefinedOrNull(o)&&(o=new GameLib.API.Vector3(0,0,0)),this.targetPosition=o,GameLib.Utils.UndefinedOrNull(r)&&(r=new GameLib.API.Quaternion),this.quaternion=r,GameLib.Utils.UndefinedOrNull(c)&&(c=new GameLib.API.Vector3(0,0,0)),this.rotation=c,GameLib.Utils.UndefinedOrNull(m)&&(m=new GameLib.API.Vector3(1,1,1)),this.scale=m,GameLib.Utils.UndefinedOrNull(h)&&(h=0),this.distance=h,GameLib.Utils.UndefinedOrNull(l)&&(l=1),this.decay=l,GameLib.Utils.UndefinedOrNull(p)&&(p=4*Math.PI),this.power=p,GameLib.Utils.UndefinedOrNull(u)&&(u=Math.PI/3),this.angle=u,GameLib.Utils.UndefinedOrNull(b)&&(b=0),this.penumbra=b,GameLib.Utils.UndefinedOrNull(d)&&(d=null),this.parentScene=d,GameLib.API.Component.call(this,GameLib.Component.LIGHT,L)},GameLib.D3.API.Light.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Light.prototype.constructor=GameLib.D3.API.Light,GameLib.D3.API.Light.FromObject=function(e){return new GameLib.D3.API.Light(e.id,e.lightType,e.name,GameLib.API.Color.FromObject(e.color),e.intensity,GameLib.API.Vector3.FromObject(e.position),GameLib.API.Vector3.FromObject(e.targetPosition),GameLib.API.Quaternion.FromObject(e.quaternion),GameLib.API.Vector3.FromObject(e.rotation),GameLib.API.Vector3.FromObject(e.scale),e.distance,e.decay,e.power,e.angle,e.penumbra,e.parentScene,e.parentEntity)},GameLib.D3.API.Material=function(e,t,i,n,a,s,o,r,c,m,h,l,p,u,b,d,L,G,E,f,y,I,P,A,T,O,S,D,C,g,U,v,N,_,M,w,R,x,F,Y,j,V,H,k,z,B,q,W,X,Q,K,Z,J,$,ee,te,ie,ne,ae,se,oe,re,ce,me,he,le,pe,ue,be){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t=GameLib.D3.Material.MATERIAL_TYPE_STANDARD),this.materialType=t,GameLib.Utils.UndefinedOrNull(i)&&(i="Material ("+t+")"),this.name=i,GameLib.Utils.UndefinedOrNull(n)&&(n=1),this.opacity=n,GameLib.Utils.UndefinedOrNull(a)&&(a=GameLib.D3.Material.TYPE_FRONT_SIDE),this.side=a,GameLib.Utils.UndefinedOrNull(s)&&(s=!1),this.transparent=s,GameLib.Utils.UndefinedOrNull(o)&&(o=new GameLib.API.Color(.06,.06,.06,.06)),this.specular=o,GameLib.Utils.UndefinedOrNull(r)&&(r=1),this.lightMapIntensity=r,GameLib.Utils.UndefinedOrNull(c)&&(c=1),this.aoMapIntensity=c,GameLib.Utils.UndefinedOrNull(m)&&(m=new GameLib.API.Color(1,1,1,1)),this.color=m,GameLib.Utils.UndefinedOrNull(h)&&(h=new GameLib.API.Color(0,0,0,0)),this.emissive=h,GameLib.Utils.UndefinedOrNull(l)&&(l=1),this.emissiveIntensity=l,GameLib.Utils.UndefinedOrNull(p)&&(p=GameLib.D3.Material.TYPE_MULTIPLY_OPERATION),this.combine=p,GameLib.Utils.UndefinedOrNull(u)&&(u=30),this.shininess=u,GameLib.Utils.UndefinedOrNull(b)&&(b=1),this.reflectivity=b,GameLib.Utils.UndefinedOrNull(d)&&(d=.98),this.refractionRatio=d,GameLib.Utils.UndefinedOrNull(L)&&(L=!0),this.fog=L,GameLib.Utils.UndefinedOrNull(G)&&(G=!1),this.wireframe=G,GameLib.Utils.UndefinedOrNull(E)&&(E=1),this.wireframeLineWidth=E,GameLib.Utils.UndefinedOrNull(f)&&(f="round"),this.wireframeLineCap=f,GameLib.Utils.UndefinedOrNull(y)&&(y="round"),this.wireframeLineJoin=y,GameLib.Utils.UndefinedOrNull(I)&&(I=GameLib.D3.Material.TYPE_NO_COLORS),this.vertexColors=I,GameLib.Utils.UndefinedOrNull(P)&&(P=!1),this.skinning=P,GameLib.Utils.UndefinedOrNull(A)&&(A=!1),this.morphTargets=A,GameLib.Utils.UndefinedOrNull(T)&&(T=!1),this.morphNormals=T,GameLib.Utils.UndefinedOrNull(z)&&(z=0),this.overdraw=z,GameLib.Utils.UndefinedOrNull(O)&&(O=1),this.lineWidth=O,GameLib.Utils.UndefinedOrNull(S)&&(S="round"),this.lineCap=S,GameLib.Utils.UndefinedOrNull(D)&&(D="round"),this.lineJoin=D,GameLib.Utils.UndefinedOrNull(C)&&(C=3),this.dashSize=C,GameLib.Utils.UndefinedOrNull(g)&&(g=1),this.gapWidth=g,GameLib.Utils.UndefinedOrNull(U)&&(U=GameLib.D3.Material.TYPE_NORMAL_BLENDING),this.blending=U,GameLib.Utils.UndefinedOrNull(v)&&(v=GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR),this.blendSrc=v,GameLib.Utils.UndefinedOrNull(N)&&(N=GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR),this.blendDst=N,GameLib.Utils.UndefinedOrNull(_)&&(_=GameLib.D3.Material.TYPE_ADD_EQUATION),this.blendEquation=_,GameLib.Utils.UndefinedOrNull(M)&&(M=!0),this.depthTest=M,GameLib.Utils.UndefinedOrNull(w)&&(w=GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH),this.depthFunc=w,GameLib.Utils.UndefinedOrNull(R)&&(R=!0),this.depthWrite=R,GameLib.Utils.UndefinedOrNull(x)&&(x=!1),this.polygonOffset=x,GameLib.Utils.UndefinedOrNull(F)&&(F=1),this.polygonOffsetFactor=F,GameLib.Utils.UndefinedOrNull(Y)&&(Y=1),this.polygonOffsetUnits=Y,GameLib.Utils.UndefinedOrNull(j)&&(j=0),this.alphaTest=j,GameLib.Utils.UndefinedOrNull(V)&&(V=[]),this.clippingPlanes=V,GameLib.Utils.UndefinedOrNull(H)&&(H=!1),this.clipShadows=H,GameLib.Utils.UndefinedOrNull(k)&&(k=!0),this.visible=k,GameLib.Utils.UndefinedOrNull(B)&&(B=!1),this.flatShading=B,GameLib.Utils.UndefinedOrNull(q)&&(q=1),this.bumpScale=q,GameLib.Utils.UndefinedOrNull(W)&&(W=1),this.normalScale=W,GameLib.Utils.UndefinedOrNull(X)&&(X=1),this.displacementScale=X, -GameLib.Utils.UndefinedOrNull(Q)&&(Q=0),this.displacementBias=Q,GameLib.Utils.UndefinedOrNull(K)&&(K=.5),this.roughness=K,GameLib.Utils.UndefinedOrNull(Z)&&(Z=.5),this.metalness=Z,GameLib.Utils.UndefinedOrNull(J)&&(J=1),this.pointSize=J,GameLib.Utils.UndefinedOrNull($)&&($=!0),this.pointSizeAttenuation=$,GameLib.Utils.UndefinedOrNull(ee)&&(ee=0),this.spriteRotation=ee,GameLib.Utils.UndefinedOrNull(te)&&(te=1),this.envMapIntensity=te,GameLib.Utils.UndefinedOrNull(ie)&&(ie=null),this.alphaMap=ie,GameLib.Utils.UndefinedOrNull(ne)&&(ne=null),this.aoMap=ne,GameLib.Utils.UndefinedOrNull(ae)&&(ae=null),this.bumpMap=ae,GameLib.Utils.UndefinedOrNull(se)&&(se=null),this.diffuseMap=se,GameLib.Utils.UndefinedOrNull(oe)&&(oe=null),this.displacementMap=oe,GameLib.Utils.UndefinedOrNull(re)&&(re=null),this.emissiveMap=re,GameLib.Utils.UndefinedOrNull(ce)&&(ce=null),this.environmentMap=ce,GameLib.Utils.UndefinedOrNull(me)&&(me=null),this.lightMap=me,GameLib.Utils.UndefinedOrNull(he)&&(he=null),this.metalnessMap=he,GameLib.Utils.UndefinedOrNull(le)&&(le=null),this.normalMap=le,GameLib.Utils.UndefinedOrNull(pe)&&(pe=null),this.roughnessMap=pe,GameLib.Utils.UndefinedOrNull(ue)&&(ue=null),this.specularMap=ue,GameLib.API.Component.call(this,GameLib.Component.MATERIAL,be),this.needsUpdate=!1},GameLib.D3.API.Material.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Material.prototype.constructor=GameLib.D3.API.Material,GameLib.D3.API.Material.FromObject=function(e){var t=null,i=null,n=null,a=null,s=null,o=null,r=null,c=null,m=null,h=null,l=null,p=null;return e.alphaMap&&(t=e.alphaMap),e.aoMap&&(i=e.aoMap),e.bumpMap&&(n=e.bumpMap),e.diffuseMap&&(a=e.diffuseMap),e.displacementMap&&(s=e.displacementMap),e.emissiveMap&&(o=e.emissiveMap),e.environmentMap&&(r=e.environmentMap),e.lightMap&&(c=e.lightMap),e.metalnessMap&&(m=e.metalnessMap),e.normalMap&&(h=e.normalMap),e.roughnessMap&&(l=e.roughnessMap),e.specularMap&&(p=e.specularMap),new GameLib.D3.API.Material(e.id,e.materialType,e.name,e.opacity,e.side,e.transparent,GameLib.API.Color.FromObject(e.specular),e.lightMapIntensity,e.aoMapIntensity,GameLib.API.Color.FromObject(e.color),GameLib.API.Color.FromObject(e.emissive),e.emissiveIntensity,e.combine,e.shininess,e.reflectivity,e.refractionRatio,e.fog,e.wireframe,e.wireframeLineWidth,e.wireframeLineCap,e.wireframeLineJoin,e.vertexColors,e.skinning,e.morphTargets,e.morphNormals,e.lineWidth,e.lineCap,e.lineJoin,e.dashSize,e.gapWidth,e.blending,e.blendSrc,e.blendDst,e.blendEquation,e.depthTest,e.depthFunc,e.depthWrite,e.polygonOffset,e.polygonOffsetFactor,e.polygonOffsetUnits,e.alphaTest,e.clippingPlanes,e.clipShadows,e.visible,e.overdraw,e.flatShading,e.bumpScale,e.normalScale,e.displacementScale,e.displacementBias,e.roughness,e.metalness,e.pointSize,e.pointSizeAttenuation,e.spriteRotation,e.envMapIntensity,t,i,n,a,s,o,r,c,m,h,l,p,e.parentEntity)},GameLib.D3.API.Mesh=function(e,t,i,n,a,s,o,r,c,m,h,l,p,u,b,d,L,G,E,f,y,I){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t=GameLib.D3.API.Mesh.MESH_TYPE_NORMAL),this.meshType=t,GameLib.Utils.UndefinedOrNull(i)&&(i="Mesh ("+e+")"),this.name=i,GameLib.Utils.UndefinedOrNull(n)&&(n=[]),this.vertices=n,GameLib.Utils.UndefinedOrNull(a)&&(a=[]),this.faces=a,GameLib.Utils.UndefinedOrNull(o)&&(o=null),this.parentMesh=o,GameLib.Utils.UndefinedOrNull(r)&&(r=null),this.parentScene=r,GameLib.Utils.UndefinedOrNull(c)&&(c=null),this.skeleton=c,GameLib.Utils.UndefinedOrNull(m)&&(m=[]),this.skinIndices=m,GameLib.Utils.UndefinedOrNull(h)&&(h=[]),this.skinWeights=h,(GameLib.Utils.UndefinedOrNull(s)||s instanceof Array&&0===s.length)&&(s=[new GameLib.D3.API.Material(null,GameLib.D3.Material.MATERIAL_TYPE_STANDARD,"Material ("+this.name+")")]),this.materials=s,GameLib.Utils.UndefinedOrNull(l)&&(l=new GameLib.API.Vector3(0,0,0)),this.position=l,GameLib.Utils.UndefinedOrNull(p)&&(p=new GameLib.API.Quaternion),this.quaternion=p,GameLib.Utils.UndefinedOrNull(u)&&(u=new GameLib.API.Vector3(0,0,0)),this.rotation=u,GameLib.Utils.UndefinedOrNull(b)&&(b=new GameLib.API.Vector3(1,1,1)),this.scale=b,GameLib.Utils.UndefinedOrNull(d)&&(d=new GameLib.API.Vector3(0,1,0)),this.up=d,GameLib.Utils.UndefinedOrNull(L)&&(L=new GameLib.API.Matrix4),this.modelMatrix=L,GameLib.Utils.UndefinedOrNull(G)&&(G=0),this.renderOrder=G,GameLib.Utils.UndefinedOrNull(E)&&(E=!1),this.isBufferMesh=E,GameLib.Utils.UndefinedOrNull(f)&&(f=!0),this.useQuaternion=f,GameLib.Utils.UndefinedOrNull(y)&&(y=!0),this.visible=y;var P=GameLib.Component.MESH;this.meshType===GameLib.D3.API.Mesh.MESH_TYPE_PLANE&&(P=GameLib.Component.MESH_PLANE),this.meshType===GameLib.D3.API.Mesh.MESH_TYPE_BOX&&(P=GameLib.Component.MESH_BOX),this.meshType===GameLib.D3.API.Mesh.MESH_TYPE_CYLINDER&&(P=GameLib.Component.MESH_CYLINDER),this.meshType===GameLib.D3.API.Mesh.MESH_TYPE_SPHERE&&(P=GameLib.Component.MESH_SPHERE),this.meshType===GameLib.D3.API.Mesh.MESH_TYPE_LINE&&(P=GameLib.Component.MESH_LINE),this.meshType===GameLib.D3.API.Mesh.MESH_TYPE_TEXT&&(P=GameLib.Component.MESH_TEXT),GameLib.API.Component.call(this,P,I)},GameLib.D3.API.Mesh.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Mesh.prototype.constructor=GameLib.D3.API.Mesh,GameLib.D3.API.Mesh.MESH_TYPE_NORMAL=0,GameLib.D3.API.Mesh.MESH_TYPE_SKINNED=1,GameLib.D3.API.Mesh.MESH_TYPE_CURVE=2,GameLib.D3.API.Mesh.MESH_TYPE_SPHERE=3,GameLib.D3.API.Mesh.MESH_TYPE_PLANE=4,GameLib.D3.API.Mesh.MESH_TYPE_BOX=5,GameLib.D3.API.Mesh.MESH_TYPE_CYLINDER=6,GameLib.D3.API.Mesh.MESH_TYPE_TEXT=7,GameLib.D3.API.Mesh.MESH_TYPE_LINE=8,GameLib.D3.API.Mesh.FromObject=function(e){var t=[];e.faces&&(t=e.faces.map(function(e){return GameLib.D3.API.Face.FromObject(e)}));var i=null;e.skeleton&&(i=GameLib.D3.API.Skeleton.FromObject(e.skeleton));var n=[];e.materials&&(n=e.materials.map(function(e){return e instanceof Object?GameLib.D3.API.Material.FromObject(e):e}));var a=[];e.vertices&&(a=e.vertices.map(function(e){return GameLib.D3.API.Vertex.FromObject(e)}));var s=new GameLib.API.Vector3;e.position&&(s=GameLib.API.Vector3.FromObject(e.position));var o=new GameLib.API.Vector3;e.rotation&&(o=GameLib.API.Vector3.FromObject(e.rotation));var r=new GameLib.API.Quaternion;e.quaternion&&(r=GameLib.API.Quaternion.FromObject(e.quaternion));var c=new GameLib.API.Vector3(1,1,1);e.scale&&(c=GameLib.API.Vector3.FromObject(e.scale));var m=new GameLib.API.Vector3(0,1,0);e.up&&(m=GameLib.API.Vector3.FromObject(e.up));var h=new GameLib.API.Matrix4;e.modelMatrix&&(h=GameLib.API.Matrix4.FromObject(e.modelMatrix));var l=GameLib.D3.API.Mesh.MESH_TYPE_NORMAL;return e.meshType!==GameLib.D3.API.Mesh.MESH_TYPE_NORMAL&&e.meshType!==GameLib.D3.API.Mesh.MESH_TYPE_SKINNED||(l=e.meshType),e.componentType===GameLib.Component.MESH_PLANE&&(l=GameLib.D3.API.Mesh.MESH_TYPE_PLANE),e.componentType===GameLib.Component.MESH_SPHERE&&(l=GameLib.D3.API.Mesh.MESH_TYPE_SPHERE),e.componentType===GameLib.Component.MESH_CURVE&&(l=GameLib.D3.API.Mesh.MESH_TYPE_CURVE),e.componentType===GameLib.Component.MESH_BOX&&(l=GameLib.D3.API.Mesh.MESH_TYPE_BOX),e.componentType===GameLib.Component.MESH_CYLINDER&&(l=GameLib.D3.API.Mesh.MESH_TYPE_CYLINDER),e.componentType===GameLib.Component.MESH_TEXT&&(l=GameLib.D3.API.Mesh.MESH_TYPE_TEXT),e.componentType===GameLib.Component.MESH_TYPE_LINE&&(l=GameLib.D3.API.Mesh.MESH_LINE),new GameLib.D3.API.Mesh(e.id,l,e.name,a,t,n,e.parentMesh,e.parentScene,i,e.skinIndices,e.skinWeights,s,r,o,c,m,h,e.renderOrder,e.isBufferMesh,e.useQuaternion,e.visible,e.parentEntity)},GameLib.D3.API.ParticleEngine=function(e,t,i,n,a,s,o,r,c,m,h,l){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="ParticleEngine ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=new GameLib.API.Vector3(0,0,0)),this.position=i,GameLib.Utils.UndefinedOrNull(n)&&(n=new GameLib.API.Vector3(0,1,0)),this.direction=n,GameLib.Utils.UndefinedOrNull(a)&&(a=!1),this.enabled=a,GameLib.Utils.UndefinedOrNull(s)&&(s=null),this.templateParticle=s,GameLib.Utils.UndefinedOrNull(o)&&(o=1),this.particlesPerSecond=o,GameLib.Utils.UndefinedOrNull(r)&&(r=Number(1/Number(this.particlesPerSecond))),this.frequency=r,GameLib.Utils.UndefinedOrNull(c)&&(c=0),this.elapsed=c,GameLib.Utils.UndefinedOrNull(m)&&(m=null),this.camera=m,GameLib.Utils.UndefinedOrNull(h)&&(h=!1),this.pulse=h,GameLib.API.Component.call(this,GameLib.Component.PARTICLE_ENGINE,l)},GameLib.D3.API.ParticleEngine.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.ParticleEngine.prototype.constructor=GameLib.D3.API.ParticleEngine,GameLib.D3.API.ParticleEngine.FromObject=function(e){var t=null;e.templateParticle&&(t=e.templateParticle instanceof Object?GameLib.D3.API.Particle.FromObject(e.templateParticle):e.templateParticle);var i=null;e.camera&&(i=e.camera instanceof Object?GameLib.D3.API.Camera.FromObject(e.camera):e.camera);var n=null;e.position&&(n=GameLib.API.Vector3.FromObject(e.position));var a=null;return e.direction&&(a=GameLib.API.Vector3.FromObject(e.direction)),new GameLib.D3.API.ParticleEngine(e.id,e.name,n,a,e.enabled,t,e.particlesPerSecond,e.frequency,e.elapsed,i,e.pulse,e.parentEntity)},GameLib.D3.API.Particle=function(e,t,i,n,a,s,o,r,c,m,h,l,p,u,b,d,L,G,E,f,y,I,P){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Particle ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=10),this.lifeTime=i,GameLib.Utils.UndefinedOrNull(n)&&(n=0),this.elapsed=n,GameLib.Utils.UndefinedOrNull(a)&&(a=null),this.mesh=a,GameLib.Utils.UndefinedOrNull(s)&&(s=GameLib.D3.Particle.OPACITY_TYPE_CONSTANT),this.opacityType=s,GameLib.Utils.UndefinedOrNull(o)&&(o=.01),this.opacityFactor=o,GameLib.Utils.UndefinedOrNull(r)&&(r=GameLib.D3.Particle.POSITION_OFFSET_TYPE_CONSTANT),this.positionOffsetType=r,GameLib.Utils.UndefinedOrNull(c)&&(c=new GameLib.API.Vector3(0,0,0)),this.positionOffset=c,GameLib.Utils.UndefinedOrNull(m)&&(m="//@ sourceURL=positionOffsetFn.js"),this.positionOffsetFn=m,GameLib.Utils.UndefinedOrNull(h)&&(h=GameLib.D3.Particle.DIRECTION_TYPE_CONSTANT),this.directionType=h,GameLib.Utils.UndefinedOrNull(l)&&(l=new GameLib.API.Vector3(0,1,0)),this.direction=l,GameLib.Utils.UndefinedOrNull(p)&&(p="//@ sourceURL=directionFn.js"),this.directionFn=p,GameLib.Utils.UndefinedOrNull(u)&&(u=GameLib.D3.Particle.SPEED_TYPE_CONSTANT),this.speedType=u,GameLib.Utils.UndefinedOrNull(b)&&(b=1),this.speed=b,GameLib.Utils.UndefinedOrNull(d)&&(d=GameLib.D3.Particle.SCALE_TYPE_CONSTANT),this.scaleType=d,GameLib.Utils.UndefinedOrNull(L)&&(L=new GameLib.API.Vector3(1,1,1)),this.scale=L,GameLib.Utils.UndefinedOrNull(G)&&(G="//@ sourceURL=scaleFn.js"),this.scaleFn=G,GameLib.Utils.UndefinedOrNull(E)&&(E=GameLib.D3.Particle.ROTATION_TYPE_CONSTANT),this.rotationType=E,GameLib.Utils.UndefinedOrNull(f)&&(f=new GameLib.API.Vector3(0,0,0)),this.rotation=f,GameLib.Utils.UndefinedOrNull(y)&&(y="//@ sourceURL=rotationFn.js"),this.rotationFn=y,GameLib.Utils.UndefinedOrNull(I)&&(I=null),this.parentEngine=I,GameLib.API.Component.call(this,GameLib.Component.PARTICLE,P)},GameLib.D3.API.Particle.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Particle.prototype.constructor=GameLib.D3.API.Particle,GameLib.D3.API.Particle.FromObject=function(e){var t=null;return e.mesh&&(t=e.mesh instanceof Object?GameLib.D3.API.Mesh.FromObject(e.mesh):e.mesh),new GameLib.D3.API.Particle(e.id,e.name,e.lifeTime,e.elapsed,t,e.opacityType,e.opacityFactor,e.positionOffsetType,GameLib.API.Vector3.FromObject(e.positionOffset),e.positionOffsetFn,e.directionType,GameLib.API.Vector3.FromObject(e.direction),e.directionFn,e.speedType,e.speed,e.scaleType,GameLib.API.Vector3.FromObject(e.scale),e.scaleFn,e.rotationType,GameLib.API.Vector3.FromObject(e.rotation),e.rotationFn,e.parentEngine,e.parentEntity)},GameLib.D3.API.Pass=function(e,t,i,n,a,s,o){if(GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Pass ("+e+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=GameLib.D3.Pass.PASS_TYPE_RENDER),this.passType=i,GameLib.Utils.UndefinedOrNull(n)&&(n=null),this.camera=n,GameLib.Utils.UndefinedOrNull(a)&&(a=null),this.scene=a,GameLib.Utils.UndefinedOrNull(s))if(this.passType===GameLib.D3.Pass.PASS_TYPE_RENDER)s=!1;else{if(!GameLib.D3.Pass.PASS_TYPE_COPY_SHADER)throw console.warn("Unsupported Render Pass Type : "+this.passType),new Error("Unsupported Render Pass Type : "+this.passType);s=!0}this.renderToScreen=s,GameLib.API.Component.call(this,GameLib.Component.PASS,o)},GameLib.D3.API.Pass.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Pass.prototype.constructor=GameLib.D3.API.Pass,GameLib.D3.API.Pass.FromObject=function(e){return new GameLib.D3.API.Pass(e.id,e.name,e.passType,e.camera,e.scene,e.renderToScreen,e.parentEntity)},GameLib.D3.API.PhysicsWorld=function(e,t,i,n,a,s,o,r,c,m){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Physics World ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=new GameLib.API.Vector3(0,-9.81,0)),this.gravity=i,GameLib.Utils.UndefinedOrNull(n)&&(n=new GameLib.D3.API.Broadphase(null,"Broadphase (Physics World "+this.id+")")),this.broadphase=n,GameLib.Utils.UndefinedOrNull(a)&&(a=new GameLib.D3.API.Solver(null,"Solver (Physics World "+this.id+")")),this.solver=a,GameLib.Utils.UndefinedOrNull(s)&&(s=[]),this.rigidBodies=s,GameLib.Utils.UndefinedOrNull(o)&&(o=[]),this.contactMaterials=o,GameLib.Utils.UndefinedOrNull(r)&&(r=!0),this.allowSleep=r,GameLib.Utils.UndefinedOrNull(c)&&(c=new GameLib.D3.API.FrictionContactMaterial(null,"Default Contact Material (Physics World "+this.id+")")),this.defaultContactMaterial=c,GameLib.API.Component.call(this,GameLib.Component.PHYSICS_WORLD,m)},GameLib.D3.API.PhysicsWorld.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.PhysicsWorld.prototype.constructor=GameLib.D3.API.PhysicsWorld,GameLib.D3.API.PhysicsWorld.FromObject=function(e){return new GameLib.D3.API.PhysicsWorld(e.id,e.name,GameLib.API.Vector3.FromObject(e.gravity),e.broadphase,e.solver,e.rigidBodies,e.contactMaterials,e.allowSleep,e.defaultContactMaterial,e.parentEntity)},GameLib.D3.API.RaycastVehicle=function(e,t,i,n,a,s,o){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="RaycastVehicle ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=null),this.chassis=i,GameLib.Utils.UndefinedOrNull(n)&&(n=[]),this.wheels=n,GameLib.Utils.UndefinedOrNull(a)&&(a=[]),this.raycastWheels=a,GameLib.Utils.UndefinedOrNull(s)&&(s=null),this.parentPhysicsWorld=s,GameLib.API.Component.call(this,GameLib.Component.RAYCAST_VEHICLE,o)},GameLib.D3.API.RaycastVehicle.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.RaycastVehicle.prototype.constructor=GameLib.D3.API.RaycastVehicle,GameLib.D3.API.RaycastVehicle.FromObject=function(e){return new GameLib.D3.API.RaycastVehicle(e.id,e.name,e.chassis,e.wheels,e.raycastWheels,e.parentPhysicsWorld,e.parentEntity)},GameLib.D3.API.RaycastWheel=function(e,t,i,n,a,s,o,r,c,m,h,l,p,u,b,d,L,G){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="RaycastWheel ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=.5),this.radius=i,GameLib.Utils.UndefinedOrNull(n)&&(n=new GameLib.API.Vector3(0,0,-1)),this.directionLocal=n,GameLib.Utils.UndefinedOrNull(a)&&(a=30),this.suspensionStiffness=a,GameLib.Utils.UndefinedOrNull(s)&&(s=.3),this.suspensionRestLength=s,GameLib.Utils.UndefinedOrNull(o)&&(o=5),this.frictionSlip=o,GameLib.Utils.UndefinedOrNull(r)&&(r=2.3),this.dampingRelaxation=r,GameLib.Utils.UndefinedOrNull(c)&&(c=4.4),this.dampingCompression=c,GameLib.Utils.UndefinedOrNull(m)&&(m=1e5),this.maxSuspensionForce=m,GameLib.Utils.UndefinedOrNull(h)&&(h=.01),this.rollInfluence=h,GameLib.Utils.UndefinedOrNull(l)&&(l=new GameLib.API.Vector3(0,1,0)),this.axleLocal=l,GameLib.Utils.UndefinedOrNull(p)&&(p=new GameLib.API.Vector3(1,1,0)),this.chassisConnectionPointLocal=p,GameLib.Utils.UndefinedOrNull(u)&&(u=.3),this.maxSuspensionTravel=u,GameLib.Utils.UndefinedOrNull(b)&&(b=-30),this.customSlidingRotationalSpeed=b,GameLib.Utils.UndefinedOrNull(d)&&(d=!0),this.useCustomSlidingRotationalSpeed=d,GameLib.Utils.UndefinedOrNull(L)&&(L=null),this.parentMesh=L,GameLib.API.Component.call(this,GameLib.Component.RAYCAST_WHEEL,G)},GameLib.D3.API.RaycastWheel.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.RaycastWheel.prototype.constructor=GameLib.D3.API.RaycastWheel,GameLib.D3.API.RaycastWheel.FromObject=function(e){return new GameLib.D3.API.RaycastWheel(e.id,e.name,e.radius,e.directionLocal,e.suspensionStiffness,e.suspensionRestLength,e.frictionSlip,e.dampingRelaxation,e.dampingCompression,e.maxSuspensionForce,e.rollInfluence,e.axleLocal,e.chassisConnectionPointLocal,e.maxSuspensionTravel,e.customSlidingRotationalSpeed,e.useCustomSlidingRotationalSpeed,e.parentMesh,e.parentEntity)},GameLib.D3.API.Raycaster=function(e,t,i,n,a){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Raycaster ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=new GameLib.API.Vector3),this.position=i,GameLib.Utils.UndefinedOrNull(n)&&(n=new GameLib.API.Vector3(0,-1,0)),this.direction=n,GameLib.API.Component.call(this,GameLib.Component.RAYCASTER,a)},GameLib.D3.API.Raycaster.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Raycaster.prototype.constructor=GameLib.D3.API.Raycaster,GameLib.D3.API.Raycaster.FromObject=function(e){return new GameLib.D3.API.Raycaster(e.id,e.name,GameLib.API.Vector3.FromObject(e.position),GameLib.API.Vector3.FromObject(e.direction),e.parentEntity)},GameLib.D3.API.RenderTarget=function(e,t,i,n,a,s,o){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Render Target ("+e+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=800),this.width=i,GameLib.Utils.UndefinedOrNull(n)&&(n=600),this.height=n,GameLib.Utils.UndefinedOrNull(a)&&(a=!1),this.stencilBuffer=a,GameLib.Utils.UndefinedOrNull(s)&&(s=null),this.texture=s,GameLib.API.Component.call(this,GameLib.Component.RENDER_TARGET,o)},GameLib.D3.API.RenderTarget.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.RenderTarget.prototype.constructor=GameLib.D3.API.RenderTarget,GameLib.D3.API.RenderTarget.FromObject=function(e){return new GameLib.D3.API.RenderTarget(e.id,e.name,e.width,e.height,e.stencilBuffer,e.texture,e.parentEntity)},GameLib.D3.API.Renderer=function(e,t,i,n,a,s,o,r,c,m,h,l,p,u,b,d,L,G,E){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Renderer ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=!0),this.autoClear=i,GameLib.Utils.UndefinedOrNull(n)&&(n=!1,p&&p.length>0&&(n=!0)),this.localClipping=n,GameLib.Utils.UndefinedOrNull(a)&&(a=800),this.width=a,GameLib.Utils.UndefinedOrNull(s)&&(s=600),this.height=s,GameLib.Utils.UndefinedOrNull(o)&&(o=!1),this.preserveDrawingBuffer=o,GameLib.Utils.UndefinedOrNull(r)&&(r=null),this.domElement=r,GameLib.Utils.UndefinedOrNull(c)&&(c=new GameLib.API.Color(.11,.11,.11)),this.clearColor=c,GameLib.Utils.UndefinedOrNull(m)&&(m=null),this.camera=m,GameLib.Utils.UndefinedOrNull(h)&&(h=[]),this.scenes=h,GameLib.Utils.UndefinedOrNull(l)&&(l=[]),this.viewports=l,GameLib.Utils.UndefinedOrNull(p)&&(p=[]),this.clippingPlanes=p,GameLib.Utils.UndefinedOrNull(u)&&(u=null),this.bufferScene=u,GameLib.Utils.UndefinedOrNull(b)&&(b=m),this.bufferCamera=b,GameLib.Utils.UndefinedOrNull(d)&&(d=null),this.renderTarget=d,GameLib.Utils.UndefinedOrNull(L)&&(L=null),this.defaultScene=L,GameLib.Utils.UndefinedOrNull(G)&&(G=!0),this.sortObjects=G,GameLib.API.Component.call(this,GameLib.Component.RENDERER,E)},GameLib.D3.API.Renderer.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Renderer.prototype.constructor=GameLib.D3.API.Renderer,GameLib.D3.API.Renderer.FromObject=function(e){return new GameLib.D3.API.Renderer(e.id,e.name,e.autoClear,e.localClipping,e.width,e.height,e.preserveDrawingBuffer,e.domElement,e.clearColor,e.camera,e.scenes,e.viewports,e.clippingPlanes,e.bufferScene,e.bufferCamera,e.renderTarget,e.defaultScene,e.sortObjects,e.parentEntity)},GameLib.D3.API.RigidBody=function(e,t,i,n,a,s,o,r,c,m,h,l,p,u,b,d,L,G,E,f,y){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="RigidBody ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=0),this.mass=i,GameLib.Utils.UndefinedOrNull(n)&&(n=5),this.friction=n,GameLib.Utils.UndefinedOrNull(a)&&(a=new GameLib.API.Vector3(0,0,0)),this.position=a,GameLib.Utils.UndefinedOrNull(s)&&(s=new GameLib.API.Quaternion),this.quaternion=s,GameLib.Utils.UndefinedOrNull(o)&&(o=new GameLib.API.Vector3),this.velocity=o,GameLib.Utils.UndefinedOrNull(r)&&(r=new GameLib.API.Vector3),this.angularVelocity=r,GameLib.Utils.UndefinedOrNull(c)&&(c=.01),this.linearDamping=c,GameLib.Utils.UndefinedOrNull(m)&&(m=.01),this.angularDamping=m,GameLib.Utils.UndefinedOrNull(h)&&(h=!0),this.allowSleep=h,GameLib.Utils.UndefinedOrNull(l)&&(l=.1),this.sleepSpeedLimit=l,GameLib.Utils.UndefinedOrNull(p)&&(p=1),this.sleepTimeLimit=p,GameLib.Utils.UndefinedOrNull(u)&&(u=1),this.collisionFilterGroup=u,GameLib.Utils.UndefinedOrNull(b)&&(b=1),this.collisionFilterMask=b,GameLib.Utils.UndefinedOrNull(d)&&(d=!1),this.fixedRotation=d,GameLib.Utils.UndefinedOrNull(L)&&(L=[]),this.shapes=L,GameLib.Utils.UndefinedOrNull(G)&&(G=!1),this.kinematic=G,GameLib.Utils.UndefinedOrNull(E)&&(E=null),this.parentMesh=E,GameLib.Utils.UndefinedOrNull(f)&&(f=null),this.parentPhysicsWorld=f,GameLib.API.Component.call(this,GameLib.Component.RIGID_BODY,y)},GameLib.D3.API.RigidBody.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.RigidBody.prototype.constructor=GameLib.D3.API.RigidBody,GameLib.D3.API.RigidBody.FromObject=function(e){return new GameLib.D3.API.RigidBody(e.id,e.name,e.mass,e.friction,e.position,e.quaternion,e.velocity,e.angularVelocity,e.linearDamping,e.angularDamping,e.allowSleep,e.sleepSpeedLimit,e.sleepTimeLimit,e.collisionFilterGroup,e.collisionFilterMask,e.fixedRotation,e.shapes,e.kinematic,e.parentMesh,e.parentPhysicsWorld,e.parentEntity)},GameLib.D3.API.Scene=function(e,t,i,n,a,s,o,r,c,m,h,l,p,u){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Scene ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=[]),this.meshes=i,GameLib.Utils.UndefinedOrNull(n)&&(n=[]),this.lights=n,GameLib.Utils.UndefinedOrNull(a)&&(a=[]),this.textures=a,GameLib.Utils.UndefinedOrNull(s)&&(s=[]),this.materials=s,GameLib.Utils.UndefinedOrNull(o)&&(o=[]),this.images=o,GameLib.Utils.UndefinedOrNull(r)&&(r=null),this.fog=r,GameLib.Utils.UndefinedOrNull(c)&&(c=null),this.renderCamera=c,GameLib.Utils.UndefinedOrNull(m)&&(m=!0),this.showGrid=m,GameLib.Utils.UndefinedOrNull(h)&&(h=!0),this.showAxis=h,GameLib.Utils.UndefinedOrNull(l)&&(l=10),this.gridSize=l,GameLib.Utils.UndefinedOrNull(p)&&(p=new GameLib.API.Color(.1,.1,.1)),this.gridColor=p,GameLib.API.Component.call(this,GameLib.Component.SCENE,u)},GameLib.D3.API.Scene.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Scene.prototype.constructor=GameLib.D3.API.Scene,GameLib.D3.API.Scene.FromObject=function(e){var t=[],i=[],n=[],a=[],s=[];return e.meshes&&(t=e.meshes.map(function(e){return e instanceof Object?GameLib.D3.API.Mesh.FromObject(e):e})),e.lights&&(i=e.lights.map(function(e){return e instanceof Object?GameLib.D3.API.Light.FromObject(e):e})),e.textures&&(n=e.textures.map(function(e){return e instanceof Object?GameLib.D3.API.Texture.FromObject(e):e})),e.materials&&(a=e.materials.map(function(e){return e instanceof Object?GameLib.D3.API.Material.FromObject(e):e})),e.images&&(s=e.images.map(function(e){return e instanceof Object?GameLib.API.Image.FromObject(e):e})),new GameLib.D3.API.Scene(e.id,e.name,t,i,n,a,s,e.fog,e.renderCamera,e.showGrid,e.showAxis,e.gridSize,GameLib.API.Color.FromObject(e.gridColor),e.parentEntity)},GameLib.D3.API.Shape=function(e,t,i,n,a,s,o,r){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(i)&&(i=GameLib.D3.API.Shape.SHAPE_TYPE_NONE),this.shapeType=i,GameLib.Utils.UndefinedOrNull(t)&&(t="Shape ("+this.id+")",this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_BOX&&(t="Shape Box ("+this.id+")"),this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL&&(t="Shape Convex Hull ("+this.id+")"),this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL_CYLINDER&&(t="Shape Convex Hull Cylinder ("+this.id+")"),this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_HEIGHT_MAP&&(t="Shape HeightMap ("+this.id+")"),this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_PLANE&&(t="Shape Plane ("+this.id+")"),this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_SPHERE&&(t="Shape Sphere ("+this.id+")"),this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_TRIMESH&&(t="Shape TriMesh ("+this.id+")")),this.name=t,GameLib.Utils.UndefinedOrNull(n)&&(n=0),this.boundingSphereRadius=n,GameLib.Utils.UndefinedOrNull(a)&&(a=!0),this.collisionResponse=a,GameLib.Utils.UndefinedOrNull(s)&&(s=null),this.frictionMaterial=s,GameLib.Utils.UndefinedOrNull(o)&&(o=null),this.parentMesh=o;var c=GameLib.Component.SHAPE;this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_BOX&&(c=GameLib.Component.SHAPE_BOX),this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL&&(c=GameLib.Component.SHAPE_CONVEX_HULL),this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL_CYLINDER&&(c=GameLib.Component.SHAPE_CONVEX_HULL_CYLINDER),this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_HEIGHT_MAP&&(c=GameLib.Component.SHAPE_HEIGHT_MAP),this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_PLANE&&(c=GameLib.Component.SHAPE_PLANE),this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_SPHERE&&(c=GameLib.Component.SHAPE_SPHERE),this.shapeType===GameLib.D3.API.Shape.SHAPE_TYPE_TRIMESH&&(c=GameLib.Component.SHAPE_TRI_MESH),GameLib.API.Component.call(this,c,r)},GameLib.D3.API.Shape.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Shape.prototype.constructor=GameLib.D3.API.Shape,GameLib.D3.API.Shape.SHAPE_TYPE_NONE=0;GameLib.D3.API.Shape.SHAPE_TYPE_BOX=1,GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL=2,GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL_CYLINDER=3,GameLib.D3.API.Shape.SHAPE_TYPE_HEIGHT_MAP=4,GameLib.D3.API.Shape.SHAPE_TYPE_PLANE=5,GameLib.D3.API.Shape.SHAPE_TYPE_SPHERE=6,GameLib.D3.API.Shape.SHAPE_TYPE_TRIMESH=7,GameLib.D3.API.Shape.FromObject=function(e){return new GameLib.D3.API.Shape(e.id,e.name,e.shapeType,e.boundingSphereRadius,e.collisionResponse,e.frictionMaterial,e.parentMesh,e.parentEntity)},GameLib.D3.API.Skeleton=function(e,t,i,n,a,s,o,r,c,m){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Skeleton"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=[]),this.bones=i,GameLib.Utils.UndefinedOrNull(n)&&(n=[]),this.boneInverses=n,GameLib.Utils.UndefinedOrNull(a)&&(a=!1),this.useVertexTexture=a,a&&console.warn("support for vertex texture bones is not supported yet - something could break somewhere"),GameLib.Utils.UndefinedOrNull(s)&&(s=0),this.boneTextureWidth=s,GameLib.Utils.UndefinedOrNull(o)&&(o=0),this.boneTextureHeight=o,GameLib.Utils.UndefinedOrNull(r)&&(r=[]),this.boneMatrices=r,GameLib.Utils.UndefinedOrNull(c)&&(c=null),this.boneTexture=c,GameLib.API.Component.call(this,GameLib.Component.SKELETON,m)},GameLib.D3.API.Skeleton.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Skeleton.prototype.constructor=GameLib.D3.API.Skeleton,GameLib.D3.API.Skeleton.FromObject=function(e){return new GameLib.D3.API.Skeleton(e.id,e.name,e.bones.map(function(e){return GameLib.D3.API.Bone.FromObject(e)}),e.boneInverses.map(function(e){return GameLib.D3.API.Matrix4.FromObject(e)}),e.useVertexTexture,e.boneTextureWidth,e.boneTextureHeight,e.boneMatrices.map(function(e){return GameLib.D3.API.Matrix4.FromObject(e)}),e.boneTexture,e.parentEntity)},GameLib.D3.API.Solver=function(e,t,i,n,a,s){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Solver ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=GameLib.D3.API.Solver.GS_SOLVER),this.solverType=i,GameLib.Utils.UndefinedOrNull(n)&&(n=10),this.iterations=n,GameLib.Utils.UndefinedOrNull(a)&&(a=1e-7),this.tolerance=a,GameLib.API.Component.call(this,GameLib.Component.SOLVER,s)},GameLib.D3.API.Solver.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Solver.prototype.constructor=GameLib.D3.API.Solver,GameLib.D3.API.Solver.GS_SOLVER=1,GameLib.D3.API.Solver.SPLIT_SOLVER=2,GameLib.D3.API.Solver.FromObject=function(e){return new GameLib.D3.API.Solver(e.id,e.name,e.solverType,e.iterations,e.tolerance,e.parentEntity)},GameLib.D3.API.Spline=function(e,t,i,n){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Spline ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=[]),this.vertices=i,GameLib.API.Component.call(this,GameLib.Component.SPLINE,n)},GameLib.D3.API.Spline.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Spline.prototype.constructor=GameLib.D3.API.Spline,GameLib.D3.API.Spline.FromObject=function(e){return new GameLib.D3.API.Spline(e.id,e.name,e.vertices.map(function(e){return GameLib.API.Vector3.FromObject(e)}),e.parentEntity)},GameLib.D3.API.Texture=function(e,t,i,n,a,s,o,r,c,m,h,l,p,u,b,d,L,G,E,f,y,I,P,A,T,O,S){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t=GameLib.D3.API.Texture.TEXTURE_TYPE_NORMAL),this.textureType=t,GameLib.Utils.UndefinedOrNull(i)&&(i="Texture ("+e+")"),this.name=i,GameLib.Utils.UndefinedOrNull(n)&&(n=null),this.image=n,GameLib.Utils.UndefinedOrNull(a)&&(a=[]),this.images=a,GameLib.Utils.UndefinedOrNull(s)&&(s=GameLib.D3.API.Texture.TYPE_REPEAT_WRAPPING),this.wrapS=s,GameLib.Utils.UndefinedOrNull(o)&&(o=GameLib.D3.API.Texture.TYPE_REPEAT_WRAPPING),this.wrapT=o,GameLib.Utils.UndefinedOrNull(r)&&(r=new GameLib.API.Vector2(1,1)),this.repeat=r,GameLib.Utils.UndefinedOrNull(c)&&(c=null),this.data=c,GameLib.Utils.UndefinedOrNull(m)&&(m=GameLib.D3.API.Texture.TYPE_RGBA_FORMAT),this.format=m,GameLib.Utils.UndefinedOrNull(h)&&(h=GameLib.D3.API.Texture.TYPE_UV_MAPPING),this.mapping=h,GameLib.Utils.UndefinedOrNull(l)&&(l=GameLib.D3.API.Texture.TYPE_LINEAR_FILTER),this.magFilter=l,GameLib.Utils.UndefinedOrNull(p)&&(p=GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER),this.minFilter=p,GameLib.Utils.UndefinedOrNull(u)&&(u=GameLib.D3.API.Texture.TYPE_UNSIGNED_BYTE),this.storageType=u,GameLib.Utils.UndefinedOrNull(b)&&(b=1),this.anisotropy=b,GameLib.Utils.UndefinedOrNull(d)&&(d=new GameLib.API.Vector2(0,0)),this.offset=d,GameLib.Utils.UndefinedOrNull(L)&&(L=!0),this.generateMipmaps=L,GameLib.Utils.UndefinedOrNull(G)&&(G=!0),this.flipY=G,GameLib.Utils.UndefinedOrNull(E)&&(E=[]),this.mipmaps=E,GameLib.Utils.UndefinedOrNull(f)&&(f=4),this.unpackAlignment=f,GameLib.Utils.UndefinedOrNull(y)&&(y=!1),this.premultiplyAlpha=y,GameLib.Utils.UndefinedOrNull(I)&&(I=GameLib.D3.API.Texture.TYPE_LINEAR_ENCODING),this.encoding=I,GameLib.Utils.UndefinedOrNull(P)&&(P=null),this.canvas=P,GameLib.Utils.UndefinedOrNull(A)&&(A=!1),this.animated=A,GameLib.Utils.UndefinedOrNull(T)&&(T=!1),this.reverseAnimation=T,GameLib.Utils.UndefinedOrNull(O)&&(O=!0),this.forward=O,this.needsUpdate=!1,GameLib.API.Component.call(this,GameLib.Component.TEXTURE,S)},GameLib.D3.API.Texture.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Texture.prototype.constructor=GameLib.D3.API.Texture, -GameLib.D3.API.Texture.TYPE_ALPHA_FORMAT=1019,GameLib.D3.API.Texture.TYPE_RGB_FORMAT=1020,GameLib.D3.API.Texture.TYPE_RGBA_FORMAT=1021,GameLib.D3.API.Texture.TYPE_LUMINANCE_FORMAT=1022,GameLib.D3.API.Texture.TYPE_LUMINANCE_ALPHA_FORMAT=1023,GameLib.D3.API.Texture.TYPE_DEPTH_FORMAT=1026,GameLib.D3.API.Texture.TYPE_UV_MAPPING=300,GameLib.D3.API.Texture.TYPE_CUBE_REFLECTION_MAPPING=301,GameLib.D3.API.Texture.TYPE_CUBE_REFRACTION_MAPPING=302,GameLib.D3.API.Texture.TYPE_EQUI_RECTANGULAR_REFLECTION_MAPPING=303,GameLib.D3.API.Texture.TYPE_EQUI_RECTANGULAR_REFRACTION_MAPPING=304,GameLib.D3.API.Texture.TYPE_SPHERICAL_REFLECTION_MAPPING=305,GameLib.D3.API.Texture.TYPE_CUBE_UV_REFLECTION_MAPPING=306,GameLib.D3.API.Texture.TYPE_CUBE_UV_REFRACTION_MAPPING=307,GameLib.D3.API.Texture.TYPE_REPEAT_WRAPPING=1e3,GameLib.D3.API.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING=1001,GameLib.D3.API.Texture.TYPE_MIRRORED_REPEAT_WRAPPING=1002,GameLib.D3.API.Texture.TYPE_NEAREST_FILTER=1003,GameLib.D3.API.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER=1004,GameLib.D3.API.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER=1005,GameLib.D3.API.Texture.TYPE_LINEAR_FILTER=1006,GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER=1007,GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER=1008,GameLib.D3.API.Texture.TYPE_UNSIGNED_BYTE=1009,GameLib.D3.API.Texture.TYPE_BYTE=1010,GameLib.D3.API.Texture.TYPE_SHORT=1011,GameLib.D3.API.Texture.TYPE_UNSIGNED_SHORT=1012,GameLib.D3.API.Texture.TYPE_INT=1013,GameLib.D3.API.Texture.TYPE_UNSIGNED_INT=1014,GameLib.D3.API.Texture.TYPE_FLOAT=1015,GameLib.D3.API.Texture.TYPE_HALF_FLOAT=1025,GameLib.D3.API.Texture.TYPE_LINEAR_ENCODING=3e3,GameLib.D3.API.Texture.TYPE_SRGB_ENCODING=3001,GameLib.D3.API.Texture.TYPE_GAMMA_ENCODING=3007,GameLib.D3.API.Texture.TYPE_RGBE_ENCODING=3002,GameLib.D3.API.Texture.TYPE_LOG_LUV_ENCODING=3003,GameLib.D3.API.Texture.TYPE_RGBM7_ENCODING=3004,GameLib.D3.API.Texture.TYPE_RGBM16_ENCODING=3005,GameLib.D3.API.Texture.TYPE_RGBD_ENCODING=3006,GameLib.D3.API.Texture.TEXTURE_TYPE_NORMAL=1,GameLib.D3.API.Texture.TEXTURE_TYPE_CUBE=2,GameLib.D3.API.Texture.TEXTURE_TYPE_CANVAS=3,GameLib.D3.API.Texture.FromObject=function(e){return new GameLib.D3.API.Texture(e.id,e.typeId||e.textureType,e.name,e.image,e.images,e.wrapS,e.wrapT,GameLib.API.Vector2.FromObject(e.repeat),e.data,e.format,e.mapping,e.magFilter,e.minFilter,e.storageType,e.anisotropy,GameLib.API.Vector2.FromObject(e.offset),e.generateMipmaps,e.flipY,e.mipmaps,e.unpackAlignment,e.premultiplyAlpha,e.encoding,e.canvas,e.animated,e.reverseAnimation,e.forward,e.parentEntity)},GameLib.D3.API.Vertex=function(e,t){GameLib.Utils.UndefinedOrNull(e)&&(e=new GameLib.API.Vector3),this.position=e,GameLib.Utils.UndefinedOrNull(t)&&(t=[]),this.boneWeights=t},GameLib.D3.API.Vertex.FromObject=function(e){return new GameLib.D3.API.Vertex(GameLib.API.Vector3.FromObject(e.position),e.boneWeights.map(function(e){return GameLib.D3.API.BoneWeight.FromObject(e)}))},GameLib.D3.API.Viewport=function(e,t,i,n,a,s,o){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Viewport ("+this.id+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=800),this.width=i,GameLib.Utils.UndefinedOrNull(n)&&(n=600),this.height=n,GameLib.Utils.UndefinedOrNull(a)&&(a=0),this.x=a,GameLib.Utils.UndefinedOrNull(s)&&(s=0),this.y=s,GameLib.API.Component.call(this,GameLib.Component.VIEWPORT,o)},GameLib.D3.API.Viewport.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.API.Viewport.prototype.constructor=GameLib.D3.API.Viewport,GameLib.D3.API.Viewport.FromObject=function(e){return new GameLib.D3.API.Viewport(e.id,e.name,e.width,e.height,e.x,e.y,e.parentEntity)},GameLib.D3.Animation=function(e){if(GameLib.Utils.UndefinedOrNull(e)&&(e={}),e instanceof GameLib.D3.Animation)return e;GameLib.D3.API.Animation.call(this,e.id,e.name,e.rotationSpeed,e.translationSpeed,e.scaleSpeed,e.rotationFn,e.translationFn,e.scaleFn,e.blocking,e.applyToMeshWhenDone,e.meshes,e.parentEntity),this.functionType=GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION,this.editor=null,this.inProcess=!1,GameLib.Component.call(this,{meshes:[GameLib.D3.Mesh]})},GameLib.D3.Animation.prototype=Object.create(GameLib.D3.API.Animation.prototype),GameLib.D3.Animation.prototype.constructor=GameLib.D3.Animation,GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION=1,GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION=2,GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE=3,GameLib.D3.Animation.prototype.createInstance=function(){this.instance={rotation:null,translation:null,scale:null};try{this.rotationFn&&(this.instance.rotation=new Function("data",this.rotationFn).bind(this)),this.translationFn&&(this.instance.translation=new Function("data",this.translationFn).bind(this)),this.scaleFn&&(this.instance.scale=new Function("data",this.scaleFn).bind(this))}catch(e){console.error(e),this.publish(GameLib.Event.ANIMATION_COMPILE_FAILED,{component:this})}GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Animation.prototype.updateInstance=function(){try{this.rotationFn&&(this.instance.rotation=new Function("data",this.rotationFn).bind(this),this.publish(GameLib.Event.ANIMATION_COMPILE_SUCCESS,{component:this,type:GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION})),this.translationFn&&(this.instance.translation=new Function("data",this.translationFn).bind(this),this.publish(GameLib.Event.ANIMATION_COMPILE_SUCCESS,{component:this,type:GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION})),this.scaleFn&&(this.instance.scale=new Function("data",this.scaleFn).bind(this),this.publish(GameLib.Event.ANIMATION_COMPILE_SUCCESS,{component:this,type:GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE}))}catch(e){console.error(e),this.publish(GameLib.Event.ANIMATION_COMPILE_FAILED,{component:this})}},GameLib.D3.Animation.prototype.toApiObject=function(){return new GameLib.D3.API.Animation(this.id,this.name,this.rotationSpeed,this.translationSpeed,this.scaleSpeed,this.rotationFn,this.translationFn,this.scaleFn,this.blocking,this.applyToMeshWhenDone,this.meshes.map(function(e){return GameLib.Utils.IdOrNull(e)}),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Animation.FromObject=function(e){var t=GameLib.D3.API.Animation.FromObject(e);return new GameLib.D3.Animation(t)},GameLib.D3.Animation.prototype.launchEditor=function(){GameLib.Event.Emit(GameLib.Event.GET_RUNTIME,null,function(e){this.coder=e.coder,this.coder.isNotCodeMirrorThrow()}.bind(this));var e=null;this.functionType===GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION&&(this.rotationFn="//when the animation is complete, return true\nreturn true;",e="rotationFn"),this.functionType===GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION&&(this.translationFn="//when the animation is complete, return true\nreturn true;",e="translationFn"),this.functionType===GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE&&(this.scaleFn="//when the animation is complete, return true\nreturn true;",e="scaleFn"),e?(this.editor=this.coder.instance(document.body,{value:this[e],mode:"javascript",lineNumbers:!0,scrollbarStyle:"overlay"}),this.editor.on("change",function(){this[e]=this.editor.getValue(),this.updateInstance()}.bind(this))):console.warn("invalid function type selected")},GameLib.D3.Animation.prototype.closeEditor=function(){var e=this.editor.getWrapperElement();e.parentElement.removeChild(e)},GameLib.D3.Animation.prototype.addMesh=function(e){GameLib.Utils.PushUnique(this.meshes,e),GameLib.Event.Emit(GameLib.Event.ANIMATION_MESH_ADDED,{animation:this,mesh:e})},GameLib.D3.Animation.prototype.removeMesh=function(e){var t=this.meshes.indexOf(e);this.meshes.splice(t,1),GameLib.Event.Emit(GameLib.Event.ANIMATION_MESH_REMOVED,{animation:this,mesh:e})},GameLib.D3.Audio=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Audio)return t;GameLib.D3.API.Audio.call(this,t.id,t.name,t.path,t.loop,t.volume,t.camera,t.overplay,t.pause,t.parentEntity),this.camera instanceof GameLib.D3.API.Camera&&(this.camera=new GameLib.D3.Camera(this.graphics,this.camera)),GameLib.Component.call(this,{camera:GameLib.D3.Camera})},GameLib.D3.Audio.prototype=Object.create(GameLib.D3.API.Audio.prototype),GameLib.D3.Audio.prototype.constructor=GameLib.D3.Audio,GameLib.D3.Audio.prototype.createInstance=function(){if(GameLib.Utils.UndefinedOrNull(this.camera)||GameLib.Utils.UndefinedOrNull(this.camera.instance))return void console.log("audio not ready to create instance");GameLib.Event.Emit(GameLib.Event.GET_API_URL,null,function(e){this.apiUrl=e.apiUrl}.bind(this));var e=new THREE.AudioListener;this.camera.instance.add(e),this.instance=new THREE.Audio(e),(new THREE.AudioLoader).load(this.apiUrl+this.path+"?ts="+Date.now(),function(e){this.instance.setBuffer(e),this.instance.setLoop(this.loop),this.instance.setVolume(this.volume),GameLib.Component.prototype.createInstance.call(this)}.bind(this))},GameLib.D3.Audio.prototype.updateInstance=function(e){"loop"===e&&this.instance.setLoop(this.loop),"volume"===e&&this.instance.setVolume(this.volume),"paused"===e&&(this.paused?this.instance.pause():this.instance.play())},GameLib.D3.Audio.prototype.toApiObject=function(){return new GameLib.D3.API.Audio(this.id,this.name,this.path,this.loop,this.volume,GameLib.Utils.IdOrNull(this.camera),this.overplay,this.paused,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Audio.FromObject=function(e,t){var i=GameLib.D3.API.Audio.FromObject(t);return new GameLib.D3.Audio(e,i)},GameLib.D3.Audio.prototype.play=function(){this.instance.play()},GameLib.D3.BoneWeight=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.BoneWeight)return t;GameLib.D3.API.BoneWeight.call(this,t.boneIndex,t.weight)},GameLib.D3.BoneWeight.prototype=Object.create(GameLib.D3.API.BoneWeight.prototype),GameLib.D3.BoneWeight.prototype.constructor=GameLib.D3.BoneWeight,GameLib.D3.BoneWeight.prototype.toApiObject=function(){return new GameLib.D3.API.BoneWeight(this.boneIndex,this.weight)},GameLib.D3.BoneWeight.FromObject=function(e,t){var i=GameLib.D3.API.BoneWeight.FromObject(t);return new GameLib.D3.BoneWeight(e,i)},GameLib.D3.Bone=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Bone)return t;GameLib.D3.API.Bone.call(this,t.id,t.name,t.childBoneIds,t.parentBoneIds,t.position,t.quaternion,t.scale,t.up,t.parentEntity),this.position=new GameLib.Vector3(e,this.position,this),this.quaternion=new GameLib.Quaternion(e,this.quaternion,this),this.scale=new GameLib.Vector3(e,this.scale,this),this.up=new GameLib.Vector3(e,this.up,this),GameLib.Component.call(this)},GameLib.D3.Bone.prototype=Object.create(GameLib.D3.API.Bone.prototype),GameLib.D3.Bone.prototype.constructor=GameLib.D3.Bone,GameLib.D3.Bone.prototype.createInstance=function(){this.instance=new THREE.Bone,this.instance.name=this.name,this.instance.position.x=this.position.x,this.instance.position.y=this.position.y,this.instance.position.z=this.position.z,this.instance.quaternion.x=this.quaternion.x,this.instance.quaternion.y=this.quaternion.y,this.instance.quaternion.z=this.quaternion.z,this.instance.quaternion.w=this.quaternion.w,this.instance.scale.x=this.scale.x,this.instance.scale.y=this.scale.y,this.instance.scale.z=this.scale.z,this.instance.up.x=this.up.x,this.instance.up.y=this.up.y,this.instance.up.z=this.up.z,GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Bone.prototype.updateInstance=function(){this.instance.name=this.name,this.instance.position.x=this.position.x,this.instance.position.y=this.position.y,this.instance.position.z=this.position.z,this.instance.quaternion.x=this.quaternion.x,this.instance.quaternion.y=this.quaternion.y,this.instance.quaternion.z=this.quaternion.z,this.instance.quaternion.w=this.quaternion.w,this.instance.scale.x=this.scale.x,this.instance.scale.y=this.scale.y,this.instance.scale.z=this.scale.z,this.instance.up.x=this.up.x,this.instance.up.y=this.up.y,this.instance.up.z=this.up.z},GameLib.D3.Bone.prototype.toApiObject=function(){return new GameLib.D3.API.Bone(this.id,this.name,this.childBoneIds,this.parentBoneIds,this.position.toApiObject(),this.quaternion.toApiObject(),this.scale.toApiObject(),this.up.toApiObject(),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Bone.FromObject=function(e,t){var i=GameLib.D3.API.Bone.FromObject(t);return GameLib.D3.Bone(e,i)},GameLib.D3.Broadphase=function(e,t){if(this.physics=e,this.physics.isNotCannonThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Broadphase)return t;GameLib.D3.API.Broadphase.call(this,t.id,t.name,t.broadphaseType,t.parentEntity),GameLib.Component.call(this)},GameLib.D3.Broadphase.prototype=Object.create(GameLib.D3.API.Broadphase.prototype),GameLib.D3.Broadphase.prototype.constructor=GameLib.D3.Broadphase,GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE=1,GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID=2,GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP=3,GameLib.D3.Broadphase.prototype.createInstance=function(){if(this.broadphaseType===GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE)this.instance=new CANNON.NaiveBroadphase;else if(this.broadphaseType===GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID)this.instance=new CANNON.GridBroadphase;else{if(this.broadphaseType!==GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP)throw console.warn("Unsupported broadphase type: "+this.broadphaseType),new Error("Unsupported broadphase type: "+this.broadphaseType);this.instance=new CANNON.SAPBroadphase}GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Broadphase.prototype.updateInstance=function(){this.broadphaseType===GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE&&(this.instance instanceof CANNON.NaiveBroadphase||this.createInstance()),this.broadphaseType===GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID&&(this.instance instanceof CANNON.GridBroadphase||this.createInstance()),this.broadphaseType===GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP&&(this.instance instanceof CANNON.SAPBroadphase||this.createInstance())},GameLib.D3.Broadphase.prototype.toApiObject=function(){return new GameLib.D3.API.Broadphase(this.id,this.name,this.broadphaseType,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Broadphase.FromObject=function(e,t){var i=GameLib.D3.API.Broadphase.FromObject(t);return new GameLib.D3.Broadphase(e,i)},GameLib.D3.Camera=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Camera)return t;if(GameLib.D3.API.Camera.call(this,t.id,t.cameraType,t.name,t.fov,t.aspect,t.near,t.far,t.position,t.lookAt,t.minX,t.maxX,t.minY,t.maxY,t.minZ,t.maxZ,t.offsetX,t.offsetY,t.quaternion,t.eyeSeparation,t.focalLength,t.parentEntity),!(this.position instanceof GameLib.API.Vector3))throw console.warn("position not instance of API.Vector3"),new Error("position not instance of API.Vector3");if(this.position=new GameLib.Vector3(e,this.position,this),!(this.quaternion instanceof GameLib.API.Quaternion))throw console.warn("quaternion not instance of API.Quaternion"),new Error("quaternion not instance of API.Quaternion");if(this.quaternion=new GameLib.Quaternion(e,this.quaternion,this),!(this.lookAt instanceof GameLib.API.Vector3))throw console.warn("lookAt not instance of API.Vector3"),new Error("lookAt not instance of API.Vector3");this.lookAt=new GameLib.Vector3(e,this.lookAt,this),GameLib.Component.call(this,GameLib.Component.CAMERA)},GameLib.D3.Camera.prototype=Object.create(GameLib.D3.API.Camera.prototype),GameLib.D3.Camera.prototype.constructor=GameLib.D3.Camera,GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE=1,GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL=2,GameLib.D3.Camera.CAMERA_TYPE_STEREO=3,GameLib.D3.Camera.prototype.createInstance=function(){if(this.cameraType===GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE)this.instance=new THREE.PerspectiveCamera(this.fov,this.aspect,this.near,this.far);else if(this.cameraType===GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL)this.instance=new THREE.OrthographicCamera(this.minX+this.offsetX,this.maxX+this.offsetX,this.maxY,this.minY,this.minZ,this.maxZ);else{if(this.cameraType!==GameLib.D3.Camera.CAMERA_TYPE_STEREO)throw new Error("unsupported camera type : "+this.cameraType);this.instance=new THREE.StereoCamera}this.instance.position.x=this.position.x,this.instance.position.y=this.position.y,this.instance.position.z=this.position.z,this.instance.quaternion.x=this.quaternion.x,this.instance.quaternion.y=this.quaternion.y,this.instance.quaternion.z=this.quaternion.z,this.instance.quaternion.w=this.quaternion.w,this.instance.lookAt(this.lookAt.instance),this.instance.updateProjectionMatrix(),GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Camera.prototype.updateInstance=function(e){GameLib.Utils.UndefinedOrNull(e)&&console.warn("no camera property specified for : "+this.name),"cameraType"===e&&(this.cameraType!==GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL||this.instance instanceof THREE.OrthographicCamera||this.createInstance(),this.cameraType!==GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE||this.instance instanceof THREE.PerspectiveCamera||this.createInstance()),"aspect"!==e&&"minX"!==e&&"maxX"!==e&&"minY"!==e&&"maxY"!==e&&"minZ"!==e&&"maxZ"!==e&&"offsetX"!==e&&"offsetY"!==e&&"fov"!==e&&"near"!==e&&"far"!==e&&"eyeSeparation"!==e&&"focalLength"!==e||(this.cameraType===GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL&&(this.minX=this.aspect*this.minY,this.maxX=this.aspect*this.maxY,this.instance.left=this.minX+this.offsetX,this.instance.right=this.maxX+this.offsetX,this.instance.bottom=this.minY+this.offsetY,this.instance.top=this.maxY+this.offsetY,this.instance.near=this.minZ,this.instance.far=this.maxZ),this.cameraType!==GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE&&this.cameraType!==GameLib.D3.Camera.CAMERA_TYPE_STEREO||(this.instance.fov=this.fov,this.instance.aspect=this.aspect,this.instance.near=this.near,this.instance.far=this.far),this.cameraType===GameLib.D3.Camera.CAMERA_TYPE_STEREO&&(this.instance.eyeSeparation=this.eyeSeparation,this.instance.focalLength=this.focalLength,this.instance.update(this.instance))),"position"===e&&(this.instance.position.x=this.position.x,this.instance.position.y=this.position.y,this.instance.position.z=this.position.z),"quaternion"===e&&(this.instance.quaternion.x=this.quaternion.x,this.instance.quaternion.y=this.quaternion.y,this.instance.quaternion.z=this.quaternion.z,this.instance.quaternion.w=this.quaternion.w),"lookAt"===e&&(this.lookAt.instance.x=this.lookAt.x,this.lookAt.instance.y=this.lookAt.y,this.lookAt.instance.z=this.lookAt.z,this.instance.lookAt(this.lookAt.instance)),this.instance.updateProjectionMatrix()},GameLib.D3.Camera.prototype.resize=function(e,t){camera.aspect=e/t,camera.updateInstance()},GameLib.D3.Camera.prototype.toApiObject=function(){return new GameLib.D3.API.Camera(this.id,this.cameraType,this.name,this.fov,this.aspect,this.near,this.far,this.position.toApiObject(),this.lookAt.toApiObject(),this.minX,this.maxX,this.minY,this.maxY,this.minZ,this.maxZ,this.offsetX,this.offsetY,this.quaternion.toApiObject(),this.eyeSeparation,this.focalLength,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Camera.FromObject=function(e,t){var i=GameLib.D3.API.Camera.FromObject(t);return new GameLib.D3.Camera(e,i)},GameLib.D3.Composer=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Composer)return t;GameLib.D3.API.Composer.call(this,t.id,t.name,t.renderer,t.renderTarget,t.passes,t.parentEntity),GameLib.Component.call(this,{renderer:GameLib.D3.Renderer,renderTarget:GameLib.D3.RenderTarget,passes:[GameLib.D3.Pass]})},GameLib.D3.Composer.prototype=Object.create(GameLib.D3.API.Composer.prototype),GameLib.D3.Composer.prototype.constructor=GameLib.D3.Composer,GameLib.D3.Composer.prototype.createInstance=function(){console.log("GameLib.D3.Composer.prototype.createInstance() - fix me"),GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Composer.prototype.updateInstance=function(){console.log("GameLib.D3.Composer.prototype.updateInstance() - fix me")},GameLib.D3.Composer.prototype.toApiObject=function(){return new GameLib.D3.API.Composer(this.id,this.name,GameLib.Utils.IdOrNull(this.renderer),GameLib.Utils.IdOrNull(this.renderTarget),this.passes.map(function(e){return GameLib.Utils.IdOrNull(e)}),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Composer.FromObject=function(e,t){var i=GameLib.D3.API.Composer.FromObject(t);return new GameLib.D3.Composer(e,i)},GameLib.D3.Face=function(e,t){if(this.implementation=e,e instanceof GameLib.GraphicsRuntime)this.implementation.isNotThreeThrow();else{if(!(e instanceof GameLib.PhysicsRuntime))throw new Error("Unhandled implementation : "+e);this.implementation.isNotCannonThrow()}if(GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Face)return t;GameLib.D3.API.Face.call(this,t.id,t.name,t.v0index,t.v1index,t.v2index,t.materialIndex,t.uvs,t.color,t.vertexColors,t.vertexNormals,t.normal),this.implementation instanceof GameLib.GraphicsRuntime&&(this.color=new GameLib.Color(this.implementation,this.color,this),this.vertexColors=this.vertexColors.map(function(e){return e instanceof GameLib.Color?e:e instanceof GameLib.API.Color?new GameLib.Color(this.implementation,e,this):void console.warn("unknown vertex color type",e)}.bind(this))),this.vertexNormals=this.vertexNormals.map(function(e){return e instanceof GameLib.Vector3?e:e instanceof GameLib.API.Vector3?new GameLib.Vector3(this.implementation,e,this):void console.warn("unknown vertex normal type",e)}.bind(this)),this.uvs=this.uvs.reduce(function(e,t,i){return e[i]=t.reduce(function(e,t){return t instanceof GameLib.API.Vector2?e.push(new GameLib.Vector2(this.implementation,t,this)):console.warn("unknown uv type"),e}.bind(this),[]),e}.bind(this),[]),this.normal=new GameLib.Vector3(this.implementation,this.normal,this)},GameLib.D3.Face.prototype=Object.create(GameLib.D3.API.Face.prototype),GameLib.D3.Face.prototype.constructor=GameLib.D3.Face,GameLib.D3.Face.prototype.createInstance=function(){},GameLib.D3.Face.prototype.updateInstance=function(){},GameLib.D3.Face.prototype.toApiObject=function(){return new GameLib.D3.API.Face(this.id,this.name,this.v0index,this.v1index,this.v2index,this.materialIndex,this.uvs.reduce(function(e,t,i){return e[i]=t.reduce(function(e,t){return t instanceof GameLib.Vector2?e.push(t.toApiObject()):console.warn("unknown uv type - cannot commit to API"),e}.bind(this),[]),e}.bind(this),[]),this.color.toApiObject(),this.vertexColors.map(function(e){return e.toApiObject()}),this.vertexNormals.map(function(e){return e.toApiObject()}),this.normal.toApiObject())},GameLib.D3.Face.FromObject=function(e,t){return new GameLib.D3.Face(e,GameLib.D3.API.Face.FromObject(t))},GameLib.D3.Fog=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Fog)return t;GameLib.D3.API.Fog.call(this,t.id,t.name,t.exponential,t.color,t.near,t.far,t.density,t.parentEntity),this.color=new GameLib.Color(this.graphics,this.color,this),GameLib.Component.call(this)},GameLib.D3.Fog.prototype=Object.create(GameLib.D3.API.Fog.prototype),GameLib.D3.Fog.prototype.constructor=GameLib.D3.Fog,GameLib.D3.Fog.prototype.createInstance=function(){this.exponential?this.instance=new THREE.FogExp2(this.color.instance,this.density):this.instance=new THREE.Fog(this.color.instance,this.near,this.far),this.instance.name=this.name,GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Fog.prototype.updateInstance=function(e){if("exponential"===e){if(this.exponential&&!(this.instance instanceof THREE.FogExp2))return void this.createInstance();if(!(this.exponential||this.instance instanceof THREE.Fog))return void this.createInstance()}"color"===e&&(this.color.instance.setRGB(this.color.r,this.color.g,this.color.b),this.instance.color=this.color.instance),"near"!==e&&"far"!==e||this.instance instanceof THREE.Fog&&(this.instance.near=this.near,this.instance.far=this.far),"density"===e&&this.instance instanceof THREE.FogExp2&&(this.instance.density=this.density)},GameLib.D3.Fog.prototype.toApiObject=function(){return new GameLib.D3.API.Fog(this.id,this.name,this.exponential,this.color.toApiObject(),this.near,this.far,this.density,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Fog.FromObject=function(e,t){var i=GameLib.D3.API.Fog.FromObject(t);return new GameLib.D3.Fog(e,i)},GameLib.D3.Font=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Font)return t;GameLib.D3.API.Font.call(this,t.id,t.name,t.url,t.parentEntity),GameLib.Component.call(this)},GameLib.D3.Font.prototype=Object.create(GameLib.D3.API.Font.prototype),GameLib.D3.Font.prototype.constructor=GameLib.D3.Font,GameLib.D3.Font.prototype.createInstance=function(){GameLib.Event.Emit(GameLib.Event.LOAD_FONT,{font:this},function(e){this.instance=e,GameLib.Component.prototype.createInstance.call(this)}.bind(this),function(e){console.error(e),this.instance=null,GameLib.Component.prototype.createInstance.call(this)}.bind(this))},GameLib.D3.Font.prototype.updateInstance=function(){GameLib.Event.Emit(GameLib.Event.LOAD_FONT,{font:this})},GameLib.D3.Font.prototype.toApiObject=function(){return new GameLib.D3.API.Font(this.id,this.name,this.url,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Font.FromObject=function(e,t){return new GameLib.D3.Font(e,GameLib.D3.API.Font.FromObject(t))},GameLib.D3.FrictionContactMaterial=function(e,t){if(this.physics=e,this.physics.isNotCannonThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.FrictionContactMaterial)return t;GameLib.D3.API.FrictionContactMaterial.call(this,t.id,t.name,t.materials,t.friction,t.restitution,t.contactEquationStiffness,t.contactEquationRelaxation,t.frictionEquationStiffness,t.frictionEquationRelaxation,t.parentEntity),GameLib.Component.call(this,{materials:[GameLib.D3.FrictionMaterial]})},GameLib.D3.FrictionContactMaterial.prototype=Object.create(GameLib.D3.API.FrictionContactMaterial.prototype),GameLib.D3.FrictionContactMaterial.prototype.constructor=GameLib.D3.FrictionContactMaterial,GameLib.D3.FrictionContactMaterial.prototype.createInstance=function(){this.instance=new CANNON.ContactMaterial(null,null,{friction:this.friction,restitution:this.restitution,contactEquationStiffness:this.contactEquationStiffness}),this.instance.materials=this.materials.map(function(e){return e.instance}),GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.FrictionContactMaterial.prototype.updateInstance=function(){this.instance.materials=this.materials.map(function(e){return e.instance}),this.instance.friction=this.friction,this.instance.restitution=this.restitution,this.instance.contactEquationStiffness=this.contactEquationStiffness,this.instance.contactEquationRelaxation=this.contactEquationRelaxation,this.instance.frictionEquationStiffness=this.frictionEquationStiffness,this.instance.frictionEquationRelaxation=this.frictionEquationRelaxation},GameLib.D3.FrictionContactMaterial.prototype.toApiObject=function(){return new GameLib.D3.API.FrictionContactMaterial(this.id,this.name,this.materials.map(function(e){return GameLib.Utils.IdOrNull(e)}),this.friction,this.restitution,this.contactEquationStiffness,this.contactEquationRelaxation,this.frictionEquationStiffness,this.frictionEquationRelaxation,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.FrictionContactMaterial.FromObject=function(e,t){var i=GameLib.D3.API.FrictionContactMaterial.FromObject(t);return new GameLib.D3.FrictionContactMaterial(e,i)},GameLib.D3.FrictionMaterial=function(e,t){if(this.physics=e,this.physics.isNotCannonThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.FrictionMaterial)return t;GameLib.D3.API.FrictionMaterial.call(this,t.id,t.name,t.friction,t.restitution,t.parentEntity),GameLib.Component.call(this)},GameLib.D3.FrictionMaterial.prototype=Object.create(GameLib.D3.API.FrictionMaterial.prototype),GameLib.D3.FrictionMaterial.prototype.constructor=GameLib.D3.FrictionMaterial,GameLib.D3.FrictionMaterial.prototype.createInstance=function(){this.instance=new CANNON.Material(this.name),this.instance.friction=this.friction,this.instance.restitution=this.restitution,GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.FrictionMaterial.prototype.updateInstance=function(){this.instance.friction=this.friction,this.instance.restitution=this.restitution,this.instance.name=this.name},GameLib.D3.FrictionMaterial.prototype.toApiObject=function(){return new GameLib.D3.API.FrictionMaterial(this.id,this.name,this.friction,this.restitution,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.FrictionMaterial.FromObject=function(e,t){var i=GameLib.D3.API.FrictionMaterial.FromObject(t);return new GameLib.D3.FrictionMaterial(e,i)},GameLib.D3.Helper=function(e,t,i,n,a,s){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t=GameLib.Utils.RandomId()),this.id=t,GameLib.Utils.UndefinedOrNull(i)&&(i="Helper ("+t+")"),this.name=i,GameLib.Utils.UndefinedOrNull(n))throw console.warn("Cannot create a helper for an Object which does not exist"),new Error("Cannot create a helper for an Object which does not exist");this.object=n,GameLib.Utils.UndefinedOrNull(a)&&(a=GameLib.D3.Helper.HELPER_TYPE_NONE,n instanceof GameLib.D3.Mesh&&n.meshType!==GameLib.D3.API.Mesh.MESH_TYPE_CURVE&&(a=GameLib.D3.Helper.HELPER_TYPE_EDGES),n instanceof GameLib.D3.Light&&(n.lightType===GameLib.D3.Light.LIGHT_TYPE_DIRECTIONAL&&(a=GameLib.D3.Helper.HELPER_TYPE_DIRECTIONAL_LIGHT),n.lightType===GameLib.D3.Light.LIGHT_TYPE_POINT&&(a=GameLib.D3.Helper.HELPER_TYPE_POINT_LIGHT),n.lightType===GameLib.D3.Light.LIGHT_TYPE_SPOT&&(a=GameLib.D3.Helper.HELPER_TYPE_SPOT_LIGHT)),n instanceof GameLib.D3.Skeleton&&(a=GameLib.D3.Helper.HELPER_TYPE_SKELETON)),this.helperType=a,GameLib.Utils.UndefinedOrNull(s)&&(s=null),this.parentEntity=s,this.createInstance()},GameLib.D3.Helper.prototype=Object.create(GameLib.Component.prototype),GameLib.D3.Helper.prototype.constructor=GameLib.D3.Helper,GameLib.D3.Helper.HELPER_TYPE_NONE=0,GameLib.D3.Helper.HELPER_TYPE_EDGES=1,GameLib.D3.Helper.HELPER_TYPE_DIRECTIONAL_LIGHT=2,GameLib.D3.Helper.HELPER_TYPE_SPOT_LIGHT=3,GameLib.D3.Helper.HELPER_TYPE_POINT_LIGHT=4,GameLib.D3.Helper.HELPER_TYPE_WIREFRAME=5,GameLib.D3.Helper.HELPER_TYPE_SKELETON=6,GameLib.D3.Helper.prototype.createInstance=function(){this.helperType===GameLib.D3.Helper.HELPER_TYPE_EDGES&&(this.instance=new THREE.LineSegments(new THREE.EdgesGeometry(this.object.instance.geometry),new THREE.LineBasicMaterial({color:65280,linewidth:2}))),this.helperType===GameLib.D3.Helper.HELPER_TYPE_DIRECTIONAL_LIGHT&&(this.instance=new THREE.DirectionalLightHelper(this.object.instance)),this.helperType===GameLib.D3.Helper.HELPER_TYPE_POINT_LIGHT&&(this.instance=new THREE.PointLightHelper(this.object.instance,1)),this.helperType===GameLib.D3.Helper.HELPER_TYPE_SPOT_LIGHT&&(this.instance=new THREE.SpotLightHelper(this.object.instance)),this.helperType===GameLib.D3.Helper.HELPER_TYPE_WIREFRAME&&(this.instance=new THREE.WireframeGeometry(this.object.instance,65280)),this.helperType===GameLib.D3.Helper.HELPER_TYPE_SKELETON&&(this.instance=new THREE.SkeletonHelper(this.object.instance))},GameLib.D3.Helper.prototype.updateInstance=function(){this.instance.position.copy(this.object.instance.position),this.object.instance.parentMesh&&this.object.instance.parentMesh.instance&&this.instance.position.add(this.object.instance.parentMesh.instance.position),this.instance.scale.copy(this.object.instance.scale),this.instance.quaternion.copy(this.object.instance.quaternion)},GameLib.D3.Light=function(e,t){if(this.graphics=e, -this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Light)return t;GameLib.D3.API.Light.call(this,t.id,t.lightType,t.name,t.color,t.intensity,t.position,t.targetPosition,t.quaternion,t.rotation,t.scale,t.distance,t.decay,t.power,t.angle,t.penumbra,t.parentScene,t.parentEntity),this.color=new GameLib.Color(e,this.color,this),this.position=new GameLib.Vector3(e,this.position,this),this.targetPosition=new GameLib.Vector3(e,this.targetPosition,this),this.scale=new GameLib.Vector3(e,this.scale,this),this.quaternion=new GameLib.Quaternion(e,this.quaternion,this),this.rotation=new GameLib.Vector3(e,this.rotation,this),GameLib.Component.call(this,{parentScene:GameLib.D3.Scene})},GameLib.D3.Light.prototype=Object.create(GameLib.D3.API.Light.prototype),GameLib.D3.Light.prototype.constructor=GameLib.D3.Light,GameLib.D3.Light.LIGHT_TYPE_AMBIENT=1,GameLib.D3.Light.LIGHT_TYPE_DIRECTIONAL=2,GameLib.D3.Light.LIGHT_TYPE_POINT=3,GameLib.D3.Light.LIGHT_TYPE_SPOT=4,GameLib.D3.Light.prototype.createInstance=function(){if(this.lightType===GameLib.D3.Light.LIGHT_TYPE_AMBIENT||"AmbientLight"===this.lightType)this.instance=new THREE.AmbientLight(this.color.instance,this.intensity);else if(this.lightType===GameLib.D3.Light.LIGHT_TYPE_DIRECTIONAL||"DirectionalLight"===this.lightType)this.instance=new THREE.DirectionalLight(this.color.instance,this.intensity);else if(this.lightType===GameLib.D3.Light.LIGHT_TYPE_POINT||"PointLight"===this.lightType)this.instance=new THREE.PointLight(this.color.instance,this.intensity),this.instance.distance=this.distance,this.instance.decay=this.decay;else{if(this.lightType!==GameLib.D3.Light.LIGHT_TYPE_SPOT&&"SpotLight"!==this.lightType)return void console.warn("unsupported light type: "+this.lightType);this.instance=new THREE.SpotLight(this.color.instance,this.intensity),this.instance.distance=this.distance,this.instance.angle=this.angle,this.instance.penumbra=this.penumbra,this.instance.decay=this.decay}this.instance.name=this.name,this.instance.position.x=this.position.x,this.instance.position.y=this.position.y,this.instance.position.z=this.position.z,this.instance.scale.x=this.scale.x,this.instance.scale.y=this.scale.y,this.instance.scale.z=this.scale.z,this.instance.target&&(this.instance.target.position.x=this.targetPosition.x,this.instance.target.position.y=this.targetPosition.y,this.instance.target.position.z=this.targetPosition.z),this.instance.quaternion.x=this.quaternion.x,this.instance.quaternion.y=this.quaternion.y,this.instance.quaternion.z=this.quaternion.z,this.instance.quaternion.w=this.quaternion.w,this.instance.intensity=this.intensity,this.instance.color.set(this.color.toHex()),GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Light.prototype.updateInstance=function(e){GameLib.Utils.UndefinedOrNull(e)&&console.warn("no property for light: "+this.name),"lightType"===e&&(this.parentScene.instance.remove(this.instance),this.createInstance(),this.parentScene.instance.add(this.instance)),"name"===e&&(this.instance.name=this.name),"position"===e&&(this.instance.position.x=this.position.x,this.instance.position.y=this.position.y,this.instance.position.z=this.position.z),"scale"===e&&(this.instance.scale.x=this.scale.x,this.instance.scale.y=this.scale.y,this.instance.scale.z=this.scale.z),"target"===e&&this.instance.target&&(this.instance.target.position.x=this.targetPosition.x,this.instance.target.position.y=this.targetPosition.y,this.instance.target.position.z=this.targetPosition.z),"quaternion"===e&&(this.instance.quaternion.x=this.quaternion.x,this.instance.quaternion.y=this.quaternion.y,this.instance.quaternion.z=this.quaternion.z,this.instance.quaternion.w=this.quaternion.w),"intensity"===e&&(this.instance.intensity=this.intensity),"color"===e&&this.instance.color.set(this.color.toHex())},GameLib.D3.Light.prototype.toApiObject=function(){return new GameLib.D3.API.Light(this.id,this.lightType,this.name,this.color.toApiObject(),this.intensity,this.position.toApiObject(),this.targetPosition.toApiObject(),this.quaternion.toApiObject(),this.rotation.toApiObject(),this.scale.toApiObject(),this.distance,this.decay,this.power,this.angle,this.penumbra,GameLib.Utils.IdOrNull(this.parentScene),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Light.FromObject=function(e,t){return new GameLib.D3.Light(e,GameLib.D3.API.Light.FromObject(t))},GameLib.D3.Material=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Material)return t;GameLib.D3.API.Material.call(this,t.id,t.materialType,t.name,t.opacity,t.side,t.transparent,t.specular,t.lightMapIntensity,t.aoMapIntensity,t.color,t.emissive,t.emissiveIntensity,t.combine,t.shininess,t.reflectivity,t.refractionRatio,t.fog,t.wireframe,t.wireframeLineWidth,t.wireframeLineCap,t.wireframeLineJoin,t.vertexColors,t.skinning,t.morphTargets,t.morphNormals,t.lineWidth,t.lineCap,t.lineJoin,t.dashSize,t.gapWidth,t.blending,t.blendSrc,t.blendDst,t.blendEquation,t.depthTest,t.depthFunc,t.depthWrite,t.polygonOffset,t.polygonOffsetFactor,t.polygonOffsetUnits,t.alphaTest,t.clippingPlanes,t.clipShadows,t.visible,t.overdraw,t.flatShading,t.bumpScale,t.normalScale,t.displacementScale,t.displacementBias,t.roughness,t.metalness,t.pointSize,t.pointSizeAttenuation,t.spriteRotation,t.envMapIntensity,t.alphaMap,t.aoMap,t.bumpMap,t.diffuseMap,t.displacementMap,t.emissiveMap,t.environmentMap,t.lightMap,t.metalnessMap,t.normalMap,t.roughnessMap,t.specularMap,t.parentEntity),this.specular=new GameLib.Color(e,this.specular,this),this.color=new GameLib.Color(e,this.color,this),this.emissive=new GameLib.Color(e,this.emissive,this),this.alphaMap&&this.alphaMap instanceof GameLib.D3.API.Texture&&(this.alphaMap=new GameLib.D3.Texture(this.graphics,this.alphaMap)),this.aoMap&&this.aoMap instanceof GameLib.D3.API.Texture&&(this.aoMap=new GameLib.D3.Texture(this.graphics,this.aoMap)),this.bumpMap&&this.bumpMap instanceof GameLib.D3.API.Texture&&(this.bumpMap=new GameLib.D3.Texture(this.graphics,this.bumpMap)),this.diffuseMap&&this.diffuseMap instanceof GameLib.D3.API.Texture&&(this.diffuseMap=new GameLib.D3.Texture(this.graphics,this.diffuseMap)),this.displacementMap&&this.displacementMap instanceof GameLib.D3.API.Texture&&(this.displacementMap=new GameLib.D3.Texture(this.graphics,this.displacementMap)),this.emissiveMap&&this.emissiveMap instanceof GameLib.D3.API.Texture&&(this.emissiveMap=new GameLib.D3.Texture(this.graphics,this.emissiveMap)),this.environmentMap&&this.environmentMap instanceof GameLib.D3.API.Texture&&(this.environmentMap=new GameLib.D3.Texture(this.graphics,this.environmentMap)),this.lightMap&&this.lightMap instanceof GameLib.D3.API.Texture&&(this.lightMap=new GameLib.D3.Texture(this.graphics,this.lightMap)),this.metalnessMap&&this.metalnessMap instanceof GameLib.D3.API.Texture&&(this.metalnessMap=new GameLib.D3.Texture(this.graphics,this.metalnessMap)),this.normalMap&&this.normalMap instanceof GameLib.D3.API.Texture&&(this.normalMap=new GameLib.D3.Texture(this.graphics,this.normalMap)),this.roughnessMap&&this.roughnessMap instanceof GameLib.D3.API.Texture&&(this.roughnessMap=new GameLib.D3.Texture(this.graphics,this.roughnessMap)),this.specularMap&&this.specularMap instanceof GameLib.D3.API.Texture&&(this.specularMap=new GameLib.D3.Texture(this.graphics,this.specularMap)),GameLib.Component.call(this,{alphaMap:GameLib.D3.Texture,aoMap:GameLib.D3.Texture,bumpMap:GameLib.D3.Texture,diffuseMap:GameLib.D3.Texture,displacementMap:GameLib.D3.Texture,emissiveMap:GameLib.D3.Texture,environmentMap:GameLib.D3.Texture,lightMap:GameLib.D3.Texture,metalnessMap:GameLib.D3.Texture,normalMap:GameLib.D3.Texture,roughnessMap:GameLib.D3.Texture,specularMap:GameLib.D3.Texture})},GameLib.D3.Material.prototype=Object.create(GameLib.D3.API.Material.prototype),GameLib.D3.Material.prototype.constructor=GameLib.D3.Material,GameLib.D3.Material.TYPE_MULTIPLY_OPERATION=0,GameLib.D3.Material.TYPE_MIX_OPERATION=1,GameLib.D3.Material.TYPE_ADD_OPERATION=2;GameLib.D3.Material.TYPE_NO_COLORS=0,GameLib.D3.Material.TYPE_FACE_COLORS=1,GameLib.D3.Material.TYPE_VERTEX_COLORS=2,GameLib.D3.Material.TYPE_NO_BLENDING=0,GameLib.D3.Material.TYPE_NORMAL_BLENDING=1,GameLib.D3.Material.TYPE_ADDITIVE_BLENDING=2,GameLib.D3.Material.TYPE_SUBTRACTIVE_BLENDING=3,GameLib.D3.Material.TYPE_MULTIPLY_BLENDING=4,GameLib.D3.Material.TYPE_CUSTOM_BLENDING=5,GameLib.D3.Material.TYPE_ZERO_FACTOR=200,GameLib.D3.Material.TYPE_ONE_FACTOR=201,GameLib.D3.Material.TYPE_SRC_COLOR_FACTOR=202,GameLib.D3.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR=203,GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR=204,GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR=205,GameLib.D3.Material.TYPE_DST_ALPHA_FACTOR=206,GameLib.D3.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR=207,GameLib.D3.Material.TYPE_DST_COLOR_FACTOR=208,GameLib.D3.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR=209,GameLib.D3.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR=210,GameLib.D3.Material.TYPE_ADD_EQUATION=100,GameLib.D3.Material.TYPE_SUBTRACT_EQUATION=101,GameLib.D3.Material.TYPE_REVERSE_SUBTRACT_EQUATION=102,GameLib.D3.Material.TYPE_MIN_EQUATION=103,GameLib.D3.Material.TYPE_MAX_EQUATION=104,GameLib.D3.Material.TYPE_NEVER_DEPTH=0,GameLib.D3.Material.TYPE_ALWAYS_DEPTH=1,GameLib.D3.Material.TYPE_LESS_DEPTH=2,GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH=3,GameLib.D3.Material.TYPE_EQUAL_DEPTH=4,GameLib.D3.Material.TYPE_GREATER_EQUAL_DEPTH=5,GameLib.D3.Material.TYPE_GREATER_DEPTH=6,GameLib.D3.Material.TYPE_NOT_EQUAL_DEPTH=7,GameLib.D3.Material.TYPE_FRONT_SIDE=0,GameLib.D3.Material.TYPE_BACK_SIDE=1,GameLib.D3.Material.TYPE_DOUBLE_SIDE=2,GameLib.D3.Material.TYPE_FLAT_SHADING=1,GameLib.D3.Material.TYPE_SMOOTH_SHADING=2,GameLib.D3.Material.MATERIAL_TYPE_LINE_BASIC=1,GameLib.D3.Material.MATERIAL_TYPE_LINE_DASHED=2,GameLib.D3.Material.MATERIAL_TYPE_BASIC=3,GameLib.D3.Material.MATERIAL_TYPE_DEPTH=4,GameLib.D3.Material.MATERIAL_TYPE_LAMBERT=5,GameLib.D3.Material.MATERIAL_TYPE_NORMAL=6,GameLib.D3.Material.MATERIAL_TYPE_PHONG=7,GameLib.D3.Material.MATERIAL_TYPE_STANDARD=8,GameLib.D3.Material.MATERIAL_TYPE_POINTS=9,GameLib.D3.Material.MATERIAL_TYPE_SPRITE=10,GameLib.D3.Material.MATERIAL_TYPE_TOON=11,GameLib.D3.Material.LINE_CAP_BUTT=1,GameLib.D3.Material.LINE_CAP_ROUND=2,GameLib.D3.Material.LINE_CAP_SQUARE=3,GameLib.D3.Material.LINE_JOIN_ROUND=1,GameLib.D3.Material.LINE_JOIN_BEVEL=2,GameLib.D3.Material.LINE_JOIN_MITER=3,GameLib.D3.Material.prototype.createToonMaterialInstance=function(){return new THREE.MeshToonMaterial({name:this.name,opacity:this.opacity,transparent:this.transparent,blending:this.blending,blendSrc:this.blendSrc,blendDst:this.blendDst,blendEquation:this.blendEquation,depthTest:this.depthTest,depthFunc:this.depthFunc,depthWrite:this.depthWrite,polygonOffset:this.polygonOffset,polygonOffsetFactor:this.polygonOffsetFactor,polygonOffsetUnits:this.polygonOffsetUnits,alphaTest:this.alphaTest,clippingPlanes:this.clippingPlanes,clipShadows:this.clipShadows,overdraw:this.overdraw,visible:this.visible,side:this.side,color:this.color.instance,roughness:this.roughness,metalness:this.metalness,lightMapIntensity:this.lightMapIntensity,aoMapIntensity:this.aoMapIntensity,emissive:this.emissive.instance,emissiveIntensity:this.emissiveIntensity,bumpScale:this.bumpScale,normalScale:this.normalScale,displacementScale:this.displacementScale,refractionRatio:this.refractionRatio,fog:this.fog,flatShading:this.flatShading,wireframe:this.wireframe,wireframeLinewidth:this.wireframeLineWidth,wireframeLinecap:this.wireframeLineCap,wireframeLinejoin:this.wireframeLineJoin,vertexColors:GameLib.D3.Material.TYPE_VERTEX_COLORS,skinning:this.skinning,morphTargets:this.morphTargets,morphNormals:this.morphNormals})},GameLib.D3.Material.prototype.createStandardMaterialInstance=function(){return new THREE.MeshStandardMaterial({name:this.name,opacity:this.opacity,transparent:this.transparent,blending:this.blending,blendSrc:this.blendSrc,blendDst:this.blendDst,blendEquation:this.blendEquation,depthTest:this.depthTest,depthFunc:this.depthFunc,depthWrite:this.depthWrite,polygonOffset:this.polygonOffset,polygonOffsetFactor:this.polygonOffsetFactor,polygonOffsetUnits:this.polygonOffsetUnits,alphaTest:this.alphaTest,clippingPlanes:this.clippingPlanes,clipShadows:this.clipShadows,overdraw:this.overdraw,visible:this.visible,side:this.side,color:this.color.instance,roughness:this.roughness,metalness:this.metalness,lightMapIntensity:this.lightMapIntensity,aoMapIntensity:this.aoMapIntensity,emissive:this.emissive.instance,emissiveIntensity:this.emissiveIntensity,bumpScale:this.bumpScale,normalScale:this.normalScale,displacementScale:this.displacementScale,refractionRatio:this.refractionRatio,fog:this.fog,flatShading:this.flatShading,wireframe:this.wireframe,wireframeLinewidth:this.wireframeLineWidth,wireframeLinecap:this.wireframeLineCap,wireframeLinejoin:this.wireframeLineJoin,vertexColors:GameLib.D3.Material.TYPE_VERTEX_COLORS,skinning:this.skinning,morphTargets:this.morphTargets,morphNormals:this.morphNormals})},GameLib.D3.Material.prototype.createPointsMaterialInstance=function(){return new THREE.PointsMaterial({name:this.name,opacity:this.opacity,transparent:this.transparent,depthTest:this.depthTest,depthFunc:this.depthFunc,depthWrite:this.depthWrite,visible:this.visible,side:this.side,color:this.color.instance,size:this.pointSize,sizeAttenuation:this.pointSizeAttenuation})},GameLib.D3.Material.prototype.createLineBasicMaterialInstance=function(){var e="round";this.lineCap===GameLib.D3.Material.LINE_CAP_BUTT&&(e="butt"),this.lineCap===GameLib.D3.Material.LINE_CAP_SQUARE&&(e="square");var t="round";return this.lineJoin===GameLib.D3.Material.LINE_JOIN_BEVEL&&(t="bevel"),this.lineJoin===GameLib.D3.Material.LINE_JOIN_MITER&&(t="miter"),new THREE.LineBasicMaterial({name:this.name,opacity:this.opacity,transparent:this.transparent,depthTest:this.depthTest,depthFunc:this.depthFunc,depthWrite:this.depthWrite,visible:this.visible,side:this.side,color:this.color.instance,linewidth:this.lineWidth,linecap:e,linejoin:t})},GameLib.D3.Material.prototype.createPhongMaterialInstance=function(){return new THREE.MeshPhongMaterial({name:this.name,opacity:this.opacity,transparent:this.transparent,blending:this.blending,blendSrc:this.blendSrc,blendDst:this.blendDst,blendEquation:this.blendEquation,depthTest:this.depthTest,depthFunc:this.depthFunc,depthWrite:this.depthWrite,polygonOffset:this.polygonOffset,polygonOffsetFactor:this.polygonOffsetFactor,polygonOffsetUnits:this.polygonOffsetUnits,alphaTest:this.alphaTest,clippingPlanes:this.clippingPlanes,clipShadows:this.clipShadows,overdraw:this.overdraw,visible:this.visible,side:this.side,color:this.color.instance,specular:this.specular.instance,shininess:this.shininess,lightMapIntensity:this.lightMapIntensity,aoMapIntensity:this.aoMapIntensity,emissive:this.emissive.instance,emissiveIntensity:this.emissiveIntensity,bumpScale:this.bumpScale,normalScale:this.normalScale,displacementScale:this.displacementScale,combine:this.combine,refractionRatio:this.refractionRatio,fog:this.fog,flatShading:this.flatShading,wireframe:this.wireframe,wireframeLinewidth:this.wireframeLineWidth,wireframeLinecap:this.wireframeLineCap,wireframeLinejoin:this.wireframeLineJoin,vertexColors:GameLib.D3.Material.TYPE_VERTEX_COLORS,skinning:this.skinning,morphTargets:this.morphTargets,morphNormals:this.morphNormals})},GameLib.D3.Material.prototype.createMeshBasicMaterialInstance=function(){return new THREE.MeshBasicMaterial({name:this.name,opacity:this.opacity,transparent:this.transparent,blending:this.blending,blendSrc:this.blendSrc,blendDst:this.blendDst,blendEquation:this.blendEquation,depthTest:this.depthTest,depthFunc:this.depthFunc,depthWrite:this.depthWrite,polygonOffset:this.polygonOffset,polygonOffsetFactor:this.polygonOffsetFactor,polygonOffsetUnits:this.polygonOffsetUnits,alphaTest:this.alphaTest,clippingPlanes:this.clippingPlanes,clipShadows:this.clipShadows,overdraw:this.overdraw,visible:this.visible,side:this.side,color:this.color.instance,vertexColors:GameLib.D3.Material.TYPE_VERTEX_COLORS,fog:this.fog})},GameLib.D3.Material.prototype.checkTexture=function(e,t){var i=!1;return this[e]&&this[e].instance?this.instance[t]!==this[e].instance&&(this.instance[t]=this[e].instance,i=!0):null!==this.instance[t]&&(this.instance[t]=null,i=!0),i},GameLib.D3.Material.prototype.updateTextures=function(){var e=!1;return this.checkTexture("alphaMap","alphaMap")&&(e=!0),this.checkTexture("aoMap","aoMap")&&(e=!0),this.checkTexture("bumpMap","bumpMap")&&(e=!0),this.checkTexture("diffuseMap","map")&&(e=!0),this.checkTexture("displacementMap","displacementMap")&&(e=!0),this.checkTexture("emissiveMap","emissiveMap")&&(e=!0),this.checkTexture("environmentMap","envMap")&&(e=!0),this.checkTexture("lightMap","lightMap")&&(e=!0),this.checkTexture("metalnessMap","metalnessMap")&&(e=!0),this.checkTexture("normalMap","normalMap")&&(e=!0),this.checkTexture("roughnessMap","roughnessMap")&&(e=!0),this.checkTexture("specularMap","specularMap")&&(e=!0),e&&this.publish(GameLib.Event.MATERIAL_TEXTURES_UPDATED,{material:this}),e},GameLib.D3.Material.prototype.updateToonMaterialInstance=function(e){this.instance.name=this.name,this.instance.opacity=this.opacity,this.instance.transparent=this.transparent,this.instance.blending=this.blending,this.instance.blendSrc=this.blendSrc,this.instance.blendDst=this.blendDst,this.instance.blendEquation=this.blendEquation,this.instance.depthTest=this.depthTest,this.instance.depthFunc=this.depthFunc,this.instance.depthWrite=this.depthWrite,this.instance.polygonOffset=this.polygonOffset,this.instance.polygonOffsetFactor=this.polygonOffsetFactor,this.instance.polygonOffsetUnits=this.polygonOffsetUnits,this.instance.alphaTest=this.alphaTest,this.instance.clippingPlanes=this.clippingPlanes,this.instance.clipShadows=this.clipShadows,this.instance.overdraw=this.overdraw,this.instance.visible=this.visible,this.instance.side=this.side,this.instance.color=this.color.instance,this.instance.envMapIntensity=this.envMapIntensity,this.instance.roughness=this.roughness,this.instance.metalness=this.metalness,this.instance.lightMapIntensity=this.lightMapIntensity,this.instance.aoMapIntensity=this.aoMapIntensity,this.instance.emissive=this.emissive.instance,this.instance.emissiveIntensity=this.emissiveIntensity,this.instance.bumpScale=this.bumpScale,this.instance.normalScale=this.normalScale,this.instance.displacementScale=this.displacementScale,this.instance.refractionRatio=this.refractionRatio,this.instance.fog=this.fog,this.instance.flatShading=this.flatShading,this.instance.wireframe=this.wireframe,this.instance.wireframeLinewidth=this.wireframeLineWidth,this.instance.wireframeLinecap=this.wireframeLineCap,this.instance.wireframeLinejoin=this.wireframeLineJoin,this.instance.vertexColors=GameLib.D3.Material.TYPE_VERTEX_COLORS,this.instance.skinning=this.skinning,this.instance.morphTargets=this.morphTargets,this.instance.morphNormals=this.morphNormals},GameLib.D3.Material.prototype.updateStandardMaterialInstance=function(e){this.instance.name=this.name,this.instance.opacity=this.opacity,this.instance.transparent=this.transparent,this.instance.blending=this.blending,this.instance.blendSrc=this.blendSrc,this.instance.blendDst=this.blendDst,this.instance.blendEquation=this.blendEquation,this.instance.depthTest=this.depthTest,this.instance.depthFunc=this.depthFunc,this.instance.depthWrite=this.depthWrite,this.instance.polygonOffset=this.polygonOffset,this.instance.polygonOffsetFactor=this.polygonOffsetFactor,this.instance.polygonOffsetUnits=this.polygonOffsetUnits,this.instance.alphaTest=this.alphaTest,this.instance.clippingPlanes=this.clippingPlanes,this.instance.clipShadows=this.clipShadows,this.instance.overdraw=this.overdraw,this.instance.visible=this.visible,this.instance.side=this.side,this.instance.color=this.color.instance,this.instance.envMapIntensity=this.envMapIntensity,this.instance.roughness=this.roughness,this.instance.metalness=this.metalness,this.instance.lightMapIntensity=this.lightMapIntensity,this.instance.aoMapIntensity=this.aoMapIntensity,this.instance.emissive=this.emissive.instance,this.instance.emissiveIntensity=this.emissiveIntensity,this.instance.bumpScale=this.bumpScale,this.instance.normalScale=this.normalScale,this.instance.displacementScale=this.displacementScale,this.instance.refractionRatio=this.refractionRatio,this.instance.fog=this.fog,this.instance.flatShading=this.flatShading,this.instance.wireframe=this.wireframe,this.instance.wireframeLinewidth=this.wireframeLineWidth,this.instance.wireframeLinecap=this.wireframeLineCap,this.instance.wireframeLinejoin=this.wireframeLineJoin,this.instance.vertexColors=GameLib.D3.Material.TYPE_VERTEX_COLORS,this.instance.skinning=this.skinning,this.instance.morphTargets=this.morphTargets,this.instance.morphNormals=this.morphNormals},GameLib.D3.Material.prototype.updatePointsMaterialInstance=function(e){this.instance.name=this.name,this.instance.opacity=this.opacity,this.instance.transparent=this.transparent,this.instance.depthFunc=this.depthFunc,this.instance.depthWrite=this.depthWrite,this.instance.visible=this.visible,this.instance.side=this.side,this.instance.color=this.color.instance,this.instance.size=this.pointSize,this.instance.sizeAttenuation=this.pointSizeAttenuation},GameLib.D3.Material.prototype.updateLineBasicMaterialInstance=function(e){var t="round";this.lineCap===GameLib.D3.Material.LINE_CAP_BUTT&&(t="butt"),this.lineCap===GameLib.D3.Material.LINE_CAP_SQUARE&&(t="square");var i="round";this.lineJoin===GameLib.D3.Material.LINE_JOIN_BEVEL&&(i="bevel"),this.lineJoin===GameLib.D3.Material.LINE_JOIN_MITER&&(i="miter"),this.instance.name=this.name,this.instance.opacity=this.opacity,this.instance.transparent=this.transparent,this.instance.depthFunc=this.depthFunc,this.instance.depthWrite=this.depthWrite,this.instance.visible=this.visible,this.instance.side=this.side,this.instance.color=this.color.instance,this.instance.linewidth=this.lineWidth,this.instance.linecap=t,this.instance.linejoin=i},GameLib.D3.Material.prototype.updatePhongMaterialInstance=function(e){this.instance.name=this.name,this.instance.opacity=this.opacity,this.instance.transparent=this.transparent,this.instance.blending=this.blending,this.instance.blendSrc=this.blendSrc,this.instance.blendDst=this.blendDst,this.instance.blendEquation=this.blendEquation,this.instance.depthTest=this.depthTest,this.instance.depthFunc=this.depthFunc,this.instance.depthWrite=this.depthWrite,this.instance.polygonOffset=this.polygonOffset,this.instance.polygonOffsetFactor=this.polygonOffsetFactor,this.instance.polygonOffsetUnits=this.polygonOffsetUnits,this.instance.alphaTest=this.alphaTest,this.instance.clippingPlanes=this.clippingPlanes,this.instance.clipShadows=this.clipShadows,this.instance.overdraw=this.overdraw,this.instance.visible=this.visible,this.instance.side=this.side,this.instance.color=this.color.instance,this.instance.specular=this.specular.instance,this.instance.shininess=this.shininess,this.instance.lightMapIntensity=this.lightMapIntensity,this.instance.aoMapIntensity=this.aoMapIntensity,this.instance.emissive=this.emissive.instance,this.instance.emissiveIntensity=this.emissiveIntensity,this.instance.envMapIntensity=this.envMapIntensity,this.instance.bumpScale=this.bumpScale,this.instance.normalScale=this.normalScale,this.instance.displacementScale=this.displacementScale,this.instance.combine=this.combine,this.instance.refractionRatio=this.refractionRatio,this.instance.fog=this.fog,this.instance.flatShading=this.flatShading,this.instance.wireframe=this.wireframe,this.instance.wireframeLinewidth=this.wireframeLineWidth,this.instance.wireframeLinecap=this.wireframeLineCap,this.instance.wireframeLinejoin=this.wireframeLineJoin,this.instance.vertexColors=GameLib.D3.Material.TYPE_VERTEX_COLORS,this.instance.skinning=this.skinning,this.instance.morphTargets=this.morphTargets,this.instance.morphNormals=this.morphNormals},GameLib.D3.Material.prototype.updateMeshBasicMaterialInstance=function(e){this.instance.name=this.name,this.instance.opacity=this.opacity,this.instance.transparent=this.transparent,this.instance.blending=this.blending,this.instance.blendSrc=this.blendSrc,this.instance.blendDst=this.blendDst,this.instance.blendEquation=this.blendEquation,this.instance.depthTest=this.depthTest,this.instance.depthFunc=this.depthFunc,this.instance.depthWrite=this.depthWrite,this.instance.polygonOffset=this.polygonOffset,this.instance.polygonOffsetFactor=this.polygonOffsetFactor,this.instance.polygonOffsetUnits=this.polygonOffsetUnits,this.instance.alphaTest=this.alphaTest,this.instance.clippingPlanes=this.clippingPlanes,this.instance.clipShadows=this.clipShadows,this.instance.overdraw=this.overdraw,this.instance.visible=this.visible,this.instance.side=this.side,this.instance.color=this.color.instance,this.instance.vertexColors=GameLib.D3.Material.TYPE_VERTEX_COLORS,this.instance.fog=this.fog},GameLib.D3.Material.prototype.createInstance=function(){this.materialType===GameLib.D3.Material.MATERIAL_TYPE_STANDARD?this.instance=this.createStandardMaterialInstance():this.materialType===GameLib.D3.Material.MATERIAL_TYPE_POINTS?this.instance=this.createPointsMaterialInstance():this.materialType===GameLib.D3.Material.MATERIAL_TYPE_PHONG?this.instance=this.createPhongMaterialInstance():this.materialType===GameLib.D3.Material.MATERIAL_TYPE_BASIC?this.instance=this.createMeshBasicMaterialInstance():this.materialType===GameLib.D3.Material.MATERIAL_TYPE_LINE_BASIC?this.instance=this.createLineBasicMaterialInstance():this.materialType===GameLib.D3.Material.MATERIAL_TYPE_TOON?this.instance=this.createToonMaterialInstance():console.warn("material type is not implemented yet: "+this.materialType),this.instance.needsUpdate=!0,this.updateTextures(),GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Material.prototype.updateInstance=function(e){return this.instance?"materialType"===e?(this.createInstance(),void this.publish(GameLib.Event.MATERIAL_TYPE_CHANGED,{material:this})):("alphaMap"!==e&&"aoMap"!==e&&"bumpMap"!==e&&"diffuseMap"!==e&&"displacementMap"!==e&&"emissiveMap"!==e&&"environmentMap"!==e&&"lightMap"!==e&&"metalnessMap"!==e&&"normalMap"!==e&&"roughnessMap"!==e&&"specularMap"!==e||this.updateTextures(),this.materialType===GameLib.D3.Material.MATERIAL_TYPE_STANDARD?this.updateStandardMaterialInstance(e):this.materialType===GameLib.D3.Material.MATERIAL_TYPE_POINTS?this.updatePointsMaterialInstance(e):this.materialType===GameLib.D3.Material.MATERIAL_TYPE_PHONG?this.updatePhongMaterialInstance(e):this.materialType===GameLib.D3.Material.MATERIAL_TYPE_BASIC?this.updateMeshBasicMaterialInstance(e):this.materialType===GameLib.D3.Material.MATERIAL_TYPE_LINE_BASIC?this.updateLineBasicMaterialInstance(e):this.materialType===GameLib.D3.Material.MATERIAL_TYPE_TOON?this.updateToonMaterialInstance(e):console.warn("not yet implemented (material type = "+this.materialType+")"),void(this.instance.needsUpdate=!0)):void console.warn("Attempt to update a non-existent instance")},GameLib.D3.Material.prototype.toApiObject=function(e){GameLib.Utils.UndefinedOrNull(e)&&(e=!1);var t=null;this.alphaMap&&(e&&this.alphaMap.save(),t=this.alphaMap.id);var i=null;this.aoMap&&(e&&this.aoMap.save(),i=this.aoMap.id);var n=null;this.bumpMap&&(e&&this.bumpMap.save(),n=this.bumpMap.id);var a=null;this.diffuseMap&&(e&&this.diffuseMap.save(),a=this.diffuseMap.id);var s=null;this.displacementMap&&(e&&this.displacementMap.save(),s=this.displacementMap.id);var o=null;this.emissiveMap&&(e&&this.emissiveMap.save(),o=this.emissiveMap.id);var r=null;this.environmentMap&&(e&&this.environmentMap.save(),r=this.environmentMap.id);var c=null;this.lightMap&&(e&&this.lightMap.save(),c=this.lightMap.id);var m=null;this.metalnessMap&&(e&&this.metalnessMap.save(),m=this.metalnessMap.id);var h=null;this.normalMap&&(this.normalMap.save(),h=this.normalMap.id);var l=null;this.roughnessMap&&(e&&this.roughnessMap.save(),l=this.roughnessMap.id);var p=null;return this.specularMap&&(e&&this.specularMap.save(),p=this.specularMap.id),new GameLib.D3.API.Material(this.id,this.materialType,this.name,this.opacity,this.side,this.transparent,this.specular.toApiObject(),this.lightMapIntensity,this.aoMapIntensity,this.color.toApiObject(),this.emissive.toApiObject(),this.emissiveIntensity,this.combine,this.shininess,this.reflectivity,this.refractionRatio,this.fog,this.wireframe,this.wireframeLineWidth,this.wireframeLineCap,this.wireframeLineJoin,this.vertexColors,this.skinning,this.morphTargets,this.morphNormals,this.lineWidth,this.lineCap,this.lineJoin,this.dashSize,this.gapWidth,this.blending,this.blendSrc,this.blendDst,this.blendEquation,this.depthTest,this.depthFunc,this.depthWrite,this.polygonOffset,this.polygonOffsetFactor,this.polygonOffsetUnits,this.alphaTest,this.clippingPlanes,this.clipShadows,this.visible,this.overdraw,this.flatShading,this.bumpScale,this.normalScale,this.displacementScale,this.displacementBias,this.roughness,this.metalness,this.pointSize,this.pointSizeAttenuation,this.spriteRotation,this.envMapIntensity,t,i,n,a,s,o,r,c,m,h,l,p,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Material.prototype.getTextures=function(){var e=[];return this.alphaMap&&e.push(this.alphaMap),this.aoMap&&e.push(this.aoMap),this.bumpMap&&e.push(this.bumpMap),this.diffuseMap&&e.push(this.diffuseMap),this.displacementMap&&e.push(this.displacementMap),this.emissiveMap&&e.push(this.emissiveMap),this.environmentMap&&e.push(this.environmentMap),this.lightMap&&e.push(this.lightMap),this.metalnessMap&&e.push(this.metalnessMap),this.normalMap&&e.push(this.normalMap),this.roughnessMap&&e.push(this.roughnessMap),this.specularMap&&e.push(this.specularMap),e},GameLib.D3.Material.FromObject=function(e,t){return new GameLib.D3.Material(e,GameLib.D3.API.Material.FromObject(t))},GameLib.D3.Mesh=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={meshType:GameLib.D3.API.Mesh.MESH_TYPE_NORMAL}),t instanceof GameLib.D3.Mesh)return t;GameLib.D3.API.Mesh.call(this,t.id,t.meshType,t.name,t.vertices,t.faces,t.materials,t.parentMesh,t.parentScene,t.skeleton,t.skinIndices,t.skinWeights,t.position,t.quaternion,t.rotation,t.scale,t.up,t.modelMatrix,t.renderOrder,t.isBufferMesh,t.useQuaternion,t.visible,t.parentEntity),this.faces=this.faces.map(function(e){return e instanceof GameLib.D3.API.Face?new GameLib.D3.Face(this.graphics,e):e}.bind(this)),this.materials=this.materials.map(function(e){return e instanceof GameLib.D3.API.Material?new GameLib.D3.Material(this.graphics,e):e}.bind(this)),this.skeleton&&(this.skeleton=new GameLib.D3.Skeleton(this.graphics,this.skeleton)),this.vertices=this.vertices.map(function(e){return new GameLib.D3.Vertex(this.graphics,e)}.bind(this)),this.position=new GameLib.Vector3(this.graphics,this.position,this),this.quaternion=new GameLib.Quaternion(this.graphics,this.quaternion,this),this.rotation=new GameLib.Vector3(this.graphics,this.rotation,this),this.scale=new GameLib.Vector3(this.graphics,this.scale,this),this.up=new GameLib.Vector3(this.graphics,this.up,this),this.modelMatrix=new GameLib.Matrix4(this.graphics,this.modelMatrix,this),this.dimensions=new GameLib.Vector3(this.graphics,new GameLib.API.Vector3,this);var i={parentMesh:GameLib.D3.Mesh,parentScene:GameLib.D3.Scene,materials:[GameLib.D3.Material],skeleton:GameLib.D3.Skeleton};this.meshType===GameLib.D3.API.Mesh.MESH_TYPE_TEXT&&(i.font=GameLib.D3.Font),this.helper=null,this.updateRotationFromAxisAngle=!0,GameLib.Component.call(this,i)},GameLib.D3.Mesh.prototype=Object.create(GameLib.D3.API.Mesh.prototype),GameLib.D3.Mesh.prototype.constructor=GameLib.D3.Mesh,GameLib.D3.Mesh.prototype.lookAt=function(e){this.instance.lookAt(new THREE.Vector3(e.x,e.y,e.z)),this.rotation.x=this.instance.rotation.x,this.rotation.y=this.instance.rotation.y,this.rotation.z=this.instance.rotation.z, -this.quaternion.x=this.instance.quaternion.x,this.quaternion.y=this.instance.quaternion.y,this.quaternion.z=this.instance.quaternion.z,this.quaternion.w=this.instance.quaternion.w},GameLib.D3.Mesh.prototype.createInstanceGeometry=function(e){if(e instanceof THREE.Geometry&&(this.computeBoundingBox(e),this.isBufferMesh))return(new THREE.BufferGeometry).fromGeometry(e);this.faces.sort(function(e,t){return e.materialIndext.materialIndex?1:0});var t=new Float32Array(this.faces.reduce(function(e,t){return e.push(this.vertices[t.v0index].position.x),e.push(this.vertices[t.v0index].position.y),e.push(this.vertices[t.v0index].position.z),e.push(this.vertices[t.v1index].position.x),e.push(this.vertices[t.v1index].position.y),e.push(this.vertices[t.v1index].position.z),e.push(this.vertices[t.v2index].position.x),e.push(this.vertices[t.v2index].position.y),e.push(this.vertices[t.v2index].position.z),e}.bind(this),[])),i=null;if(this.isBufferMesh){i=new THREE.BufferGeometry,i.addAttribute("position",new THREE.BufferAttribute(t,3));var n=new Float32Array(this.faces.reduce(function(e,t){return e.push(1,1,1,1,1,1,1,1,1),e}.bind(this),[]));i.addAttribute("color",new THREE.BufferAttribute(n,3,!0));var a=new Float32Array(this.faces.reduce(function(e,t){return t.uvs[0].map(function(t){e.push(t.x),e.push(t.y)}),e},[]));i.addAttribute("uv",new THREE.BufferAttribute(a,2));var s=new Float32Array(this.faces.reduce(function(e,t){return e.push(t.normal.x,t.normal.y,t.normal.z),e.push(t.normal.x,t.normal.y,t.normal.z),e.push(t.normal.x,t.normal.y,t.normal.z),e},[]));i.addAttribute("normal",new THREE.BufferAttribute(s,3)),i.computeVertexNormals();this.faces.reduce(function(e,t){var i=e.pop();return i.index!==t.materialIndex?(e.push(i),e.push({index:t.materialIndex,count:3})):(i.count+=3,e.push(i)),e},[{index:0,count:0}]).reduce(function(e,t){return i.addGroup(e,t.count,t.index),e+t.count},0)}else{i=new THREE.Geometry;var o=[];i.faces=this.faces.map(function(e){e.uvs[0].length>0&&o.push(e.uvs[0].map(function(e){return new THREE.Vector2(e.x,e.y)}));var t=new THREE.Face3(e.v0index,e.v1index,e.v2index);return e.normal&&(t.normal=new THREE.Vector3(e.normal.x,e.normal.y,e.normal.z)),e.color&&(t.color=new THREE.Color(e.color.r,e.color.g,e.color.b)),t.materialIndex=e.materialIndex,t}),i.vertices=this.vertices.map(function(e){return new THREE.Vector3(e.position.x,e.position.y,e.position.z)}),i.verticesNeedUpdate=!0,o.length>0&&(i.faceVertexUvs=[o]),i.computeFaceNormals(),i.computeVertexNormals()}return this.computeBoundingBox(i),i},GameLib.D3.Mesh.prototype.createInstance=function(){var e=this.createInstanceGeometry();this.skeleton?(1===this.materials.length?this.instance=new THREE.SkinnedMesh(e,this.materials[0].instance):this.instance=new THREE.SkinnedMesh(e,this.materials.map(function(e){return e.instance})),this.instance.add(this.skeleton.rootBoneInstance),this.instance.bind(this.skeleton.instance)):1===this.materials.length?this.instance=new THREE.Mesh(e,this.materials[0].instance):this.instance=new THREE.Mesh(e,this.materials.map(function(e){return e.instance})),this.instance.name=this.name,this.parentMesh&&this.parentMesh.instance&&this.parentMesh.add(this.instance,this),this.instance.position.x=this.position.x,this.instance.position.y=this.position.y,this.instance.position.z=this.position.z,this.useQuaternion?(this.instance.quaternion.x=this.quaternion.x,this.instance.quaternion.y=this.quaternion.y,this.instance.quaternion.z=this.quaternion.z,this.instance.quaternion.w=this.quaternion.w,this.instance.quaternion.setFromAxisAngle(new THREE.Vector3(this.quaternion.axis.x,this.quaternion.axis.y,this.quaternion.axis.z),this.quaternion.angle)):(this.instance.rotation.x=this.rotation.x,this.instance.rotation.y=this.rotation.y,this.instance.rotation.z=this.rotation.z),this.instance.scale.x=this.scale.x,this.instance.scale.y=this.scale.y,this.instance.scale.z=this.scale.z,this.instance.up.x=this.up.x,this.instance.up.y=this.up.y,this.instance.up.z=this.up.z,this.instance.renderOrder=this.renderOrder,this.instance.visible=this.visible,GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Mesh.prototype.updateInstance=function(e){GameLib.Utils.UndefinedOrNull(e)&&console.warn("unknown mesh property update"),"isBufferMesh"===e&&(this.isBufferMesh&&!(this.instance.geometry instanceof THREE.BufferGeometry)||!this.isBufferMesh&&this.instance.geometry instanceof THREE.BufferGeometry)&&(this.instance.geometry=this.createInstanceGeometry(this.instance.geometry)),"rotation"!==e&&"quaternion"!==e&&"useQuaternion"!==e||this.updateInstanceRotation(),"parentMesh"===e&&this.parentMesh&&this.parentMesh.instance&&this.instance.parent!==this.parentMesh.instance&&(this.instance.parent=this.parentMesh.instance),"scale"===e&&this.updateInstanceScale(),"position"===e&&this.updateInstancePosition(),"up"===e&&(this.instance.up.x=this.up.x,this.instance.up.y=this.up.y,this.instance.up.z=this.up.z),"name"===e&&(this.instance.name=this.name),"materials"===e&&1===this.materials.length&&this.materials[0].instance&&(this.instance.material=this.materials[0].instance),"renderOrder"===e&&(this.instance.renderOrder=this.renderOrder),"visible"===e&&(this.instance.visible=this.visible),this.helper&&(this.removeHelper(),this.createHelper())},GameLib.D3.Mesh.prototype.updateVerticesFromGeometryInstance=function(e){if(this.vertices=[],this.faces=[],e instanceof THREE.BufferGeometry){var t=e.getAttribute("position").array,i=e.getAttribute("uv").array;e.groups.map(function(e){for(var n=e.materialIndex,a=e.start,s=e.count,o=[],r=[],c=a;c0&&e.push({mesh:t,distance:i[0].distance}),e}.bind(this),[])},GameLib.D3.Raycaster.prototype.getFaceNormal=function(e){var t=null,i=this.instance.intersectObject(e.instance);return i&&i.length>0&&(t=new GameLib.Vector3(this.graphics,new GameLib.API.Vector3(i[0].face.normal.x,i[0].face.normal.y,i[0].face.normal.z),this)),t},GameLib.D3.Raycaster.prototype.getIntersectPoint=function(e){var t=null,i=this.instance.intersectObject(e.instance);return i&&i.length>0&&(t=new GameLib.Vector3(this.graphics,new GameLib.API.Vector3(i[0].point.x,i[0].point.y,i[0].point.z),this)),t},GameLib.D3.RenderTarget=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.RenderTarget)return t;GameLib.D3.API.RenderTarget.call(this,t.id,t.name,t.width,t.height,t.stencilBuffer,t.texture),GameLib.Component.call(this,{texture:GameLib.D3.Texture})},GameLib.D3.RenderTarget.prototype=Object.create(GameLib.D3.API.RenderTarget.prototype),GameLib.D3.RenderTarget.prototype.constructor=GameLib.D3.RenderTarget,GameLib.D3.RenderTarget.prototype.createInstance=function(){if(GameLib.Utils.UndefinedOrNull(this.texture))throw new Error("no texture") -;if(GameLib.Utils.UndefinedOrNull(this.texture.instance))throw new Error("no texture instance");this.instance=new THREE.WebGLRenderTarget(this.width,this.height,{stencilBuffer:this.stencilBuffer}),this.instance.texture=this.texture.instance,GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.RenderTarget.prototype.updateInstance=function(){if(this.instance)this.instance.setSize(this.width,this.height),this.instance.stencilBuffer=this.stencilBuffer,this.texture&&this.texture.instance?(this.instance.texture=this.texture.instance,this.instance.texture.needsUpdate=!0):this.instance.texture=null;else try{this.createInstance()}catch(e){console.error(e)}},GameLib.D3.RenderTarget.prototype.toApiObject=function(){return new GameLib.D3.API.RenderTarget(this.id,this.name,this.width,this.height,this.stencilBuffer,GameLib.Utils.IdOrNull(this.texture),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.RenderTarget.FromObject=function(e,t){var i=GameLib.D3.API.RenderTarget.FromObject(t);return new GameLib.D3.RenderTarget(e,i)},GameLib.D3.Renderer=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Renderer)return t;GameLib.D3.API.Renderer.call(this,t.id,t.name,t.autoClear,t.localClipping,t.width,t.height,t.preserveDrawingBuffer,t.domElement,t.clearColor,t.camera,t.scenes,t.viewports,t.clippingPlanes,t.bufferScene,t.bufferCamera,t.renderTarget,t.defaultScene,t.sortObjects,t.parentEntity),this.clearColor=new GameLib.Color(this.graphics,this.clearColor,this),this.domElement instanceof GameLib.API.DomElement&&(this.domElement=new GameLib.DomElement(this.domElement)),this.camera instanceof GameLib.D3.API.Camera&&(this.camera=new GameLib.D3.Camera(this.graphics,this.camera)),this.scenes=this.scenes.map(function(e){return e instanceof GameLib.D3.API.Scene?new GameLib.D3.Scene(this.graphics,e):e}.bind(this)),this.viewports=this.viewports.map(function(e){return e instanceof GameLib.D3.API.Viewport?new GameLib.D3.Viewport(this.graphics,e):e}.bind(this)),this.clippingPlanes=this.clippingPlanes.map(function(e){return e instanceof GameLib.D3.API.Mesh?new GameLib.D3.Mesh.Plane(this.graphics,e,e.width,e.height,e.widthSegments,e.heightSegments,e.heightMapScale,e.isHeightMap,e.isClippingPlane,e.distanceFromOrigin):e}.bind(this)),this.bufferScene instanceof GameLib.D3.API.Scene&&(this.bufferScene=new GameLib.D3.Scene(this.graphics,this.bufferScene)),this.bufferCamera instanceof GameLib.D3.API.Camera&&(this.bufferCamera=new GameLib.D3.Camera(this.graphics,this.bufferCamera)),this.renderTarget instanceof GameLib.D3.API.RenderTarget&&(this.renderTarget=new GameLib.D3.RenderTarget(this.graphics,this.renderTarget)),GameLib.Component.call(this,{domElement:GameLib.DomElement,camera:GameLib.D3.Camera,scenes:[GameLib.D3.Scene],viewports:[GameLib.D3.Viewport],clippingPlanes:[GameLib.D3.Mesh.Plane],bufferScene:GameLib.D3.Scene,bufferCamera:GameLib.D3.Camera,renderTarget:GameLib.D3.RenderTarget,defaultScene:GameLib.D3.Scene})},GameLib.D3.Renderer.prototype=Object.create(GameLib.D3.API.Renderer.prototype),GameLib.D3.Renderer.prototype.constructor=GameLib.D3.Renderer,GameLib.D3.Renderer.prototype.createInstance=function(){if(GameLib.Utils.UndefinedOrNull(this.domElement))throw new Error("no dom element");if(GameLib.Utils.UndefinedOrNull(this.domElement.instance))throw new Error("no dom element instance");this.instance=new THREE.WebGLRenderer({canvas:this.domElement.instance}),this.clippingPlanes.length>0&&(this.instance.clippingPlanes=this.clippingPlanes.map(function(e){if(!e.isClippingPlane||!e.instance||!e.instance.clipping)throw new Error("is not a clipping plane or no clipping plane instance");return e.instance.clipping})),this.instance.localClippingEnabled=this.localClipping,this.instance.setSize(this.width,this.height),this.instance.setClearColor(new THREE.Color(this.clearColor.r,this.clearColor.g,this.clearColor.b),1-this.clearColor.a),this.instance.domElement.width=this.width,this.instance.domElement.height=this.height,this.instance.autoClear=this.autoClear,this.instance.preserveDrawingBuffer=this.preserveDrawingBuffer,this.instance.sortObjects=this.sortObjects,GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Renderer.prototype.updateInstance=function(e){if(this.instance)e||console.error("no property for renderer"),"localClipping"===e&&(this.instance.localClippingEnabled=this.localClipping),this.instance.setSize(this.width,this.height),this.instance.domElement.width=this.width,this.instance.domElement.height=this.height,"clearColor"===e&&this.instance.setClearColor(new THREE.Color(this.clearColor.r,this.clearColor.g,this.clearColor.b),1-this.clearColor.a),"autoClear"===e&&(this.instance.autoClear=this.autoClear),"preserveDrawingBuffer"===e&&(this.instance.preserveDrawingBuffer=this.preserveDrawingBuffer),this.clippingPlanes.length>0?this.instance.clippingPlanes=this.clippingPlanes.map(function(e){if(!e.isClippingPlane||!e.instance||!e.instance.clipping)throw new Error("is not a clipping plane or no clipping plane instance");return e.instance.clipping}):this.instance.clippingPlanes=[],"sortObjects"===e&&(this.instance.sortObjects=this.sortObjects);else try{this.createInstance()}catch(e){console.error(e.message)}},GameLib.D3.Renderer.prototype.toApiObject=function(){return new GameLib.D3.API.Renderer(this.id,this.name,this.autoClear,this.localClipping,this.width,this.height,this.preserveDrawingBuffer,GameLib.Utils.IdOrNull(this.domElement),this.clearColor.toApiObject(),GameLib.Utils.IdOrNull(this.camera),this.scenes.map(function(e){return GameLib.Utils.IdOrNull(e)}),this.viewports.map(function(e){return GameLib.Utils.IdOrNull(e)}),this.clippingPlanes.map(function(e){return GameLib.Utils.IdOrNull(e)}),GameLib.Utils.IdOrNull(this.bufferScene),GameLib.Utils.IdOrNull(this.bufferCamera),GameLib.Utils.IdOrNull(this.renderTarget),GameLib.Utils.IdOrNull(this.defaultScene),this.sortObjects,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Renderer.FromObject=function(e,t){var i=GameLib.D3.API.Renderer.FromObject(t);return new GameLib.D3.Renderer(e,i)},GameLib.D3.Renderer.prototype.render=function(e,t){this.instance&&(GameLib.Utils.UndefinedOrNull(t)&&(t=this.scenes),this.viewports.length>1&&(this.instance.autoClear=!1),t.length>1&&(this.instance.autoClear=!1),this.instance.clear(),this.bufferScene&&this.bufferScene.instance&&this.bufferCamera&&this.bufferCamera.instance&&this.renderTarget&&this.renderTarget.instance&&this.instance.render(this.bufferScene.instance,this.bufferCamera.instance,this.renderTarget.instance),this.viewports.map(function(e){this.instance.setViewport(e.x*this.width,e.y*this.height,e.width*this.width,e.height*this.height),t.map(function(e){e.instance&&(this.camera.instance||e.renderCamera||e.renderCamera.instance)&&(e.renderCamera&&e.renderCamera.instance?this.instance.render(e.instance,e.renderCamera.instance):this.instance.render(e.instance,this.camera.instance))}.bind(this))}.bind(this)))},GameLib.D3.Renderer.prototype.setSize=function(e,t){this.width=e,this.height=t,this.instance?this.instance.setSize(this.width,this.height):console.log("renderer not ready to set size")},GameLib.D3.RigidBody=function(e,t){if(this.physics=e,this.physics.isNotCannonThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.RigidBody)return t;GameLib.D3.API.RigidBody.call(this,t.id,t.name,t.mass,t.friction,t.position,t.quaternion,t.velocity,t.angularVelocity,t.linearDamping,t.angularDamping,t.allowSleep,t.sleepSpeedLimit,t.sleepTimeLimit,t.collisionFilterGroup,t.collisionFilterMask,t.fixedRotation,t.shapes,t.kinematic,t.parentMesh,t.parentPhysicsWorld,t.parentEntity),this.position=new GameLib.Vector3(this.physics,this.position,this),this.quaternion=new GameLib.Quaternion(this.physics,this.quaternion,this),this.velocity=new GameLib.Vector3(this.physics,this.velocity,this),this.angularVelocity=new GameLib.Vector3(this.physics,this.angularVelocity,this),this.force=new GameLib.Vector3(this.physics),this.forcePoint=new GameLib.Vector3(this.physics),GameLib.Component.call(this,{shapes:[GameLib.D3.Shape],parentMesh:GameLib.D3.Mesh,parentPhysicsWorld:GameLib.D3.PhysicsWorld})},GameLib.D3.RigidBody.prototype=Object.create(GameLib.D3.API.RigidBody.prototype),GameLib.D3.RigidBody.prototype.constructor=GameLib.D3.RigidBody,GameLib.D3.RigidBody.prototype.createInstance=function(){this.instance=new CANNON.Body({mass:this.mass,friction:this.friction,position:this.position.instance,quaternion:this.quaternion.instance,velocity:this.velocity.instance,angularVelocity:this.angularVelocity.instance,linearDamping:this.linearDamping,angularDamping:this.angularDamping,allowSleep:this.allowSleep,sleepSpeedLimit:this.sleepSpeedLimit,sleepTimeLimit:this.sleepTimeLimit,collisionFilterGroup:this.collisionFilterGroup,collisionFilterMask:this.collisionFilterMask,fixedRotation:this.fixedRotation,kinematic:this.kinematic}),this.instance.addEventListener("sleepy",function(){console.log(this.name+" is feeling sleepy...")}.bind(this)),this.instance.addEventListener("sleep",function(){console.log(this.name+" fell asleep!")}.bind(this)),this.instance.addEventListener("wakeup",function(){console.log(this.name+" woke up!")}.bind(this)),this.shapes.map(function(e){if(GameLib.Utils.UndefinedOrNull(e))throw new Error("no shape");if(GameLib.Utils.UndefinedOrNull(e.instance))throw new Error("no shape instance");this.instance.addShape(e.instance)}.bind(this)),GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.RigidBody.prototype.updateInstance=function(){this.instance.mass=this.mass,this.instance.friction=this.friction,this.instance.position.x=this.position.x,this.instance.position.y=this.position.y,this.instance.position.z=this.position.z,this.quaternion.axis.instance.x=this.quaternion.axis.x,this.quaternion.axis.instance.y=this.quaternion.axis.y,this.quaternion.axis.instance.z=this.quaternion.axis.z,this.instance.quaternion.setFromAxisAngle(this.quaternion.axis.instance,this.quaternion.angle),this.quaternion.x=this.instance.quaternion.x,this.quaternion.y=this.instance.quaternion.y,this.quaternion.z=this.instance.quaternion.z,this.quaternion.w=this.instance.quaternion.w,this.parentMesh.position.setFrom(this.position),this.parentMesh.quaternion.setFrom(this.quaternion),this.parentMesh.updateInstance(),this.instance.velocity.x=this.velocity.x,this.instance.velocity.y=this.velocity.y,this.instance.velocity.z=this.velocity.z,this.instance.angularVelocity.x=this.angularVelocity.x,this.instance.angularVelocity.y=this.angularVelocity.y,this.instance.angularVelocity.z=this.angularVelocity.z,this.instance.linearDamping=this.linearDamping,this.instance.angularDamping=this.angularDamping,this.instance.allowSleep=this.allowSleep,this.instance.sleepSpeedLimit=this.sleepSpeedLimit,this.instance.sleepTimeLimit=this.sleepTimeLimit,this.instance.collisionFilterGroup=this.collisionFilterGroup,this.instance.collisionFilterMask=this.collisionFilterMask,this.instance.fixedRotation=this.fixedRotation,this.instance.kinematic=this.kinematic},GameLib.D3.RigidBody.prototype.setFromParentMesh=function(){this.parentMesh&&this.parentMesh.instance||console.log("no parent mesh or instance"),this.instance.position.x=this.parentMesh.position.x,this.instance.position.y=this.parentMesh.position.y,this.instance.position.z=this.parentMesh.position.z,this.instance.quaternion.x=this.parentMesh.quaternion.x,this.instance.quaternion.y=this.parentMesh.quaternion.y,this.instance.quaternion.z=this.parentMesh.quaternion.z,this.instance.quaternion.w=this.parentMesh.quaternion.w},GameLib.D3.RigidBody.prototype.toApiObject=function(){return new GameLib.D3.API.RigidBody(this.id,this.name,this.mass,this.friction,this.position.toApiObject(),this.quaternion.toApiObject(),this.velocity.toApiObject(),this.angularVelocity.toApiObject(),this.linearDamping,this.angularDamping,this.allowSleep,this.sleepSpeedLimit,this.sleepTimeLimit,this.collisionFilterGroup,this.collisionFilterMask,this.fixedRotation,this.shapes.map(function(e){return GameLib.Utils.IdOrNull(e)}),this.kinematic,GameLib.Utils.IdOrNull(this.parentMesh),GameLib.Utils.IdOrNull(this.parentPhysicsWorld),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.RigidBody.FromObject=function(e,t){var i=GameLib.D3.API.RigidBody.FromObject(t);return new GameLib.D3.RigidBody(e,i)},GameLib.D3.RigidBody.prototype.applyForce=function(){this.instance.applyForce(this.force.instance,this.forcePoint.instance)},GameLib.D3.RigidBody.prototype.applyLocalForce=function(){this.instance.applyLocalForce(this.force.instance,this.forcePoint.instance)},GameLib.D3.Scene=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Scene)return t;GameLib.D3.API.Scene.call(this,t.id,t.name,t.meshes,t.lights,t.textures,t.materials,t.images,t.fog,t.renderCamera,t.showGrid,t.showAxis,t.gridSize,t.gridColor,t.parentEntity),this.meshes=this.meshes.map(function(e){return e instanceof GameLib.D3.API.Mesh?(e.parentScene=this,new GameLib.D3.Mesh(this.graphics,e)):e}.bind(this)),this.lights=this.lights.map(function(e){return e instanceof GameLib.D3.API.Light?new GameLib.D3.Light(this.graphics,e):e}.bind(this)),this.textures=this.textures.map(function(e){if(e instanceof GameLib.D3.API.Texture){return new GameLib.D3.Texture(this.graphics,e)}return e}.bind(this)),this.materials=this.materials.map(function(e){if(e instanceof GameLib.D3.API.Material){return new GameLib.D3.Material(this.graphics,e)}return e}.bind(this)),this.images=this.images.map(function(e){if(e instanceof GameLib.API.Image){return new GameLib.Image(this.graphics,e)}return e}.bind(this)),this.fog instanceof GameLib.D3.API.Fog&&(this.fog=new GameLib.D3.Fog(this.graphics,this.fog)),this.renderCamera instanceof GameLib.D3.API.Camera&&(this.renderCamera=new GameLib.D3.Camera(this.graphics,this.renderCamera)),this.gridColor instanceof GameLib.API.Color&&(this.gridColor=new GameLib.Color(this.graphics,this.gridColor,this)),this.helpers=[],this.clones=[],this.grid=[],this.axis=[],this.storeClones=!1,GameLib.Component.call(this,{meshes:[GameLib.D3.Mesh],lights:[GameLib.D3.Light],textures:[GameLib.D3.Texture],materials:[GameLib.D3.Material],images:[GameLib.Image],fog:GameLib.D3.Fog,renderCamera:GameLib.D3.Camera})},GameLib.D3.Scene.prototype=Object.create(GameLib.D3.API.Scene.prototype),GameLib.D3.Scene.prototype.constructor=GameLib.D3.Scene,GameLib.D3.Scene.prototype.createInstance=function(){this.instance=new THREE.Scene,this.instance.name=this.name,this.fog&&this.fog.instance&&(this.instance.fog=this.fog.instance),this.meshes.map(function(e){if(GameLib.Utils.UndefinedOrNull(e))throw new Error("no mesh");if(GameLib.Utils.UndefinedOrNull(e.instance))throw new Error("no mesh instance");this.instance.add(e.instance),e.parentScene=this}.bind(this)),this.lights.map(function(e){if(GameLib.Utils.UndefinedOrNull(e))throw new Error("no light");if(GameLib.Utils.UndefinedOrNull(e.instance))throw new Error("no light instance");this.instance.add(e.instance),e.parentScene=this}.bind(this)),this.showGrid&&this.drawGrid(),this.showAxis&&this.drawAxis(),GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Scene.prototype.updateInstance=function(e){if("name"===e)return void(this.instance.name=this.name);this.fog&&this.fog.instance!==this.instance.fog&&(this.instance.fog=this.fog.instance),this.meshes.map(function(e){this.instance.children.indexOf(-1===e.instance)&&this.instance.add(e.instance)}.bind(this)),this.lights.map(function(e){-1===this.instance.children.indexOf(e.instance)&&this.instance.add(e.instance)}.bind(this)),this.instance.children.map(function(e){var t=this.meshes.map(function(e){return e.instance}),i=this.lights.map(function(e){return e.instance});(e instanceof THREE.Mesh||e instanceof THREE.Light)&&-1===i.indexOf(e)&&-1===t.indexOf(e)&&this.instance.remove(e)}.bind(this)),"showGrid"!==e&&"gridSize"!==e&&"gridColor"!==e||(this.showGrid?this.drawGrid():this.removeGrid()),"showAxis"===e&&(this.showAxis?this.drawAxis():this.removeAxis())},GameLib.D3.Scene.prototype.toApiObject=function(){var e=this.meshes.reduce(function(e,t){return(-1===this.clones.indexOf(t)||this.storeClones)&&e.push(GameLib.Utils.IdOrNull(t)),e}.bind(this),[]),t=this.lights.reduce(function(e,t){return(-1===this.clones.indexOf(t)||this.storeClones)&&e.push(GameLib.Utils.IdOrNull(t)),e}.bind(this),[]),i=this.textures.map(function(e){return GameLib.Utils.IdOrNull(e)}),n=this.materials.map(function(e){return GameLib.Utils.IdOrNull(e)}),a=this.images.map(function(e){return GameLib.Utils.IdOrNull(e)});return new GameLib.D3.API.Scene(this.id,this.name,e,t,i,n,a,GameLib.Utils.IdOrNull(this.fog),GameLib.Utils.IdOrNull(this.renderCamera),this.showGrid,this.showAxis,this.gridSize,this.gridColor.toApiObject(),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Scene.FromObject=function(e,t){var i=GameLib.D3.API.Scene.FromObject(t);return new GameLib.D3.Scene(e,i)},GameLib.D3.Scene.prototype.addObject=function(e){e instanceof GameLib.D3.Mesh?-1===this.meshes.indexOf(e)&&this.meshes.push(e):e instanceof GameLib.D3.API.Mesh&&(e=new GameLib.D3.Mesh(this.graphics,e),this.meshes.push(e)),e instanceof GameLib.D3.Light?-1===this.lights.indexOf(e)&&this.lights.push(e):e instanceof GameLib.D3.API.Light&&(e=new GameLib.D3.Light(this.graphics,e),this.lights.push(e)),e.parentScene=this,this.instance&&e.instance&&-1===this.instance.children.indexOf(e.instance)&&this.instance.add(e.instance)},GameLib.D3.Scene.prototype.addClone=function(e){(e instanceof GameLib.D3.Mesh||e instanceof GameLib.D3.Light)&&(this.instance&&e.instance&&this.instance.add(e.instance),GameLib.Utils.PushUnique(this.clones,e),e.parentScene=this)},GameLib.D3.Scene.prototype.removeObject=function(e){var t=-1;if(e instanceof GameLib.D3.Mesh)t=this.meshes.indexOf(e),-1!==t&&this.meshes.splice(t,1),-1!==(t=this.clones.indexOf(e))&&this.clones.splice(t,1);else{if(!(e instanceof GameLib.D3.Light))return void console.warn("Cannot remove this object - what is this ?"+e.toString());t=this.lights.indexOf(e),-1!==t&&this.lights.splice(t,1),-1!==(t=this.clones.indexOf(e))&&this.clones.splice(t,1)}-1!==this.instance.children.indexOf(e.instance)?this.instance.remove(e.instance):console.warn("no scene instance"),e.parentScene===this&&(e.parentScene=null)},GameLib.D3.Scene.prototype.drawGrid=function(){this.removeGrid();for(var e=new THREE.LineBasicMaterial({color:this.gridColor.toHex(),linewidth:1}),t=-this.gridSize;t<=this.gridSize;t+=1){var i=new THREE.Geometry;i.vertices.push(new THREE.Vector3(t,0,-1*this.gridSize),new THREE.Vector3(t,0,this.gridSize));var n=new THREE.Line(i,e);this.instance.add(n),this.grid.push(n);var a=new THREE.Geometry;a.vertices.push(new THREE.Vector3(-1*this.gridSize,0,t),new THREE.Vector3(this.gridSize,0,t));var s=new THREE.Line(a,e);this.instance.add(s),this.grid.push(s)}},GameLib.D3.Scene.prototype.removeGrid=function(){this.grid.map(function(e){this.instance.remove(e)}.bind(this))},GameLib.D3.Scene.prototype.drawAxis=function(){this.removeAxis();var e=new THREE.LineBasicMaterial({color:16711680,linewidth:2}),t=new THREE.Geometry;t.vertices.push(new THREE.Vector3(0,0,0),new THREE.Vector3(100,0,0));var i=new THREE.Line(t,e);this.instance.add(i),this.axis.push(i);var n=new THREE.LineBasicMaterial({color:65280,linewidth:2}),a=new THREE.Geometry;a.vertices.push(new THREE.Vector3(0,0,0),new THREE.Vector3(0,100,0));var s=new THREE.Line(a,n);this.instance.add(s),this.axis.push(s);var o=new THREE.LineBasicMaterial({color:255,linewidth:2}),r=new THREE.Geometry;r.vertices.push(new THREE.Vector3(0,0,0),new THREE.Vector3(0,0,100));var c=new THREE.Line(r,o);this.instance.add(c),this.axis.push(c)},GameLib.D3.Scene.prototype.removeAxis=function(){this.axis.map(function(e){this.instance.remove(e)}.bind(this))},GameLib.D3.Shape=function(e,t){if(this.physics=e,this.physics.isNotCannonThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={shapeType:GameLib.D3.API.Shape.SHAPE_TYPE_NONE}),t instanceof GameLib.D3.Shape)return t;GameLib.D3.API.Shape.call(this,t.id,t.name,t.shapeType,t.boundingSphereRadius,t.collisionResponse,t.frictionMaterial,t.parentMesh,t.parentEntity);var i={frictionMaterial:GameLib.D3.FrictionMaterial,parentMesh:GameLib.D3.Mesh};GameLib.Component.call(this,i)},GameLib.D3.Shape.prototype=Object.create(GameLib.D3.API.Shape.prototype),GameLib.D3.Shape.prototype.constructor=GameLib.D3.Shape,GameLib.D3.Shape.prototype.createInstance=function(){GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Shape.prototype.updateInstance=function(){throw new Error("Do not instantiate this class directly - use a child class instead")},GameLib.D3.Shape.prototype.toApiObject=function(){return new GameLib.D3.API.Shape(this.id,this.name,this.shapeType,this.boundingSphereRadius,this.collisionResponse,GameLib.Utils.IdOrNull(this.frictionMaterial),GameLib.Utils.IdOrNull(this.parentMesh),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Shape.FromObject=function(e,t){throw"not implemented"},GameLib.D3.Shape.prototype.stopVisualize=function(){GameLib.Event.Emit(GameLib.Event.STOP_VISUALIZE,{mesh:this.mesh})},GameLib.D3.Shape.prototype.visualize=function(){GameLib.Event.Emit(GameLib.Event.VISUALIZE,{shape:this})},GameLib.D3.Shape.Box=function(e,t,i){if(this.physics=e,this.physics.isNotCannonThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={shapeType:GameLib.D3.API.Shape.SHAPE_TYPE_BOX}),t instanceof GameLib.D3.Shape.Box)return t;GameLib.Utils.UndefinedOrNull(i)?i=new GameLib.Vector3(e,new GameLib.API.Vector3(1,1,1)):i instanceof GameLib.API.Vector3&&(i=new GameLib.Vector3(this.physics,i,this)),this.halfExtents=i,GameLib.D3.Shape.call(this,this.physics,t)},GameLib.D3.Shape.Box.prototype=Object.create(GameLib.D3.Shape.prototype),GameLib.D3.Shape.Box.prototype.constructor=GameLib.D3.Shape.Box,GameLib.D3.Shape.Box.prototype.createInstance=function(){if(GameLib.Utils.UndefinedOrNull(this.halfExtents))throw new Error("no halfExtents");if(GameLib.Utils.UndefinedOrNull(this.halfExtents.instance))throw new Error("no halfExtents instance");this.instance=new CANNON.Box(this.halfExtents.instance),GameLib.D3.Shape.prototype.createInstance.call(this)},GameLib.D3.Shape.Box.prototype.updateInstance=function(){this.instance.halfExtents.x=this.halfExtents.x,this.instance.halfExtents.y=this.halfExtents.y,this.instance.halfExtents.z=this.halfExtents.z,this.instance.updateBoundingSphereRadius(),this.instance.updateConvexPolyhedronRepresentation()},GameLib.D3.Shape.Box.prototype.toApiObject=function(){var e=GameLib.D3.Shape.prototype.toApiObject.call(this);return e.halfExtents=this.halfExtents.toApiObject(),e},GameLib.D3.Shape.Box.prototype.setFromMesh=function(){if(null===this.parentMesh)return void console.log("select a mesh first");var e=this.parentMesh.getBoundingBox();this.halfExtents.x=e.x/2,this.halfExtents.y=e.y/2,this.halfExtents.z=e.z/2,this.halfExtents.updateInstance()},GameLib.D3.Shape.Box.FromObject=function(e,t){var i=GameLib.D3.API.Shape.FromObject(t);return i.halfExtents=GameLib.API.Vector3.FromObject(t.halfExtents),new GameLib.D3.Shape.Box(e,i,i.halfExtents)},GameLib.D3.Shape.ConvexHull=function(e,t,i,n,a,s){if(this.physics=e,this.physics.isNotCannonThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={shapeType:GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL}),t instanceof GameLib.D3.Shape.ConvexHull)return t;GameLib.Utils.UndefinedOrNull(i)&&(i=[]),this.vertices=i,GameLib.Utils.UndefinedOrNull(n)&&(n=[]),this.faces=n,GameLib.Utils.UndefinedOrNull(a)&&(a=[]),this.uniqueAxes=a,GameLib.Utils.UndefinedOrNull(s)&&(s=[]),this.uniqueEdges=s,this.vertices=this.vertices.map(function(e){return e instanceof GameLib.D3.API.Vertex?new GameLib.D3.Vertex(this.physics,e):e}.bind(this)),this.faces=this.faces.map(function(e){return e instanceof GameLib.D3.API.Face?new GameLib.D3.Face(this.physics,e):e}.bind(this)),this.uniqueAxes=this.uniqueAxes.map(function(e){return e instanceof GameLib.API.Vector3?new GameLib.Vector3(this.physics,e,this):e}.bind(this)),this.uniqueEdges=this.uniqueEdges.map(function(e){return e instanceof GameLib.API.Vector3?new GameLib.Vector3(this.physics,e,this):e}.bind(this)),GameLib.D3.Shape.call(this,this.physics,t)},GameLib.D3.Shape.ConvexHull.prototype=Object.create(GameLib.D3.Shape.prototype),GameLib.D3.Shape.ConvexHull.prototype.constructor=GameLib.D3.Shape.ConvexHull,GameLib.D3.Shape.ConvexHull.prototype.createInstance=function(){var e=[];this.instance=new CANNON.ConvexPolyhedron(this.vertices.map(function(e){if(GameLib.Utils.UndefinedOrNull(e))throw new Error("no vertex");if(GameLib.Utils.UndefinedOrNull(e.position))throw new Error("no vertex position");if(GameLib.Utils.UndefinedOrNull(e.position.instance))throw new Error("no vertex position instance");return e.position.instance}),this.faces.map(function(t){if(GameLib.Utils.UndefinedOrNull(t))throw new Error("no face");if(GameLib.Utils.UndefinedOrNull(t.normal))throw new Error("no face normal");if(GameLib.Utils.UndefinedOrNull(t.normal.instance))throw new Error("no face normal instance");if(GameLib.Utils.UndefinedOrNull(t.v0index))throw new Error("no face v0index");if(GameLib.Utils.UndefinedOrNull(t.v1index))throw new Error("no face v1index");if(GameLib.Utils.UndefinedOrNull(t.v2index))throw new Error("no face v2index");return e.push(t.normal.instance),[t.v0index,t.v1index,t.v2index]})),this.instance.faceNormals=e,GameLib.D3.Shape.prototype.createInstance.call(this)},GameLib.D3.Shape.ConvexHull.prototype.updateInstance=function(){console.log("todo: update convex hull instance")},GameLib.D3.Shape.ConvexHull.prototype.loadFromInstance=function(){console.log("todo: eventually load the faces and vertices from the instance faces and vertices and normals"),console.log("todo: this way we can nicely visualize them with our gamelib classes :)")},GameLib.D3.Shape.ConvexHull.prototype.toApiObject=function(){var e=GameLib.D3.Shape.prototype.toApiObject.call(this);return e.vertices=this.vertices.map(function(e){return e instanceof GameLib.D3.Vertex?e.toApiObject():e}),e.faces=this.faces.map(function(e){return e instanceof GameLib.D3.Face?e.toApiObject():e}),e.uniqueAxes=this.uniqueAxes.map(function(e){return e instanceof GameLib.Vector3?e.toApiObject():e}),e.uniqueEdges=this.uniqueEdges.map(function(e){return e instanceof GameLib.Vector3?e.toApiObject():e}),e},GameLib.D3.Shape.ConvexHull.prototype.setFromMesh=function(){console.log("todo: set convex hull from mesh"),this.updateInstance()},GameLib.D3.Shape.ConvexHull.InheritableProperties=function(e,t){return{vertices:t.vertices.map(function(t){return GameLib.D3.Vertex.FromObject(e,t)}),faces:t.faces.map(function(t){return GameLib.D3.Face.FromObject(e,t)}),uniqueAxes:t.uniqueAxes.map(function(e){return GameLib.API.Vector3.FromObject(e)}),uniqueEdges:t.uniqueEdges.map(function(e){return GameLib.API.Vector3.FromObject(e)})}},GameLib.D3.Shape.ConvexHull.FromObject=function(e,t){var i=GameLib.D3.API.Shape.FromObject(t),n=GameLib.D3.Shape.ConvexHull.InheritableProperties(e,t);return new GameLib.D3.Shape.ConvexHull.call(this,e,i,n.vertices,n.faces,n.uniqueAxes,n.uniqueEdges)},GameLib.D3.Shape.ConvexHull.Cylinder=function(e,t,i,n,a,s){if(this.physics=e,this.physics.isNotCannonThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={shapeType:GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL_CYLINDER}),t instanceof GameLib.D3.Shape.ConvexHull.Cylinder)return t;GameLib.Utils.UndefinedOrNull(i)&&(i=1),this.radiusTop=i,GameLib.Utils.UndefinedOrNull(n)&&(n=1),this.radiusBottom=n,GameLib.Utils.UndefinedOrNull(a)&&(a=n/2),this.height=a,GameLib.Utils.UndefinedOrNull(s)&&(s=20),this.numSegments=s,GameLib.D3.Shape.ConvexHull.call(this,this.physics,t)},GameLib.D3.Shape.ConvexHull.Cylinder.prototype=Object.create(GameLib.D3.Shape.ConvexHull.prototype),GameLib.D3.Shape.ConvexHull.Cylinder.prototype.constructor=GameLib.D3.Shape.ConvexHull.Cylinder,GameLib.D3.Shape.ConvexHull.Cylinder.prototype.createInstance=function(){this.instance=new CANNON.Cylinder(this.radiusTop,this.radiusBottom,this.height,this.numSegments),GameLib.D3.Shape.prototype.createInstance.call(this)},GameLib.D3.Shape.ConvexHull.Cylinder.prototype.updateInstance=function(){console.log("todo : update cylinder instance")},GameLib.D3.Shape.ConvexHull.Cylinder.prototype.setFromMesh=function(){this.radiusTop=this.parentMesh.dimensions.x/2,this.radiusBottom=this.parentMesh.dimensions.x/2,this.height=this.parentMesh.dimensions.z},GameLib.D3.Shape.ConvexHull.Cylinder.prototype.toApiObject=function(){var e=GameLib.D3.Shape.ConvexHull.prototype.toApiObject.call(this);return e.radiusTop=this.radiusTop,e.radiusBottom=this.radiusBottom,e.height=this.height,e.numSegments=this.numSegments,e},GameLib.D3.Shape.ConvexHull.Cylinder.FromObject=function(e,t){var i=GameLib.D3.API.Shape.FromObject(t),n=GameLib.D3.Shape.ConvexHull.InheritableProperties(e,t);for(var a in n)n.hasOwnProperty(a)&&(i[a]=n[a]);return new GameLib.D3.Shape.ConvexHull.Cylinder(e,i,t.radiusTop,t.radiusBottom,t.height,t.numSegments)},GameLib.D3.Shape.HeightMap=function(e,t,i,n,a,s){if(this.physics=e,this.physics.isNotCannonThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={shapeType:GameLib.D3.API.Shape.SHAPE_TYPE_HEIGHT_MAP}),t instanceof GameLib.D3.Shape.HeightMap)return t;GameLib.Utils.UndefinedOrNull(i)&&(i=[[10,10,10],[10,10,10],[10,10,10]]),this.heightData=i,GameLib.Utils.UndefinedOrNull(n)&&(n=0),this.minValue=n,GameLib.Utils.UndefinedOrNull(a)&&(a=10),this.maxValue=a,GameLib.Utils.UndefinedOrNull(s)&&(s=1),this.elementSize=s,GameLib.D3.Shape.call(this,this.physics,t)},GameLib.D3.Shape.HeightMap.prototype=Object.create(GameLib.D3.Shape.prototype),GameLib.D3.Shape.HeightMap.prototype.constructor=GameLib.D3.Shape.HeightMap,GameLib.D3.Shape.HeightMap.prototype.createInstance=function(){this.instance=new CANNON.Heightfield(this.heightData,{elemSize:this.elementSize}),GameLib.D3.Shape.prototype.createInstance.call(this)},GameLib.D3.Shape.HeightMap.prototype.updateInstance=function(){this.instance.data=this.heightData,this.instance.elemSize=this.elemSize,this.instance.update()},GameLib.D3.Shape.HeightMap.prototype.toApiObject=function(){var e=GameLib.D3.Shape.prototype.toApiObject.call(this);return e.heightData=this.heightData,e.minValue=this.minValue,e.maxValue=this.maxValue,e.elemSize=this.elemSize,e},GameLib.D3.Shape.HeightMap.prototype.setFromMesh=function(){if(null===this.parentMesh)return void console.log("select a mesh first");if(!this.parentMesh.isHeightMap)return void console.log("not a heightmap mesh");var e=Array.prototype.slice.call(this.parentMesh.getHeightData());this.heightData=[];for(var t=0;t<=this.parentMesh.widthSegments;t++){this.heightData[t]=[];for(var i=0;i<=this.parentMesh.heightSegments;i++)this.heightData[t][i]=e[t*(this.parentMesh.widthSegments+1)+i]}this.updateInstance()},GameLib.D3.Shape.HeightMap.FromObject=function(e,t){var i=GameLib.D3.API.Shape.FromObject(t);return new GameLib.D3.Shape.HeightMap(e,i,t.heightData,t.minValue,t.maxValue,t.elemSize)},GameLib.D3.Shape.Plane=function(e,t){if(this.physics=e,this.physics.isNotCannonThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={shapeType:GameLib.D3.API.Shape.SHAPE_TYPE_PLANE}),t instanceof GameLib.D3.Shape.Plane)return t;GameLib.D3.Shape.call(this,this.physics,t)},GameLib.D3.Shape.Plane.prototype=Object.create(GameLib.D3.Shape.prototype),GameLib.D3.Shape.Plane.prototype.constructor=GameLib.D3.Shape.Plane,GameLib.D3.Shape.Plane.prototype.createInstance=function(){this.instance=new CANNON.Plane,GameLib.D3.Shape.prototype.createInstance.call(this)},GameLib.D3.Shape.Plane.prototype.updateInstance=function(){},GameLib.D3.Shape.Plane.FromObject=function(e,t){var i=GameLib.D3.API.Shape.FromObject(t);return new GameLib.D3.Shape.Plane(e,i)},GameLib.D3.Shape.Sphere=function(e,t,i){if(this.physics=e,this.physics.isNotCannonThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={shapeType:GameLib.D3.API.Shape.SHAPE_TYPE_SPHERE}),t instanceof GameLib.D3.Shape.Sphere)return t -;GameLib.Utils.UndefinedOrNull(i)&&(i=1),this.radius=i,GameLib.D3.Shape.call(this,this.physics,t)},GameLib.D3.Shape.Sphere.prototype=Object.create(GameLib.D3.Shape.prototype),GameLib.D3.Shape.Sphere.prototype.constructor=GameLib.D3.Shape.Sphere,GameLib.D3.Shape.Sphere.prototype.createInstance=function(){this.instance=new CANNON.Sphere(this.radius),GameLib.D3.Shape.prototype.createInstance.call(this)},GameLib.D3.Shape.Sphere.prototype.updateInstance=function(){this.instance.radius=this.radius,this.instance.updateBoundingSphereRadius()},GameLib.D3.Shape.Sphere.prototype.toApiObject=function(){var e=GameLib.D3.Shape.prototype.toApiObject.call(this);return e.radius=this.radius,e},GameLib.D3.Shape.Sphere.FromObject=function(e,t){var i=GameLib.D3.API.Shape.FromObject(t);return new GameLib.D3.Shape.Sphere(e,i,t.radius)},GameLib.D3.Shape.TriMesh=function(e,t,i,n){if(this.physics=e,this.physics.isNotCannonThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={shapeType:GameLib.D3.API.Shape.SHAPE_TYPE_TRIMESH}),t instanceof GameLib.D3.Shape.TriMesh)return t;GameLib.Utils.UndefinedOrNull(i)&&(i=[]),this.vertices=i,GameLib.Utils.UndefinedOrNull(n)&&(n=[]),this.indices=n,GameLib.D3.Shape.call(this,this.physics,t)},GameLib.D3.Shape.TriMesh.prototype=Object.create(GameLib.D3.Shape.prototype),GameLib.D3.Shape.TriMesh.prototype.constructor=GameLib.D3.Shape.TriMesh,GameLib.D3.Shape.TriMesh.prototype.createInstance=function(){this.instance=new CANNON.TriMesh(this.vertices,this.indices),GameLib.D3.Shape.prototype.createInstance.call(this)},GameLib.D3.Shape.TriMesh.prototype.updateInstance=function(){this.instance.vertices=this.vertices,this.instance.indices=this.indices,this.instance.updateAABB(),this.instance.updateBoundingSphereRadius(),this.instance.updateEdges(),this.instance.updateNormals(),this.instance.updateTree()},GameLib.D3.Skeleton=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Skeleton)return t;GameLib.D3.API.Skeleton.call(this,t.id,t.name,t.bones,t.boneInverses,t.useVertexTexture,t.boneTextureWidth,t.boneTextureHeight,t.boneMatrices,t.boneTexture,t.parentEntity),this.bones=this.bones.map(function(e){if(e instanceof GameLib.D3.API.Bone)return new GameLib.D3.Bone(this.graphics,e);throw console.warn("apiBone not an instance of API.Bone"),new Error("apiBone not an instance of API.Bone")}.bind(this)),this.boneInverses=this.boneInverses.map(function(e){if(e instanceof GameLib.API.Matrix4)return new GameLib.Matrix4(this.graphics,e,this);throw console.warn("boneInverse not an instance of API.Matrix4"),new Error("boneInverse not an instance of API.Matrix4")}.bind(this)),this.boneMatrices=this.boneMatrices.map(function(e){if(e instanceof GameLib.API.Matrix4)return new GameLib.Matrix4(this.graphics,e,this);throw console.warn("boneMatrices not an instance of API.Matrix4"),new Error("boneMatrices not an instance of API.Matrix4")}.bind(this)),GameLib.Component.call(this,{bones:[GameLib.D3.Bone]})},GameLib.D3.Skeleton.prototype=Object.create(GameLib.D3.API.Skeleton.prototype),GameLib.D3.Skeleton.prototype.constructor=GameLib.D3.Skeleton,GameLib.D3.Skeleton.prototype.createInstance=function(e){var t=this.bones.map(function(e){if(GameLib.Utils.UndefinedOrNull(e))throw new Error("no bone");if(GameLib.Utils.UndefinedOrNull(e.instance))throw new Error("no bone instance");return e.instance}),i=this.bones.reduce(function(e,t){return e||(0===t.parentBoneIds.length?t.instance:null)},null);if(GameLib.Utils.UndefinedOrNull(i))throw new Error("could not find parent bone instance");this.instance=new THREE.Skeleton(t),this.rootBoneInstance=i,this.instance.useVertexTexture=this.useVertexTexture,this.boneIdToBone={},this.bones.map(function(e){this.boneIdToBone[e.id]=e}.bind(this)),this.bones.map(function(e){return function(t){t.childBoneIds.map(function(t){e.add(this.boneIdToBone[t].instance)}.bind(this))}}(i).bind(this)),this.instance.update(),this.instance.calculateInverses(),GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Skeleton.prototype.updateInstance=function(){},GameLib.D3.Skeleton.prototype.toApiObject=function(){return new GameLib.D3.API.Skeleton(this.id,this.name,this.bones.map(function(e){return e.toApiObject()}),this.boneInverses.map(function(e){return e.toApiObject()}),this.useVertexTexture,this.boneTextureWidth,this.boneTextureHeight,this.boneMatrices.map(function(e){return e.toApiObject()}),this.boneTexture,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Skeleton.FromObject=function(e,t){if(!t)return null;var i=GameLib.D3.API.Skeleton.FromObject(t);return new GameLib.D3.Skeleton(e,i)},GameLib.D3.Solver=function(e,t){if(this.physics=e,this.physics.isNotCannonThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Solver)return t;GameLib.D3.API.Solver.call(this,t.id,t.name,t.solverType,t.iterations,t.tolerance,t.parentEntity),GameLib.Component.call(this)},GameLib.D3.Solver.prototype=Object.create(GameLib.D3.API.Solver.prototype),GameLib.D3.Solver.prototype.constructor=GameLib.D3.Solver,GameLib.D3.Solver.prototype.createInstance=function(){if(this.solverType===GameLib.D3.API.Solver.GS_SOLVER)this.instance=new CANNON.GSSolver;else{if(this.solverType!==GameLib.D3.API.Solver.SPLIT_SOLVER)throw new Error("unsupported solver type: "+this.solverType);this.instance=new CANNON.SplitSolver}this.instance.tolerance=this.tolerance,this.instance.iterations=this.iterations,GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Solver.prototype.updateInstance=function(){this.solverType===GameLib.D3.API.Solver.GS_SOLVER&&(this.instance instanceof CANNON.GSSolver||(this.instance=new CANNON.GSSolver)),this.solverType===GameLib.D3.API.Solver.SPLIT_SOLVER&&(this.instance instanceof CANNON.SplitSolver||(this.instance=new CANNON.SplitSolver)),this.instance.iterations=this.iterations,this.instance.tolerance=this.tolerance},GameLib.D3.Solver.prototype.toApiObject=function(){return new GameLib.D3.API.Solver(this.id,this.name,this.solverType,this.iterations,this.tolerance,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Solver.FromObject=function(e,t){var i=GameLib.D3.API.Solver.FromObject(t);return new GameLib.D3.Solver(e,i)},GameLib.D3.Spline=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Spline)return t;GameLib.D3.API.Spline.call(this,t.id,t.name,t.vertices,t.parentEntity),this.vertices=this.vertices.map(function(t){return new GameLib.Vector3(e,t,this)}),GameLib.Component.call(this)},GameLib.D3.Spline.prototype=Object.create(GameLib.D3.API.Spline.prototype),GameLib.D3.Spline.prototype.constructor=GameLib.D3.Spline,GameLib.D3.Spline.prototype.createInstance=function(){var e=this.vertices.map(function(e){if(GameLib.Utils.UndefinedOrNull(e))throw new Error("no vertex");if(GameLib.Utils.UndefinedOrNull(e.instance))throw new Error("no vertex instance");return e.instance});this.instance=THREE.CatmullRomCurve3(e),GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Spline.prototype.updateInstance=function(){var e=this.vertices.map(function(e){if(GameLib.Utils.UndefinedOrNull(e))throw new Error("no vertex");if(GameLib.Utils.UndefinedOrNull(e.instance))throw new Error("no vertex instance");return e.instance});this.instance=new THREE.CatmullRomCurve3(e)},GameLib.D3.Spline.prototype.toApiObject=function(){return new GameLib.D3.API.Spline(this.id,this.name,this.vertices.map(function(e){return e.toApiObject()}),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Spline.FromObject=function(e,t){var i=GameLib.D3.API.Spline.FromObject(t);return new GameLib.D3.Spline(e,i)},GameLib.D3.Spline.prototype.getPointAt=function(e){var t=this.instance.getPointAt(e);return new GameLib.Vector3(this.graphics,new GameLib.API.Vector3(t.x,t.y,t.z),this,.1)},GameLib.D3.Texture=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Texture)return t;GameLib.D3.API.Texture.call(this,t.id,t.textureType,t.name,t.image,t.images,t.wrapS,t.wrapT,t.repeat,t.data,t.format,t.mapping,t.magFilter,t.minFilter,t.storageType,t.anisotropy,t.offset,t.generateMipmaps,t.flipY,t.mipmaps,t.unpackAlignment,t.premultiplyAlpha,t.encoding,t.canvas,t.animated,t.reverseAnimation,t.forward,t.parentEntity),this.offset=new GameLib.Vector2(this.graphics,this.offset,this),this.repeat=new GameLib.Vector2(this.graphics,this.repeat,this),this.image instanceof GameLib.API.Image&&(this.image=new GameLib.Image(this.graphics,this.image)),this.images=this.images.map(function(e){return e instanceof GameLib.API.Image?new GameLib.Image(this.graphics,e):e}.bind(this)),this.canvas instanceof GameLib.API.Canvas&&(this.canvas=new GameLib.Canvas(this.graphics,this.canvas)),GameLib.Component.call(this,{image:GameLib.Image,images:[GameLib.Image],canvas:GameLib.Canvas})},GameLib.D3.Texture.prototype=Object.create(GameLib.D3.API.Texture.prototype),GameLib.D3.Texture.prototype.constructor=GameLib.D3.Texture,GameLib.D3.Texture.prototype.createInstance=function(){if(this.textureType===GameLib.D3.API.Texture.TEXTURE_TYPE_CUBE){if(6!==this.images.length)throw new Error("not enough images for cube texture");var e=this.images.map(function(e){if(GameLib.Utils.UndefinedOrNull(e))throw new Error("no image");if(GameLib.Utils.UndefinedOrNull(e.instance))throw new Error("no image instance");return e.instance});this.instance=new THREE.CubeTexture(e)}else if(this.textureType===GameLib.D3.API.Texture.TEXTURE_TYPE_NORMAL)GameLib.Utils.UndefinedOrNull(this.image)||GameLib.Utils.UndefinedOrNull(this.image.instance)?this.instance=new THREE.Texture:this.instance=new THREE.Texture(this.image.instance);else if(this.textureType===GameLib.D3.API.Texture.TEXTURE_TYPE_CANVAS)if(GameLib.Utils.UndefinedOrNull(this.canvas))this.instance=new THREE.Texture;else{if(GameLib.Utils.UndefinedOrNull(this.canvas.instance))throw new Error("no canvas instance");this.instance=new THREE.Texture(this.canvas.instance)}this.mapping=this.instance.mapping,this.encoding=this.instance.encoding,this.format=this.instance.format,this.instance.name=this.name,this.instance.flipY=this.flipY,this.instance.offset.x=this.offset.x,this.instance.offset.y=this.offset.y,this.instance.repeat.x=this.repeat.x,this.instance.repeat.y=this.repeat.y,this.instance.wrapS=this.wrapS,this.instance.wrapT=this.wrapT,this.instance.needsUpdate=!0,GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Texture.prototype.updateInstance=function(e){if(GameLib.Utils.UndefinedOrNull(this.instance))try{return void this.createInstance()}catch(e){console.error(e)}if(GameLib.Utils.UndefinedOrNull(e))throw new Error("need to specify a property");if("image"===e){if(this.textureType===GameLib.D3.API.Texture.TEXTURE_TYPE_NORMAL){if(GameLib.Utils.UndefinedOrNull(this.image)&&this.instance.image)try{this.createInstance()}catch(e){console.error(e)}if(this.image&&this.image.instance&&this.instance.image!==this.image.instance)try{this.createInstance()}catch(e){console.error(e)}}else if(this.textureType===GameLib.D3.API.Texture.TEXTURE_TYPE_CANVAS){if(GameLib.Utils.UndefinedOrNull(this.canvas)&&this.instance.canvas)try{this.createInstance()}catch(e){console.error(e)}if(this.canvas&&this.canvas.instance&&this.instance.image!==this.canvas.instance)try{this.createInstance()}catch(e){console.error(e)}}else this.textureType===GameLib.D3.API.Texture.TEXTURE_TYPE_CUBE&&console.log("todo : cube images change check here");this.publish(GameLib.Event.IMAGE_CHANGED,{texture:this}),this.instance.needsUpdate=!0}"name"===e&&(this.instance.name=this.name),"flipY"===e&&(this.instance.flipY=this.flipY),"encoding"===e&&(this.instance.encoding=this.encoding),"offset"===e&&(this.instance.offset.x=this.offset.x,this.instance.offset.y=this.offset.y),"repeat"===e&&(this.instance.repeat.x=this.repeat.x,this.instance.repeat.y=this.repeat.y),"mapping"===e&&(this.instance.mapping=this.mapping),"format"===e&&(this.instance.format=this.format),"wrapS"===e&&(this.instance.wrapS=this.wrapS,this.instance.needsUpdate=!0),"wrapT"===e&&(this.instance.wrapT=this.wrapT,this.instance.needsUpdate=!0),"animated"===e&&GameLib.Event.Emit(GameLib.Event.TEXTURE_ANIMATED_CHANGE,{texture:this})},GameLib.D3.Texture.prototype.toApiObject=function(){return new GameLib.D3.API.Texture(this.id,this.textureType,this.name,GameLib.Utils.IdOrNull(this.image),this.images.map(function(e){return GameLib.Utils.IdOrNull(e)}),this.wrapS,this.wrapT,this.repeat.toApiObject(),this.data,this.format,this.mapping,this.magFilter,this.minFilter,this.storageType,this.anisotropy,this.offset.toApiObject(),this.generateMipmaps,this.flipY,this.mipmaps,this.unpackAlignment,this.premultiplyAlpha,this.encoding,GameLib.Utils.IdOrNull(this.canvas),this.animated,this.reverseAnimation,this.forward,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Texture.FromObject=function(e,t){var i=GameLib.D3.API.Texture.FromObject(t);return new GameLib.D3.Texture(e,i)},GameLib.D3.TriangleEdge=function(e,t){this.triangle=e,this.edge=t},GameLib.D3.Vertex=function(e,t){if(this.implementation=e,e instanceof GameLib.GraphicsRuntime)this.implementation.isNotThreeThrow();else{if(!(e instanceof GameLib.PhysicsRuntime))throw new Error("Unhandled implementation : "+e);this.implementation.isNotCannonThrow()}if(GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Vertex)return t;GameLib.D3.API.Vertex.call(this,t.position,t.boneWeights),this.position=new GameLib.Vector3(this.implementation,this.position,null),e instanceof GameLib.GraphicsRuntime&&(this.boneWeights=this.boneWeights.map(function(e){return new GameLib.D3.BoneWeight(this.implementation,e)}.bind(this)))},GameLib.D3.Vertex.prototype=Object.create(GameLib.D3.API.Vertex.prototype),GameLib.D3.Vertex.prototype.constructor=GameLib.D3.Vertex,GameLib.D3.Vertex.prototype.toApiObject=function(){return new GameLib.D3.API.Vertex(this.position.toApiObject(),this.boneWeights.map(function(e){return e.toApiObject()}))},GameLib.D3.Vertex.FromObject=function(e,t){var i=GameLib.D3.API.Vertex.FromObject(t);return new GameLib.D3.Vertex(e,i)},GameLib.D3.Viewport=function(e,t){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.D3.Viewport)return t;GameLib.D3.API.Viewport.call(this,t.id,t.name,t.width,t.height,t.x,t.y,t.parentEntity),GameLib.Component.call(this)},GameLib.D3.Viewport.prototype=Object.create(GameLib.D3.API.Viewport.prototype),GameLib.D3.Viewport.prototype.constructor=GameLib.D3.Viewport,GameLib.D3.Viewport.prototype.createInstance=function(){this.instance=!0,GameLib.Component.prototype.createInstance.call(this)},GameLib.D3.Viewport.prototype.updateInstance=function(){},GameLib.D3.Viewport.prototype.toApiObject=function(){return new GameLib.D3.API.Viewport(this.id,this.name,this.width,this.height,this.x,this.y,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.D3.Viewport.FromObject=function(e,t){var i=GameLib.D3.API.Viewport.FromObject(t);return new GameLib.D3.Viewport(e,i)},GameLib.DomElement=function(e){if(GameLib.Utils.UndefinedOrNull(e)&&(e={}),e instanceof GameLib.DomElement)return e;GameLib.API.DomElement.call(this,e.id,e.name,e.domElementId,e.parentEntity),this.fullscreen=!1,GameLib.Component.call(this)},GameLib.DomElement.prototype=Object.create(GameLib.API.DomElement.prototype),GameLib.DomElement.prototype.constructor=GameLib.DomElement,GameLib.DomElement.prototype.createInstance=function(){this.instance=document.getElementById(this.domElementId),GameLib.Component.prototype.createInstance.call(this)},GameLib.DomElement.prototype.updateInstance=function(){this.instance=document.getElementById(this.domElementId)},GameLib.DomElement.prototype.toApiObject=function(){return new GameLib.API.DomElement(this.id,this.name,this.domElementId,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.DomElement.prototype.append=function(e){this.instance.appendChild(e)},GameLib.DomElement.prototype.clear=function(){this.instance.innerHTML=""},GameLib.DomElement.prototype.requestFullscreen=function(e){var t=document.documentElement;t.requestFullscreen?t.requestFullscreen():t.msRequestFullscreen?t.msRequestFullscreen():t.mozRequestFullScreen?t.mozRequestFullScreen():t.webkitRequestFullscreen&&t.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT),this.fullscreen=!0},GameLib.DomElement.prototype.exitFullscreen=function(e){document.exitFullscreen?document.exitFullscreen():document.msExitFullscreen?document.msExitFullscreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitExitFullscreen&&document.webkitExitFullscreen(),this.fullscreen=!1},GameLib.DomElement.FromObject=function(e){var t=GameLib.API.DomElement.FromObject(e);return new GameLib.DomElement(t)};GameLib.EntityManager=function(e){if(GameLib.Utils.UndefinedOrNull(e)&&(e={}),e instanceof GameLib.EntityManager)return e;GameLib.API.EntityManager.call(this,e.id,e.name,e.entities,e.defaultEntity,e.defaultRenderer,e.parentEntity),this.register={},this.idRegister={},GameLib.Event.Subscribe(GameLib.Event.COMPONENT_REGISTER,this.registerComponent.bind(this)),GameLib.Event.Subscribe(GameLib.Event.REMOVE_COMPONENT,this.removeComponent.bind(this)),GameLib.Component.call(this,{entities:[GameLib.Entity],defaultEntity:GameLib.Entity,defaultRenderer:GameLib.D3.Renderer})},GameLib.EntityManager.prototype=Object.create(GameLib.API.EntityManager.prototype),GameLib.EntityManager.prototype.constructor=GameLib.EntityManager,GameLib.EntityManager.prototype.createInstance=function(){this.instance=GameLib.EntityManager.Instance,GameLib.Component.prototype.createInstance.call(this)},GameLib.EntityManager.prototype.registerComponent=function(e){var t=!1;GameLib.Utils.UndefinedOrNull(this.register[e.component.componentType])&&(this.register[e.component.componentType]={},GameLib.Event.Emit(GameLib.Event.COMPONENT_TYPES_UPDATE,{componentType:e.component.componentType,componentTypes:Object.keys(this.register)}),t=!0),GameLib.Utils.UndefinedOrNull(this.register[e.component.componentType][e.component.id])&&(this.register[e.component.componentType][e.component.id]=e.component,t=!0),GameLib.Utils.UndefinedOrNull(this.idRegister[e.component.id])&&(this.idRegister[e.component.id]=e.component,t=!0),t&&GameLib.Event.Emit(GameLib.Event.REGISTER_UPDATE,{componentType:e.component.componentType,components:this.register[e.component.componentType],idRegister:this.idRegister,register:this.register})},GameLib.EntityManager.prototype.removeComponent=function(e){var t=!0;GameLib.Utils.UndefinedOrNull(this.register[e.component.componentType])||GameLib.Utils.UndefinedOrNull(this.register[e.component.componentType][e.component.id])||GameLib.Utils.UndefinedOrNull(this.idRegister[e.component.id])?(console.warn("register out of sync"),t=!1):(delete this.register[e.component.componentType][e.component.id],GameLib.Utils.IsEmpty(this.register[e.component.componentType])&&(delete this.register[e.component.componentType],GameLib.Event.Emit(GameLib.Event.COMPONENT_TYPES_UPDATE,{componentType:e.component.componentType,componentTypes:Object.keys(this.register)})),delete this.idRegister[e.component.id]),t&&GameLib.Event.Emit(GameLib.Event.REGISTER_UPDATE,{componentType:e.component.componentType,components:this.register[e.component.componentType],idRegister:this.idRegister,register:this.register})},GameLib.EntityManager.prototype.createEntity=function(e){var t=new GameLib.API.Entity(null,e,null,null,this),i=new GameLib.Entity(t);return this.entities.push(i),this.defaultEntity=i,GameLib.Event.Emit(GameLib.Event.NEW_ENTITY,{entity:i}),i},GameLib.EntityManager.prototype.findEntityById=function(e){var t=this.register[GameLib.Component.ENTITY][e];return t||null},GameLib.EntityManager.prototype.findComponentById=function(e){return this.idRegister[e]},GameLib.EntityManager.prototype.findComponentByName=function(e){return Object.keys(this.idRegister).reduce(function(t,i){return this.idRegister[i].name===e&&(t=this.idRegister[i]),t}.bind(this),null)},GameLib.EntityManager.prototype.findHelperByObject=function(e){return void 0===this.register[GameLib.Component.HELPER]?null:Object.keys(this.register[GameLib.Component.HELPER]).reduce(function(t,i){return this.register[GameLib.Component.HELPER][i].object===e&&(t=this.register[GameLib.Component.HELPER][i]),t}.bind(this),null)},GameLib.EntityManager.prototype.findSceneByObject=function(e){return Object.keys(this.register[GameLib.Component.SCENE]).reduce(function(t,i){return-1===this.register[GameLib.Component.SCENE][i].meshes.indexOf(e)&&-1===this.register[GameLib.Component.SCENE][i].lights.indexOf(e)||(t=this.register[GameLib.Component.SCENE][i]),t}.bind(this),null)},GameLib.EntityManager.prototype.addEntity=function(e){e.parentEntityManager=this,this.entities.push(e)},GameLib.EntityManager.prototype.queryByName=function(e){return this.entities.reduce(function(t,i){return i.name===e&&(t=i),t},null)},GameLib.EntityManager.prototype.removeEntity=function(e){var t=this.entities.indexOf(e);return-1===t?(console.log("failed to remove entity : ",e),!1):(this.entities.splice(t,1),e.parentEntityManager=null,!0)},GameLib.EntityManager.prototype.findEntities=function(e){return this.entities.reduce(function(t,i){return e.reduce(function(e,t){return i.hasComponent(t)||(e=!1),e},!0)&&t.push(i),t},[])},GameLib.EntityManager.prototype.queryComponents=function(e){var t=[];if(e instanceof Array)e.map(function(e){void 0!==this.register[e]&&Object.keys(this.register[e]).map(function(i){t.push(this.register[e][i])}.bind(this))}.bind(this));else{if(void 0===this.register[e])return t;Object.keys(this.register[e]).map(function(i){t.push(this.register[e][i])}.bind(this))}return t},GameLib.EntityManager.prototype.queryComponentsByConstructor=function(e){return Object.keys(this.idRegister).reduce(function(t,i){return e instanceof Array?e.map(function(e){this.idRegister[i]instanceof e&&t.push(this.idRegister[i])}.bind(this)):this.idRegister[i]instanceof e&&t.push(this.idRegister[i]),t}.bind(this),[])},GameLib.EntityManager.prototype.toApiObject=function(){var e=this.entities.map(function(e){return GameLib.Utils.IdOrNull(e)});return new GameLib.API.EntityManager(this.id,this.name,e,GameLib.Utils.IdOrNull(this.defaultEntity),GameLib.Utils.IdOrNull(this.defaultRenderer),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.EntityManager.FromObject=function(e){var t=GameLib.API.EntityManager.FromObject(e);return new GameLib.EntityManager(t)},GameLib.Entity=function(e){if(GameLib.Utils.UndefinedOrNull(e)&&(e={}),e instanceof GameLib.Entity)return e;GameLib.API.Entity.call(this,e.id,e.name,e.components,e.parentEntity,e.parentEntityManager),GameLib.Component.call(this,{components:[GameLib.Component],activeComponent:GameLib.Component})},GameLib.Entity.prototype=Object.create(GameLib.API.Entity.prototype),GameLib.Entity.prototype.constructor=GameLib.Entity,GameLib.Entity.prototype.createInstance=function(){this.instance=!0,GameLib.Component.prototype.createInstance.call(this)},GameLib.Entity.prototype.addComponent=function(e){if(GameLib.Utils.PushUnique(this.components,e),e instanceof GameLib.D3.Mesh)e.getChildrenComponents().map(function(e){GameLib.Utils.PushUnique(this.components,e),e.parentEntity=this}.bind(this));else{e.buildIdToObject();for(var t in e.idToObject)e.idToObject.hasOwnProperty(t)&&e.idToObject[t]!==e&&e.idToObject[t]instanceof GameLib.Component&&(GameLib.Utils.PushUnique(this.components,e.idToObject[t]),e.idToObject[t].parentEntity=this)}e.parentEntity=this},GameLib.Entity.prototype.getComponents=function(e){return this.components.reduce(function(t,i){return i instanceof e&&t.push(i),t},[])},GameLib.Entity.prototype.getFirstComponent=function(e){var t=this.getComponents(e);return t.length>0?t[0]:null},GameLib.Entity.prototype.hasComponent=function(e){return this.components.reduce(function(t,i){return i instanceof e&&(t=!0),t},!1)},GameLib.Entity.prototype.removeComponent=function(e){GameLib.Utils.UndefinedOrNull(e)&&(e=this.activeComponent);var t=this.components.indexOf(e);return-1!==t?this.components.splice(t,1):console.error("component not found"),e.parentEntity=null,!0},GameLib.Entity.prototype.updateInstance=function(){console.log("entity update instance called")},GameLib.Entity.prototype.toApiObject=function(){var e=this.components.map(function(e){return GameLib.Utils.IdOrNull(e)});return new GameLib.API.Entity(this.id,this.name,e,GameLib.Utils.IdOrNull(this.parentEntity),GameLib.Utils.IdOrNull(this.parentEntityManager))},GameLib.Entity.FromObject=function(e,t){var i=GameLib.API.Entity.FromObject(e),n=new GameLib.Entity(i);return GameLib.Utils.UndefinedOrNull(t)?n:(t.addEntity(n),n)},GameLib.GraphicsRuntime=function(e,t,i){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Graphics ("+e+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=GameLib.GraphicsRuntime.TYPE_THREE_JS),this.graphicsType=i,this.createInstance()},GameLib.GraphicsRuntime.TYPE_THREE_JS=1,GameLib.GraphicsRuntime.prototype.createInstance=function(){this.graphicsType===GameLib.GraphicsRuntime.TYPE_THREE_JS?this.instance=THREE:this.instance=null},GameLib.GraphicsRuntime.prototype.updateInstance=function(e){"graphicsType"===e&&this.createInstance()},GameLib.GraphicsRuntime.prototype.isNotThreeThrow=function(){if(this.instance!==THREE)throw console.error("Only THREE supported"),new Error("Only THREE supported")},GameLib.GUIRuntime=function(e,t,i){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="GUI ("+e+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=GameLib.GUIRuntime.TYPE_DAT_GUI),this.guiType=i,this.createInstance()},GameLib.GUIRuntime.TYPE_DAT_GUI=1,GameLib.GUIRuntime.prototype.createInstance=function(){this.guiType===GameLib.GUIRuntime.TYPE_DAT_GUI?this.instance=dat.GUI:this.instance=null},GameLib.GUIRuntime.prototype.updateInstance=function(e){"guiType"===e&&this.createInstance()},GameLib.GUIRuntime.prototype.isNotDatGuiThrow=function(){if(this.instance!==dat.GUI)throw console.error("Only dat.gui supported"),new Error("Only dat.gui supported")},GameLib.GUI=function(e,t){if(this.guiRuntime=e,this.guiRuntime.isNotDatGuiThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.GUI)return t;GameLib.API.GUI.call(this,t.id,t.name,t.domElement,t.parentEntity),GameLib.Component.call(this,{domElement:GameLib.DomElement})},GameLib.GUI.prototype=Object.create(GameLib.Component.prototype),GameLib.GUI.prototype.constructor=GameLib.GUI,GameLib.GUI.prototype.createInstance=function(){this.instance=new this.guiRuntime.instance({autoPlace:!1}),GameLib.Component.prototype.createInstance.call(this)},GameLib.GUI.prototype.updateInstance=function(e){console.log("todo: implement gui update instance:"+e)},GameLib.GUI.prototype.toApiObject=function(){return new GameLib.API.GUI(this.id,this.name,GameLib.Utils.IdOrNull(this.domElement),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.GUI.FromObject=function(e,t){var i=GameLib.API.GUI.FromObject(t);return new GameLib.GUI(e,i)},GameLib.GUI.prototype.removeEmtpyFolders=function(){this.instance.removeEmptyFolders()},GameLib.GUI.prototype.removeAllFolders=function(){this.instance.removeAllFolders()},GameLib.GUI.prototype.addFolder=function(e){try{return this.instance.addFolder(e)}catch(t){try{return e+=" duplicate ("+GameLib.Utils.RandomId()+")",this.instance.addFolder(e)}catch(e){return console.log(e.message),null}}},GameLib.Image=function(e){if(GameLib.Utils.UndefinedOrNull(e)&&(e={}),e instanceof GameLib.Image)return e;GameLib.API.Image.call(this,e.id,e.name,e.fileName,e.extension,e.path,e.contentType,e.size,e.parentEntity),GameLib.Component.call(this)},GameLib.Image.prototype=Object.create(GameLib.API.Image.prototype),GameLib.Image.prototype.constructor=GameLib.Image,GameLib.Image.prototype.createInstance=function(){GameLib.Event.Emit(GameLib.Event.LOAD_IMAGE,{image:this},function(e){this.instance=e,GameLib.Component.prototype.createInstance.call(this)}.bind(this),function(e){console.error(e),this.instance=null,GameLib.Component.prototype.createInstance.call(this)}.bind(this))},GameLib.Image.prototype.updateInstance=function(e){GameLib.Utils.UndefinedOrNull(e)&&console.warn("unknown property update for Image: "+e),"fileName"!==e&&"extension"!==e&&"path"!==e||this.createInstance()},GameLib.Image.prototype.updateFromRawObject=function(e){this.id=e.id,this.name=e.name,this.fileName=e.fileName,this.extension=e.extension,this.path=e.path,this.contentType=e.contentType,this.size=e.size},GameLib.Image.prototype.toApiObject=function(){return new GameLib.API.Image(this.id,this.name,this.fileName,this.extension,this.path,this.contentType,this.size,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.Image.FromObject=function(e){return new GameLib.Image(GameLib.API.Image.FromObject(e))},GameLib.Matrix4=function(e,t,i,n){if(this.graphics=e,this.graphics.isNotThreeThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.Matrix4)return t;GameLib.API.Matrix4.call(this,t.rows[0],t.rows[1],t.rows[2],t.rows[3]),GameLib.Utils.UndefinedOrNull(i)&&(i=null),this.parentObject=i,GameLib.Utils.UndefinedOrNull(n)&&(n=.001),this.grain=n,this.rows=this.rows.map(function(e){if(e instanceof GameLib.API.Vector4)return new GameLib.Vector4(this.graphics,e,this,this.grain);throw console.warn("Attempted conversion of wrong instance"),new Error("Attempted conversion of wrong instance")}.bind(this)),this.forward=new GameLib.Vector4(this.graphics,this.forward,this,this.grain),this.left=new GameLib.Vector4(this.graphics,this.left,this,this.grain),this.up=new GameLib.Vector4(this.graphics,this.up,this,this.grain),this.createInstance()},GameLib.Matrix4.prototype=Object.create(GameLib.API.Matrix4.prototype),GameLib.Matrix4.prototype.constructor=GameLib.Matrix4,GameLib.Matrix4.prototype.createInstance=function(e){this.instance=new THREE.Matrix4,this.instance.set(this.rows[0].x,this.rows[1].x,this.rows[2].x,this.rows[3].x,this.rows[0].y,this.rows[1].y,this.rows[2].y,this.rows[3].y,this.rows[0].z,this.rows[1].z,this.rows[2].z,this.rows[3].z,this.rows[0].w,this.rows[1].w,this.rows[2].w,this.rows[3].w)},GameLib.Matrix4.prototype.updateInstance=function(){this.instance.set(this.rows[0].x,this.rows[1].x,this.rows[2].x,this.rows[3].x,this.rows[0].y,this.rows[1].y,this.rows[2].y,this.rows[3].y,this.rows[0].z,this.rows[1].z,this.rows[2].z,this.rows[3].z,this.rows[0].w,this.rows[1].w,this.rows[2].w,this.rows[3].w),this.parentObject&&this.parentObject.updateInstance&&this.parentObject.updateInstance()},GameLib.Matrix4.prototype.toApiObject=function(){return new GameLib.API.Matrix4(this.rows[0].toApiObject(),this.rows[1].toApiObject(),this.rows[2].toApiObject(),this.rows[3].toApiObject())},GameLib.Matrix4.FromObject=function(e,t,i){var n=new GameLib.API.Matrix4.FromObject(t);return new GameLib.Matrix4(e,i,n)},GameLib.Matrix4.prototype.lookAt=function(e,t,i){var n=new GameLib.API.Vector3(e.x,e.y,e.z),a=n.subtract(t).normalize();0===a.squared()&&(a.z=1);var s=i.cross(a).normalize();0===s.squared()&&(a.x+=1e-4,s=i.cross(a).normalize());var o=a.cross(s);return this.rows[0].x=s.x,this.rows[0].y=s.y,this.rows[0].z=s.z,this.rows[1].x=o.x,this.rows[1].y=o.y,this.rows[1].z=o.z,this.rows[2].x=a.x,this.rows[2].y=a.y,this.rows[2].z=a.z,this.forward.x=a.x,this.forward.y=a.y,this.forward.z=a.z,this.left.x=s.x,this.left.y=s.y,this.left.z=s.z,this.up.x=o.x,this.up.y=o.y,this.up.z=o.z,this.updateInstance(),this},GameLib.Matrix4.prototype.identity=function(){this.rows=[new GameLib.Vector4(this.graphics,new GameLib.API.Vector4(1,0,0,0),this,this.grain),new GameLib.Vector4(this.graphics,new GameLib.API.Vector4(0,1,0,0),this,this.grain),new GameLib.Vector4(this.graphics,new GameLib.API.Vector4(0,0,1,0),this,this.grain),new GameLib.Vector4(this.graphics,new GameLib.API.Vector4(0,0,0,1),this,this.grain)]},GameLib.Matrix4.prototype.transpose=function(){ -return this.temp[0].x=this.rows[0].x,this.temp[0].y=this.rows[1].x,this.temp[0].z=this.rows[2].x,this.temp[0].w=this.rows[3].x,this.temp[1].x=this.rows[0].y,this.temp[1].y=this.rows[1].y,this.temp[1].z=this.rows[2].y,this.temp[1].w=this.rows[3].y,this.temp[2].x=this.rows[0].z,this.temp[2].y=this.rows[1].z,this.temp[2].z=this.rows[2].z,this.temp[2].w=this.rows[3].z,this.temp[3].x=this.rows[0].w,this.temp[3].y=this.rows[1].w,this.temp[3].z=this.rows[2].w,this.temp[3].w=this.rows[3].w,this.rows[0].x=this.temp[0].x,this.rows[0].y=this.temp[0].y,this.rows[0].z=this.temp[0].z,this.rows[0].w=this.temp[0].w,this.rows[1].x=this.temp[1].x,this.rows[1].y=this.temp[1].y,this.rows[1].z=this.temp[1].z,this.rows[1].w=this.temp[1].w,this.rows[2].x=this.temp[2].x,this.rows[2].y=this.temp[2].y,this.rows[2].z=this.temp[2].z,this.rows[2].w=this.temp[2].w,this.rows[3].x=this.temp[3].x,this.rows[3].y=this.temp[3].y,this.rows[3].z=this.temp[3].z,this.rows[3].w=this.temp[3].w,this},GameLib.Mouse=function(e){if(GameLib.Utils.UndefinedOrNull(e)&&(e={}),e instanceof GameLib.Mouse)return e;GameLib.API.Mouse.call(this,e.id,e.name,e.x,e.y,e.parentEntity),GameLib.Component.call(this)},GameLib.Mouse.prototype=Object.create(GameLib.API.Mouse.prototype),GameLib.Mouse.prototype.constructor=GameLib.Mouse,GameLib.Mouse.prototype.createInstance=function(){this.instance=!0,GameLib.Component.prototype.createInstance.call(this)},GameLib.Mouse.prototype.updateInstance=function(e){GameLib.Utils.UndefinedOrNull(e)&&console.warn("unknown property update for Mouse: "+e)},GameLib.Mouse.prototype.toApiObject=function(){return new GameLib.API.Mouse(this.id,this.name,this.x,this.y,this.parentEntity)},GameLib.Mouse.FromObject=function(e){return new GameLib.Mouse(GameLib.API.Mouse.FromObject(e))},GameLib.PhysicsRuntime=function(e,t,i){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Physics ("+e+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=GameLib.PhysicsRuntime.TYPE_CANNON_JS),this.physicsType=i,this.createInstance()},GameLib.PhysicsRuntime.TYPE_CANNON_JS=1,GameLib.PhysicsRuntime.prototype.createInstance=function(){this.physicsType===GameLib.PhysicsRuntime.TYPE_CANNON_JS?this.instance=CANNON:this.instance=null},GameLib.PhysicsRuntime.prototype.updateInstance=function(e){"physicsType"===e&&this.createInstance()},GameLib.PhysicsRuntime.prototype.isNotCannonThrow=function(){if(this.instance!==CANNON)throw console.error("Only CANNON supported"),new Error("Only CANNON supported")},GameLib.Quaternion=function(e,t,i,n){if(this.implementation=e,e instanceof GameLib.GraphicsRuntime)this.physics=null,this.graphics=e,this.graphics.isNotThreeThrow();else{if(!(e instanceof GameLib.PhysicsRuntime))throw new Error("Unhandled implementation : "+e);this.graphics=null,this.physics=e,this.physics.isNotCannonThrow()}if(GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.Quaternion)return t;GameLib.API.Quaternion.call(this,t.x,t.y,t.z,t.w,t.axis,t.angle),GameLib.Utils.UndefinedOrNull(i)&&(i=null),this.parentObject=i,this.axis=new GameLib.Vector3(this.implementation,this.axis,this,this.grain),Object.defineProperty(this,"angle",GameLib.Utils.LimitToPI("angle",this.angle)),GameLib.Utils.UndefinedOrNull(n)&&(n=.001),this.grain=n,this.createInstance()},GameLib.Quaternion.prototype=Object.create(GameLib.API.Quaternion.prototype),GameLib.Quaternion.prototype.constructor=GameLib.Quaternion,GameLib.Quaternion.prototype.createInstance=function(){this.graphics&&(this.instance=new THREE.Quaternion(this.x,this.y,this.z,this.w)),this.physics&&(this.instance=new CANNON.Quaternion(this.x,this.y,this.z,this.w))},GameLib.Quaternion.prototype.updateInstance=function(e){this.instance.x=this.x,this.instance.y=this.y,this.instance.z=this.z,this.instance.w=this.w,this.parentObject&&this.parentObject.updateInstance&&this.parentObject.updateInstance(e)},GameLib.Quaternion.prototype.toApiObject=function(){return new GameLib.API.Quaternion(this.x,this.y,this.z,this.w,this.axis.toApiObject(),this.angle)},GameLib.Quaternion.prototype.equals=function(e){return this.x===e.x&&this.y===e.y&&this.z===e.z&&this.w===e.w&&this.axis.equals(e.axis)&&this.angle===e.angle},GameLib.Quaternion.prototype.setFrom=function(e){this.x=e.x,this.y=e.y,this.z=e.z,this.w=e.w,this.axis.setFrom(e.axis),this.angle=e.angle},GameLib.Quaternion.prototype.copy=function(e){console.log("todo")},GameLib.Server=function(e){if(GameLib.Utils.UndefinedOrNull(e)&&(e={}),e instanceof GameLib.Server)return e;GameLib.API.Server.call(this,e.id,e.name,e.protocol,e.ip,e.port,e.protocols,e.parentEntity),this.connected=!1,GameLib.Component.call(this)},GameLib.Server.prototype=Object.create(GameLib.API.Server.prototype),GameLib.Server.prototype.constructor=GameLib.Server,GameLib.Server.prototype.createInstance=function(){this.instance=!0,GameLib.Component.prototype.createInstance.call(this)},GameLib.Server.prototype.updateInstance=function(e){"protocol"===e&&console.log("todo: server protocol update"),"ip"===e&&console.log("todo: server ip update"),"port"===e&&console.log("todo: server port update"),"protocols"===e&&console.log("todo: server protocols update")},GameLib.Server.prototype.toApiObject=function(){return new GameLib.API.Server(this.id,this.name,this.protocol,this.ip,this.port,this.protocols,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.Server.FromObject=function(e){var t=GameLib.API.Server.FromObject(e);return new GameLib.Server(t)},GameLib.Socket=function(e,t){if(this.socket=e,this.socket.isNotWebSocketThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.Socket)return t;GameLib.API.Socket.call(this,t.id,t.name,t.socketType,t.roomId,t.peerId,t.server,t.parentEntity),this.server instanceof GameLib.API.Server&&(this.server=new GameLib.Server(this.server)),this.connected=!1,GameLib.Component.call(this,{server:GameLib.Server})},GameLib.Socket.prototype=Object.create(GameLib.API.Socket.prototype),GameLib.Socket.prototype.constructor=GameLib.Socket,GameLib.Socket.prototype.createInstance=function(){this.instance=!0,GameLib.Component.prototype.createInstance.call(this)},GameLib.Socket.prototype.updateInstance=function(e){"socketType"===e&&console.log("todo: implement socket socketType update"),"roomId"===e&&console.log("todo: implement socket roomId update"),"peerId"===e&&console.log("todo: implement socket peerId update"),"server"===e&&console.log("todo: implement socket server update")},GameLib.Socket.prototype.toApiObject=function(){return new GameLib.API.Socket(this.id,this.name,this.socketType,this.roomId,this.peerId,GameLib.Utils.IdOrNull(this.server),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.Socket.FromObject=function(e,t){var i=GameLib.API.Socket.FromObject(t);return new GameLib.Socket(e,i)},GameLib.Socket.Cast=function(e,t){if(this.socket=e,this.socket.isNotWebSocketThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={socketType:GameLib.API.Socket.TYPE_CAST}),t instanceof GameLib.Socket.Cast)return t;GameLib.API.Socket.Cast.call(this,t,t.castType,t.source,t.sourceProperties),GameLib.Socket.call(this,e,t),GameLib.Component.call(this,{source:GameLib.Component})},GameLib.Socket.Cast.prototype=Object.create(GameLib.API.Socket.Cast.prototype),GameLib.Socket.Cast.prototype.constructor=GameLib.Socket.Cast,GameLib.Socket.Cast.prototype.createInstance=function(){this.instance=!0,GameLib.Socket.prototype.createInstance.call(this)},GameLib.Socket.Cast.prototype.updateInstance=function(e){GameLib.Socket.prototype.updateInstance.call(this,e),"castType"===e&&console.log("todo: implement socket.receive.castType update"),"source"===e&&(null!==this.source?this.sourceProperties=GameLib.Utils.ObjectPropertiesAsBoolean(this.source):this.sourceProperties={},GameLib.Event.Emit(GameLib.Event.CAST_SOURCE_CHANGED,{component:this})),"sourceProperties"===e&&console.log("todo: implement socket.receive.sourceProperties update")},GameLib.Socket.Cast.prototype.toApiObject=function(){var e=new GameLib.API.Socket(this.id,this.name,this.socketType,this.roomId,this.peerId,GameLib.Utils.IdOrNull(this.server),GameLib.Utils.IdOrNull(this.parentEntity));return new GameLib.API.Socket.Cast(e,this.castType,GameLib.Utils.IdOrNull(this.source),this.sourceProperties)},GameLib.Socket.Cast.FromObject=function(e,t){var i=GameLib.API.Socket.Cast.FromObject(t);return new GameLib.Socket.Cast(e,i)},GameLib.Socket.Receive=function(e,t){if(this.socket=e,this.socket.isNotWebSocketThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={socketType:GameLib.API.Socket.TYPE_RECEIVE}),t instanceof GameLib.Socket.Receive)return t;GameLib.API.Socket.Receive.call(this,t,t.receiveType,t.destination,t.destinationProperties),GameLib.Socket.call(this,e,t),GameLib.Component.call(this,{destination:GameLib.Component})},GameLib.Socket.Receive.prototype=Object.create(GameLib.API.Socket.Receive.prototype),GameLib.Socket.Receive.prototype.constructor=GameLib.Socket.Receive,GameLib.Socket.Receive.prototype.createInstance=function(){this.instance=!0,GameLib.Socket.prototype.createInstance.call(this)},GameLib.Socket.Receive.prototype.updateInstance=function(e){GameLib.Socket.prototype.updateInstance.call(this,e),"receiveType"===e&&console.log("todo: implement socket.receive.receiveType update"),"destination"===e&&(null!==this.destination?this.destinationProperties=GameLib.Utils.ObjectPropertiesAsBoolean(this.destination):this.destinationProperties={},GameLib.Event.Emit(GameLib.Event.RECEIVE_DESTINATION_CHANGED,{component:this})),"destinationProperties"===e&&console.log("todo: implement socket.receive.destinationProperties update")},GameLib.Socket.Receive.prototype.toApiObject=function(){var e=new GameLib.API.Socket(this.id,this.name,this.socketType,this.roomId,this.peerId,GameLib.Utils.IdOrNull(this.server),GameLib.Utils.IdOrNull(this.parentEntity));return new GameLib.API.Socket.Receive(e,this.receiveType,this.destination,this.destinationProperties)},GameLib.Socket.Receive.FromObject=function(e,t){var i=GameLib.API.Socket.Receive.FromObject(t);return new GameLib.Socket.Receive(e,i)},GameLib.SocketsRuntime=function(e,t,i){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Sockets ("+e+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=GameLib.SocketsRuntime.TYPE_WEB_SOCKET),this.socketsType=i,this.connections=[],this.createInstance()},GameLib.SocketsRuntime.TYPE_WEB_SOCKET=1,GameLib.SocketsRuntime.prototype.createInstance=function(){this.socketsType===GameLib.SocketsRuntime.TYPE_WEB_SOCKET?this.instance=WebSocket:this.instance=null},GameLib.SocketsRuntime.prototype.connect=function(e){var t=new WebSocket(e.protocol+"://"+e.ip+":"+e.port,e.protocols);this.connections.push(t)},GameLib.SocketsRuntime.prototype.updateInstance=function(e){"socketsType"===e&&this.createInstance()},GameLib.SocketsRuntime.prototype.isNotWebSocketThrow=function(){if(this.instance!==WebSocket)throw console.error("Only WebSocket supported"),new Error("Only WebSocket supported")},GameLib.StatisticsRuntime=function(e,t,i){GameLib.Utils.UndefinedOrNull(e)&&(e=GameLib.Utils.RandomId()),this.id=e,GameLib.Utils.UndefinedOrNull(t)&&(t="Statistics ("+e+")"),this.name=t,GameLib.Utils.UndefinedOrNull(i)&&(i=GameLib.StatisticsRuntime.TYPE_STATS),this.statisticsType=i,this.createInstance()},GameLib.StatisticsRuntime.TYPE_STATS=1,GameLib.StatisticsRuntime.prototype.createInstance=function(){this.statisticsType===GameLib.StatisticsRuntime.TYPE_STATS?this.instance=Stats:this.instance=null},GameLib.StatisticsRuntime.prototype.updateInstance=function(e){"statisticsType"===e&&this.createInstance()},GameLib.StatisticsRuntime.prototype.isNotStatsThrow=function(){if(this.instance!==Stats)throw console.error("Only stats supported"),new Error("Only stats supported")},GameLib.Stats=function(e,t){if(this.stats=e,this.stats.isNotStatsThrow(),GameLib.Utils.UndefinedOrNull(t)&&(t={}),t instanceof GameLib.Stats)return t;GameLib.API.Stats.call(this,t.id,t.name,t.domElement,t.parentEntity),GameLib.Component.call(this,{domElement:GameLib.DomElement})},GameLib.Stats.prototype=Object.create(GameLib.Component.prototype),GameLib.Stats.prototype.constructor=GameLib.Stats,GameLib.Stats.prototype.createInstance=function(){this.instance=this.stats.instance(),this.resize(),this.domElement.instance.parentElement.appendChild(this.instance.dom),GameLib.Component.prototype.createInstance.call(this)},GameLib.Stats.prototype.updateInstance=function(){this.instance=new this.stats},GameLib.Stats.prototype.toApiObject=function(){return new GameLib.API.Stats(this.id,this.name,GameLib.Utils.IdOrNull(this.domElement),GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.Stats.FromObject=function(e,t){var i=GameLib.API.Stats.FromObject(t);return new GameLib.Stats(e,i)},GameLib.Stats.prototype.resize=function(){console.log("override stats resize per implementation")},GameLib.Stats.prototype.start=function(){this.instance.begin()},GameLib.Stats.prototype.end=function(){this.instance.end()},GameLib.System=function(e){if(GameLib.Utils.UndefinedOrNull(e)&&(e={}),e instanceof GameLib.System)return e;GameLib.API.System.call(this,e.id,e.name,e.systemType,e.parentEntity),this.started=!1,this.paused=!1;var t={};e.systemType===GameLib.System.SYSTEM_TYPE_INPUT&&(t.mouseControls=[GameLib.Controls.Mouse],t.keyboardControls=[GameLib.Controls.Keyboard],t.touchControls=[GameLib.Controls.Touch],t.editorControls=[GameLib.Controls.D3.Editor]),e.systemType===GameLib.System.SYSTEM_TYPE_AUDIO&&(t.audioComponents=[GameLib.D3.Audio]),GameLib.Component.call(this,t)},GameLib.System.prototype=Object.create(GameLib.API.System.prototype),GameLib.System.prototype.constructor=GameLib.System,GameLib.System.SYSTEM_TYPE_NONE=0,GameLib.System.SYSTEM_TYPE_RENDER=1,GameLib.System.SYSTEM_TYPE_ANIMATION=2,GameLib.System.SYSTEM_TYPE_INPUT=4,GameLib.System.SYSTEM_TYPE_STORAGE=8,GameLib.System.SYSTEM_TYPE_GUI=16,GameLib.System.SYSTEM_TYPE_PHYSICS=32,GameLib.System.SYSTEM_TYPE_LINKING=64,GameLib.System.SYSTEM_TYPE_CUSTOM=128,GameLib.System.SYSTEM_TYPE_VISUALIZATION=256,GameLib.System.SYSTEM_TYPE_PARTICLE=512,GameLib.System.SYSTEM_TYPE_AUDIO=1024,GameLib.System.SYSTEM_TYPE_SOCKET=2048,GameLib.System.SYSTEM_TYPE_ALL=65535,GameLib.System.prototype.createInstance=function(){this.instance=!0,GameLib.Component.prototype.createInstance.call(this)},GameLib.System.prototype.start=function(){this.started=!0,console.log("starting "+this.name)},GameLib.System.prototype.stop=function(){this.started=!1,console.log("stopping "+this.name)},GameLib.System.prototype.toApiObject=function(){return new GameLib.API.System(this.id,this.name,this.systemType,GameLib.Utils.IdOrNull(this.parentEntity))},GameLib.System.prototype.restart=function(){console.log("restarting system : "+this.name),this.stop(),this.start()},GameLib.System.Animation=function(e){GameLib.System.call(this,e),this.animations={},this.latest={},this.textures={},this.textureIds=[],this.animationMeshAddedSubscription=null,this.animationMeshRemovedSubscription=null,this.instanceCreatedSubscription=null,this.removeComponentSubscription=null,this.textureAnimatedSubscription=null,this.animateTextureInstanceSubscription=null},GameLib.System.Animation.prototype=Object.create(GameLib.System.prototype),GameLib.System.Animation.prototype.constructor=GameLib.System.Animation,GameLib.System.Animation.prototype.start=function(){GameLib.System.prototype.start.call(this),this.beforeRenderSubscription=GameLib.Event.Subscribe(GameLib.Event.BEFORE_RENDER,this.beforeRender.bind(this)),GameLib.EntityManager.Instance.queryComponents(GameLib.Component.ANIMATION).map(function(e){e.meshes.map(function(t){this.attachAnimation(e,t)}.bind(this)),this.animations[e.id]=e}.bind(this)),this.animationMeshAddedSubscription=GameLib.Event.Subscribe(GameLib.Event.ANIMATION_MESH_ADDED,function(e){this.attachAnimation(e.animation,e.mesh)}.bind(this)),this.animationMeshRemovedSubscription=GameLib.Event.Subscribe(GameLib.Event.ANIMATION_MESH_REMOVED,function(e){this.detachAnimation(e.mesh)}.bind(this)),this.instanceCreatedSubscription=GameLib.Event.Subscribe(GameLib.Event.INSTANCE_CREATED,this.instanceCreated.bind(this)),this.removeComponentSubscription=GameLib.Event.Subscribe(GameLib.Event.REMOVE_COMPONENT,this.removeComponent.bind(this)),this.textureAnimatedSubscription=GameLib.Event.Subscribe(GameLib.Event.TEXTURE_ANIMATED_CHANGE,this.textureAnimatedChange.bind(this)),this.animateTextureInstanceSubscription=GameLib.Event.Subscribe(GameLib.Event.ANIMATE_TEXTURE_INSTANCE,this.animateTextureInstance.bind(this))},GameLib.System.Animation.prototype.instanceCreated=function(e){if(e.component instanceof GameLib.D3.Texture&&e.component.animated){if(e.component.repeat.x>1||e.component.repeat.x<0)return console.warn("cannot animate a texture with repeat.x greater than 1 or less than 0"),void(e.component.animated=!1);if(e.component.repeat.y>1||e.component.repeat.y<0)return console.warn("cannot animate a texture with repeat.y greater than 1 or less than 0"),void(e.component.animated=!1);this.textures[e.component.id]=e.component,this.textureIds=Object.keys(this.textures)}e.component instanceof GameLib.D3.Animation&&(this.animations[e.component.id]=e.component,e.component.meshes.map(function(t){this.attachAnimation(e.component,t)}.bind(this)))},GameLib.System.Animation.prototype.removeComponent=function(e){e.component instanceof GameLib.D3.Texture&&e.component.animated&&(GameLib.Utils.UndefinedOrNull(this.textures[e.component.id])?console.warn("tried to remove an animated texture, which should have been in the list but isnt: "+e.component.name):(delete this.textures[e.component.id],this.textureIds=Object.keys(this.textures))),e.component instanceof GameLib.D3.Animation&&(e.component.meshes.map(function(e){this.detachAnimation(e)}.bind(this)),delete this.animations[e.component.id])},GameLib.System.Animation.prototype.textureAnimatedChange=function(e){if(e.texture.animated){if(e.texture.repeat.x>1||e.texture.repeat.x<0)return console.warn("cannot animate a texture with repeat.x greater than 1 or less than 0"),void(e.texture.animated=!1);if(e.texture.repeat.y>1||e.texture.repeat.y<0)return console.warn("cannot animate a texture with repeat.y greater than 1 or less than 0"),void(e.texture.animated=!1);this.textures[e.texture.id]=e.texture,this.textureIds=Object.keys(this.textures)}else GameLib.Utils.UndefinedOrNull(this.textures[e.texture.id])?console.warn("tried to remove an animated texture, which should have been in the list but isnt: "+e.texture.name):(delete this.textures[e.texture.id],this.textureIds=Object.keys(this.textures))},GameLib.System.Animation.prototype.animateTextureInstance=function(e){return e.texture.repeat.x>1||e.texture.repeat.x<0?(console.warn("cannot animate a texture with repeat.x greater than 1 or less than 0"),void(e.texture.userData.animated=!1)):e.texture.repeat.y>1||e.texture.repeat.y<0?(console.warn("cannot animate a texture with repeat.y greater than 1 or less than 0"),void(e.texture.userData.animated=!1)):(e.texture.userData.animated=!0,this.textures[e.texture.id]=e.texture,void(this.textureIds=Object.keys(this.textures)))},GameLib.System.Animation.prototype.beforeRender=function(e){if(!this.paused){var t=e.delta;for(var i in this.animations)if(this.animations.hasOwnProperty(i)){var n=[];if(this.animations[i].length>0)for(var a=!1,s=0;s=1-t.repeat.x&&(t.offset.y>=1-t.repeat.y?(t.offset.x=1-t.repeat.x,t.offset.y=1-t.repeat.y,t.userData?t.userData.forward=!1:t.forward=!1):(t.offset.x=0,t.offset.y+=t.repeat.y))),(!1===t.forward||t.userData&&!1===t.userData.forward)&&(t.offset.x-=t.repeat.x,t.offset.x<=0&&(t.offset.x=0,t.offset.y=1-t.repeat.x&&(t.offset.y>=1-t.repeat.y?(t.offset.x=0,t.offset.y=0):(t.offset.x=0,t.offset.y+=t.repeat.y))),t.userData||t.updateInstance("offset")}.bind(this))}},GameLib.System.Animation.prototype.detachAnimation=function(e){var t=!1;e.backupQuaternionAngleDescriptor&&(Object.defineProperty(e.quaternion,"angle",e.backupQuaternionAngleDescriptor),delete e.backupQuaternionAngleDescriptor,t=!0),e.backupQuaternionAxisXDescriptor&&(Object.defineProperty(e.quaternion.axis,"x",e.backupQuaternionAxisXDescriptor),delete e.backupQuaternionAxisXDescriptor,t=!0),e.backupQuaternionAxisYDescriptor&&(Object.defineProperty(e.quaternion.axis,"y",e.backupQuaternionAxisYDescriptor),delete e.backupQuaternionAxisYDescriptor,t=!0),e.backupQuaternionAxisZDescriptor&&(Object.defineProperty(e.quaternion.axis,"z",e.backupQuaternionAxisZDescriptor),delete e.backupQuaternionAxisXDescriptor,t=!0),e.backupRotationXDescriptor&&(Object.defineProperty(e.rotation,"x",e.backupRotationXDescriptor),delete e.backupRotationXDescriptor,t=!0),e.backupRotationYDescriptor&&(Object.defineProperty(e.rotation,"y",e.backupRotationYDescriptor),delete e.backupRotationYDescriptor,t=!0),e.backupRotationZDescriptor&&(Object.defineProperty(e.rotation,"z",e.backupRotationZDescriptor),delete e.backupRotationZDescriptor,t=!0),e.backupPositionXDescriptor&&(Object.defineProperty(e.position,"x",e.backupPositionXDescriptor),delete e.backupPositionXDescriptor,t=!0),e.backupPositionYDescriptor&&(Object.defineProperty(e.position,"y",e.backupPositionYDescriptor),delete e.backupPositionYDescriptor,t=!0),e.backupPositionZDescriptor&&(Object.defineProperty(e.position,"z",e.backupPositionZDescriptor),delete e.backupPositionZDescriptor,t=!0),e.backupScaleXDescriptor&&(Object.defineProperty(e.scale,"x",e.backupScaleXDescriptor),delete e.backupScaleXDescriptor,t=!0),e.backupScaleYDescriptor&&(Object.defineProperty(e.scale,"y",e.backupScaleYDescriptor),delete e.backupScaleYDescriptor,t=!0),e.backupScaleZDescriptor&&(Object.defineProperty(e.scale,"z",e.backupScaleZDescriptor),delete e.backupScaleZDescriptor,t=!0),this.latest[e.id]&&(e.rotation.x=this.latest[e.id].rotation.x,e.rotation.y=this.latest[e.id].rotation.y,e.rotation.z=this.latest[e.id].rotation.z,e.position.x=this.latest[e.id].position.x,e.position.y=this.latest[e.id].position.y,e.position.z=this.latest[e.id].position.z,e.scale.x=this.latest[e.id].scale.x,e.scale.y=this.latest[e.id].scale.y,e.scale.z=this.latest[e.id].scale.z,e.quaternion.axis.x=this.latest[e.id].quaternion.axis.x,e.quaternion.axis.y=this.latest[e.id].quaternion.axis.y,e.quaternion.axis.z=this.latest[e.id].quaternion.axis.z,e.quaternion.angle=this.latest[e.id].quaternion.angle,delete this.latest[e.id],t=!0),this.animations[e.id]&&(delete this.animations[e.id],t=!0),t&&(e.updateInstance("position"),e.updateInstance("rotation"),e.updateInstance("scale"))},GameLib.System.Animation.prototype.attachAnimation=function(e,t){if(this.latest[t.id]={rotation:{x:t.rotation.x,y:t.rotation.y,z:t.rotation.z},position:{x:t.position.x,y:t.position.y,z:t.position.z},scale:{x:t.scale.x,y:t.scale.y,z:t.scale.z},quaternion:{axis:{x:t.quaternion.axis.x,y:t.quaternion.axis.y,z:t.quaternion.axis.z},angle:t.quaternion.angle}},this.animations[t.id]=[],t.backupRotationXDescriptor)throw new Error("already a backed up x descriptor");t.backupQuaternionAngleDescriptor=Object.getOwnPropertyDescriptor(t.quaternion,"angle"),t.backupQuaternionAxisXDescriptor=Object.getOwnPropertyDescriptor(t.quaternion.axis,"x"),t.backupQuaternionAxisYDescriptor=Object.getOwnPropertyDescriptor(t.quaternion.axis,"y"),t.backupQuaternionAxisZDescriptor=Object.getOwnPropertyDescriptor(t.quaternion.axis,"z"),t.backupRotationXDescriptor=Object.getOwnPropertyDescriptor(t.rotation,"x"),t.backupRotationYDescriptor=Object.getOwnPropertyDescriptor(t.rotation,"y"),t.backupRotationZDescriptor=Object.getOwnPropertyDescriptor(t.rotation,"z"),t.backupPositionXDescriptor=Object.getOwnPropertyDescriptor(t.position,"x"),t.backupPositionYDescriptor=Object.getOwnPropertyDescriptor(t.position,"y"),t.backupPositionZDescriptor=Object.getOwnPropertyDescriptor(t.position,"z"),t.backupScaleXDescriptor=Object.getOwnPropertyDescriptor(t.scale,"x"),t.backupScaleYDescriptor=Object.getOwnPropertyDescriptor(t.scale,"y"),t.backupScaleZDescriptor=Object.getOwnPropertyDescriptor(t.scale,"z"),Object.defineProperty(t.quaternion,"angle",{get:this.getProperty(t,"angle","quaternion"),set:this.setProperty(t,e,"angle","quaternion"),configurable:!0}),Object.defineProperty(t.quaternion.axis,"x",{get:this.getSubProperty(t,"x","quaternion","axis"),set:this.setSubProperty(t,e,"x","quaternion","axis"),configurable:!0}),Object.defineProperty(t.quaternion.axis,"y",{get:this.getSubProperty(t,"y","quaternion","axis"),set:this.setSubProperty(t,e,"y","quaternion","axis"),configurable:!0}),Object.defineProperty(t.quaternion.axis,"z",{get:this.getSubProperty(t,"z","quaternion","axis"),set:this.setSubProperty(t,e,"z","quaternion","axis"),configurable:!0}),Object.defineProperty(t.rotation,"x",{get:this.getProperty(t,"x","rotation"),set:this.setProperty(t,e,"x","rotation"),configurable:!0}),Object.defineProperty(t.rotation,"y",{get:this.getProperty(t,"y","rotation"),set:this.setProperty(t,e,"y","rotation"),configurable:!0}),Object.defineProperty(t.rotation,"z",{get:this.getProperty(t,"z","rotation"),set:this.setProperty(t,e,"z","rotation"),configurable:!0}),Object.defineProperty(t.scale,"x",{get:this.getProperty(t,"x","scale"),set:this.setProperty(t,e,"x","scale"),configurable:!0}),Object.defineProperty(t.scale,"y",{get:this.getProperty(t,"y","scale"),set:this.setProperty(t,e,"y","scale"),configurable:!0}),Object.defineProperty(t.scale,"z",{get:this.getProperty(t,"z","scale"),set:this.setProperty(t,e,"z","scale"),configurable:!0}),Object.defineProperty(t.position,"x",{get:this.getProperty(t,"x","position"),set:this.setProperty(t,e,"x","position"),configurable:!0}),Object.defineProperty(t.position,"y",{get:this.getProperty(t,"y","position"),set:this.setProperty(t,e,"y","position"),configurable:!0}),Object.defineProperty(t.position,"z",{get:this.getProperty(t,"z","position"),set:this.setProperty(t,e,"z","position"),configurable:!0})},GameLib.System.Animation.prototype.getSubProperty=function(e,t,i,n){return function(){return this.latest[e.id][i][n][t]}.bind(this)},GameLib.System.Animation.prototype.setSubProperty=function(e,t,i,n,a){return function(s){var o=Number(this.latest[e.id][n][a][i]);this.latest[e.id][n][a][i]=s,this.animations[e.id].push({type:n,axis:i,from:o,to:s,animation:t,mesh:e})}.bind(this)},GameLib.System.Animation.prototype.getProperty=function(e,t,i){return function(){return this.latest[e.id][i][t]}.bind(this)},GameLib.System.Animation.prototype.setProperty=function(e,t,i,n){return function(a){var s=Number(this.latest[e.id][n][i]);this.latest[e.id][n][i]=a,this.animations[e.id].push({type:n,axis:i,from:s,to:a,animation:t,mesh:e})}.bind(this)},GameLib.System.Animation.prototype.stop=function(){GameLib.System.prototype.stop.call(this),this.beforeRenderSubscription.remove(),this.animationMeshAddedSubscription.remove(),this.animationMeshRemovedSubscription.remove(),Object.keys(this.animations).map(function(e){this.animations[e]&&this.animations[e].meshes&&this.animations[e].meshes.map(function(e){this.detachAnimation(e)}.bind(this))}.bind(this)),this.animations={},this.instanceCreatedSubscription.remove(),this.removeComponentSubscription.remove(),this.textureAnimatedSubscription.remove(),this.animateTextureInstanceSubscription.remove()},GameLib.System.Audio=function(e){GameLib.System.call(this,e),this.instanceCreatedSubscription=null,this.removeComponentSubscription=null,this.playAudioSubscription=null,this.pauseAllAudioSubscription=null,this.muteAudioSubscription=null,this.continueAllAudioSubscription=null,this.stopAudioSubscription=null,this.stopAllAudioSubscription=null,this.mute=!1,this.paused=[],this.audioComponents=[],this.toPlay=[]},GameLib.System.Audio.prototype=Object.create(GameLib.System.prototype),GameLib.System.Audio.prototype.constructor=GameLib.System.Audio,GameLib.System.Audio.prototype.start=function(){GameLib.System.prototype.start.call(this),this.instanceCreatedSubscription=GameLib.Event.Subscribe(GameLib.Event.INSTANCE_CREATED,this.instanceCreated.bind(this)),this.removeComponentSubscription=GameLib.Event.Subscribe(GameLib.Event.REMOVE_COMPONENT,this.removeComponent.bind(this)),this.playAudioSubscription=GameLib.Event.Subscribe(GameLib.Event.PLAY_AUDIO,this.playAudio.bind(this)),this.pauseAllAudioSubscription=GameLib.Event.Subscribe(GameLib.Event.PAUSE_ALL_AUDIO,this.pauseAllAudio.bind(this)),this.muteAudioSubscription=GameLib.Event.Subscribe(GameLib.Event.MUTE_AUDIO,this.muteAudio.bind(this)),this.continueAllAudioSubscription=GameLib.Event.Subscribe(GameLib.Event.CONTINUE_ALL_AUDIO,this.continueAllAudio.bind(this)),this.stopAudioSubscription=GameLib.Event.Subscribe(GameLib.Event.STOP_AUDIO,this.stopAudio.bind(this)),this.stopAllAudioSubscription=GameLib.Event.Subscribe(GameLib.Event.STOP_ALL_AUDIO,this.stopAllAudio.bind(this))},GameLib.System.Audio.prototype.instanceCreated=function(e){if(e.component instanceof GameLib.D3.Audio){GameLib.Utils.PushUnique(this.audioComponents,e.component),e.component.instance.onEnded=function(){this.isPlaying=!1,GameLib.Event.Emit(GameLib.Event.AUDIO_ENDED,{audio:e.component})};var t=this.toPlay.indexOf(e.component.name);-1!==t&&(GameLib.Event.Emit(GameLib.Event.PLAY_AUDIO,{name:e.component.name}),this.toPlay.splice(t,1))}},GameLib.System.Audio.prototype.playAudio=function(e){var t=!1;this.audioComponents.map(function(i){i.name===e.name&&(t=!0,i.instance||console.log("audio not ready yet"),i.overplay?(i.instance.isPlaying&&i.instance.stop(),i.instance.offset=0,i.instance.play()):i.instance.isPlaying||i.instance.play())}.bind(this)),t||(console.log("delaying audio play until loaded for: "+e.name),this.toPlay.push(e.name))},GameLib.System.Audio.prototype.pauseAllAudio=function(e){this.paused=[],this.audioComponents.map(function(e){e.instance.isPlaying&&(this.paused.push(e),e.paused=!0,e.updateInstance("paused"))}.bind(this))},GameLib.System.Audio.prototype.continueAllAudio=function(e){this.paused.map(function(e){e.paused=!1,e.updateInstance("paused")}),this.paused=[]},GameLib.System.Audio.prototype.stopAllAudio=function(e){this.audioComponents.map(function(e){e.instance.isPlaying&&e.instance.stop()})},GameLib.System.Audio.prototype.stopAudio=function(e){this.audioComponents.map(function(t){t.name===e.name&&t.instance.isPlaying&&t.instance.stop()})},GameLib.System.Audio.prototype.removeComponent=function(e){},GameLib.System.Audio.prototype.muteAudio=function(){this.mute=!this.mute,this.mute?(this.audioVolumes=this.audioComponents.reduce(function(e,t){return e.push({audio:t,volume:t.volume}),t.volume=0,t.updateInstance("volume"),e},[]),GameLib.Event.Emit(GameLib.Event.AUDIO_MUTED,{audioSystem:this})):(this.audioVolumes.map(function(e){e.audio.volume=e.volume,e.audio.updateInstance("volume")}),GameLib.Event.Emit(GameLib.Event.AUDIO_UNMUTED,{audioSystem:this}))},GameLib.System.Audio.prototype.stop=function(){GameLib.System.prototype.stop.call(this),this.instanceCreatedSubscription.remove(),this.removeComponentSubscription.remove(), -this.playAudioSubscription.remove(),this.pauseAllAudioSubscription.remove(),this.muteAudioSubscription.remove(),this.continueAllAudioSubscription.remove(),this.stopAudioSubscription.remove(),this.stopAllAudioSubscription.remove()},GameLib.System.CustomCode=function(e){GameLib.System.call(this,e),this.instanceCreatedSubscription=null,this.removeComponentSubscription=null,this.compileSuccessSubscription=null,this.compileFailedSubscription=null,this.subscriptions={}},GameLib.System.CustomCode.prototype=Object.create(GameLib.System.prototype),GameLib.System.CustomCode.prototype.constructor=GameLib.System.CustomCode,GameLib.System.CustomCode.prototype.start=function(){GameLib.System.prototype.start.call(this),GameLib.EntityManager.Instance.queryComponents(GameLib.Component.CUSTOM_CODE).map(function(e){this.subscriptions[e.id]=GameLib.Event.Subscribe(e.eventId,e.instance)}.bind(this)),this.instanceCreatedSubscription=GameLib.Event.Subscribe(GameLib.Event.INSTANCE_CREATED,this.instanceCreated.bind(this)),this.removeComponentSubscription=GameLib.Event.Subscribe(GameLib.Event.REMOVE_COMPONENT,this.removeComponent.bind(this)),this.compileSuccessSubscription=GameLib.Event.Subscribe(GameLib.Event.COMPILE_SUCCESS,this.compileSuccess.bind(this)),this.compileFailedSubscription=GameLib.Event.Subscribe(GameLib.Event.COMPILE_FAILED,this.compileFailed.bind(this))},GameLib.System.CustomCode.prototype.instanceCreated=function(e){e.component instanceof GameLib.CustomCode&&(this.subscriptions[e.component.id]&&(console.warn("a component already existed"),this.subscriptions[e.component.id].remove()),this.subscriptions[e.component.id]=GameLib.Event.Subscribe(e.component.eventId,e.component.instance))},GameLib.System.CustomCode.prototype.removeComponent=function(e){e.component instanceof GameLib.CustomCode&&this.subscriptions[e.component.id]&&(this.subscriptions[e.component.id].remove(),delete this.subscriptions[e.component.id])},GameLib.System.CustomCode.prototype.compileSuccess=function(e){this.subscriptions[e.component.id]&&this.subscriptions[e.component.id].remove(),this.subscriptions[e.component.id]=GameLib.Event.Subscribe(e.component.eventId,e.component.instance)},GameLib.System.CustomCode.prototype.compileFailed=function(e){this.subscriptions[e.component.id]&&(this.subscriptions[e.component.id].remove(),delete this.subscriptions[e.component.id])},GameLib.System.CustomCode.prototype.stop=function(){GameLib.System.prototype.stop.call(this),this.instanceCreatedSubscription&&(this.instanceCreatedSubscription.remove(),this.instanceCreatedSubscription=null),this.removeComponentSubscription&&(this.removeComponentSubscription.remove(),this.removeComponentSubscription=null),this.compileSuccessSubscription&&(this.compileSuccessSubscription.remove(),this.compileSuccessSubscription=null),this.compileFailedSubscription&&(this.compileFailedSubscription.remove(),this.compileFailedSubscription=null),Object.keys(this.subscriptions).map(function(e){this.subscriptions[e]&&(this.subscriptions[e].remove(),delete this.subscriptions[e])}.bind(this))};GameLib.System.GUI=function(e){GameLib.System.call(this,e),this.guis=[],this.components=[],this.backupComponents=[],this.exclusiveMode=!1,this.buildGUISubscription=null,this.meshDeletedSubscription=null,this.meshSelectedSubscription=null,this.meshDeselectedSubscription=null,this.newEntitySubscription=null,this.meshSelectionObjects={},this.sourceChangedSubscription=null,this.instanceCreatedSubscription=null,this.removeComponentSubscription=null,this.windowResizeSubscription=null},GameLib.System.GUI.prototype=Object.create(GameLib.System.prototype),GameLib.System.GUI.prototype.constructor=GameLib.System.GUI,GameLib.System.GUI.prototype.windowResize=function(e){this.guis.map(function(t){t.instance.domElement.getElementsByTagName("ul")[0].style.maxHeight=e.height-93+"px"})},GameLib.System.GUI.prototype.initialize=function(e){var t=this.guis.length;e.instance.domElement.style.position="absolute",e.instance.domElement.style.top=34*t+"px",e.instance.domElement.style.right="0px",e.domElement.instance.parentElement.appendChild(e.instance.domElement)},GameLib.System.GUI.prototype.instanceCreated=function(e){e.component instanceof GameLib.GUI&&(GameLib.Utils.PushUnique(this.guis,e.component),this.initialize(e.component))},GameLib.System.GUI.prototype.removeComponent=function(e){if(e.component instanceof GameLib.GUI){var t=this.guis.indexOf(e.component);if(-1===t)console.warn("gui system out of sync");else{var i=this.guis[t];i.domElement.instance.parentElement.removeChild(i.instance.domElement),this.guis.splice(t,1)}}},GameLib.System.GUI.prototype.start=function(){GameLib.System.prototype.start.call(this),this.instanceCreatedSubscription=GameLib.Event.Subscribe(GameLib.Event.INSTANCE_CREATED,this.instanceCreated.bind(this)),this.removeComponentSubscription=GameLib.Event.Subscribe(GameLib.Event.REMOVE_COMPONENT,this.removeComponent.bind(this)),this.windowResizeSubscription=GameLib.Event.Subscribe(GameLib.Event.WINDOW_RESIZE,this.windowResize.bind(this)),this.guis=GameLib.EntityManager.Instance.queryComponents(GameLib.Component.GUI),this.guis.map(function(e){this.initialize(e)}.bind(this)),dat.GUI.prototype.removeEmtpyFolders=function(){for(var e in this.__folders)if(this.__folders.hasOwnProperty(e)){var t=this.__folders[e];0===t.__listening.length&&(t.close(),this.__ul.removeChild(t.domElement.parentNode),delete this.__folders[e],this.onResize())}},dat.GUI.prototype.listen=function(e){this.__listening.length;this.__listening.push(e),delete this.closed,Object.defineProperty(this,"closed",{get:function(){return this.params.closed},set:function(e){this.params.closed=e,this.params.closed?(this.dom.addClass(this.__ul,"closed"),cancelAnimationFrame(this.animationId)):(this.dom.removeClass(this.__ul,"closed"),this.updateDisplaysCallback=function(){this.animationId=requestAnimationFrame(this.updateDisplaysCallback.bind(this)),this.__listening.map(function(e){e.updateDisplay()})}.bind(this),this.animationId=requestAnimationFrame(this.updateDisplaysCallback)),this.onResize(),this.__closeButton&&(this.__closeButton.innerHTML=e?"Open Controls":"Close Controls")},configurable:!0})},dat.GUI.prototype.removeAllFolders=function(){for(var e in this.__folders)if(this.__folders.hasOwnProperty(e)){var t=this.__folders[e];cancelAnimationFrame(t.animationId),t.__controllers.map(function(e){e.remove()}),t.__controllers=[],t.__listening=[],t.close(),this.__ul.removeChild(t.domElement.parentNode),delete this.__folders[e],this.onResize()}},this.buildGUISubscription=this.subscribe(GameLib.Event.BUILD_GUI,this.buildGUI),this.meshDeletedSubscription=this.subscribe(GameLib.Event.REMOVE_MESH,this.meshDeleted),this.meshSelectedSubscription=this.subscribe(GameLib.Event.MESH_SELECTED,this.meshSelected),this.meshDeselectedSubscription=this.subscribe(GameLib.Event.MESH_DESELECTED,this.meshDeslected),this.newEntitySubscription=this.subscribe(GameLib.Event.NEW_ENTITY,this.newEntity),this.componentRemovedSubscription=this.subscribe(GameLib.Event.REMOVE_COMPONENT,this.removeComponent),this.sourceChangedSubscription=this.subscribe(GameLib.Event.CAST_SOURCE_CHANGED,this.castSourceChanged),this.destinationChangedSubscription=this.subscribe(GameLib.Event.RECEIVE_DESTINATION_CHANGED,this.receiveDestinationChanged)},GameLib.System.GUI.prototype.onChange=function(e,t,i){return function(n){i.map(function(i){i[e][t]=n,i instanceof GameLib.D3.Mesh&&"rotation"===e&&(i.useQuaternion=!1),i instanceof GameLib.D3.Mesh&&"quaternion"===e&&(i.useQuaternion=!0),"function"==typeof i[e].updateInstance?i[e].updateInstance(e):"function"==typeof i[e][t].updateInstance?i[e][t].updateInstance(t):i.updateInstance(e)})}},GameLib.System.GUI.prototype.controller=function(e,t,i,n,a,s,o,r,c){GameLib.Utils.UndefinedOrNull(r)&&(r=-1e3),GameLib.Utils.UndefinedOrNull(c)&&(c=1e3),"axleLocal"!==i&&"directionLocal"!==i||(r=-1,c=1,a=1),"offset"!==i&&"repeat"!==i||(r=-1e3,c=1e3,a=.01);var m=e.add(t[i],n,r,c,a).name(i+"."+n);return m.onChange(this.onChange(i,n,o)),s&&m.listen(),m},GameLib.System.GUI.prototype.buildQuaternionControl=function(e,t,i){var n=t.template,a=!1;1===t.affected.length&&(n=t.affected[0],a=!0);var s=t.affected;this.controller(e,n,i,"x",.1,a,s),this.controller(e,n,i,"y",.1,a,s),this.controller(e,n,i,"z",.1,a,s),this.controller(e,n,i,"w",.1,a,s),this.controller(e,n,i,"angle",.001,a,s,-Math.PI,Math.PI),e.add(n[i].axis,"x",-1,1,.01).name("quaternion.axis.x").onChange(function(e){s.map(function(t){t.useQuaternion=!0,t[i].axis.x=Number(e),t.updateInstance("x")})}),e.add(n[i].axis,"y",-1,1,.01).name("quaternion.axis.y").onChange(function(e){s.map(function(t){t.useQuaternion=!0,t[i].axis.y=Number(e),t.updateInstance("y")})}),e.add(n[i].axis,"z",-1,1,.01).name("quaternion.axis.z").onChange(function(e){s.map(function(t){t.useQuaternion=!0,t[i].axis.z=Number(e),t.updateInstance("z")})})},GameLib.System.GUI.prototype.buildVectorControl=function(e,t,i){var n=t.template,a=!1;1===t.affected.length&&(n=t.affected[0],a=!0);var s=t.affected,o=[];GameLib.Utils.isVector4(n[i])&&o.push(this.controller(e,n,i,"w",.01,a,s)),o.push(this.controller(e,n,i,"x",.01,a,s)),o.push(this.controller(e,n,i,"y",.01,a,s)),(GameLib.Utils.isVector3(n[i])||GameLib.Utils.isVector4(n[i]))&&o.push(this.controller(e,n,i,"z",.01,a,s))},GameLib.System.GUI.prototype.buildParentSelectionControl=function(e,t,i){var n=GameLib.Utils.UpperCaseUnderscore(i.replace("parent","")),a=GameLib.Component[n],s=GameLib.Component.GetComponentConstructor(a),o=GameLib.EntityManager.Instance.queryComponentsByConstructor(s).reduce(function(e,t){return e[t.name]=t,e},{none:null}),r=t.template,c=t.affected;e.add(r,i,o).listen().onChange(function(e){var t=null;"null"!==e&&(t=GameLib.EntityManager.Instance.findComponentById(e)),c.map(function(e){e[i]=t,"parentEntity"===i&&GameLib.Event.Emit(GameLib.Event.PARENT_ENTITY_CHANGE,{originalEntity:this.initialValue,newEntity:t,object:e}),"parentPhysicsWorld"===i&&GameLib.Event.Emit(GameLib.Event.PARENT_WORLD_CHANGE,{originalWorld:this.initialValue,newWorld:t,object:e}),"parentScene"===i&&GameLib.Event.Emit(GameLib.Event.PARENT_SCENE_CHANGE,{originalScene:this.initialValue,newScene:t,object:e})}.bind(this)),"parentEntity"===i&&GameLib.Event.Emit(GameLib.Event.BUILD_GUI,null),this.initialValue=t})},GameLib.System.GUI.prototype.buildArrayManagerControl=function(e,t,i){var n=t.template.linkedObjects[i];if(!(n instanceof Array))return void console.error("data mismatch - something not an array");var a=t.template,s=a[i],o=function(n,a){var s="invalid item";n&&n.name&&(s=n.name);var o=e.add({remove:function(){t.affected.map(function(t){t[i].splice(a,1),e.remove(o)})}},"remove").name("remove "+i+"["+a+"] - "+s);e.updateDisplay()};s.map(o);var r={},c=GameLib.EntityManager.Instance.queryComponents(n).reduce(function(e,t){return e[t.name]=t,r[t.id]=t,e},{none:null}),m={component:null,add:function(){t.affected.map(function(e){-1===e[i].indexOf(m.component)&&(e[i].push(m.component),GameLib.Event.Emit(GameLib.Event.ARRAY_ITEM_ADDED,{component:e,property:i,item:m.component}))}),GameLib.Event.Emit(GameLib.Event.BUILD_GUI)}};e.add(m,"component",c).name("select "+i).onChange(function(e){m.component="null"===e?null:r[e]}).listen(),e.add(m,"add").name("add to "+i)},GameLib.System.GUI.prototype.buildColorControl=function(e,t,i){var n=t.template,a={hexColor:n[i].toHex()};e.addColor(a,"hexColor").name(i).listen().onChange(function(e){t.affected.map(function(t){t[i].fromHex(e),t[i].updateInstance(i)})}),e.add(a,"hexColor").name(i).listen().onChange(function(e){t.affected.map(function(t){t[i].fromHex(e),t[i].updateInstance(i)})})},GameLib.System.GUI.prototype.buildObjectControl=function(e,t,i){var n=t.template[i];null!==n&&("sourceProperties"!==i&&"destinationProperties"!==i||Object.keys(n).map(function(a){e.add(n,a).name(i+"."+a).listen().onChange(function(e){t.affected.map(function(t){t[i][a]=e,t.updateInstance(i)})})}))},GameLib.System.GUI.prototype.buildSelectControl=function(e,t,i){var n=null;if(t.template.linkedObjects&&t.template.linkedObjects[i]?n=t.template.linkedObjects[i]:t.template[i]&&(n=t.template[i].constructor),!n)return void console.log("cannot determine constructor");var a=t.template,s=GameLib.EntityManager.Instance.queryComponentsByConstructor(n),o={},r=s.reduce(function(e,t){return e[t.name]=t,o[t.id]=t,e},{none:null});e.add(a,i,r).name(i).listen().onChange(function(e){var n=null;"null"!==e&&(n=o[e]),t.affected.map(function(e){e[i]=n,e.updateInstance(i)}),this.initialValue=n})},GameLib.System.GUI.prototype.buildControl=function(e,t,i){var n=t.template,a=!1;1===t.affected.length&&(n=t.affected[0],a=!0);var s=t.componentType,o=[];if((GameLib.Utils.isString(n[i])||GameLib.Utils.isBoolean(n[i]))&&o.push(e.add(n,i)),GameLib.Utils.isNumber(n[i])){if(n.grain&&n.grain,"componentType"===i){var r={componentType:GameLib.Component.GetComponentInfo(n[i]).name};o.push(e.add(r,"componentType"))}else if("systemType"===i)o.push(e.add(n,i,{animation:GameLib.System.SYSTEM_TYPE_ANIMATION,gui:GameLib.System.SYSTEM_TYPE_GUI,input:GameLib.System.SYSTEM_TYPE_INPUT,render:GameLib.System.SYSTEM_TYPE_RENDER,storage:GameLib.System.SYSTEM_TYPE_STORAGE,linking:GameLib.System.SYSTEM_TYPE_LINKING,physics:GameLib.System.SYSTEM_TYPE_PHYSICS,"custom code":GameLib.System.SYSTEM_TYPE_CUSTOM}));else if("socketType"===i)o.push(e.add(n,i,{none:GameLib.API.Socket.TYPE_NONE,cast:GameLib.API.Socket.TYPE_CAST,receive:GameLib.API.Socket.TYPE_RECEIVE}));else if("castType"===i)o.push(e.add(n,i,{room:GameLib.API.Socket.Cast.CAST_TYPE_ROOM,peer:GameLib.API.Socket.Cast.CAST_TYPE_PEER,all:GameLib.API.Socket.Cast.CAST_TYPE_ALL,"all but peer":GameLib.API.Socket.Cast.CAST_TYPE_ALL_BUT_PEER}));else if("receiveType"===i)o.push(e.add(n,i,{room:GameLib.API.Socket.Receive.RECEIVE_TYPE_ROOM,peer:GameLib.API.Socket.Cast.RECEIVE_TYPE_PEER}));else if("opacityType"===i)o.push(e.add(n,i,{constant:GameLib.D3.Particle.OPACITY_TYPE_CONSTANT,decrease:GameLib.D3.Particle.OPACITY_TYPE_DECREASE_LINEAR,increase:GameLib.D3.Particle.OPACITY_TYPE_INCREASE_LINEAR}));else if("positionOffsetType"===i)o.push(e.add(n,i,{constant:GameLib.D3.Particle.POSITION_OFFSET_TYPE_CONSTANT,random:GameLib.D3.Particle.POSITION_OFFSET_TYPE_RANDOM,function:GameLib.D3.Particle.POSITION_OFFSET_TYPE_FUNCTION}));else if("directionType"===i)o.push(e.add(n,i,{constant:GameLib.D3.Particle.DIRECTION_TYPE_CONSTANT,random:GameLib.D3.Particle.DIRECTION_TYPE_RANDOM,"random normalized":GameLib.D3.Particle.DIRECTION_TYPE_RANDOM_NORMALIZED,function:GameLib.D3.Particle.DIRECTION_TYPE_FUNCTION}));else if("speedType"===i)o.push(e.add(n,i,{constant:GameLib.D3.Particle.SPEED_TYPE_CONSTANT,linear:GameLib.D3.Particle.SPEED_TYPE_LINEAR,exponential:GameLib.D3.Particle.SPEED_TYPE_EXPONENTIAL,logarithmic:GameLib.D3.Particle.SPEED_TYPE_LOGARITHMIC,"1 / log":GameLib.D3.Particle.SPEED_TYPE_ONE_OVER_LOG,exp:GameLib.D3.Particle.SPEED_TYPE_EXP,"1 / exp":GameLib.D3.Particle.SPEED_TYPE_ONE_OVER_EXP}));else if("scaleType"===i)o.push(e.add(n,i,{constant:GameLib.D3.Particle.SCALE_TYPE_CONSTANT,linear:GameLib.D3.Particle.SCALE_TYPE_LINEAR,exponential:GameLib.D3.Particle.SCALE_TYPE_EXPONENTIAL,random:GameLib.D3.Particle.SCALE_TYPE_RANDOM,"random (x = y)":GameLib.D3.Particle.SCALE_TYPE_RANDOM_X_EQUALS_Y,function:GameLib.D3.Particle.SCALE_TYPE_FUNCTION}));else if("rotationType"===i)o.push(e.add(n,i,{constant:GameLib.D3.Particle.ROTATION_TYPE_CONSTANT,random:GameLib.D3.Particle.ROTATION_TYPE_RANDOM,function:GameLib.D3.Particle.ROTATION_TYPE_FUNCTION}));else if("broadphaseType"===i)o.push(e.add(n,i,{naive:GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE,grid:GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID,sap:GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP}));else if("solverType"===i)o.push(e.add(n,i,{gs:GameLib.D3.API.Solver.GS_SOLVER,split:GameLib.D3.API.Solver.SPLIT_SOLVER}));else if("meshType"===i)o.push(e.add(n,i,{normal:GameLib.D3.API.Mesh.MESH_TYPE_NORMAL,curve:GameLib.D3.API.Mesh.MESH_TYPE_CURVE,skinned:GameLib.D3.API.Mesh.MESH_TYPE_SKINNED,plane:GameLib.D3.API.Mesh.MESH_TYPE_PLANE,sphere:GameLib.D3.API.Mesh.MESH_TYPE_SPHERE,box:GameLib.D3.API.Mesh.MESH_TYPE_BOX,cylinder:GameLib.D3.API.Mesh.MESH_TYPE_CYLINDER,text:GameLib.D3.API.Mesh.MESH_TYPE_TEXT}));else if("cameraType"===i)o.push(e.add(n,i,{perspective:GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE,orthographic:GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL}));else if("materialType"===i)o.push(e.add(n,i,{standard:GameLib.D3.Material.MATERIAL_TYPE_STANDARD,basic:GameLib.D3.Material.MATERIAL_TYPE_BASIC,phong:GameLib.D3.Material.MATERIAL_TYPE_PHONG,points:GameLib.D3.Material.MATERIAL_TYPE_POINTS,toon:GameLib.D3.Material.MATERIAL_TYPE_TOON,"line basic":GameLib.D3.Material.MATERIAL_TYPE_LINE_BASIC}));else if("side"===i)o.push(e.add(n,i,{double:GameLib.D3.Material.TYPE_DOUBLE_SIDE,front:GameLib.D3.Material.TYPE_FRONT_SIDE,back:GameLib.D3.Material.TYPE_BACK_SIDE}));else if("combine"===i)o.push(e.add(n,i,{multiply:GameLib.D3.Material.TYPE_MULTIPLY_OPERATION,mix:GameLib.D3.Material.TYPE_MIX_OPERATION,add:GameLib.D3.Material.TYPE_ADD_OPERATION}));else if("vertexColors"===i)o.push(e.add(n,i,{none:GameLib.D3.Material.TYPE_NO_COLORS,face:GameLib.D3.Material.TYPE_FACE_COLORS,vertex:GameLib.D3.Material.TYPE_VERTEX_COLORS}));else if("blending"===i)o.push(e.add(n,i,{none:GameLib.D3.Material.TYPE_NO_BLENDING,normal:GameLib.D3.Material.TYPE_NORMAL_BLENDING,additive:GameLib.D3.Material.TYPE_ADDITIVE_BLENDING,subtractive:GameLib.D3.Material.TYPE_SUBTRACTIVE_BLENDING,multiply:GameLib.D3.Material.TYPE_MULTIPLY_BLENDING,custom:GameLib.D3.Material.TYPE_CUSTOM_BLENDING}));else if("blendSrc"===i)o.push(e.add(n,i,{zero:GameLib.D3.Material.TYPE_ZERO_FACTOR,one:GameLib.D3.Material.TYPE_ONE_FACTOR,"source color":GameLib.D3.Material.TYPE_SRC_COLOR_FACTOR,"one minus source color":GameLib.D3.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR,"source alpha":GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR,"one minus source alpha":GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR,"destination alpha":GameLib.D3.Material.TYPE_DST_ALPHA_FACTOR,"one minus destination alpha":GameLib.D3.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR,"destination color":GameLib.D3.Material.TYPE_DST_COLOR_FACTOR,"one minus destination color":GameLib.D3.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR,"source alpha saturate":GameLib.D3.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR}));else if("blendDst"===i)o.push(e.add(n,i,{zero:GameLib.D3.Material.TYPE_ZERO_FACTOR,one:GameLib.D3.Material.TYPE_ONE_FACTOR,"source color":GameLib.D3.Material.TYPE_SRC_COLOR_FACTOR,"one minus source color":GameLib.D3.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR,"source alpha":GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR,"one minus source alpha":GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR,"destination alpha":GameLib.D3.Material.TYPE_DST_ALPHA_FACTOR,"one minus destination alpha":GameLib.D3.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR,"destination color":GameLib.D3.Material.TYPE_DST_COLOR_FACTOR,"one minus destination color":GameLib.D3.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR,"source alpha saturate":GameLib.D3.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR}));else if("blendEquation"===i)o.push(e.add(n,i,{add:GameLib.D3.Material.TYPE_ADD_EQUATION,subtract:GameLib.D3.Material.TYPE_SUBTRACT_EQUATION,"reverse subtract":GameLib.D3.Material.TYPE_REVERSE_SUBTRACT_EQUATION,min:GameLib.D3.Material.TYPE_MIN_EQUATION,max:GameLib.D3.Material.TYPE_MAX_EQUATION}));else if("depthFunc"===i)o.push(e.add(n,i,{never:GameLib.D3.Material.TYPE_NEVER_DEPTH,always:GameLib.D3.Material.TYPE_ALWAYS_DEPTH,"less depth":GameLib.D3.Material.TYPE_LESS_DEPTH,"less equal depth":GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH,"equal depth":GameLib.D3.Material.TYPE_EQUAL_DEPTH,"greated equal depth":GameLib.D3.Material.TYPE_GREATER_EQUAL_DEPTH,"greated depth":GameLib.D3.Material.TYPE_GREATER_DEPTH,"not equal depth":GameLib.D3.Material.TYPE_NOT_EQUAL_DEPTH}));else if("wrapS"===i)o.push(e.add(n,i,{repeat:GameLib.D3.API.Texture.TYPE_REPEAT_WRAPPING,clamp:GameLib.D3.API.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING,"mirrored repeat":GameLib.D3.API.Texture.TYPE_MIRRORED_REPEAT_WRAPPING}));else if("wrapT"===i)o.push(e.add(n,i,{repeat:GameLib.D3.API.Texture.TYPE_REPEAT_WRAPPING,clamp:GameLib.D3.API.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING,"mirrored repeat":GameLib.D3.API.Texture.TYPE_MIRRORED_REPEAT_WRAPPING}));else if("format"===i)o.push(e.add(n,i,{alpha:GameLib.D3.API.Texture.TYPE_ALPHA_FORMAT,rgb:GameLib.D3.API.Texture.TYPE_RGB_FORMAT,rgba:GameLib.D3.API.Texture.TYPE_RGBA_FORMAT,luminance:GameLib.D3.API.Texture.TYPE_LUMINANCE_FORMAT,"luminance alpha":GameLib.D3.API.Texture.TYPE_LUMINANCE_ALPHA_FORMAT,depth:GameLib.D3.API.Texture.TYPE_DEPTH_FORMAT}));else if("mapping"===i)o.push(e.add(n,i,{uv:GameLib.D3.API.Texture.TYPE_UV_MAPPING,"cube reflection":GameLib.D3.API.Texture.TYPE_CUBE_REFLECTION_MAPPING,"cube refraction":GameLib.D3.API.Texture.TYPE_CUBE_REFRACTION_MAPPING,"equi rectangular reflection":GameLib.D3.API.Texture.TYPE_EQUI_RECTANGULAR_REFLECTION_MAPPING,"equi rectangular refraction":GameLib.D3.API.Texture.TYPE_EQUI_RECTANGULAR_REFRACTION_MAPPING,"spherical reflection":GameLib.D3.API.Texture.TYPE_SPHERICAL_REFLECTION_MAPPING,"cube uv reflection":GameLib.D3.API.Texture.TYPE_CUBE_UV_REFLECTION_MAPPING,"cube uv refraction":GameLib.D3.API.Texture.TYPE_CUBE_UV_REFRACTION_MAPPING}));else if("magFilter"===i)o.push(e.add(n,i,{nearest:GameLib.D3.API.Texture.TYPE_NEAREST_FILTER,"nearest mipmap nearest":GameLib.D3.API.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER,"nearest mipmap linear":GameLib.D3.API.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER,linear:GameLib.D3.API.Texture.TYPE_LINEAR_FILTER,"linear mipmap nearest":GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER,"linear mipmap linear":GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER}));else if("minFilter"===i)o.push(e.add(n,i,{nearest:GameLib.D3.API.Texture.TYPE_NEAREST_FILTER,"nearest mipmap nearest":GameLib.D3.API.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER,"nearest mipmap linear":GameLib.D3.API.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER,linear:GameLib.D3.API.Texture.TYPE_LINEAR_FILTER,"linear mipmap nearest":GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER,"linear mipmap linear":GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER}));else if(s===GameLib.Component.TEXTURE&&"textureType"===i)o.push(e.add(n,i,{normal:GameLib.D3.API.Texture.TEXTURE_TYPE_NORMAL,cube:GameLib.D3.API.Texture.TEXTURE_TYPE_CUBE,canvas:GameLib.D3.API.Texture.TEXTURE_TYPE_CANVAS}));else if("textureType"===i)o.push(e.add(n,i,{"unsigned byte":GameLib.D3.API.Texture.TYPE_UNSIGNED_BYTE,byte:GameLib.D3.API.Texture.TYPE_BYTE,short:GameLib.D3.API.Texture.TYPE_SHORT,"unsigned short":GameLib.D3.API.Texture.TYPE_UNSIGNED_SHORT,int:GameLib.D3.API.Texture.TYPE_INT,"unsigned int":GameLib.D3.API.Texture.TYPE_UNSIGNED_INT,float:GameLib.D3.API.Texture.TYPE_FLOAT,"half float":GameLib.D3.API.Texture.TYPE_HALF_FLOAT}));else if("encoding"===i)o.push(e.add(n,i,{linear:GameLib.D3.API.Texture.TYPE_LINEAR_ENCODING,srgb:GameLib.D3.API.Texture.TYPE_SRGB_ENCODING,gamma:GameLib.D3.API.Texture.TYPE_GAMMA_ENCODING,rgbe:GameLib.D3.API.Texture.TYPE_RGBE_ENCODING,"log luv":GameLib.D3.API.Texture.TYPE_LOG_LUV_ENCODING,rgbm7:GameLib.D3.API.Texture.TYPE_RGBM7_ENCODING,rgbm16:GameLib.D3.API.Texture.TYPE_RGBM16_ENCODING,rgbd:GameLib.D3.API.Texture.TYPE_RGBD_ENCODING}));else if("lightType"===i)o.push(e.add(n,i,{ambient:GameLib.D3.Light.LIGHT_TYPE_AMBIENT,directional:GameLib.D3.Light.LIGHT_TYPE_DIRECTIONAL,spot:GameLib.D3.Light.LIGHT_TYPE_SPOT,point:GameLib.D3.Light.LIGHT_TYPE_POINT}));else if("eventId"===i){for(var c={},m=0;m<200;m++)try{c[GameLib.Event.GetEventName(m)]=m}catch(e){}o.push(e.add(n,i,c))}else"functionType"===i?o.push(e.add(n,i,{rotation:GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION,translation:GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION,scale:GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE})):"opacity"===i||"opacityFactor"===i||"metalness"===i||"roughness"===i||"volume"===i?o.push(e.add(n,i,0,1,.001)):"shininess"===i||"fov"===i?o.push(e.add(n,i,-255,255,1)):"aspect"===i||"wireframeLineWidth"===i||"lineWidth"===i?o.push(e.add(n,i,0,5,.001)):"bumpScale"===i||"normalScale"===i||"displacementScale"===i||"heightMapScale"===i||"intensity"===i?o.push(e.add(n,i,-10,10,.001)):"minX"===i||"minY"===i||"minZ"===i||"maxX"===i||"maxY"===i||"maxZ"===i||"offsetX"===i?o.push(e.add(n,i,-1e3,1e3,.01)):"widthSegments"===i||"radiusSegments"===i||"heightSegments"===i||"particlesPerSecond"===i?o.push(e.add(n,i,1,1e3,1)):"width"===i||"height"===i||"depth"===i||"radius"===i?o.push(e.add(n,i,0,1e3,.1)):"near"===i||"distanceGrain"===i||"envMapIntensity"===i?o.push(e.add(n,i,-10,100,.001)):"bumpScale"===i?o.push(e.add(n,i,0,20,.001)):"heightOffset"===i||"rotationFactor"===i?o.push(e.add(n,i,-100,100,.001)):"friction"===i?o.push(e.add(n,i,0,1e3,.01)):"radiusTop"===i||"radiusBottom"===i?o.push(e.add(n,i,0,100,.1)):"mass"===i?o.push(e.add(n,i,0,1e3,.1)):"sensitivity"===i?o.push(e.add(n,i,1,50,1)):"density"===i?o.push(e.add(n,i,0,1,1e-4)):"thetaLength"===i||"angle"===i?o.push(e.add(n,i,2*-Math.PI,2*Math.PI,.01)):"port"===i?o.push(e.add(n,i,1,65536,1)):o.push(e.add(n,i,-1e3,1e3,.1))}o.map(function(n){"name"===i?n.onFinishChange(function(e,n){return function(e){t.affected.map(function(t){t[i]=e,t.updateInstance(i)}),n.domElement.getElementsByClassName("title")[0].innerHTML=e}}(0,e)):n.onChange(function(e){"number"==typeof this.initialValue&&(e=Number(e)),t.affected.map(function(t){t[i]=e,t.updateInstance(i)})}),a&&n.listen()})},GameLib.System.GUI.prototype.meshSelected=function(e){this.exclusiveMode?GameLib.Utils.PushUnique(this.backupComponents,e.mesh):GameLib.Utils.PushUnique(this.components,e.mesh)},GameLib.System.GUI.prototype.meshDeslected=function(e){var t=-1;this.exclusiveMode?-1!==(t=this.backupComponents.indexOf(e.mesh))&&this.backupComponents.splice(t,1):-1!==(t=this.components.indexOf(e.mesh))&&this.components.splice(t,1)},GameLib.System.GUI.prototype.buildGUI=function(e){this.guis.map(function(t){if(t.instance.destroy(),t.removeAllFolders(),e&&(e.components?(this.exclusiveMode||(this.exclusiveMode=!0,this.backupComponents=this.components.map(function(e){return e})),this.components=e.components.map(function(e){return e})):this.exclusiveMode?(this.exclusiveMode=!1,this.components=this.backupComponents.map(function(e){return e})):console.log("we are already not in mesh select mode - not doing anything with the backup")),this.exclusiveMode||(this.components=this.components.filter(function(e){return e instanceof GameLib.D3.Mesh})),!(GameLib.Utils.UndefinedOrNull(this.components.length)||this.components.length<1)){this.exclusiveMode||(this.components=this.components.reduce(function(e,t){var i=t.getChildrenComponents();return GameLib.Utils.PushUnique(e,t),i.map(function(t){GameLib.Utils.PushUnique(e,t)}),e}.bind(this),[])),this.components.sort(function(e,t){return e.componentType>t.componentType?1:e.componentType0?console.log("ignoring multiple editor controls"):(this.editorControls.push(e.component),this.registerEditorControls())),e.component instanceof GameLib.Controls.Touch&&(this.touchControls.length>0?console.log("ignoring multiple touch controls"):(this.touchControls.push(e.component),this.registerTouchControls())),e.component instanceof GameLib.Controls.Keyboard&&(this.keyboardControls.length>0?console.log("ignoring multiple keyboard controls"):(this.keyboardControls.push(e.component),this.registerKeyboardControls())),e.component instanceof GameLib.Controls.Mouse&&(this.mouseControls.length>0?console.log("ignoring multiple mouse controls"):(this.mouseControls.push(e.component),this.registerMouseControls()))},GameLib.System.Input.prototype.removeComponent=function(e){if(e.component instanceof GameLib.Controls.D3.Editor){var t=this.editorControls.indexOf(e.component);-1!==t?(console.log("removing editor controls from system"),this.deRegisterEditorControls(),this.editorControls.splice(t,1)):console.log("failed to find the editor controls in the system - probably it was ignored - "+e.component.name)}},GameLib.System.Input.prototype.delayedInstanceEncountered=function(e){e.component instanceof GameLib.Controls.D3.Editor&&(0===this.editorControls.length?(this.editorControls.push(e.component),this.registerEditorControls()):e.component.createInstance())},GameLib.System.Input.prototype.registerTouchControls=function(){if(1===this.touchControls.length){var e=this.touchControls[0];this.touchSensitivity=e.sensitivity,this.touchStart=this.onTouchStart.bind(this),this.touchMove=this.onTouchMove.bind(this),this.touchEnd=this.onTouchEnd.bind(this),this.touchCancel=this.onTouchCancel.bind(this),e.domElement.instance.addEventListener("touchstart",this.touchStart,!1),e.domElement.instance.addEventListener("touchmove",this.touchMove,!1),e.domElement.instance.addEventListener("touchend",this.touchEnd,!1),e.domElement.instance.addEventListener("touchcancel",this.touchCancel,!1)}},GameLib.System.Input.prototype.registerKeyboardControls=function(){if(1===this.keyboardControls.length){var e=this.keyboardControls[0];this.keyboardKeyUp=this.onKeyboardKeyUp.bind(this),this.keyboardKeyDown=this.onKeyboardKeyDown.bind(this),e.domElement.instance.addEventListener("keyup",this.keyboardKeyUp,!1),e.domElement.instance.addEventListener("keydown",this.keyboardKeyDown,!1)}},GameLib.System.Input.prototype.registerMouseControls=function(){if(1===this.mouseControls.length){var e=this.mouseControls[0];this.mouseDown=this.onMouseDown.bind(this),this.mouseMove=this.onMouseMove.bind(this),this.mouseWheel=this.onMouseWheel.bind(this),this.mouseUp=this.onMouseUp.bind(this),e.domElement.instance.addEventListener("mousedown",this.mouseDown,!1),e.domElement.instance.addEventListener("mousemove",this.mouseMove,!1),e.domElement.instance.addEventListener("wheel",this.mouseWheel,!1),e.domElement.instance.addEventListener("mouseup",this.mouseUp,!1)}},GameLib.System.Input.prototype.registerEditorControls=function(){if(1===this.editorControls.length){var e=this.editorControls[0];this.mouseDownEdit=this.onMouseDownEdit.bind(this),this.mouseMoveEdit=this.onMouseMoveEdit.bind(this),e.domElement.instance.addEventListener("mousedown",this.mouseDownEdit,!1),e.domElement.instance.addEventListener("mousemove",this.mouseMoveEdit,!1),this.keyboardControls.length>0||(this.keyDown=this.onKeyDown.bind(this),this.keyUp=this.onKeyUp.bind(this),e.domElement.instance.addEventListener("keydown",this.keyDown,!1),e.domElement.instance.addEventListener("keyup",this.keyUp,!1)),e.createInstance(),this.mouseWheelEdit=this.onMouseWheelEdit.bind(this),this.mouseUpEdit=this.onMouseUpEdit.bind(this),e.domElement.instance.addEventListener("wheel",this.mouseWheelEdit,!1),e.domElement.instance.addEventListener("mouseup",this.mouseUpEdit,!1)}},GameLib.System.Input.prototype.deRegisterEditorControls=function(){if(1===this.editorControls.length){var e=this.editorControls[0];e.domElement.instance.removeEventListener("mousedown",this.mouseDownEdit,!1),e.domElement.instance.removeEventListener("mousemove",this.mouseMoveEdit,!1),this.keyboardControls.length<1&&(e.domElement.instance.removeEventListener("keydown",this.keyDown,!1),e.domElement.instance.removeEventListener("keyup",this.keyUp,!1)),e.instance.dispose(),e.domElement.instance.removeEventListener("wheel",this.mouseWheelEdit,!1),e.domElement.instance.removeEventListener("mouseup",this.mouseUpEdit,!1)}},GameLib.System.Input.prototype.deRegisterTouchControls=function(){if(1===this.touchControls.length){var e=this.touchControls[0];e.domElement.instance.removeEventListener("touchstart",this.touchStart,!1),e.domElement.instance.removeEventListener("touchmove",this.touchMove,!1),e.domElement.instance.removeEventListener("touchend",this.touchEnd,!1),e.domElement.instance.removeEventListener("touchcancel",this.touchCancel,!1)}},GameLib.System.Input.prototype.deRegisterKeyboardControls=function(){if(1===this.keyboardControls.length){var e=this.keyboardControls[0];e.domElement.instance.removeEventListener("keydown",this.keyboardKeyDown,!1),e.domElement.instance.removeEventListener("keyup",this.keyboardKeyUp,!1)}},GameLib.System.Input.prototype.deRegisterMouseControls=function(){if(1===this.mouseControls.length){var e=this.mouseControls[0];e.domElement.instance.removeEventListener("mousedown",this.mouseDown,!1),e.domElement.instance.removeEventListener("mousemove",this.mouseMove,!1),e.domElement.instance.removeEventListener("wheel",this.mouseWheel,!1),e.domElement.instance.removeEventListener("mouseup",this.mouseUp,!1)}},GameLib.System.Input.prototype.onKeyboardKeyUp=function(e){GameLib.Event.Emit(GameLib.Event.KEY_DOWN,{code:e.code})},GameLib.System.Input.prototype.onKeyboardKeyDown=function(e){GameLib.Event.Emit(GameLib.Event.KEY_UP,{code:e.code})},GameLib.System.Input.prototype.onTouchStart=function(e){this.sensitivityCounter=0,this.touches={};for(var t=0;te.changedTouches[h].pageX&&(u+=l),this.touches[t].lastTouchY>e.changedTouches[h].pageY&&(d+=p),this.touches[t].lastTouchY=this.touchSensitivity&&(this.sensitivityCounter=0,GameLib.Event.Emit(GameLib.Event.TOUCH_MOVE,this.touches))},GameLib.System.Input.prototype.onTouchCancel=function(e){this.sensitivityCounter=0;for(var t=0;tt.distance?1:0});var a=n.map(function(e){return e.mesh}),s=a[0];s&&(e.preventDefault(),e.stopImmediatePropagation(),s.selected?this.deSelectMesh(s):this.selectMesh(s),GameLib.Event.Emit(GameLib.Event.BUILD_GUI,null))}}.bind(this))},GameLib.System.Input.prototype.onMouseMoveEdit=function(e){},GameLib.System.Input.prototype.onMouseUpEdit=function(e){this.editorControls.map(function(e){e.camera.position.x=e.camera.instance.position.x,e.camera.position.y=e.camera.instance.position.y,e.camera.position.z=e.camera.instance.position.z,e.camera.quaternion.x=e.camera.instance.quaternion.x,e.camera.quaternion.y=e.camera.instance.quaternion.y,e.camera.quaternion.z=e.camera.instance.quaternion.z,e.camera.quaternion.w=e.camera.instance.quaternion.w,e.camera.lookAt.x=e.instance.center.x,e.camera.lookAt.y=e.instance.center.y,e.camera.lookAt.z=e.instance.center.z,e.camera.lookAt.instance.copy(e.instance.center)})},GameLib.System.Input.prototype.onMouseWheelEdit=function(e){this.editorControls.map(function(e){e.camera.position.x=e.camera.instance.position.x,e.camera.position.y=e.camera.instance.position.y,e.camera.position.z=e.camera.instance.position.z})},GameLib.System.Input.prototype.selectMesh=function(e){!0!==e.selected&&(e.selected=!0,e.createHelper(),GameLib.Event.Emit(GameLib.Event.MESH_SELECTED,{mesh:e}))},GameLib.System.Input.prototype.deSelectMesh=function(e){e.selected=!1,e.removeHelper(),GameLib.Event.Emit(GameLib.Event.MESH_DESELECTED,{mesh:e})},GameLib.System.Linking=function(e){GameLib.System.call(this,e),this.dependencies={},this.resolved=[],this.componentCreatedSubscription=null,this.componentUpdateSubcription=null,this.componentClonedSubscription=null,this.registerDependenciesSubscription=null,this.componentRemoveSubscription=null,this.parentSceneChangeSubscription=null,this.parentPhysicsWorldChangeSubscription=null,this.parentEntityChangeSubscription=null,this.instanceCreatedSubscription=null,this.instanceClonedSubscription=null,this.removeMeshSubscription=null,this.imageChangedSubscription=null,this.materialTypeChangedSubscription=null,this.arrayItemAddedSubscription=null},GameLib.System.Linking.prototype=Object.create(GameLib.System.prototype),GameLib.System.Linking.prototype.constructor=GameLib.System.Linking,GameLib.System.Linking.prototype.start=function(){GameLib.System.prototype.start.call(this),this.componentCreatedSubscription=this.subscribe(GameLib.Event.COMPONENT_CREATED,this.componentCreated.bind(this)),this.componentUpdateSubcription=this.subscribe(GameLib.Event.COMPONENT_UPDATE,this.componentUpdate.bind(this)),this.componentClonedSubscription=this.subscribe(GameLib.Event.COMPONENT_CLONED,this.componentCloned.bind(this)),this.registerDependenciesSubscription=this.subscribe(GameLib.Event.REGISTER_DEPENDENCIES,this.registerDependenciesDirect),this.componentRemoveSubscription=this.subscribe(GameLib.Event.REMOVE_COMPONENT,this.removeComponent),this.parentSceneChangeSubscription=this.subscribe(GameLib.Event.PARENT_SCENE_CHANGE,this.onParentSceneChange),this.parentPhysicsWorldChangeSubscription=this.subscribe(GameLib.Event.PARENT_WORLD_CHANGE,this.onParentWorldChange),this.parentEntityChangeSubscription=this.subscribe(GameLib.Event.PARENT_ENTITY_CHANGE,this.onParentEntityChange),this.instanceCreatedSubscription=this.subscribe(GameLib.Event.INSTANCE_CREATED,this.instanceCreated),this.instanceClonedSubscription=this.subscribe(GameLib.Event.INSTANCE_CLONED,this.instanceCloned),this.removeMeshSubscription=this.subscribe(GameLib.Event.REMOVE_MESH,this.removeMesh),this.imageChangedSubscription=this.subscribe(GameLib.Event.IMAGE_CHANGED,this.imageChanged),this.materialTypeChangedSubscription=this.subscribe(GameLib.Event.MATERIAL_TYPE_CHANGED,this.materialTypeChanged),this.arrayItemAddedSubscription=this.subscribe(GameLib.Event.ARRAY_ITEM_ADDED,this.arrayItemAdded)},GameLib.System.Linking.prototype.link=function(e,t){for(var i in e.linkedObjects)if(e.linkedObjects.hasOwnProperty(i))if(e.linkedObjects[i]instanceof Array){var n=[];e[i]=e[i].map(function(a){return a===t.component.id?(n.push({parent:e,property:i,child:t.component}),t.component):a}),n.map(function(e){GameLib.Event.Emit(GameLib.Event.COMPONENT_LINKED,e)})}else e[i]&&e[i]===t.component.id&&(e[i]=t.component,GameLib.Event.Emit(GameLib.Event.COMPONENT_LINKED,{parent:e,property:i,child:t.component}))},GameLib.System.Linking.prototype.resolveDependencies=function(e){if(!e.loaded)return!1;var t=this.dependencies[e.id];if(GameLib.Utils.UndefinedOrNull(t))return!1;t.map(function(t){if(this.link(t,{component:e}),GameLib.Utils.PushUnique(this.resolved,e),GameLib.Utils.UndefinedOrNull(t.dependencies)||t.dependencies instanceof Array&&0===t.dependencies.length){if(!t.loaded||GameLib.Utils.UndefinedOrNull(t.instance))try{t.performInstanceCreation()}catch(e){console.error(e)}}else{var i=t.dependencies.indexOf(e.id);-1!==i&&t.dependencies.splice(i,1),0===t.dependencies.length&&t.performInstanceCreation()}}.bind(this)),delete this.dependencies[e.id],GameLib.Event.Emit(GameLib.Event.UNRESOLVED_DEPENDENCIES_UPDATE,{dependencies:this.dependencies}),GameLib.Utils.IsEmpty(this.dependencies)&&(GameLib.Event.Emit(GameLib.Event.COMPONENTS_LINKED,{components:this.resolved.map(function(e){return e})}),this.resolved=[])},GameLib.System.Linking.prototype.registerDependencies=function(e){e.dependencies&&e.dependencies.length>0&&(e.dependencies=e.dependencies.reduce(function(t,i){var n=GameLib.EntityManager.Instance.findComponentById(i);return n&&n.loaded?(this.link(e,{component:n}),GameLib.Utils.PushUnique(this.resolved,n)):(GameLib.Utils.UndefinedOrNull(this.dependencies[i])&&(this.dependencies[i]=[]),-1===this.dependencies[i].indexOf(e)&&(this.dependencies[i].push(e),GameLib.Event.Emit(GameLib.Event.UNRESOLVED_DEPENDENCIES_UPDATE,{dependencies:this.dependencies})),t.push(i)),t}.bind(this),[]),0===e.dependencies.length&&e.performInstanceCreation())},GameLib.System.Linking.prototype.componentCreated=function(e){var t=e.component;this.registerDependencies(t),this.resolveDependencies(t)},GameLib.System.Linking.prototype.componentUpdate=function(e){var t=GameLib.EntityManager.Instance.findComponentByName(e.name);return GameLib.Utils.UndefinedOrNull(e.property)?void console.warn("invalid data format - we expect data.property"):GameLib.Utils.UndefinedOrNull(e.value)?void console.warn("invalid data format - we expect data.value"):(GameLib.Utils.UndefinedOrNull(e.subProperty)?t[e.property]=e.value:t[e.property][e.subProperty]=e.value,void t.updateInstance(e.property))},GameLib.System.Linking.prototype.componentCloned=function(e){if(this.componentCreated(e),e.component instanceof GameLib.D3.Mesh){if(!(e.parent instanceof GameLib.D3.Mesh))throw new Error("no scene parent");e.parent.parentScene&&e.parent.parentScene.addClone(e.component)}},GameLib.System.Linking.prototype.registerDependenciesDirect=function(e){this.registerDependencies(e.component)},GameLib.System.Linking.prototype.removeComponent=function(e){if(!e.component)return void console.error("no component to remove");var t=e.component;t.parentEntity instanceof GameLib.Entity&&t.parentEntity.removeComponent(t),t instanceof GameLib.D3.Mesh&&t.parentScene instanceof GameLib.D3.Scene&&(t.removeHelper(),t.parentScene.removeObject(t)),t instanceof GameLib.D3.Light&&t.parentScene instanceof GameLib.D3.Scene&&t.parentScene.removeObject(t),t instanceof GameLib.Entity&&GameLib.EntityManager.Instance.removeEntity(t)},GameLib.System.Linking.prototype.imageChanged=function(e){GameLib.EntityManager.Instance.queryComponents(GameLib.Component.MATERIAL).map(function(t){-1!==t.getTextures().indexOf(e.texture)&&t.updateInstance("diffuseMap")})},GameLib.System.Linking.prototype.arrayItemAdded=function(e){e.component instanceof GameLib.D3.PhysicsWorld&&e.item instanceof GameLib.D3.RigidBody&&e.component.addRigidBody(e.item),e.component instanceof GameLib.D3.Mesh&&e.item instanceof GameLib.D3.Material&&e.component.addMaterial(e.item)},GameLib.System.Linking.prototype.instanceCloned=function(e){},GameLib.System.Linking.prototype.instanceCreated=function(e){this.resolveDependencies(e.component),e.component instanceof GameLib.Image&&GameLib.EntityManager.Instance.queryComponents(GameLib.Component.TEXTURE).map(function(t){t.image!==e.component&&-1===t.images.indexOf(e.component)||t.updateInstance("image")}),e.component instanceof GameLib.D3.Scene&&Object.keys(GameLib.EntityManager.Instance.idRegister).map(function(t){GameLib.EntityManager.Instance.idRegister[t].parentScene===e.component.id&&(GameLib.EntityManager.Instance.idRegister[t].parentScene=e.component)}),e.component.parentScene&&"string"==typeof e.component.parentScene&&GameLib.EntityManager.Instance.queryComponents(GameLib.Component.SCENE).map(function(t){e.component.parentScene===t.id&&(e.component.parentScene=t,t.addObject(e.component))}),e.component.parentEngine&&"string"==typeof e.component.parentEngine&&GameLib.EntityManager.Instance.queryComponents(GameLib.Component.PARTICLE_ENGINE).map(function(t){e.component.parentEngine===t.id&&(e.component.parentEngine=t)}),e.component instanceof GameLib.D3.Mesh&&(e.preventParentMeshCheck||Object.keys(GameLib.EntityManager.Instance.idRegister).map(function(t){GameLib.EntityManager.Instance.idRegister[t].parentMesh===e.component.id&&(GameLib.EntityManager.Instance.idRegister[t].parentMesh=e.component,GameLib.EntityManager.Instance.idRegister[t]instanceof GameLib.D3.Mesh&&GameLib.EntityManager.Instance.idRegister[t].setParentMesh(e.component))})),e.component.parentMesh&&"string"==typeof e.component.parentMesh&&GameLib.EntityManager.Instance.queryComponents(GameLib.Component.MESH).map(function(t){e.component.parentMesh===t.id&&(e.component.parentMesh=t,e.component instanceof GameLib.D3.Mesh&&e.component.setParentMesh(t))}),e.component.parentPhysicsWorld&&"string"==typeof e.component.parentPhysicsWorld&&GameLib.EntityManager.Instance.queryComponents(GameLib.Component.PHYSICS_WORLD).map(function(t){e.component.parentPhysicsWorld===t.id&&(e.component.parentPhysicsWorld=t,"function"==typeof e.component.instance.addToWorld&&(e.component.instance.addToWorld(t.instance),console.log("instance added to physics world")))})},GameLib.System.Linking.prototype.materialTypeChanged=function(e){GameLib.EntityManager.Instance.queryComponents(GameLib.Component.MESH).map(function(t){t.materials.reduce(function(t,i){return i===e.material&&(t=!0),t},!1)&&(1===t.materials.length?t.instance.material=t.materials[0].instance:t.instance.material=t.materials.map(function(e){return e.instance}),t.instance.geometry.uvsNeedUpdate=!0,t.instance.material.needsUpdate=!0)})},GameLib.System.Linking.prototype.onParentWorldChange=function(e){e.object instanceof GameLib.D3.RigidBody&&(e.originalWorld instanceof GameLib.D3.PhysicsWorld&&e.originalWorld.removeRigidBody(e.object),e.newWorld instanceof GameLib.D3.PhysicsWorld&&e.newWorld.addRigidBody(e.object))},GameLib.System.Linking.prototype.onParentSceneChange=function(e){if(e.object instanceof GameLib.D3.Mesh||e.object instanceof GameLib.D3.Light){var t=GameLib.EntityManager.Instance.findHelperByObject(e.object);t&&(e.originalScene&&e.originalScene.instance&&e.originalScene.instance.remove(t.instance),e.newScene.instance.add(t.instance)),e.originalScene&&e.originalScene.removeObject&&e.originalScene.removeObject(e.object),e.newScene&&e.newScene.addObject(e.object)}},GameLib.System.Linking.prototype.onParentEntityChange=function(e){e.originalEntity instanceof GameLib.Entity&&e.originalEntity.removeComponent(e.object),e.newEntity instanceof GameLib.Entity&&e.newEntity.addComponent(e.object),GameLib.Event.Emit(GameLib.Event.PARENT_ENTITY_CHANGED,{originalEntity:e.originalEntity,newEntity:e.newEntity,component:e.object})},GameLib.System.Linking.prototype.removeMesh=function(e){var t=e.meshes.reduce(function(e,t){return e.push(t),t.getChildrenComponents().map(function(t){e.push(t)}),e},[]),i=GameLib.EntityManager.Instance.queryComponents(GameLib.Component.MESH);i=i.filter(function(t){return-1===e.meshes.indexOf(t)});var n=i.reduce(function(e,t){return e.push(t),t.getChildrenComponents().map(function(t){e.push(t)}),e},[]);t=t.filter(function(e){return-1===n.indexOf(e)}),t.map(function(e){e.remove()})},GameLib.System.Linking.prototype.stop=function(){GameLib.System.prototype.stop.call(this),this.componentCreatedSubscription.remove(),this.componentUpdateSubcription.remove(),this.componentClonedSubscription.remove(),this.registerDependenciesSubscription.remove(),this.componentRemoveSubscription.remove(),this.parentSceneChangeSubscription.remove(),this.parentPhysicsWorldChangeSubscription.remove(),this.parentEntityChangeSubscription.remove(),this.instanceCreatedSubscription.remove(),this.instanceClonedSubscription.remove(),this.removeMeshSubscription.remove(),this.imageChangedSubscription.remove(),this.materialTypeChangedSubscription.remove(),this.arrayItemAddedSubscription.remove()},GameLib.System.Particle=function(e){GameLib.System.call(this,e),this.engines=[],this.totalTime=0,this.instanceCreatedSubscription=null,this.removeComponentSubscription=null,this.beforeRenderSubscription=null},GameLib.System.Particle.prototype=Object.create(GameLib.System.prototype),GameLib.System.Particle.prototype.constructor=GameLib.System.Particle,GameLib.System.Particle.prototype.start=function(){GameLib.System.prototype.start.call(this),this.particleEngines=GameLib.EntityManager.Instance.queryComponents(GameLib.Component.PARTICLE_ENGINE),this.instanceCreatedSubscription=GameLib.Event.Subscribe(GameLib.Event.INSTANCE_CREATED,this.instanceCreated.bind(this)),this.removeComponentSubscription=GameLib.Event.Subscribe(GameLib.Event.REMOVE_COMPONENT,this.removeComponent.bind(this)),this.beforeRenderSubscription=GameLib.Event.Subscribe(GameLib.Event.BEFORE_RENDER,this.beforeRender.bind(this))},GameLib.System.Particle.prototype.instanceCreated=function(e){e.component instanceof GameLib.D3.ParticleEngine&&this.particleEngines.push(e.component)},GameLib.System.Particle.prototype.removeComponent=function(e){if(e.component instanceof GameLib.D3.ParticleEngine){var t=this.particleEngines.indexOf(e.component);-1!==t&&this.particleEngines.splice(t,1)}},GameLib.System.Particle.prototype.beforeRender=function(e){this.totalTime+=e.delta,this.particleEngines.map(function(t){if(!(GameLib.Utils.UndefinedOrNull(t.camera)||GameLib.Utils.UndefinedOrNull(t.templateParticle)||GameLib.Utils.UndefinedOrNull(t.templateParticle.mesh)||GameLib.Utils.UndefinedOrNull(t.templateParticle.mesh.parentScene)||GameLib.Utils.UndefinedOrNull(t.templateParticle.mesh.parentScene.instance))&&(t.elapsed+=e.delta,t.particles=t.particles.reduce(function(i,n){var a=n.userData.speed;return n.userData.speedType===GameLib.D3.Particle.SPEED_TYPE_CONSTANT&&(a=e.delta*n.userData.speed),n.userData.speedType===GameLib.D3.Particle.SPEED_TYPE_LINEAR&&(a=e.delta*n.userData.speed,n.userData.speed+=a),n.userData.speedType===GameLib.D3.Particle.SPEED_TYPE_EXPONENTIAL&&(a=Math.pow(n.userData.speed,2)*e.delta,n.userData.speed+=a),n.userData.speedType===GameLib.D3.Particle.SPEED_TYPE_LOGARITHMIC&&(a=Math.log(n.userData.speed)*e.delta,n.userData.speed+=a),n.userData.speedType===GameLib.D3.Particle.SPEED_TYPE_ONE_OVER_LOG&&(a=1/Math.log(n.userData.speed)*e.delta,n.userData.speed+=a),n.userData.speedType===GameLib.D3.Particle.SPEED_TYPE_EXP&&(a=Math.exp(n.userData.speed)*e.delta,n.userData.speed+=a),n.userData.speedType===GameLib.D3.Particle.SPEED_TYPE_ONE_OVER_EXP&&(a=1/Math.exp(n.userData.speed)*e.delta,n.userData.speed+=a),n.position.x+=n.userData.direction.x*a,n.position.y+=n.userData.direction.y*a,n.position.z+=n.userData.direction.z*a,t.templateParticle.scaleType,GameLib.D3.Particle.SCALE_TYPE_CONSTANT,t.templateParticle.scaleType===GameLib.D3.Particle.SCALE_TYPE_LINEAR&&(n.scale.x+=n.userData.scale.x*e.delta,n.scale.y+=n.userData.scale.x*e.delta,n.scale.z+=n.userData.scale.x*e.delta),n.quaternion.copy(t.camera.instance.quaternion),t.templateParticle.opacityType===GameLib.D3.Particle.OPACITY_TYPE_INCREASE_LINEAR&&(n.material.opacity+=t.templateParticle.opacityFactor),t.templateParticle.opacityType===GameLib.D3.Particle.OPACITY_TYPE_DECREASE_LINEAR&&(n.material.opacity-=t.templateParticle.opacityFactor),n.userData.elapsed+=e.delta,n.userData.elapsed>n.userData.lifeTime||n.material.opacity<0?(n.userData.scene.remove(n),n.geometry.dispose(),n.material.dispose()):i.push(n),i},[]),t.disabledForRemoval&&0===t.particles.length&&GameLib.Event.Emit(GameLib.Event.REMOVE_PARTICLE_ENGINE,{component:t}),t.enabled&&!t.disabledForRemoval)){var i=null;if(t.pulse){if(0===t.particles.length){t.elapsed=0;for(var n=0;nt.frequency&&(t.elapsed=0,i=t.templateParticle.cloneInstance(),t.particles.push(i))}}.bind(this))},GameLib.System.Particle.prototype.stop=function(){GameLib.System.prototype.stop.call(this),this.instanceCreatedSubscription.remove(),this.removeComponentSubscription.remove(),this.beforeRenderSubscription.remove()},GameLib.System.Physics=function(e){GameLib.System.call(this,e),this.worlds=[],this.beforeRenderSubscription=null,this.afterRenderSubscription=null},GameLib.System.Physics.prototype=Object.create(GameLib.System.prototype),GameLib.System.Physics.prototype.constructor=GameLib.System.Physics,GameLib.System.Physics.prototype.start=function(){GameLib.System.prototype.start.call(this),this.worlds=GameLib.EntityManager.Instance.queryComponents(GameLib.Component.PHYSICS_WORLD),this.beforeRenderSubscription=this.subscribe(GameLib.Event.BEFORE_RENDER,this.beforeRender)},GameLib.System.Physics.prototype.beforeRender=function(e){this.worlds.map(function(t){t.instance&&(t.instance.step(e.delta),t.rigidBodies.map(function(e){e.position.x=e.instance.position.x,e.position.y=e.instance.position.y,e.position.z=e.instance.position.z,e.quaternion.x=e.instance.quaternion.x,e.quaternion.y=e.instance.quaternion.y,e.quaternion.z=e.instance.quaternion.z,e.quaternion.w=e.instance.quaternion.w,e.parentMesh.position.x=e.instance.position.x,e.parentMesh.position.y=e.instance.position.y,e.parentMesh.position.z=e.instance.position.z,e.parentMesh.quaternion.x=e.instance.quaternion.x,e.parentMesh.quaternion.y=e.instance.quaternion.y,e.parentMesh.quaternion.z=e.instance.quaternion.z,e.parentMesh.quaternion.w=e.instance.quaternion.w,e.instance.getVelocityAtWorldPoint(new CANNON.Vec3(0,0,0),e.velocity.instance),e.velocity.x=e.velocity.instance.x,e.velocity.y=e.velocity.instance.y,e.velocity.z=e.velocity.instance.z,e.parentMesh.updateRotationFromAxisAngle=!1,e.parentMesh.updateInstance(),e.parentMesh.updateRotationFromAxisAngle=!0}))}.bind(this))},GameLib.System.Physics.prototype.stop=function(){GameLib.System.prototype.stop.call(this),this.worlds=[],this.rigidBodies=[],this.wheels=[],this.vehicles=[],this.beforeRenderSubscription&&this.beforeRenderSubscription.remove(),this.afterRenderSubscription&&this.afterRenderSubscription.remove()},GameLib.System.Render=function(e,t){GameLib.System.call(this,e),this.renderSubscription=null,this.clock=new GameLib.Clock(t),this.delta=null,this.animationFrameHook=null},GameLib.System.Render.prototype=Object.create(GameLib.System.prototype),GameLib.System.Render.prototype.constructor=GameLib.System.Render,GameLib.System.Render.prototype.start=function(){GameLib.System.prototype.start.call(this),this.renderers=GameLib.EntityManager.Instance.queryComponents(GameLib.Component.RENDERER),this.statistics=GameLib.EntityManager.Instance.queryComponents(GameLib.Component.STATS),this.instanceCreatedSubscription=GameLib.Event.Subscribe(GameLib.Event.INSTANCE_CREATED,this.instanceCreated.bind(this)), -this.removeComponentSubscription=GameLib.Event.Subscribe(GameLib.Event.REMOVE_COMPONENT,this.removeComponent.bind(this)),this.renderSubscription=this.subscribe(GameLib.Event.RENDER,this.render),this.windowResizeSubscription=this.subscribe(GameLib.Event.WINDOW_RESIZE,this.windowResize),window.addEventListener("resize",this.nativeWindowResize,!1),GameLib.Event.Emit(GameLib.Event.WINDOW_RESIZE,{width:window.innerWidth,height:window.innerHeight}),this.run()},GameLib.System.Render.prototype.run=function(){this.animationFrameHook=requestAnimationFrame(this.run.bind(this)),this.delta=this.clock.getDelta(),GameLib.Event.Emit(GameLib.Event.RENDER,{delta:this.delta})},GameLib.System.Render.prototype.nativeWindowResize=function(){GameLib.Event.Emit(GameLib.Event.WINDOW_RESIZE,{width:window.innerWidth,height:window.innerHeight})},GameLib.System.Render.prototype.windowResize=function(e){var t=e.width/e.height;GameLib.EntityManager.Instance.queryComponents(GameLib.Component.CAMERA).map(function(e){e.aspect=t,e.updateInstance("aspect")}),GameLib.EntityManager.Instance.queryComponents(GameLib.Component.RENDERER).map(function(t){t.setSize(e.width,e.height)}),GameLib.Event.Emit(GameLib.Event.CUSTOM_CODE_WINDOW_RESIZE,{aspect:t,width:e.width,height:e.height})},GameLib.System.Render.prototype.instanceCreated=function(e){e.component instanceof GameLib.D3.Renderer&&this.renderers.push(e.component),e.component instanceof GameLib.Stats&&this.statistics.push(e.component)},GameLib.System.Render.prototype.removeComponent=function(e){if(e.component instanceof GameLib.D3.Renderer){var t=this.renderers.indexOf(e.component);-1!==t?(console.log("removing renderer from system"),this.renderers.splice(t,1)):console.log("failed to find the renderer in the system : "+e.component.name)}},GameLib.System.Render.prototype.render=function(e){if(this.statistics&&this.statistics.map(function(e){e.start()}),GameLib.Event.Emit(GameLib.Event.BEFORE_RENDER,e),this.renderers.length<1);else if(1===this.renderers.length)this.renderers[0].render(e.delta);else{var t=this.renderers.reduce(function(e,t){return t.scenes.map(function(t){e.push(t)}),e},[]),i=GameLib.EntityManager.Instance.defaultRenderer;GameLib.Utils.UndefinedOrNull(i)&&(i=this.renderers[0]),i.render(e.delta,t)}GameLib.Event.Emit(GameLib.Event.AFTER_RENDER,e),this.statistics&&this.statistics.map(function(e){e.end()})},GameLib.System.Render.prototype.stop=function(){GameLib.System.prototype.stop.call(this),cancelAnimationFrame(this.animationFrameHook),this.instanceCreatedSubscription.remove(),this.removeComponentSubscription.remove(),this.renderSubscription.remove(),window.removeEventListener("resize",this.nativeWindowResize,!1),this.windowResizeSubscription.remove(),this.renderers.map(function(e){e.statistics&&(e.statistics.resize(),e.domElement.instance.parentElement.removeChild(e.statistics.instance.dom))}),this.renderers=[]},GameLib.System.Socket=function(e){GameLib.System.call(this,e),this.totalTime=0,this.castComponents=[],this.receiveComponents=[],this.servers=[],this.instanceCreatedSubscription=null,this.removeComponentSubscription=null,this.beforeRenderSubscription=null},GameLib.System.Socket.prototype=Object.create(GameLib.System.prototype),GameLib.System.Socket.prototype.constructor=GameLib.System.Socket,GameLib.System.Socket.prototype.start=function(){GameLib.System.prototype.start.call(this),this.castComponents=GameLib.EntityManager.Instance.queryComponents(GameLib.Component.SOCKET_CAST),this.receiveComponents=GameLib.EntityManager.Instance.queryComponents(GameLib.Component.SOCKET_RECEIVE),this.servers=GameLib.EntityManager.Instance.queryComponents(GameLib.Component.SERVER),this.instanceCreatedSubscription=GameLib.Event.Subscribe(GameLib.Event.INSTANCE_CREATED,this.instanceCreated.bind(this)),this.removeComponentSubscription=GameLib.Event.Subscribe(GameLib.Event.REMOVE_COMPONENT,this.removeComponent.bind(this)),this.beforeRenderSubscription=GameLib.Event.Subscribe(GameLib.Event.BEFORE_RENDER,this.beforeRender.bind(this))},GameLib.System.Socket.prototype.connect=function(e){console.log(e.name+" is connecting to the server "+e.serverIp)},GameLib.System.Socket.prototype.disconnect=function(e){console.log(e.name+" is disconnecting from server "+e.serverIp)},GameLib.System.Socket.prototype.instanceCreated=function(e){e.component instanceof GameLib.Socket.Cast&&GameLib.Utils.PushUnique(this.castComponents,e.component),e.component instanceof GameLib.Socket.Receive&&GameLib.Utils.PushUnique(this.receiveComponents,e.component),e.component instanceof GameLib.Server&&GameLib.Utils.PushUnique(this.servers,e.component)},GameLib.System.Socket.prototype.removeComponent=function(e){var t;e.component instanceof GameLib.Socket.Cast&&(t=this.castComponents.indexOf(e.component),-1!==t?this.castComponents.splice(t,1):console.log("Socket System out of Cast Component sync")),e.component instanceof GameLib.Socket.Receive&&(t=this.receiveComponents.indexOf(e.component),-1!==t?this.receiveComponents.splice(t,1):console.log("Socket System out of Receive Component sync")),e.component instanceof GameLib.Server&&(t=this.servers.indexOf(e.component),-1!==t?this.servers.splice(t,1):console.log("Socket System out of Server Component sync"))},GameLib.System.Socket.prototype.beforeRender=function(e){this.totalTime+=e.delta},GameLib.System.Socket.prototype.stop=function(){GameLib.System.prototype.stop.call(this),this.instanceCreatedSubscription.remove(),this.removeComponentSubscription.remove(),this.beforeRenderSubscription.remove(),this.servers=this.servers.reduce(function(e,t){t.disconnect()||e.push(t)}.bind(this),[]),0!==this.servers.length&&console.warn(this.servers.length+" connections still open after socket system stopped")},GameLib.System.Storage=function(e,t,i,n,a,s,o,r,c){GameLib.System.call(this,e),GameLib.Utils.UndefinedOrNull(t)&&(t=null),this.token=t,GameLib.Utils.UndefinedOrNull(i)&&(console.warn("Need an API Upload URL for a storage system"),i=""),this.apiUploadUrl=i,GameLib.Utils.UndefinedOrNull(n)&&(n=null),this.onImageLoaded=n,GameLib.Utils.UndefinedOrNull(a)&&(a=null),this.onImageProgress=a,GameLib.Utils.UndefinedOrNull(s)&&(s=null),this.onImageError=s,GameLib.Utils.UndefinedOrNull(o)&&(o=null),this.onComponentLoaded=o,GameLib.Utils.UndefinedOrNull(r)&&(r=null),this.onComponentProgress=r,GameLib.Utils.UndefinedOrNull(c)&&(c=null),this.onComponentError=c,this.loaded=[],this.loading=[],this.failed=[],this.otherDependencies=[],this.loginSubscription=null,this.saveSubscription=null,this.loadSubscription=null,this.loadImageSubscription=null,this.blenderDataSubscription=null,this.imageUploadCompleteSubscription=null,this.fetchComponentTypesSubscription=null,this.fetchComponentsSubscription=null},GameLib.System.Storage.prototype=Object.create(GameLib.System.prototype),GameLib.System.Storage.prototype.constructor=GameLib.System.Storage,GameLib.System.Storage.prototype.start=function(){GameLib.System.prototype.start.call(this),this.loginSubscription=this.subscribe(GameLib.Event.LOGGED_IN,function(e){this.token=e.token}),this.saveSubscription=this.subscribe(GameLib.Event.SAVE_COMPONENT,this.save),this.loadSubscription=this.subscribe(GameLib.Event.LOAD_COMPONENT,this.load),this.deleteSubscription=this.subscribe(GameLib.Event.DELETE_COMPONENT,this.delete),this.loadImageSubscription=this.subscribe(GameLib.Event.LOAD_IMAGE,this.loadImage),this.loadFontSubscription=this.subscribe(GameLib.Event.LOAD_FONT,this.loadFont),this.blenderDataSubscription=this.subscribe(GameLib.Event.BLENDER_DATA_RECEIVED,this.processBlenderData),this.imageUploadCompleteSubscription=this.subscribe(GameLib.Event.IMAGE_UPLOAD_COMPLETE,this.imageUploadComplete),this.fetchComponentTypesSubscription=this.subscribe(GameLib.Event.FETCH_COMPONENT_TYPES,this.fetchComponentTypes),this.fetchComponentsSubscription=this.subscribe(GameLib.Event.FETCH_COMPONENTS,this.fetchComponents)},GameLib.System.Storage.prototype.delete=function(e){this.publish(GameLib.Event.GET_API_URL,null,function(t){if("undefined"==typeof XMLHttpRequest)return void console.log("Implement server side delete here");e.ids.map(function(e){var i=new XMLHttpRequest;i.open("POST",t.apiUrl+"/component/delete/"+e),i.setRequestHeader("Accept","application/json"),i.setRequestHeader("Content-Type","application/json"),i.setRequestHeader("x-authorization",t.passwoid),i.onreadystatechange=function(){if(4===this.readyState){try{var e=JSON.parse(this.responseText)}catch(e){GameLib.Event.Emit(GameLib.Event.DELETE_COMPONENT_ERROR,{message:this.responseText})}"success"===e.result?GameLib.Event.Emit(GameLib.Event.COMPONENT_DELETED,{message:e.message||"Successfully saved the component"}):GameLib.Event.Emit(GameLib.Event.DELETE_COMPONENT_ERROR,{message:e.message||"The server responded but failed to save the component"})}},i.send(JSON.stringify({session:this.token}))}.bind(this))}.bind(this),function(e){throw console.error(e.message),new Error(e.message)})},GameLib.System.Storage.prototype.save=function(e){var t=GameLib.Event.GET_API_URL;e.remote&&(t=GameLib.Event.GET_REMOTE_API_URL),this.publish(t,null,function(t){if("undefined"==typeof XMLHttpRequest)return void console.log("Implement server side save here");var i=new XMLHttpRequest;i.open("POST",t.apiUrl+"/component/create"),i.setRequestHeader("Accept","application/json"),i.setRequestHeader("Content-Type","application/json"),i.setRequestHeader("x-authorization",t.passwoid),i.onreadystatechange=function(){if(4===this.readyState){try{var t=JSON.parse(this.responseText)}catch(t){GameLib.Event.Emit(GameLib.Event.SAVE_COMPONENT_ERROR,{message:this.responseText,component:e.apiObject})}"success"===t.result?GameLib.Event.Emit(GameLib.Event.COMPONENT_SAVED,{message:t.message||"Successfully saved the component",component:e.apiObject}):GameLib.Event.Emit(GameLib.Event.SAVE_COMPONENT_ERROR,{message:t.message||"The server responded but failed to save the component",component:e.apiObject})}},i.send(JSON.stringify({component:e.apiObject,session:this.token}))})},GameLib.System.Storage.prototype.createRuntimeObject=function(e,t){try{var i=JSON.parse(e)}catch(e){return this.onComponentError&&this.onComponentError(e),t&&t({message:e.message||"JSON parse error"}),GameLib.Event.Emit(GameLib.Event.LOAD_COMPONENT_ERROR,{error:e}),null}if("success"!==i.result)return this.onComponentError&&this.onComponentError(id,i),t&&t({message:i.message||"Server load error"}),GameLib.Event.Emit(GameLib.Event.LOAD_COMPONENT_ERROR,{error:i}),null;var n=GameLib.Component.ConstructFromObject(i.component[0]);return n||t&&t({result:"failure",message:"Could not create a runtime component: "+i.component[0].name}),n},GameLib.System.Storage.prototype.loadComponent=function(e,t,i,n,a){t.map(function(e){GameLib.Utils.PushUnique(this.loading,e);var t=GameLib.EntityManager.Instance.findComponentById(e);t&&t.remove()}.bind(this)),t.map(function(t){var s=new XMLHttpRequest;s.onload=function(s){return function(){var o=s.createRuntimeObject.bind(s)(this.responseText);if(!o)return void s.failed.push(t);if(o.parentEntity&&"string"==typeof o.parentEntity&&GameLib.EntityManager.Instance.queryComponents(GameLib.Component.ENTITY).map(function(e){o.parentEntity===e.id&&(o.parentEntity=e)}),GameLib.Event.Emit(GameLib.Event.COMPONENT_CREATED,{component:o}),s.loaded.push(o.id),i){var r=o.getDependencies();s.otherDependencies.map(function(e){var t=r.indexOf(e);-1!==t&&r.splice(t,1)}),r.map(function(e){GameLib.Utils.PushUnique(this.otherDependencies,e)}.bind(s)),r=r.reduce(function(e,t){return-1===s.failed.indexOf(t)?e.push(t):console.log("ignoring failed component : "+t),e}.bind(s),[]),r=r.reduce(function(e,t){return GameLib.EntityManager.Instance.findComponentById(t)||e.push(t),e},[]),r=r.reduce(function(e,t){return-1===s.loaded.indexOf(t)&&e.push(t),e},[]),r.map(function(e){GameLib.Utils.PushUnique(s.loading,e)}),s.loadComponent(e,r,i,n,a)}GameLib.Event.Emit(GameLib.Event.LOAD_PROGRESS,{loading:s.loading.length,loaded:s.loaded.length}),s.onComponentLoaded&&s.onComponentLoaded(o),s.loading.length===s.loaded.length&&(console.log("loaded "+s.loaded.length+" components"),n&&n({components:s.loaded}))}}(this),s.onprogress=function(e){return function(t){var i=0;0!==t.total&&(i=Math.round(100*Number(t.loaded/t.total))),this.onComponentProgress&&this.onComponentProgress(e,i)}.bind(this)}(t),s.onerror=function(e){return function(t){console.warn("component load failed for component ID "+e),this.onComponentError&&this.onComponentError(e,t),a&&a({message:"xhr request failure"})}.bind(this)}(t),s.open("GET",e+"/component/load/"+t),s.send()}.bind(this))},GameLib.System.Storage.prototype.load=function(e,t,i){this.publish(GameLib.Event.GET_API_URL,null,function(n){if("undefined"==typeof XMLHttpRequest)return void console.log("Implement server side load here");e.ids&&e.ids.length>0?this.loadComponent(n.apiUrl,e.ids,e.includeDependencies,t,i):console.log("No components selected")}.bind(this),function(e){throw console.error(e.message),new Error(e.message)})},GameLib.System.Storage.prototype.xhrLoad=function(e,t,i){if("undefined"==typeof XMLHttpRequest)return void console.log("Implement server side load here");console.log("Loading...","success");var n=new XMLHttpRequest;n.open("GET",e),n.setRequestHeader("Accept","application/json"),n.setRequestHeader("Content-Type","application/json"),n.onreadystatechange=function(){if(4===n.readyState){if(!n.responseText)return console.log("Invalid response from server"),void i({message:"Invalid response from server"});try{var e=JSON.parse(n.responseText)}catch(e){e.message="Could not parse JSON",i(e)}if("success"!==e.result)return i({message:e.message||"Unknown Error Occurred"});t(e)}},n.onerror=i,n.send()},GameLib.System.Storage.prototype.fetchComponentTypes=function(e,t,i){this.xhrLoad(e.url,function(e){t({ids:e.ids})},i)},GameLib.System.Storage.prototype.fetchComponents=function(e,t,i){this.xhrLoad(e.url,function(e){t({components:e.component})},i)},GameLib.System.Storage.prototype.imageUploadComplete=function(e){e.images.map(function(e){var t=GameLib.EntityManager.Instance.findComponentById(e.id);t?(t.updateFromRawObject(e),t.updateInstance("path")):GameLib.Component.ConstructFromObject(e)}.bind(this))},GameLib.System.Storage.prototype.processBlenderData=function(e){console.log("loading blender data"),e.images.map(function(e){var t=GameLib.Component.ConstructFromObject(e);GameLib.Event.Emit(GameLib.Event.COMPONENT_CREATED,{component:t})}.bind(this)),e.textures.map(function(e){var t=GameLib.Component.ConstructFromObject(e);GameLib.Event.Emit(GameLib.Event.COMPONENT_CREATED,{component:t})}.bind(this)),e.materials.map(function(e){var t=GameLib.Component.ConstructFromObject(e);GameLib.Event.Emit(GameLib.Event.COMPONENT_CREATED,{component:t})}.bind(this)),e.meshes.map(function(e){var t=GameLib.Component.ConstructFromObject(e);GameLib.Event.Emit(GameLib.Event.COMPONENT_CREATED,{component:t})}.bind(this))},GameLib.System.Storage.prototype.loadFont=function(e,t,i){console.log("loading font : "+e.font.name),this.publish(GameLib.Event.GET_API_URL,null,function(n){var a=n.apiUrl+"/fonts/"+e.font.url+"?ts="+Date.now();(new THREE.FontLoader).load(a,function(e){GameLib.Utils.IsEmpty(e.data)?i({message:"font is empty"}):t(e)})}.bind(this),function(e){i(e)})},GameLib.System.Storage.prototype.loadImage=function(e,t,i){console.log("loading image : "+e.image.name),this.publish(GameLib.Event.GET_API_URL,null,function(n){var a=this.onImageLoaded,s=this.onImageProgress,o=this.onImageError,r=e.image,c=n.apiUrl+r.path+r.fileName+r.extension+"?ts="+Date.now(),m=new XMLHttpRequest;m.withCredentials=!0,m.open("OPTIONS",c),m.setRequestHeader("Content-Type","application/json"),m.onload=function(){var n=new XMLHttpRequest;n.withCredentials=!0,n.open("GET",c),n.setRequestHeader("Content-Type",r.contentType),n.responseType="blob",n.onload=function(){var n=!1,s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAAlC+aJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoWEQMQBXD4hQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAABRSURBVGje7c8xDQAwCAAwmA3koA/PU8FB0jpo1nRc9uI4AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBgX0fjEoBa8xN1z4AAAAASUVORK5CYII=";try{"application/json"!==this.response.type&&(s=window.URL.createObjectURL(this.response),n=!0)}catch(t){i&&i({result:"failure",message:"invalid server response trying to download image "+e.image.name})}var o=document.createElement("img");o.onload=function(){n&&window.URL.revokeObjectURL(s),t&&t(o),a&&a(r,e.createTexture)},o.src=s},n.onprogress=function(e){var t=0;0!==e.total&&(t=Math.round(100*Number(e.loaded/e.total))),s&&s(r,t),r.size=e.total},n.onerror=function(e){console.warn("image load failed for image "+r.name),i&&i(e),o&&o(r,e)},n.send()},m.onerror=function(e){console.warn("image pre-flight request failed for image "+r.name),i&&i(e),o&&o(r,e)},m.send()}.bind(this),function(e){throw console.error(e.message),new Error(e.message)})},GameLib.System.Storage.prototype.stop=function(){GameLib.System.prototype.stop.call(this),this.loginSubscription.remove(),this.loadSubscription.remove(),this.saveSubscription.remove(),this.loadImageSubscription.remove(),this.loadFontSubscription.remove(),this.blenderDataSubscription.remove(),this.imageUploadCompleteSubscription.remove(),this.deleteSubscription.remove(),this.fetchComponentTypesSubscription.remove(),this.fetchComponentsSubscription.remove()},GameLib.System.Visualization=function(e,t,i){GameLib.System.call(this,e),GameLib.Utils.UndefinedOrNull(t)&&GameLib.Event.Emit(GameLib.Event.GET_GRAPHICS_RUNTIME,null,function(e){t=e}.bind(this),function(){t=null}.bind(this)),this.graphics=t,GameLib.Utils.UndefinedOrNull(i)&&GameLib.Event.Emit(GameLib.Event.GET_PHYSICS_RUNTIME,null,function(e){i=e}.bind(this),function(){i=null}.bind(this)),this.physics=i,this.visualizationSubscription=null,this.stopVisualizationSubscription=null},GameLib.System.Visualization.prototype=Object.create(GameLib.System.prototype),GameLib.System.Visualization.prototype.constructor=GameLib.System.Visualization,GameLib.System.Visualization.prototype.start=function(){GameLib.System.prototype.start.call(this),this.visualizationSubscription=this.subscribe(GameLib.Event.VISUALIZE,this.visualize),this.stopVisualizationSubscription=this.subscribe(GameLib.Event.STOP_VISUALIZE,this.stopVisualize)},GameLib.System.Visualization.prototype.visualize=function(e){var t=e.shape;t.parentMesh;t.setFromMesh();var i=new GameLib.D3.API.Mesh;if(i.name="Visualization Mesh for Shape "+t.name,t instanceof GameLib.D3.Shape.HeightMap)for(var n=new CANNON.Vec3,a=new CANNON.Vec3,s=new CANNON.Vec3,o=0;o Math.PI) { - value -= (Math.PI * 2); - } - - while (value < -(Math.PI)) { - value += (Math.PI * 2); - } - - store = value; - } - }; -}; - -/** - * Returns an array of IDs representing the objects - * @param array - * @returns [] - * @constructor - */ -GameLib.Utils.IdArrayOrEmptyArray = function (array) { - if (GameLib.Utils.UndefinedOrNull(array)) { - return []; - } else { - - return array.map(function(item) { - - if (GameLib.Utils.UndefinedOrNull(item.id)) { - throw new Error('No ID found while trying to store IDs to array'); - } - - return item.id - }); - } -}; - -/** - * Links an object to its parent through idToObject array - * @param propertyString - * @param idToObject - * @param parentObject - * @param id - * @constructor - */ -GameLib.Utils.Link = function(propertyString, idToObject, parentObject, id) { - - if (!GameLib.Utils.UndefinedOrNull(parentObject[propertyString])) { - - if (!idToObject.hasOwnProperty(id)) { - console.warn('Linking failed for object:' + parentObject.name); - } - - parentObject[propertyString] = idToObject[id]; - } -}; - -/** - * Generates a random ID - * @returns {string} - * @constructor - */ -GameLib.Utils.RandomId = function(length) { - - if (GameLib.Utils.UndefinedOrNull(length)) { - length = 10; - } - - return Math.random().toString(36).substr(2, length); -}; - -GameLib.Utils.InvertWindingOrder = function(triangles) { - - for (var i = 0; i < triangles.length; i++) { - var v1 = triangles[i].v1; - triangles[i].v1 = triangles[i].v2; - triangles[i].v2 = v1; - - var backupUV = triangles[i].triangle.v1uv; - triangles[i].triangle.v1uv = triangles[i].triangle.v2uv; - triangles[i].triangle.v2uv = backupUV; - } - - return triangles; -}; - -/** - * Inverts a mesh winding order (and its instance) - * @param mesh GameLib.D3.Mesh - * @returns {*} - * @constructor - */ -GameLib.Utils.InvertMeshWindingOrder = function(mesh) { - - mesh.faces.forEach( - function (face) { - - var tmpV1 = face.v1; - face.v1 = face.v2; - face.v2 = tmpV1; - - var tmpV1uv = face.v1uv; - face.v1uv = face.v2uv; - face.v2uv = tmpV1uv; - - }.bind(this) - ); - - mesh.computeNormals = true; - mesh.createInstance(); -}; - -/** - * This function resets a the winding order of a mesh from a reference point V (the average center of the mesh) - */ -GameLib.Utils.ResetWindingOrder = function(faces, vertices) { - - var vertexList = new GameLib.API.Vector3.Points(); - - for (var v = 0; v < vertices.length; v++) { - vertexList.add(new GameLib.API.Vector3( - vertices[v].position.x, - vertices[v].position.y, - vertices[v].position.z - )); - } - - var V = vertexList.average(); - - var triangles = []; - - for (var s = 0; s < faces.length; s += 3) { - - var v0 = faces[s]; - var v1 = faces[s+1]; - var v2 = faces[s+2]; - - triangles.push( - { - v0 : v0, - v1 : v1, - v2 : v2, - edges : [ - {v0: v0, v1: v1}, - {v0: v1, v1: v2}, - {v0: v2, v1: v0} - ], - winding : 0, - edgeIndex : -1, - processed : false - } - ); - } - - for (var i = 0; i < triangles.length; i++) { - if ( - GameLib.API.Vector3.clockwise( - vertices[triangles[i].v0].position, - vertices[triangles[i].v1].position, - vertices[triangles[i].v2].position, - V - ) - ) { - console.log('clockwise'); - var bv1 = triangles[i].v1; - triangles[i].v1 = triangles[i].v2; - triangles[i].v2 = bv1; - } else { - console.log('not clockwise'); - } - } - - return triangles; -}; - -/** - * This function resets the winding order for triangles in faces, given an initial triangle and orientation edge - * used pseudocode from - * http://stackoverflow.com/questions/17036970/how-to-correct-winding-of-triangles-to-counter-clockwise-direction-of-a-3d-mesh - * We need to use a graph traversal algorithm, - * lets assume we have method that returns neighbor of triangle on given edge - * - * neighbor_on_egde( next_tria, edge ) - * - * to_process = set of pairs triangle and orientation edge, initial state is one good oriented triangle with any edge on it - * processed = set of processed triangles; initial empty - * - * while to_process is not empty: - * next_tria, orientation_edge = to_process.pop() - * add next_tria in processed - * if next_tria is not opposite oriented than orientation_edge: - * change next_tria (ABC) orientation (B<->C) - * for each edge (AB) in next_tria: - * neighbor_tria = neighbor_on_egde( next_tria, edge ) - * if neighbor_tria exists and neighbor_tria not in processed: - * to_process add (neighbor_tria, edge opposite oriented (BA)) - * @param faces GameLib.D3.Face[] - * @param orientationEdge GameLib.API.Vector2 - * @returns {Array} - */ -GameLib.Utils.FixWindingOrder = function(faces, orientationEdge) { - - /** - * Checks if a Face belonging to a TriangleEdge has already been processed - * @param processed TriangleEdge[] - * @param triangle Face - * @returns {boolean} - */ - function inProcessed(processed, triangle) { - - for (var i = 0; i < processed.length; i++) { - if (processed[i].triangle.equals(triangle)) { - return true; - } - } - - return false; - } - - /** - * Returns a neighbouring triangle on a specific edge - preserving the edge orientation - * @param edge GameLib.API.Vector2 - * @param faces GameLib.D3.Face[] - * @param currentTriangle - * @returns {*} - */ - function neighbourOnEdge(edge, faces, currentTriangle) { - - for (var i = 0; i < faces.length; i++) { - if ( - (faces[i].v0 === edge.x && faces[i].v1 === edge.y) || - (faces[i].v1 === edge.x && faces[i].v2 === edge.y) || - (faces[i].v2 === edge.x && faces[i].v0 === edge.y) || - (faces[i].v0 === edge.y && faces[i].v1 === edge.x) || - (faces[i].v1 === edge.y && faces[i].v2 === edge.x) || - (faces[i].v2 === edge.y && faces[i].v0 === edge.x) - ) { - - var triangle = new GameLib.D3.API.Face( - null, - null, - faces[i].v0index, - faces[i].v1index, - faces[i].v2index, - faces[i].materialIndex, - faces[i].uvs - ); - - if (triangle.equals(currentTriangle)) { - continue; - } - - return new GameLib.D3.TriangleEdge( - triangle, - edge - ); - } - } - - return null; - } - - var toProcess = [ - new GameLib.D3.TriangleEdge( - new GameLib.D3.API.Face( - null, - null, - faces[0].v0index, - faces[0].v1index, - faces[0].v2index, - faces[0].materialIndex, - faces[0].uvs - ), - orientationEdge - ) - ]; - - var processed = []; - - while (toProcess.length > 0) { - - var triangleEdge = toProcess.pop(); - - /** - * If edge is the same orientation (i.e. the edge order is the same as the given triangle edge) it needs to be reversed - * to have the same winding order) - */ - if ( - (triangleEdge.triangle.v0index === triangleEdge.edge.x && - triangleEdge.triangle.v1index === triangleEdge.edge.y) || - (triangleEdge.triangle.v1index === triangleEdge.edge.x && - triangleEdge.triangle.v2index === triangleEdge.edge.y) || - (triangleEdge.triangle.v2index === triangleEdge.edge.x && - triangleEdge.triangle.v0index === triangleEdge.edge.y) - ) { - var backupV = triangleEdge.triangle.v1index; - triangleEdge.triangle.v1index = triangleEdge.triangle.v2index; - triangleEdge.triangle.v2index = backupV; - - // var backupUV = triangleEdge.triangle.v1uv; - // triangleEdge.triangle.v1uv = triangleEdge.triangle.v2uv; - // triangleEdge.triangle.v2uv = backupUV; - // - var backupUV = triangleEdge.triangle.uvs[0][1]; - triangleEdge.triangle.uvs[0][1] = triangleEdge.triangle.uvs[0][2]; - triangleEdge.triangle.uvs[0][2] = backupUV; - } - - processed.push(triangleEdge); - - var edges = [ - new GameLib.API.Vector2( - triangleEdge.triangle.v0index, - triangleEdge.triangle.v1index - ), - new GameLib.API.Vector2( - triangleEdge.triangle.v1index, - triangleEdge.triangle.v2index - ), - new GameLib.API.Vector2( - triangleEdge.triangle.v2index, - triangleEdge.triangle.v0index - ) - ]; - - for (var j = 0; j < edges.length; j++) { - var neighbour = neighbourOnEdge(edges[j], faces, triangleEdge.triangle); - if (neighbour && !inProcessed(processed, neighbour.triangle)) { - toProcess.push(neighbour); - } - } - } - - /** - * In processed - we will have some duplicates - only add the unique ones - * @type {Array} - */ - var triangles = []; - for (var i = 0; i < processed.length; i++) { - var found = false; - for (var k = 0; k < triangles.length; k++) { - if (triangles[k].equals(processed[i].triangle)){ - found = true; - break; - } - } - if (!found) { - triangles.push(processed[i].triangle); - } - } - - return triangles; -}; - -/** - * This is a work-around function to fix polys which don't triangulate because - * they could lie on Z-plane (XZ or YZ)) - we translate the poly to the origin, systematically rotate the poly around - * Z then Y axis - * @param verticesFlat [] - * @param grain is the amount to systematically rotate the poly by - a finer grain means a more accurate maximum XY - * @return [] - */ -GameLib.Utils.FixPolyZPlane = function(verticesFlat, grain) { - - if ((verticesFlat.length % 3) !== 0 && !(verticesFlat.length > 9)) { - console.log("The vertices are not in the right length : " + verticesFlat.length); - } - - var vertices = []; - - var points = new GameLib.API.Quaternion.Points(); - - for (var i = 0; i < verticesFlat.length; i += 3) { - points.add(new GameLib.API.Vector3( - verticesFlat[i], - verticesFlat[i + 1], - verticesFlat[i + 2] - )); - } - - points.toOrigin(); - - points.maximizeXDistance(grain); - - points.maximizeYDistance(grain); - - for (i = 0; i < points.vectors.length; i++) { - vertices.push( - [ - points.vectors[i].x, - points.vectors[i].y - ] - ); - } - - return vertices; -}; - -GameLib.Utils.MovingAverage = function(period) { - var nums = []; - return function(num) { - nums.push(num); - if (nums.length > period) - nums.splice(0,1); // remove the first element of the array - var sum = 0; - for (var i in nums) - sum += nums[i]; - var n = period; - if (nums.length < period) - n = nums.length; - return(sum/n); - } -}; - -GameLib.Utils.Intersect = function (a, b) { - - var t; - - /** - * Loop over shortest array - */ - if (b.length > a.length) { - t = b; - b = a; - a = t; - } - - return a.filter( - /** - * Check if exists - * @param e - * @returns {boolean} - */ - function (e) { - return (b.indexOf(e) > -1); - } - ).filter( - /** - * Remove Duplicates - * @param e - * @param i - * @param c - * @returns {boolean} - */ - function (e, i, c) { - return c.indexOf(e) === i; - } - ); -}; - -GameLib.Utils.Difference = function (a, b) { - - var t; - - /** - * Loop over shortest array - */ - if (b.length > a.length) { - t = b; - b = a; - a = t; - } - - return a.filter( - /** - * Check if exists - * @param e - * @returns {boolean} - */ - function (e) { - return (b.indexOf(e) === -1); - } - ).filter( - /** - * Remove Duplicates - * @param e - * @param i - * @param c - * @returns {boolean} - */ - function (e, i, c) { - return c.indexOf(e) === i; - } - ); -}; - -/** - * Push only if not in there already - * @param array - * @param object - * @constructor - */ -GameLib.Utils.PushUnique = function(array, object) { - - if (array.indexOf(object) === -1) { - array.push(object); - } -}; - -/** - * Checks whether or not the object is empty - * @param obj - * @returns {boolean} - * @constructor - */ -GameLib.Utils.IsEmpty = function(obj) { - return (Object.keys(obj).length === 0 && obj.constructor === Object); -}; - -GameLib.Utils.isString = function(member) { - return (typeof member === 'string'); -}; - -GameLib.Utils.isBoolean = function(member) { - return (member === true || member === false); -}; - -GameLib.Utils.isColor = function(member) { - return (member instanceof GameLib.Color); -}; - -GameLib.Utils.isNumber = function(member) { - return (typeof member === 'number'); -}; - -GameLib.Utils.isVector2 = function(member) { - return ( - member instanceof GameLib.API.Vector2 || - member instanceof GameLib.Vector2 - ); -}; - -GameLib.Utils.isVector3 = function(member) { - return ( - member instanceof GameLib.API.Vector3 || - member instanceof GameLib.Vector3 - ); -}; - -GameLib.Utils.isVector4 = function(member) { - return ( - member instanceof GameLib.API.Vector4 || - member instanceof GameLib.Vector4 || - member instanceof GameLib.API.Quaternion || - member instanceof GameLib.Quaternion - ); -}; - -/** - * @return {string} - */ -GameLib.Utils.LowerUnderscore = function(name) { - return name.toLowerCase().replace(/\s+/, '_'); -}; - -GameLib.Utils.UpperCaseWordsSpaces = function(word) { - return word.replace(/[-_]/g, ' ').split(' ').reduce( - function(result, word) { - result += word[0].toUpperCase() + word.substr(1); - return result + ' '; - }, - '' - ).trim(); -}; - -/** - * @return {string} - */ -GameLib.Utils.UpperCaseUnderscore = function(word) { - - var str = ''; - - word.split('').map(function(letter){ - if (letter == letter.toUpperCase()) { - str += '_' + letter; - } else { - str += letter.toUpperCase(); - } - }); - - str = str.replace(new RegExp('^_'),''); - - return str; -}; -/** - * API Component Interface - Do not construct objects of this type directly - * @param componentType - * @param parentEntity - * @constructor - */ -GameLib.API.Component = function( - componentType, - parentEntity -) { - this.componentType = componentType; - - if (GameLib.Utils.UndefinedOrNull(parentEntity)) { - parentEntity = null; - } - this.parentEntity = parentEntity; -}; - -GameLib.API.Component.prototype = Object.create(GameLib.Event.prototype); -GameLib.API.Component.prototype.constructor = GameLib.API.Component; -/** - * Component Interface - * @constructor - * @param linkedObjects - * @param delayed - */ -GameLib.Component = function( - linkedObjects, - delayed -) { - if (GameLib.Utils.UndefinedOrNull(linkedObjects)) { - linkedObjects = {}; - } - this.linkedObjects = linkedObjects; - this.linkedObjects.parentEntity = GameLib.Entity; - - this.idToObject = {}; - - this.selected = false; - - this.building = false; - - this.loaded = false; - - this.linked = false; - - this.cloneNumber = 0; - - this.isClone = false; - - if (GameLib.Utils.UndefinedOrNull(delayed)) { - delayed = false; - } - this.delayed = delayed; - - this.dependencies = this.getDependencies(); - - GameLib.Event.Emit( - GameLib.Event.COMPONENT_REGISTER, - { - component : this - } - ); - - if (this.dependencies.length === 0) { - - this.performInstanceCreation(); - - } else { - GameLib.Event.Emit( - GameLib.Event.REGISTER_DEPENDENCIES, - { - component : this - } - ); - } - - -}; - -GameLib.Component.prototype = Object.create(GameLib.API.Component.prototype); -GameLib.Component.prototype.constructor = GameLib.Component; - -/** - * This function, performs standard instance creation steps for all our components, which means - * Ensure we have no dependencies - * Build a list of all child components - if they are all linked, we are ready to create an instance - * Ensure we are linked - * Ensure we are not delayed - * Try to create the instance - * Error Log if failed - * Don't do anything if we are not fully linked - */ -GameLib.Component.prototype.performInstanceCreation = function() { - - var dependencies = true; - - if (GameLib.Utils.UndefinedOrNull(this.dependencies)) { - dependencies = false; - } - - if (this.dependencies && this.dependencies instanceof Array && this.dependencies.length === 0) { - dependencies = false; - } - - if (dependencies) { - throw new Error('performInstanceCreation called while this object still has dependencies'); - } - - delete this.dependencies; - - /** - * Build ID to object should run through all sub components - - * if one is found which is not linked, this component is not linked fully - */ - this.buildIdToObject(); - - /** - * Don't try to create an instance of this object until it is fully linked - */ - if (this.linked) { - if (!this.delayed) { - try { - this.createInstance(); - } catch (error) { - console.error(error); - } - } else { - /** - * Some systems require a restart in order to create the delayed components (like System.Input for - * Edit Controls) - we need to give them the opportunity to restart - */ - GameLib.Event.Emit( - GameLib.Event.DELAYED_INSTANCE_ENCOUNTERED, - { - component : this - } - ) - } - } -}; - -GameLib.Component.prototype.createInstance = function() { - - // console.log('create instance : '+ this.name); - - /** - * When you do actually call 'createInstance' - it is wise to state we are no longer delayed - we assume the caller - * knows when to call createInstance, so we do the housekeeping here - * @type {boolean} - */ - this.delayed = false; - - if (this.instance) { - - this.loaded = true; - - GameLib.Event.Emit( - GameLib.Event.INSTANCE_CREATED, - { - component: this - } - ) - } - - if (this instanceof GameLib.Entity) { - GameLib.Event.Emit( - GameLib.Event.ENTITY_LOADED, - { - entity:this - } - ) - } -}; - -/** - * Dependencies are everything which is either a string or an object with an id which is linked to this object - * @returns {Array} - */ -GameLib.Component.prototype.getDependencies = function() { - - var dependencies = []; - - for (var property in this.linkedObjects) { - - if ( - this.linkedObjects.hasOwnProperty(property) && - property.indexOf('parent') !== 0 && - this.hasOwnProperty(property) - ){ - if (typeof this[property] === 'string') { - GameLib.Utils.PushUnique(dependencies, this[property]); - } - - if (this[property] instanceof Array) { - this[property].map( - function(arrayProperty) { - - if (typeof arrayProperty === 'string') { - GameLib.Utils.PushUnique(dependencies, arrayProperty); - } - - if (arrayProperty && - arrayProperty instanceof GameLib.Component - ) { - GameLib.Utils.PushUnique(dependencies, arrayProperty.id); - } - } - ); - } - - if (this[property] && - this[property] instanceof GameLib.Component - ) { - GameLib.Utils.PushUnique(dependencies, this[property].id); - } - } - } - - return dependencies; -}; - -GameLib.Component.prototype.toString = function() { - return this.id; -}; - -GameLib.Component.SOCKET_RECEIVE = 0x1; -GameLib.Component.MATERIAL = 0x2; -GameLib.Component.RENDERER = 0x3; -GameLib.Component.SERVER = 0x4; -GameLib.Component.CAMERA = 0x5; -GameLib.Component.SOCKET = 0x6; -GameLib.Component.MESH = 0x7; -GameLib.Component.SPLINE = 0x8; -GameLib.Component.LIGHT = 0x9; -//GameLib.Component.INPUT_DRIVE = 0xa; -GameLib.Component.COMPOSER = 0xb; -GameLib.Component.RENDER_TARGET = 0xc; -GameLib.Component.PASS = 0xd; -GameLib.Component.SCENE = 0xe; -GameLib.Component.RAYCASTER = 0xf; -//GameLib.Component.INPUT_EDITOR = 0x10; -//GameLib.Component.EDITOR = 0x11; -GameLib.Component.VIEWPORT = 0x12; -GameLib.Component.SYSTEM = 0x13; -GameLib.Component.GRAPHICS = 0x14; -GameLib.Component.HELPER = 0x15; -GameLib.Component.CUSTOM_CODE = 0x16; -GameLib.Component.MOUSE = 0x17; -GameLib.Component.SKELETON = 0x18; -GameLib.Component.TEXTURE = 0x19; -GameLib.Component.ENTITY_MANAGER = 0x1a; -GameLib.Component.DOM_ELEMENT = 0x1b; -//GameLib.Component.IMAGE_FACTORY = 0x1c; -GameLib.Component.STATS = 0x1d; -GameLib.Component.GUI = 0x1e; -GameLib.Component.IMAGE = 0x1f; -GameLib.Component.ENTITY = 0x20; -GameLib.Component.MESH_SPHERE = 0x21; -GameLib.Component.MESH_PLANE = 0x22; -GameLib.Component.MESH_CURVE = 0x23; -GameLib.Component.PHYSICS_WORLD = 0x24; -GameLib.Component.BROADPHASE = 0x25; -GameLib.Component.SOLVER = 0x26; -GameLib.Component.RIGID_BODY = 0x27; -GameLib.Component.SHAPE = 0x28; -GameLib.Component.SHAPE_BOX = 0x29; -GameLib.Component.SHAPE_SPHERE = 0x2a; -GameLib.Component.SHAPE_TRI_MESH = 0x2b; -GameLib.Component.SHAPE_CONVEX_HULL = 0x2c; -GameLib.Component.SHAPE_CONVEX_HULL_CYLINDER = 0x2d; -GameLib.Component.SHAPE_HEIGHT_MAP = 0x2e; -GameLib.Component.SHAPE_PLANE = 0x2f; -GameLib.Component.CONTROLS = 0x30; -GameLib.Component.CONTROLS_EDITOR = 0x31; -GameLib.Component.CONTROLS_TOUCH = 0x32; -GameLib.Component.FRICTION_MATERIAL = 0x33; -GameLib.Component.FRICTION_CONTACT_MATERIAL = 0x34; -GameLib.Component.RAYCAST_VEHICLE = 0x35; -GameLib.Component.RAYCAST_WHEEL = 0x36; -GameLib.Component.CLOCK = 0x37; -GameLib.Component.ANIMATION = 0x38; -GameLib.Component.CONTROLS_KEYBOARD = 0x39; -GameLib.Component.CONTROLS_MOUSE = 0x3a; -GameLib.Component.MESH_TEXT = 0x3b; -GameLib.Component.FONT = 0x3c; -GameLib.Component.CANVAS = 0x3d; -GameLib.Component.BONE = 0x3e; -GameLib.Component.MESH_BOX = 0x3f; -GameLib.Component.MESH_CYLINDER = 0x40; -GameLib.Component.SYSTEM_ANIMATION = 0x41; -GameLib.Component.SYSTEM_CUSTOM_CODE = 0x42; -GameLib.Component.SYSTEM_GUI = 0x43; -GameLib.Component.SYSTEM_INPUT = 0x44; -GameLib.Component.SYSTEM_LINKING = 0x45; -GameLib.Component.SYSTEM_PHYSICS = 0x46; -GameLib.Component.SYSTEM_RENDER = 0x47; -GameLib.Component.SYSTEM_STORAGE = 0x48; -GameLib.Component.SYSTEM_VISUALIZATION = 0x49; -GameLib.Component.FOG = 0x50; -GameLib.Component.MESH_LINE = 0x51; -GameLib.Component.PARTICLE_ENGINE = 0x52; -GameLib.Component.SYSTEM_PARTICLE = 0x53; -GameLib.Component.PARTICLE = 0x54; -GameLib.Component.AUDIO = 0x55; -GameLib.Component.SYSTEM_AUDIO = 0x56; -GameLib.Component.SOCKET_CAST = 0x57; -GameLib.Component.MAX_COMPONENTS = 0x58; - -GameLib.Component.GRAPHICS_RUNTIME = 0x1; -GameLib.Component.PHYSICS_RUNTIME = 0x2; -GameLib.Component.SOCKET_RUNTIME = 0x3; -GameLib.Component.STATISTICS_RUNTIME = 0x4; -GameLib.Component.DEFAULT_RUNTIME = 0x5; -GameLib.Component.GUI_RUNTIME = 0x6; -GameLib.Component.CODER_RUNTIME = 0x7; - -GameLib.Component.GetCompentTypes = function(constructor) { - - if (constructor === GameLib.Component) { - - } -}; - -/** - * Returns string name for component number - * @param number - * @returns {*} - * @constructor - */ -GameLib.Component.GetComponentInfo = function(number) { - switch(number) { - case 0x1 : return { - name : 'GameLib.Socket.Receive', - runtime : GameLib.Component.SOCKET_RUNTIME, - constructor : GameLib.Socket.Receive, - apiConstructor : GameLib.API.Socket.Receive - }; - case 0x2 : return { - name : 'GameLib.D3.Material', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Material, - apiConstructor : GameLib.D3.API.Material - }; - case 0x3 : return { - name : 'GameLib.D3.Renderer', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Renderer, - apiConstructor : GameLib.D3.API.Renderer - }; - case 0x4 : return { - name : 'GameLib.Server', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.Server, - apiConstructor : GameLib.API.Server - }; - case 0x5 : return { - name : 'GameLib.D3.Camera', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Camera, - apiConstructor : GameLib.D3.API.Camera - }; - case 0x6 : return { - name : 'GameLib.Socket', - runtime : GameLib.Component.SOCKET_RUNTIME, - constructor : GameLib.Socket, - apiConstructor : GameLib.API.Socket - }; - case 0x7 : return { - name : 'GameLib.D3.Mesh', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Mesh, - apiConstructor : GameLib.D3.API.Mesh - }; - case 0x8 : return { - name : 'GameLib.D3.Spline', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Spline, - apiConstructor : GameLib.D3.API.Spline - }; - case 0x9 : return { - name : 'GameLib.D3.Light', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Light, - apiConstructor : GameLib.D3.API.Light - }; - case 0xa : return null; - case 0xb : return { - name : 'GameLib.D3.Composer', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Composer, - apiConstructor : GameLib.D3.API.Composer - }; - case 0xc : return { - name : 'GameLib.D3.RenderTarget', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.RenderTarget, - apiConstructor : GameLib.D3.API.RenderTarget - }; - case 0xd : return { - name : 'GameLib.D3.Pass', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Pass, - apiConstructor : GameLib.D3.API.Pass - }; - case 0xe : return { - name : 'GameLib.D3.Scene', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Scene - }; - case 0xf : return { - name : 'GameLib.D3.Raycaster', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Raycaster, - apiConstructor : GameLib.D3.API.Raycaster - }; - case 0x10 : return null; - case 0x11 : return null; - case 0x12 : return { - name : 'GameLib.D3.Viewport', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Viewport, - apiConstructor : GameLib.D3.API.Viewport - }; - case 0x13 : return { - name : 'GameLib.System', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.System, - apiConstructor : GameLib.API.System - }; - case 0x14 : return { - name : 'GameLib.GraphicsRuntime', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.GraphicsRuntime - }; - case 0x15 : return { - name : 'GameLib.D3.Helper', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Helper - }; - case 0x16 : return { - name : 'GameLib.CustomCode', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.CustomCode, - apiConstructor : GameLib.API.CustomCode - }; - case 0x17 : return { - name : 'GameLib.Mouse', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.Mouse, - apiConstructor : GameLib.API.Mouse - }; - case 0x18 : return { - name : 'GameLib.D3.Skeleton', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Skeleton, - apiConstructor : GameLib.D3.API.Skeleton - }; - case 0x19 : return { - name : 'GameLib.D3.Texture', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Texture, - apiConstructor : GameLib.D3.API.Texture - }; - case 0x1a : return { - name : 'GameLib.EntityManager', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.EntityManager, - apiConstructor : GameLib.API.EntityManager - }; - case 0x1b : return { - name : 'GameLib.DomElement', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.DomElement, - apiConstructor : GameLib.API.DomElement - }; - case 0x1c : return null; - case 0x1d : return { - name : 'GameLib.Stats', - runtime : GameLib.Component.STATISTICS_RUNTIME, - constructor : GameLib.Stats, - apiConstructor : GameLib.API.Stats - }; - case 0x1e : return { - name : 'GameLib.GUI', - runtime : GameLib.Component.GUI_RUNTIME, - constructor : GameLib.GUI, - apiConstructor : GameLib.API.GUI - }; - case 0x1f : return { - name : 'GameLib.Image', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.Image - }; - case 0x20 : return { - name : 'GameLib.Entity', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.Entity, - apiConstructor : GameLib.API.Entity - }; - case 0x21 : return { - name : 'GameLib.D3.Mesh.Sphere', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Mesh.Sphere, - apiConstructor : GameLib.D3.API.Mesh - }; - case 0x22 : return { - name : 'GameLib.D3.Mesh.Plane', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Mesh.Plane, - apiConstructor : GameLib.D3.API.Mesh - }; - case 0x23 : return { - name : 'GameLib.D3.Mesh.Curve', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Mesh.Curve, - apiConstructor : GameLib.D3.API.Mesh - }; - case 0x24 : return { - name : 'GameLib.D3.PhysicsWorld', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.PhysicsWorld, - apiConstructor : GameLib.D3.API.PhysicsWorld - }; - case 0x25 : return { - name : 'GameLib.D3.Broadphase', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.Broadphase, - apiConstructor : GameLib.D3.API.Broadphase - }; - case 0x26 : return { - name : 'GameLib.D3.Solver', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.Solver, - apiConstructor : GameLib.D3.API.Solver - }; - case 0x27 : return { - name : 'GameLib.D3.RigidBody', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.RigidBody, - apiConstructor : GameLib.D3.API.RigidBody - }; - case 0x28 : return { - name : 'GameLib.D3.Shape', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.Shape, - apiConstructor : GameLib.D3.API.Shape - }; - case 0x29 : return { - name : 'GameLib.D3.Shape.Box', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.Shape.Box, - apiConstructor : GameLib.D3.API.Shape - }; - case 0x2a : return { - name : 'GameLib.D3.Shape.Sphere', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.Shape.Sphere, - apiConstructor : GameLib.D3.API.Shape - }; - case 0x2b : return { - name : 'GameLib.D3.Shape.TriMesh', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.Shape.TriMesh, - apiConstructor : GameLib.D3.API.Shape - }; - case 0x2c : return { - name : 'GameLib.D3.Shape.ConvexHull', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.Shape.ConvexHull, - apiConstructor : GameLib.D3.API.Shape - }; - case 0x2d : return { - name : 'GameLib.D3.Shape.ConvexHull.Cylinder', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.Shape.ConvexHull.Cylinder, - apiConstructor : GameLib.D3.API.Shape - }; - case 0x2e : return { - name : 'GameLib.D3.Shape.HeightMap', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.D3.Shape.HeightMap, - apiConstructor : GameLib.D3.API.Shape - }; - case 0x2f : return { - name : 'GameLib.D3.Shape.Plane', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.Shape.Plane, - apiConstructor : GameLib.D3.API.Shape - }; - case 0x30 : return { - name : 'GameLib.Controls', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.Controls, - apiConstructor : GameLib.API.Controls - }; - case 0x31 : return { - name : 'GameLib.Controls.D3.Editor', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.Controls.D3.Editor, - apiConstructor : GameLib.API.Controls - }; - case 0x32 : return { - name : 'GameLib.Controls.Touch', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.Controls.Touch, - apiConstructor : GameLib.API.Controls - }; - case 0x33 : return { - name : 'GameLib.D3.FrictionMaterial', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.FrictionMaterial, - apiConstructor : GameLib.D3.API.FrictionMaterial - }; - case 0x34 : return { - name : 'GameLib.D3.FrictionContactMaterial', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.FrictionContactMaterial, - apiConstructor : GameLib.D3.API.FrictionContactMaterial - }; - case 0x35 : return { - name : 'GameLib.D3.RaycastVehicle', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.RaycastVehicle, - apiConstructor : GameLib.D3.API.RaycastVehicle - }; - case 0x36 : return { - name : 'GameLib.D3.RaycastWheel', - runtime : GameLib.Component.PHYSICS_RUNTIME, - constructor : GameLib.D3.RaycastWheel, - apiConstructor : GameLib.D3.API.RaycastWheel - }; - case 0x37 : return { - name : 'GameLib.Clock', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.Clock, - apiConstructor : GameLib.API.Clock - }; - case 0x38 : return { - name : 'GameLib.D3.Animation', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.D3.Animation, - apiConstructor : GameLib.D3.API.Animation - }; - case 0x39 : return { - name : 'GameLib.Controls.Keyboard', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.Controls.Keyboard, - apiConstructor : GameLib.API.Controls - }; - case 0x3a : return { - name : 'GameLib.Controls.Mouse', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.Controls.Mouse, - apiConstructor : GameLib.API.Controls - }; - case 0x3b : return { - name : 'GameLib.D3.Mesh.Text', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Mesh.Text, - apiConstructor : GameLib.D3.API.Mesh - }; - case 0x3c : return { - name : 'GameLib.D3.Font', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Font, - apiConstructor : GameLib.D3.API.Font - }; - case 0x3d : return { - name : 'GameLib.Canvas', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.Canvas, - apiConstructor : GameLib.API.Canvas - }; - case 0x3e : return { - name : 'GameLib.D3.Bone', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Bone, - apiConstructor : GameLib.D3.API.Bone - }; - case 0x3f : return { - name : 'GameLib.D3.Mesh.Box', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Mesh.Box, - apiConstructor : GameLib.D3.API.Mesh - }; - case 0x40 : return { - name : 'GameLib.D3.Mesh.Cylinder', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Mesh.Cylinder, - apiConstructor : GameLib.D3.API.Mesh - }; - case 0x41 : return { - name : 'GameLib.System.Animation', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.System.Animation, - apiConstructor : GameLib.API.System - }; - case 0x42 : return { - name : 'GameLib.System.CustomCode', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.System.CustomCode, - apiConstructor : GameLib.API.System - }; - case 0x43 : return { - name : 'GameLib.System.GUI', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.System.GUI, - apiConstructor : GameLib.API.System - }; - case 0x44 : return { - name : 'GameLib.System.Input', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.System.Input, - apiConstructor : GameLib.API.System - }; - case 0x45 : return { - name : 'GameLib.System.Linking', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.System.Linking, - apiConstructor : GameLib.API.System - }; - case 0x46 : return { - name : 'GameLib.System.Physics', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.System.Physics, - apiConstructor : GameLib.API.System - }; - case 0x47 : return { - name : 'GameLib.System.Render', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.System.Render, - apiConstructor : GameLib.API.System - }; - case 0x48 : return { - name : 'GameLib.System.Storage', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.System.Storage, - apiConstructor : GameLib.API.System - }; - case 0x49 : return { - name : 'GameLib.System.Visualization', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.System.Visualization, - apiConstructor : GameLib.API.System - }; - case 0x50 : return { - name : 'GameLib.D3.Fog', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Fog, - apiConstructor : GameLib.D3.API.Fog - }; - case 0x51 : return { - name : 'GameLib.D3.Mesh.Line', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Mesh.Line, - apiConstructor : GameLib.D3.API.Mesh - }; - case 0x52 : return { - name : 'GameLib.D3.ParticleEngine', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.ParticleEngine, - apiConstructor : GameLib.D3.API.ParticleEngine - }; - case 0x53 : return { - name : 'GameLib.System.Particle', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.System.Particle, - apiConstructor : GameLib.API.System - }; - case 0x54 : return { - name : 'GameLib.D3.Particle', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Particle, - apiConstructor : GameLib.D3.API.Particle - }; - case 0x55 : return { - name : 'GameLib.D3.Audio', - runtime : GameLib.Component.GRAPHICS_RUNTIME, - constructor : GameLib.D3.Audio, - apiConstructor : GameLib.D3.API.Audio - }; - case 0x56 : return { - name : 'GameLib.System.Audio', - runtime : GameLib.Component.DEFAULT_RUNTIME, - constructor : GameLib.System.Audio, - apiConstructor : GameLib.API.System - }; - case 0x57 : return { - name : 'GameLib.Socket.Cast', - runtime : GameLib.Component.SOCKET_RUNTIME, - constructor : GameLib.Socket.Cast, - apiConstructor : GameLib.API.Socket.Cast - }; - break; - } - - throw new Error('Unknown component type: ' + number ); -}; - -/** - * Returns the runtime friendly name - * @param runtime - * @returns {*} - * @constructor - */ -GameLib.Component.GetRuntimeName = function(runtime) { - - if (runtime === GameLib.Component.GRAPHICS_RUNTIME) { - return 'Graphics'; - } - - if (runtime === GameLib.Component.PHYSICS_RUNTIME) { - return 'Physics'; - } - - if (runtime === GameLib.Component.GUI_RUNTIME) { - return 'GUI'; - } - - if (runtime === GameLib.Component.STATISTICS_RUNTIME) { - return 'Statistics'; - } - - if (runtime === GameLib.Component.SOCKET_RUNTIME) { - return 'Sockets'; - } - - if (runtime === GameLib.Component.CODER_RUNTIME) { - return 'Coder'; - } - - return 'Default'; -}; - -/** - * @return {string} - */ -GameLib.Component.GetComponentName = function(componentType) { - - var info = GameLib.Component.GetComponentInfo(componentType); - - if (info) { - return info.name; - } - - return 'unused'; -}; - -/** - * @return {null || Object} - */ -GameLib.Component.GetComponentRuntime = function(componentType) { - - var info = GameLib.Component.GetComponentInfo(componentType); - - if (info) { - return info.runtime; - } - return null; -}; - - -/** - * @return {null || Object} - */ -GameLib.Component.GetComponentConstructor = function(componentType) { - - var info = GameLib.Component.GetComponentInfo(componentType); - - if (info) { - return info.constructor; - } - - return null; -}; - - -/** - * Components are linked at runtime - for storing, we just store the ID - * @returns {*} - */ -GameLib.Component.prototype.toApiObject = function() { - return this.id; -}; - -GameLib.Component.prototype.processComponent = function(object) { - if (object instanceof GameLib.Component) { - - object.buildIdToObject(); - - if (!object.linked) { - this.linked = false; - } - - var idToObject = object.idToObject; - - for (var objectProperty in idToObject) { - if (idToObject.hasOwnProperty(objectProperty)) { - this.idToObject[objectProperty] = idToObject[objectProperty]; - } - } - - if (object.id) { - this.idToObject[object.id] = object; - } else { - console.warn('Object with no ID passed: ' + object) - } - - } else if (typeof object === 'string') { - this.linked = false; - } else { - console.warn('Unhandled type of object: ', object); - } -}; - -/** - * This function - builds an 'id to object' object - which contains the ids which point directly - * to its corresponding object, for all the objects contained inside this object - */ -GameLib.Component.prototype.buildIdToObject = function() { - - if (this.building) { - return; - } - - /** - * If this component 'building' flag is true - it is in the process of building idToObject up the callstack and the - * caller should know to not try to build idToObject again (prevent infinite recursion) - */ - this.building = true; - - /** - * If any child component is not fully linked, this component will show as not linked - * @type {boolean} - */ - this.linked = true; - - this.idToObject = {}; - - for (var property in this.linkedObjects) { - if ( - this.linkedObjects.hasOwnProperty(property) && - this.hasOwnProperty(property) && - this[property] && - property.indexOf('parent') !== 0 - ) { - - if (this.linkedObjects[property] instanceof Array) { - - /** - * Remove null objects (can happen) - */ - this[property] = this[property].filter( - function (object) { - if (object === null) { - console.log('null object found and removed'); - return false; - } - return true; - } - ); - - this[property].map( - function (object) { - this.processComponent(object); - }.bind(this) - ); - - } else { - this.processComponent(this[property]); - } - } - } - - if (this instanceof GameLib.D3.Scene) { - if (!this.storeClones) { - this.clones.map( - function (clone) { - if (this.idToObject.hasOwnProperty(clone.id)) { - delete this.idToObject[clone.id]; - } - }.bind(this) - ) - } - } - - this.idToObject[this.id] = this; - - this.building = false; -}; - -GameLib.Component.prototype.generateNewIds = function() { - - this.buildIdToObject(); - - var codeComponents = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.CUSTOM_CODE); - - for (var property in this.idToObject) { - if (this.idToObject.hasOwnProperty(property)) { - - var oldId = this.idToObject[property].id; - var newId = GameLib.Utils.RandomId(); - - this.idToObject[property].id = newId; - this.idToObject[property].name = this.idToObject[property].name.replace(oldId,newId); - codeComponents.map(function(codeComponent){ - codeComponent.code = codeComponent.code.replace(oldId,newId); - }); - } - } - -}; - -GameLib.Component.prototype.remove = function() { - - this.buildIdToObject(); - - var dependencies = this.getDependencies(); - - dependencies.map( - function(objectId) { - - var childComponent = this.idToObject[objectId]; - - if (childComponent instanceof GameLib.Component) { - childComponent.remove(); - } - - }.bind(this) - ); - - GameLib.Event.Emit( - GameLib.Event.REMOVE_COMPONENT, - { - component : this - } - ) - -}; - -GameLib.Component.prototype.clone = function() { - - var apiObject = this.toApiObject(); - - this.cloneNumber += 1; - - apiObject.id = GameLib.Utils.RandomId(); - - apiObject.name = this.name + ' Clone (' + this.cloneNumber + ')'; - - var runtimeComponent = GameLib.Component.ConstructFromObject(apiObject); - - runtimeComponent.isClone = true; - - GameLib.Event.Emit( - GameLib.Event.COMPONENT_CLONED, - { - parent : this, - component : runtimeComponent - } - ); - - runtimeComponent.parentEntity = null; - - return runtimeComponent; -}; - -/** - * Clones only the instance - */ -GameLib.Component.prototype.cloneInstance = function() { - - var clone = null; - - if ( - this.instance && - this.instance.clone && - typeof (this.instance.clone === 'function')) { - - clone = this.instance.clone(); - - GameLib.Event.Emit( - GameLib.Event.INSTANCE_CLONED, - { - component : this, - instance : clone - } - ) - } - - return clone; -}; - -GameLib.Component.prototype.saveToRemoteAPI = function() { - this.save(true); -}; - -GameLib.Component.prototype.save = function(remote) { - - var toSave = []; - var saved = []; - var failed = []; - - this.buildIdToObject(); - - if (this.saveSubscription || this.saveErrorSubscription) { - console.warn('another save is in progress'); - return; - } - - GameLib.Event.Emit( - GameLib.Event.SAVING, - { - component: this - } - ); - - this.saveSubscription = GameLib.Event.Subscribe( - GameLib.Event.COMPONENT_SAVED, - function(data) { - - saved.push(data.component); - - if (failed.length + saved.length === toSave.length) { - - this.saveSubscription.remove(); - - this.saveSubscription = null; - - this.saveErrorSubscription.remove(); - - this.saveErrorSubscription = null; - - GameLib.Event.Emit( - GameLib.Event.DONE_SAVING, - { - failed: failed, - saved: saved - } - ) - } - - }.bind(this) - ); - - this.saveErrorSubscription = GameLib.Event.Subscribe( - GameLib.Event.SAVE_COMPONENT_ERROR, - function(data) { - - failed.push(data.component); - - if (failed.length + saved.length === toSave.length) { - - this.saveSubscription.remove(); - - this.saveSubscription = null; - - this.saveErrorSubscription.remove(); - - this.saveErrorSubscription = null; - - GameLib.Event.Emit( - GameLib.Event.DONE_SAVING, - { - failed: failed, - saved: saved - } - ) - } - - }.bind(this) - ); - - for (var property in this.idToObject) { - if ( - this.idToObject.hasOwnProperty(property) && - this.idToObject[property] instanceof GameLib.Component - ) { - - var apiObject = this.idToObject[property].toApiObject(); - - toSave.push(apiObject); - - this.publish( - GameLib.Event.SAVE_COMPONENT, - { - apiObject: apiObject, - remote: remote - } - ); - } - } -}; - -/** - * @return {null|Object} - */ -GameLib.Component.GetRuntimeObject = function(runtimeInfo) { - - var runtime = null; - - GameLib.Event.Emit( - GameLib.Event.GET_RUNTIME, - null, - function(runtimeObject) { - runtime = runtimeObject; - } - ); - - if (runtimeInfo === GameLib.Component.GRAPHICS_RUNTIME) { - - if (GameLib.Utils.UndefinedOrNull(runtime.graphics)) { - console.warn('no runtime graphics'); - return null; - } - - return runtime.graphics; - - } else if (runtimeInfo === GameLib.Component.PHYSICS_RUNTIME) { - - if (GameLib.Utils.UndefinedOrNull(runtime.physics)) { - console.warn('no runtime physics'); - return null; - } - - return runtime.physics; - - } else if (runtimeInfo === GameLib.Component.GUI_RUNTIME) { - - if (GameLib.Utils.UndefinedOrNull(runtime.gui)) { - console.warn('no runtime gui'); - return null; - } - - return runtime.gui; - - } else if (runtimeInfo === GameLib.Component.SOCKET_RUNTIME) { - - if (GameLib.Utils.UndefinedOrNull(runtime.sockets)) { - console.warn('no runtime sockets'); - return null; - } - - return runtime.sockets; - - } else if (runtimeInfo === GameLib.Component.STATISTICS_RUNTIME) { - - if (GameLib.Utils.UndefinedOrNull(runtime.statistics)) { - console.warn('no runtime statistics'); - return null; - } - - return runtime.statistics; - - } else if (runtimeInfo === GameLib.Component.DEFAULT_RUNTIME) { - - } else { - console.log('unknown runtime object found : ' + info.runtime); - } - - return null; -}; - -GameLib.Component.Construct = function(componentType) { - - var info = GameLib.Component.GetComponentInfo(componentType); - - var componentClass = info.constructor; - - var runtime = GameLib.Component.GetRuntimeObject(info.runtime); - - if (runtime) { - return new componentClass(runtime); - } else { - return new componentClass(); - } - -}; - -GameLib.Component.ConstructFromObject = function(rawComponentObject) { - - var runtimeComponent = null; - - var info = GameLib.Component.GetComponentInfo(rawComponentObject.componentType); - - var componentClass = info.constructor; - - var fn = componentClass['FromObject']; - - if (rawComponentObject.componentType === GameLib.Component.ENTITY) { - - runtimeComponent = fn(rawComponentObject, GameLib.EntityManager.Instance); - - } else { - var runtime = GameLib.Component.GetRuntimeObject(info.runtime); - - if (runtime) { - runtimeComponent = fn(runtime, rawComponentObject); - } else { - runtimeComponent = fn(rawComponentObject); - } - } - - return runtimeComponent; -}; -/** - * Raw Canvas API object - should always correspond with the Canvas Schema - * @param id - * @param name - * @param width - * @param height - * @param parentEntity - * @constructor - */ -GameLib.API.Canvas = function( - id, - name, - width, - height, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Canvas (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(width)) { - width = 512; - } - this.width = width; - - if (GameLib.Utils.UndefinedOrNull(height)) { - height = 512; - } - this.height = height; - - GameLib.API.Component.call( - this, - GameLib.Component.CANVAS, - parentEntity - ); -}; - -GameLib.API.Canvas.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.Canvas.prototype.constructor = GameLib.API.Canvas; - -/** - * Returns an API light from an Object light - * @param objectCanvas - * @constructor - */ -GameLib.API.Canvas.FromObject = function(objectCanvas) { - return new GameLib.API.Canvas( - objectCanvas.id, - objectCanvas.name, - objectCanvas.width, - objectCanvas.height, - objectCanvas.parentEntity - ); -}; - -/** - * Raw Clock API object - should always correspond with the Clock Schema - * @constructor - * @param id - * @param name - * @param parentEntity - */ -GameLib.API.Clock = function( - id, - name, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Clock (' + this.id + ')'; - } - this.name = name; - - GameLib.API.Component.call( - this, - GameLib.Component.CLOCK, - parentEntity - ); -}; - -GameLib.API.Clock.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.Clock.prototype.constructor = GameLib.API.Clock; - -/** - * Creates an API camera from an Object camera - * @param objectClock - * @constructor - */ -GameLib.API.Clock.FromObject = function(objectClock) { - - return new GameLib.API.Clock( - objectClock.id, - objectClock.name, - objectClock.parentEntity - ); - -}; - -/** - * API Color - * @param r - * @param g - * @param b - * @param a - * @constructor - */ -GameLib.API.Color = function (r, g, b, a) { - - if (GameLib.Utils.UndefinedOrNull(r)) { - r = 1; - } - this.r = r; - - if (GameLib.Utils.UndefinedOrNull(g)) { - g = 1; - } - this.g = g; - - if (GameLib.Utils.UndefinedOrNull(b)) { - b = 1; - } - this.b = b; - - if (GameLib.Utils.UndefinedOrNull(a)) { - a = 0; - } - this.a = a; - -}; - -/** - * Returns an API color from an Object color - * @param objectColor - * @constructor - */ -GameLib.API.Color.FromObject = function(objectColor) { - - if (GameLib.Utils.UndefinedOrNull(objectColor)){ - objectColor = {}; - } - - return new GameLib.API.Color( - objectColor.r, - objectColor.g, - objectColor.b, - objectColor.a - ); - -}; - -/** - * Converts the current color to HTML hex format (ex. #ffffff) - * @returns {string} - */ -GameLib.API.Color.prototype.toHex = function() { - - if (this.r < 0) { - this.r = 0; - } - - if (this.g < 0) { - this.g = 0; - } - - if (this.b < 0) { - this.b = 0; - } - - if (this.r > 1) { - this.r = 1; - } - - if (this.g > 1) { - this.g = 1; - } - - if (this.b > 1) { - this.b = 1; - } - - var rf = Math.floor(this.r >= 1? 255 : this.r * 256.0).toString(16); - var gf = Math.floor(this.g >= 1? 255 : this.g * 256.0).toString(16); - var bf = Math.floor(this.b >= 1? 255 : this.b * 256.0).toString(16); - - if (rf.length < 2) { - rf = '0' + rf; - } - - if (gf.length < 2) { - gf = '0' + gf; - } - - if (bf.length < 2) { - bf = '0' + bf; - } - - return '#' + rf + gf + bf; -}; - -/** - * Sets this object color to what the hex value is - * @param hex - * @returns {string} - */ -GameLib.API.Color.prototype.fromHex = function(hex) { - - var matches = hex.match(new RegExp('#+(..)(..)(..)')); - - this.r = parseInt(matches[1], 16) / 255.0; - this.g = parseInt(matches[2], 16) / 255.0; - this.b = parseInt(matches[3], 16) / 255.0; -}; - -/** - * Raw Controls API object - * @param id - * @param controlsType - * @param name - * @param domElement - * @param parentEntity - * @constructor - */ -GameLib.API.Controls = function( - id, - controlsType, - name, - domElement, - // fullscreen, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(controlsType)) { - - if (this instanceof GameLib.Controls.D3.Editor) { - controlsType = GameLib.Controls.CONTROLS_TYPE_EDITOR; - } - - if (this instanceof GameLib.Controls.Touch) { - controlsType = GameLib.Controls.CONTROLS_TYPE_TOUCH; - } - - if (this instanceof GameLib.Controls.Keyboard) { - controlsType = GameLib.Controls.CONTROLS_TYPE_KEYBOARD; - } - - if (this instanceof GameLib.Controls.Mouse) { - controlsType = GameLib.Controls.CONTROLS_TYPE_MOUSE; - } - - if (GameLib.Utils.UndefinedOrNull(controlsType)) { - throw new Error('Could not determine controls type from this'); - } - } - this.controlsType = controlsType; - - if (GameLib.Utils.UndefinedOrNull(name)) { - - if (controlsType === GameLib.Controls.CONTROLS_TYPE_EDITOR) { - name = 'Editing Controls'; - } - - if (controlsType === GameLib.Controls.CONTROLS_TYPE_TOUCH) { - name = 'Touch Controls'; - } - - if (controlsType === GameLib.Controls.CONTROLS_TYPE_KEYBOARD) { - name = 'Keyboard Controls'; - } - - if (controlsType === GameLib.Controls.CONTROLS_TYPE_MOUSE) { - name = 'Mouse Controls'; - } - - name += ' (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(domElement)) { - domElement = null; - } - this.domElement = domElement; - - var componentType = GameLib.Component.CONTROLS; - - if (this.controlsType === GameLib.Controls.CONTROLS_TYPE_EDITOR) { - componentType = GameLib.Component.CONTROLS_EDITOR; - } - - if (this.controlsType === GameLib.Controls.CONTROLS_TYPE_TOUCH) { - componentType = GameLib.Component.CONTROLS_TOUCH - } - - if (this.controlsType === GameLib.Controls.CONTROLS_TYPE_KEYBOARD) { - componentType = GameLib.Component.CONTROLS_KEYBOARD - } - - if (this.controlsType === GameLib.Controls.CONTROLS_TYPE_MOUSE) { - componentType = GameLib.Component.CONTROLS_MOUSE - } - - GameLib.API.Component.call( - this, - componentType, - parentEntity - ); -}; - -GameLib.API.Controls.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.Controls.prototype.constructor = GameLib.API.Controls; - -/** - * Returns an API Controls from an Object - * @param objectControls - * @constructor - */ -GameLib.API.Controls.FromObject = function (objectControls){ - return new GameLib.API.Controls( - objectControls.id, - objectControls.controlsType, - objectControls.name, - objectControls.domElement, - objectControls.parentEntity - ); -}; - -/** - * Custom Code Component - * @param id - * @param name - * @param eventId - * @param code - * @param parentEntity - * @constructor - */ -GameLib.API.CustomCode = function ( - id, - name, - eventId, - code, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'CustomCode (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(eventId)) { - eventId = 42; - } - this.eventId = eventId; - - if (GameLib.Utils.UndefinedOrNull(code)) { - code = "return null;\n//@ sourceURL=" + this.name + ".js"; - } - this.code = code; - - GameLib.API.Component.call( - this, - GameLib.Component.CUSTOM_CODE, - parentEntity - ); -}; - -GameLib.API.CustomCode.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.CustomCode.prototype.constructor = GameLib.API.CustomCode; - -/** - * Object to GameLib.API.CustomCode - * @param objectComponent - * @returns {GameLib.API.CustomCode} - * @constructor - */ -GameLib.API.CustomCode.FromObject = function(objectComponent) { - return new GameLib.API.CustomCode( - objectComponent.id, - objectComponent.name, - objectComponent.eventId, - objectComponent.code, - objectComponent.parentEntity - ); -}; - -/** - * API DomElement - * @param id - * @param name - * @param domElementId - * @param parentEntity - * @constructor - */ -GameLib.API.DomElement = function( - id, - name, - domElementId, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'DOM Element (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(domElementId)) { - domElementId = ''; - } - this.domElementId = domElementId; - - GameLib.API.Component.call( - this, - GameLib.Component.DOM_ELEMENT, - parentEntity - ); -}; - -GameLib.API.DomElement.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.DomElement.prototype.constructor = GameLib.API.DomElement; - -/** - * Returns an API domElement from an Object domElement - * @param objectDomElement - * @constructor - */ -GameLib.API.DomElement.FromObject = function (objectDomElement) { - return new GameLib.API.DomElement( - objectDomElement.id, - objectDomElement.name, - objectDomElement.domElementId, - objectDomElement.parentEntity - ) -}; - -/** - * Entity API Object (for storing / loading entities to and from API) - * @constructor - * @param id - * @param name - * @param entities GameLib.API.Entity[] - * @param defaultEntity - * @param defaultRenderer - * @param parentEntity - */ -GameLib.API.EntityManager = function( - id, - name, - entities, - defaultEntity, - defaultRenderer, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Entity Manager (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(entities)) { - entities = []; - } - this.entities = entities; - - if (GameLib.Utils.UndefinedOrNull(defaultEntity)) { - defaultEntity = null; - } - this.defaultEntity = defaultEntity; - - if (GameLib.Utils.UndefinedOrNull(defaultRenderer)) { - defaultRenderer = null; - } - this.defaultRenderer = defaultRenderer; - - GameLib.API.Component.call( - this, - GameLib.Component.ENTITY_MANAGER, - parentEntity - ); -}; - -GameLib.API.EntityManager.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.EntityManager.prototype.constructor = GameLib.API.EntityManager; - -/** - * Creates an API entity manager from an Object entity manager - * @param objectEntityManager - * @constructor - */ -GameLib.API.EntityManager.FromObject = function(objectEntityManager) { - - var apiEntities = objectEntityManager.entities.map( - function (objectEntity) { - return GameLib.API.Entity.FromObject(objectEntity); - } - ); - - return new GameLib.API.EntityManager( - objectEntityManager.id, - objectEntityManager.name, - apiEntities, - objectEntityManager.defaultEntity, - objectEntityManager.defaultRenderer, - objectEntityManager.parentEntity - ); -}; - -/** - * Entity API Object (for storing / loading entities to and from API) - * @param id - * @param name - * @param components GameLib.Component[] - * @param parentEntity GameLib.Entity - * @param parentEntityManager - * @constructor - */ -GameLib.API.Entity = function( - id, - name, - components, - parentEntity, - parentEntityManager -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Entity (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(components)) { - components = []; - } - this.components = components; - - GameLib.API.Component.call( - this, - GameLib.Component.ENTITY, - parentEntity - ); - - if (GameLib.Utils.UndefinedOrNull(parentEntityManager)) { - parentEntityManager = null; - } - this.parentEntityManager = parentEntityManager; - - this.activeComponent = null; -}; - -GameLib.API.Entity.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.Entity.prototype.constructor = GameLib.API.Entity; - -/** - * Returns an API entity from an Object entity - * @param objectEntity - * @constructor - */ -GameLib.API.Entity.FromObject = function(objectEntity) { - return new GameLib.API.Entity( - objectEntity.id, - objectEntity.name, - objectEntity.components, - objectEntity.parentEntity, - objectEntity.parentEntityManager - ) -}; - -/** - * Raw GUI API object - should always correspond with the GUI Schema - * @param id - * @param name - * @param domElement - * @param parentEntity - * @constructor - */ -GameLib.API.GUI = function( - id, - name, - domElement, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'GUI (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(domElement)) { - domElement = null; - } - this.domElement = domElement; - - GameLib.API.Component.call( - this, - GameLib.Component.GUI, - parentEntity - ); -}; - -GameLib.API.GUI.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.GUI.prototype.constructor = GameLib.API.GUI; - -/** - * Creates an API GUI from an Object GUI - * @param objectGUI - * @constructor - */ -GameLib.API.GUI.FromObject = function(objectGUI) { - - var apiDomElement = null; - if (objectGUI.domElement) { - if (objectGUI.domElement instanceof Object) { - apiDomElement = GameLib.API.DomElement.FromObject(objectGUI.domElement); - } else { - apiDomElement = objectGUI.domElement; - } - } - - return new GameLib.API.GUI( - objectGUI.id, - objectGUI.name, - apiDomElement, - objectGUI.parentEntity - ); - -}; - -/** - * Image - * @param id - * @param name - * @param fileName - * @param extension - * @param path - * @param contentType - * @param size - * @param parentEntity GameLib.Entity - * @constructor - */ -GameLib.API.Image = function( - id, - name, - fileName, - extension, - path, - contentType, - size, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Image ' + id; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(fileName)) { - fileName = GameLib.Utils.LowerUnderscore(name); - } - this.fileName = fileName; - - if (GameLib.Utils.UndefinedOrNull(extension)) { - extension = '.unknown'; - } - this.extension = extension; - - if (GameLib.Utils.UndefinedOrNull(path)) { - path = '/'; - } - this.path = path; - - if (GameLib.Utils.UndefinedOrNull(contentType)) { - - contentType = 'application/octet-stream'; - - if (this.extension.match(/(png)$/i)) { - contentType = 'image/png'; - } - - if (this.extension.match(/(jpg|jpeg)$/i)) { - contentType = 'image/jpeg'; - } - - if (this.extension.match(/(gif)$/i)) { - contentType = 'image/gif'; - } - } - this.contentType = contentType; - - if (GameLib.Utils.UndefinedOrNull(size)) { - size = 0; - } - this.size = size; - - GameLib.API.Component.call( - this, - GameLib.Component.IMAGE, - parentEntity - ); -}; - -GameLib.API.Image.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.Image.prototype.constructor = GameLib.API.Image; - -/** - * Returns an API light from an Object light - * @constructor - * @param objectImage - */ -GameLib.API.Image.FromObject = function(objectImage) { - return new GameLib.API.Image( - objectImage.id, - objectImage.name, - objectImage.fileName, - objectImage.extension, - objectImage.path, - objectImage.contentType, - objectImage.size, - objectImage.parentEntity - ); -}; - - -/** - * Api Matrix 4 - * @param row0 GameLib.API.Vector4 - * @param row1 GameLib.API.Vector4 - * @param row2 GameLib.API.Vector4 - * @param row3 GameLib.API.Vector4 - * @constructor - */ -GameLib.API.Matrix4 = function ApiMatrix4( - row0, - row1, - row2, - row3 -) { - this.rows = []; - - if (GameLib.Utils.UndefinedOrNull(row0)) { - row0 = new GameLib.API.Vector4(1, 0, 0, 0); - } - this.rows[0] = row0; - - if (GameLib.Utils.UndefinedOrNull(row1)) { - row1 = new GameLib.API.Vector4(0, 1, 0, 0); - } - this.rows[1] = row1; - - if (GameLib.Utils.UndefinedOrNull(row2)) { - row2 = new GameLib.API.Vector4(0, 0, 1, 0); - } - this.rows[2] = row2; - - if (GameLib.Utils.UndefinedOrNull(row3)) { - row3 = new GameLib.API.Vector4(0, 0, 0, 1); - } - this.rows[3] = row3; - - this.temp = []; - this.temp.push( - new GameLib.API.Vector4() - ); - - this.temp.push( - new GameLib.API.Vector4() - ); - - this.temp.push( - new GameLib.API.Vector4() - ); - - this.temp.push( - new GameLib.API.Vector4() - ); - - this.forward = new GameLib.API.Vector4(); - this.left = new GameLib.API.Vector4(); - this.up = new GameLib.API.Vector4(); -}; - -/** - * Returns an API matrix from an Object matrix - * @param objectMatrix - * @constructor - */ -GameLib.API.Matrix4.FromObject = function(objectMatrix) { - - if (objectMatrix.rows) { - return new GameLib.API.Matrix4( - GameLib.API.Vector4.FromObject(objectMatrix.rows[0]), - GameLib.API.Vector4.FromObject(objectMatrix.rows[1]), - GameLib.API.Vector4.FromObject(objectMatrix.rows[2]), - GameLib.API.Vector4.FromObject(objectMatrix.rows[3]) - ); - } else if (objectMatrix instanceof Array) { - return new GameLib.API.Matrix4( - GameLib.API.Vector4.FromObject(objectMatrix[0]), - GameLib.API.Vector4.FromObject(objectMatrix[1]), - GameLib.API.Vector4.FromObject(objectMatrix[2]), - GameLib.API.Vector4.FromObject(objectMatrix[3]) - ); - } else { - console.warn('Unsupported object matrix type - whats your DB version?'); - throw new Error('Unsupported object matrix type - whats your DB version?'); - } -}; - -GameLib.API.Matrix4.prototype.rotationMatrixX = function (radians) { - this.identity(); - this.rows[1] = new GameLib.API.Vector4(0, Math.cos(radians), -1 * Math.sin(radians), 0); - this.rows[2] = new GameLib.API.Vector4(0, Math.sin(radians), Math.cos(radians), 0); - return this; -}; - -GameLib.API.Matrix4.prototype.rotationMatrixY = function (radians) { - this.identity(); - this.rows[0] = new GameLib.API.Vector4( - Math.cos(radians), - 0, - Math.sin(radians), - 0 - ); - this.rows[2] = new GameLib.API.Vector4( - -1 * Math.sin(radians), - 0, - Math.cos(radians), - 0 - ); - return this; -}; - -GameLib.API.Matrix4.prototype.rotationMatrixZ = function (radians) { - this.identity(); - this.rows[0] = new GameLib.API.Vector4(Math.cos(radians), -1 * Math.sin(radians), 0, 0); - this.rows[1] = new GameLib.API.Vector4(Math.sin(radians), Math.cos(radians), 0, 0); - return this; -}; - -GameLib.API.Matrix4.prototype.rotateX = function (radians, point) { - this.identity(); - this.rotationMatrixX(radians); - return this.multiply(point); -}; - -GameLib.API.Matrix4.prototype.rotateY = function (radians, point) { - this.identity(); - this.rotationMatrixY(radians); - return this.multiply(point); -}; - -GameLib.API.Matrix4.prototype.rotateZ = function (radians, point) { - this.identity(); - this.rotationMatrixZ(radians); - return this.multiply(point); -}; - -GameLib.API.Matrix4.prototype.multiply = function (mvp) { - if (mvp instanceof GameLib.API.Quaternion || mvp instanceof GameLib.API.Vector4) { - return new GameLib.API.Quaternion( - this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z + this.rows[0].w * mvp.w, - this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z + this.rows[1].w * mvp.w, - this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z + this.rows[2].w * mvp.w, - this.rows[3].x * mvp.x + this.rows[3].y * mvp.y + this.rows[3].z * mvp.z + this.rows[3].w * mvp.w - ); - } else if (mvp instanceof GameLib.API.Vector3) { - return new GameLib.API.Vector3( - this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z, - this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z, - this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z - ); - } -}; - -GameLib.API.Matrix4.prototype.identity = function () { - this.rows = [ - new GameLib.API.Vector4(1, 0, 0, 0), - new GameLib.API.Vector4(0, 1, 0, 0), - new GameLib.API.Vector4(0, 0, 1, 0), - new GameLib.API.Vector4(0, 0, 0, 1) - ]; -}; - -/** - * API Mouse - * @param id - * @param name - * @param x - * @param y - * @param parentEntity - * @constructor - */ -GameLib.API.Mouse = function( - id, - name, - x, - y, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Mouse (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(x)) { - x = 0; - } - this.x = x; - - if (GameLib.Utils.UndefinedOrNull(y)) { - y = 0; - } - this.y = y; - - GameLib.API.Component.call( - this, - GameLib.Component.MOUSE, - parentEntity - ); -}; - -GameLib.API.Mouse.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.Mouse.prototype.constructor = GameLib.API.Mouse; - -/** - * Returns an API mouse from an Object mouse - * @param objectMouse - * @constructor - */ -GameLib.API.Mouse.FromObject = function (objectMouse) { - return new GameLib.API.Mouse( - objectMouse.id, - objectMouse.name, - objectMouse.x, - objectMouse.y, - objectMouse.parentEntity - ) -}; - -/** - * Quaternion - * @param x - * @param y - * @param z - * @param w - * @param axis - * @param angle - * @constructor - */ -GameLib.API.Quaternion = function ( - x, - y, - z, - w, - axis, - angle -) { - - if (GameLib.Utils.UndefinedOrNull(x)) { - x = 0; - } - this.x = x; - - if (GameLib.Utils.UndefinedOrNull(y)) { - y = 0; - } - this.y = y; - - if (GameLib.Utils.UndefinedOrNull(z)) { - z = 0; - } - this.z = z; - - if (GameLib.Utils.UndefinedOrNull(w)) { - w = 1; - } - this.w = w; - - if (GameLib.Utils.UndefinedOrNull(axis)) { - axis = new GameLib.API.Vector3(); - } - this.axis = axis; - - if (GameLib.Utils.UndefinedOrNull(angle)) { - angle = 0; - } - this.angle = angle; -}; - -GameLib.API.Quaternion.prototype.translate = function (v) { - this.x += v.x; - this.y += v.y; - this.z += v.z; - return this; -}; - -GameLib.API.Quaternion.prototype.copy = function () { - return new GameLib.API.Quaternion( - this.x, - this.y, - this.z, - this.w - ); -}; - -/** - * Note, this normalize function leaves 'w' component untouched - */ -GameLib.API.Quaternion.prototype.normalize = function () { - - var EPSILON = 0.000001; - - var v2 = this.x * this.x + this.y * this.y + this.z * this.z; - - if (v2 < EPSILON) { - return this; //do nothing for zero vector - } - - var invLength = 1 / Math.sqrt(v2); - - this.x *= invLength; - this.y *= invLength; - this.z *= invLength; -}; - -GameLib.API.Quaternion.prototype.multiply = function (q) { - - var x, y, z, w; - var a = q; - var b = this; - - if (q instanceof GameLib.API.Matrix4) { - - x = a.rows[0].x * b.x + a.rows[0].y * b.y + a.rows[0].z * b.z + a.rows[0].w * b.w; - y = a.rows[1].x * b.x + a.rows[1].y * b.y + a.rows[1].z * b.z + a.rows[1].w * b.w; - z = a.rows[2].x * b.x + a.rows[2].y * b.y + a.rows[2].z * b.z + a.rows[2].w * b.w; - w = a.rows[3].x * b.x + a.rows[3].y * b.y + a.rows[3].z * b.z + a.rows[3].w * b.w; - - this.x = x; - this.y = y; - this.z = z; - this.w = w; - - return this; - - } else if (q instanceof GameLib.API.Quaternion) { - - x = ((a.x * b.x) - (a.y * b.y) - (a.z * b.z) - (a.w * a.w)); - y = ((a.x * b.y) + (a.y * b.x) - (a.z * b.w) + (a.w * a.z)); - z = ((a.x * b.z) + (a.y * b.w) + (a.z * b.x) - (a.w * a.y)); - w = ((a.x * b.w) - (a.y * b.z) + (a.z * b.y) + (a.w * a.x)); - - this.x = x; - this.y = y; - this.z = z; - this.w = w; - - return this; - - } else { - console.log("This functionality not implemented - please do this"); - throw new Error("This functionality not implemented - please do this"); - } -}; - -GameLib.API.Quaternion.prototype.setFromAngle = function (angle) { - - this.instance.setFromAxisAngle(this.axis.instance, angle); - - this.x = this.instance.x; - this.y = this.instance.y; - this.z = this.instance.z; - this.w = this.instance.w; - - return this; -}; - -GameLib.API.Quaternion.prototype.subtract = function (v) { - - if (v instanceof GameLib.API.Vector3) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; - } - - if (v instanceof GameLib.API.Quaternion) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; - this.w -= v.w; - } - - return this; -}; - -GameLib.API.Quaternion.prototype.magnitude = function () { - return Math.sqrt( - (this.x * this.x) + - (this.y * this.y) + - (this.z * this.z) + - (this.w * this.w) - ); -}; - -GameLib.API.Quaternion.prototype.normalize = function () { - - var magnitude = this.magnitude(); - - if (magnitude < 0.000001) { - return this; //do nothing for zero vector - } - - this.x *= magnitude; - this.y *= magnitude; - this.z *= magnitude; - this.w *= magnitude; - - return this; -}; - -/** - * - * @param matrix4 GameLib.Matrix4 - */ -GameLib.API.Quaternion.prototype.setFromRotationMatrix = function(matrix4) { - - this.instance.setFromRotationMatrix(matrix4.instance); - - this.x = this.instance.x; - this.y = this.instance.y; - this.z = this.instance.z; - this.w = this.instance.w; -}; - -/** - * - * @param quaternion GameLib.Quaternion - * @param t - * @returns {GameLib.Quaternion} - */ -GameLib.API.Quaternion.prototype.slerp = function (quaternion, t) { - - this.updateInstance(); - - this.instance.slerp(quaternion.instance, t); - - this.x = this.instance.x; - this.y = this.instance.y; - this.z = this.instance.z; - this.w = this.instance.w; - - return this; -}; - -/** - * Returns an API quaternion from an Object quaternion - * @param objectQuaternion - * @constructor - */ -GameLib.API.Quaternion.FromObject = function (objectQuaternion) { - - var apiAxis = null; - - if (objectQuaternion.axis) { - apiAxis = GameLib.API.Vector3.FromObject(objectQuaternion.axis); - } - - return new GameLib.API.Quaternion( - objectQuaternion.x, - objectQuaternion.y, - objectQuaternion.z, - objectQuaternion.w, - apiAxis, - objectQuaternion.angle - ) -}; -GameLib.API.Quaternion.Points = function () { - this.vectors = []; -}; - -GameLib.API.Quaternion.Points.prototype.add = function (vector) { - - if (vector instanceof GameLib.API.Vector3) { - vector = new GameLib.API.Quaternion( - vector.x, - vector.y, - vector.z, - 1 - ) - } - - if (!vector instanceof GameLib.API.Quaternion) { - console.warn("Vector needs to be of type Quaternion"); - throw new Error("Vector needs to be of type Quaternion"); - } - - this.vectors.push(vector); - - return this; -}; - -GameLib.API.Quaternion.Points.prototype.copy = function () { - - var vectors = []; - - for (var i = 0; i < this.vectors.length; i++) { - vectors.push(this.vectors[i].copy()); - } - - return vectors; -}; - -GameLib.API.Quaternion.Points.prototype.maximizeXDistance = function (grain) { - -// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); - - var multiplier = 0; - - var rotationMatrixY = new GameLib.API.Matrix4().rotationMatrixY(grain); - - var totalRadians = 0; - - var backupVectors = this.copy(); - - var maxXDistance = 0; - - for (var i = 0; i < Math.PI * 2; i += grain) { - - multiplier++; - - for (var j = 0; j < this.vectors.length; j++) { - this.vectors[j] = rotationMatrixY.multiply(this.vectors[j]); - } - - var distances = this.distances(); - - if (distances.x > maxXDistance) { - - maxXDistance = distances.x; - totalRadians = multiplier * grain; - } - } - - this.vectors = backupVectors; - -// console.log("distance: " + maxXDistance + " radians : " + totalRadians); - - var maxRotationMatrix = new GameLib.API.Matrix4().rotationMatrixY(totalRadians); - - for (var k = 0; k < this.vectors.length; k++) { - this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); - } - -// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); - -}; - -GameLib.API.Quaternion.Points.prototype.maximizeYDistance = function (grain) { - -// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); - - var multiplier = 0; - - var rotationMatrixX = new GameLib.API.Matrix4().rotationMatrixX(grain); - - var totalRadians = 0; - - var backupVectors = this.copy(); - - var maxYDistance = 0; - - for (var i = 0; i < Math.PI * 2; i += grain) { - - multiplier++; - - for (var j = 0; j < this.vectors.length; j++) { - this.vectors[j] = rotationMatrixX.multiply(this.vectors[j]); - } - - var distances = this.distances(); - - if (distances.y > maxYDistance) { - maxYDistance = distances.y; - totalRadians = multiplier * grain; - } - } - - this.vectors = backupVectors; - -// console.log("distance: " + maxYDistance + " radians : " + totalRadians); - - var maxRotationMatrix = new GameLib.API.Matrix4().rotationMatrixX(totalRadians); - - for (var k = 0; k < this.vectors.length; k++) { - this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); - } - -// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); - -}; - - -GameLib.API.Quaternion.Points.prototype.lookAt = function (at, up) { - - var polyCenter = this.average(); - - console.log("poly center : " + JSON.stringify(polyCenter)); - - var lookAtMatrix = new GameLib.API.Matrix4().lookAt(polyCenter, at, up); - - lookAtMatrix.rows[0] = new GameLib.API.Quaternion(1, 0, 0, 0); - lookAtMatrix.rows[1] = new GameLib.API.Quaternion(0, 0, 1, 0); - lookAtMatrix.rows[2] = new GameLib.API.Quaternion(0, 1, 0, 0); - - console.log("look at matrix : " + JSON.stringify(lookAtMatrix, null, 2)); - - for (var i = 0; i < this.vectors.length; i++) { - console.log("vector " + i + " (before): " + JSON.stringify(this.vectors[i])); - this.vectors[i] = lookAtMatrix.multiply(this.vectors[i]); - console.log("vector " + i + " (after) : " + JSON.stringify(this.vectors[i])); - } -}; - -GameLib.API.Quaternion.Points.prototype.distances = function () { - - var minX = this.vectors[0].x; - var minY = this.vectors[0].y; - var minZ = this.vectors[0].z; - - var maxX = this.vectors[0].x; - var maxY = this.vectors[0].y; - var maxZ = this.vectors[0].z; - - for (var i = 0; i < this.vectors.length; i++) { - if (this.vectors[i].x < minX) { - minX = this.vectors[i].x; - } - if (this.vectors[i].y < minY) { - minY = this.vectors[i].y; - } - if (this.vectors[i].z < minZ) { - minZ = this.vectors[i].z; - } - - if (this.vectors[i].x > maxX) { - maxX = this.vectors[i].x; - } - if (this.vectors[i].y > maxY) { - maxY = this.vectors[i].y; - } - if (this.vectors[i].z > maxZ) { - maxZ = this.vectors[i].z; - } - } - - return new GameLib.API.Vector3( - Math.abs(maxX - minX), - Math.abs(maxY - minY), - Math.abs(maxY - minZ) - ) -}; - -GameLib.API.Quaternion.Points.prototype.average = function () { - var averageX = 0; - var averageY = 0; - var averageZ = 0; - - for (var i = 0; i < this.vectors.length; i++) { - averageX += this.vectors[i].x; - averageY += this.vectors[i].y; - averageZ += this.vectors[i].z; - } - - return new GameLib.API.Vector3( - averageX / this.vectors.length, - averageY / this.vectors.length, - averageZ / this.vectors.length - ); -}; - -GameLib.API.Quaternion.Points.prototype.negate = function () { - - for (var i = 0; i < this.vectors.length; i++) { - this.vectors[i].x *= -1; - this.vectors[i].y *= -1; - this.vectors[i].z *= -1; - } - - return this; -}; - - -GameLib.API.Quaternion.Points.prototype.toOrigin = function () { - - var distanceFromOrigin = this.average().negate(); - - for (var i = 0; i < this.vectors.length; i++) { - this.vectors[i].translate(distanceFromOrigin); - } -}; -/** - * Raw Server API object - should always correspond with the Server Schema - * @param id - * @param name - * @param protocol - * @param ip - * @param port - * @param protocols - * @param parentEntity - * @constructor - */ -GameLib.API.Server = function( - id, - name, - protocol, - ip, - port, - protocols, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Server (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(protocol)) { - protocol = 'http'; - } - this.protocol = protocol; - - if (GameLib.Utils.UndefinedOrNull(ip)) { - ip = '127.0.0.1'; - } - this.ip = ip; - - if (GameLib.Utils.UndefinedOrNull(port)) { - port = 80; - } - this.port = port; - - if (GameLib.Utils.UndefinedOrNull(protocols)) { - protocols = []; - } - this.protocols = protocols; - - GameLib.API.Component.call( - this, - GameLib.Component.SERVER, - parentEntity - ); -}; - -GameLib.API.Server.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.Server.prototype.constructor = GameLib.API.Server; - -/** - * Creates an API Server from an Object Server - * @param objectServer - * @constructor - */ -GameLib.API.Server.FromObject = function(objectServer) { - - return new GameLib.API.Server( - objectServer.id, - objectServer.name, - objectServer.protocol, - objectServer.ip, - objectServer.port, - objectServer.protocols, - objectServer.parentEntity - ); - -}; - -/** - * Raw Socket API object - should always correspond with the Socket Schema - * @param id - * @param name - * @param socketType - * @param roomId - * @param peerId - * @param server GameLib.Server - * @param parentEntity - * @constructor - */ -GameLib.API.Socket = function( - id, - name, - socketType, - roomId, - peerId, - server, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Socket (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(socketType)) { - socketType = GameLib.API.Socket.TYPE_NONE; - } - this.socketType = socketType; - - if (GameLib.Utils.UndefinedOrNull(roomId)) { - roomId = 'room_' + GameLib.Utils.RandomId(); - } - this.roomId = roomId; - - if (GameLib.Utils.UndefinedOrNull(peerId)) { - peerId = null; - } - this.peerId = peerId; - - if (GameLib.Utils.UndefinedOrNull(server)) { - server = null; - } - this.server = server; - - var componentType = GameLib.Component.SOCKET; - - if (this.socketType === GameLib.API.Socket.TYPE_CAST) { - componentType = GameLib.Component.SOCKET_CAST; - } - - if (this.socketType === GameLib.API.Socket.TYPE_RECEIVE) { - componentType = GameLib.Component.SOCKET_RECEIVE; - } - - GameLib.API.Component.call( - this, - componentType, - parentEntity - ); -}; - -GameLib.API.Socket.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.Socket.prototype.constructor = GameLib.API.Socket; - -GameLib.API.Socket.TYPE_NONE = 0x1; -GameLib.API.Socket.TYPE_CAST = 0x2; -GameLib.API.Socket.TYPE_RECEIVE = 0x3; - -/** - * Creates an API Socket from an Object Socket - * @param objectSocket - * @constructor - */ -GameLib.API.Socket.FromObject = function(objectSocket) { - - return new GameLib.API.Socket( - objectSocket.id, - objectSocket.name, - objectSocket.socketType, - objectSocket.roomId, - objectSocket.peerId, - objectSocket.server, - objectSocket.parentEntity - ); - -}; - -/** - * Raw Cast API object - should always correspond with the Cast Schema - * @param apiSocket - * @param castType - * @param source - * @param sourceProperties - * @constructor - */ -GameLib.API.Socket.Cast = function( - apiSocket, - castType, - source, - sourceProperties -) { - - if (GameLib.Utils.UndefinedOrNull(apiSocket)) { - apiSocket = {}; - } - - GameLib.API.Socket.call( - this, - apiSocket - ); - - if (GameLib.Utils.UndefinedOrNull(castType)) { - castType = GameLib.API.Socket.Cast.CAST_TYPE_ROOM; - } - this.castType = castType; - - if (GameLib.Utils.UndefinedOrNull(source)) { - source = null; - } - this.source = source; - - if (GameLib.Utils.UndefinedOrNull(sourceProperties)) { - sourceProperties = null; - } - this.sourceProperties = sourceProperties; - - GameLib.API.Component.call( - this, - GameLib.Component.SOCKET_CAST - ); -}; - -GameLib.API.Socket.Cast.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.Socket.Cast.prototype.constructor = GameLib.API.Socket.Cast.Receive; - -GameLib.API.Socket.Cast.CAST_TYPE_ROOM = 0x1; -GameLib.API.Socket.Cast.CAST_TYPE_PEER = 0x2; -GameLib.API.Socket.Cast.CAST_TYPE_ALL = 0x3; -GameLib.API.Socket.Cast.CAST_TYPE_ALL_BUT_PEER = 0x4; - - -/** - * Creates an API.Socket.Cast from an Object Cast - * @param objectSocketCast - * @constructor - */ -GameLib.API.Socket.Cast.FromObject = function(objectSocketCast) { - - var apiSocket = GameLib.API.Socket.FromObject(objectSocketCast); - - return new GameLib.API.Socket.Cast( - apiSocket, - objectSocketCast.castType, - objectSocketCast.source, - objectSocketCast.sourceProperties - ); -}; - -/** - * Raw Socket.Receive API object - should always correspond with the Socket.Receive Schema - * @param apiSocket - * @param receiveType - * @param destination - * @param destinationProperties - * @constructor - */ -GameLib.API.Socket.Receive = function( - apiSocket, - receiveType, - destination, - destinationProperties -) { - - if (GameLib.Utils.UndefinedOrNull(apiSocket)) { - apiSocket = {}; - } - - GameLib.API.Socket.call( - this, - apiSocket - ); - - if (GameLib.Utils.UndefinedOrNull(receiveType)) { - receiveType = GameLib.API.Socket.Receive.RECEIVE_TYPE_ROOM; - } - this.receiveType = receiveType; - - if (GameLib.Utils.UndefinedOrNull(destination)) { - destination = null; - } - this.destination = destination; - - if (GameLib.Utils.UndefinedOrNull(destinationProperties)) { - destinationProperties = null; - } - this.destinationProperties = destinationProperties; - - GameLib.API.Component.call( - this, - GameLib.Component.SOCKET_RECEIVE - ); -}; - -GameLib.API.Socket.Receive.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.Socket.Receive.prototype.constructor = GameLib.API.Socket.Receive; - -GameLib.API.Socket.Receive.RECEIVE_TYPE_ROOM = 0x1; -GameLib.API.Socket.Receive.RECEIVE_TYPE_PEER = 0x2; - - -/** - * Creates an API Socket.Receive from an Object Socket.Receive - * @param socket GameLib.SocketsRuntime - * @param objectSocketReceive - * @constructor - */ -GameLib.API.Socket.Receive.FromObject = function(socket, objectSocketReceive) { - - var apiSocket = GameLib.API.Socket.FromObject(objectSocketReceive); - - return new GameLib.API.Socket.Receive( - apiSocket, - objectSocketReceive.receiveType, - objectSocketReceive.destination, - objectSocketReceive.destinationProperties - ); - -}; - -/** - * Raw Stats API object - should always correspond with the Stats Schema - * @param id - * @param name - * @param domElement - * @param parentEntity - * @constructor - */ -GameLib.API.Stats = function( - id, - name, - domElement, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Stats (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(domElement)) { - domElement = null; - } - this.domElement = domElement; - - GameLib.API.Component.call( - this, - GameLib.Component.STATS, - parentEntity - ); -}; - -GameLib.API.Stats.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.Stats.prototype.constructor = GameLib.API.Stats; - -/** - * Creates an API Stats from an Object Stats - * @param objectStats - * @constructor - */ -GameLib.API.Stats.FromObject = function(objectStats) { - - var apiDomElement = null; - if (objectStats.domElement) { - if (objectStats.domElement instanceof Object) { - apiDomElement = GameLib.API.DomElement.FromObject(objectStats.domElement); - } else { - apiDomElement = objectStats.domElement; - } - } - - return new GameLib.API.Stats( - objectStats.id, - objectStats.name, - apiDomElement, - objectStats.parentEntity - ); - -}; - -/** - * This component renders a scene - * @param id String - * @param name String - * @param systemType - * @param parentEntity - * @constructor - */ -GameLib.API.System = function ( - id, - name, - systemType, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = "System (" + this.id + ")"; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(systemType)) { - systemType = GameLib.System.SYSTEM_TYPE_NONE; - } - this.systemType = systemType; - - var componentType = GameLib.Component.SYSTEM; - - if (this.systemType === GameLib.System.SYSTEM_TYPE_NONE) { - componentType = GameLib.Component.SYSTEM; - } - - if (this.systemType === GameLib.System.SYSTEM_TYPE_ANIMATION) { - componentType = GameLib.Component.SYSTEM_ANIMATION; - } - - if (this.systemType === GameLib.System.SYSTEM_TYPE_CUSTOM) { - componentType = GameLib.Component.SYSTEM_CUSTOM_CODE; - } - - if (this.systemType === GameLib.System.SYSTEM_TYPE_GUI) { - componentType = GameLib.Component.SYSTEM_GUI; - } - - if (this.systemType === GameLib.System.SYSTEM_TYPE_INPUT) { - componentType = GameLib.Component.SYSTEM_INPUT; - } - - if (this.systemType === GameLib.System.SYSTEM_TYPE_LINKING) { - componentType = GameLib.Component.SYSTEM_LINKING; - } - - if (this.systemType === GameLib.System.SYSTEM_TYPE_PHYSICS) { - componentType = GameLib.Component.SYSTEM_PHYSICS; - } - - if (this.systemType === GameLib.System.SYSTEM_TYPE_RENDER) { - componentType = GameLib.Component.SYSTEM_RENDER; - } - - if (this.systemType === GameLib.System.SYSTEM_TYPE_STORAGE) { - componentType = GameLib.Component.SYSTEM_STORAGE; - } - - if (this.systemType === GameLib.System.SYSTEM_TYPE_VISUALIZATION) { - componentType = GameLib.Component.SYSTEM_VISUALIZATION; - } - - if (this.systemType === GameLib.System.SYSTEM_TYPE_PARTICLE) { - componentType = GameLib.Component.SYSTEM_PARTICLE; - } - - if (this.systemType === GameLib.System.SYSTEM_TYPE_AUDIO) { - componentType = GameLib.Component.SYSTEM_AUDIO; - } - - GameLib.API.Component.call( - this, - componentType, - parentEntity - ); - -}; - -GameLib.API.System.prototype = Object.create(GameLib.Component.prototype); -GameLib.API.System.prototype.constructor = GameLib.API.System; - -/** - * Object to GameLib.D3.API.System - * @param objectComponent - * @constructor - */ -GameLib.API.System.FromObject = function(objectComponent) { - return new GameLib.API.System( - objectComponent.id, - objectComponent.name, - objectComponent.systemType, - objectComponent.parentEntity - ); -}; - -GameLib.API.Vector2 = function (x, y) { - - if (GameLib.Utils.UndefinedOrNull(x)) { - x = 0; - } - this.x = x; - - if (GameLib.Utils.UndefinedOrNull(y)) { - y = 0; - } - this.y = y; - -}; - -GameLib.API.Vector2.prototype.copy = function () { - return new GameLib.API.Vector2( - this.x, - this.y - ); -}; - -GameLib.API.Vector2.prototype.equals = function (v) { - return this.x === v.x && this.y === v.y; -}; - -/** - * Returns an API vector from an Object vector - * @param objectVector - * @constructor - */ -GameLib.API.Vector2.FromObject = function (objectVector) { - return new GameLib.API.Vector2( - objectVector.x, - objectVector.y - ) -}; - -GameLib.API.Vector3 = function (x, y, z) { - - if (GameLib.Utils.UndefinedOrNull(x)) { - x = 0; - } - this.x = x; - - if (GameLib.Utils.UndefinedOrNull(y)) { - y = 0; - } - this.y = y; - - if (GameLib.Utils.UndefinedOrNull(z)) { - z = 0; - } - this.z = z; - -}; - -GameLib.API.Vector3.prototype.negate = function() { - this.x = -this.x; - this.y = -this.y; - this.z = -this.z; - return this; -}; - -GameLib.API.Vector3.prototype.subtract = function (v) { - return new GameLib.API.Vector3( - this.x - v.x, - this.y - v.y, - this.z - v.z - ); -}; - -GameLib.API.Vector3.prototype.sub = function (v) { - return new GameLib.API.Vector3( - this.x - v.x, - this.y - v.y, - this.z - v.z - ); -}; - -GameLib.API.Vector3.prototype.equals = function (v) { - return this.x === v.x && this.y === v.y && this.z === v.z; -}; - -GameLib.API.Vector3.prototype.cross = function (v) { - return new GameLib.API.Vector3( - this.y * v.z - this.z * v.y, - this.z * v.x - this.x * v.z, - this.x * v.y - this.y * v.x - ); -}; - -GameLib.API.Vector3.clockwise = function (u, v, w, viewPoint) { - var normal = GameLib.API.Vector3.normal(u, v, w); - var uv = u.copy(); - var winding = normal.dot(uv.subtract(viewPoint)); - return (winding > 0); -}; - -GameLib.API.Vector3.normal = function (u, v, w) { - var vv = v.copy(); - var wv = w.copy(); - return vv.subtract(u).cross(wv.subtract(u)); -}; - -GameLib.API.Vector3.prototype.lookAt = function (at, up) { - var lookAtMatrix = GameLib.API.Matrix4.lookAt(this, at, up); - return this.multiply(lookAtMatrix); -}; - -GameLib.API.Vector3.prototype.translate = function (v) { - this.x += v.x; - this.y += v.y; - this.z += v.z; - return this; -}; - -GameLib.API.Vector3.prototype.add = function (v) { - this.x += v.x; - this.y += v.y; - this.z += v.z; - return this; -}; - -GameLib.API.Vector3.prototype.squared = function () { - return this.x * this.x + this.y * this.y + this.z * this.z; -}; - -GameLib.API.Vector3.prototype.copy = function () { - return new GameLib.API.Vector3( - this.x, - this.y, - this.z - ); -}; - -GameLib.API.Vector3.prototype.set = function (x, y, z) { - this.x = x; - this.y = y; - this.z = z; -}; - -GameLib.API.Vector3.prototype.lerp = function ( v, alpha ) { - return new GameLib.API.Vector3( - this.x + ( v.x - this.x ) * alpha, - this.y + ( v.y - this.y ) * alpha, - this.z + ( v.z - this.z ) * alpha - ); -}; - -GameLib.API.Vector3.prototype.distanceTo = function(v) { - var dx = this.x - v.x, - dy = this.y - v.y, - dz = this.z - v.z; - return Math.sqrt(dx * dx + dy * dy + dz * dz); -}; - -/** - * @return {number} - */ -GameLib.API.Vector3.AngleDirection = function(forward, directionToCheck, up) { - var perp = forward.cross(directionToCheck); - var dir = perp.dot(up); - - if (dir > 0.0) { - return 1.0; - } else if (dir < 0.0) { - return -1.0; - } else { - return 0.0; - } -}; - -/** - * Multiplies this vector with a scalar, vector or matrix. If you want a copy, copy() it first - * @param object {Number | GameLib.API.Vector3 | GameLib.API.Vector4 | GameLib.API.Matrix3 | GameLib.API.Matrix4} - * @param cross boolean true if you want the cross product, otherwise returns the scalar (dot or inner) product - * @returns {GameLib.API.Vector3 | Number} - */ -GameLib.API.Vector3.prototype.multiply = function (object, cross) { - - var x, y, z; - - var a = object; - var b = this; - - if (GameLib.Utils.UndefinedOrNull(cross)) { - cross = false; - } - - if (typeof object === 'number') { - - if (cross) { - this.x *= object; - this.y *= object; - this.z *= object; - return this; - } else { - return ((this.x * object) + (this.y * object) + (this.z * object)); - } - - } - - if (object instanceof GameLib.API.Vector3) { - - if (cross) { - - x = (a.y * b.z) - (a.z * b.y); - y = (a.z * b.x) - (a.x * b.z); - z = (a.x * b.y) - (a.y * b.x); - - this.x = x; - this.y = y; - this.z = z; - - return this; - - } else { - return ((this.x * object.x) + (this.y * object.y) + (this.z * object.z)); - } - - } else { - console.log("functionality not implemented - please do this"); - throw new Error("not implemented"); - } -}; - - -GameLib.API.Vector3.prototype.dot = function (v) { - return (this.x * v.x) + (this.y * v.y) + (this.z * v.z); -}; - -GameLib.API.Vector3.prototype.normalize = function () { - var EPSILON = 0.000001; - var v2 = this.squared(); - - if (v2 < EPSILON) { - return this; //do nothing for zero vector - } - - var invLength = 1.0 / Math.sqrt(v2); - return new GameLib.API.Vector3( - this.x * invLength, - this.y * invLength, - this.z * invLength - ); -}; - -GameLib.API.Vector3.prototype.clone = function () { - return new GameLib.API.Vector3( - this.x, - this.y, - this.z - ); -}; - -GameLib.API.Vector3.prototype.applyQuaternion = function(q) { - var x = this.x, y = this.y, z = this.z; - var qx = q.x, qy = q.y, qz = q.z, qw = q.w; - - // calculate quat * vector - - var ix = qw * x + qy * z - qz * y; - var iy = qw * y + qz * x - qx * z; - var iz = qw * z + qx * y - qy * x; - var iw = - qx * x - qy * y - qz * z; - - // calculate result * inverse quat - - this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy; - this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz; - this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx; - - return this; -}; - -GameLib.API.Vector3.prototype.clamp = function(min, max) { - this.x = Math.max( min.x, Math.min( max.x, this.x ) ); - this.y = Math.max( min.y, Math.min( max.y, this.y ) ); - this.z = Math.max( min.z, Math.min( max.z, this.z ) ); - - return this; -}; - -GameLib.API.Vector3.prototype.length = function() { - return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); -}; - -GameLib.API.Vector3.prototype.reflect = function(normal) { - return this.sub( v1.copy( normal ).multiply( 2 * this.dot( normal ) ) ); -}; - -GameLib.API.Vector3.prototype.angleTo = function (v) { - var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) ); - return Math.acos( exports.Math.clamp( theta, - 1, 1 ) ); -}; - -/** - * Returns an API vector from an Object vector - * @param objectVector - * @constructor - */ -GameLib.API.Vector3.FromObject = function (objectVector) { - return new GameLib.API.Vector3( - objectVector.x, - objectVector.y, - objectVector.z - ) -}; - -GameLib.API.Vector4 = function (x, y, z, w) { - - if (GameLib.Utils.UndefinedOrNull(x)) { - x = 0; - } - this.x = x; - - if (GameLib.Utils.UndefinedOrNull(y)) { - y = 0; - } - this.y = y; - - if (GameLib.Utils.UndefinedOrNull(z)) { - z = 0; - } - this.z = z; - - if (GameLib.Utils.UndefinedOrNull(w)) { - w = 1; - } - this.w = w; -}; - -GameLib.API.Vector4.prototype.equals = function (v) { - return this.x === v.x && this.y === v.y && this.z === v.z && this.w === v.w; -}; - -/** - * Returns an API vector from an Object vector - * @param objectVector - * @constructor - */ -GameLib.API.Vector4.FromObject = function (objectVector) { - return new GameLib.API.Vector4( - objectVector.x, - objectVector.y, - objectVector.z, - objectVector.w - ) -}; - -/** - * Canvas object - * @param apiCanvas - * @returns {GameLib.Canvas} - * @constructor - */ -GameLib.Canvas = function( - apiCanvas -) { - if (GameLib.Utils.UndefinedOrNull(apiCanvas)) { - apiCanvas = {}; - } - - if (apiCanvas instanceof GameLib.Canvas) { - return apiCanvas; - } - - GameLib.API.Canvas.call( - this, - apiCanvas.id, - apiCanvas.name, - apiCanvas.width, - apiCanvas.height, - apiCanvas.parentEntity - ); - - GameLib.Component.call(this); -}; - -GameLib.Canvas.prototype = Object.create(GameLib.API.Canvas.prototype); -GameLib.Canvas.prototype.constructor = GameLib.Canvas; - -/** - * Creates a light instance - * @returns {*} - */ -GameLib.Canvas.prototype.createInstance = function() { - - this.instance = document.createElement('canvas'); - - this.instance.width = this.width; - this.instance.height = this.height; - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.Canvas.prototype.updateInstance = function(property) { - - if (GameLib.Utils.UndefinedOrNull(property)) { - console.warn('unknown property update for Canvas: ' + property); - } - - if (property === 'width') { - this.instance.width = this.width; - } - - if (property === 'height') { - this.instance.height = this.height; - } - -}; - -/** - * Converts a GameLib.Canvas to a GameLib.API.Canvas - * @returns {GameLib.API.Canvas} - */ -GameLib.Canvas.prototype.toApiObject = function() { - return new GameLib.API.Canvas( - this.id, - this.name, - this.width, - this.height, - GameLib.Utils.IdOrNull(this.parentEntity) - ); -}; - -/** - * Returns a new GameLib.Canvas from a GameLib.API.Canvas - * @param objectCanvas GameLib.API.Canvas - * @returns {GameLib.Canvas} - */ -GameLib.Canvas.FromObject = function(objectCanvas) { - - return new GameLib.Canvas( - GameLib.API.Canvas.FromObject(objectCanvas) - ); - -}; -/** - * Creates a Clock object - * @param graphics - * @param apiClock GameLib.API.Clock - * @constructor - */ -GameLib.Clock = function( - graphics, - apiClock -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiClock)) { - apiClock = {}; - } - - if (apiClock instanceof GameLib.Clock) { - return apiClock; - } - - GameLib.API.Clock.call( - this, - apiClock.id, - apiClock.name, - apiClock.parentEntity - ); - - GameLib.Component.call(this); -} ; - -GameLib.Clock.prototype = Object.create(GameLib.API.Clock.prototype); -GameLib.Clock.prototype.constructor = GameLib.Clock; - -/** - * Creates a camera instance of 'graphics' type (only THREE for now) - * @returns {THREE.Clock} - */ -GameLib.Clock.prototype.createInstance = function() { - - this.instance = new THREE.Clock(); - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.Clock.prototype.updateInstance = function() { - -}; - -GameLib.Clock.prototype.getDelta = function() { - - var delta = this.instance.getDelta(); - - /** - * clamp the delta to 1/60 - */ - - if (delta > (1 / 30.0)) { - // console.log('clipped ' + (delta - (1/30.0)) + ' seconds - essentially lost time'); - delta = (1 / 30.0); - } - - return delta; -}; - -/** - * Converts a GameLib.Clock to a new GameLib.API.Clock - * @returns {GameLib.API.Clock} - */ -GameLib.Clock.prototype.toApiObject = function() { - - return new GameLib.API.Clock( - this.id, - this.name, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - -}; - -/** - * Converts from an Object camera to a GameLib.Clock - * @param graphics GameLib.Graphics - * @param objectClock Object - * @returns {GameLib.Clock} - * @constructor - */ -GameLib.Clock.FromObject = function(graphics, objectClock) { - - var apiClock = GameLib.API.Clock.FromObject(objectClock); - - return new GameLib.Clock( - graphics, - apiClock - ); - -}; - -/** - * Coder - * @param id - * @param name - * @param coderType - * @constructor - */ -GameLib.CoderRuntime = function( - id, - name, - coderType -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Coder (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(coderType)) { - coderType = GameLib.CoderRuntime.TYPE_CODE_MIRROR; - } - this.coderType = coderType; - - this.createInstance(); -}; - -/** - * GameLib.CoderRuntime Types - * @type {number} - */ -GameLib.CoderRuntime.TYPE_CODE_MIRROR = 0x1; - -GameLib.CoderRuntime.prototype.createInstance = function() { - if (this.coderType === GameLib.CoderRuntime.TYPE_CODE_MIRROR) { - this.instance = CodeMirror; - } else { - this.instance = null; - } -}; - -GameLib.CoderRuntime.prototype.updateInstance = function(property) { - if (property === 'coderType') { - this.createInstance(); - } -}; - -/** - * Logs a warning and throws an error if not cannon - */ -GameLib.CoderRuntime.prototype.isNotCodeMirrorThrow = function() { - if (this.instance !== CodeMirror) { - console.error('Only CodeMirror supported'); - throw new Error('Only CodeMirror supported'); - } -}; - -/** - * Runtime color for updating instance objects - * @param graphics GameLib.GraphicsRuntime - * @param parentObject GameLib.D3.* - * @param apiColor GameLib.API.Color - * @param grain Number - * @constructor - */ -GameLib.Color = function ( - graphics, - apiColor, - parentObject, - grain -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiColor)) { - apiColor = {}; - } - - if (apiColor instanceof GameLib.Color) { - return apiColor; - } - - GameLib.API.Color.call( - this, - apiColor.r, - apiColor.g, - apiColor.b, - apiColor.a - ); - - if (GameLib.Utils.UndefinedOrNull(parentObject)) { - parentObject = null; - } - this.parentObject = parentObject; - - if (GameLib.Utils.UndefinedOrNull(grain)) { - grain = 0.001; - } - this.grain = grain; - - this.createInstance(); -}; - -GameLib.Color.prototype = Object.create(GameLib.API.Color.prototype); -GameLib.Color.prototype.constructor = GameLib.Color; - -/** - * Creates an instance color - * @returns {*} - */ -GameLib.Color.prototype.createInstance = function() { - this.instance = new THREE.Color( - this.r, - this.g, - this.b - ); -}; - -/** - * Updates the instance color, calls updateInstance on the parent object - */ -GameLib.Color.prototype.updateInstance = function(property) { - - this.instance.r = this.r; - this.instance.g = this.g; - this.instance.b = this.b; - - if (this.parentObject && - this.parentObject.updateInstance) { - this.parentObject.updateInstance(property); - } -}; - -/** - * Converts runtime color to API Color - * @returns {GameLib.API.Color} - */ -GameLib.Color.prototype.toApiObject = function() { - return new GameLib.API.Color( - this.r, - this.g, - this.b, - this.a - ); -}; - -/** - * Controls Superset - The apiControls properties get moved into the Controls object itself, and then the instance is created - * @param apiControls GameLib.API.Controls - * @constructor - */ -GameLib.Controls = function ( - apiControls -) { - - if (GameLib.Utils.UndefinedOrNull(apiControls)) { - apiControls = {}; - } - - if (apiControls instanceof GameLib.Controls) { - return apiControls; - } - - GameLib.API.Controls.call( - this, - apiControls.id, - apiControls.controlsType, - apiControls.name, - apiControls.domElement, - apiControls.parentEntity - ); - - var linkedObjects = { - domElement : GameLib.DomElement - }; - - var delayed = false; - - if (this.controlsType === GameLib.Controls.CONTROLS_TYPE_EDITOR) { - - linkedObjects.raycaster = GameLib.D3.Raycaster; - linkedObjects.camera = GameLib.D3.Camera; - - delayed = true; - } - - GameLib.Component.call( - this, - linkedObjects, - delayed - ); -}; - -GameLib.Controls.prototype = Object.create(GameLib.API.Controls.prototype); -GameLib.Controls.prototype.constructor = GameLib.Controls; - -GameLib.Controls.D3 = function() {}; - -/** - * Controls Type - * @type {number} - */ -GameLib.Controls.CONTROLS_TYPE_EDITOR = 0x0; -GameLib.Controls.CONTROLS_TYPE_TOUCH = 0x1; -GameLib.Controls.CONTROLS_TYPE_KEYBOARD = 0x2; -GameLib.Controls.CONTROLS_TYPE_MOUSE = 0x3; - -/** - * Creates a mesh instance or updates it - */ -GameLib.Controls.prototype.createInstance = function() { - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the mesh instance - */ -GameLib.Controls.prototype.updateInstance = function() { - console.log('default controls update instance'); -}; - -/** - * Converts a GameLib.Controls to a GameLib.API.Controls - * @returns {GameLib.API.Controls} - */ -GameLib.Controls.prototype.toApiObject = function() { - - var apiControls = new GameLib.API.Controls( - this.id, - this.controlsType, - this.name, - GameLib.Utils.IdOrNull(this.domElement), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiControls; -}; - -/** - * Converts a data object to a GameLib.Controls - * @param objectControls {Object} - * @constructor - */ -GameLib.Controls.FromObject = function(objectControls) { - - var apiControls = GameLib.API.Controls.FromObject(objectControls); - - return new GameLib.Controls( - apiControls - ); - -}; - -/** - * Controls Superset - The apiControls properties get moved into the Controls object itself, and then the instance is created - * @param graphics GameLib.GraphicsRuntime - * @param apiControls GameLib.API.Controls - * @param raycaster - * @param camera - * @constructor - */ -GameLib.Controls.D3.Editor = function ( - graphics, - apiControls, - raycaster, - camera -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(raycaster)) { - raycaster = null; - } - this.raycaster = raycaster; - - if (GameLib.Utils.UndefinedOrNull(camera)) { - camera = null; - } - this.camera = camera; - - if (this.raycaster instanceof GameLib.D3.API.Raycaster) { - this.raycaster = new GameLib.D3.Raycaster( - this.graphics, - this.raycaster - ); - } - - if (this.camera instanceof GameLib.D3.API.Camera) { - this.camera = new GameLib.D3.Camera( - this.graphics, - this.camera - ) - } - - GameLib.Controls.call( - this, - apiControls - ); -}; - -/** - * Inheritance - * @type {GameLib.Controls} - */ -GameLib.Controls.D3.Editor.prototype = Object.create(GameLib.Controls.prototype); -GameLib.Controls.D3.Editor.prototype.constructor = GameLib.Controls.D3.Editor; - -/** - * Create Instance - * @returns {THREE.EditorControls} - */ -GameLib.Controls.D3.Editor.prototype.createInstance = function() { - - if (!this.camera || !this.camera.instance) { - throw new Error('No camera at time of instance'); - } - - if (!this.domElement || !this.domElement.instance) { - throw new Error('No dom element at time of instance'); - } - - this.instance = new THREE.EditorControls( - this.camera.instance, - this.domElement.instance - ); - - GameLib.Controls.prototype.createInstance.call(this); -}; - -/** - * Update Instance - */ -GameLib.Controls.D3.Editor.prototype.updateInstance = function() { - - console.warn('an update instance was called on editor controls - which, if not called from within a running system at the right time will affect the order of input event handling and cause system instability'); - - GameLib.Controls.prototype.updateInstance.call(this); -}; - -/** - * Converts a GameLib.Controls.D3.Editor to a GameLib.D3.API.Mesh - * @returns {GameLib.API.Controls} - */ -GameLib.Controls.D3.Editor.prototype.toApiObject = function() { - - var apiControls = GameLib.Controls.prototype.toApiObject.call(this); - - apiControls.raycaster = GameLib.Utils.IdOrNull(this.raycaster); - apiControls.camera = GameLib.Utils.IdOrNull(this.camera); - - return apiControls; -}; - -/** - * Construct an Editor Controls object from data - * @param graphics - * @param objectControls - * @returns {GameLib.Controls.D3.Editor} - * @constructor - */ -GameLib.Controls.D3.Editor.FromObject = function(graphics, objectControls) { - - var apiControls = GameLib.API.Controls.FromObject(objectControls); - - return new GameLib.Controls.D3.Editor( - graphics, - apiControls, - objectControls.raycaster, - objectControls.camera - ); - -}; -/** - * Keyboard Controls - * @param apiControls GameLib.API.Controls - * @constructor - */ -GameLib.Controls.Keyboard = function ( - apiControls -) { - GameLib.Controls.call( - this, - apiControls - ); -}; - -/** - * Inheritance - * @type {GameLib.Controls} - */ -GameLib.Controls.Keyboard.prototype = Object.create(GameLib.Controls.prototype); -GameLib.Controls.Keyboard.prototype.constructor = GameLib.Controls.Keyboard; - -/** - * Create Instance - * @returns - */ -GameLib.Controls.Keyboard.prototype.createInstance = function() { - /** - * Set instance to true to indicate no dependencies to other components - */ - this.instance = true; - GameLib.Controls.prototype.createInstance.call(this); -}; - -/** - * Update Instance - */ -GameLib.Controls.Keyboard.prototype.updateInstance = function() { - GameLib.Controls.prototype.updateInstance.call(this); -}; - -/** - * Converts a GameLib.Controls.Keyboard to a GameLib.API.Controls - * @returns {GameLib.API.Controls} - */ -GameLib.Controls.Keyboard.prototype.toApiObject = function() { - var apiControls = GameLib.Controls.prototype.toApiObject.call(this); - /** - * add other properties here as this component develops... - */ - return apiControls; -}; - -/** - * Construct an Keyboard Controls object from data - * @param objectControls - * @returns {GameLib.Controls.Keyboard} - * @constructor - */ -GameLib.Controls.Keyboard.FromObject = function(objectControls) { - - var apiControls = GameLib.API.Controls.FromObject(objectControls); - - return new GameLib.Controls.Keyboard( - apiControls - ); - -}; -/** - * Mouse Controls - * @param apiControls GameLib.API.Controls - * @constructor - */ -GameLib.Controls.Mouse = function ( - apiControls -) { - GameLib.Controls.call( - this, - apiControls - ); -}; - -/** - * Inheritance - * @type {GameLib.Controls} - */ -GameLib.Controls.Mouse.prototype = Object.create(GameLib.Controls.prototype); -GameLib.Controls.Mouse.prototype.constructor = GameLib.Controls.Mouse; - -/** - * Create Instance - * @returns - */ -GameLib.Controls.Mouse.prototype.createInstance = function() { - /** - * Set instance to true to indicate no dependencies to other components - */ - this.instance = true; - GameLib.Controls.prototype.createInstance.call(this); -}; - -/** - * Update Instance - */ -GameLib.Controls.Mouse.prototype.updateInstance = function() { - GameLib.Controls.prototype.updateInstance.call(this); -}; - -/** - * Converts a GameLib.Controls.Mouse to a GameLib.API.Controls - * @returns {GameLib.API.Controls} - */ -GameLib.Controls.Mouse.prototype.toApiObject = function() { - var apiControls = GameLib.Controls.prototype.toApiObject.call(this); - /** - * add other properties here as this component develops... - */ - return apiControls; -}; - -/** - * Construct an Mouse Controls object from data - * @param objectControls - * @returns {GameLib.Controls.Mouse} - * @constructor - */ -GameLib.Controls.Mouse.FromObject = function(objectControls) { - - var apiControls = GameLib.API.Controls.FromObject(objectControls); - - return new GameLib.Controls.Mouse( - apiControls - ); - -}; -/** - * Touch Controls - * @param apiControls GameLib.API.Controls - * @param sensitivity - * @constructor - */ -GameLib.Controls.Touch = function ( - apiControls, - sensitivity -) { - if (GameLib.Utils.UndefinedOrNull(sensitivity)) { - sensitivity = 5; - } - this.sensitivity = sensitivity; - - GameLib.Controls.call( - this, - apiControls - ); -}; - -/** - * Inheritance - * @type {GameLib.Controls} - */ -GameLib.Controls.Touch.prototype = Object.create(GameLib.Controls.prototype); -GameLib.Controls.Touch.prototype.constructor = GameLib.Controls.Touch; - -/** - * Create Instance - * @returns - */ -GameLib.Controls.Touch.prototype.createInstance = function() { - /** - * Set instance to true to indicate no dependencies to other components - */ - this.instance = true; - GameLib.Controls.prototype.createInstance.call(this); -}; - -/** - * Update Instance - */ -GameLib.Controls.Touch.prototype.updateInstance = function() { - GameLib.Controls.prototype.updateInstance.call(this); -}; - -/** - * Converts a GameLib.Controls.Touch to a GameLib.API.Controls - * @returns {GameLib.API.Controls} - */ -GameLib.Controls.Touch.prototype.toApiObject = function() { - - var apiControls = GameLib.Controls.prototype.toApiObject.call(this); - - apiControls.sensitivity = this.sensitivity; - - /** - * add other properties here as this component develops... - */ - return apiControls; -}; - -/** - * Construct an Touch Controls object from data - * @param objectControls - * @returns {GameLib.Controls.Touch} - * @constructor - */ -GameLib.Controls.Touch.FromObject = function(objectControls) { - - var apiControls = GameLib.API.Controls.FromObject(objectControls); - - return new GameLib.Controls.Touch( - apiControls, - objectControls.sensitivity - ); - -}; -/** - * Creates a CustomCode object - * @param apiCustomCode GameLib.API.CustomCode - * @constructor - */ -GameLib.CustomCode = function( - apiCustomCode -) { - - if (GameLib.Utils.UndefinedOrNull(apiCustomCode)) { - apiCustomCode = {}; - } - - if (apiCustomCode instanceof GameLib.CustomCode) { - return apiCustomCode; - } - - GameLib.API.CustomCode.call( - this, - apiCustomCode.id, - apiCustomCode.name, - apiCustomCode.eventId, - apiCustomCode.code, - apiCustomCode.parentEntity - ); - - this.editor = null; - - GameLib.Component.call(this); -}; - -GameLib.CustomCode.prototype = Object.create(GameLib.API.CustomCode.prototype); -GameLib.CustomCode.prototype.constructor = GameLib.CustomCode; - -GameLib.CustomCode.prototype.createInstance = function() { - - try { - this.instance = new Function('data', this.code).bind(this); - } catch (error) { - /** - * Set the instance to true here to indicate that even though the compilation failed, the instance will be fine and - * this component loaded fine. - */ - this.instance = new Function('data', "console.log('compilation failed for : " + this.name + "');").bind(this); - } - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.CustomCode.prototype.updateInstance = function() { - - try { - this.instance = new Function('data', this.code).bind(this); - this.publish( - GameLib.Event.COMPILE_SUCCESS, - { - component : this - } - ) - } catch (error) { - this.instance = new Function('data', "console.log('compilation update failed for : " + this.name + "');").bind(this); - this.publish( - GameLib.Event.COMPILE_FAILED, - { - component : this - } - ) - } - -}; - -/** - * Converts a GameLib.CustomCode to a new GameLib.API.CustomCode - * @returns {GameLib.API.CustomCode} - */ -GameLib.CustomCode.prototype.toApiObject = function() { - - return new GameLib.API.CustomCode( - this.id, - this.name, - this.eventId, - this.code, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - -}; - -/** - * Converts from an Object CustomCode to a GameLib.CustomCode - * @param objectCustomCode Object - * @returns {GameLib.CustomCode} - * @constructor - */ -GameLib.CustomCode.FromObject = function(objectCustomCode) { - var apiCustomCode = GameLib.API.CustomCode.FromObject(objectCustomCode); - return new GameLib.CustomCode( - apiCustomCode - ); -}; - -GameLib.CustomCode.prototype.launchEditor = function(){ - - GameLib.Event.Emit( - GameLib.Event.GET_RUNTIME, - null, - function(runtime) { - this.coder = runtime.coder; - this.coder.isNotCodeMirrorThrow(); - }.bind(this) - ); - - this.editor = this.coder.instance( - document.body, - { - value : this.code, - mode : 'javascript', - lineNumbers : true, - scrollbarStyle : 'overlay', - indentWithTabs: true, - indentUnit : 4 - } - ); - - this.editor.on('change', function(){ - - this.code = this.editor.getValue(); - - this.updateInstance(); - - }.bind(this)) -}; - -GameLib.CustomCode.prototype.closeEditor = function(){ - var dom = this.editor.getWrapperElement(); - dom.parentElement.removeChild(dom); -}; -/** - * Animation Component - * @param id - * @param name - * @param rotationSpeed - * @param translationSpeed - * @param scaleSpeed - * @param rotationFn - * @param translationFn - * @param scaleFn - * @param blocking - * @param applyToMeshWhenDone - * @param meshes - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Animation = function ( - id, - name, - rotationSpeed, - translationSpeed, - scaleSpeed, - rotationFn, - translationFn, - scaleFn, - blocking, - applyToMeshWhenDone, - meshes, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Animation (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(rotationSpeed)) { - rotationSpeed = 0; - } - this.rotationSpeed = rotationSpeed; - - if (GameLib.Utils.UndefinedOrNull(translationSpeed)) { - translationSpeed = 0; - } - this.translationSpeed = translationSpeed; - - if (GameLib.Utils.UndefinedOrNull(scaleSpeed)) { - scaleSpeed = 0; - } - this.scaleSpeed = scaleSpeed; - - if (GameLib.Utils.UndefinedOrNull(rotationFn)) { - rotationFn = null; - } - this.rotationFn = rotationFn; - - if (GameLib.Utils.UndefinedOrNull(translationFn)) { - translationFn = null; - } - this.translationFn = translationFn; - - if (GameLib.Utils.UndefinedOrNull(scaleFn)) { - scaleFn = null; - } - this.scaleFn = scaleFn; - - if (GameLib.Utils.UndefinedOrNull(blocking)) { - blocking = { - position : false, //positions can be blocked from accumulating and executing at once - rotation : true, //rotations need to execute in order - scale : false //scale can accumulate - }; - } - this.blocking = blocking; - - if (GameLib.Utils.UndefinedOrNull(applyToMeshWhenDone)) { - applyToMeshWhenDone = true; - } - this.applyToMeshWhenDone = applyToMeshWhenDone; - - if (GameLib.Utils.UndefinedOrNull(meshes)) { - meshes = []; - } - this.meshes = meshes; - - GameLib.API.Component.call( - this, - GameLib.Component.ANIMATION, - parentEntity - ); -}; - -GameLib.D3.API.Animation.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Animation.prototype.constructor = GameLib.D3.API.Animation; - -/** - * Object to GameLib.D3.API.Animation - * @param objectComponent - * @returns {GameLib.D3.API.Animation} - * @constructor - */ -GameLib.D3.API.Animation.FromObject = function(objectComponent) { - return new GameLib.D3.API.Animation( - objectComponent.id, - objectComponent.name, - objectComponent.rotationSpeed, - objectComponent.translationSpeed, - objectComponent.scaleSpeed, - objectComponent.rotationFn, - objectComponent.translationFn, - objectComponent.scaleFn, - objectComponent.blocking, - objectComponent.applyToMeshWhenDone, - objectComponent.meshes, - objectComponent.parentEntity - ); -}; - -/** - * Raw Audio API object - should always correspond with the Audio Schema - * @param id - * @param name - * @param path - * @param loop - * @param volume - * @param camera - * @param overplay - * @param paused - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Audio = function( - id, - name, - path, - loop, - volume, - camera, - overplay, - paused, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Audio (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(path)) { - path = ''; - } - this.path = path; - - if (GameLib.Utils.UndefinedOrNull(loop)) { - loop = false; - } - this.loop = loop; - - if (GameLib.Utils.UndefinedOrNull(volume)) { - volume = 0.5; - } - this.volume = volume; - - if (GameLib.Utils.UndefinedOrNull(camera)) { - camera = null; - } - this.camera = camera; - - if (GameLib.Utils.UndefinedOrNull(overplay)) { - overplay = false; - } - this.overplay = overplay; - - if (GameLib.Utils.UndefinedOrNull(paused)) { - paused = false; - } - this.paused = paused; - - GameLib.API.Component.call( - this, - GameLib.Component.AUDIO, - parentEntity - ); -}; - -GameLib.D3.API.Audio.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Audio.prototype.constructor = GameLib.D3.API.Audio; - -/** - * Creates an API Audio from an Object Audio - * @param objectAudio - * @constructor - */ -GameLib.D3.API.Audio.FromObject = function(objectAudio) { - - var apiCamera = null; - if (objectAudio.camera) { - if (objectAudio.camera instanceof Object) { - apiCamera = GameLib.D3.API.Camera.FromObject(objectAudio.camera); - } else { - apiCamera = objectAudio.camera; - } - } - - return new GameLib.D3.API.Audio( - objectAudio.id, - objectAudio.name, - objectAudio.path, - objectAudio.loop, - objectAudio.volume, - apiCamera, - objectAudio.overplay, - objectAudio.paused, - objectAudio.parentEntity - ); - -}; - -/** - * BoneWeight object - associates a vertex to a bone with some weight - * @param boneIndex int - * @param weight float - * @constructor - */ -GameLib.D3.API.BoneWeight = function ( - boneIndex, - weight -) { - this.boneIndex = boneIndex; - this.weight = weight; -}; - -/** - * Object to GameLib.D3.API.BoneWeight - * @param objectBoneWeight - * @returns {GameLib.D3.API.BoneWeight} - * @constructor - */ -GameLib.D3.API.BoneWeight.FromObject = function(objectBoneWeight) { - return new GameLib.D3.API.BoneWeight( - objectBoneWeight.boneIndex, - objectBoneWeight.weight - ) -}; - -/** - * Bone Superset - * @param id - * @param name string - * @param childBoneIds - * @param parentBoneIds - * @param quaternion GameLib.API.Quaternion - * @param position GameLib.API.Vector3 - * @param scale GameLib.API.Vector3 - * @param up GameLib.API.Vector3 - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Bone = function ( - id, - name, - childBoneIds, - parentBoneIds, - position, - quaternion, - scale, - up, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Bone (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(childBoneIds)) { - childBoneIds = []; - } - this.childBoneIds = childBoneIds; - - if (GameLib.Utils.UndefinedOrNull(parentBoneIds)) { - parentBoneIds = []; - } - this.parentBoneIds = parentBoneIds; - - if (GameLib.Utils.UndefinedOrNull(position)) { - position = new GameLib.API.Vector3(); - } - this.position = position; - - if (GameLib.Utils.UndefinedOrNull(quaternion)) { - quaternion = new GameLib.API.Quaternion(); - } - this.quaternion = quaternion; - - if (GameLib.Utils.UndefinedOrNull(scale)) { - scale = new GameLib.API.Vector3(1,1,1); - } - this.scale = scale; - - if (GameLib.Utils.UndefinedOrNull(up)) { - up = new GameLib.API.Vector3(0,1,0); - } - this.up = up; - - GameLib.API.Component.call( - this, - GameLib.Component.BONE, - parentEntity - ); -}; - -GameLib.D3.API.Bone.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Bone.prototype.constructor = GameLib.D3.API.Bone; - -/** - * Returns an API bone from an Object bone - * @param objectBone - * @constructor - */ -GameLib.D3.API.Bone.FromObject = function(objectBone) { - return new GameLib.D3.API.Bone( - objectBone.id, - objectBone.name, - objectBone.childBoneIds, - objectBone.parentBoneIds, - GameLib.API.Vector3.FromObject(objectBone.position), - GameLib.API.Quaternion.FromObject(objectBone.quaternion), - GameLib.API.Vector3.FromObject(objectBone.scale), - GameLib.API.Vector3.FromObject(objectBone.up), - objectBone.parentEntity - ); -}; - -/** - * Raw Broadphase API object - should always correspond with the Broadphase Schema - * @param id - * @param name - * @param broadphaseType - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Broadphase = function( - id, - name, - broadphaseType, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Broadphase (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(broadphaseType)) { - broadphaseType = GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE; - } - this.broadphaseType = broadphaseType; - - GameLib.API.Component.call( - this, - GameLib.Component.BROADPHASE, - parentEntity - ); -}; - -GameLib.D3.API.Broadphase.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Broadphase.prototype.constructor = GameLib.D3.API.Broadphase; - -/** - * Creates an API Broadphase from an Object Broadphase - * @param objectBroadphase - * @constructor - */ -GameLib.D3.API.Broadphase.FromObject = function(objectBroadphase) { - return new GameLib.D3.API.Broadphase( - objectBroadphase.id, - objectBroadphase.name, - objectBroadphase.broadphaseType, - objectBroadphase.parentEntity - ); -}; - - -/** - * Raw Camera API object - should always correspond with the Camera Schema - * @param id - * @param name - * @param cameraType GameLib.D3.Camera.CAMERA_TYPE_* - * @param fov - * @param aspect - * @param near - * @param far - * @param position GameLib.API.Vector3 - * @param lookAt GameLib.API.Vector3 - * @param minX - * @param maxX - * @param minY - * @param maxY - * @param minZ - * @param maxZ - * @param offsetX - * @param offsetY - * @param quaternion GameLib.Quaternion - * @param eyeSeparation - * @param focalLength - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Camera = function( - id, - cameraType, - name, - fov, - aspect, - near, - far, - position, - lookAt, - minX, - maxX, - minY, - maxY, - minZ, - maxZ, - offsetX, - offsetY, - quaternion, - eyeSeparation, - focalLength, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(cameraType)) { - cameraType = GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE; - } - this.cameraType = cameraType; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Camera (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(fov)) { - fov = 75; - } - this.fov = fov; - - if (GameLib.Utils.UndefinedOrNull(aspect)) { - aspect = window.innerWidth / window.innerHeight; - } - this.aspect = aspect; - - if (GameLib.Utils.UndefinedOrNull(near)) { - near = 0.01; - } - this.near = near; - - if (GameLib.Utils.UndefinedOrNull(far)) { - far = 1000; - } - this.far = far; - - if (GameLib.Utils.UndefinedOrNull(position)) { - position = new GameLib.API.Vector3( - 15, - 15, - 15 - ); - } - this.position = position; - - if (GameLib.Utils.UndefinedOrNull(quaternion)) { - quaternion = new GameLib.API.Quaternion(); - } - this.quaternion = quaternion; - - if (GameLib.Utils.UndefinedOrNull(lookAt)) { - lookAt = new GameLib.API.Vector3( - 0, - 0, - 0 - ); - } - this.lookAt = lookAt; - - if (GameLib.Utils.UndefinedOrNull(minX)) { - minX = -100; - } - this.minX = minX; - - if (GameLib.Utils.UndefinedOrNull(maxX)) { - maxX = 100; - } - this.maxX = maxX; - - if (GameLib.Utils.UndefinedOrNull(minY)) { - minY = -100; - } - this.minY = minY; - - if (GameLib.Utils.UndefinedOrNull(maxY)) { - maxY = 100; - } - this.maxY = maxY; - - if (GameLib.Utils.UndefinedOrNull(minZ)) { - minZ = -100; - } - this.minZ = minZ; - - if (GameLib.Utils.UndefinedOrNull(maxZ)) { - maxZ = 100; - } - this.maxZ = maxZ; - - if (GameLib.Utils.UndefinedOrNull(offsetX)) { - offsetX = 0; - } - this.offsetX = offsetX; - - if (GameLib.Utils.UndefinedOrNull(offsetY)) { - offsetY = 0; - } - this.offsetY = offsetY; - - if (GameLib.Utils.UndefinedOrNull(eyeSeparation)) { - eyeSeparation = 30; - } - this.eyeSeparation = eyeSeparation; - - if (GameLib.Utils.UndefinedOrNull(focalLength)) { - focalLength = 150; - } - this.focalLength = focalLength; - - GameLib.API.Component.call( - this, - GameLib.Component.CAMERA, - parentEntity - ); -}; - -GameLib.D3.API.Camera.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Camera.prototype.constructor = GameLib.D3.API.Camera; - -/** - * Creates an API camera from an Object camera - * @param objectCamera - * @constructor - */ -GameLib.D3.API.Camera.FromObject = function(objectCamera) { - - return new GameLib.D3.API.Camera( - objectCamera.id, - objectCamera.cameraType, - objectCamera.name, - objectCamera.fov, - objectCamera.aspect, - objectCamera.near, - objectCamera.far, - GameLib.API.Vector3.FromObject(objectCamera.position), - GameLib.API.Vector3.FromObject(objectCamera.lookAt), - objectCamera.minX, - objectCamera.maxX, - objectCamera.minY, - objectCamera.maxY, - objectCamera.minZ, - objectCamera.maxZ, - objectCamera.offsetX, - objectCamera.offsetY, - GameLib.API.Quaternion.FromObject(objectCamera.quaternion), - objectCamera.eyeSeparation, - objectCamera.focalLength, - objectCamera.parentEntity - ); - -}; - -/** - * This component renders a scene - * @param id String - * @param name String - * @param renderer GameLib.D3.Renderer - * @param renderTarget GameLib.D3.API.RenderTarget - * @param passes GameLib.D3.API.Pass[] - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Composer = function ( - id, - name, - renderer, - renderTarget, - passes, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Composer (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(renderer)) { - renderer = null; - } - this.renderer = renderer; - - if (GameLib.Utils.UndefinedOrNull(renderTarget)) { - renderTarget = null; - } - this.renderTarget = renderTarget; - - if (GameLib.Utils.UndefinedOrNull(passes)) { - passes = []; - } - this.passes = passes; - - GameLib.API.Component.call( - this, - GameLib.Component.COMPOSER, - parentEntity - ); -}; - -GameLib.D3.API.Composer.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Composer.prototype.constructor = GameLib.D3.API.Composer; - -/** - * Object to GameLib.D3.API.Composer - * @param objectComponent - * @constructor - */ -GameLib.D3.API.Composer.FromObject = function(objectComponent) { - return new GameLib.D3.API.Composer( - objectComponent.id, - objectComponent.name, - objectComponent.renderer, - objectComponent.renderTarget, - objectComponent.passes, - objectComponent.parentEntity - ); -}; - -/** - * Face - * @param id - * @param name - * @param v0index - * @param v1index - * @param v2index - * @param materialIndex - * @param uvs [[v0uv (GameLib.Vector2), v1uv(GameLib.Vector2), v2uv(GameLib.Vector2)]] - * @param color - * @param vertexColors - * @param vertexNormals - * @param normal - * @constructor - */ -GameLib.D3.API.Face = function( - id, - name, - v0index, - v1index, - v2index, - materialIndex, - uvs, - color, - vertexColors, - vertexNormals, - normal -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Face ' + id; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(v0index)) { - v0index = -1; - } - this.v0index = v0index; - - if (GameLib.Utils.UndefinedOrNull(v1index)) { - v1index = -1; - } - this.v1index = v1index; - - if (GameLib.Utils.UndefinedOrNull(v2index)) { - v2index = -1; - } - this.v2index = v2index; - - if (GameLib.Utils.UndefinedOrNull(materialIndex)) { - materialIndex = -1; - } - this.materialIndex = materialIndex; - - if (GameLib.Utils.UndefinedOrNull(uvs)) { - uvs = [[]]; - } - this.uvs = uvs; - - if (GameLib.Utils.UndefinedOrNull(color)) { - color = null; - } - this.color = color; - - if (GameLib.Utils.UndefinedOrNull(vertexColors)) { - vertexColors = []; - } - this.vertexColors = vertexColors; - - if (GameLib.Utils.UndefinedOrNull(vertexNormals)) { - vertexNormals = []; - } - this.vertexNormals = vertexNormals; - - if (GameLib.Utils.UndefinedOrNull(normal)) { - normal = null; - } - this.normal = normal; -}; - -/** - * We don't inherit from component - it makes the entitymanager too heavy - all faces end up in the register etc.. - */ - -// GameLib.D3.API.Face.prototype = Object.create(GameLib.Component.prototype); -// GameLib.D3.API.Face.prototype.constructor = GameLib.D3.API.Face; - -/** - * Returns an API Face from a data object - * @constructor - * @param objectFace - */ -GameLib.D3.API.Face.FromObject = function(objectFace) { - - var apiUvs = objectFace.uvs.reduce( - - function(result, uvArray, index) { - - result[index] = uvArray.reduce( - function(uvResult, uv) { - uvResult.push(GameLib.API.Vector2.FromObject(uv)); - return uvResult; - }, - [] - ); - - return result; - }, - [] - ); - - var apiVertexColors = objectFace.vertexColors.map( - function(vertexColor) { - return GameLib.API.Color.FromObject(vertexColor); - } - ); - - var apiColor = null; - if (objectFace.color) { - apiColor = GameLib.API.Color.FromObject(objectFace.color); - } - - var apiVertexNormals = objectFace.vertexNormals.map( - function(vertexNormal) { - return GameLib.API.Vector3.FromObject(vertexNormal); - } - ); - - var apiNormal = null; - if (objectFace.normal) { - apiNormal = GameLib.API.Vector3.FromObject(objectFace.normal); - } - - return new GameLib.D3.API.Face( - objectFace.id, - objectFace.name, - objectFace.v0index, - objectFace.v1index, - objectFace.v2index, - objectFace.materialIndex, - apiUvs, - apiColor, - apiVertexColors, - apiVertexNormals, - apiNormal - ); -}; - -/** - * Clone a Face - * @returns {GameLib.D3.API.Face} - */ -GameLib.D3.API.Face.prototype.clone = function(){ - return new GameLib.D3.API.Face( - this.id, - this.name, - this.v0index, - this.v1index, - this.v2index, - this.materialIndex, - this.uvs, - this.color, - this.vertexColors, - this.vertexNormals, - this.normal - ); - -}; - -/** - * Returns true if two triangles are equal (their vertex indices match in some order) - * @param triangle - * @returns {boolean} - */ -GameLib.D3.API.Face.prototype.equals = function(triangle) { - return ( - ( - (this.v0index === triangle.v0index) && - (this.v1index === triangle.v1index) && - (this.v2index === triangle.v2index) - ) - || - ( - (this.v0index === triangle.v0index) && - (this.v1index === triangle.v2index) && - (this.v2index === triangle.v1index) - ) - || - ( - (this.v0index === triangle.v1index) && - (this.v1index === triangle.v0index) && - (this.v2index === triangle.v2index) - ) - || - ( - (this.v0index === triangle.v1index) && - (this.v1index === triangle.v2index) && - (this.v2index === triangle.v0index) - ) - || - ( - (this.v0index === triangle.v2index) && - (this.v1index === triangle.v0index) && - (this.v2index === triangle.v1index) - ) - || - ( - (this.v0index === triangle.v2index) && - (this.v1index === triangle.v1index) && - (this.v2index === triangle.v0index) - ) - ); -}; - -/** - * Raw Fog API object - should always correspond with the Fog Schema - * @param id String - * @param name String - * @param exponential - * @param color - * @param near - * @param far - * @param density - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Fog = function( - id, - name, - exponential, - color, - near, - far, - density, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Fog (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(exponential)) { - exponential = false; - } - this.exponential = exponential; - - if (GameLib.Utils.UndefinedOrNull(color)) { - color = new GameLib.API.Color(1, 1, 1, 1) - } - this.color = color; - - if (GameLib.Utils.UndefinedOrNull(near)) { - near = 1; - } - this.near = near; - - if (GameLib.Utils.UndefinedOrNull(far)) { - far = 1000; - } - this.far = far; - - if (GameLib.Utils.UndefinedOrNull(density)) { - density = 0.00025; - } - this.density = density; - - GameLib.API.Component.call( - this, - GameLib.Component.FOG, - parentEntity - ); -}; - -GameLib.D3.API.Fog.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Fog.prototype.constructor = GameLib.D3.API.Fog; - -/** - * Returns an API scene from an Object scene - * @param objectFog - * @constructor - */ -GameLib.D3.API.Fog.FromObject = function(objectFog) { - - return new GameLib.D3.API.Fog( - objectFog.id, - objectFog.name, - objectFog.exponential, - objectFog.color, - objectFog.near, - objectFog.far, - objectFog.density, - objectFog.parentEntity - ); - -}; - -/** - * Raw Font API object - should always correspond with the Font Schema - * @param id - * @param name - * @param url - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Font = function( - id, - name, - url, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Font (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(url)) { - url = '/apiRelative/path/to/font'; - } - this.url = url; - - GameLib.API.Component.call( - this, - GameLib.Component.FONT, - parentEntity - ); -}; - -GameLib.D3.API.Font.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Font.prototype.constructor = GameLib.D3.API.Font; - -/** - * Returns an API light from an Object light - * @param objectFont - * @constructor - */ -GameLib.D3.API.Font.FromObject = function(objectFont) { - return new GameLib.D3.API.Font( - objectFont.id, - objectFont.name, - objectFont.url, - objectFont.parentEntity - ); -}; - -/** - * Raw FrictionContactMaterial API object - should always correspond with the FrictionContactMaterial Schema - * @param id - * @param name - * @param materials - * @param friction - * @param restitution - * @param contactEquationStiffness - * @param contactEquationRelaxation - * @param frictionEquationStiffness - * @param frictionEquationRelaxation - * @param parentEntity - * @constructor - */ -GameLib.D3.API.FrictionContactMaterial = function( - id, - name, - materials, - friction, - restitution, - contactEquationStiffness, - contactEquationRelaxation, - frictionEquationStiffness, - frictionEquationRelaxation, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Friction Material (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(materials)) { - materials = []; - } - this.materials = materials; - - if (GameLib.Utils.UndefinedOrNull(friction)) { - friction = 0.3; - } - this.friction = friction; - - if (GameLib.Utils.UndefinedOrNull(restitution)) { - restitution = 0.3; - } - this.restitution = restitution; - - if (GameLib.Utils.UndefinedOrNull(contactEquationStiffness)) { - contactEquationStiffness = 1e7; - } - this.contactEquationStiffness = contactEquationStiffness; - - if (GameLib.Utils.UndefinedOrNull(contactEquationRelaxation)) { - contactEquationRelaxation = 3; - } - this.contactEquationRelaxation = contactEquationRelaxation; - - if (GameLib.Utils.UndefinedOrNull(frictionEquationStiffness)) { - frictionEquationStiffness = 1e7; - } - this.frictionEquationStiffness = frictionEquationStiffness; - - if (GameLib.Utils.UndefinedOrNull(frictionEquationRelaxation)) { - frictionEquationRelaxation = 3; - } - this.frictionEquationRelaxation = frictionEquationRelaxation; - - GameLib.API.Component.call( - this, - GameLib.Component.FRICTION_CONTACT_MATERIAL, - parentEntity - ); -}; - -GameLib.D3.API.FrictionContactMaterial.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.FrictionContactMaterial.prototype.constructor = GameLib.D3.API.FrictionContactMaterial; - -/** - * Creates an API FrictionContactMaterial from an Object FrictionContactMaterial - * @param objectFrictionContactMaterial - * @constructor - */ -GameLib.D3.API.FrictionContactMaterial.FromObject = function(objectFrictionContactMaterial) { - return new GameLib.D3.API.FrictionContactMaterial( - objectFrictionContactMaterial.id, - objectFrictionContactMaterial.name, - objectFrictionContactMaterial.materials, - objectFrictionContactMaterial.friction, - objectFrictionContactMaterial.restitution, - objectFrictionContactMaterial.contactEquationStiffness, - objectFrictionContactMaterial.contactEquationRelaxation, - objectFrictionContactMaterial.frictionEquationStiffness, - objectFrictionContactMaterial.frictionEquationRelaxation, - objectFrictionContactMaterial.parentEntity - ); -}; - - -/** - * Raw FrictionMaterial API object - should always correspond with the FrictionMaterial Schema - * @param id - * @param name - * @param friction - * @param restitution - * @param parentEntity - * @constructor - */ -GameLib.D3.API.FrictionMaterial = function( - id, - name, - friction, - restitution, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Friction Material (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(friction)) { - friction = -1; - } - this.friction = friction; - - if (GameLib.Utils.UndefinedOrNull(restitution)) { - restitution = -1; - } - this.restitution = restitution; - - GameLib.API.Component.call( - this, - GameLib.Component.FRICTION_MATERIAL, - parentEntity - ); -}; - -GameLib.D3.API.FrictionMaterial.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.FrictionMaterial.prototype.constructor = GameLib.D3.API.FrictionMaterial; - -/** - * Creates an API FrictionMaterial from an Object FrictionMaterial - * @param objectFrictionMaterial - * @constructor - */ -GameLib.D3.API.FrictionMaterial.FromObject = function(objectFrictionMaterial) { - return new GameLib.D3.API.FrictionMaterial( - objectFrictionMaterial.id, - objectFrictionMaterial.name, - objectFrictionMaterial.friction, - objectFrictionMaterial.restitution, - objectFrictionMaterial.parentEntity - ); -}; - - -/** - * Raw Light API object - should always correspond with the Light Schema - * @param id - * @param lightType - * @param name - * @param color - * @param intensity - * @param position - * @param targetPosition - * @param quaternion - * @param rotation - * @param scale - * @param distance - * @param decay - * @param power - * @param angle - * @param penumbra - * @param parentScene - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Light = function( - id, - lightType, - name, - color, - intensity, - position, - targetPosition, - quaternion, - rotation, - scale, - distance, - decay, - power, - angle, - penumbra, - parentScene, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(lightType)) { - lightType = GameLib.D3.Light.LIGHT_TYPE_AMBIENT; - } - this.lightType = lightType; - - if (GameLib.Utils.UndefinedOrNull(name)) { - - if (this.lightType === GameLib.D3.Light.LIGHT_TYPE_AMBIENT) { - name = 'Ambient '; - } - - if (this.lightType === GameLib.D3.Light.LIGHT_TYPE_DIRECTIONAL) { - name = 'Directional '; - } - - if (this.lightType === GameLib.D3.Light.LIGHT_TYPE_POINT) { - name = 'Point '; - } - - if (this.lightType === GameLib.D3.Light.LIGHT_TYPE_SPOT) { - name = 'Spot '; - } - - name += 'Light (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(color)) { - color = new GameLib.API.Color(1,1,1,1); - } - this.color = color; - - if (GameLib.Utils.UndefinedOrNull(intensity)) { - intensity = 1; - } - this.intensity = intensity; - - if (GameLib.Utils.UndefinedOrNull(position)) { - position = new GameLib.API.Vector3(10,10,10); - } - this.position = position; - - if (GameLib.Utils.UndefinedOrNull(targetPosition)) { - targetPosition = new GameLib.API.Vector3(0,0,0); - } - this.targetPosition = targetPosition; - - if (GameLib.Utils.UndefinedOrNull(quaternion)){ - quaternion = new GameLib.API.Quaternion(); - } - this.quaternion = quaternion; - - if (GameLib.Utils.UndefinedOrNull(rotation)){ - rotation = new GameLib.API.Vector3(0,0,0); - } - this.rotation = rotation; - - if (GameLib.Utils.UndefinedOrNull(scale)){ - scale = new GameLib.API.Vector3(1,1,1); - } - this.scale = scale; - - if (GameLib.Utils.UndefinedOrNull(distance)){ - distance = 0; - } - this.distance = distance; - - if (GameLib.Utils.UndefinedOrNull(decay)){ - decay = 1; - } - this.decay = decay; - - if (GameLib.Utils.UndefinedOrNull(power)){ - power = 4 * Math.PI; - } - this.power = power; - - if (GameLib.Utils.UndefinedOrNull(angle)){ - angle = Math.PI / 3; - } - this.angle = angle; - - if (GameLib.Utils.UndefinedOrNull(penumbra)){ - penumbra = 0; - } - this.penumbra = penumbra; - - if (GameLib.Utils.UndefinedOrNull(parentScene)){ - parentScene = null; - } - this.parentScene = parentScene; - - GameLib.API.Component.call( - this, - GameLib.Component.LIGHT, - parentEntity - ); -}; - -GameLib.D3.API.Light.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Light.prototype.constructor = GameLib.D3.API.Light; - -/** - * Returns an API light from an Object light - * @param objectLight - * @constructor - */ -GameLib.D3.API.Light.FromObject = function(objectLight) { - return new GameLib.D3.API.Light( - objectLight.id, - objectLight.lightType, - objectLight.name, - GameLib.API.Color.FromObject(objectLight.color), - objectLight.intensity, - GameLib.API.Vector3.FromObject(objectLight.position), - GameLib.API.Vector3.FromObject(objectLight.targetPosition), - GameLib.API.Quaternion.FromObject(objectLight.quaternion), - GameLib.API.Vector3.FromObject(objectLight.rotation), - GameLib.API.Vector3.FromObject(objectLight.scale), - objectLight.distance, - objectLight.decay, - objectLight.power, - objectLight.angle, - objectLight.penumbra, - objectLight.parentScene, - objectLight.parentEntity - ); -}; - -/** - * Raw material API object - should always correspond with the Material Schema - * @param id - * @param materialType - * @param name - * @param opacity - * @param side - * @param transparent - * @param specular - * @param lightMapIntensity - * @param aoMapIntensity - * @param color - * @param emissive - * @param emissiveIntensity - * @param combine - * @param shininess - * @param reflectivity - * @param refractionRatio - * @param fog - * @param wireframe - * @param wireframeLineWidth - * @param wireframeLineCap - * @param wireframeLineJoin - * @param vertexColors - * @param skinning - * @param morphTargets - * @param morphNormals - * @param lineWidth - * @param lineCap - * @param lineJoin - * @param dashSize - * @param gapWidth - * @param blending - * @param blendSrc - * @param blendDst - * @param blendEquation - * @param depthTest - * @param depthFunc - * @param depthWrite - * @param polygonOffset - * @param polygonOffsetFactor - * @param polygonOffsetUnits - * @param alphaTest - * @param clippingPlanes - * @param clipShadows - * @param visible - * @param overdraw - * @param flatShading - * @param bumpScale - * @param normalScale - * @param displacementScale - * @param displacementBias - * @param roughness - * @param metalness - * @param pointSize - * @param pointSizeAttenuation - * @param spriteRotation - * @param envMapIntensity - * @param alphaMap - * @param aoMap - * @param bumpMap - * @param diffuseMap - * @param displacementMap - * @param emissiveMap - * @param environmentMap - * @param lightMap - * @param metalnessMap - * @param normalMap - * @param roughnessMap - * @param specularMap - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Material = function( - id, - materialType, - name, - opacity, - side, - transparent, - specular, - lightMapIntensity, - aoMapIntensity, - color, - emissive, - emissiveIntensity, - combine, - shininess, - reflectivity, - refractionRatio, - fog, - wireframe, - wireframeLineWidth, - wireframeLineCap, - wireframeLineJoin, - vertexColors, - skinning, - morphTargets, - morphNormals, - lineWidth, - lineCap, - lineJoin, - dashSize, - gapWidth, - blending, - blendSrc, - blendDst, - blendEquation, - depthTest, - depthFunc, - depthWrite, - polygonOffset, - polygonOffsetFactor, - polygonOffsetUnits, - alphaTest, - clippingPlanes, - clipShadows, - visible, - overdraw, - flatShading, - bumpScale, - normalScale, - displacementScale, - displacementBias, - roughness, - metalness, - pointSize, - pointSizeAttenuation, - spriteRotation, - envMapIntensity, - alphaMap, - aoMap, - bumpMap, - diffuseMap, - displacementMap, - emissiveMap, - environmentMap, - lightMap, - metalnessMap, - normalMap, - roughnessMap, - specularMap, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(materialType)) { - materialType = GameLib.D3.Material.MATERIAL_TYPE_STANDARD; - } - this.materialType = materialType; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Material (' + materialType + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(opacity)) { - opacity = 1.0; - } - this.opacity = opacity; - - if (GameLib.Utils.UndefinedOrNull(side)) { - side = GameLib.D3.Material.TYPE_FRONT_SIDE; - } - this.side = side; - - if (GameLib.Utils.UndefinedOrNull(transparent)) { - transparent = false; - } - this.transparent = transparent; - - if (GameLib.Utils.UndefinedOrNull(specular)) { - specular = new GameLib.API.Color(0.06, 0.06, 0.06, 0.06); - } - this.specular = specular; - - if (GameLib.Utils.UndefinedOrNull(lightMapIntensity)) { - lightMapIntensity = 1; - } - this.lightMapIntensity = lightMapIntensity; - - if (GameLib.Utils.UndefinedOrNull(aoMapIntensity)) { - aoMapIntensity = 1; - } - this.aoMapIntensity = aoMapIntensity; - - if (GameLib.Utils.UndefinedOrNull(color)) { - color = new GameLib.API.Color(1, 1, 1, 1) - } - this.color = color; - - if (GameLib.Utils.UndefinedOrNull(emissive)) { - emissive = new GameLib.API.Color(0, 0, 0, 0); - } - this.emissive = emissive; - - if (GameLib.Utils.UndefinedOrNull(emissiveIntensity)) { - emissiveIntensity = 1; - } - this.emissiveIntensity = emissiveIntensity; - - if (GameLib.Utils.UndefinedOrNull(combine)) { - combine = GameLib.D3.Material.TYPE_MULTIPLY_OPERATION; - } - this.combine = combine; - - if (GameLib.Utils.UndefinedOrNull(shininess)) { - shininess = 30; - } - this.shininess = shininess; - - if (GameLib.Utils.UndefinedOrNull(reflectivity)) { - reflectivity = 1; - } - this.reflectivity = reflectivity; - - if (GameLib.Utils.UndefinedOrNull(refractionRatio)) { - refractionRatio = 0.98; - } - this.refractionRatio = refractionRatio; - - if (GameLib.Utils.UndefinedOrNull(fog)) { - fog = true; - } - this.fog = fog; - - if (GameLib.Utils.UndefinedOrNull(wireframe)) { - wireframe = false; - } - this.wireframe = wireframe; - - if (GameLib.Utils.UndefinedOrNull(wireframeLineWidth)) { - wireframeLineWidth = 1; - } - this.wireframeLineWidth = wireframeLineWidth; - - if (GameLib.Utils.UndefinedOrNull(wireframeLineCap)) { - wireframeLineCap = 'round'; - } - this.wireframeLineCap = wireframeLineCap; - - if (GameLib.Utils.UndefinedOrNull(wireframeLineJoin)) { - wireframeLineJoin = 'round'; - } - this.wireframeLineJoin = wireframeLineJoin; - - if (GameLib.Utils.UndefinedOrNull(vertexColors)) { - vertexColors = GameLib.D3.Material.TYPE_NO_COLORS; - } - this.vertexColors = vertexColors; - - if (GameLib.Utils.UndefinedOrNull(skinning)) { - skinning = false; - } - this.skinning = skinning; - - if (GameLib.Utils.UndefinedOrNull(morphTargets)) { - morphTargets = false; - } - this.morphTargets = morphTargets; - - if (GameLib.Utils.UndefinedOrNull(morphNormals)) { - morphNormals = false; - } - this.morphNormals = morphNormals; - - if (GameLib.Utils.UndefinedOrNull(overdraw)) { - overdraw = 0; - } - this.overdraw = overdraw; - - if (GameLib.Utils.UndefinedOrNull(lineWidth)) { - lineWidth = 1; - } - this.lineWidth = lineWidth; - - if (GameLib.Utils.UndefinedOrNull(lineCap)) { - lineCap = 'round'; - } - this.lineCap = lineCap; - - if (GameLib.Utils.UndefinedOrNull(lineJoin)) { - lineJoin = 'round'; - } - this.lineJoin = lineJoin; - - if (GameLib.Utils.UndefinedOrNull(dashSize)) { - dashSize = 3; - } - this.dashSize = dashSize; - - if (GameLib.Utils.UndefinedOrNull(gapWidth)) { - gapWidth = 1; - } - this.gapWidth = gapWidth; - - if (GameLib.Utils.UndefinedOrNull(blending)) { - blending = GameLib.D3.Material.TYPE_NORMAL_BLENDING; - } - this.blending = blending; - - if (GameLib.Utils.UndefinedOrNull(blendSrc)) { - blendSrc = GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR; - } - this.blendSrc = blendSrc; - - if (GameLib.Utils.UndefinedOrNull(blendDst)) { - blendDst = GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR; - } - this.blendDst = blendDst; - - if (GameLib.Utils.UndefinedOrNull(blendEquation)) { - blendEquation = GameLib.D3.Material.TYPE_ADD_EQUATION; - } - this.blendEquation = blendEquation; - - if (GameLib.Utils.UndefinedOrNull(depthTest)) { - depthTest = true; - } - this.depthTest = depthTest; - - if (GameLib.Utils.UndefinedOrNull(depthFunc)) { - depthFunc = GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH; - } - this.depthFunc = depthFunc; - - if (GameLib.Utils.UndefinedOrNull(depthWrite)) { - depthWrite = true; - } - this.depthWrite = depthWrite; - - if (GameLib.Utils.UndefinedOrNull(polygonOffset)) { - polygonOffset = false; - } - this.polygonOffset = polygonOffset; - - if (GameLib.Utils.UndefinedOrNull(polygonOffsetFactor)) { - polygonOffsetFactor = 1; - } - this.polygonOffsetFactor = polygonOffsetFactor; - - if (GameLib.Utils.UndefinedOrNull(polygonOffsetUnits)) { - polygonOffsetUnits = 1; - } - this.polygonOffsetUnits = polygonOffsetUnits; - - if (GameLib.Utils.UndefinedOrNull(alphaTest)) { - alphaTest = 0; - } - this.alphaTest = alphaTest; - - if (GameLib.Utils.UndefinedOrNull(clippingPlanes)) { - clippingPlanes = []; - } - this.clippingPlanes = clippingPlanes; - - if (GameLib.Utils.UndefinedOrNull(clipShadows)) { - clipShadows = false; - } - this.clipShadows = clipShadows; - - if (GameLib.Utils.UndefinedOrNull(visible)) { - visible = true; - } - this.visible = visible; - - if (GameLib.Utils.UndefinedOrNull(flatShading)) { - flatShading = false; - } - this.flatShading = flatShading; - - if (GameLib.Utils.UndefinedOrNull(bumpScale)) { - bumpScale = 1; - } - this.bumpScale = bumpScale; - - if (GameLib.Utils.UndefinedOrNull(normalScale)) { - normalScale = 1; - } - this.normalScale = normalScale; - - if (GameLib.Utils.UndefinedOrNull(displacementScale)) { - displacementScale = 1; - } - this.displacementScale = displacementScale; - - if (GameLib.Utils.UndefinedOrNull(displacementBias)) { - displacementBias = 0; - } - this.displacementBias = displacementBias; - - if (GameLib.Utils.UndefinedOrNull(roughness)) { - roughness = 0.5; - } - this.roughness = roughness; - - if (GameLib.Utils.UndefinedOrNull(metalness)) { - metalness = 0.5; - } - this.metalness = metalness; - - if (GameLib.Utils.UndefinedOrNull(pointSize)) { - pointSize = 1; - } - this.pointSize = pointSize; - - if (GameLib.Utils.UndefinedOrNull(pointSizeAttenuation)) { - pointSizeAttenuation = true; - } - this.pointSizeAttenuation = pointSizeAttenuation; - - if (GameLib.Utils.UndefinedOrNull(spriteRotation)) { - spriteRotation = 0; - } - this.spriteRotation = spriteRotation; - - if (GameLib.Utils.UndefinedOrNull(envMapIntensity)) { - envMapIntensity = 1.0; - } - this.envMapIntensity = envMapIntensity; - - if (GameLib.Utils.UndefinedOrNull(alphaMap)) { - alphaMap = null; - } - this.alphaMap = alphaMap; - - if (GameLib.Utils.UndefinedOrNull(aoMap)) { - aoMap = null; - } - this.aoMap = aoMap; - - if (GameLib.Utils.UndefinedOrNull(bumpMap)) { - bumpMap = null; - } - this.bumpMap = bumpMap; - - if (GameLib.Utils.UndefinedOrNull(diffuseMap)) { - diffuseMap = null; - } - this.diffuseMap = diffuseMap; - - if (GameLib.Utils.UndefinedOrNull(displacementMap)) { - displacementMap = null; - } - this.displacementMap = displacementMap; - - if (GameLib.Utils.UndefinedOrNull(emissiveMap)) { - emissiveMap = null; - } - this.emissiveMap = emissiveMap; - - if (GameLib.Utils.UndefinedOrNull(environmentMap)) { - environmentMap = null; - } - this.environmentMap = environmentMap; - - if (GameLib.Utils.UndefinedOrNull(lightMap)) { - lightMap = null; - } - this.lightMap = lightMap; - - if (GameLib.Utils.UndefinedOrNull(metalnessMap)) { - metalnessMap = null; - } - this.metalnessMap = metalnessMap; - - if (GameLib.Utils.UndefinedOrNull(normalMap)) { - normalMap = null; - } - this.normalMap = normalMap; - - if (GameLib.Utils.UndefinedOrNull(roughnessMap)) { - roughnessMap = null; - } - this.roughnessMap = roughnessMap; - - if (GameLib.Utils.UndefinedOrNull(specularMap)) { - specularMap = null; - } - this.specularMap = specularMap; - - GameLib.API.Component.call( - this, - GameLib.Component.MATERIAL, - parentEntity - ); - - this.needsUpdate = false; -}; - -GameLib.D3.API.Material.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Material.prototype.constructor = GameLib.D3.API.Material; - -/** - * Returns an API Material from an Object material - * @param objectMaterial - * @constructor - */ -GameLib.D3.API.Material.FromObject = function(objectMaterial) { - - var apiAlphaMap = null; - var apiAoMap = null; - var apiBumpMap = null; - var apiDiffuseMap = null; - var apiDisplacementMap = null; - var apiEmissiveMap = null; - var apiEnvironmentMap = null; - var apiLightMap = null; - var apiMetalnessMap = null; - var apiNormalMap = null; - var apiRoughnessMap = null; - var apiSpecularMap = null; - - if (objectMaterial.alphaMap) { - apiAlphaMap = objectMaterial.alphaMap; - } - - if (objectMaterial.aoMap) { - apiAoMap = objectMaterial.aoMap; - } - - if (objectMaterial.bumpMap) { - apiBumpMap = objectMaterial.bumpMap; - } - - if (objectMaterial.diffuseMap) { - apiDiffuseMap = objectMaterial.diffuseMap; - } - - if (objectMaterial.displacementMap) { - apiDisplacementMap = objectMaterial.displacementMap; - } - - if (objectMaterial.emissiveMap) { - apiEmissiveMap = objectMaterial.emissiveMap; - } - - if (objectMaterial.environmentMap) { - apiEnvironmentMap = objectMaterial.environmentMap; - } - - if (objectMaterial.lightMap) { - apiLightMap = objectMaterial.lightMap; - } - - if (objectMaterial.metalnessMap) { - apiMetalnessMap = objectMaterial.metalnessMap; - } - - if (objectMaterial.normalMap) { - apiNormalMap = objectMaterial.normalMap; - } - - if (objectMaterial.roughnessMap) { - apiRoughnessMap = objectMaterial.roughnessMap; - } - - if (objectMaterial.specularMap) { - apiSpecularMap = objectMaterial.specularMap; - } - - return new GameLib.D3.API.Material( - objectMaterial.id, - objectMaterial.materialType, - objectMaterial.name, - objectMaterial.opacity, - objectMaterial.side, - objectMaterial.transparent, - GameLib.API.Color.FromObject(objectMaterial.specular), - objectMaterial.lightMapIntensity, - objectMaterial.aoMapIntensity, - GameLib.API.Color.FromObject(objectMaterial.color), - GameLib.API.Color.FromObject(objectMaterial.emissive), - objectMaterial.emissiveIntensity, - objectMaterial.combine, - objectMaterial.shininess, - objectMaterial.reflectivity, - objectMaterial.refractionRatio, - objectMaterial.fog, - objectMaterial.wireframe, - objectMaterial.wireframeLineWidth, - objectMaterial.wireframeLineCap, - objectMaterial.wireframeLineJoin, - objectMaterial.vertexColors, - objectMaterial.skinning, - objectMaterial.morphTargets, - objectMaterial.morphNormals, - objectMaterial.lineWidth, - objectMaterial.lineCap, - objectMaterial.lineJoin, - objectMaterial.dashSize, - objectMaterial.gapWidth, - objectMaterial.blending, - objectMaterial.blendSrc, - objectMaterial.blendDst, - objectMaterial.blendEquation, - objectMaterial.depthTest, - objectMaterial.depthFunc, - objectMaterial.depthWrite, - objectMaterial.polygonOffset, - objectMaterial.polygonOffsetFactor, - objectMaterial.polygonOffsetUnits, - objectMaterial.alphaTest, - objectMaterial.clippingPlanes, - objectMaterial.clipShadows, - objectMaterial.visible, - objectMaterial.overdraw, - objectMaterial.flatShading, - objectMaterial.bumpScale, - objectMaterial.normalScale, - objectMaterial.displacementScale, - objectMaterial.displacementBias, - objectMaterial.roughness, - objectMaterial.metalness, - objectMaterial.pointSize, - objectMaterial.pointSizeAttenuation, - objectMaterial.spriteRotation, - objectMaterial.envMapIntensity, - apiAlphaMap, - apiAoMap, - apiBumpMap, - apiDiffuseMap, - apiDisplacementMap, - apiEmissiveMap, - apiEnvironmentMap, - apiLightMap, - apiMetalnessMap, - apiNormalMap, - apiRoughnessMap, - apiSpecularMap, - objectMaterial.parentEntity - ) -}; - -/** - * Raw Mesh API object - should always correspond with the Mesh Schema - * @param id - * @param meshType - - * @param name - * @param vertices - * @param faces - * @param materials - * @param parentMesh - * @param parentScene - * @param skeleton - * @param skinIndices - * @param skinWeights - * @param position - * @param quaternion - * @param rotation - * @param scale - * @param up - * @param modelMatrix - * @param renderOrder - * @param isBufferMesh - * @param useQuaternion - * @param visible - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Mesh = function( - id, - meshType, - name, - vertices, - faces, - materials, - parentMesh, - parentScene, - skeleton, - skinIndices, - skinWeights, - position, - quaternion, - rotation, - scale, - up, - modelMatrix, - renderOrder, - isBufferMesh, - useQuaternion, - visible, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(meshType)) { - meshType = GameLib.D3.API.Mesh.MESH_TYPE_NORMAL; - } - this.meshType = meshType; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Mesh (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(vertices)) { - vertices = []; - } - this.vertices = vertices; - - if (GameLib.Utils.UndefinedOrNull(faces)) { - faces = []; - } - this.faces = faces; - - if (GameLib.Utils.UndefinedOrNull(parentMesh)) { - parentMesh = null; - } - this.parentMesh = parentMesh; - - if (GameLib.Utils.UndefinedOrNull(parentScene)) { - parentScene = null; - } - this.parentScene = parentScene; - - if (GameLib.Utils.UndefinedOrNull(skeleton)) { - skeleton = null; - } - this.skeleton = skeleton; - - if (GameLib.Utils.UndefinedOrNull(skinIndices)) { - skinIndices = []; - } - this.skinIndices = skinIndices; - - if (GameLib.Utils.UndefinedOrNull(skinWeights)) { - skinWeights = []; - } - this.skinWeights = skinWeights; - - if (GameLib.Utils.UndefinedOrNull(materials) || (materials instanceof Array && materials.length === 0)) { - materials = [new GameLib.D3.API.Material(null, GameLib.D3.Material.MATERIAL_TYPE_STANDARD, 'Material (' + this.name + ')')]; - } - this.materials = materials; - - if (GameLib.Utils.UndefinedOrNull(position)) { - position = new GameLib.API.Vector3(0,0,0); - } - this.position = position; - - if (GameLib.Utils.UndefinedOrNull(quaternion)) { - quaternion = new GameLib.API.Quaternion(); - } - this.quaternion = quaternion; - - if (GameLib.Utils.UndefinedOrNull(rotation)) { - rotation = new GameLib.API.Vector3(0,0,0); - } - this.rotation = rotation; - - if (GameLib.Utils.UndefinedOrNull(scale)) { - scale = new GameLib.API.Vector3(1,1,1); - } - this.scale = scale; - - if (GameLib.Utils.UndefinedOrNull(up)) { - up = new GameLib.API.Vector3(0,1,0); - } - this.up = up; - - if (GameLib.Utils.UndefinedOrNull(modelMatrix)) { - modelMatrix = new GameLib.API.Matrix4(); - } - this.modelMatrix = modelMatrix; - - if (GameLib.Utils.UndefinedOrNull(renderOrder)) { - renderOrder = 0; - } - this.renderOrder = renderOrder; - - if (GameLib.Utils.UndefinedOrNull(isBufferMesh)) { - isBufferMesh = false; - } - this.isBufferMesh = isBufferMesh; - - if (GameLib.Utils.UndefinedOrNull(useQuaternion)) { - useQuaternion = true; - } - this.useQuaternion = useQuaternion; - - if (GameLib.Utils.UndefinedOrNull(visible)) { - visible = true; - } - this.visible = visible; - - var componentType = GameLib.Component.MESH; - - if (this.meshType === GameLib.D3.API.Mesh.MESH_TYPE_PLANE) { - componentType = GameLib.Component.MESH_PLANE - } - - if (this.meshType === GameLib.D3.API.Mesh.MESH_TYPE_BOX) { - componentType = GameLib.Component.MESH_BOX - } - - if (this.meshType === GameLib.D3.API.Mesh.MESH_TYPE_CYLINDER) { - componentType = GameLib.Component.MESH_CYLINDER - } - - if (this.meshType === GameLib.D3.API.Mesh.MESH_TYPE_SPHERE) { - componentType = GameLib.Component.MESH_SPHERE - } - - if (this.meshType === GameLib.D3.API.Mesh.MESH_TYPE_LINE) { - componentType = GameLib.Component.MESH_LINE - } - - if (this.meshType === GameLib.D3.API.Mesh.MESH_TYPE_TEXT) { - componentType = GameLib.Component.MESH_TEXT; - } - - GameLib.API.Component.call( - this, - componentType, - parentEntity - ); -}; - -GameLib.D3.API.Mesh.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Mesh.prototype.constructor = GameLib.D3.API.Mesh; - - -/** - * Mesh Type - * @type {number} - */ -GameLib.D3.API.Mesh.MESH_TYPE_NORMAL = 0x0; -GameLib.D3.API.Mesh.MESH_TYPE_SKINNED = 0x1; -GameLib.D3.API.Mesh.MESH_TYPE_CURVE = 0x2; -GameLib.D3.API.Mesh.MESH_TYPE_SPHERE = 0x3; -GameLib.D3.API.Mesh.MESH_TYPE_PLANE = 0x4; -GameLib.D3.API.Mesh.MESH_TYPE_BOX = 0x5; -GameLib.D3.API.Mesh.MESH_TYPE_CYLINDER = 0x6; -GameLib.D3.API.Mesh.MESH_TYPE_TEXT = 0x7; -GameLib.D3.API.Mesh.MESH_TYPE_LINE = 0x8; - -/** - * Returns an API Mesh from an Object mesh - * @param objectMesh - * @constructor - */ -GameLib.D3.API.Mesh.FromObject = function (objectMesh){ - - var apiFaces = []; - if (objectMesh.faces) { - apiFaces = objectMesh.faces.map( - function(face) { - return GameLib.D3.API.Face.FromObject(face); - } - ); - } - - var apiSkeleton = null; - if (objectMesh.skeleton) { - apiSkeleton = GameLib.D3.API.Skeleton.FromObject(objectMesh.skeleton); - } - - var apiMaterials = []; - if (objectMesh.materials) { - apiMaterials = objectMesh.materials.map( - function (objectMaterial) { - /** - * From blender we only get Ids to materials (strings) - */ - if (objectMaterial instanceof Object) { - return GameLib.D3.API.Material.FromObject(objectMaterial); - } else { - return objectMaterial - } - } - ) - } - - var apiVertices = []; - if (objectMesh.vertices) { - apiVertices = objectMesh.vertices.map( - function (objectVertex) { - return GameLib.D3.API.Vertex.FromObject(objectVertex); - } - ) - } - - var apiPosition = new GameLib.API.Vector3(); - if (objectMesh.position) { - apiPosition = GameLib.API.Vector3.FromObject(objectMesh.position); - } - - var apiRotation = new GameLib.API.Vector3(); - if (objectMesh.rotation) { - apiRotation = GameLib.API.Vector3.FromObject(objectMesh.rotation); - } - - var apiQuaternion = new GameLib.API.Quaternion(); - if (objectMesh.quaternion) { - apiQuaternion = GameLib.API.Quaternion.FromObject(objectMesh.quaternion); - } - - var apiScale = new GameLib.API.Vector3(1,1,1); - if (objectMesh.scale) { - apiScale = GameLib.API.Vector3.FromObject(objectMesh.scale); - } - - var apiUp = new GameLib.API.Vector3(0,1,0); - if (objectMesh.up) { - apiUp = GameLib.API.Vector3.FromObject(objectMesh.up); - } - - var apiModelMatrix = new GameLib.API.Matrix4(); - if (objectMesh.modelMatrix) { - apiModelMatrix = GameLib.API.Matrix4.FromObject(objectMesh.modelMatrix); - } - - var meshType = GameLib.D3.API.Mesh.MESH_TYPE_NORMAL; - - if (objectMesh.meshType === GameLib.D3.API.Mesh.MESH_TYPE_NORMAL || - objectMesh.meshType === GameLib.D3.API.Mesh.MESH_TYPE_SKINNED - ) { - meshType = objectMesh.meshType; - } - - if (objectMesh.componentType === GameLib.Component.MESH_PLANE) { - meshType = GameLib.D3.API.Mesh.MESH_TYPE_PLANE; - } - - if (objectMesh.componentType === GameLib.Component.MESH_SPHERE) { - meshType = GameLib.D3.API.Mesh.MESH_TYPE_SPHERE; - } - - if (objectMesh.componentType === GameLib.Component.MESH_CURVE) { - meshType = GameLib.D3.API.Mesh.MESH_TYPE_CURVE; - } - - if (objectMesh.componentType === GameLib.Component.MESH_BOX) { - meshType = GameLib.D3.API.Mesh.MESH_TYPE_BOX; - } - - if (objectMesh.componentType === GameLib.Component.MESH_CYLINDER) { - meshType = GameLib.D3.API.Mesh.MESH_TYPE_CYLINDER; - } - - if (objectMesh.componentType === GameLib.Component.MESH_TEXT) { - meshType = GameLib.D3.API.Mesh.MESH_TYPE_TEXT; - } - - if (objectMesh.componentType === GameLib.Component.MESH_TYPE_LINE) { - meshType = GameLib.D3.API.Mesh.MESH_LINE; - } - - return new GameLib.D3.API.Mesh( - objectMesh.id, - meshType, - objectMesh.name, - apiVertices, - apiFaces, - apiMaterials, - objectMesh.parentMesh, - objectMesh.parentScene, - apiSkeleton, - objectMesh.skinIndices, - objectMesh.skinWeights, - apiPosition, - apiQuaternion, - apiRotation, - apiScale, - apiUp, - apiModelMatrix, - objectMesh.renderOrder, - objectMesh.isBufferMesh, - objectMesh.useQuaternion, - objectMesh.visible, - objectMesh.parentEntity - ); -}; - -/** - * Raw ParticleEngine API object - should always correspond with the ParticleEngine Schema - * @param id - * @param name - * @param position - * @param direction - * @param enabled - * @param templateParticle - * @param particlesPerSecond - * @param frequency - * @param elapsed - * @param camera - * @param pulse - * @param parentEntity - * @constructor - */ -GameLib.D3.API.ParticleEngine = function( - id, - name, - position, - direction, - enabled, - templateParticle, - particlesPerSecond, - frequency, - elapsed, - camera, - pulse, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'ParticleEngine (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(position)) { - position = new GameLib.API.Vector3(0, 0, 0); - } - this.position = position; - - if (GameLib.Utils.UndefinedOrNull(direction)) { - direction = new GameLib.API.Vector3(0, 1, 0); - } - this.direction = direction; - - if (GameLib.Utils.UndefinedOrNull(enabled)) { - enabled = false; - } - this.enabled = enabled; - - if (GameLib.Utils.UndefinedOrNull(templateParticle)) { - templateParticle = null; - } - this.templateParticle = templateParticle; - - if (GameLib.Utils.UndefinedOrNull(particlesPerSecond)) { - particlesPerSecond = 1; - } - this.particlesPerSecond = particlesPerSecond; - - if (GameLib.Utils.UndefinedOrNull(frequency)) { - frequency = Number(1 / Number(this.particlesPerSecond)); - } - this.frequency = frequency; - - if (GameLib.Utils.UndefinedOrNull(elapsed)) { - elapsed = 0; - } - this.elapsed = elapsed; - - if (GameLib.Utils.UndefinedOrNull(camera)) { - camera = null; - } - this.camera = camera; - - if (GameLib.Utils.UndefinedOrNull(pulse)) { - pulse = false; - } - this.pulse = pulse; - - GameLib.API.Component.call( - this, - GameLib.Component.PARTICLE_ENGINE, - parentEntity - ); -}; - -GameLib.D3.API.ParticleEngine.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.ParticleEngine.prototype.constructor = GameLib.D3.API.ParticleEngine; - - -/** - * Creates an API ParticleEngine from an Object ParticleEngine - * @param objectParticleEngine - * @constructor - */ -GameLib.D3.API.ParticleEngine.FromObject = function(objectParticleEngine) { - - var apiTemplateParticle = null; - if (objectParticleEngine.templateParticle) { - if (objectParticleEngine.templateParticle instanceof Object) { - apiTemplateParticle = GameLib.D3.API.Particle.FromObject(objectParticleEngine.templateParticle); - } else { - apiTemplateParticle = objectParticleEngine.templateParticle; - } - } - - var apiCamera = null; - if (objectParticleEngine.camera) { - if (objectParticleEngine.camera instanceof Object) { - apiCamera = GameLib.D3.API.Camera.FromObject(objectParticleEngine.camera); - } else { - apiCamera = objectParticleEngine.camera; - } - } - - var apiPosition = null; - if (objectParticleEngine.position) { - apiPosition = GameLib.API.Vector3.FromObject(objectParticleEngine.position); - } - - var apiDirection = null; - if (objectParticleEngine.direction) { - apiDirection = GameLib.API.Vector3.FromObject(objectParticleEngine.direction); - } - - return new GameLib.D3.API.ParticleEngine( - - objectParticleEngine.id, - objectParticleEngine.name, - apiPosition, - apiDirection, - objectParticleEngine.enabled, - apiTemplateParticle, - objectParticleEngine.particlesPerSecond, - objectParticleEngine.frequency, - objectParticleEngine.elapsed, - apiCamera, - objectParticleEngine.pulse, - objectParticleEngine.parentEntity - - ); - -}; - -/** - * Raw Particle API object - should always correspond with the Particle Schema - * @param id - * @param name - * @param lifeTime - * @param elapsed - * @param mesh - * @param opacityType - * @param opacityFactor - * @param positionOffsetType - * @param positionOffset - * @param positionOffsetFn - * @param directionType - * @param rotation - * @param scale - * @param direction - * @param directionFn - * @param speedType - * @param speed - * @param scaleFn - * @param scaleType - * @param rotationType - * @param rotationFn - * @param parentEngine - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Particle = function( - id, - name, - lifeTime, - elapsed, - mesh, - opacityType, - opacityFactor, - positionOffsetType, - positionOffset, - positionOffsetFn, - directionType, - direction, - directionFn, - speedType, - speed, - scaleType, - scale, - scaleFn, - rotationType, - rotation, - rotationFn, - parentEngine, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Particle (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(lifeTime)) { - lifeTime = 10; - } - this.lifeTime = lifeTime; - - if (GameLib.Utils.UndefinedOrNull(elapsed)) { - elapsed = 0; - } - this.elapsed = elapsed; - - if (GameLib.Utils.UndefinedOrNull(mesh)) { - mesh = null; - } - this.mesh = mesh; - - if (GameLib.Utils.UndefinedOrNull(opacityType)) { - opacityType = GameLib.D3.Particle.OPACITY_TYPE_CONSTANT; - } - this.opacityType = opacityType; - - if (GameLib.Utils.UndefinedOrNull(opacityFactor)) { - opacityFactor = 0.01; - } - this.opacityFactor = opacityFactor; - - if (GameLib.Utils.UndefinedOrNull(positionOffsetType)) { - positionOffsetType = GameLib.D3.Particle.POSITION_OFFSET_TYPE_CONSTANT; - } - this.positionOffsetType = positionOffsetType; - - if (GameLib.Utils.UndefinedOrNull(positionOffset)) { - positionOffset = new GameLib.API.Vector3(0, 0, 0); - } - this.positionOffset = positionOffset; - - if (GameLib.Utils.UndefinedOrNull(positionOffsetFn)) { - positionOffsetFn = '//@ sourceURL=positionOffsetFn.js'; - } - this.positionOffsetFn = positionOffsetFn; - - if (GameLib.Utils.UndefinedOrNull(directionType)) { - directionType = GameLib.D3.Particle.DIRECTION_TYPE_CONSTANT; - } - this.directionType = directionType; - - if (GameLib.Utils.UndefinedOrNull(direction)) { - direction = new GameLib.API.Vector3(0, 1, 0); - } - this.direction = direction; - - if (GameLib.Utils.UndefinedOrNull(directionFn)) { - directionFn = '//@ sourceURL=directionFn.js'; - } - this.directionFn = directionFn; - - if (GameLib.Utils.UndefinedOrNull(speedType)) { - speedType = GameLib.D3.Particle.SPEED_TYPE_CONSTANT; - } - this.speedType = speedType; - - if (GameLib.Utils.UndefinedOrNull(speed)) { - speed = 1; - } - this.speed = speed; - - if (GameLib.Utils.UndefinedOrNull(scaleType)) { - scaleType = GameLib.D3.Particle.SCALE_TYPE_CONSTANT; - } - this.scaleType = scaleType; - - if (GameLib.Utils.UndefinedOrNull(scale)) { - scale = new GameLib.API.Vector3(1, 1, 1); - } - this.scale = scale; - - if (GameLib.Utils.UndefinedOrNull(scaleFn)) { - scaleFn = '//@ sourceURL=scaleFn.js'; - } - this.scaleFn = scaleFn; - - if (GameLib.Utils.UndefinedOrNull(rotationType)) { - rotationType = GameLib.D3.Particle.ROTATION_TYPE_CONSTANT; - } - this.rotationType = rotationType; - - if (GameLib.Utils.UndefinedOrNull(rotation)) { - rotation = new GameLib.API.Vector3(0, 0, 0); - } - this.rotation = rotation; - - if (GameLib.Utils.UndefinedOrNull(rotationFn)) { - rotationFn = '//@ sourceURL=rotationFn.js'; - } - this.rotationFn = rotationFn; - - if (GameLib.Utils.UndefinedOrNull(parentEngine)) { - parentEngine = null; - } - this.parentEngine = parentEngine; - - GameLib.API.Component.call( - this, - GameLib.Component.PARTICLE, - parentEntity - ); -}; - -GameLib.D3.API.Particle.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Particle.prototype.constructor = GameLib.D3.API.Particle; - -/** - * Creates an API Particle from an Object Particle - * @param objectParticle - * @constructor - */ -GameLib.D3.API.Particle.FromObject = function(objectParticle) { - - var apiMesh = null; - if (objectParticle.mesh) { - if (objectParticle.mesh instanceof Object) { - apiMesh = GameLib.D3.API.Mesh.FromObject(objectParticle.mesh); - } else { - apiMesh = objectParticle.mesh; - } - } - - return new GameLib.D3.API.Particle( - objectParticle.id, - objectParticle.name, - objectParticle.lifeTime, - objectParticle.elapsed, - apiMesh, - objectParticle.opacityType, - objectParticle.opacityFactor, - objectParticle.positionOffsetType, - GameLib.API.Vector3.FromObject(objectParticle.positionOffset), - objectParticle.positionOffsetFn, - objectParticle.directionType, - GameLib.API.Vector3.FromObject(objectParticle.direction), - objectParticle.directionFn, - objectParticle.speedType, - objectParticle.speed, - objectParticle.scaleType, - GameLib.API.Vector3.FromObject(objectParticle.scale), - objectParticle.scaleFn, - objectParticle.rotationType, - GameLib.API.Vector3.FromObject(objectParticle.rotation), - objectParticle.rotationFn, - objectParticle.parentEngine, - objectParticle.parentEntity - ); - -}; - -/** - * This component renders a scene - * @param id String - * @param name String - * @param passType - * @param camera - * @param scene - * @param renderToScreen - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Pass = function ( - id, - name, - passType, - camera, - scene, - renderToScreen, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Pass (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(passType)) { - passType = GameLib.D3.Pass.PASS_TYPE_RENDER; - } - this.passType = passType; - - if (GameLib.Utils.UndefinedOrNull(camera)) { - camera = null; - } - this.camera = camera; - - if (GameLib.Utils.UndefinedOrNull(scene)) { - scene = null; - } - this.scene = scene; - - if (GameLib.Utils.UndefinedOrNull(renderToScreen)) { - - if (this.passType === GameLib.D3.Pass.PASS_TYPE_RENDER) { - renderToScreen = false; - } else if (GameLib.D3.Pass.PASS_TYPE_COPY_SHADER) { - renderToScreen = true; - } else { - console.warn('Unsupported Render Pass Type : ' + this.passType); - throw new Error('Unsupported Render Pass Type : ' + this.passType); - } - - } - this.renderToScreen = renderToScreen; - - GameLib.API.Component.call( - this, - GameLib.Component.PASS, - parentEntity - ); -}; - -GameLib.D3.API.Pass.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Pass.prototype.constructor = GameLib.D3.API.Pass; - -/** - * Object to GameLib.D3.API.Pass - * @param objectComponent - * @constructor - */ -GameLib.D3.API.Pass.FromObject = function(objectComponent) { - return new GameLib.D3.API.Pass( - objectComponent.id, - objectComponent.name, - objectComponent.passType, - objectComponent.camera, - objectComponent.scene, - objectComponent.renderToScreen, - objectComponent.parentEntity - ); -}; - -/** - * Raw World API object - should always correspond with the World Schema - * @param id - * @param name - * @param gravity - * @param broadphase - * @param solver - * @param rigidBodies - * @param contactMaterials - * @param allowSleep - * @param defaultContactMaterial - * @param parentEntity - * @constructor - */ -GameLib.D3.API.PhysicsWorld = function( - id, - name, - gravity, - broadphase, - solver, - rigidBodies, - contactMaterials, - allowSleep, - defaultContactMaterial, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Physics World (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(gravity)) { - gravity = new GameLib.API.Vector3(0, -9.81, 0); - } - this.gravity = gravity; - - if (GameLib.Utils.UndefinedOrNull(broadphase)) { - broadphase = new GameLib.D3.API.Broadphase( - null, - 'Broadphase (Physics World ' + this.id + ')' - ); - } - this.broadphase = broadphase; - - if (GameLib.Utils.UndefinedOrNull(solver)) { - solver = new GameLib.D3.API.Solver( - null, - 'Solver (Physics World ' + this.id + ')' - ) - } - this.solver = solver; - - if (GameLib.Utils.UndefinedOrNull(rigidBodies)) { - rigidBodies = []; - } - this.rigidBodies = rigidBodies; - - if (GameLib.Utils.UndefinedOrNull(contactMaterials)) { - contactMaterials = []; - } - this.contactMaterials = contactMaterials; - - if (GameLib.Utils.UndefinedOrNull(allowSleep)) { - allowSleep = true; - } - this.allowSleep = allowSleep; - - if (GameLib.Utils.UndefinedOrNull(defaultContactMaterial)) { - defaultContactMaterial = new GameLib.D3.API.FrictionContactMaterial( - null, - 'Default Contact Material (Physics World ' + this.id + ')' - ); - } - this.defaultContactMaterial = defaultContactMaterial; - - GameLib.API.Component.call( - this, - GameLib.Component.PHYSICS_WORLD, - parentEntity - ); -}; - -GameLib.D3.API.PhysicsWorld.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.PhysicsWorld.prototype.constructor = GameLib.D3.API.PhysicsWorld; - -/** - * Creates an API World from an Object World - * @param objectWorld - * @constructor - */ -GameLib.D3.API.PhysicsWorld.FromObject = function(objectWorld) { - return new GameLib.D3.API.PhysicsWorld( - objectWorld.id, - objectWorld.name, - GameLib.API.Vector3.FromObject(objectWorld.gravity), - objectWorld.broadphase, - objectWorld.solver, - objectWorld.rigidBodies, - objectWorld.contactMaterials, - objectWorld.allowSleep, - objectWorld.defaultContactMaterial, - objectWorld.parentEntity - ); -}; - - -/** - * Raw RaycastVehicle API object - should always correspond with the RaycastVehicle Schema - * @param id - * @param name - * @param chassis - * @param wheels - * @param raycastWheels - * @param parentPhysicsWorld - * @param parentEntity - * @constructor - */ -GameLib.D3.API.RaycastVehicle = function( - id, - name, - chassis, - wheels, - raycastWheels, - parentPhysicsWorld, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'RaycastVehicle (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(chassis)) { - chassis = null; - } - this.chassis = chassis; - - if (GameLib.Utils.UndefinedOrNull(wheels)) { - wheels = []; - } - this.wheels = wheels; - - if (GameLib.Utils.UndefinedOrNull(raycastWheels)) { - raycastWheels = []; - } - this.raycastWheels = raycastWheels; - - if (GameLib.Utils.UndefinedOrNull(parentPhysicsWorld)) { - parentPhysicsWorld = null; - } - this.parentPhysicsWorld = parentPhysicsWorld; - - GameLib.API.Component.call( - this, - GameLib.Component.RAYCAST_VEHICLE, - parentEntity - ); -}; - -GameLib.D3.API.RaycastVehicle.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.RaycastVehicle.prototype.constructor = GameLib.D3.API.RaycastVehicle; - -/** - * Creates an API RaycastVehicle from an Object RaycastVehicle - * @param objectRaycastVehicle - * @constructor - */ -GameLib.D3.API.RaycastVehicle.FromObject = function(objectRaycastVehicle) { - return new GameLib.D3.API.RaycastVehicle( - objectRaycastVehicle.id, - objectRaycastVehicle.name, - objectRaycastVehicle.chassis, - objectRaycastVehicle.wheels, - objectRaycastVehicle.raycastWheels, - objectRaycastVehicle.parentPhysicsWorld, - objectRaycastVehicle.parentEntity - ); -}; - - -/** - * Raw RaycastWheel API object - should always correspond with the RaycastWheel Schema - * @param id - * @param name - * @param radius - * @param directionLocal - * @param suspensionStiffness - * @param suspensionRestLength - * @param frictionSlip - * @param dampingRelaxation - * @param dampingCompression - * @param maxSuspensionForce - * @param rollInfluence - * @param axleLocal - * @param chassisConnectionPointLocal - * @param maxSuspensionTravel - * @param customSlidingRotationalSpeed - * @param useCustomSlidingRotationalSpeed - * @param parentEntity - * @param parentMesh - * @constructor - */ -GameLib.D3.API.RaycastWheel = function( - id, - name, - radius, - directionLocal, - suspensionStiffness, - suspensionRestLength, - frictionSlip, - dampingRelaxation, - dampingCompression, - maxSuspensionForce, - rollInfluence, - axleLocal, - chassisConnectionPointLocal, - maxSuspensionTravel, - customSlidingRotationalSpeed, - useCustomSlidingRotationalSpeed, - parentMesh, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'RaycastWheel (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(radius)) { - radius = 0.5; - } - this.radius = radius; - - if (GameLib.Utils.UndefinedOrNull(directionLocal)) { - directionLocal = new GameLib.API.Vector3(0, 0, -1); - } - this.directionLocal = directionLocal; - - if (GameLib.Utils.UndefinedOrNull(suspensionStiffness)) { - suspensionStiffness = 30; - } - this.suspensionStiffness = suspensionStiffness; - - if (GameLib.Utils.UndefinedOrNull(suspensionRestLength)) { - suspensionRestLength = 0.3; - } - this.suspensionRestLength = suspensionRestLength; - - if (GameLib.Utils.UndefinedOrNull(frictionSlip)) { - frictionSlip = 5; - } - this.frictionSlip = frictionSlip; - - if (GameLib.Utils.UndefinedOrNull(dampingRelaxation)) { - dampingRelaxation = 2.3; - } - this.dampingRelaxation = dampingRelaxation; - - if (GameLib.Utils.UndefinedOrNull(dampingCompression)) { - dampingCompression = 4.4; - } - this.dampingCompression = dampingCompression; - - if (GameLib.Utils.UndefinedOrNull(maxSuspensionForce)) { - maxSuspensionForce = 100000; - } - this.maxSuspensionForce = maxSuspensionForce; - - if (GameLib.Utils.UndefinedOrNull(rollInfluence)) { - rollInfluence = 0.01; - } - this.rollInfluence = rollInfluence; - - if (GameLib.Utils.UndefinedOrNull(axleLocal)) { - axleLocal = new GameLib.API.Vector3(0, 1, 0); - } - this.axleLocal = axleLocal; - - if (GameLib.Utils.UndefinedOrNull(chassisConnectionPointLocal)) { - chassisConnectionPointLocal = new GameLib.API.Vector3(1, 1, 0); - } - this.chassisConnectionPointLocal = chassisConnectionPointLocal; - - if (GameLib.Utils.UndefinedOrNull(maxSuspensionTravel)) { - maxSuspensionTravel = 0.3; - } - this.maxSuspensionTravel = maxSuspensionTravel; - - if (GameLib.Utils.UndefinedOrNull(customSlidingRotationalSpeed)) { - customSlidingRotationalSpeed = -30; - } - this.customSlidingRotationalSpeed = customSlidingRotationalSpeed; - - if (GameLib.Utils.UndefinedOrNull(useCustomSlidingRotationalSpeed)) { - useCustomSlidingRotationalSpeed = true; - } - this.useCustomSlidingRotationalSpeed = useCustomSlidingRotationalSpeed; - - if (GameLib.Utils.UndefinedOrNull(parentMesh)) { - parentMesh = null; - } - this.parentMesh = parentMesh; - - GameLib.API.Component.call( - this, - GameLib.Component.RAYCAST_WHEEL, - parentEntity - ); -}; - -GameLib.D3.API.RaycastWheel.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.RaycastWheel.prototype.constructor = GameLib.D3.API.RaycastWheel; - -/** - * Creates an API RaycastWheel from an Object RaycastWheel - * @param objectRaycastWheel - * @constructor - */ -GameLib.D3.API.RaycastWheel.FromObject = function(objectRaycastWheel) { - return new GameLib.D3.API.RaycastWheel( - objectRaycastWheel.id, - objectRaycastWheel.name, - objectRaycastWheel.radius, - objectRaycastWheel.directionLocal, - objectRaycastWheel.suspensionStiffness, - objectRaycastWheel.suspensionRestLength, - objectRaycastWheel.frictionSlip, - objectRaycastWheel.dampingRelaxation, - objectRaycastWheel.dampingCompression, - objectRaycastWheel.maxSuspensionForce, - objectRaycastWheel.rollInfluence, - objectRaycastWheel.axleLocal, - objectRaycastWheel.chassisConnectionPointLocal, - objectRaycastWheel.maxSuspensionTravel, - objectRaycastWheel.customSlidingRotationalSpeed, - objectRaycastWheel.useCustomSlidingRotationalSpeed, - objectRaycastWheel.parentMesh, - objectRaycastWheel.parentEntity - ); -}; - - -/** - * Raycaster for GameLib.D3 - * @param id - * @param name - * @param position GameLib.API.Vector3 - * @param direction GameLib.API.Vector3 - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Raycaster = function( - id, - name, - position, - direction, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Raycaster (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(position)) { - position = new GameLib.API.Vector3(); - } - this.position = position; - - if (GameLib.Utils.UndefinedOrNull(direction)) { - direction = new GameLib.API.Vector3(0, -1, 0); - } - this.direction = direction; - - GameLib.API.Component.call( - this, - GameLib.Component.RAYCASTER, - parentEntity - ); -}; - -GameLib.D3.API.Raycaster.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Raycaster.prototype.constructor = GameLib.D3.API.Raycaster; - -/** - * Returns an API raycaster from an Object raycaster - * @param objectRaycaster - * @constructor - */ -GameLib.D3.API.Raycaster.FromObject = function(objectRaycaster) { - return new GameLib.D3.API.Raycaster( - objectRaycaster.id, - objectRaycaster.name, - GameLib.API.Vector3.FromObject(objectRaycaster.position), - GameLib.API.Vector3.FromObject(objectRaycaster.direction), - objectRaycaster.parentEntity - ); -}; - -/** - * RenderTarget is used to render a scene to a target - * @param id - * @param name - * @param width - * @param height - * @param stencilBuffer - * @param texture - * @param parentEntity - * @constructor - */ -GameLib.D3.API.RenderTarget = function ( - id, - name, - width, - height, - stencilBuffer, - texture, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Render Target (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(width)) { - width = 800; - } - this.width = width; - - if (GameLib.Utils.UndefinedOrNull(height)) { - height = 600; - } - this.height = height; - - if (GameLib.Utils.UndefinedOrNull(stencilBuffer)) { - stencilBuffer = false; - } - this.stencilBuffer = stencilBuffer; - - if (GameLib.Utils.UndefinedOrNull(texture)) { - texture = null; - } - this.texture = texture; - - GameLib.API.Component.call( - this, - GameLib.Component.RENDER_TARGET, - parentEntity - ); - -}; - -GameLib.D3.API.RenderTarget.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.RenderTarget.prototype.constructor = GameLib.D3.API.RenderTarget; - -/** - * Object to GameLib.D3.API.RenderTarget - * @param objectComponent - * @constructor - */ -GameLib.D3.API.RenderTarget.FromObject = function(objectComponent) { - return new GameLib.D3.API.RenderTarget( - objectComponent.id, - objectComponent.name, - objectComponent.width, - objectComponent.height, - objectComponent.stencilBuffer, - objectComponent.texture, - objectComponent.parentEntity - ); -}; - -/** - * This component renders a scene - * @param id String - * @param name String - * @param autoClear bool - * @param localClipping - * @param width - * @param height - * @param domElement - * @param clearColor - * @param camera - * @param scenes - * @param viewports - * @param parentEntity - * @param preserveDrawingBuffer - * @param clippingPlanes - * @param bufferScene - * @param bufferCamera - * @param renderTarget - * @param sortObjects - * @param defaultScene - * @constructor - */ -GameLib.D3.API.Renderer = function ( - id, - name, - autoClear, - localClipping, - width, - height, - preserveDrawingBuffer, - domElement, - clearColor, - camera, - scenes, - viewports, - clippingPlanes, - bufferScene, - bufferCamera, - renderTarget, - defaultScene, - sortObjects, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = "Renderer (" + this.id + ")"; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(autoClear)) { - autoClear = true; - } - this.autoClear = autoClear; - - if (GameLib.Utils.UndefinedOrNull(localClipping)) { - localClipping = false; - - if (clippingPlanes && clippingPlanes.length > 0) { - localClipping = true; - } - } - this.localClipping = localClipping; - - if (GameLib.Utils.UndefinedOrNull(width)) { - width = 800; - } - this.width = width; - - if (GameLib.Utils.UndefinedOrNull(height)) { - height = 600; - } - this.height = height; - - if (GameLib.Utils.UndefinedOrNull(preserveDrawingBuffer)) { - preserveDrawingBuffer = false; - } - this.preserveDrawingBuffer = preserveDrawingBuffer; - - if (GameLib.Utils.UndefinedOrNull(domElement)) { - domElement = null; - } - this.domElement = domElement; - - if (GameLib.Utils.UndefinedOrNull(clearColor)) { - clearColor = new GameLib.API.Color(0.11, 0.11, 0.11); - } - this.clearColor = clearColor; - - if (GameLib.Utils.UndefinedOrNull(camera)) { - camera = null; - } - this.camera = camera; - - if (GameLib.Utils.UndefinedOrNull(scenes)) { - scenes = []; - } - this.scenes = scenes; - - if (GameLib.Utils.UndefinedOrNull(viewports)) { - viewports = []; - } - this.viewports = viewports; - - if (GameLib.Utils.UndefinedOrNull(clippingPlanes)) { - clippingPlanes = []; - } - this.clippingPlanes = clippingPlanes; - - if (GameLib.Utils.UndefinedOrNull(bufferScene)) { - bufferScene = null; - } - this.bufferScene = bufferScene; - - if (GameLib.Utils.UndefinedOrNull(bufferCamera)) { - bufferCamera = camera; - } - this.bufferCamera = bufferCamera; - - if (GameLib.Utils.UndefinedOrNull(renderTarget)) { - renderTarget = null; - } - this.renderTarget = renderTarget; - - if (GameLib.Utils.UndefinedOrNull(defaultScene)) { - defaultScene = null; - } - this.defaultScene = defaultScene; - - if (GameLib.Utils.UndefinedOrNull(sortObjects)) { - sortObjects = true; - } - this.sortObjects = sortObjects; - - GameLib.API.Component.call( - this, - GameLib.Component.RENDERER, - parentEntity - ); - -}; - -GameLib.D3.API.Renderer.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Renderer.prototype.constructor = GameLib.D3.API.Renderer; - -/** - * Object to GameLib.D3.API.Renderer - * @param objectComponent - * @constructor - */ -GameLib.D3.API.Renderer.FromObject = function(objectComponent) { - return new GameLib.D3.API.Renderer( - objectComponent.id, - objectComponent.name, - objectComponent.autoClear, - objectComponent.localClipping, - objectComponent.width, - objectComponent.height, - objectComponent.preserveDrawingBuffer, - objectComponent.domElement, - objectComponent.clearColor, - objectComponent.camera, - objectComponent.scenes, - objectComponent.viewports, - objectComponent.clippingPlanes, - objectComponent.bufferScene, - objectComponent.bufferCamera, - objectComponent.renderTarget, - objectComponent.defaultScene, - objectComponent.sortObjects, - objectComponent.parentEntity - ); -}; - -/** - * Raw RigidBody API object - should always correspond with the RigidBody Schema - * @param id - * @param name - * @param mass - * @param friction - * @param position - * @param quaternion - * @param velocity - * @param angularVelocity - * @param linearDamping - * @param angularDamping - * @param allowSleep - * @param sleepSpeedLimit - * @param sleepTimeLimit - * @param collisionFilterGroup - * @param collisionFilterMask - * @param fixedRotation - * @param shapes - * @param kinematic - * @param parentMesh - * @param parentPhysicsWorld - * @param parentEntity - * @constructor - */ -GameLib.D3.API.RigidBody = function( - id, - name, - mass, - friction, - position, - quaternion, - velocity, - angularVelocity, - linearDamping, - angularDamping, - allowSleep, - sleepSpeedLimit, - sleepTimeLimit, - collisionFilterGroup, - collisionFilterMask, - fixedRotation, - shapes, - kinematic, - parentMesh, - parentPhysicsWorld, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'RigidBody (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(mass)) { - mass = 0; - } - this.mass = mass; - - if (GameLib.Utils.UndefinedOrNull(friction)) { - friction = 5; - } - this.friction = friction; - - if (GameLib.Utils.UndefinedOrNull(position)) { - position = new GameLib.API.Vector3(0,0,0); - } - this.position = position; - - if (GameLib.Utils.UndefinedOrNull(quaternion)) { - quaternion = new GameLib.API.Quaternion(); - } - this.quaternion = quaternion; - - if (GameLib.Utils.UndefinedOrNull(velocity)) { - velocity = new GameLib.API.Vector3(); - } - this.velocity = velocity; - - if (GameLib.Utils.UndefinedOrNull(angularVelocity)) { - angularVelocity = new GameLib.API.Vector3(); - } - this.angularVelocity = angularVelocity; - - if (GameLib.Utils.UndefinedOrNull(linearDamping)) { - linearDamping = 0.01; - } - this.linearDamping = linearDamping; - - if (GameLib.Utils.UndefinedOrNull(angularDamping)) { - angularDamping = 0.01; - } - this.angularDamping = angularDamping; - - if (GameLib.Utils.UndefinedOrNull(allowSleep)) { - allowSleep = true; - } - this.allowSleep = allowSleep; - - if (GameLib.Utils.UndefinedOrNull(sleepSpeedLimit)) { - sleepSpeedLimit = 0.1; - } - this.sleepSpeedLimit = sleepSpeedLimit; - - if (GameLib.Utils.UndefinedOrNull(sleepTimeLimit)) { - sleepTimeLimit = 1.0; - } - this.sleepTimeLimit = sleepTimeLimit; - - if (GameLib.Utils.UndefinedOrNull(collisionFilterGroup)) { - collisionFilterGroup = 1; - } - this.collisionFilterGroup = collisionFilterGroup; - - if (GameLib.Utils.UndefinedOrNull(collisionFilterMask)) { - collisionFilterMask = 1; - } - this.collisionFilterMask = collisionFilterMask; - - if (GameLib.Utils.UndefinedOrNull(fixedRotation)) { - fixedRotation = false; - } - this.fixedRotation = fixedRotation; - - if (GameLib.Utils.UndefinedOrNull(shapes)) { - shapes = []; - } - this.shapes = shapes; - - if (GameLib.Utils.UndefinedOrNull(kinematic)) { - kinematic = false; - } - this.kinematic = kinematic; - - if (GameLib.Utils.UndefinedOrNull(parentMesh)) { - parentMesh = null; - } - this.parentMesh = parentMesh; - - if (GameLib.Utils.UndefinedOrNull(parentPhysicsWorld)) { - parentPhysicsWorld = null; - } - this.parentPhysicsWorld = parentPhysicsWorld; - - GameLib.API.Component.call( - this, - GameLib.Component.RIGID_BODY, - parentEntity - ); -}; - -GameLib.D3.API.RigidBody.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.RigidBody.prototype.constructor = GameLib.D3.API.RigidBody; - -/** - * Creates an API RigidBody from an Object RigidBody - * @param objectRigidBody - * @constructor - */ -GameLib.D3.API.RigidBody.FromObject = function(objectRigidBody) { - return new GameLib.D3.API.RigidBody( - objectRigidBody.id, - objectRigidBody.name, - objectRigidBody.mass, - objectRigidBody.friction, - objectRigidBody.position, - objectRigidBody.quaternion, - objectRigidBody.velocity, - objectRigidBody.angularVelocity, - objectRigidBody.linearDamping, - objectRigidBody.angularDamping, - objectRigidBody.allowSleep, - objectRigidBody.sleepSpeedLimit, - objectRigidBody.sleepTimeLimit, - objectRigidBody.collisionFilterGroup, - objectRigidBody.collisionFilterMask, - objectRigidBody.fixedRotation, - objectRigidBody.shapes, - objectRigidBody.kinematic, - objectRigidBody.parentMesh, - objectRigidBody.parentPhysicsWorld, - objectRigidBody.parentEntity - ); -}; - - -/** - * Raw Scene API object - should always correspond with the Scene Schema - * @param id String - * @param name String - * @param meshes [GameLib.D3.API.Mesh] - * @param lights [GameLib.D3.API.Light] - * @param textures [GameLib.D3.API.Texture] - * @param materials [GameLib.D3.API.Material] - * @param images - * @param fog - * @param renderCamera - this is a camera which takes precedence over the renderer camera at time of render - * @param showGrid - * @param showAxis - * @param gridSize - * @param gridColor - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Scene = function( - id, - name, - meshes, - lights, - textures, - materials, - images, - fog, - renderCamera, - showGrid, - showAxis, - gridSize, - gridColor, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Scene (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(meshes)) { - meshes = []; - } - this.meshes = meshes; - - if (GameLib.Utils.UndefinedOrNull(lights)) { - lights = []; - } - this.lights = lights; - - if (GameLib.Utils.UndefinedOrNull(textures)) { - textures = []; - } - this.textures = textures; - - if (GameLib.Utils.UndefinedOrNull(materials)) { - materials = []; - } - this.materials = materials; - - if (GameLib.Utils.UndefinedOrNull(images)) { - images = []; - } - this.images = images; - - if (GameLib.Utils.UndefinedOrNull(fog)) { - fog = null; - } - this.fog = fog; - - if (GameLib.Utils.UndefinedOrNull(renderCamera)) { - renderCamera = null; - } - this.renderCamera = renderCamera; - - if (GameLib.Utils.UndefinedOrNull(showGrid)) { - showGrid = true; - } - this.showGrid = showGrid; - - if (GameLib.Utils.UndefinedOrNull(showAxis)) { - showAxis = true; - } - this.showAxis = showAxis; - - if (GameLib.Utils.UndefinedOrNull(gridSize)) { - gridSize = 10; - } - this.gridSize = gridSize; - - if (GameLib.Utils.UndefinedOrNull(gridColor)) { - gridColor = new GameLib.API.Color(0.1, 0.1, 0.1); - } - this.gridColor = gridColor; - - GameLib.API.Component.call( - this, - GameLib.Component.SCENE, - parentEntity - ); - -}; - -GameLib.D3.API.Scene.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Scene.prototype.constructor = GameLib.D3.API.Scene; - -/** - * Returns an API scene from an Object scene - * @param objectScene - * @constructor - */ -GameLib.D3.API.Scene.FromObject = function(objectScene) { - - var apiMeshes = []; - var apiLights = []; - var apiTextures = []; - var apiMaterials = []; - var apiImages = []; - - if (objectScene.meshes) { - apiMeshes = objectScene.meshes.map( - function(objectMesh) { - if (objectMesh instanceof Object){ - return GameLib.D3.API.Mesh.FromObject(objectMesh); - } else { - return objectMesh; - } - } - ) - } - - if (objectScene.lights) { - apiLights = objectScene.lights.map( - function(objectLight) { - if (objectLight instanceof Object) { - return GameLib.D3.API.Light.FromObject(objectLight); - } else { - return objectLight; - } - } - ) - } - - if (objectScene.textures) { - apiTextures = objectScene.textures.map( - function(objectTexture) { - if (objectTexture instanceof Object) { - return GameLib.D3.API.Texture.FromObject(objectTexture) - } else { - return objectTexture; - } - } - ) - } - - if (objectScene.materials) { - apiMaterials = objectScene.materials.map( - function(objectMaterial) { - if (objectMaterial instanceof Object) { - return GameLib.D3.API.Material.FromObject(objectMaterial) - } else { - return objectMaterial; - } - } - ) - } - - if (objectScene.images) { - apiImages = objectScene.images.map( - function(objectImage) { - if (objectImage instanceof Object) { - return GameLib.API.Image.FromObject(objectImage) - } else { - return objectImage; - } - } - ) - } - - return new GameLib.D3.API.Scene( - objectScene.id, - objectScene.name, - apiMeshes, - apiLights, - apiTextures, - apiMaterials, - apiImages, - objectScene.fog, - objectScene.renderCamera, - objectScene.showGrid, - objectScene.showAxis, - objectScene.gridSize, - GameLib.API.Color.FromObject(objectScene.gridColor), - objectScene.parentEntity - ); - -}; - -/** - * Raw Shape API object - should always correspond with the Shape Schema - * @param id - * @param name - * @param shapeType - * @param boundingSphereRadius - * @param collisionResponse - * @param frictionMaterial - * @param parentMesh - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Shape = function( - id, - name, - shapeType, - boundingSphereRadius, - collisionResponse, - frictionMaterial, - parentMesh, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(shapeType)) { - shapeType = GameLib.D3.API.Shape.SHAPE_TYPE_NONE; - } - this.shapeType = shapeType; - - if (GameLib.Utils.UndefinedOrNull(name)) { - - name = 'Shape (' + this.id + ')'; - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_BOX) { - name = 'Shape Box (' + this.id + ')'; - } - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL) { - name = 'Shape Convex Hull (' + this.id + ')'; - } - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL_CYLINDER) { - name = 'Shape Convex Hull Cylinder (' + this.id + ')'; - } - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_HEIGHT_MAP) { - name = 'Shape HeightMap (' + this.id + ')'; - } - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_PLANE) { - name = 'Shape Plane (' + this.id + ')'; - } - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_SPHERE) { - name = 'Shape Sphere (' + this.id + ')'; - } - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_TRIMESH) { - name = 'Shape TriMesh (' + this.id + ')'; - } - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(boundingSphereRadius)) { - boundingSphereRadius = 0; - } - this.boundingSphereRadius = boundingSphereRadius; - - if (GameLib.Utils.UndefinedOrNull(collisionResponse)) { - collisionResponse = true; - } - this.collisionResponse = collisionResponse; - - if (GameLib.Utils.UndefinedOrNull(frictionMaterial)) { - frictionMaterial = null; - } - this.frictionMaterial = frictionMaterial; - - if (GameLib.Utils.UndefinedOrNull(parentMesh)) { - parentMesh = null; - } - this.parentMesh = parentMesh; - - var componentType = GameLib.Component.SHAPE; - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_BOX) { - componentType = GameLib.Component.SHAPE_BOX; - } - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL) { - componentType = GameLib.Component.SHAPE_CONVEX_HULL; - } - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL_CYLINDER) { - componentType = GameLib.Component.SHAPE_CONVEX_HULL_CYLINDER; - } - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_HEIGHT_MAP) { - componentType = GameLib.Component.SHAPE_HEIGHT_MAP; - } - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_PLANE) { - componentType = GameLib.Component.SHAPE_PLANE; - } - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_SPHERE) { - componentType = GameLib.Component.SHAPE_SPHERE; - } - - if (this.shapeType === GameLib.D3.API.Shape.SHAPE_TYPE_TRIMESH) { - componentType = GameLib.Component.SHAPE_TRI_MESH; - } - - GameLib.API.Component.call( - this, - componentType, - parentEntity - ); -}; - -GameLib.D3.API.Shape.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Shape.prototype.constructor = GameLib.D3.API.Shape; - -GameLib.D3.API.Shape.SHAPE_TYPE_NONE = 0x0; -GameLib.D3.API.Shape.SHAPE_TYPE_BOX = 0x1; -GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL = 0x2; -GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL_CYLINDER = 0x3; -GameLib.D3.API.Shape.SHAPE_TYPE_HEIGHT_MAP = 0x4; -GameLib.D3.API.Shape.SHAPE_TYPE_PLANE = 0x5; -GameLib.D3.API.Shape.SHAPE_TYPE_SPHERE = 0x6; -GameLib.D3.API.Shape.SHAPE_TYPE_TRIMESH = 0x7; - -/** - * Creates an API Shape from an Object Shape - * @param objectShape - * @constructor - */ -GameLib.D3.API.Shape.FromObject = function(objectShape) { - return new GameLib.D3.API.Shape( - objectShape.id, - objectShape.name, - objectShape.shapeType, - objectShape.boundingSphereRadius, - objectShape.collisionResponse, - objectShape.frictionMaterial, - objectShape.parentMesh, - objectShape.parentEntity - ); -}; - - -/** - * API Skeleton - * @param id - * @param name - * @param bones GameLib.D3.API.Bone[] - * @param boneInverses GameLib.API.Matrix4[] - * @param useVertexTexture boolean - * @param boneTextureWidth Number - * @param boneTextureHeight Number - * @param boneMatrices GameLib.API.Matrix4[] - * @param boneTexture null (not implemented) - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Skeleton = function ( - id, - name, - bones, - boneInverses, - useVertexTexture, - boneTextureWidth, - boneTextureHeight, - boneMatrices, - boneTexture, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Skeleton'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(bones)) { - bones = []; - } - this.bones = bones; - - /** - * An array of Matrix4s that represent the inverse of the matrixWorld of the individual bones. - */ - if (GameLib.Utils.UndefinedOrNull(boneInverses)) { - boneInverses = []; - } - this.boneInverses = boneInverses; - - /** - * Use a vertex texture in the shader - allows for more than 4 bones per vertex, not supported by all devices - */ - if (GameLib.Utils.UndefinedOrNull(useVertexTexture)) { - useVertexTexture = false; - } - this.useVertexTexture = useVertexTexture; - if (useVertexTexture) { - console.warn('support for vertex texture bones is not supported yet - something could break somewhere'); - } - - if (GameLib.Utils.UndefinedOrNull(boneTextureWidth)) { - boneTextureWidth = 0; - } - this.boneTextureWidth = boneTextureWidth; - - if (GameLib.Utils.UndefinedOrNull(boneTextureHeight)) { - boneTextureHeight = 0; - } - this.boneTextureHeight = boneTextureHeight; - - if (GameLib.Utils.UndefinedOrNull(boneMatrices)) { - boneMatrices = []; - } - this.boneMatrices = boneMatrices; - - if (GameLib.Utils.UndefinedOrNull(boneTexture)) { - boneTexture = null; - } - this.boneTexture = boneTexture; - - GameLib.API.Component.call( - this, - GameLib.Component.SKELETON, - parentEntity - ); -}; - -GameLib.D3.API.Skeleton.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Skeleton.prototype.constructor = GameLib.D3.API.Skeleton; - -/** - * Creates an API skeleton from an Object skeleton - * @param objectSkeleton - * @constructor - */ -GameLib.D3.API.Skeleton.FromObject = function(objectSkeleton) { - return new GameLib.D3.API.Skeleton( - objectSkeleton.id, - objectSkeleton.name, - objectSkeleton.bones.map( - function (objectBone) { - return GameLib.D3.API.Bone.FromObject(objectBone); - } - ), - objectSkeleton.boneInverses.map( - function (boneInverse) { - return GameLib.D3.API.Matrix4.FromObject(boneInverse); - } - ), - objectSkeleton.useVertexTexture, - objectSkeleton.boneTextureWidth, - objectSkeleton.boneTextureHeight, - objectSkeleton.boneMatrices.map( - function (boneMatrix) { - return GameLib.D3.API.Matrix4.FromObject(boneMatrix); - } - ), - objectSkeleton.boneTexture, - objectSkeleton.parentEntity - ); -}; -/** - * Raw Solver API object - should always correspond with the Solver Schema - * @param id - * @param name - * @param solverType - * @param iterations - * @param tolerance - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Solver = function( - id, - name, - solverType, - iterations, - tolerance, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Solver (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(solverType)) { - solverType = GameLib.D3.API.Solver.GS_SOLVER; - } - this.solverType = solverType; - - if (GameLib.Utils.UndefinedOrNull(iterations)) { - iterations = 10; - } - this.iterations = iterations; - - if (GameLib.Utils.UndefinedOrNull(tolerance)) { - tolerance = 1e-7; - } - this.tolerance = tolerance; - - GameLib.API.Component.call( - this, - GameLib.Component.SOLVER, - parentEntity - ); -}; - -GameLib.D3.API.Solver.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Solver.prototype.constructor = GameLib.D3.API.Solver; - -/** - * Solver Types - * @type {number} - */ -GameLib.D3.API.Solver.GS_SOLVER = 0x1; -GameLib.D3.API.Solver.SPLIT_SOLVER = 0x2; - -/** - * Creates an API Solver from an Object Solver - * @param objectSolver - * @constructor - */ -GameLib.D3.API.Solver.FromObject = function(objectSolver) { - return new GameLib.D3.API.Solver( - objectSolver.id, - objectSolver.name, - objectSolver.solverType, - objectSolver.iterations, - objectSolver.tolerance, - objectSolver.parentEntity - ); -}; - - -/** - * API Spline - * @param id String - * @param name String - * @param vertices GameLib.API.Vector3[] - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Spline = function( - id, - name, - vertices, - parentEntity -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Spline (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(vertices)) { - vertices = []; - } - this.vertices = vertices; - - GameLib.API.Component.call( - this, - GameLib.Component.SPLINE, - parentEntity - ); -}; - -GameLib.D3.API.Spline.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Spline.prototype.constructor = GameLib.D3.API.Spline; - -/** - * Object to GameLib.D3.API.Spline - * @param objectComponent - * @constructor - */ -GameLib.D3.API.Spline.FromObject = function(objectComponent) { - return new GameLib.D3.API.Spline( - objectComponent.id, - objectComponent.name, - objectComponent.vertices.map( - function (objectVertex) { - return GameLib.API.Vector3.FromObject(objectVertex); - } - ), - objectComponent.parentEntity - ); -}; - -/** - * Raw Texture API object - should always correspond with the Texture Schema - * @param id - * @param textureType - * @param name - * @param image - * @param images - * @param wrapS - * @param wrapT - * @param repeat - * @param data - * @param format - * @param mapping - * @param magFilter - * @param minFilter - * @param storageType - * @param textureType - * @param anisotropy - * @param offset - * @param generateMipmaps - * @param flipY - * @param mipmaps - * @param unpackAlignment - * @param premultiplyAlpha - * @param encoding - * @param canvas - * @param animated - * @param reverseAnimation - * @param forward - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Texture = function( - id, - textureType, - name, - image, - images, - wrapS, - wrapT, - repeat, - data, - format, - mapping, - magFilter, - minFilter, - storageType, - anisotropy, - offset, - generateMipmaps, - flipY, - mipmaps, - unpackAlignment, - premultiplyAlpha, - encoding, - canvas, - animated, - reverseAnimation, - forward, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(textureType)) { - textureType = GameLib.D3.API.Texture.TEXTURE_TYPE_NORMAL; - } - this.textureType = textureType; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Texture (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(image)) { - image = null; - } - this.image = image; - - if (GameLib.Utils.UndefinedOrNull(images)) { - images = []; - } - this.images = images; - - if (GameLib.Utils.UndefinedOrNull(wrapS)) { - wrapS = GameLib.D3.API.Texture.TYPE_REPEAT_WRAPPING; - } - this.wrapS = wrapS; - - if (GameLib.Utils.UndefinedOrNull(wrapT)) { - wrapT = GameLib.D3.API.Texture.TYPE_REPEAT_WRAPPING; - } - this.wrapT = wrapT; - - if (GameLib.Utils.UndefinedOrNull(repeat)) { - repeat = new GameLib.API.Vector2(1, 1); - } - this.repeat = repeat; - - if (GameLib.Utils.UndefinedOrNull(data)) { - data = null; - } - this.data = data; - - if (GameLib.Utils.UndefinedOrNull(format)) { - format = GameLib.D3.API.Texture.TYPE_RGBA_FORMAT; - } - this.format = format; - - if (GameLib.Utils.UndefinedOrNull(mapping)) { - mapping = GameLib.D3.API.Texture.TYPE_UV_MAPPING; - } - this.mapping = mapping; - - if (GameLib.Utils.UndefinedOrNull(magFilter)) { - magFilter = GameLib.D3.API.Texture.TYPE_LINEAR_FILTER; - } - this.magFilter = magFilter; - - if (GameLib.Utils.UndefinedOrNull(minFilter)) { - minFilter = GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER; - } - this.minFilter = minFilter; - - if (GameLib.Utils.UndefinedOrNull(storageType)) { - storageType = GameLib.D3.API.Texture.TYPE_UNSIGNED_BYTE; - } - this.storageType = storageType; - - if (GameLib.Utils.UndefinedOrNull(anisotropy)) { - anisotropy = 1; - } - this.anisotropy = anisotropy; - - if (GameLib.Utils.UndefinedOrNull(offset)) { - offset = new GameLib.API.Vector2(0, 0); - } - this.offset = offset; - - if (GameLib.Utils.UndefinedOrNull(generateMipmaps)) { - generateMipmaps = true; - } - this.generateMipmaps = generateMipmaps; - - if (GameLib.Utils.UndefinedOrNull(flipY)) { - flipY = true; - } - this.flipY = flipY; - - if (GameLib.Utils.UndefinedOrNull(mipmaps)) { - mipmaps = []; - } - this.mipmaps = mipmaps; - - if (GameLib.Utils.UndefinedOrNull(unpackAlignment)) { - unpackAlignment = 4; - } - this.unpackAlignment = unpackAlignment; - - if (GameLib.Utils.UndefinedOrNull(premultiplyAlpha)) { - premultiplyAlpha = false; - } - this.premultiplyAlpha = premultiplyAlpha; - - if (GameLib.Utils.UndefinedOrNull(encoding)) { - encoding = GameLib.D3.API.Texture.TYPE_LINEAR_ENCODING; - } - this.encoding = encoding; - - if (GameLib.Utils.UndefinedOrNull(canvas)) { - canvas = null; - } - this.canvas = canvas; - - if (GameLib.Utils.UndefinedOrNull(animated)) { - animated = false; - } - this.animated = animated; - - if (GameLib.Utils.UndefinedOrNull(reverseAnimation)) { - reverseAnimation = false; - } - this.reverseAnimation = reverseAnimation; - - if (GameLib.Utils.UndefinedOrNull(forward)) { - forward = true; - } - this.forward = forward; - - this.needsUpdate = false; - - GameLib.API.Component.call( - this, - GameLib.Component.TEXTURE, - parentEntity - ); -}; - -GameLib.D3.API.Texture.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Texture.prototype.constructor = GameLib.D3.API.Texture; - -/** - * Texture Formats - * @type {number} - */ -GameLib.D3.API.Texture.TYPE_ALPHA_FORMAT = 1019; -GameLib.D3.API.Texture.TYPE_RGB_FORMAT = 1020; -GameLib.D3.API.Texture.TYPE_RGBA_FORMAT = 1021; -GameLib.D3.API.Texture.TYPE_LUMINANCE_FORMAT = 1022; -GameLib.D3.API.Texture.TYPE_LUMINANCE_ALPHA_FORMAT = 1023; -GameLib.D3.API.Texture.TYPE_DEPTH_FORMAT = 1026; - -/** - * Mapping modes - * @type {number} - */ -GameLib.D3.API.Texture.TYPE_UV_MAPPING = 300; -GameLib.D3.API.Texture.TYPE_CUBE_REFLECTION_MAPPING = 301; -GameLib.D3.API.Texture.TYPE_CUBE_REFRACTION_MAPPING = 302; -GameLib.D3.API.Texture.TYPE_EQUI_RECTANGULAR_REFLECTION_MAPPING = 303; -GameLib.D3.API.Texture.TYPE_EQUI_RECTANGULAR_REFRACTION_MAPPING = 304; -GameLib.D3.API.Texture.TYPE_SPHERICAL_REFLECTION_MAPPING = 305; -GameLib.D3.API.Texture.TYPE_CUBE_UV_REFLECTION_MAPPING = 306; -GameLib.D3.API.Texture.TYPE_CUBE_UV_REFRACTION_MAPPING = 307; - -/** - * Wrapping Modes - * @type {number} - */ -GameLib.D3.API.Texture.TYPE_REPEAT_WRAPPING = 1000; -GameLib.D3.API.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING = 1001; -GameLib.D3.API.Texture.TYPE_MIRRORED_REPEAT_WRAPPING = 1002; - -/** - * Mipmap Filters - * @type {number} - */ -GameLib.D3.API.Texture.TYPE_NEAREST_FILTER = 1003; -GameLib.D3.API.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER = 1004; -GameLib.D3.API.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER = 1005; -GameLib.D3.API.Texture.TYPE_LINEAR_FILTER = 1006; -GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER = 1007; -GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER = 1008; - -/** - * Texture Data Types - * @type {number} - */ -GameLib.D3.API.Texture.TYPE_UNSIGNED_BYTE = 1009; -GameLib.D3.API.Texture.TYPE_BYTE = 1010; -GameLib.D3.API.Texture.TYPE_SHORT = 1011; -GameLib.D3.API.Texture.TYPE_UNSIGNED_SHORT = 1012; -GameLib.D3.API.Texture.TYPE_INT = 1013; -GameLib.D3.API.Texture.TYPE_UNSIGNED_INT = 1014; -GameLib.D3.API.Texture.TYPE_FLOAT = 1015; -GameLib.D3.API.Texture.TYPE_HALF_FLOAT = 1025; - -/** - * Encoding Modes - * @type {number} - */ -GameLib.D3.API.Texture.TYPE_LINEAR_ENCODING = 3000; // NO ENCODING AT ALL. -GameLib.D3.API.Texture.TYPE_SRGB_ENCODING = 3001; -GameLib.D3.API.Texture.TYPE_GAMMA_ENCODING = 3007; // USES GAMMA_FACTOR, FOR BACKWARDS COMPATIBILITY WITH WEBGLRENDERER.GAMMAINPUT/GAMMAOUTPUT -GameLib.D3.API.Texture.TYPE_RGBE_ENCODING = 3002; // AKA RADIANCE. -GameLib.D3.API.Texture.TYPE_LOG_LUV_ENCODING = 3003; -GameLib.D3.API.Texture.TYPE_RGBM7_ENCODING = 3004; -GameLib.D3.API.Texture.TYPE_RGBM16_ENCODING = 3005; -GameLib.D3.API.Texture.TYPE_RGBD_ENCODING = 3006; // MAXRANGE IS 256. - -GameLib.D3.API.Texture.TEXTURE_TYPE_NORMAL = 0x1; -GameLib.D3.API.Texture.TEXTURE_TYPE_CUBE = 0x2; -GameLib.D3.API.Texture.TEXTURE_TYPE_CANVAS = 0x3; - - -/** - * Creates an API texture from Object data - * @param objectTexture - * @constructor - */ -GameLib.D3.API.Texture.FromObject = function(objectTexture) { - return new GameLib.D3.API.Texture( - objectTexture.id, - objectTexture.typeId || objectTexture.textureType, - objectTexture.name, - objectTexture.image, - objectTexture.images, - objectTexture.wrapS, - objectTexture.wrapT, - GameLib.API.Vector2.FromObject(objectTexture.repeat), - objectTexture.data, - objectTexture.format, - objectTexture.mapping, - objectTexture.magFilter, - objectTexture.minFilter, - objectTexture.storageType, - objectTexture.anisotropy, - GameLib.API.Vector2.FromObject(objectTexture.offset), - objectTexture.generateMipmaps, - objectTexture.flipY, - objectTexture.mipmaps, - objectTexture.unpackAlignment, - objectTexture.premultiplyAlpha, - objectTexture.encoding, - objectTexture.canvas, - objectTexture.animated, - objectTexture.reverseAnimation, - objectTexture.forward, - objectTexture.parentEntity - ) -}; - -/** - * API Vertex - * @param position GameLib.API.Vector3 - * @param boneWeights GameLib.API.BoneWeight[] - * @constructor - */ -GameLib.D3.API.Vertex = function( - position, - boneWeights -) { - - if (GameLib.Utils.UndefinedOrNull(position)) { - position = new GameLib.API.Vector3(); - } - this.position = position; - - if (GameLib.Utils.UndefinedOrNull(boneWeights)) { - boneWeights = []; - } - this.boneWeights = boneWeights; -}; - -/** - * Creates an API vertex from an Object vertex - * @param objectVertex - * @constructor - */ -GameLib.D3.API.Vertex.FromObject = function(objectVertex) { - return new GameLib.D3.API.Vertex( - GameLib.API.Vector3.FromObject(objectVertex.position), - objectVertex.boneWeights.map( - function(boneWeight) { - return GameLib.D3.API.BoneWeight.FromObject(boneWeight); - } - ) - ); -}; - -/** - * Raw Viewport API object - should always correspond with the Viewport Schema - * @param id - * @param name - * @param width - * @param height - * @param x - * @param y - * @param parentEntity - * @constructor - */ -GameLib.D3.API.Viewport = function( - id, - name, - width, - height, - x, - y, - parentEntity -) { - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Viewport (' + this.id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(width)) { - width = 800; - } - this.width = width; - - if (GameLib.Utils.UndefinedOrNull(height)) { - height = 600; - } - this.height = height; - - if (GameLib.Utils.UndefinedOrNull(x)) { - x = 0; - } - this.x = x; - - if (GameLib.Utils.UndefinedOrNull(y)) { - y = 0; - } - this.y = y; - - GameLib.API.Component.call( - this, - GameLib.Component.VIEWPORT, - parentEntity - ); -}; - -GameLib.D3.API.Viewport.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.API.Viewport.prototype.constructor = GameLib.D3.API.Viewport; - -/** - * Creates an API Viewport from an Object Viewport - * @param objectViewport - * @constructor - */ -GameLib.D3.API.Viewport.FromObject = function(objectViewport) { - return new GameLib.D3.API.Viewport( - objectViewport.id, - objectViewport.name, - objectViewport.width, - objectViewport.height, - objectViewport.x, - objectViewport.y, - objectViewport.parentEntity - ); -}; - - -/** - * Creates a Animation object - * @param apiAnimation GameLib.D3.API.Animation - * @constructor - */ -GameLib.D3.Animation = function( - apiAnimation -) { - - if (GameLib.Utils.UndefinedOrNull(apiAnimation)) { - apiAnimation = {}; - } - - if (apiAnimation instanceof GameLib.D3.Animation) { - return apiAnimation; - } - - GameLib.D3.API.Animation.call( - this, - apiAnimation.id, - apiAnimation.name, - apiAnimation.rotationSpeed, - apiAnimation.translationSpeed, - apiAnimation.scaleSpeed, - apiAnimation.rotationFn, - apiAnimation.translationFn, - apiAnimation.scaleFn, - apiAnimation.blocking, - apiAnimation.applyToMeshWhenDone, - apiAnimation.meshes, - apiAnimation.parentEntity - ); - - this.functionType = GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION; - - this.editor = null; - - /** - * This indicates whether an animation is currently in process - for blocking to take effect - * @type {boolean} - */ - this.inProcess = false; - - GameLib.Component.call( - this, - { - 'meshes' : [GameLib.D3.Mesh] - } - ); -}; - -GameLib.D3.Animation.prototype = Object.create(GameLib.D3.API.Animation.prototype); -GameLib.D3.Animation.prototype.constructor = GameLib.D3.Animation; - -GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION = 1; -GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION = 2; -GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE = 3; - -GameLib.D3.Animation.prototype.createInstance = function() { - - this.instance = { - rotation : null, - translation : null, - scale : null - }; - - try { - if (this.rotationFn) { - this.instance.rotation = new Function( - 'data', - this.rotationFn - ).bind(this); - } - - if (this.translationFn) { - this.instance.translation = new Function( - 'data', - this.translationFn - ).bind(this); - } - - if (this.scaleFn) { - this.instance.scale = new Function( - 'data', - this.scaleFn - ).bind(this); - } - } catch (error) { - console.error(error); - this.publish( - GameLib.Event.ANIMATION_COMPILE_FAILED, - { - component : this - } - ) - } - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.D3.Animation.prototype.updateInstance = function() { - - try { - - if (this.rotationFn) { - this.instance.rotation = new Function('data', this.rotationFn).bind(this); - this.publish( - GameLib.Event.ANIMATION_COMPILE_SUCCESS, - { - component : this, - type : GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION - } - ) - } - - if (this.translationFn) { - this.instance.translation = new Function('data', this.translationFn).bind(this); - this.publish( - GameLib.Event.ANIMATION_COMPILE_SUCCESS, - { - component : this, - type : GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION - } - ) - } - - if (this.scaleFn) { - this.instance.scale = new Function('data', this.scaleFn).bind(this); - this.publish( - GameLib.Event.ANIMATION_COMPILE_SUCCESS, - { - component : this, - type : GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE - } - ) - } - - } catch (error) { - console.error(error); - this.publish( - GameLib.Event.ANIMATION_COMPILE_FAILED, - { - component : this - } - ) - } -}; - -/** - * Converts a GameLib.D3.Animation to a new GameLib.D3.API.Animation - * @returns {GameLib.D3.API.Animation} - */ -GameLib.D3.Animation.prototype.toApiObject = function() { - - return new GameLib.D3.API.Animation( - this.id, - this.name, - this.rotationSpeed, - this.translationSpeed, - this.scaleSpeed, - this.rotationFn, - this.translationFn, - this.scaleFn, - this.blocking, - this.applyToMeshWhenDone, - this.meshes.map( - function(mesh) { - return GameLib.Utils.IdOrNull(mesh); - } - ), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - -}; - -/** - * Converts from an Object Animation to a GameLib.D3.Animation - * @param objectAnimation Object - * @returns {GameLib.D3.Animation} - * @constructor - */ -GameLib.D3.Animation.FromObject = function(objectAnimation) { - var apiAnimation = GameLib.D3.API.Animation.FromObject(objectAnimation); - return new GameLib.D3.Animation( - apiAnimation - ); -}; - -GameLib.D3.Animation.prototype.launchEditor = function(){ - - GameLib.Event.Emit( - GameLib.Event.GET_RUNTIME, - null, - function(runtime) { - this.coder = runtime.coder; - this.coder.isNotCodeMirrorThrow(); - }.bind(this) - ); - - var property = null; - - if (this.functionType === GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION) { - this.rotationFn = '//when the animation is complete, return true\nreturn true;'; - property = 'rotationFn'; - } - - if (this.functionType === GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION) { - this.translationFn = '//when the animation is complete, return true\nreturn true;'; - property = 'translationFn'; - } - - if (this.functionType === GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE) { - this.scaleFn = '//when the animation is complete, return true\nreturn true;'; - property = 'scaleFn'; - } - - if (property) { - this.editor = this.coder.instance( - document.body, - { - value : this[property], - mode : 'javascript', - lineNumbers : true, - scrollbarStyle : 'overlay' - } - ); - - this.editor.on('change', function(){ - - this[property] = this.editor.getValue(); - - this.updateInstance(); - - }.bind(this)) - } else { - console.warn('invalid function type selected'); - } -}; - -GameLib.D3.Animation.prototype.closeEditor = function(){ - var dom = this.editor.getWrapperElement(); - dom.parentElement.removeChild(dom); -}; - -GameLib.D3.Animation.prototype.addMesh = function(mesh) { - - GameLib.Utils.PushUnique(this.meshes, mesh); - - GameLib.Event.Emit( - GameLib.Event.ANIMATION_MESH_ADDED, - { - animation : this, - mesh : mesh - } - ) - -}; - -GameLib.D3.Animation.prototype.removeMesh = function(mesh) { - - var index = this.meshes.indexOf(mesh); - - this.meshes.splice(index, 1); - - GameLib.Event.Emit( - GameLib.Event.ANIMATION_MESH_REMOVED, - { - animation : this, - mesh : mesh - } - ) - -}; -/** - * Creates a Audio object - * @param graphics GameLib.GraphicsRuntime - * @param apiAudio GameLib.D3.API.Audio - * @constructor - */ -GameLib.D3.Audio = function( - graphics, - apiAudio -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiAudio)) { - apiAudio = {}; - } - - if (apiAudio instanceof GameLib.D3.Audio) { - return apiAudio; - } - - GameLib.D3.API.Audio.call( - this, - apiAudio.id, - apiAudio.name, - apiAudio.path, - apiAudio.loop, - apiAudio.volume, - apiAudio.camera, - apiAudio.overplay, - apiAudio.pause, - apiAudio.parentEntity - ); - - if (this.camera instanceof GameLib.D3.API.Camera) { - this.camera = new GameLib.D3.Camera( - this.graphics, - this.camera - ) - } - - GameLib.Component.call( - this, - { - 'camera' : GameLib.D3.Camera - } - ); - -}; - -GameLib.D3.Audio.prototype = Object.create(GameLib.D3.API.Audio.prototype); -GameLib.D3.Audio.prototype.constructor = GameLib.D3.Audio; - -/** - * Audio create instance - */ -GameLib.D3.Audio.prototype.createInstance = function() { - - if (GameLib.Utils.UndefinedOrNull(this.camera) || - GameLib.Utils.UndefinedOrNull(this.camera.instance)) { - console.log('audio not ready to create instance'); - return; - } - - - GameLib.Event.Emit( - GameLib.Event.GET_API_URL, - null, - function(data) { - this.apiUrl = data.apiUrl; - }.bind(this) - ); - - //Create an AudioListener and add it to the camera - var listener = new THREE.AudioListener(); - - this.camera.instance.add( listener ); - - // create a global audio source - this.instance = new THREE.Audio( listener ); - - var audioLoader = new THREE.AudioLoader(); - - //Load a sound and set it as the Audio object's buffer - audioLoader.load( - this.apiUrl + this.path + '?ts=' + Date.now(), - function( buffer ) { - this.instance.setBuffer( buffer ); - this.instance.setLoop( this.loop ); - this.instance.setVolume( this.volume ); - GameLib.Component.prototype.createInstance.call(this); - }.bind(this) - ); -}; - -/** - * Updates the instance with the current state - */ -GameLib.D3.Audio.prototype.updateInstance = function(property) { - - if (property === 'loop') { - this.instance.setLoop(this.loop); - } - - if (property === 'volume') { - this.instance.setVolume(this.volume); - } - - if (property === 'paused') { - if (this.paused) { - this.instance.pause(); - } else { - this.instance.play(); - } - } - -}; - -/** - * Converts a GameLib.D3.Audio to a new GameLib.D3.API.Audio - * @returns {GameLib.D3.API.Audio} - */ -GameLib.D3.Audio.prototype.toApiObject = function() { - - return new GameLib.D3.API.Audio( - this.id, - this.name, - this.path, - this.loop, - this.volume, - GameLib.Utils.IdOrNull(this.camera), - this.overplay, - this.paused, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - -}; - -/** - * Converts from an Object Audio to a GameLib.D3.Audio - * @param graphics GameLib.GraphicsRuntime - * @param objectAudio Object - * @returns {GameLib.D3.Audio} - * @constructor - */ -GameLib.D3.Audio.FromObject = function(graphics, objectAudio) { - - var apiAudio = GameLib.D3.API.Audio.FromObject(objectAudio); - - return new GameLib.D3.Audio( - graphics, - apiAudio - ); - -}; - - -GameLib.D3.Audio.prototype.play = function() { - this.instance.play(); -}; -/** - * BoneWeight Superset - * @constructor - * @param graphics GameLib.GraphicsRuntime - * @param apiBoneWeight GameLib.D3.API.BoneWeight - */ -GameLib.D3.BoneWeight = function ( - graphics, - apiBoneWeight -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiBoneWeight)) { - apiBoneWeight = {}; - } - - if (apiBoneWeight instanceof GameLib.D3.BoneWeight) { - return apiBoneWeight; - } - - GameLib.D3.API.BoneWeight.call( - this, - apiBoneWeight.boneIndex, - apiBoneWeight.weight - ); -}; - -GameLib.D3.BoneWeight.prototype = Object.create(GameLib.D3.API.BoneWeight.prototype); -GameLib.D3.BoneWeight.prototype.constructor = GameLib.D3.BoneWeight; - -/** - * Converts a GameLib.D3.BoneWeight to GameLib.D3.API.BoneWeight - * @returns {GameLib.D3.API.BoneWeight} - */ -GameLib.D3.BoneWeight.prototype.toApiObject = function() { - - var apiBoneWeight = new GameLib.D3.API.BoneWeight( - this.boneIndex, - this.weight - ); - - return apiBoneWeight; -}; - -/** - * Returns a GameLib.D3.BoneWeight from a boneWeight Object - * @param graphics GameLib.GraphicsRuntime - * @param objectBoneWeight Object - * @returns {GameLib.D3.BoneWeight} - * @constructor - */ -GameLib.D3.BoneWeight.FromObject = function( - graphics, - objectBoneWeight -) { - var apiBoneWeight = GameLib.D3.API.BoneWeight.FromObject(objectBoneWeight); - - var boneWeight = new GameLib.D3.BoneWeight( - graphics, - apiBoneWeight - ); - - return boneWeight; -}; -/** - * Bone Superset - * @constructor - * @param graphics GameLib.GraphicsRuntime - * @param apiBone GameLib.D3.API.Bone - */ -GameLib.D3.Bone = function ( - graphics, - apiBone -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiBone)) { - apiBone = {}; - } - - if (apiBone instanceof GameLib.D3.Bone) { - return apiBone; - } - - GameLib.D3.API.Bone.call( - this, - apiBone.id, - apiBone.name, - apiBone.childBoneIds, - apiBone.parentBoneIds, - apiBone.position, - apiBone.quaternion, - apiBone.scale, - apiBone.up, - apiBone.parentEntity - ); - - this.position = new GameLib.Vector3( - graphics, - this.position, - this - ); - - this.quaternion = new GameLib.Quaternion( - graphics, - this.quaternion, - this - ); - - this.scale = new GameLib.Vector3( - graphics, - this.scale, - this - ); - - this.up = new GameLib.Vector3( - graphics, - this.up, - this - ); - - GameLib.Component.call(this); -}; - -GameLib.D3.Bone.prototype = Object.create(GameLib.D3.API.Bone.prototype); -GameLib.D3.Bone.prototype.constructor = GameLib.D3.Bone; - - -/** - * Creates an instance bone - - */ -GameLib.D3.Bone.prototype.createInstance = function() { - - this.instance = new THREE.Bone(); - - this.instance.name = this.name; - - this.instance.position.x = this.position.x; - this.instance.position.y = this.position.y; - this.instance.position.z = this.position.z; - - this.instance.quaternion.x = this.quaternion.x; - this.instance.quaternion.y = this.quaternion.y; - this.instance.quaternion.z = this.quaternion.z; - this.instance.quaternion.w = this.quaternion.w; - - this.instance.scale.x = this.scale.x; - this.instance.scale.y = this.scale.y; - this.instance.scale.z = this.scale.z; - - this.instance.up.x = this.up.x; - this.instance.up.y = this.up.y; - this.instance.up.z = this.up.z; - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance - */ -GameLib.D3.Bone.prototype.updateInstance = function() { - this.instance.name = this.name; - - this.instance.position.x = this.position.x; - this.instance.position.y = this.position.y; - this.instance.position.z = this.position.z; - - this.instance.quaternion.x = this.quaternion.x; - this.instance.quaternion.y = this.quaternion.y; - this.instance.quaternion.z = this.quaternion.z; - this.instance.quaternion.w = this.quaternion.w; - - this.instance.scale.x = this.scale.x; - this.instance.scale.y = this.scale.y; - this.instance.scale.z = this.scale.z; - - this.instance.up.x = this.up.x; - this.instance.up.y = this.up.y; - this.instance.up.z = this.up.z; -}; - -/** - * Converts a GameLib.D3.Bone to GameLib.D3.API.Bone - * @returns {GameLib.D3.API.Bone} - */ -GameLib.D3.Bone.prototype.toApiObject = function() { - - var apiBone = new GameLib.D3.API.Bone( - this.id, - this.name, - this.childBoneIds, - this.parentBoneIds, - this.position.toApiObject(), - this.quaternion.toApiObject(), - this.scale.toApiObject(), - this.up.toApiObject(), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiBone; -}; - -/** - * Returns a GameLib.D3.Bone from a bone Object - * @param graphics GameLib.GraphicsRuntime - * @param objectBone Object - * @returns {GameLib.D3.Bone} - * @constructor - */ -GameLib.D3.Bone.FromObject = function( - graphics, - objectBone -) { - var apiBone = GameLib.D3.API.Bone.FromObject(objectBone); - - var bone = GameLib.D3.Bone( - graphics, - apiBone - ); - - return bone; -}; -/** - * Broadphase Runtime - * @param physics GameLib.GraphicsRuntime - * @param apiBroadphase GameLib.D3.API.Broadphase - * @constructor - */ -GameLib.D3.Broadphase = function ( - physics, - apiBroadphase -) { - - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiBroadphase)) { - apiBroadphase = {}; - } - - if (apiBroadphase instanceof GameLib.D3.Broadphase) { - return apiBroadphase; - } - - GameLib.D3.API.Broadphase.call( - this, - apiBroadphase.id, - apiBroadphase.name, - apiBroadphase.broadphaseType, - apiBroadphase.parentEntity - ); - - GameLib.Component.call(this); -}; - -GameLib.D3.Broadphase.prototype = Object.create(GameLib.D3.API.Broadphase.prototype); -GameLib.D3.Broadphase.prototype.constructor = GameLib.D3.Broadphase; - -/** - * Broadphase Types - * @type {number} - */ -GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE = 0x1; -GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID = 0x2; -GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP = 0x3; - -/** - * - * @returns {*} - */ -GameLib.D3.Broadphase.prototype.createInstance = function() { - - if (this.broadphaseType === GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE) { - this.instance = new CANNON.NaiveBroadphase(); - } else if (this.broadphaseType === GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID) { - this.instance = new CANNON.GridBroadphase(); - } else if (this.broadphaseType === GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP) { - this.instance = new CANNON.SAPBroadphase(); - } else { - console.warn('Unsupported broadphase type: ' + this.broadphaseType); - throw new Error('Unsupported broadphase type: ' + this.broadphaseType); - } - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * - */ -GameLib.D3.Broadphase.prototype.updateInstance = function() { - - if (this.broadphaseType === GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE) { - if (!(this.instance instanceof CANNON.NaiveBroadphase)) { - this.createInstance(); - } - } - - if (this.broadphaseType === GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID) { - if (!(this.instance instanceof CANNON.GridBroadphase)) { - this.createInstance(); - } - } - - if (this.broadphaseType === GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP) { - if (!(this.instance instanceof CANNON.SAPBroadphase)) { - this.createInstance(); - } - } -}; - -/** - * GameLib.D3.Broadphase to GameLib.D3.API.Broadphase - * @returns {GameLib.D3.API.Broadphase} - */ -GameLib.D3.Broadphase.prototype.toApiObject = function() { - - var apiBroadphase = new GameLib.D3.API.Broadphase( - this.id, - this.name, - this.broadphaseType, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiBroadphase; -}; - -/** - * GameLib.D3.Broadphase from Object Broadphase - * @param graphics - * @param objectComponent - * @returns {GameLib.D3.Broadphase} - * @constructor - */ -GameLib.D3.Broadphase.FromObject = function(graphics, objectComponent) { - - var apiBroadphase = GameLib.D3.API.Broadphase.FromObject(objectComponent); - - return new GameLib.D3.Broadphase( - graphics, - apiBroadphase - ); -}; -/** - * Creates a Camera object - * @param graphics GameLib.GraphicsRuntime - * @param apiCamera GameLib.D3.API.Camera - * @constructor - */ -GameLib.D3.Camera = function( - graphics, - apiCamera -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiCamera)) { - apiCamera = {}; - } - - if (apiCamera instanceof GameLib.D3.Camera) { - return apiCamera; - } - - GameLib.D3.API.Camera.call( - this, - apiCamera.id, - apiCamera.cameraType, - apiCamera.name, - apiCamera.fov, - apiCamera.aspect, - apiCamera.near, - apiCamera.far, - apiCamera.position, - apiCamera.lookAt, - apiCamera.minX, - apiCamera.maxX, - apiCamera.minY, - apiCamera.maxY, - apiCamera.minZ, - apiCamera.maxZ, - apiCamera.offsetX, - apiCamera.offsetY, - apiCamera.quaternion, - apiCamera.eyeSeparation, - apiCamera.focalLength, - apiCamera.parentEntity - ); - - if (this.position instanceof GameLib.API.Vector3) { - this.position = new GameLib.Vector3( - graphics, - this.position, - this - ); - } else { - console.warn('position not instance of API.Vector3'); - throw new Error('position not instance of API.Vector3'); - } - - if (this.quaternion instanceof GameLib.API.Quaternion) { - this.quaternion = new GameLib.Quaternion( - graphics, - this.quaternion, - this - ); - } else { - console.warn('quaternion not instance of API.Quaternion'); - throw new Error('quaternion not instance of API.Quaternion'); - } - - if (this.lookAt instanceof GameLib.API.Vector3) { - this.lookAt = new GameLib.Vector3( - graphics, - this.lookAt, - this - ); - } else { - console.warn('lookAt not instance of API.Vector3'); - throw new Error('lookAt not instance of API.Vector3'); - } - - GameLib.Component.call( - this, - GameLib.Component.CAMERA - ); - -} ; - -GameLib.D3.Camera.prototype = Object.create(GameLib.D3.API.Camera.prototype); -GameLib.D3.Camera.prototype.constructor = GameLib.D3.Camera; - -GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE = 0x1; -GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL = 0x2; -GameLib.D3.Camera.CAMERA_TYPE_STEREO = 0x3; - -/** - * Creates a camera instance of 'graphics' type (only THREE for now) - * @returns {THREE.Camera} - */ -GameLib.D3.Camera.prototype.createInstance = function() { - - if (this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE ) { - this.instance = new THREE.PerspectiveCamera( - this.fov, - this.aspect, - this.near, - this.far - ); - } else if (this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL) { - this.instance = new THREE.OrthographicCamera( - this.minX + this.offsetX, - this.maxX + this.offsetX, - this.maxY, - this.minY, - this.minZ, - this.maxZ - ); - } else if (this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_STEREO) { - this.instance = new THREE.StereoCamera(); - } else { - throw new Error('unsupported camera type : ' + this.cameraType); - } - - this.instance.position.x = this.position.x; - this.instance.position.y = this.position.y; - this.instance.position.z = this.position.z; - - this.instance.quaternion.x = this.quaternion.x; - this.instance.quaternion.y = this.quaternion.y; - this.instance.quaternion.z = this.quaternion.z; - this.instance.quaternion.w = this.quaternion.w; - - this.instance.lookAt(this.lookAt.instance); - - this.instance.updateProjectionMatrix(); - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.D3.Camera.prototype.updateInstance = function(property) { - - if (GameLib.Utils.UndefinedOrNull(property)) { - console.warn('no camera property specified for : ' + this.name); - } - - if (property === 'cameraType') { - if ( - this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL && - !(this.instance instanceof THREE.OrthographicCamera) - ) { - this.createInstance(); - } - - if ( - this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE && - !(this.instance instanceof THREE.PerspectiveCamera) - ) { - this.createInstance(); - } - } - - if ( - property === 'aspect' || - property === 'minX' || - property === 'maxX' || - property === 'minY' || - property === 'maxY' || - property === 'minZ' || - property === 'maxZ' || - property === 'offsetX' || - property === 'offsetY' || - property === 'fov' || - property === 'near' || - property === 'far' || - property === 'eyeSeparation' || - property === 'focalLength' - ) { - - if (this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL) { - - this.minX = this.aspect * this.minY; - this.maxX = this.aspect * this.maxY; - - this.instance.left = this.minX + this.offsetX; - this.instance.right = this.maxX + this.offsetX; - - this.instance.bottom = this.minY + this.offsetY; - this.instance.top = this.maxY + this.offsetY; - - this.instance.near = this.minZ; - this.instance.far = this.maxZ; - } - - if ( - this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE || - this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_STEREO - ) { - this.instance.fov = this.fov; - this.instance.aspect = this.aspect; - this.instance.near = this.near; - this.instance.far = this.far; - } - - if (this.cameraType === GameLib.D3.Camera.CAMERA_TYPE_STEREO) { - this.instance.eyeSeparation = this.eyeSeparation; - this.instance.focalLength = this.focalLength; - this.instance.update(this.instance); - } - } - - if (property === 'position') { - this.instance.position.x = this.position.x; - this.instance.position.y = this.position.y; - this.instance.position.z = this.position.z; - } - - if (property === 'quaternion') { - this.instance.quaternion.x = this.quaternion.x; - this.instance.quaternion.y = this.quaternion.y; - this.instance.quaternion.z = this.quaternion.z; - this.instance.quaternion.w = this.quaternion.w; - } - - if (property === 'lookAt') { - this.lookAt.instance.x = this.lookAt.x; - this.lookAt.instance.y = this.lookAt.y; - this.lookAt.instance.z = this.lookAt.z; - this.instance.lookAt(this.lookAt.instance); - } - - this.instance.updateProjectionMatrix(); -}; - -/** - * Resize default - * @param width - * @param height - */ -GameLib.D3.Camera.prototype.resize = function(width, height) { - camera.aspect = width / height; - camera.updateInstance(); -}; - -/** - * Converts a GameLib.D3.Camera to a new GameLib.D3.API.Camera - * @returns {GameLib.D3.API.Camera} - */ -GameLib.D3.Camera.prototype.toApiObject = function() { - - return new GameLib.D3.API.Camera( - this.id, - this.cameraType, - this.name, - this.fov, - this.aspect, - this.near, - this.far, - this.position.toApiObject(), - this.lookAt.toApiObject(), - this.minX, - this.maxX, - this.minY, - this.maxY, - this.minZ, - this.maxZ, - this.offsetX, - this.offsetY, - this.quaternion.toApiObject(), - this.eyeSeparation, - this.focalLength, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - -}; - -/** - * Converts from an Object Camera to a GameLib.D3.Camera - * @param graphics GameLib.GraphicsRuntime - * @param objectCamera Object - * @returns {GameLib.D3.Camera} - * @constructor - */ -GameLib.D3.Camera.FromObject = function(graphics, objectCamera) { - - var apiCamera = GameLib.D3.API.Camera.FromObject(objectCamera); - - return new GameLib.D3.Camera( - graphics, - apiCamera - ); - -}; - -/** - * Renders a scene with a camera - * @param graphics GameLib.GraphicsRuntime - * @param apiComposer GameLib.D3.API.Composer - * @constructor - */ -GameLib.D3.Composer = function ( - graphics, - apiComposer -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiComposer)) { - apiComposer = {}; - } - - if (apiComposer instanceof GameLib.D3.Composer) { - return apiComposer; - } - - GameLib.D3.API.Composer.call( - this, - apiComposer.id, - apiComposer.name, - apiComposer.renderer, - apiComposer.renderTarget, - apiComposer.passes, - apiComposer.parentEntity - ); - - GameLib.Component.call( - this, - { - 'renderer' : GameLib.D3.Renderer, - 'renderTarget' : GameLib.D3.RenderTarget, - 'passes' : [GameLib.D3.Pass] - } - ); -}; - -GameLib.D3.Composer.prototype = Object.create(GameLib.D3.API.Composer.prototype); -GameLib.D3.Composer.prototype.constructor = GameLib.D3.Composer; - -/** - * Creates a Composer instance - * @returns {*} - */ -GameLib.D3.Composer.prototype.createInstance = function() { - - //TODO : Fix this too - make it nice (no circular references) - // var instance = null; - // - // if (update) { - // instance = this.instance; - // } - - //TODO : Fix this still (renderer and renderTarget should be objects) - // if (this.renderer && - // this.renderTarget) { - // - // if (!THREE.EffectComposer) { - // console.warn('No THREE.EffectComposer'); - // throw new Error('No THREE.EffectComposer'); - // } - // - // instance = new THREE.EffectComposer( - // this.renderer.instance, - // this.renderTarget.instance - // ); - // - // this.passes.map( - // function(pass) { - // this.instance.addPass(pass.instance); - // }.bind(this) - // ); - // } - console.log('GameLib.D3.Composer.prototype.createInstance() - fix me'); - - GameLib.Component.prototype.createInstance.call(this); - - //return instance; -}; - -/** - * Updates Composer instance - */ -GameLib.D3.Composer.prototype.updateInstance = function() { - console.log('GameLib.D3.Composer.prototype.updateInstance() - fix me'); -}; - -/** - * GameLib.D3.Composer to GameLib.D3.API.Composer - * @returns {GameLib.D3.API.Composer} - */ -GameLib.D3.Composer.prototype.toApiObject = function() { - - var apiComposer = new GameLib.D3.API.Composer( - this.id, - this.name, - GameLib.Utils.IdOrNull(this.renderer), - GameLib.Utils.IdOrNull(this.renderTarget), - this.passes.map( - function(pass) { - return GameLib.Utils.IdOrNull(pass); - } - ), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiComposer; -}; - -/** - * - * @param graphics - * @param objectComponent - * @returns {GameLib.D3.Composer} - * @constructor - */ -GameLib.D3.Composer.FromObject = function(graphics, objectComponent) { - - var apiComposer = GameLib.D3.API.Composer.FromObject(objectComponent); - - return new GameLib.D3.Composer( - graphics, - apiComposer - ); -}; - -/** - * Face - * @constructor - * @param implementation - * @param apiFace - */ -GameLib.D3.Face = function Face( - implementation, - apiFace -) { - - this.implementation = implementation; - if (implementation instanceof GameLib.GraphicsRuntime) { - this.implementation.isNotThreeThrow(); - } else if (implementation instanceof GameLib.PhysicsRuntime) { - this.implementation.isNotCannonThrow(); - } else { - throw new Error('Unhandled implementation : ' + implementation); - } - - if (GameLib.Utils.UndefinedOrNull(apiFace)) { - apiFace = {}; - } - - if (apiFace instanceof GameLib.D3.Face) { - return apiFace; - } - - GameLib.D3.API.Face.call( - this, - apiFace.id, - apiFace.name, - apiFace.v0index, - apiFace.v1index, - apiFace.v2index, - apiFace.materialIndex, - apiFace.uvs, - apiFace.color, - apiFace.vertexColors, - apiFace.vertexNormals, - apiFace.normal - ); - - if (this.implementation instanceof GameLib.GraphicsRuntime) { - /** - * physics faces have no color... a little sad right? - */ - this.color = new GameLib.Color( - this.implementation, - this.color, - this - ); - - this.vertexColors = this.vertexColors.map(function(vertexColor){ - if (vertexColor instanceof GameLib.Color) { - return vertexColor; - } - - if (vertexColor instanceof GameLib.API.Color) { - return new GameLib.Color( - this.implementation, - vertexColor, - this - ) - } - - console.warn('unknown vertex color type', vertexColor); - }.bind(this)); - - } - - this.vertexNormals = this.vertexNormals.map(function(vertexNormal){ - if (vertexNormal instanceof GameLib.Vector3) { - return vertexNormal; - } - - if (vertexNormal instanceof GameLib.API.Vector3) { - return new GameLib.Vector3( - this.implementation, - vertexNormal, - this - ) - } - - console.warn('unknown vertex normal type', vertexNormal); - }.bind(this)); - - this.uvs = this.uvs.reduce( - - function(result, uvArray, index) { - - result[index] = uvArray.reduce( - function(uvResult, uv) { - - if (uv instanceof GameLib.API.Vector2) { - uvResult.push( - new GameLib.Vector2( - this.implementation, - uv, - this - ) - ); - } else { - console.warn('unknown uv type'); - } - - return uvResult; - }.bind(this), - [] - ); - - return result; - - - }.bind(this), - [] - ); - - this.normal = new GameLib.Vector3( - this.implementation, - this.normal, - this - ); - -}; - -GameLib.D3.Face.prototype = Object.create(GameLib.D3.API.Face.prototype); -GameLib.D3.Face.prototype.constructor = GameLib.D3.Face; - -GameLib.D3.Face.prototype.createInstance = function() { - -}; - -GameLib.D3.Face.prototype.updateInstance = function() { - -}; - -GameLib.D3.Face.prototype.toApiObject = function() { - - return new GameLib.D3.API.Face( - this.id, - this.name, - this.v0index, - this.v1index, - this.v2index, - this.materialIndex, - this.uvs.reduce( - function(result, uvArray, index) { - - result[index] = uvArray.reduce( - function(uvResult, uv) { - - if (uv instanceof GameLib.Vector2) { - uvResult.push(uv.toApiObject()); - } else { - console.warn('unknown uv type - cannot commit to API'); - } - - return uvResult; - }.bind(this), - [] - ); - - return result; - - }.bind(this), - [] - ), - this.color.toApiObject(), - this.vertexColors.map(function(vertexColor){ - return vertexColor.toApiObject(); - }), - this.vertexNormals.map(function(vertexNormal){ - return vertexNormal.toApiObject(); - }), - this.normal.toApiObject() - ); -}; - -/** - * @param implementation - * @param objectFace - * @returns {GameLib.D3.Face} - * @constructor - */ -GameLib.D3.Face.FromObject = function(implementation, objectFace) { - return new GameLib.D3.Face( - implementation, - GameLib.D3.API.Face.FromObject(objectFace) - ); -}; - - -/** - * Fog Superset - The apiFog properties get moved into the Fog object itself, and then the instance is - * created - * @param graphics - * @param apiFog GameLib.D3.API.Fog - * @constructor - */ -GameLib.D3.Fog = function ( - graphics, - apiFog -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiFog)) { - apiFog = {}; - } - - if (apiFog instanceof GameLib.D3.Fog) { - return apiFog; - } - - GameLib.D3.API.Fog.call( - this, - apiFog.id, - apiFog.name, - apiFog.exponential, - apiFog.color, - apiFog.near, - apiFog.far, - apiFog.density, - apiFog.parentEntity - ); - - this.color = new GameLib.Color( - this.graphics, - this.color, - this - ); - - GameLib.Component.call(this); -}; - -GameLib.D3.Fog.prototype = Object.create(GameLib.D3.API.Fog.prototype); -GameLib.D3.Fog.prototype.constructor = GameLib.D3.Fog; - -/** - * Creates an instance scene - * @returns {THREE.Fog} - */ -GameLib.D3.Fog.prototype.createInstance = function() { - - if (this.exponential) { - - this.instance = new THREE.FogExp2( - this.color.instance, - this.density - ); - - } else { - - this.instance = new THREE.Fog( - this.color.instance, - this.near, - this.far - ); - - } - - this.instance.name = this.name; - - GameLib.Component.prototype.createInstance.call(this); - -}; - -GameLib.D3.Fog.prototype.updateInstance = function(property) { - - if (property === 'exponential') { - if ( - this.exponential && - !(this.instance instanceof THREE.FogExp2) - ) { - this.createInstance(); - return; - } - - if ( - !this.exponential && - !(this.instance instanceof THREE.Fog) - ) { - this.createInstance(); - return; - } - } - - if (property === 'color') { - this.color.instance.setRGB( - this.color.r, - this.color.g, - this.color.b - ); - this.instance.color = this.color.instance; - } - - if (property === 'near' || property === 'far') { - if (this.instance instanceof THREE.Fog) { - this.instance.near = this.near; - this.instance.far = this.far; - } - } - - if (property === 'density') { - if (this.instance instanceof THREE.FogExp2) { - this.instance.density = this.density; - } - } - -}; - -/** - * Converts a GameLib.D3.Fog to a GameLib.D3.API.Fog - * @returns {GameLib.D3.API.Fog} - */ -GameLib.D3.Fog.prototype.toApiObject = function() { - - return new GameLib.D3.API.Fog( - this.id, - this.name, - this.exponential, - this.color.toApiObject(), - this.near, - this.far, - this.density, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - -}; - -/** - * Converts a scene Object to a GameLib.D3.Fog object - * @param graphics GameLib.GraphicsRuntime - * @param objectFog Object - * @returns {GameLib.D3.Fog} - * @constructor - */ -GameLib.D3.Fog.FromObject = function( - graphics, - objectFog -) { - var apiFog = GameLib.D3.API.Fog.FromObject(objectFog); - - return new GameLib.D3.Fog( - graphics, - apiFog - ); -}; - -/** - * Font Superset - The apiFont properties get moved into the Font object itself, and then the instance is created - * @param graphics GameLib.GraphicsRuntime - * @param apiFont GameLib.D3.API.Font - * @constructor - */ -GameLib.D3.Font = function( - graphics, - apiFont -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiFont)) { - apiFont = {}; - } - - if (apiFont instanceof GameLib.D3.Font) { - return apiFont; - } - - GameLib.D3.API.Font.call( - this, - apiFont.id, - apiFont.name, - apiFont.url, - apiFont.parentEntity - ); - - GameLib.Component.call(this); -}; - -GameLib.D3.Font.prototype = Object.create(GameLib.D3.API.Font.prototype); -GameLib.D3.Font.prototype.constructor = GameLib.D3.Font; - -/** - * Creates a light instance - * @returns {*} - */ -GameLib.D3.Font.prototype.createInstance = function() { - - GameLib.Event.Emit( - GameLib.Event.LOAD_FONT, - { - font : this - }, - function(fontInstance) { - this.instance = fontInstance; - GameLib.Component.prototype.createInstance.call(this); - }.bind(this), - function(error) { - console.error(error); - this.instance = null; - GameLib.Component.prototype.createInstance.call(this); - }.bind(this) - ); - -}; - -/** - * Updates the instance with the current state - */ -GameLib.D3.Font.prototype.updateInstance = function() { - - GameLib.Event.Emit( - GameLib.Event.LOAD_FONT, - { - font : this - } - ); -}; - -/** - * Converts a GameLib.D3.Font to a GameLib.D3.API.Font - * @returns {GameLib.D3.API.Font} - */ -GameLib.D3.Font.prototype.toApiObject = function() { - return new GameLib.D3.API.Font( - this.id, - this.name, - this.url, - GameLib.Utils.IdOrNull(this.parentEntity) - ); -}; - -/** - * Returns a new GameLib.D3.Font from a GameLib.D3.API.Font - * @param graphics GameLib.GraphicsRuntime - * @param objectFont GameLib.D3.API.Font - * @returns {GameLib.D3.Font} - */ -GameLib.D3.Font.FromObject = function(graphics, objectFont) { - - return new GameLib.D3.Font( - graphics, - GameLib.D3.API.Font.FromObject(objectFont) - ); - -}; -/** - * FrictionContactMaterial Runtime - * @param physics GameLib.GraphicsRuntime - * @param apiFrictionContactMaterial GameLib.D3.API.FrictionContactMaterial - * @constructor - */ -GameLib.D3.FrictionContactMaterial = function ( - physics, - apiFrictionContactMaterial -) { - - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiFrictionContactMaterial)) { - apiFrictionContactMaterial = {}; - } - - if (apiFrictionContactMaterial instanceof GameLib.D3.FrictionContactMaterial) { - return apiFrictionContactMaterial; - } - - GameLib.D3.API.FrictionContactMaterial.call( - this, - apiFrictionContactMaterial.id, - apiFrictionContactMaterial.name, - apiFrictionContactMaterial.materials, - apiFrictionContactMaterial.friction, - apiFrictionContactMaterial.restitution, - apiFrictionContactMaterial.contactEquationStiffness, - apiFrictionContactMaterial.contactEquationRelaxation, - apiFrictionContactMaterial.frictionEquationStiffness, - apiFrictionContactMaterial.frictionEquationRelaxation, - apiFrictionContactMaterial.parentEntity - ); - - GameLib.Component.call( - this, - { - materials : [GameLib.D3.FrictionMaterial] - } - ); -}; - -GameLib.D3.FrictionContactMaterial.prototype = Object.create(GameLib.D3.API.FrictionContactMaterial.prototype); -GameLib.D3.FrictionContactMaterial.prototype.constructor = GameLib.D3.FrictionContactMaterial; - -/** - * - * @returns {*} - */ -GameLib.D3.FrictionContactMaterial.prototype.createInstance = function() { - - this.instance = new CANNON.ContactMaterial( - null, - null, - { - friction: this.friction, - restitution: this.restitution, - contactEquationStiffness: this.contactEquationStiffness - } - ); - - this.instance.materials = this.materials.map( - function(material){ - return material.instance; - } - ); - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * - */ -GameLib.D3.FrictionContactMaterial.prototype.updateInstance = function() { - - this.instance.materials = this.materials.map( - function(material) { - return material.instance; - } - ); - - this.instance.friction = this.friction; - this.instance.restitution = this.restitution; - this.instance.contactEquationStiffness = this.contactEquationStiffness; - this.instance.contactEquationRelaxation = this.contactEquationRelaxation; - this.instance.frictionEquationStiffness = this.frictionEquationStiffness; - this.instance.frictionEquationRelaxation = this.frictionEquationRelaxation; - -}; - -/** - * GameLib.D3.FrictionContactMaterial to GameLib.D3.API.FrictionContactMaterial - * @returns {GameLib.D3.API.FrictionContactMaterial} - */ -GameLib.D3.FrictionContactMaterial.prototype.toApiObject = function() { - - var apiFrictionContactMaterial = new GameLib.D3.API.FrictionContactMaterial( - this.id, - this.name, - this.materials.map( - function(material) { - return GameLib.Utils.IdOrNull(material); - } - ), - this.friction, - this.restitution, - this.contactEquationStiffness, - this.contactEquationRelaxation, - this.frictionEquationStiffness, - this.frictionEquationRelaxation, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - return apiFrictionContactMaterial; -}; - -/** - * GameLib.D3.FrictionContactMaterial from Object FrictionContactMaterial - * @param physics - * @param objectComponent - * @returns {GameLib.D3.FrictionContactMaterial} - * @constructor - */ -GameLib.D3.FrictionContactMaterial.FromObject = function(physics, objectComponent) { - - var apiFrictionContactMaterial = GameLib.D3.API.FrictionContactMaterial.FromObject(objectComponent); - - return new GameLib.D3.FrictionContactMaterial( - physics, - apiFrictionContactMaterial - ); -}; - -/** - * FrictionMaterial Runtime - * @param physics GameLib.GraphicsRuntime - * @param apiFrictionMaterial GameLib.D3.API.FrictionMaterial - * @constructor - */ -GameLib.D3.FrictionMaterial = function ( - physics, - apiFrictionMaterial -) { - - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiFrictionMaterial)) { - apiFrictionMaterial = {}; - } - - if (apiFrictionMaterial instanceof GameLib.D3.FrictionMaterial) { - return apiFrictionMaterial; - } - - GameLib.D3.API.FrictionMaterial.call( - this, - apiFrictionMaterial.id, - apiFrictionMaterial.name, - apiFrictionMaterial.friction, - apiFrictionMaterial.restitution, - apiFrictionMaterial.parentEntity - ); - - GameLib.Component.call(this); -}; - -GameLib.D3.FrictionMaterial.prototype = Object.create(GameLib.D3.API.FrictionMaterial.prototype); -GameLib.D3.FrictionMaterial.prototype.constructor = GameLib.D3.FrictionMaterial; - -/** - * create instance - */ -GameLib.D3.FrictionMaterial.prototype.createInstance = function() { - - this.instance = new CANNON.Material( - this.name - ); - - this.instance.friction = this.friction; - this.instance.restitution = this.restitution; - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * - */ -GameLib.D3.FrictionMaterial.prototype.updateInstance = function() { - this.instance.friction = this.friction; - this.instance.restitution = this.restitution; - this.instance.name = this.name; -}; - -/** - * GameLib.D3.FrictionMaterial to GameLib.D3.API.FrictionMaterial - * @returns {GameLib.D3.API.FrictionMaterial} - */ -GameLib.D3.FrictionMaterial.prototype.toApiObject = function() { - - var apiFrictionMaterial = new GameLib.D3.API.FrictionMaterial( - this.id, - this.name, - this.friction, - this.restitution, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiFrictionMaterial; -}; - -/** - * GameLib.D3.FrictionMaterial from Object FrictionMaterial - * @param physics - * @param objectComponent - * @returns {GameLib.D3.FrictionMaterial} - * @constructor - */ -GameLib.D3.FrictionMaterial.FromObject = function(physics, objectComponent) { - - var apiFrictionMaterial = GameLib.D3.API.FrictionMaterial.FromObject(objectComponent); - - return new GameLib.D3.FrictionMaterial( - physics, - apiFrictionMaterial - ); -}; - -/** - * Helpers for displaying outlines or making 'invisible' scene objects visible - * @param graphics GameLib.GraphicsRuntime - * @param id - * @param name - * @param object - * @param helperType - * @param parentEntity - * @constructor - */ -GameLib.D3.Helper = function( - graphics, - id, - name, - object, - helperType, - parentEntity -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Helper (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(object)) { - console.warn('Cannot create a helper for an Object which does not exist'); - throw new Error('Cannot create a helper for an Object which does not exist'); - } - this.object = object; - - if (GameLib.Utils.UndefinedOrNull(helperType)) { - - helperType = GameLib.D3.Helper.HELPER_TYPE_NONE; - - if ( - object instanceof GameLib.D3.Mesh && - object.meshType !== GameLib.D3.API.Mesh.MESH_TYPE_CURVE - ) { - helperType = GameLib.D3.Helper.HELPER_TYPE_EDGES; - } - - if (object instanceof GameLib.D3.Light) { - if (object.lightType === GameLib.D3.Light.LIGHT_TYPE_DIRECTIONAL) { - helperType = GameLib.D3.Helper.HELPER_TYPE_DIRECTIONAL_LIGHT; - } - - if (object.lightType === GameLib.D3.Light.LIGHT_TYPE_POINT) { - helperType = GameLib.D3.Helper.HELPER_TYPE_POINT_LIGHT; - } - - if (object.lightType === GameLib.D3.Light.LIGHT_TYPE_SPOT) { - helperType = GameLib.D3.Helper.HELPER_TYPE_SPOT_LIGHT; - } - } - - if (object instanceof GameLib.D3.Skeleton) { - helperType = GameLib.D3.Helper.HELPER_TYPE_SKELETON; - } - } - this.helperType = helperType; - - if (GameLib.Utils.UndefinedOrNull(parentEntity)) { - parentEntity = null; - } - this.parentEntity = parentEntity; - - this.createInstance(); - /** - * A helper as a component - does this make sense at all? - */ - // GameLib.Component.call( - // this, - // GameLib.Component.HELPER - // ); -}; - -GameLib.D3.Helper.prototype = Object.create(GameLib.Component.prototype); -GameLib.D3.Helper.prototype.constructor = GameLib.D3.Helper; - -/** - * Helper types - * @type {string} - */ -GameLib.D3.Helper.HELPER_TYPE_NONE = 0x0; -GameLib.D3.Helper.HELPER_TYPE_EDGES = 0x1; -GameLib.D3.Helper.HELPER_TYPE_DIRECTIONAL_LIGHT = 0x2; -GameLib.D3.Helper.HELPER_TYPE_SPOT_LIGHT = 0x3; -GameLib.D3.Helper.HELPER_TYPE_POINT_LIGHT = 0x4; -GameLib.D3.Helper.HELPER_TYPE_WIREFRAME = 0x5; -GameLib.D3.Helper.HELPER_TYPE_SKELETON = 0x6; - -/** - * Creates a helper instance - */ -GameLib.D3.Helper.prototype.createInstance = function() { - - if (this.helperType === GameLib.D3.Helper.HELPER_TYPE_EDGES) { - this.instance = new THREE.LineSegments( - new THREE.EdgesGeometry( - this.object.instance.geometry - ), - new THREE.LineBasicMaterial( - { - color:0x00ff00, - linewidth:2 - } - ) - ) - } - - if (this.helperType === GameLib.D3.Helper.HELPER_TYPE_DIRECTIONAL_LIGHT) { - this.instance = new THREE.DirectionalLightHelper(this.object.instance); - } - - if (this.helperType === GameLib.D3.Helper.HELPER_TYPE_POINT_LIGHT) { - this.instance = new THREE.PointLightHelper(this.object.instance, 1); - } - - if (this.helperType === GameLib.D3.Helper.HELPER_TYPE_SPOT_LIGHT) { - this.instance = new THREE.SpotLightHelper(this.object.instance); - } - - if (this.helperType === GameLib.D3.Helper.HELPER_TYPE_WIREFRAME) { - this.instance = new THREE.WireframeGeometry(this.object.instance, 0x00FF00); - } - - if (this.helperType === GameLib.D3.Helper.HELPER_TYPE_SKELETON) { - this.instance = new THREE.SkeletonHelper(this.object.instance); - } - -}; - -/** - * Updates the instance with the current state - */ -GameLib.D3.Helper.prototype.updateInstance = function() { - this.instance.position.copy(this.object.instance.position); - - if (this.object.instance.parentMesh && this.object.instance.parentMesh.instance) { - this.instance.position.add(this.object.instance.parentMesh.instance.position); - } - - this.instance.scale.copy(this.object.instance.scale); - this.instance.quaternion.copy(this.object.instance.quaternion); -}; - -/** - * Light Superset - The apiLight properties get moved into the Light object itself, and then the instance is created - * @param graphics GameLib.GraphicsRuntime - * @param apiLight GameLib.D3.API.Light - * @constructor - */ -GameLib.D3.Light = function( - graphics, - apiLight -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiLight)) { - apiLight = {}; - } - - if (apiLight instanceof GameLib.D3.Light) { - return apiLight; - } - - GameLib.D3.API.Light.call( - this, - apiLight.id, - apiLight.lightType, - apiLight.name, - apiLight.color, - apiLight.intensity, - apiLight.position, - apiLight.targetPosition, - apiLight.quaternion, - apiLight.rotation, - apiLight.scale, - apiLight.distance, - apiLight.decay, - apiLight.power, - apiLight.angle, - apiLight.penumbra, - apiLight.parentScene, - apiLight.parentEntity - ); - - this.color = new GameLib.Color( - graphics, - this.color, - this - ); - - this.position = new GameLib.Vector3( - graphics, - this.position, - this - ); - - this.targetPosition = new GameLib.Vector3( - graphics, - this.targetPosition, - this - ); - - this.scale = new GameLib.Vector3( - graphics, - this.scale, - this - ); - - this.quaternion = new GameLib.Quaternion( - graphics, - this.quaternion, - this - ); - - this.rotation = new GameLib.Vector3( - graphics, - this.rotation, - this - ); - - GameLib.Component.call( - this, - { - 'parentScene' : GameLib.D3.Scene - } - ); -}; - -GameLib.D3.Light.prototype = Object.create(GameLib.D3.API.Light.prototype); -GameLib.D3.Light.prototype.constructor = GameLib.D3.Light; - -/** - * Light Types - * @type {number} - */ -GameLib.D3.Light.LIGHT_TYPE_AMBIENT = 0x1; -GameLib.D3.Light.LIGHT_TYPE_DIRECTIONAL = 0x2; -GameLib.D3.Light.LIGHT_TYPE_POINT = 0x3; -GameLib.D3.Light.LIGHT_TYPE_SPOT = 0x4; - -/** - * Creates a light instance - * @returns {*} - */ -GameLib.D3.Light.prototype.createInstance = function() { - - if ( - this.lightType === GameLib.D3.Light.LIGHT_TYPE_AMBIENT || - this.lightType === 'AmbientLight' - ) { - this.instance = new THREE.AmbientLight( - this.color.instance, - this.intensity - ); - } else if ( - this.lightType === GameLib.D3.Light.LIGHT_TYPE_DIRECTIONAL || - this.lightType === 'DirectionalLight' - ) { - this.instance = new THREE.DirectionalLight( - this.color.instance, - this.intensity - ); - } else if ( - this.lightType === GameLib.D3.Light.LIGHT_TYPE_POINT || - this.lightType === 'PointLight' - ) { - this.instance = new THREE.PointLight( - this.color.instance, - this.intensity - ); - this.instance.distance = this.distance; - this.instance.decay = this.decay; - } else if ( - this.lightType === GameLib.D3.Light.LIGHT_TYPE_SPOT || - this.lightType === 'SpotLight' - ) { - this.instance = new THREE.SpotLight( - this.color.instance, - this.intensity - ); - this.instance.distance = this.distance; - this.instance.angle = this.angle; - this.instance.penumbra = this.penumbra; - this.instance.decay = this.decay; - } else { - console.warn('unsupported light type: ' + this.lightType); - return; - } - - this.instance.name = this.name; - - this.instance.position.x = this.position.x; - this.instance.position.y = this.position.y; - this.instance.position.z = this.position.z; - - this.instance.scale.x = this.scale.x; - this.instance.scale.y = this.scale.y; - this.instance.scale.z = this.scale.z; - - if (this.instance.target) { - this.instance.target.position.x = this.targetPosition.x; - this.instance.target.position.y = this.targetPosition.y; - this.instance.target.position.z = this.targetPosition.z; - } - - this.instance.quaternion.x = this.quaternion.x; - this.instance.quaternion.y = this.quaternion.y; - this.instance.quaternion.z = this.quaternion.z; - this.instance.quaternion.w = this.quaternion.w; - - this.instance.intensity = this.intensity; - - this.instance.color.set(this.color.toHex()); - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.D3.Light.prototype.updateInstance = function(property) { - - if (GameLib.Utils.UndefinedOrNull(property)) { - console.warn('no property for light: ' + this.name); - } - - if (property === 'lightType') { - this.parentScene.instance.remove(this.instance); - this.createInstance(); - this.parentScene.instance.add(this.instance); - } - - if (property === 'name') { - this.instance.name = this.name; - } - - if (property === 'position') { - this.instance.position.x = this.position.x; - this.instance.position.y = this.position.y; - this.instance.position.z = this.position.z; - } - - if (property === 'scale') { - this.instance.scale.x = this.scale.x; - this.instance.scale.y = this.scale.y; - this.instance.scale.z = this.scale.z; - } - - if (property === 'target') { - if (this.instance.target) { - this.instance.target.position.x = this.targetPosition.x; - this.instance.target.position.y = this.targetPosition.y; - this.instance.target.position.z = this.targetPosition.z; - } - } - - if (property === 'quaternion') { - this.instance.quaternion.x = this.quaternion.x; - this.instance.quaternion.y = this.quaternion.y; - this.instance.quaternion.z = this.quaternion.z; - this.instance.quaternion.w = this.quaternion.w; - } - - if (property === 'intensity') { - this.instance.intensity = this.intensity; - } - - if (property === 'color') { - this.instance.color.set(this.color.toHex()); - } -}; - -/** - * Converts a GameLib.D3.Light to a GameLib.D3.API.Light - * @returns {GameLib.D3.API.Light} - */ -GameLib.D3.Light.prototype.toApiObject = function() { - return new GameLib.D3.API.Light( - this.id, - this.lightType, - this.name, - this.color.toApiObject(), - this.intensity, - this.position.toApiObject(), - this.targetPosition.toApiObject(), - this.quaternion.toApiObject(), - this.rotation.toApiObject(), - this.scale.toApiObject(), - this.distance, - this.decay, - this.power, - this.angle, - this.penumbra, - GameLib.Utils.IdOrNull(this.parentScene), - GameLib.Utils.IdOrNull(this.parentEntity) - ); -}; - -/** - * Returns a new GameLib.D3.Light from a GameLib.D3.API.Light - * @param graphics GameLib.GraphicsRuntime - * @param objectLight GameLib.D3.API.Light - * @returns {GameLib.D3.Light} - */ -GameLib.D3.Light.FromObject = function(graphics, objectLight) { - - return new GameLib.D3.Light( - graphics, - GameLib.D3.API.Light.FromObject(objectLight) - ); - -}; -/** - * Material Superset - The apiMaterial properties get moved into the Material object itself, and then the instance is - * created - * @param graphics GameLib.GraphicsRuntime - * @param apiMaterial GameLib.D3.API.Material - * @constructor - * @returns {GameLib.D3.Material | GameLib.D3.API.Material} - */ -GameLib.D3.Material = function( - graphics, - apiMaterial -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiMaterial)) { - apiMaterial = {}; - } - - if (apiMaterial instanceof GameLib.D3.Material) { - return apiMaterial; - } - - GameLib.D3.API.Material.call( - this, - apiMaterial.id, - apiMaterial.materialType, - apiMaterial.name, - apiMaterial.opacity, - apiMaterial.side, - apiMaterial.transparent, - apiMaterial.specular, - apiMaterial.lightMapIntensity, - apiMaterial.aoMapIntensity, - apiMaterial.color, - apiMaterial.emissive, - apiMaterial.emissiveIntensity, - apiMaterial.combine, - apiMaterial.shininess, - apiMaterial.reflectivity, - apiMaterial.refractionRatio, - apiMaterial.fog, - apiMaterial.wireframe, - apiMaterial.wireframeLineWidth, - apiMaterial.wireframeLineCap, - apiMaterial.wireframeLineJoin, - apiMaterial.vertexColors, - apiMaterial.skinning, - apiMaterial.morphTargets, - apiMaterial.morphNormals, - apiMaterial.lineWidth, - apiMaterial.lineCap, - apiMaterial.lineJoin, - apiMaterial.dashSize, - apiMaterial.gapWidth, - apiMaterial.blending, - apiMaterial.blendSrc, - apiMaterial.blendDst, - apiMaterial.blendEquation, - apiMaterial.depthTest, - apiMaterial.depthFunc, - apiMaterial.depthWrite, - apiMaterial.polygonOffset, - apiMaterial.polygonOffsetFactor, - apiMaterial.polygonOffsetUnits, - apiMaterial.alphaTest, - apiMaterial.clippingPlanes, - apiMaterial.clipShadows, - apiMaterial.visible, - apiMaterial.overdraw, - apiMaterial.flatShading, - apiMaterial.bumpScale, - apiMaterial.normalScale, - apiMaterial.displacementScale, - apiMaterial.displacementBias, - apiMaterial.roughness, - apiMaterial.metalness, - apiMaterial.pointSize, - apiMaterial.pointSizeAttenuation, - apiMaterial.spriteRotation, - apiMaterial.envMapIntensity, - apiMaterial.alphaMap, - apiMaterial.aoMap, - apiMaterial.bumpMap, - apiMaterial.diffuseMap, - apiMaterial.displacementMap, - apiMaterial.emissiveMap, - apiMaterial.environmentMap, - apiMaterial.lightMap, - apiMaterial.metalnessMap, - apiMaterial.normalMap, - apiMaterial.roughnessMap, - apiMaterial.specularMap, - apiMaterial.parentEntity - ); - - this.specular = new GameLib.Color( - graphics, - this.specular, - this - ); - - this.color = new GameLib.Color( - graphics, - this.color, - this - ); - - this.emissive = new GameLib.Color( - graphics, - this.emissive, - this - ); - - if (this.alphaMap) { - if (this.alphaMap instanceof GameLib.D3.API.Texture) { - this.alphaMap = new GameLib.D3.Texture( - this.graphics, - this.alphaMap - ); - } - } - - if (this.aoMap) { - if (this.aoMap instanceof GameLib.D3.API.Texture) { - this.aoMap = new GameLib.D3.Texture( - this.graphics, - this.aoMap - ); - } - } - - if (this.bumpMap) { - if (this.bumpMap instanceof GameLib.D3.API.Texture) { - this.bumpMap = new GameLib.D3.Texture( - this.graphics, - this.bumpMap - ); - } - } - - if (this.diffuseMap) { - if (this.diffuseMap instanceof GameLib.D3.API.Texture) { - this.diffuseMap = new GameLib.D3.Texture( - this.graphics, - this.diffuseMap - ); - } - } - - if (this.displacementMap) { - if (this.displacementMap instanceof GameLib.D3.API.Texture) { - this.displacementMap = new GameLib.D3.Texture( - this.graphics, - this.displacementMap - ); - } - } - - if (this.emissiveMap) { - if (this.emissiveMap instanceof GameLib.D3.API.Texture) { - this.emissiveMap = new GameLib.D3.Texture( - this.graphics, - this.emissiveMap - ); - } - } - - if (this.environmentMap) { - if (this.environmentMap instanceof GameLib.D3.API.Texture) { - this.environmentMap = new GameLib.D3.Texture( - this.graphics, - this.environmentMap - ); - } - } - - if (this.lightMap) { - if (this.lightMap instanceof GameLib.D3.API.Texture) { - this.lightMap = new GameLib.D3.Texture( - this.graphics, - this.lightMap - ); - } - } - - if (this.metalnessMap) { - if (this.metalnessMap instanceof GameLib.D3.API.Texture) { - this.metalnessMap = new GameLib.D3.Texture( - this.graphics, - this.metalnessMap - ); - } - } - - if (this.normalMap) { - if (this.normalMap instanceof GameLib.D3.API.Texture) { - this.normalMap = new GameLib.D3.Texture( - this.graphics, - this.normalMap - ); - } - } - - if (this.roughnessMap) { - if (this.roughnessMap instanceof GameLib.D3.API.Texture) { - this.roughnessMap = new GameLib.D3.Texture( - this.graphics, - this.roughnessMap - ); - } - } - - if (this.specularMap) { - if (this.specularMap instanceof GameLib.D3.API.Texture) { - this.specularMap = new GameLib.D3.Texture( - this.graphics, - this.specularMap - ); - } - } - - GameLib.Component.call( - this, - { - 'alphaMap' : GameLib.D3.Texture, - 'aoMap' : GameLib.D3.Texture, - 'bumpMap' : GameLib.D3.Texture, - 'diffuseMap' : GameLib.D3.Texture, - 'displacementMap' : GameLib.D3.Texture, - 'emissiveMap' : GameLib.D3.Texture, - 'environmentMap' : GameLib.D3.Texture, - 'lightMap' : GameLib.D3.Texture, - 'metalnessMap' : GameLib.D3.Texture, - 'normalMap' : GameLib.D3.Texture, - 'roughnessMap' : GameLib.D3.Texture, - 'specularMap' : GameLib.D3.Texture - } - ); -}; - -GameLib.D3.Material.prototype = Object.create(GameLib.D3.API.Material.prototype); -GameLib.D3.Material.prototype.constructor = GameLib.D3.Material; - -/** - * Combine Method - * @type {number} - */ -GameLib.D3.Material.TYPE_MULTIPLY_OPERATION = 0; -GameLib.D3.Material.TYPE_MIX_OPERATION = 1; -GameLib.D3.Material.TYPE_ADD_OPERATION = 2; - -/** - * Vertex Color Mode - * @type {number} - */ -GameLib.D3.Material.TYPE_NO_COLORS = 0; -GameLib.D3.Material.TYPE_FACE_COLORS = 1; -GameLib.D3.Material.TYPE_VERTEX_COLORS = 2; - -/** - * Blending Mode - * @type {number} - */ -GameLib.D3.Material.TYPE_NO_BLENDING = 0; -GameLib.D3.Material.TYPE_NORMAL_BLENDING = 1; -GameLib.D3.Material.TYPE_ADDITIVE_BLENDING = 2; -GameLib.D3.Material.TYPE_SUBTRACTIVE_BLENDING = 3; -GameLib.D3.Material.TYPE_MULTIPLY_BLENDING = 4; -GameLib.D3.Material.TYPE_CUSTOM_BLENDING = 5; - -/** - * Blend Source and Destination - * @type {number} - */ -GameLib.D3.Material.TYPE_ZERO_FACTOR = 200; -GameLib.D3.Material.TYPE_ONE_FACTOR = 201; -GameLib.D3.Material.TYPE_SRC_COLOR_FACTOR = 202; -GameLib.D3.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR = 203; -GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR = 204; -GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR = 205; -GameLib.D3.Material.TYPE_DST_ALPHA_FACTOR = 206; -GameLib.D3.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR = 207; -GameLib.D3.Material.TYPE_DST_COLOR_FACTOR = 208; -GameLib.D3.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR = 209; -GameLib.D3.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR = 210; - -/** - * Blend Operation - * @type {number} - */ -GameLib.D3.Material.TYPE_ADD_EQUATION = 100; -GameLib.D3.Material.TYPE_SUBTRACT_EQUATION = 101; -GameLib.D3.Material.TYPE_REVERSE_SUBTRACT_EQUATION = 102; -GameLib.D3.Material.TYPE_MIN_EQUATION = 103; -GameLib.D3.Material.TYPE_MAX_EQUATION = 104; - -/** - * Depth Function - * @type {number} - */ -GameLib.D3.Material.TYPE_NEVER_DEPTH = 0; -GameLib.D3.Material.TYPE_ALWAYS_DEPTH = 1; -GameLib.D3.Material.TYPE_LESS_DEPTH = 2; -GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH = 3; -GameLib.D3.Material.TYPE_EQUAL_DEPTH = 4; -GameLib.D3.Material.TYPE_GREATER_EQUAL_DEPTH = 5; -GameLib.D3.Material.TYPE_GREATER_DEPTH = 6; -GameLib.D3.Material.TYPE_NOT_EQUAL_DEPTH = 7; - -/** - * Culling Mode - * @type {number} - */ -GameLib.D3.Material.TYPE_FRONT_SIDE = 0; -GameLib.D3.Material.TYPE_BACK_SIDE = 1; -GameLib.D3.Material.TYPE_DOUBLE_SIDE = 2; - -/** - * Shading Type - * @type {number} - */ -GameLib.D3.Material.TYPE_FLAT_SHADING = 1; -GameLib.D3.Material.TYPE_SMOOTH_SHADING = 2; - -/** - * Material Type - * @type {string} - */ -GameLib.D3.Material.MATERIAL_TYPE_LINE_BASIC = 0x1; -GameLib.D3.Material.MATERIAL_TYPE_LINE_DASHED = 0x2; -GameLib.D3.Material.MATERIAL_TYPE_BASIC = 0x3; -GameLib.D3.Material.MATERIAL_TYPE_DEPTH = 0x4; -GameLib.D3.Material.MATERIAL_TYPE_LAMBERT = 0x5; -GameLib.D3.Material.MATERIAL_TYPE_NORMAL = 0x6; -GameLib.D3.Material.MATERIAL_TYPE_PHONG = 0x7; -GameLib.D3.Material.MATERIAL_TYPE_STANDARD = 0x8; -GameLib.D3.Material.MATERIAL_TYPE_POINTS = 0x9; -GameLib.D3.Material.MATERIAL_TYPE_SPRITE = 0xa; -GameLib.D3.Material.MATERIAL_TYPE_TOON = 0xb; - -GameLib.D3.Material.LINE_CAP_BUTT = 0x1;//'butt'; -GameLib.D3.Material.LINE_CAP_ROUND = 0x2;//'round'; -GameLib.D3.Material.LINE_CAP_SQUARE = 0x3;//'square'; - -GameLib.D3.Material.LINE_JOIN_ROUND = 0x1;//'round'; -GameLib.D3.Material.LINE_JOIN_BEVEL = 0x2;//'bevel'; -GameLib.D3.Material.LINE_JOIN_MITER = 0x3;//'miter'; - -GameLib.D3.Material.prototype.createToonMaterialInstance = function() { - return new THREE.MeshToonMaterial({ - name: this.name, - opacity: this.opacity, - transparent: this.transparent, - blending: this.blending, - blendSrc: this.blendSrc, - blendDst: this.blendDst, - blendEquation: this.blendEquation, - depthTest: this.depthTest, - depthFunc: this.depthFunc, - depthWrite: this.depthWrite, - polygonOffset: this.polygonOffset, - polygonOffsetFactor: this.polygonOffsetFactor, - polygonOffsetUnits: this.polygonOffsetUnits, - alphaTest: this.alphaTest, - clippingPlanes: this.clippingPlanes, - clipShadows: this.clipShadows, - overdraw: this.overdraw, - visible: this.visible, - side: this.side, - color: this.color.instance, - roughness: this.roughness, - metalness: this.metalness, - lightMapIntensity: this.lightMapIntensity, - aoMapIntensity: this.aoMapIntensity, - emissive: this.emissive.instance, - emissiveIntensity: this.emissiveIntensity, - bumpScale: this.bumpScale, - normalScale: this.normalScale, - displacementScale: this.displacementScale, - refractionRatio: this.refractionRatio, - fog: this.fog, - flatShading: this.flatShading, - wireframe: this.wireframe, - wireframeLinewidth: this.wireframeLineWidth, - wireframeLinecap: this.wireframeLineCap, - wireframeLinejoin: this.wireframeLineJoin, - vertexColors: GameLib.D3.Material.TYPE_VERTEX_COLORS, - skinning: this.skinning, - morphTargets: this.morphTargets, - morphNormals: this.morphNormals - }); -}; - - -GameLib.D3.Material.prototype.createStandardMaterialInstance = function() { - return new THREE.MeshStandardMaterial({ - name: this.name, - opacity: this.opacity, - transparent: this.transparent, - blending: this.blending, - blendSrc: this.blendSrc, - blendDst: this.blendDst, - blendEquation: this.blendEquation, - depthTest: this.depthTest, - depthFunc: this.depthFunc, - depthWrite: this.depthWrite, - polygonOffset: this.polygonOffset, - polygonOffsetFactor: this.polygonOffsetFactor, - polygonOffsetUnits: this.polygonOffsetUnits, - alphaTest: this.alphaTest, - clippingPlanes: this.clippingPlanes, - clipShadows: this.clipShadows, - overdraw: this.overdraw, - visible: this.visible, - side: this.side, - color: this.color.instance, - roughness: this.roughness, - metalness: this.metalness, - lightMapIntensity: this.lightMapIntensity, - aoMapIntensity: this.aoMapIntensity, - emissive: this.emissive.instance, - emissiveIntensity: this.emissiveIntensity, - bumpScale: this.bumpScale, - normalScale: this.normalScale, - displacementScale: this.displacementScale, - refractionRatio: this.refractionRatio, - fog: this.fog, - flatShading: this.flatShading, - wireframe: this.wireframe, - wireframeLinewidth: this.wireframeLineWidth, - wireframeLinecap: this.wireframeLineCap, - wireframeLinejoin: this.wireframeLineJoin, - vertexColors: GameLib.D3.Material.TYPE_VERTEX_COLORS, - skinning: this.skinning, - morphTargets: this.morphTargets, - morphNormals: this.morphNormals - }); -}; - -GameLib.D3.Material.prototype.createPointsMaterialInstance = function() { - return new THREE.PointsMaterial({ - name: this.name, - opacity: this.opacity, - transparent: this.transparent, - // blending: this.blending, - // blendSrc: this.blendSrc, - // blendDst: this.blendDst, - // blendEquation: this.blendEquation, - depthTest: this.depthTest, - depthFunc: this.depthFunc, - depthWrite: this.depthWrite, - // polygonOffset: this.polygonOffset, - // polygonOffsetFactor: this.polygonOffsetFactor, - // polygonOffsetUnits: this.polygonOffsetUnits, - // alphaTest: this.alphaTest, - // clippingPlanes: this.clippingPlanes, - // clipShadows: this.clipShadows, - // overdraw: this.overdraw, - visible: this.visible, - side: this.side, - color: this.color.instance, - size: this.pointSize, - sizeAttenuation: this.pointSizeAttenuation - // vertexColors: GameLib.D3.Material.TYPE_VERTEX_COLORS, - // fog: this.fog - }); -}; - -GameLib.D3.Material.prototype.createLineBasicMaterialInstance = function() { - - var linecap = 'round'; - - if (this.lineCap === GameLib.D3.Material.LINE_CAP_BUTT) { - linecap = 'butt'; - } - - if (this.lineCap === GameLib.D3.Material.LINE_CAP_SQUARE) { - linecap = 'square'; - } - - var linejoin = 'round'; - - if (this.lineJoin === GameLib.D3.Material.LINE_JOIN_BEVEL) { - linejoin = 'bevel'; - } - - if (this.lineJoin === GameLib.D3.Material.LINE_JOIN_MITER) { - linejoin = 'miter'; - } - - return new THREE.LineBasicMaterial({ - name: this.name, - opacity: this.opacity, - transparent: this.transparent, - // blending: this.blending, - // blendSrc: this.blendSrc, - // blendDst: this.blendDst, - // blendEquation: this.blendEquation, - depthTest: this.depthTest, - depthFunc: this.depthFunc, - depthWrite: this.depthWrite, - // polygonOffset: this.polygonOffset, - // polygonOffsetFactor: this.polygonOffsetFactor, - // polygonOffsetUnits: this.polygonOffsetUnits, - // alphaTest: this.alphaTest, - // clippingPlanes: this.clippingPlanes, - // clipShadows: this.clipShadows, - // overdraw: this.overdraw, - visible: this.visible, - side: this.side, - color: this.color.instance, - linewidth: this.lineWidth, - linecap: linecap, - linejoin: linejoin - // vertexColors: GameLib.D3.Material.TYPE_VERTEX_COLORS, - // fog: this.fog - }); -}; - -GameLib.D3.Material.prototype.createPhongMaterialInstance = function() { - return new THREE.MeshPhongMaterial({ - name: this.name, - opacity: this.opacity, - transparent: this.transparent, - blending: this.blending, - blendSrc: this.blendSrc, - blendDst: this.blendDst, - blendEquation: this.blendEquation, - depthTest: this.depthTest, - depthFunc: this.depthFunc, - depthWrite: this.depthWrite, - polygonOffset: this.polygonOffset, - polygonOffsetFactor: this.polygonOffsetFactor, - polygonOffsetUnits: this.polygonOffsetUnits, - alphaTest: this.alphaTest, - clippingPlanes: this.clippingPlanes, - clipShadows: this.clipShadows, - overdraw: this.overdraw, - visible: this.visible, - side: this.side, - color: this.color.instance, - specular: this.specular.instance, - shininess: this.shininess, - lightMapIntensity: this.lightMapIntensity, - aoMapIntensity: this.aoMapIntensity, - emissive: this.emissive.instance, - emissiveIntensity: this.emissiveIntensity, - bumpScale: this.bumpScale, - normalScale: this.normalScale, - displacementScale: this.displacementScale, - combine: this.combine, - refractionRatio: this.refractionRatio, - fog: this.fog, - flatShading: this.flatShading, - wireframe: this.wireframe, - wireframeLinewidth: this.wireframeLineWidth, - wireframeLinecap: this.wireframeLineCap, - wireframeLinejoin: this.wireframeLineJoin, - vertexColors: GameLib.D3.Material.TYPE_VERTEX_COLORS, - skinning: this.skinning, - morphTargets: this.morphTargets, - morphNormals: this.morphNormals - }); -}; - -GameLib.D3.Material.prototype.createMeshBasicMaterialInstance = function() { - return new THREE.MeshBasicMaterial({ - name: this.name, - opacity: this.opacity, - transparent: this.transparent, - blending: this.blending, - blendSrc: this.blendSrc, - blendDst: this.blendDst, - blendEquation: this.blendEquation, - depthTest: this.depthTest, - depthFunc: this.depthFunc, - depthWrite: this.depthWrite, - polygonOffset: this.polygonOffset, - polygonOffsetFactor: this.polygonOffsetFactor, - polygonOffsetUnits: this.polygonOffsetUnits, - alphaTest: this.alphaTest, - clippingPlanes: this.clippingPlanes, - clipShadows: this.clipShadows, - overdraw: this.overdraw, - visible: this.visible, - side: this.side, - color: this.color.instance, - vertexColors: GameLib.D3.Material.TYPE_VERTEX_COLORS, - fog: this.fog - }); -}; - -GameLib.D3.Material.prototype.checkTexture = function(runtimeMap, instanceMap) { - - var textureChanged = false; - - if (this[runtimeMap] && this[runtimeMap].instance) { - if (this.instance[instanceMap] !== this[runtimeMap].instance) { - this.instance[instanceMap] = this[runtimeMap].instance; - textureChanged = true; - } - } else { - if (this.instance[instanceMap] !== null) { - this.instance[instanceMap] = null; - textureChanged = true; - } - } - - return textureChanged; -}; - -/** - * updates textures - */ -GameLib.D3.Material.prototype.updateTextures = function() { - - var textureChanged = false; - - if (this.checkTexture('alphaMap', 'alphaMap')) { - textureChanged = true; - } - - if (this.checkTexture('aoMap', 'aoMap')) { - textureChanged = true; - } - - if (this.checkTexture('bumpMap', 'bumpMap')) { - textureChanged = true; - } - - if (this.checkTexture('diffuseMap', 'map')) { - textureChanged = true; - } - - if (this.checkTexture('displacementMap', 'displacementMap')) { - textureChanged = true; - } - - if (this.checkTexture('emissiveMap', 'emissiveMap')) { - textureChanged = true; - } - - if (this.checkTexture('environmentMap', 'envMap')) { - textureChanged = true; - } - - if (this.checkTexture('lightMap', 'lightMap')) { - textureChanged = true; - } - - if (this.checkTexture('metalnessMap', 'metalnessMap')) { - textureChanged = true; - } - - if (this.checkTexture('normalMap', 'normalMap')) { - textureChanged = true; - } - - if (this.checkTexture('roughnessMap', 'roughnessMap')) { - textureChanged = true; - } - - if (this.checkTexture('specularMap', 'specularMap')) { - textureChanged = true; - } - - if (textureChanged) { - this.publish( - GameLib.Event.MATERIAL_TEXTURES_UPDATED, - { - material : this - } - ); - } - - return textureChanged; -}; - - -GameLib.D3.Material.prototype.updateToonMaterialInstance = function(property) { - this.instance.name = this.name; - this.instance.opacity = this.opacity; - this.instance.transparent = this.transparent; - this.instance.blending = this.blending; - this.instance.blendSrc = this.blendSrc; - this.instance.blendDst = this.blendDst; - this.instance.blendEquation = this.blendEquation; - this.instance.depthTest = this.depthTest; - this.instance.depthFunc = this.depthFunc; - this.instance.depthWrite = this.depthWrite; - this.instance.polygonOffset = this.polygonOffset; - this.instance.polygonOffsetFactor = this.polygonOffsetFactor; - this.instance.polygonOffsetUnits = this.polygonOffsetUnits; - this.instance.alphaTest = this.alphaTest; - this.instance.clippingPlanes = this.clippingPlanes; - this.instance.clipShadows = this.clipShadows; - this.instance.overdraw = this.overdraw; - this.instance.visible = this.visible; - this.instance.side = this.side; - this.instance.color = this.color.instance; - this.instance.envMapIntensity = this.envMapIntensity; //standard material doesnt have specular color - this.instance.roughness = this.roughness; - this.instance.metalness = this.metalness; - this.instance.lightMapIntensity = this.lightMapIntensity; - this.instance.aoMapIntensity = this.aoMapIntensity; - this.instance.emissive = this.emissive.instance; - this.instance.emissiveIntensity = this.emissiveIntensity; - this.instance.bumpScale = this.bumpScale; - this.instance.normalScale = this.normalScale; - this.instance.displacementScale = this.displacementScale; - this.instance.refractionRatio = this.refractionRatio; - this.instance.fog = this.fog; - this.instance.flatShading = this.flatShading; - this.instance.wireframe = this.wireframe; - this.instance.wireframeLinewidth = this.wireframeLineWidth; - this.instance.wireframeLinecap = this.wireframeLineCap; - this.instance.wireframeLinejoin = this.wireframeLineJoin; - this.instance.vertexColors = GameLib.D3.Material.TYPE_VERTEX_COLORS; - this.instance.skinning = this.skinning; - this.instance.morphTargets = this.morphTargets; - this.instance.morphNormals = this.morphNormals; -}; - -GameLib.D3.Material.prototype.updateStandardMaterialInstance = function(property) { - this.instance.name = this.name; - this.instance.opacity = this.opacity; - this.instance.transparent = this.transparent; - this.instance.blending = this.blending; - this.instance.blendSrc = this.blendSrc; - this.instance.blendDst = this.blendDst; - this.instance.blendEquation = this.blendEquation; - this.instance.depthTest = this.depthTest; - this.instance.depthFunc = this.depthFunc; - this.instance.depthWrite = this.depthWrite; - this.instance.polygonOffset = this.polygonOffset; - this.instance.polygonOffsetFactor = this.polygonOffsetFactor; - this.instance.polygonOffsetUnits = this.polygonOffsetUnits; - this.instance.alphaTest = this.alphaTest; - this.instance.clippingPlanes = this.clippingPlanes; - this.instance.clipShadows = this.clipShadows; - this.instance.overdraw = this.overdraw; - this.instance.visible = this.visible; - this.instance.side = this.side; - this.instance.color = this.color.instance; - this.instance.envMapIntensity = this.envMapIntensity; //standard material doesnt have specular color - this.instance.roughness = this.roughness; - this.instance.metalness = this.metalness; - this.instance.lightMapIntensity = this.lightMapIntensity; - this.instance.aoMapIntensity = this.aoMapIntensity; - this.instance.emissive = this.emissive.instance; - this.instance.emissiveIntensity = this.emissiveIntensity; - this.instance.bumpScale = this.bumpScale; - this.instance.normalScale = this.normalScale; - this.instance.displacementScale = this.displacementScale; - this.instance.refractionRatio = this.refractionRatio; - this.instance.fog = this.fog; - this.instance.flatShading = this.flatShading; - this.instance.wireframe = this.wireframe; - this.instance.wireframeLinewidth = this.wireframeLineWidth; - this.instance.wireframeLinecap = this.wireframeLineCap; - this.instance.wireframeLinejoin = this.wireframeLineJoin; - this.instance.vertexColors = GameLib.D3.Material.TYPE_VERTEX_COLORS; - this.instance.skinning = this.skinning; - this.instance.morphTargets = this.morphTargets; - this.instance.morphNormals = this.morphNormals; -}; - -GameLib.D3.Material.prototype.updatePointsMaterialInstance = function(property) { - this.instance.name = this.name; - this.instance.opacity = this.opacity; - this.instance.transparent = this.transparent; - // this.instance.blending = this.blending; - // this.instance.blendSrc = this.blendSrc; - // this.instance.blendDst = this.blendDst; - // this.instance.blendEquation = this.blendEquation; - // this.instance.depthTest = this.depthTest; - this.instance.depthFunc = this.depthFunc; - this.instance.depthWrite = this.depthWrite; - // this.instance.polygonOffset = this.polygonOffset; - // this.instance.polygonOffsetFactor = this.polygonOffsetFactor; - // this.instance.polygonOffsetUnits = this.polygonOffsetUnits; - // this.instance.alphaTest = this.alphaTest; - // this.instance.clippingPlanes = this.clippingPlanes; - // this.instance.clipShadows = this.clipShadows; - // this.instance.overdraw = this.overdraw; - this.instance.visible = this.visible; - this.instance.side = this.side; - this.instance.color = this.color.instance; - this.instance.size = this.pointSize; - this.instance.sizeAttenuation = this.pointSizeAttenuation; - //this.instance.vertexColors = GameLib.D3.Material.TYPE_VERTEX_COLORS; - //this.instance.fog = this.fog; -}; - -GameLib.D3.Material.prototype.updateLineBasicMaterialInstance = function(property) { - - var linecap = 'round'; - - if (this.lineCap === GameLib.D3.Material.LINE_CAP_BUTT) { - linecap = 'butt'; - } - - if (this.lineCap === GameLib.D3.Material.LINE_CAP_SQUARE) { - linecap = 'square'; - } - - var linejoin = 'round'; - - if (this.lineJoin === GameLib.D3.Material.LINE_JOIN_BEVEL) { - linejoin = 'bevel'; - } - - if (this.lineJoin === GameLib.D3.Material.LINE_JOIN_MITER) { - linejoin = 'miter'; - } - - this.instance.name = this.name; - this.instance.opacity = this.opacity; - this.instance.transparent = this.transparent; - // this.instance.blending = this.blending; - // this.instance.blendSrc = this.blendSrc; - // this.instance.blendDst = this.blendDst; - // this.instance.blendEquation = this.blendEquation; - // this.instance.depthTest = this.depthTest; - this.instance.depthFunc = this.depthFunc; - this.instance.depthWrite = this.depthWrite; - // this.instance.polygonOffset = this.polygonOffset; - // this.instance.polygonOffsetFactor = this.polygonOffsetFactor; - // this.instance.polygonOffsetUnits = this.polygonOffsetUnits; - // this.instance.alphaTest = this.alphaTest; - // this.instance.clippingPlanes = this.clippingPlanes; - // this.instance.clipShadows = this.clipShadows; - // this.instance.overdraw = this.overdraw; - this.instance.visible = this.visible; - this.instance.side = this.side; - this.instance.color = this.color.instance; - - this.instance.linewidth = this.lineWidth; - this.instance.linecap = linecap; - this.instance.linejoin = linejoin; - - //this.instance.vertexColors = GameLib.D3.Material.TYPE_VERTEX_COLORS; - //this.instance.fog = this.fog; -}; - - -GameLib.D3.Material.prototype.updatePhongMaterialInstance = function(property) { - this.instance.name = this.name; - this.instance.opacity = this.opacity; - this.instance.transparent = this.transparent; - this.instance.blending = this.blending; - this.instance.blendSrc = this.blendSrc; - this.instance.blendDst = this.blendDst; - this.instance.blendEquation = this.blendEquation; - this.instance.depthTest = this.depthTest; - this.instance.depthFunc = this.depthFunc; - this.instance.depthWrite = this.depthWrite; - this.instance.polygonOffset = this.polygonOffset; - this.instance.polygonOffsetFactor = this.polygonOffsetFactor; - this.instance.polygonOffsetUnits = this.polygonOffsetUnits; - this.instance.alphaTest = this.alphaTest; - this.instance.clippingPlanes = this.clippingPlanes; - this.instance.clipShadows = this.clipShadows; - this.instance.overdraw = this.overdraw; - this.instance.visible = this.visible; - this.instance.side = this.side; - this.instance.color = this.color.instance; - this.instance.specular = this.specular.instance; - this.instance.shininess = this.shininess; - this.instance.lightMapIntensity = this.lightMapIntensity; - this.instance.aoMapIntensity = this.aoMapIntensity; - this.instance.emissive = this.emissive.instance; - this.instance.emissiveIntensity = this.emissiveIntensity; - this.instance.envMapIntensity = this.envMapIntensity; - this.instance.bumpScale = this.bumpScale; - this.instance.normalScale = this.normalScale; - this.instance.displacementScale = this.displacementScale; - this.instance.combine = this.combine; - this.instance.refractionRatio = this.refractionRatio; - this.instance.fog = this.fog; - this.instance.flatShading = this.flatShading; - this.instance.wireframe = this.wireframe; - this.instance.wireframeLinewidth = this.wireframeLineWidth; - this.instance.wireframeLinecap = this.wireframeLineCap; - this.instance.wireframeLinejoin = this.wireframeLineJoin; - this.instance.vertexColors = GameLib.D3.Material.TYPE_VERTEX_COLORS; - this.instance.skinning = this.skinning; - this.instance.morphTargets = this.morphTargets; - this.instance.morphNormals = this.morphNormals; -}; - -GameLib.D3.Material.prototype.updateMeshBasicMaterialInstance = function(property) { - this.instance.name = this.name; - this.instance.opacity = this.opacity; - this.instance.transparent = this.transparent; - this.instance.blending = this.blending; - this.instance.blendSrc = this.blendSrc; - this.instance.blendDst = this.blendDst; - this.instance.blendEquation = this.blendEquation; - this.instance.depthTest = this.depthTest; - this.instance.depthFunc = this.depthFunc; - this.instance.depthWrite = this.depthWrite; - this.instance.polygonOffset = this.polygonOffset; - this.instance.polygonOffsetFactor = this.polygonOffsetFactor; - this.instance.polygonOffsetUnits = this.polygonOffsetUnits; - this.instance.alphaTest = this.alphaTest; - this.instance.clippingPlanes = this.clippingPlanes; - this.instance.clipShadows = this.clipShadows; - this.instance.overdraw = this.overdraw; - this.instance.visible = this.visible; - this.instance.side = this.side; - this.instance.color = this.color.instance; - this.instance.vertexColors = GameLib.D3.Material.TYPE_VERTEX_COLORS; - this.instance.fog = this.fog; -}; - -/** - * Material instance - * @returns {*} - */ -GameLib.D3.Material.prototype.createInstance = function() { - - if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_STANDARD) { - - this.instance = this.createStandardMaterialInstance(); - - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_POINTS) { - - this.instance = this.createPointsMaterialInstance(); - - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_PHONG) { - - this.instance = this.createPhongMaterialInstance(); - - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_BASIC) { - - this.instance = this.createMeshBasicMaterialInstance(); - - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_LINE_BASIC) { - - this.instance = this.createLineBasicMaterialInstance(); - - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_TOON) { - - this.instance = this.createToonMaterialInstance(); - - } else { - console.warn("material type is not implemented yet: " + this.materialType); - } - - this.instance.needsUpdate = true; - - this.updateTextures(); - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.D3.Material.prototype.updateInstance = function(property) { - - if (!this.instance) { - console.warn('Attempt to update a non-existent instance'); - return; - } - - if (property === 'materialType') { - - this.createInstance(); - - this.publish( - GameLib.Event.MATERIAL_TYPE_CHANGED, - { - material: this - } - ); - - return; - } - - if ( - property === 'alphaMap' || - property === 'aoMap' || - property === 'bumpMap' || - property === 'diffuseMap' || - property === 'displacementMap' || - property === 'emissiveMap' || - property === 'environmentMap' || - property === 'lightMap' || - property === 'metalnessMap' || - property === 'normalMap' || - property === 'roughnessMap' || - property === 'specularMap' - ) { - this.updateTextures(); - } - - if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_STANDARD) { - this.updateStandardMaterialInstance(property); - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_POINTS) { - this.updatePointsMaterialInstance(property); - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_PHONG) { - this.updatePhongMaterialInstance(property); - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_BASIC) { - this.updateMeshBasicMaterialInstance(property); - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_LINE_BASIC) { - this.updateLineBasicMaterialInstance(property); - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_TOON) { - this.updateToonMaterialInstance(property); - } else { - console.warn('not yet implemented (material type = ' + this.materialType + ')'); - } - - this.instance.needsUpdate = true; -}; - -/** - * Converts a GameLib.D3.Material to a GameLib.D3.API.Material - * @returns {GameLib.D3.API.Material} - */ -GameLib.D3.Material.prototype.toApiObject = function(save) { - - if (GameLib.Utils.UndefinedOrNull(save)) { - save = false; - } - - var apiAlphaMap = null; - if (this.alphaMap) { - if (save) { - this.alphaMap.save(); - } - apiAlphaMap = this.alphaMap.id; - } - - var apiAoMap = null; - if (this.aoMap) { - if (save) { - this.aoMap.save(); - } - apiAoMap = this.aoMap.id; - } - - var apiBumpMap = null; - if (this.bumpMap) { - if (save) { - this.bumpMap.save(); - } - apiBumpMap = this.bumpMap.id; - } - - var apiDiffuseMap = null; - if (this.diffuseMap) { - if (save) { - this.diffuseMap.save(); - } - apiDiffuseMap = this.diffuseMap.id; - } - - var apiDisplacementMap = null; - if (this.displacementMap) { - if (save) { - this.displacementMap.save(); - } - apiDisplacementMap = this.displacementMap.id; - } - - var apiEmissiveMap = null; - if (this.emissiveMap) { - if (save) { - this.emissiveMap.save(); - } - apiEmissiveMap = this.emissiveMap.id; - } - - var apiEnvironmentMap = null; - if (this.environmentMap) { - if (save) { - this.environmentMap.save(); - } - apiEnvironmentMap = this.environmentMap.id; - } - - var apiLightMap = null; - if (this.lightMap) { - if (save) { - this.lightMap.save(); - } - apiLightMap = this.lightMap.id; - } - - var apiMetalnessMap = null; - if (this.metalnessMap) { - if (save) { - this.metalnessMap.save(); - } - apiMetalnessMap = this.metalnessMap.id; - } - - var apiNormalMap = null; - if (this.normalMap) { - this.normalMap.save(); - apiNormalMap = this.normalMap.id; - } - - var apiRoughnessMap = null; - if (this.roughnessMap) { - if (save) { - this.roughnessMap.save(); - } - apiRoughnessMap = this.roughnessMap.id; - } - - var apiSpecularMap = null; - if (this.specularMap) { - if (save) { - this.specularMap.save(); - } - apiSpecularMap = this.specularMap.id; - } - - var apiMaterial = new GameLib.D3.API.Material( - this.id, - this.materialType, - this.name, - this.opacity, - this.side, - this.transparent, - this.specular.toApiObject(), - this.lightMapIntensity, - this.aoMapIntensity, - this.color.toApiObject(), - this.emissive.toApiObject(), - this.emissiveIntensity, - this.combine, - this.shininess, - this.reflectivity, - this.refractionRatio, - this.fog, - this.wireframe, - this.wireframeLineWidth, - this.wireframeLineCap, - this.wireframeLineJoin, - this.vertexColors, - this.skinning, - this.morphTargets, - this.morphNormals, - this.lineWidth, - this.lineCap, - this.lineJoin, - this.dashSize, - this.gapWidth, - this.blending, - this.blendSrc, - this.blendDst, - this.blendEquation, - this.depthTest, - this.depthFunc, - this.depthWrite, - this.polygonOffset, - this.polygonOffsetFactor, - this.polygonOffsetUnits, - this.alphaTest, - this.clippingPlanes, - this.clipShadows, - this.visible, - this.overdraw, - this.flatShading, - this.bumpScale, - this.normalScale, - this.displacementScale, - this.displacementBias, - this.roughness, - this.metalness, - this.pointSize, - this.pointSizeAttenuation, - this.spriteRotation, - this.envMapIntensity, - apiAlphaMap, - apiAoMap, - apiBumpMap, - apiDiffuseMap, - apiDisplacementMap, - apiEmissiveMap, - apiEnvironmentMap, - apiLightMap, - apiMetalnessMap, - apiNormalMap, - apiRoughnessMap, - apiSpecularMap, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiMaterial; -}; - -GameLib.D3.Material.prototype.getTextures = function() { - - var textures = []; - - if (this.alphaMap) { - textures.push(this.alphaMap); - } - - if (this.aoMap) { - textures.push(this.aoMap); - } - - if (this.bumpMap) { - textures.push(this.bumpMap); - } - - if (this.diffuseMap) { - textures.push(this.diffuseMap); - } - - if (this.displacementMap) { - textures.push(this.displacementMap); - } - - if (this.emissiveMap) { - textures.push(this.emissiveMap); - } - - if (this.environmentMap) { - textures.push(this.environmentMap); - } - - if (this.lightMap) { - textures.push(this.lightMap); - } - - if (this.metalnessMap) { - textures.push(this.metalnessMap); - } - - if (this.normalMap) { - textures.push(this.normalMap); - } - - if (this.roughnessMap) { - textures.push(this.roughnessMap); - } - - if (this.specularMap) { - textures.push(this.specularMap); - } - - return textures; -}; - -/** - * Creates a GameLib.D3.Material from a material Object - * @param graphics GameLib.GraphicsRuntime - * @param objectMaterial Object - * @constructor - */ -GameLib.D3.Material.FromObject = function(graphics, objectMaterial) { - - var gameLibMaterial = new GameLib.D3.Material( - graphics, - GameLib.D3.API.Material.FromObject(objectMaterial) - ); - - return gameLibMaterial; -}; - -/** - * Mesh Superset - The apiMesh properties get moved into the Mesh object itself, and then the instance is created - * @param graphics GameLib.GraphicsRuntime - * @param apiMesh GameLib.D3.API.Mesh - * @constructor - */ -GameLib.D3.Mesh = function ( - graphics, - apiMesh -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiMesh)) { - apiMesh = { - meshType: GameLib.D3.API.Mesh.MESH_TYPE_NORMAL - }; - } - - if (apiMesh instanceof GameLib.D3.Mesh) { - return apiMesh; - } - - GameLib.D3.API.Mesh.call( - this, - apiMesh.id, - apiMesh.meshType, - apiMesh.name, - apiMesh.vertices, - apiMesh.faces, - apiMesh.materials, - apiMesh.parentMesh, - apiMesh.parentScene, - apiMesh.skeleton, - apiMesh.skinIndices, - apiMesh.skinWeights, - apiMesh.position, - apiMesh.quaternion, - apiMesh.rotation, - apiMesh.scale, - apiMesh.up, - apiMesh.modelMatrix, - apiMesh.renderOrder, - apiMesh.isBufferMesh, - apiMesh.useQuaternion, - apiMesh.visible, - apiMesh.parentEntity - ); - - this.faces = this.faces.map( - function(face) { - if (face instanceof GameLib.D3.API.Face) { - return new GameLib.D3.Face( - this.graphics, - face - ) - } else { - return face; - } - }.bind(this) - ); - - this.materials = this.materials.map( - function(material) { - if (material instanceof GameLib.D3.API.Material) { - return new GameLib.D3.Material( - this.graphics, - material - ) - } else { - return material; - } - }.bind(this) - ); - - if (this.skeleton) { - this.skeleton = new GameLib.D3.Skeleton( - this.graphics, - this.skeleton - ); - } - - this.vertices = this.vertices.map( - function (apiVertex) { - return new GameLib.D3.Vertex( - this.graphics, - apiVertex - ); - }.bind(this) - ); - - this.position = new GameLib.Vector3( - this.graphics, - this.position, - this - ); - - this.quaternion = new GameLib.Quaternion( - this.graphics, - this.quaternion, - this - ); - - this.rotation = new GameLib.Vector3( - this.graphics, - this.rotation, - this - ); - - this.scale = new GameLib.Vector3( - this.graphics, - this.scale, - this - ); - - this.up = new GameLib.Vector3( - this.graphics, - this.up, - this - ); - - this.modelMatrix = new GameLib.Matrix4( - this.graphics, - this.modelMatrix, - this - ); - - this.dimensions = new GameLib.Vector3( - this.graphics, - new GameLib.API.Vector3(), - this - ); - - var linkedObjects = { - 'parentMesh' : GameLib.D3.Mesh, - 'parentScene' : GameLib.D3.Scene, - 'materials' : [GameLib.D3.Material], - 'skeleton' : GameLib.D3.Skeleton - }; - - if (this.meshType === GameLib.D3.API.Mesh.MESH_TYPE_TEXT) { - linkedObjects.font = GameLib.D3.Font; - } - - /** - * Runtime meshes have helpers too - * @type {null} - */ - this.helper = null; - - this.updateRotationFromAxisAngle = true; - - GameLib.Component.call( - this, - linkedObjects - ); -}; - -GameLib.D3.Mesh.prototype = Object.create(GameLib.D3.API.Mesh.prototype); -GameLib.D3.Mesh.prototype.constructor = GameLib.D3.Mesh; - -GameLib.D3.Mesh.prototype.lookAt = function(vector) { - - this.instance.lookAt( - new THREE.Vector3( - vector.x, - vector.y, - vector.z - ) - ); - - this.rotation.x = this.instance.rotation.x; - this.rotation.y = this.instance.rotation.y; - this.rotation.z = this.instance.rotation.z; - - this.quaternion.x = this.instance.quaternion.x; - this.quaternion.y = this.instance.quaternion.y; - this.quaternion.z = this.instance.quaternion.z; - this.quaternion.w = this.instance.quaternion.w; - -}; - - -GameLib.D3.Mesh.prototype.createInstanceGeometry = function(instanceGeometry) { - - if (instanceGeometry instanceof THREE.Geometry) { - - this.computeBoundingBox(instanceGeometry); - - if (this.isBufferMesh) { - return new THREE.BufferGeometry().fromGeometry(instanceGeometry); - } - } - - /** - * Setup face indexes - first we sort according to the material index, because later we will create - * groups for each vertice group - */ - this.faces.sort(function(a, b){ - - if (a.materialIndex < b.materialIndex) { - return -1; - } - - if (a.materialIndex > b.materialIndex) { - return 1; - } - - return 0; - }); - - /** - * Setup mesh vertices positions - * @type {Float32Array} - */ - var vertices = new Float32Array( - - this.faces.reduce( - function(result, face){ - result.push(this.vertices[face.v0index].position.x); - result.push(this.vertices[face.v0index].position.y); - result.push(this.vertices[face.v0index].position.z); - result.push(this.vertices[face.v1index].position.x); - result.push(this.vertices[face.v1index].position.y); - result.push(this.vertices[face.v1index].position.z); - result.push(this.vertices[face.v2index].position.x); - result.push(this.vertices[face.v2index].position.y); - result.push(this.vertices[face.v2index].position.z); - return result; - }.bind(this), - [] - ) - - ); - - var geometry = null; - - - if (this.isBufferMesh) { - - geometry = new THREE.BufferGeometry(); - - geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3)); - - /** - * Setyp mesh vertices colors - */ - var colors = new Float32Array( - this.faces.reduce( - function(result, face){ - result.push(1,1,1,1,1,1,1,1,1); - // result.push(face.color.r); - // result.push(face.color.g); - // result.push(face.color.b); - // result.push(face.color.r); - // result.push(face.color.g); - // result.push(face.color.b); - // result.push(face.color.r); - // result.push(face.color.g); - // result.push(face.color.b); - return result; - }.bind(this), - [] - ) - ); - geometry.addAttribute('color', new THREE.BufferAttribute(colors, 3, true)); - - /** - * Setup face UVs - */ - var uvs = new Float32Array( - this.faces.reduce( - function(result, face) { - - face.uvs[0].map( - function(uv) { - result.push(uv.x); - result.push(uv.y); - } - ); - - return result; - }, - [] - ) - ); - geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2)); - - var normals = new Float32Array( - this.faces.reduce( - function(result, face) { - - result.push( - face.normal.x, - face.normal.y, - face.normal.z - ); - result.push( - face.normal.x, - face.normal.y, - face.normal.z - ); - result.push( - face.normal.x, - face.normal.y, - face.normal.z - ); - return result; - }, - [] - ) - ); - geometry.addAttribute('normal', new THREE.BufferAttribute( normals, 3 )); - - geometry.computeVertexNormals(); - - - /** - * Setup material groups - this means creating a new group for each material index change - * We know faces are sorted according to material index - */ - var groupIndexCounts = this.faces.reduce( - function(result, face) { - - var currentGroup = result.pop(); - - if (currentGroup.index !== face.materialIndex) { - /** - * We have a new group - */ - result.push(currentGroup); - result.push({ - index: face.materialIndex, - count: 3 - }) - } else { - currentGroup.count += 3; - result.push(currentGroup); - } - - return result; - }, - [ - { - index : 0, - count : 0 - } - ] - ); - - groupIndexCounts.reduce( - function(start, group) { - geometry.addGroup(start, group.count, group.index); - return start + group.count; - }, - 0 - ); - - - } else { - - geometry = new THREE.Geometry(); - - var standardUvs = []; - - /** - * Face data - * @type {Array} - */ - geometry.faces = this.faces.map( - function (face) { - - if (face.uvs[0].length > 0) { - standardUvs.push( - face.uvs[0].map( - function(uv) { - return new THREE.Vector2( - uv.x, - uv.y - ) - } - ) - ); - } - - var faceInstance = new THREE.Face3( - face.v0index, - face.v1index, - face.v2index - ); - - if (face.normal) { - faceInstance.normal = new THREE.Vector3( - face.normal.x, - face.normal.y, - face.normal.z - ); - } - - if (face.color) { - faceInstance.color = new THREE.Color( - face.color.r, - face.color.g, - face.color.b - ) - } - - faceInstance.materialIndex = face.materialIndex; - - return faceInstance; - } - ); - - /** - * Vertex data - * @type {Array} - */ - geometry.vertices = this.vertices.map( - function (vertex) { - return new THREE.Vector3( - vertex.position.x, - vertex.position.y, - vertex.position.z - ) - } - ); - geometry.verticesNeedUpdate = true; - - - /** - * UV data - but only if it exists - */ - if (standardUvs.length > 0) { - geometry.faceVertexUvs = [standardUvs]; - } - - /** - * Re-compute normals - we don't do this for buffer geometry because it assigns to every vertex normal the face - * normal - essentially disabling 'smooth shading' - */ - geometry.computeFaceNormals(); - // geometry.computeBoundingBox(); - geometry.computeVertexNormals(); - - // geometry.verticesNeedUpdate = true; - // geometry.elementsNeedUpdate = true; - // geometry.morphTargetsNeedUpdate = true; - // geometry.uvsNeedUpdate = true; - // geometry.normalsNeedUpdate = true; - // geometry.colorsNeedUpdate = true; - // geometry.tangentsNeedUpdate = true; - } - - /** - * Apply skin indices - */ - // this.applyBones(geometry); - - this.computeBoundingBox(geometry); - - return geometry; -}; - - -/** - * Creates a mesh instance or updates it - */ -GameLib.D3.Mesh.prototype.createInstance = function() { - - var geometry = this.createInstanceGeometry(); - - if (this.skeleton) { - - if (this.materials.length === 1) { - this.instance = new THREE.SkinnedMesh( - geometry, - this.materials[0].instance - ) - } else { - this.instance = new THREE.SkinnedMesh( - geometry, - this.materials.map( - function(material) { - return material.instance; - } - ) - ) - } - - this.instance.add(this.skeleton.rootBoneInstance); - this.instance.bind(this.skeleton.instance); - - } else { - if (this.materials.length === 1) { - this.instance = new THREE.Mesh( - geometry, - this.materials[0].instance - ) - } else { - this.instance = new THREE.Mesh( - geometry, - this.materials.map( - function(material) { - return material.instance; - } - ) - ) - } - } - - this.instance.name = this.name; - - if (this.parentMesh && this.parentMesh.instance) { - this.parentMesh.add(this.instance, this); - } - - this.instance.position.x = this.position.x; - this.instance.position.y = this.position.y; - this.instance.position.z = this.position.z; - - if (this.useQuaternion) { - this.instance.quaternion.x = this.quaternion.x; - this.instance.quaternion.y = this.quaternion.y; - this.instance.quaternion.z = this.quaternion.z; - this.instance.quaternion.w = this.quaternion.w; - this.instance.quaternion.setFromAxisAngle( - new THREE.Vector3( - this.quaternion.axis.x, - this.quaternion.axis.y, - this.quaternion.axis.z - ), - this.quaternion.angle - ); - } else { - this.instance.rotation.x = this.rotation.x; - this.instance.rotation.y = this.rotation.y; - this.instance.rotation.z = this.rotation.z; - } - - this.instance.scale.x = this.scale.x; - this.instance.scale.y = this.scale.y; - this.instance.scale.z = this.scale.z; - - this.instance.up.x = this.up.x; - this.instance.up.y = this.up.y; - this.instance.up.z = this.up.z; - - this.instance.renderOrder = this.renderOrder; - - this.instance.visible = this.visible; - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the mesh instance - */ -GameLib.D3.Mesh.prototype.updateInstance = function(property) { - - if (GameLib.Utils.UndefinedOrNull(property)) { - console.warn('unknown mesh property update'); - } - - if (property === 'isBufferMesh') { - if (( this.isBufferMesh && !(this.instance.geometry instanceof THREE.BufferGeometry)) || - ( !this.isBufferMesh && (this.instance.geometry instanceof THREE.BufferGeometry))) - { - /** - * The buffer geometry needs updating - */ - this.instance.geometry = this.createInstanceGeometry(this.instance.geometry); - } - } - - if ( - property === 'rotation' || - property === 'quaternion' || - property === 'useQuaternion' - ) { - this.updateInstanceRotation(); - } - - if (property === 'parentMesh') { - if (this.parentMesh && this.parentMesh.instance) { - if (this.instance.parent !== this.parentMesh.instance) { - this.instance.parent = this.parentMesh.instance; - } - } - } - - if (property === 'scale') { - this.updateInstanceScale(); - } - - if (property === 'position') { - this.updateInstancePosition(); - } - - if (property === 'up') { - this.instance.up.x = this.up.x; - this.instance.up.y = this.up.y; - this.instance.up.z = this.up.z; - } - - if (property === 'name') { - this.instance.name = this.name; - } - - if (property === 'materials') { - if (this.materials.length === 1 && this.materials[0].instance) { - this.instance.material = this.materials[0].instance; - } - } - - if (property === 'renderOrder') { - this.instance.renderOrder = this.renderOrder; - } - - if (property === 'visible') { - this.instance.visible = this.visible; - } - - if (this.helper) { - this.removeHelper(); - this.createHelper(); - } - -}; - -/** - * Apply geometry data to our game-lib object from the geometry instance (reverse of applyVertexData) - * @param geometryInstance - */ -GameLib.D3.Mesh.prototype.updateVerticesFromGeometryInstance = function(geometryInstance) { - - /** - * Setup vertices - */ - this.vertices = []; - - this.faces = []; - - if (geometryInstance instanceof THREE.BufferGeometry) { - - var vertices = geometryInstance.getAttribute('position').array; - - var uvs = geometryInstance.getAttribute('uv').array; - - geometryInstance.groups.map(function(group){ - - var materialIndex = group.materialIndex; - - var start = group.start; - - var count = group.count; - - var faceIndexes = []; - - var indexedUvs = []; - - for (var i = start; i < count; i ++) { - - var vertex = new GameLib.D3.Vertex( - this.graphics, - new GameLib.D3.API.Vertex( - new GameLib.Vector3( - this.graphics, - new GameLib.API.Vector3( - vertices[i*3], - vertices[i*3 + 1], - vertices[i*3 + 2] - ) - ) - ) - ); - - var uv = new GameLib.Vector2( - this.graphics, - new GameLib.API.Vector2( - uvs[i*2], - uvs[i*2 + 1] - ) - ); - - indexedUvs.push(uv); - - var vertexIndex = this.vertices.reduce( - function(result, indexedVertex, currentIndex){ - if (indexedVertex.position.equals(vertex.position)) { - result = currentIndex; - } - return result; - }, - -1 - ); - - var faceIndex = vertexIndex; - - if (vertexIndex === -1) { - this.vertices.push(vertex); - faceIndex = this.vertices.length - 1; - } - - faceIndexes.push(faceIndex); - - if (faceIndexes.length === 3) { - - this.faces.push( - new GameLib.D3.Face( - this.graphics, - new GameLib.D3.API.Face( - null, - null, - faceIndexes[0], - faceIndexes[1], - faceIndexes[2], - materialIndex, - [[indexedUvs[0], indexedUvs[1], indexedUvs[2]]] - ) - ) - ); - - indexedUvs = []; - faceIndexes = []; - } - } - - }.bind(this)); - - - - console.log('todo : update vertices from buffer geometry'); - } else { - - var processed = 0; - - geometryInstance.faces.map(function(face, faceIndex){ - - processed++; - - if (processed % 100 === 0) { - console.log('processed ' + processed + ' faces'); - } - - this.faces.push( - new GameLib.D3.Face( - this.graphics, - new GameLib.D3.API.Face( - null, - null, - face.a, - face.b, - face.c, - face.materialIndex, - [[ - new GameLib.API.Vector2( - geometryInstance.faceVertexUvs[0][faceIndex][0].x, - geometryInstance.faceVertexUvs[0][faceIndex][0].y - ), - new GameLib.API.Vector2( - geometryInstance.faceVertexUvs[0][faceIndex][1].x, - geometryInstance.faceVertexUvs[0][faceIndex][1].y - ), - new GameLib.API.Vector2( - geometryInstance.faceVertexUvs[0][faceIndex][2].x, - geometryInstance.faceVertexUvs[0][faceIndex][2].y - ) - ]], - new GameLib.Color( - this.graphics, - new GameLib.API.Color( - face.color.r, - face.color.g, - face.color.b - ) - ), - face.vertexColors.map(function(vertexColor){ - return new GameLib.Color( - this.graphics, - new GameLib.API.Color( - vertexColor.r, - vertexColor.g, - vertexColor.b - ) - ) - }.bind(this)), - face.vertexNormals.map(function(vertexNormal){ - return new GameLib.Vector3( - this.graphics, - new GameLib.API.Vector3( - vertexNormal.x, - vertexNormal.y, - vertexNormal.z - ) - ) - }.bind(this)), - new GameLib.Vector3( - this.graphics, - new GameLib.API.Vector3( - face.normal.x, - face.normal.y, - face.normal.z - ) - ) - ) - ) - ) - }.bind(this)); - - processed = 0; - - geometryInstance.vertices.map(function(vertex){ - - processed++; - - if (processed % 100 === 0) { - console.log('processed ' + processed + ' vertices'); - } - - this.vertices.push( - new GameLib.D3.Vertex( - this.graphics, - new GameLib.D3.API.Vertex( - new GameLib.Vector3( - this.graphics, - new GameLib.API.Vector3( - vertex.x, - vertex.y, - vertex.z - ) - ) - ) - ) - ) - }.bind(this)); - } - -}; - - -GameLib.D3.Mesh.prototype.applyBones = function(geometry) { - - /** - * Setup Bone Indexes - */ - this.skinIndices.map( - function(skinIndex) { - geometry.skinIndices.push( - new THREE.Vector4( - skinIndex.x, - skinIndex.y, - skinIndex.z, - skinIndex.w - ) - ); - } - ); - - /** - * Setup Bone Weights - */ - this.skinWeights.map( - function(skinWeight) { - geometry.skinWeights.push( - new THREE.Vector4( - skinWeight.x, - skinWeight.y, - skinWeight.z, - skinWeight.w - ) - ); - } - ); - -}; - -/** - * Adds a child instance to this instance - * @param childInstance - * @param child - */ -GameLib.D3.Mesh.prototype.addChild = function(childInstance, child) { - - if (!this.instance) { - throw new Error('mesh instance not loaded yet : ' + this.name); - } - - if (GameLib.Utils.UndefinedOrNull(childInstance)) { - throw new Error('no child mesh instance'); - } - - if (GameLib.Utils.UndefinedOrNull(child)) { - throw new Error('no child mesh'); - } - - this.instance.add(childInstance); - - childInstance.parent = this.instance; - - child.parentMesh = this; -}; - -/** - * Sets a parent for this mesh - * @param parentMesh - */ -GameLib.D3.Mesh.prototype.setParentMesh = function(parentMesh) { - - /** - * Are we removing this child from the parent? - */ - if (GameLib.Utils.UndefinedOrNull(parentMesh)) { - - if (this.instance && this.instance.parent && this.parentScene.instance) { - - /** - * Update the parent matrix world - */ - this.instance.parent.updateMatrixWorld(); - - /** - * Copy the child world position into a temporary vector - * @type {THREE.Vector3} - */ - var vector = new THREE.Vector3(); - vector.setFromMatrixPosition(this.instance.matrixWorld); - - /** - * Detach child from parent within this scene - */ - THREE.SceneUtils.detach( - this.instance, - this.instance.parent, - this.parentScene.instance - ); - - /** - * We remember from now on that we have no parent mesh - * @type {null} - */ - this.parentMesh = null; - - /** - * We store the world position back to the child - */ - this.position.x = vector.x; - this.position.y = vector.y; - this.position.z = vector.z; - - /** - * Update the instance position - */ - this.updateInstancePosition(); - - /** - * Don't touch this instance parent - since it is now probably a scene object - */ - - /** - * TODO: do we apply rotation somehow? - */ - - } else { - throw new Error('Not enough information to detach') - } - - } else { - - if (!this.instance) { - throw new Error('No valid instance at time of adding to parent for mesh ' + this.name); - } - - if (!(parentMesh instanceof GameLib.D3.Mesh)) { - throw new Error('Not a valid parent mesh'); - } - - this.parentMesh = parentMesh; - - /** - * Add this as a child to the parent - */ - this.parentMesh.addChild(this.instance, this); - } - -}; - - -// GameLib.D3.Mesh.prototype.getBoundingBox = function() { -// -// this.instance.geometry.computeBoundingBox(); -// -// return new GameLib.Vector3( -// this.graphics, -// new GameLib.API.Vector3( -// this.instance.geometry.boundingBox.max.x - this.instance.geometry.boundingBox.min.x, -// this.instance.geometry.boundingBox.max.y - this.instance.geometry.boundingBox.min.y, -// this.instance.geometry.boundingBox.max.z - this.instance.geometry.boundingBox.min.z -// ) -// ); -// -// }; - -/** - * Converts a GameLib.D3.Mesh to a GameLib.D3.API.Mesh - * @returns {GameLib.D3.API.Mesh} - */ -GameLib.D3.Mesh.prototype.toApiObject = function() { - - var apiSkeleton = null; - if (this.skeleton) { - apiSkeleton = this.skeleton.id; - } - - var apiMaterials = null; - if (this.materials) { - apiMaterials = this.materials.map( - function(material) { - return material.id; - } - ) - } - - var apiFaces = this.faces.map( - function(face){ - return face.toApiObject(); - } - ); - - var apiMesh = new GameLib.D3.API.Mesh( - this.id, - this.meshType, - this.name, - this.vertices.map( - function (vertex) { - return vertex.toApiObject(); - } - ), - apiFaces, - apiMaterials, - GameLib.Utils.IdOrNull(this.parentMesh), - GameLib.Utils.IdOrNull(this.parentScene), - apiSkeleton, - this.skinIndices, - this.skinWeights, - this.position.toApiObject(), - this.quaternion.toApiObject(), - this.rotation.toApiObject(), - this.scale.toApiObject(), - this.up.toApiObject(), - this.modelMatrix.toApiObject(), - this.renderOrder, - this.isBufferMesh, - this.useQuaternion, - this.visible, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiMesh; -}; - -/** - * Converts a standard object mesh to a GameLib.D3.Mesh - * @param graphics GameLib.GraphicsRuntime - * @param objectMesh {Object} - * @constructor - */ -GameLib.D3.Mesh.FromObject = function(graphics, objectMesh) { - - var apiMesh = GameLib.D3.API.Mesh.FromObject(objectMesh); - - return new GameLib.D3.Mesh( - graphics, - apiMesh - ); - -}; - -/** - * Centers the mesh around origin - */ -GameLib.D3.Mesh.prototype.centerAroundOrigin = function() { - - var position = this.instance.geometry.center(); - - this.instance.position.set(0,0,0); - - this.instance.updateMatrix(); - - for (var v = 0; v < this.instance.geometry.vertices.length; v++) { - this.vertices[v].position.x = this.instance.geometry.vertices[v].x; - this.vertices[v].position.y = this.instance.geometry.vertices[v].y; - this.vertices[v].position.z = this.instance.geometry.vertices[v].z; - } - - this.position.x = -position.x; - this.position.y = -position.y; - this.position.z = -position.z; - - this.updateInstancePosition(); - - return position; -}; - -GameLib.D3.Mesh.prototype.applyAxisAngleToPosition = function(axis, angle) { - - if (GameLib.Utils.UndefinedOrNull(axis)) { - axis = this.quaternion.axis; - } - - if (GameLib.Utils.UndefinedOrNull(angle)) { - angle = this.quaternion.angle; - } - - this.position.applyAxisAngle(axis, angle); - this.updateInstancePosition(); -}; - -GameLib.D3.Mesh.prototype.applyAxisAngleToUvs = function(axis, angle) { - - if (GameLib.Utils.UndefinedOrNull(axis)) { - axis = this.quaternion.axis; - } - - if (GameLib.Utils.UndefinedOrNull(angle)) { - angle = this.quaternion.angle; - } - - // this.instance.geometry.faceVertexUvs[0].map( - // function(uvs) { - // uvs.map(function(uv) { - // - // var x = uv.x; - // - // uv.x = uv.y; - // uv.y = x; - // - // //var v = new THREE.Vector3(uv.x, uv.y, 0); - // //v.applyAxisAngle(axis, angle); - // //uv.x = v.x; - // //uv.y = v.u; - // }); - // } - // ); - - this.instance.geometry.uvsNeedUpdate = true; - // - // this.faces.map( - // function(face) { - // face.uvs.map(function(uvs){ - // uvs.map( - // function(uv) { - // var v = new GameLib.Vector3(this.graphics, new GameLib.API.Vector3(uv.x, uv.y, 0)); - // v.applyAxisAngle(axis, angle); - // uv.x = v.x; - // uv.y = v.y; - // } - // ) - // }); - // } - // ) -}; - -GameLib.D3.Mesh.prototype.translate = function(vector3) { - - this.position.x += vector3.x; - this.position.y += vector3.y; - this.position.z += vector3.z; - - this.updateInstancePosition(); -}; - -GameLib.D3.Mesh.prototype.getDistanceFromCenter = function() { - var position = this.instance.geometry.center(); - return new GameLib.Vector3( - this.graphics, - new GameLib.API.Vector3( - position.x, - position.y, - position.z - ) - ) -}; - -/** - * Applies position, rotation and scale to the object vertice data, resets scale, rotation and sets position to origin. - */ -GameLib.D3.Mesh.prototype.applyPositionRotationScale = function() { - - this.instance.updateMatrix(); - - this.instance.geometry.applyMatrix(this.instance.matrix); - - /** - * Reset position - * @type {number} - */ - this.position.x = 0; - this.position.y = 0; - this.position.z = 0; - this.updateInstancePosition(); - - /** - * Reset scale - * @type {number} - */ - this.scale.x = 1; - this.scale.y = 1; - this.scale.z = 1; - this.instance.scale.set(1,1,1); - - /** - * Reset rotation - * @type {number} - */ - this.quaternion.x = 0; - this.quaternion.y = 0; - this.quaternion.z = 0; - this.quaternion.w = 1; - this.quaternion.axis.x = 0; - this.quaternion.axis.y = 0; - this.quaternion.axis.z = 0; - this.quaternion.angle = 0; - - this.rotation.x = 0; - this.rotation.y = 0; - this.rotation.z = 0; - - this.updateInstanceRotation(); - - /** - * Update our instance matrix - */ - this.instance.updateMatrix(); - - /** - * Let this reflect back to our vertices - */ - this.updateVerticesFromGeometryInstance(this.instance.geometry); -}; - -GameLib.D3.Mesh.prototype.updateInstanceRotationFromAxisAngle = function(axis, angle) { - - if (GameLib.Utils.UndefinedOrNull(axis)) { - axis = this.quaternion.axis; - } - - if (GameLib.Utils.UndefinedOrNull(angle)) { - angle = this.quaternion.angle; - } - - this.quaternion.axis.instance.x = axis.x; - this.quaternion.axis.instance.y = axis.y; - this.quaternion.axis.instance.z = axis.z; - this.quaternion.instance.setFromAxisAngle(this.quaternion.axis.instance, angle); - this.instance.quaternion.copy(this.quaternion.instance); - this.quaternion.x = this.quaternion.instance.x; - this.quaternion.y = this.quaternion.instance.y; - this.quaternion.z = this.quaternion.instance.z; - this.quaternion.w = this.quaternion.instance.w; -}; - -GameLib.D3.Mesh.prototype.updateInstanceRotation = function() { - - if (this.useQuaternion) { - - this.updateInstanceRotationFromAxisAngle(); - - } else { - - this.rotation.instance.set( - this.rotation.x, - this.rotation.y, - this.rotation.z - ); - - this.instance.rotation.set( - this.rotation.x, - this.rotation.y, - this.rotation.z - ); - } - - if (this.helper) { - this.helper.updateInstance(); - } -}; - -GameLib.D3.Mesh.prototype.updateInstancePosition = function() { - - this.position.instance.set( - this.position.x, - this.position.y, - this.position.z - ); - - this.instance.position.copy(this.position.instance); - - if (this.helper) { - this.removeHelper(); - this.createHelper(); - } -}; - -GameLib.D3.Mesh.prototype.updateInstanceScale = function() { - - this.scale.instance.set( - this.scale.x, - this.scale.y, - this.scale.z - ); - - this.instance.scale.copy(this.scale.instance); - - if (this.helper) { - this.removeHelper(); - this.createHelper(); - } -}; - - - -/** - * Gets all children components of this Mesh (all linked objects only - no object references i.e. string ids) - * @returns {Array} - */ -GameLib.D3.Mesh.prototype.getChildrenComponents = function() { - - var components = []; - - this.materials.map( - function (material) { - - if (material instanceof GameLib.D3.Material) { - GameLib.Utils.PushUnique(components, material); - - for (var property in material.linkedObjects) { - if ( - material.linkedObjects.hasOwnProperty(property) && - material.hasOwnProperty(property) && - material[property] && - typeof material[property] !== 'string' && - property !== 'parentEntity' - ) { - GameLib.Utils.PushUnique(components, material[property]); - for (var tProperty in material[property].linkedObjects) { - if ( - material[property].linkedObjects.hasOwnProperty(tProperty) && - material[property].hasOwnProperty(tProperty) && - material[property][tProperty] && - typeof material[property][tProperty] !== 'string' && - tProperty !== 'parentEntity' - ) { - - if (material[property][tProperty] instanceof Array) { - material[property][tProperty].map( - function(object) { - GameLib.Utils.PushUnique(components, object); - } - ) - } else { - GameLib.Utils.PushUnique(components, material[property][tProperty]); - } - } - } - } - } - } - - }.bind(this) - ); - - /** - * Push RigidBodies - */ - var rigidBodies = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.RIGID_BODY); - rigidBodies.map( - function(rigidBody) { - - if (rigidBody.parentMesh === this) { - GameLib.Utils.PushUnique(components, rigidBody); - } - - }.bind(this) - ); - - /** - * Push Shapes - */ - var shapes = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.SHAPE); - shapes.map( - function(shape) { - - if (shape.parentMesh === this) { - GameLib.Utils.PushUnique(components, shape); - } - - }.bind(this) - ); - - return components; -}; - -/** - * Convenience function for creating a helper for this Mesh - should be called from Systems only - */ -GameLib.D3.Mesh.prototype.createHelper = function() { - - if (GameLib.Utils.UndefinedOrNull(this.parentScene) || - GameLib.Utils.UndefinedOrNull(this.parentScene.instance)) { - console.warn('this mesh has no parent scene - cannot create helper'); - return; - } - - if (this.helper) { - this.removeHelper(); - } - - this.helper = new GameLib.D3.Helper( - this.graphics, - null, - this.name + ' Helper', - this, - GameLib.D3.Helper.HELPER_TYPE_EDGES - ); - - this.helper.updateInstance(); - - /** - * Backup the polygonOffset value, then set it to 'true' - helps for clear nice outlines - */ - this.polygonOffset = this.instance.material.polygonOffset; - - this.instance.material.polygonOffset = true; - - this.parentScene.instance.add(this.helper.instance); - -}; - -GameLib.D3.Mesh.prototype.addMaterial = function(material) { - if (this.materials.length === 1) { - this.instance.material = material.instance; - } else { - this.instance.material = this.materials.map( - function(material) { - return material.instance; - } - ); - } -}; - -/** - * Convenience function for removing a helper for this Mesh - should be called from Systems only - */ -GameLib.D3.Mesh.prototype.removeHelper = function() { - - if (GameLib.Utils.UndefinedOrNull(this.parentScene) || - GameLib.Utils.UndefinedOrNull(this.parentScene.instance)) { - console.warn('this mesh has no parent scene - cannot remove helper'); - return; - } - - if (this.helper && this.helper.instance) { - this.parentScene.instance.remove(this.helper.instance); - delete this.helper.instance; - } - - this.instance.material.polygonOffset = this.polygonOffset; - - this.helper = null; -}; - -GameLib.D3.Mesh.prototype.computeBoundingBox = function(geometry) { - - if (GameLib.Utils.UndefinedOrNull(geometry)) { - - if (this.instance && this.instance.geometry) { - geometry = this.instance.geometry; - } else { - console.log('no instance geometry to compute bounding box'); - } - } - - geometry.computeBoundingBox(); - this.dimensions.x = geometry.boundingBox.getSize().x; - this.dimensions.y = geometry.boundingBox.getSize().y; - this.dimensions.z = geometry.boundingBox.getSize().z; -}; - -/** - * Mesh Superset - The apiMesh properties get moved into the Mesh object itself, and then the instance is created - * @param graphics GameLib.GraphicsRuntime - * @param apiMesh GameLib.D3.API.Mesh - * @param width - * @param height - * @param depth - * @constructor - */ -GameLib.D3.Mesh.Box = function ( - graphics, - apiMesh, - width, - height, - depth -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiMesh)) { - apiMesh = { - meshType: GameLib.D3.API.Mesh.MESH_TYPE_BOX - }; - } - - if (apiMesh instanceof GameLib.D3.Mesh.Box) { - return apiMesh; - } - - if (GameLib.Utils.UndefinedOrNull(width)) { - width = 1; - } - this.width = width; - - if (GameLib.Utils.UndefinedOrNull(height)) { - height = 1; - } - this.height = height; - - if (GameLib.Utils.UndefinedOrNull(depth)) { - depth = 1; - } - this.depth = depth; - - GameLib.D3.Mesh.call( - this, - this.graphics, - apiMesh - ); -}; - -GameLib.D3.Mesh.Box.prototype = Object.create(GameLib.D3.Mesh.prototype); -GameLib.D3.Mesh.Box.prototype.constructor = GameLib.D3.Mesh.Box; - -GameLib.D3.Mesh.Box.prototype.createInstance = function() { - - var geometry = null; - - if (this.vertices.length === 0) { - geometry = new THREE.BoxGeometry( - this.width, - this.height, - this.depth - ); - - this.updateVerticesFromGeometryInstance(geometry); - } - - GameLib.D3.Mesh.prototype.createInstance.call(this); - - this.instance.userData.width = this.width; - this.instance.userData.height = this.height; - this.instance.userData.depth = this.depth; -}; - -GameLib.D3.Mesh.Box.prototype.updateInstance = function(property) { - - if ( - this.instance.userData.width !== this.width || - this.instance.userData.height !== this.height || - this.instance.userData.depth !== this.depth - ) { - this.instance.userData.width = this.width; - this.instance.userData.height = this.height; - this.instance.userData.depth = this.depth; - - var geometry = new THREE.BoxGeometry( - this.width, - this.height, - this.depth - ); - - this.updateVerticesFromGeometryInstance(geometry); - - geometry = this.createInstanceGeometry(); - - this.instance.geometry = geometry; - } - - GameLib.D3.Mesh.prototype.updateInstance.call(this, property); - -}; - -/** - * Converts a GameLib.D3.Mesh to a GameLib.D3.API.Mesh - * @returns {GameLib.D3.API.Mesh} - */ -GameLib.D3.Mesh.Box.prototype.toApiObject = function() { - - var apiMesh = GameLib.D3.Mesh.prototype.toApiObject.call(this); - - apiMesh.width = this.width; - apiMesh.height = this.height; - apiMesh.depth = this.depth; - - return apiMesh; -}; - -/** - * Converts a standard object mesh to a GameLib.D3.Mesh - * @param graphics GameLib.GraphicsRuntime - * @param objectMesh {Object} - * @constructor - */ -GameLib.D3.Mesh.Box.FromObject = function(graphics, objectMesh) { - - var apiMesh = GameLib.D3.API.Mesh.FromObject(objectMesh); - - return new GameLib.D3.Mesh.Box( - graphics, - apiMesh, - objectMesh.width, - objectMesh.height, - objectMesh.depth - ); - -}; - -/** - * Mesh Superset - The apiMesh properties get moved into the Mesh object itself, and then the instance is created - * @param graphics GameLib.GraphicsRuntime - * @param apiMesh GameLib.D3.API.Mesh - * @constructor - */ -GameLib.D3.Mesh.Curve = function ( - graphics, - apiMesh -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiMesh)) { - apiMesh = { - meshType: GameLib.D3.API.Mesh.MESH_TYPE_CURVE - }; - } - - if (apiMesh instanceof GameLib.D3.Mesh.Curve) { - return apiMesh; - } - - GameLib.D3.Mesh.call( - this, - this.graphics, - apiMesh - ); -}; - -GameLib.D3.Mesh.Curve.prototype = Object.create(GameLib.D3.Mesh.prototype); -GameLib.D3.Mesh.Curve.prototype.constructor = GameLib.D3.Mesh.Curve; - - -GameLib.D3.Mesh.Curve.prototype.createInstance = function() { - - var geometry = new THREE.Geometry(); - - /** - * Setup vertices - */ - this.applyVertexDataToInstance(geometry); - - var instance = new THREE.Points(geometry); - - this.createInstanceDefaults(instance); - - return instance; -}; -/** - * Mesh Superset - The apiMesh properties get moved into the Mesh object itself, and then the instance is created - * @param graphics GameLib.GraphicsRuntime - * @param apiMesh GameLib.D3.API.Mesh - * @param radiusTop - * @param radiusBottom - * @param height - * @param radiusSegments - * @param heightSegments - * @param openEnded - * @param thetaStart - * @param thetaLength - * @constructor - */ -GameLib.D3.Mesh.Cylinder = function ( - graphics, - apiMesh, - radiusTop, - radiusBottom, - height, - radiusSegments, - heightSegments, - openEnded, - thetaStart, - thetaLength -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - - if (GameLib.Utils.UndefinedOrNull(apiMesh)) { - apiMesh = { - meshType: GameLib.D3.API.Mesh.MESH_TYPE_CYLINDER - }; - } - - if (apiMesh instanceof GameLib.D3.Mesh.Cylinder) { - return apiMesh; - } - - if (GameLib.Utils.UndefinedOrNull(radiusTop)) { - radiusTop = 1; - } - this.radiusTop = radiusTop; - - if (GameLib.Utils.UndefinedOrNull(radiusBottom)) { - radiusBottom = 1; - } - this.radiusBottom = radiusBottom; - - if (GameLib.Utils.UndefinedOrNull(height)) { - height = 5; - } - this.height = height; - - if (GameLib.Utils.UndefinedOrNull(radiusSegments)) { - radiusSegments = 10; - } - this.radiusSegments = radiusSegments; - - if (GameLib.Utils.UndefinedOrNull(heightSegments)) { - heightSegments = 10; - } - this.heightSegments = heightSegments; - - if (GameLib.Utils.UndefinedOrNull(openEnded)) { - openEnded = false; - } - this.openEnded = openEnded; - - if (GameLib.Utils.UndefinedOrNull(thetaStart)) { - thetaStart = 0; - } - this.thetaStart = thetaStart; - - if (GameLib.Utils.UndefinedOrNull(thetaLength)) { - thetaLength = Math.PI * 2; - } - this.thetaLength = thetaLength; - - GameLib.D3.Mesh.call( - this, - this.graphics, - apiMesh - ); -}; - -GameLib.D3.Mesh.Cylinder.prototype = Object.create(GameLib.D3.Mesh.prototype); -GameLib.D3.Mesh.Cylinder.prototype.constructor = GameLib.D3.Mesh.Cylinder; - -GameLib.D3.Mesh.Cylinder.prototype.createInstance = function() { - - var geometry = null; - - if (this.vertices.length === 0) { - geometry = new THREE.CylinderGeometry( - this.radiusTop, - this.radiusBottom, - this.height, - this.radiusSegments, - this.heightSegments, - this.openEnded, - this.thetaStart, - this.thetaLength - ); - this.updateVerticesFromGeometryInstance(geometry); - } - - GameLib.D3.Mesh.prototype.createInstance.call(this); - - this.instance.userData.radiusTop = this.radiusTop; - this.instance.userData.radiusBottom = this.radiusBottom; - this.instance.userData.height = this.height; - this.instance.userData.radiusSegments = this.radiusSegments; - this.instance.userData.heightSegments = this.heightSegments; - this.instance.userData.openEnded = this.openEnded; - this.instance.userData.thetaStart = this.thetaStart; - this.instance.userData.thetaLength = this.thetaLength; -}; - -GameLib.D3.Mesh.Cylinder.prototype.updateInstance = function(property) { - - if ( - this.instance.userData.radiusTop !== this.radiusTop || - this.instance.userData.radiusBottom !== this.radiusBottom || - this.instance.userData.height !== this.height || - this.instance.userData.radiusSegments !== this.radiusSegments || - this.instance.userData.heightSegments !== this.heightSegments || - this.instance.userData.openEnded !== this.openEnded || - this.instance.userData.thetaStart !== this.thetaStart || - this.instance.userData.thetaLength !== this.thetaLength - ) { - this.instance.userData.radiusTop = this.radiusTop; - this.instance.userData.radiusBottom = this.radiusBottom; - this.instance.userData.height = this.height; - this.instance.userData.radiusSegments = this.radiusSegments; - this.instance.userData.heightSegments = this.heightSegments; - this.instance.userData.openEnded = this.openEnded; - this.instance.userData.thetaStart = this.thetaStart; - this.instance.userData.thetaLength = this.thetaLength; - - var geometry = new THREE.CylinderGeometry( - this.radiusTop, - this.radiusBottom, - this.height, - this.radiusSegments, - this.heightSegments, - this.openEnded, - this.thetaStart, - this.thetaLength - ); - this.updateVerticesFromGeometryInstance(geometry); - - geometry = this.createInstanceGeometry(); - - this.instance.geometry = geometry; - } - - GameLib.D3.Mesh.prototype.updateInstance.call(this, property); - -}; - -/** - * Converts a GameLib.D3.Mesh to a GameLib.D3.API.Mesh - * @returns {GameLib.D3.API.Mesh} - */ -GameLib.D3.Mesh.Cylinder.prototype.toApiObject = function() { - - var apiMesh = GameLib.D3.Mesh.prototype.toApiObject.call(this); - - apiMesh.radiusTop = this.radiusTop; - apiMesh.radiusBottom = this.radiusBottom; - apiMesh.height = this.height; - apiMesh.radiusSegments = this.radiusSegments; - apiMesh.heightSegments = this.heightSegments; - apiMesh.openEnded = this.openEnded; - apiMesh.thetaStart = this.thetaStart; - apiMesh.thetaLength = this.thetaLength; - - return apiMesh; -}; - -/** - * Converts a standard object mesh to a GameLib.D3.Mesh - * @param graphics GameLib.GraphicsRuntime - * @param objectMesh {Object} - * @constructor - */ -GameLib.D3.Mesh.Cylinder.FromObject = function(graphics, objectMesh) { - - var apiMesh = GameLib.D3.API.Mesh.FromObject(objectMesh); - - return new GameLib.D3.Mesh.Cylinder( - graphics, - apiMesh, - objectMesh.radiusTop, - objectMesh.radiusBottom, - objectMesh.height, - objectMesh.radiusSegments, - objectMesh.heightSegments, - objectMesh.openEnded, - objectMesh.thetaStart, - objectMesh.thetaLength - ); - -}; - -/** - * Mesh Superset - The apiMesh properties get moved into the Mesh object itself, and then the instance is created - * @param graphics GameLib.GraphicsRuntime - * @param apiMesh GameLib.D3.API.Mesh - * @param lineWidth - * @constructor - */ -GameLib.D3.Mesh.Line = function ( - graphics, - apiMesh, - lineWidth -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiMesh)) { - apiMesh = { - meshType: GameLib.D3.API.Mesh.MESH_TYPE_LINE - }; - } - - if (apiMesh instanceof GameLib.D3.Mesh.Line) { - return apiMesh; - } - - if (GameLib.Utils.UndefinedOrNull(lineWidth)) { - lineWidth = 1; - } - this.lineWidth = lineWidth; - - GameLib.D3.Mesh.call( - this, - this.graphics, - apiMesh - ); -}; - -GameLib.D3.Mesh.Line.prototype = Object.create(GameLib.D3.Mesh.prototype); -GameLib.D3.Mesh.Line.prototype.constructor = GameLib.D3.Mesh.Line; - -GameLib.D3.Mesh.Line.prototype.createInstance = function() { - - var geometry = new THREE.Geometry(); - - geometry.vertices.push( - this.vertices.map( - function(vertex){ - return vertex.instance; - } - ) - ); - - this.instance = new THREE.Line(geometry); - - GameLib.D3.Mesh.prototype.createInstance.call(this); - - this.instance.userData.lineWidth = this.lineWidth; -}; - -GameLib.D3.Mesh.Line.prototype.updateInstance = function(property) { - - this.instance.linewidth = this.lineWidth; - - GameLib.D3.Mesh.prototype.updateInstance.call(this, property); - -}; - -/** - * Converts a GameLib.D3.Mesh to a GameLib.D3.API.Mesh - * @returns {GameLib.D3.API.Mesh} - */ -GameLib.D3.Mesh.Line.prototype.toApiObject = function() { - - var apiMesh = GameLib.D3.Mesh.prototype.toApiObject.call(this); - - apiMesh.lineWidth = this.lineWidth; - - return apiMesh; -}; - -/** - * Converts a standard object mesh to a GameLib.D3.Mesh - * @param graphics GameLib.GraphicsRuntime - * @param objectMesh {Object} - * @constructor - */ -GameLib.D3.Mesh.Line.FromObject = function(graphics, objectMesh) { - - var apiMesh = GameLib.D3.API.Mesh.FromObject(objectMesh); - - return new GameLib.D3.Mesh.Line( - graphics, - apiMesh, - objectMesh.lineWidth - ); - -}; - -/** - * Mesh Superset - The apiMesh properties get moved into the Mesh object itself, and then the instance is created - * @param graphics GameLib.GraphicsRuntime - * @param apiMesh GameLib.D3.API.Mesh - * @param width - * @param height - * @param widthSegments - * @param heightSegments - * @param heightMapScale - * @param isHeightMap - * @param isClippingPlane - * @param distanceFromOrigin - * @constructor - */ -GameLib.D3.Mesh.Plane = function ( - graphics, - apiMesh, - width, - height, - widthSegments, - heightSegments, - heightMapScale, - isHeightMap, - isClippingPlane, - distanceFromOrigin -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiMesh)) { - apiMesh = { - meshType: GameLib.D3.API.Mesh.MESH_TYPE_PLANE - }; - } - - if (apiMesh instanceof GameLib.D3.Mesh.Plane) { - return apiMesh; - } - - if (GameLib.Utils.UndefinedOrNull(width)) { - width = 1; - } - this.width = width; - - if (GameLib.Utils.UndefinedOrNull(height)) { - height = 1; - } - this.height = height; - - if (GameLib.Utils.UndefinedOrNull(widthSegments)) { - widthSegments = 1; - } - this.widthSegments = widthSegments; - - if (GameLib.Utils.UndefinedOrNull(heightSegments)) { - heightSegments = 1 - } - this.heightSegments = heightSegments; - - if (GameLib.Utils.UndefinedOrNull(heightMapScale)) { - heightMapScale = 1; - } - this.heightMapScale = heightMapScale; - - if (GameLib.Utils.UndefinedOrNull(isHeightMap)) { - isHeightMap = false; - } - this.isHeightMap = isHeightMap; - - if (GameLib.Utils.UndefinedOrNull(isClippingPlane)) { - isClippingPlane = false; - } - this.isClippingPlane = isClippingPlane; - - if (GameLib.Utils.UndefinedOrNull(distanceFromOrigin)) { - distanceFromOrigin = 0; - } - this.distanceFromOrigin = distanceFromOrigin; - - GameLib.D3.Mesh.call( - this, - this.graphics, - apiMesh - ); -}; - -GameLib.D3.Mesh.Plane.prototype = Object.create(GameLib.D3.Mesh.prototype); -GameLib.D3.Mesh.Plane.prototype.constructor = GameLib.D3.Mesh.Plane; - - -GameLib.D3.Mesh.Plane.prototype.createInstance = function() { - - var geometry = null; - - /** - * If this geometry is not coming from the database, apply the vertex data from the instance to our runtime object - */ - if (this.vertices.length === 0) { - - geometry = new THREE.PlaneGeometry( - this.width, - this.height, - this.widthSegments, - this.heightSegments - ); - - this.updateVerticesFromGeometryInstance(geometry); - - /** - * If this is a heightmap - first generate the z-coordinates - */ - if (this.isHeightMap) { - this.generateHeightMapFromBumpMap(); - } - } - - /** - * Now construct the mesh instance - */ - GameLib.D3.Mesh.prototype.createInstance.call(this); - - /** - * Apply some plane specific data to the instance - */ - this.instance.userData.width = this.width; - this.instance.userData.height = this.height; - this.instance.userData.widthSegments = this.widthSegments; - this.instance.userData.heightSegments = this.heightSegments; - this.instance.userData.heightMapScale = this.heightMapScale; - this.instance.userData.isHeightMap = this.isHeightMap; - this.instance.userData.isClippingPlane = this.isClippingPlane; - this.instance.userData.distanceFromOrigin = this.distanceFromOrigin; - - if (this.isClippingPlane) { - this.instance.clipping = new THREE.Plane( - geometry.faces[0].normal, - this.distanceFromOrigin - ); - } -}; - -/** - * - */ -GameLib.D3.Mesh.Plane.prototype.updateInstance = function(property) { - - var geometry = null; - - if ( - this.instance.userData.width !== this.width || - this.instance.userData.height !== this.height || - this.instance.userData.widthSegments !== this.widthSegments || - this.instance.userData.heightSegments !== this.heightSegments || - this.instance.userData.isHeightMap !== this.isHeightMap || - this.instance.userData.heightMapScale !== this.heightMapScale || - this.instance.userData.isClippingPlane !== this.isClippingPlane || - this.instance.userData.distanceFromOrigin !== this.distanceFromOrigin - ) { - this.instance.userData.width = this.width; - this.instance.userData.height = this.height; - this.instance.userData.widthSegments = this.widthSegments; - this.instance.userData.heightSegments = this.heightSegments; - this.instance.userData.isHeightMap = this.isHeightMap; - this.instance.userData.heightMapScale = this.heightMapScale; - this.instance.userData.isClippingPlane = this.isClippingPlane; - this.instance.userData.distanceFromOrigin = this.distanceFromOrigin; - - geometry = new THREE.PlaneGeometry( - this.width, - this.height, - this.widthSegments, - this.heightSegments - ); - - this.updateVerticesFromGeometryInstance(geometry); - - if (this.isHeightMap) { - this.generateHeightMapFromBumpMap(); - } - - geometry = this.createInstanceGeometry(); - - this.instance.geometry = geometry; - - if (this.isClippingPlane) { - this.instance.clipping = new THREE.Plane( - geometry.faces[0].normal, - this.distanceFromOrigin - ) - } - } - - GameLib.D3.Mesh.prototype.updateInstance.call(this, property); -}; - -/** - * Converts a GameLib.D3.Mesh to a GameLib.D3.API.Mesh - * @returns {GameLib.D3.API.Mesh} - */ -GameLib.D3.Mesh.Plane.prototype.toApiObject = function() { - - var apiMesh = GameLib.D3.Mesh.prototype.toApiObject.call(this); - - apiMesh.width = this.width; - apiMesh.height = this.height; - apiMesh.widthSegments = this.widthSegments; - apiMesh.heightSegments = this.heightSegments; - apiMesh.heightMapScale = this.heightMapScale; - apiMesh.isHeightMap = this.isHeightMap; - apiMesh.isClippingPlane = this.isClippingPlane; - apiMesh.distanceFromOrigin = this.distanceFromOrigin; - - return apiMesh; -}; - -/** - * TODO fix all this weird loading shit - * Converts a standard object mesh to a GameLib.D3.Mesh - * @param graphics GameLib.GraphicsRuntime - * @param objectMesh {Object} - * @constructor - */ -GameLib.D3.Mesh.Plane.FromObject = function(graphics, objectMesh) { - - var apiMesh = GameLib.D3.API.Mesh.FromObject(objectMesh); - - return new GameLib.D3.Mesh.Plane( - graphics, - apiMesh, - objectMesh.width, - objectMesh.height, - objectMesh.widthSegments, - objectMesh.heightSegments, - objectMesh.heightMapScale, - objectMesh.isHeightMap, - objectMesh.isClippingPlane, - objectMesh.distanceFromOrigin - ); - -}; - -GameLib.D3.Mesh.Plane.prototype.getHeightData = function() { - - var i; - - var img = this.materials.reduce( - function(result, material) { - if ( - material.bumpMap && - material.bumpMap.image && - material.bumpMap.image.instance - ) { - result = material.bumpMap.image.instance; - } - - return result; - }, - null - ); - - if (!img) { - throw new Error('bumpmap image not found'); - } - - var canvas = document.createElement( 'canvas' ); - canvas.width = this.widthSegments + 1;//img.width; - canvas.height = this.heightSegments + 1;//img.height; - var context = canvas.getContext( '2d' ); - - var size = (this.widthSegments + 1) * (this.heightSegments + 1); - var data = new Float32Array( size ); - - context.drawImage(img,0,0, canvas.width, canvas.height); - - for (i = 0; i < size; i ++ ) { - data[i] = 0 - } - - var imgd = context.getImageData(0, 0, (this.widthSegments + 1), (this.heightSegments + 1)); - var pix = imgd.data; - - var j=0; - for (i = 0; i particle.userData.lifeTime) { - // particle.parent.remove(particle); - // } else { - // result.push(particle); - // } - // - // return result; - // }, - // [] - // ); -}; - -GameLib.D3.ParticleEngine.prototype.createNewParticle = function(camera) { - // - // var particle = this.templateParticle.clone(camera); - // - // this.particles.push(particle); - -}; - -/** - * Converts a GameLib.D3.ParticleEngine to a new GameLib.D3.API.ParticleEngine - * @returns {GameLib.D3.API.ParticleEngine} - */ -GameLib.D3.ParticleEngine.prototype.toApiObject = function() { - - return new GameLib.D3.API.ParticleEngine( - this.id, - this.name, - this.position.toApiObject(), - this.direction.toApiObject(), - this.enabled, - GameLib.Utils.IdOrNull(this.templateParticle), - this.particlesPerSecond, - this.frequency, - this.elapsed, - GameLib.Utils.IdOrNull(this.camera), - this.pulse, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - -}; - -/** - * Converts from an Object ParticleEngine to a GameLib.D3.ParticleEngine - * @param graphics GameLib.GraphicsRuntime - * @param objectParticleEngine Object - * @returns {GameLib.D3.ParticleEngine} - * @constructor - */ -GameLib.D3.ParticleEngine.FromObject = function(graphics, objectParticleEngine) { - - var apiParticleEngine = GameLib.D3.API.ParticleEngine.FromObject(objectParticleEngine); - - return new GameLib.D3.ParticleEngine( - graphics, - apiParticleEngine - ); - -}; - -/** - * Creates a Particle object - * @param graphics GameLib.GraphicsRuntime - * @param apiParticle GameLib.D3.API.Particle - * @constructor - */ -GameLib.D3.Particle = function( - graphics, - apiParticle -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiParticle)) { - apiParticle = {}; - } - - if (apiParticle instanceof GameLib.D3.Particle) { - return apiParticle; - } - - GameLib.D3.API.Particle.call( - this, - apiParticle.id, - apiParticle.name, - apiParticle.lifeTime, - apiParticle.elapsed, - apiParticle.mesh, - apiParticle.opacityType, - apiParticle.opacityFactor, - apiParticle.positionOffsetType, - apiParticle.positionOffset, - apiParticle.positionOffsetFn, - apiParticle.directionType, - apiParticle.direction, - apiParticle.directionFn, - apiParticle.speedType, - apiParticle.speed, - apiParticle.scaleType, - apiParticle.scale, - apiParticle.scaleFn, - apiParticle.rotationType, - apiParticle.rotation, - apiParticle.rotationFn, - apiParticle.parentEngine, - apiParticle.parentEntity - ); - - if (this.mesh instanceof GameLib.D3.API.Mesh) { - this.mesh = new GameLib.D3.Mesh( - graphics, - this.mesh - ) - } - - if (this.positionOffset instanceof GameLib.API.Vector3) { - this.positionOffset = new GameLib.Vector3( - graphics, - this.positionOffset, - this - ); - } else { - console.warn('positionOffset not instance of API.Vector3'); - throw new Error('positionOffset not instance of API.Vector3'); - } - - if (this.direction instanceof GameLib.API.Vector3) { - this.direction = new GameLib.Vector3( - graphics, - this.direction, - this - ); - } else { - console.warn('direction not instance of API.Vector3'); - throw new Error('direction not instance of API.Vector3'); - } - - if (this.scale instanceof GameLib.API.Vector3) { - this.scale = new GameLib.Vector3( - graphics, - this.scale, - this - ); - } else { - console.warn('scale not instance of API.Vector3'); - throw new Error('scale not instance of API.Vector3'); - } - - if (this.rotation instanceof GameLib.API.Vector3) { - this.rotation = new GameLib.Vector3( - graphics, - this.rotation, - this - ); - } else { - console.warn('rotation not instance of API.Vector3'); - throw new Error('rotation not instance of API.Vector3'); - } - - GameLib.Component.call( - this, - { - mesh : GameLib.D3.Mesh, - parentEngine : GameLib.D3.ParticleEngine - } - ); - -}; - -GameLib.D3.Particle.prototype = Object.create(GameLib.D3.API.Particle.prototype); -GameLib.D3.Particle.prototype.constructor = GameLib.D3.Particle; - -GameLib.D3.Particle.OPACITY_TYPE_CONSTANT = 0x1; -GameLib.D3.Particle.OPACITY_TYPE_DECREASE_LINEAR = 0x2; -GameLib.D3.Particle.OPACITY_TYPE_INCREASE_LINEAR = 0x3; - -GameLib.D3.Particle.POSITION_OFFSET_TYPE_CONSTANT = 0x1; -GameLib.D3.Particle.POSITION_OFFSET_TYPE_RANDOM = 0x2; -GameLib.D3.Particle.POSITION_OFFSET_TYPE_FUNCTION = 0x3; - -GameLib.D3.Particle.DIRECTION_TYPE_CONSTANT = 0x1; -GameLib.D3.Particle.DIRECTION_TYPE_RANDOM = 0x2; -GameLib.D3.Particle.DIRECTION_TYPE_RANDOM_NORMALIZED = 0x3; -GameLib.D3.Particle.DIRECTION_TYPE_FUNCTION = 0x4; - -GameLib.D3.Particle.SCALE_TYPE_CONSTANT = 0x1; -GameLib.D3.Particle.SCALE_TYPE_LINEAR = 0x2; -GameLib.D3.Particle.SCALE_TYPE_EXPONENTIAL = 0x3; -GameLib.D3.Particle.SCALE_TYPE_RANDOM = 0x4; -GameLib.D3.Particle.SCALE_TYPE_RANDOM_X_EQUALS_Y = 0x6; -GameLib.D3.Particle.SCALE_TYPE_FUNCTION = 0x7; - -GameLib.D3.Particle.SPEED_TYPE_CONSTANT = 0x1; -GameLib.D3.Particle.SPEED_TYPE_LINEAR = 0x2; -GameLib.D3.Particle.SPEED_TYPE_EXPONENTIAL = 0x3; -GameLib.D3.Particle.SPEED_TYPE_LOGARITHMIC = 0x4; -GameLib.D3.Particle.SPEED_TYPE_ONE_OVER_LOG = 0x5; -GameLib.D3.Particle.SPEED_TYPE_EXP = 0x6; -GameLib.D3.Particle.SPEED_TYPE_ONE_OVER_EXP = 0x7; - -GameLib.D3.Particle.ROTATION_TYPE_CONSTANT = 0x1; -GameLib.D3.Particle.ROTATION_TYPE_RANDOM = 0x2; -GameLib.D3.Particle.ROTATION_TYPE_FUNCTION = 0x3; - -/** - * Particle create instance - */ -GameLib.D3.Particle.prototype.createInstance = function() { - - if (!this.mesh) { - console.warn('no mesh to clone from - failed dependency check?'); - return - } - - this.instance = this.mesh.instance; - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.D3.Particle.prototype.updateInstance = function(property) { - - if (property === 'positionOffset') { - this.positionOffset.instance.x = this.positionOffset.x; - this.positionOffset.instance.y = this.positionOffset.y; - this.positionOffset.instance.z = this.positionOffset.z; - } - - if (property === 'direction') { - this.direction.instance.x = this.direction.x; - this.direction.instance.y = this.direction.y; - this.direction.instance.z = this.direction.z; - } - - if (property === 'scale') { - this.scale.instance.x = this.scale.x; - this.scale.instance.y = this.scale.y; - this.scale.instance.z = this.scale.z; - } - - if (property === 'rotation') { - this.rotation.instance.x = this.rotation.x; - this.rotation.instance.y = this.rotation.y; - this.rotation.instance.z = this.rotation.z; - } - -}; - - -/** - * Clones a particle - this only clones 3rd party instances, so we have less overhead of creating these types of objects - */ -GameLib.D3.Particle.prototype.cloneInstance = function() { - - this.updateInstance('positionOffset'); - this.updateInstance('direction'); - this.updateInstance('scale'); - this.updateInstance('rotation'); - - var clone = GameLib.Component.prototype.cloneInstance.call(this); - - clone.position = this.parentEngine.position.instance.clone(); - - clone.material = this.mesh.materials[0].instance.clone(); - - clone.visible = true; - - if (this.positionOffsetType === GameLib.D3.Particle.POSITION_OFFSET_TYPE_CONSTANT) { - clone.position.add(this.positionOffset.instance); - } - - var addX = 1; - var addY = 1; - var addZ = 1; - - if (this.positionOffsetType === GameLib.D3.Particle.POSITION_OFFSET_TYPE_RANDOM) { - - addX = GameLib.Utils.GetRandomIntInclusive(1,2); - addY = GameLib.Utils.GetRandomIntInclusive(1,2); - addZ = GameLib.Utils.GetRandomIntInclusive(1,2); - - if (addX === 1) { - clone.position.x += Math.random() * this.positionOffset.x; - } else { - clone.position.x -= Math.random() * this.positionOffset.x; - } - - if (addY === 1) { - clone.position.y -= Math.random() * this.positionOffset.y; - } else { - clone.position.y += Math.random() * this.positionOffset.y; - } - - if (addZ === 1) { - clone.position.z -= Math.random() * this.positionOffset.z; - } else { - clone.position.z += Math.random() * this.positionOffset.z; - } - } - - clone.userData.direction = this.direction.clone(); - - if (this.directionType === GameLib.D3.Particle.DIRECTION_TYPE_CONSTANT) { - - /** - * Nothing to do - */ - - } else if ( - this.directionType === GameLib.D3.Particle.DIRECTION_TYPE_RANDOM || - this.directionType === GameLib.D3.Particle.DIRECTION_TYPE_RANDOM_NORMALIZED - ) { - - addX = GameLib.Utils.GetRandomIntInclusive(1,2); - addY = GameLib.Utils.GetRandomIntInclusive(1,2); - addZ = GameLib.Utils.GetRandomIntInclusive(1,2); - - clone.userData.direction.x = 0; - clone.userData.direction.y = 0; - clone.userData.direction.z = 0; - - if (addX === 1) { - clone.userData.direction.x += Math.random() * this.direction.x; - } else { - clone.userData.direction.x -= Math.random() * this.direction.x; - } - - if (addY === 1) { - clone.userData.direction.y -= Math.random() * this.direction.y; - } else { - clone.userData.direction.y += Math.random() * this.direction.y; - } - - if (addZ === 1) { - clone.userData.direction.z -= Math.random() * this.direction.z; - } else { - clone.userData.direction.z += Math.random() * this.direction.z; - } - - if (this.directionType === GameLib.D3.Particle.DIRECTION_TYPE_RANDOM_NORMALIZED) { - clone.userData.direction.normalize(); - } - - } else { - throw new Error('not yet implemented') - } - - - if (this.scaleType === GameLib.D3.Particle.SCALE_TYPE_CONSTANT) { - clone.scale.x += this.scale.x; - clone.scale.y += this.scale.y; - clone.scale.z += this.scale.z; - } - - if (this.scaleType === GameLib.D3.Particle.SCALE_TYPE_RANDOM) { - - add = GameLib.Utils.GetRandomIntInclusive(1,2); - - if (add === 1) { - clone.scale.x += Math.random() * this.scale.x; - clone.scale.y += Math.random() * this.scale.y; - clone.scale.z += Math.random() * this.scale.z; - } else { - clone.scale.x -= Math.random() * this.scale.x; - clone.scale.y -= Math.random() * this.scale.y; - clone.scale.z -= Math.random() * this.scale.z; - } - } - - if (this.scaleType === GameLib.D3.Particle.SCALE_TYPE_RANDOM_X_EQUALS_Y) { - - add = GameLib.Utils.GetRandomIntInclusive(1,2); - - var factor = Math.random() * this.scale.x; - - if (add === 1) { - clone.scale.x += factor; - clone.scale.y += factor; - clone.scale.z += Math.random() * this.scale.z; - } else { - clone.scale.x -= factor; - clone.scale.y -= factor; - clone.scale.z -= Math.random() * this.scale.z; - } - } - - - clone.userData.scale = this.scale.clone(); - clone.userData.lifeTime = this.lifeTime; - clone.userData.speedType = this.speedType; - clone.userData.speed = this.speed; - clone.userData.scene = this.mesh.parentScene.instance; - - clone.userData.elapsed = 0; - - clone.userData.scene.add(clone); - - return clone; -}; - -/** - * Converts a GameLib.D3.Particle to a new GameLib.D3.API.Particle - * @returns {GameLib.D3.API.Particle} - */ -GameLib.D3.Particle.prototype.toApiObject = function() { - - return new GameLib.D3.API.Particle( - this.id, - this.name, - this.lifeTime, - this.elapsed, - GameLib.Utils.IdOrNull(this.mesh), - this.opacityType, - this.opacityFactor, - this.positionOffsetType, - this.positionOffset.toApiObject(), - this.positionOffsetFn, - this.directionType, - this.direction.toApiObject(), - this.directionFn, - this.speedType, - this.speed, - this.scaleType, - this.scale.toApiObject(), - this.scaleFn, - this.rotationType, - this.rotation.toApiObject(), - this.rotationFn, - GameLib.Utils.IdOrNull(this.parentEngine), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - -}; - -/** - * Converts from an Object Particle to a GameLib.D3.Particle - * @param graphics GameLib.GraphicsRuntime - * @param objectParticle Object - * @returns {GameLib.D3.Particle} - * @constructor - */ -GameLib.D3.Particle.FromObject = function(graphics, objectParticle) { - - var apiParticle = GameLib.D3.API.Particle.FromObject(objectParticle); - - return new GameLib.D3.Particle( - graphics, - apiParticle - ); - -}; - -/** - * Renders a scene with a camera - * @param graphics GameLib.GraphicsRuntime - * @param apiPass GameLib.D3.API.Pass - * @constructor - */ -GameLib.D3.Pass = function ( - graphics, - apiPass -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiPass)) { - apiPass = {}; - } - - if (apiPass instanceof GameLib.D3.Pass) { - return apiPass; - } - - GameLib.D3.API.Pass.call( - this, - apiPass.id, - apiPass.name, - apiPass.passType, - apiPass.camera, - apiPass.scene, - apiPass.renderToScreen, - apiPass.parentEntity - ); - - GameLib.Component.call( - this, - { - 'camera' : GameLib.D3.Camera, - 'scene' : GameLib.D3.Scene - } - ); -}; - -GameLib.D3.Pass.prototype = Object.create(GameLib.D3.API.Pass.prototype); -GameLib.D3.Pass.prototype.constructor = GameLib.D3.Pass; - -GameLib.D3.Pass.PASS_TYPE_RENDER = 0x1; -GameLib.D3.Pass.PASS_TYPE_COPY_SHADER = 0x2; - -/** - * Create Pass instance - * @returns {*} - */ -GameLib.D3.Pass.prototype.createInstance = function() { - - if (this.passType === GameLib.D3.Pass.PASS_TYPE_RENDER) { - - if (GameLib.Utils.UndefinedOrNull(this.scene)) { - throw new Error('no scene object'); - } - - if (GameLib.Utils.UndefinedOrNull(this.camera)) { - throw new Error('no camera object'); - } - - if (GameLib.Utils.UndefinedOrNull(THREE.RenderPass)) { - throw new Error('no render pass library') - } - - this.instance = new THREE.RenderPass( - this.scene.instance, - this.camera.instance - ); - - } else if (this.passType === GameLib.D3.Pass.PASS_TYPE_COPY_SHADER) { - - if (GameLib.Utils.UndefinedOrNull(THREE.CopyShader)) { - throw new Error('no copyshader library') - } - - this.instance = THREE.CopyShader; - - } else { - console.warn('Render pass not supported yet: ' + this.passType); - throw new Error('Render pass not supported yet: ' + this.passType); - } - - this.instance.renderToScreen = this.renderToScreen; - - GameLib.Component.prototype.createInstance.call(this); - -}; - -/** - * Update Pass instance - */ -GameLib.D3.Pass.prototype.updateInstance = function() { - - if ( - this.passType === GameLib.D3.Pass.PASS_TYPE_RENDER && !(this.instance instanceof THREE.RenderPass)){ - this.createInstance(); - } - - if ( - this.passType === GameLib.D3.Pass.PASS_TYPE_COPY_SHADER && !(this.instance instanceof THREE.CopyShader)){ - this.createInstance(); - } - - this.instance.renderToScreen = this.renderToScreen; - -}; - -/** - * GameLib.D3.Pass to GameLib.D3.API.Pass - * @returns {GameLib.D3.API.Pass} - */ -GameLib.D3.Pass.prototype.toApiObject = function() { - - var apiPass = new GameLib.D3.API.Pass( - this.id, - this.name, - this.passType, - GameLib.Utils.IdOrNull(this.camera), - GameLib.Utils.IdOrNull(this.scene), - this.renderToScreen, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiPass; -}; - -/** - * GameLib.D3.Pass from Object - * @param graphics - * @param objectComponent - * @returns {GameLib.D3.Pass} - * @constructor - */ -GameLib.D3.Pass.FromObject = function(graphics, objectComponent) { - - var apiPass = GameLib.D3.API.Pass.FromObject(objectComponent); - - return new GameLib.D3.Pass( - graphics, - apiPass - ); -}; - -/** - * World SuperSet - contains the custom world instance - * @constructor - * @param physics - * @param apiWorld - */ -GameLib.D3.PhysicsWorld = function( - physics, - apiWorld -) { - - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiWorld)) { - apiWorld = {}; - } - - if (apiWorld instanceof GameLib.D3.PhysicsWorld) { - return apiWorld; - } - - GameLib.D3.API.PhysicsWorld.call( - this, - apiWorld.id, - apiWorld.name, - apiWorld.gravity, - apiWorld.broadphase, - apiWorld.solver, - apiWorld.rigidBodies, - apiWorld.contactMaterials, - apiWorld.allowSleep, - apiWorld.defaultContactMaterial, - apiWorld.parentEntity - ); - - if (this.gravity instanceof GameLib.API.Vector3) { - this.gravity = new GameLib.Vector3( - this.physics, - this.gravity, - this - ); - } - - if (this.broadphase instanceof GameLib.D3.API.Broadphase) { - this.broadphase = new GameLib.D3.Broadphase( - this.physics, - this.broadphase - ); - } - - if (this.solver instanceof GameLib.D3.API.Solver) { - this.solver = new GameLib.D3.Solver( - this.physics, - this.solver - ); - } - - this.rigidBodies = this.rigidBodies.map( - function(rigidBody) { - if (rigidBody instanceof GameLib.D3.API.RigidBody) { - return new GameLib.D3.RigidBody( - this.physics, - rigidBody - ); - } - return rigidBody; - }.bind(this) - ); - - this.contactMaterials = this.contactMaterials.map( - function(contactMaterial) { - if (contactMaterial instanceof GameLib.D3.API.FrictionContactMaterial) { - return new GameLib.D3.FrictionContactMaterial( - this.physics, - contactMaterial - ); - } - return contactMaterial; - }.bind(this) - ); - - if (this.defaultContactMaterial instanceof GameLib.D3.API.FrictionContactMaterial) { - this.defaultContactMaterial = new GameLib.D3.FrictionContactMaterial( - this.physics, - this.defaultContactMaterial - ) - } - - GameLib.Component.call( - this, - { - 'broadphase' : GameLib.D3.Broadphase, - 'solver' : GameLib.D3.Solver, - 'rigidBodies' : [GameLib.D3.RigidBody], - 'contactMaterials' : [GameLib.D3.FrictionContactMaterial], - 'defaultContactMaterial' : GameLib.D3.FrictionContactMaterial - } - ); -}; - -GameLib.D3.PhysicsWorld.prototype = Object.create(GameLib.D3.API.PhysicsWorld.prototype); -GameLib.D3.PhysicsWorld.prototype.constructor = GameLib.D3.PhysicsWorld; - -/** - * private - * @returns {GameLib.D3.PhysicsWorld|GameLib.PhysicsRuntime.World|*} - */ -GameLib.D3.PhysicsWorld.prototype.createInstance = function() { - - if (GameLib.Utils.UndefinedOrNull(this.broadphase)) { - throw new Error('no broadphase'); - } - - if (GameLib.Utils.UndefinedOrNull(this.broadphase.instance)) { - throw new Error('no broadphase instance'); - } - - if (GameLib.Utils.UndefinedOrNull(this.solver)) { - throw new Error('no solver'); - } - - if (GameLib.Utils.UndefinedOrNull(this.solver.instance)) { - throw new Error('no solver instance'); - } - - this.instance = new CANNON.World(); - this.instance.broadphase = this.broadphase.instance; - this.instance.solver = this.solver.instance; - this.instance.gravity = this.gravity.instance; - this.instance.allowSleep = this.allowSleep; - - this.contactMaterials.map( - function (contactMaterial) { - - if (GameLib.Utils.UndefinedOrNull(contactMaterial)) { - throw new Error('no contact material'); - } - - if (GameLib.Utils.UndefinedOrNull(contactMaterial.instance)) { - throw new Error('no contact material instance'); - } - - this.instance.addContactMaterial(contactMaterial.instance); - - }.bind(this) - ); - - this.rigidBodies.map( - function (rigidBody) { - - if (GameLib.Utils.UndefinedOrNull(rigidBody)) { - throw new Error('no rigidbody'); - } - - if (GameLib.Utils.UndefinedOrNull(rigidBody.instance)) { - throw new Error('no rigidbody instance'); - } - - rigidBody.parentPhysicsWorld = this; - - this.instance.add(rigidBody.instance); - - }.bind(this) - ); - - this.instance.defaultContactMaterial.friction = this.defaultContactMaterial.friction; - this.instance.defaultContactMaterial.restitution = this.defaultContactMaterial.restitution; - this.instance.defaultContactMaterial.contactEquationStiffness = this.defaultContactMaterial.contactEquationStiffness; - this.instance.defaultContactMaterial.contactEquationRelaxation = this.defaultContactMaterial.contactEquationRelaxation; - this.instance.defaultContactMaterial.frictionEquationStiffness = this.defaultContactMaterial.frictionEquationStiffness; - this.instance.defaultContactMaterial.frictionEquationRelaxation = this.defaultContactMaterial.frictionEquationRelaxation; - - GameLib.Component.prototype.createInstance.call(this); -}; - -GameLib.D3.PhysicsWorld.prototype.addRigidBody = function(rigidBody) { - - if (rigidBody && rigidBody.instance) { - - /** - * Add the rigid body to the instance world - */ - this.instance.add(rigidBody.instance); - - /** - * Remember to set the parentPhysicsWorld for this rigidBody - * @type {GameLib.D3.PhysicsWorld} - */ - rigidBody.parentPhysicsWorld = this; - - /** - * Ensure this rigidBody is in our rigidBodies array, just not too many times.. - */ - GameLib.Utils.PushUnique(this.rigidBodies, rigidBody); - - } else { - console.warn('Attempt to add rigidBody ' + rigidBody.name + ' without an instance'); - } -}; - -/** - * - * @param rigidBody - */ -GameLib.D3.PhysicsWorld.prototype.removeRigidBody = function(rigidBody) { - - if (!rigidBody instanceof GameLib.D3.RigidBody) { - console.warn('not a rigid body'); - return; - } - - /** - * Remove the instance - */ - if (rigidBody.instance) { - - this.instance.remove(rigidBody.instance); - - } else { - console.warn('Attempt to remove rigidBody ' + rigidBody.name + ' without an instance'); - } - - /** - * Remember to set the parentPhysicsWorld for this rigidBody - * @type {GameLib.D3.PhysicsWorld} - */ - rigidBody.parentPhysicsWorld = null; - - /** - * Remove from this rigidBodies array - */ - var index = this.rigidBodies.indexOf(rigidBody); - - if (index !== -1) { - this.rigidBodies.splice(index, 1); - } else { - console.warn('could not remove a rigidbody from an array where it should have existed'); - } - -}; - - -/** - * - */ -GameLib.D3.PhysicsWorld.prototype.updateInstance = function() { - - if (!this.instance) { - console.log('no world instance'); - return; - } - - this.instance.broadphase = this.broadphase.instance; - this.instance.solver = this.solver.instance; - this.instance.gravity = this.gravity.instance; - this.instance.allowSleep = this.allowSleep; - - this.instance.defaultContactMaterial.friction = this.defaultContactMaterial.friction; - this.instance.defaultContactMaterial.restitution = this.defaultContactMaterial.restitution; - this.instance.defaultContactMaterial.contactEquationStiffness = this.defaultContactMaterial.contactEquationStiffness; - this.instance.defaultContactMaterial.contactEquationRelaxation = this.defaultContactMaterial.contactEquationRelaxation; - this.instance.defaultContactMaterial.frictionEquationStiffness = this.defaultContactMaterial.frictionEquationStiffness; - this.instance.defaultContactMaterial.frictionEquationRelaxation = this.defaultContactMaterial.frictionEquationRelaxation; - -}; - -/** - * GameLib.D3.PhysicsWorld to GameLib.D3.API.PhysicsWorld - * @returns {GameLib.D3.API.PhysicsWorld} - */ -GameLib.D3.PhysicsWorld.prototype.toApiObject = function() { - - var apiWorld = new GameLib.D3.API.PhysicsWorld( - this.id, - this.name, - this.gravity.toApiObject(), - GameLib.Utils.IdOrNull(this.broadphase), - GameLib.Utils.IdOrNull(this.solver), - this.rigidBodies.map(function(body){ - return GameLib.Utils.IdOrNull(body); - }), - this.contactMaterials.map(function(contactMaterial){ - return GameLib.Utils.IdOrNull(contactMaterial); - }), - this.allowSleep, - GameLib.Utils.IdOrNull(this.defaultContactMaterial), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiWorld; -}; - -/** - * GameLib.D3.PhysicsWorld from Object World - * @param graphics - * @param objectComponent - * @returns {GameLib.D3.PhysicsWorld} - * @constructor - */ -GameLib.D3.PhysicsWorld.FromObject = function(graphics, objectComponent) { - var apiWorld = GameLib.D3.API.PhysicsWorld.FromObject(objectComponent); - return new GameLib.D3.PhysicsWorld( - graphics, - apiWorld - ); -}; - -// -// GameLib.D3.PhysicsWorld.prototype.step = function( -// fixedStep, -// dtStep -// ) { -// -// }; -// -// GameLib.D3.PhysicsWorld.prototype.generateWireframeViewTriangleMesh = function( -// graphics, -// triangleMeshShape, -// normalLength, -// scale, -// opacity, -// wireframeColor -// ) { -// graphics.isNotThreeThrow(); -// this.engine.isNotCannonThrow(); -// -// if(typeof normalLength == 'undefined') { -// normalLength = 10; -// } -// -// if(typeof scale == 'undefined') { -// scale = new graphics.instance.Vector3(1, 1, 1); -// } -// -// if(typeof opacity == 'undefined') { -// opacity = 0.5; -// } -// -// if(typeof wireframeColor == 'undefined') { -// wireframeColor = 0xfefefe; -// } -// -// var graphicsGeometry = new graphics.instance.Geometry(); -// -// var wireframeMesh = new graphics.instance.Mesh( -// graphicsGeometry, -// new graphics.instance.MeshBasicMaterial({ -// color: wireframeColor, -// wireframe: true, -// opacity: opacity -// }) -// ); -// -// for(var v = 0, l = triangleMeshShape.instance.vertices.length / 3; v < l; ++v) { -// graphicsGeometry.vertices.push( -// new graphics.instance.Vector3( -// triangleMeshShape.instance.vertices[v * 3], -// triangleMeshShape.instance.vertices[v * 3 + 1], -// triangleMeshShape.instance.vertices[v * 3 + 2] -// ) -// ); -// } -// -// for(var i = 0, l = triangleMeshShape.instance.indices.length / 3; i < l; ++i) { -// var i0 = triangleMeshShape.instance.indices[i * 3]; -// var i1 = triangleMeshShape.instance.indices[i * 3 + 1]; -// var i2 = triangleMeshShape.instance.indices[i * 3 + 2]; -// -// graphicsGeometry.faces.push( -// new graphics.instance.Face3( -// i0, -// i1, -// i2 -// ) -// ); -// -// // Center point on the current triangle -// -// var centroid = new graphics.instance.Vector3() -// .add(graphicsGeometry.vertices[i0]) -// .add(graphicsGeometry.vertices[i1]) -// .add(graphicsGeometry.vertices[i2]) -// .divideScalar(3); -// -// // Get the normal from the mesh shape itself -// var normal = new this.engine.instance.Vec3(); -// triangleMeshShape.instance.getNormal(i , normal); -// -// var arrow = new graphics.instance.ArrowHelper( -// new graphics.instance.Vector3( -// normal.x, -// normal.y, -// normal.z -// ), -// centroid, -// normalLength, -// new graphics.instance.Color( -// normal.x, -// normal.y, -// normal.z -// ) -// ); -// wireframeMesh.add( arrow ); -// } -// -// wireframeMesh.scale.x = scale.x; -// wireframeMesh.scale.y = scale.y; -// wireframeMesh.scale.z = scale.z; -// -// return wireframeMesh; -// }; -// -// /** -// * @param convexPolyMeshShape GameLib.D3.Shape -// * @param normalLength Number -// * @param scale GameLib.API.Vector3 -// * @param opacity Number -// * @param wireframeColor HexCode -// * @param graphics THREE -// * @returns {THREE.Mesh|this.meshes} -// * @constructor -// */ -// GameLib.D3.PhysicsWorld.prototype.generateWireframeViewConvexPolyMesh = function( -// graphics, -// convexPolyMeshShape, -// normalLength, -// scale, -// opacity, -// wireframeColor -// ) { -// graphics.isNotThreeThrow(); -// this.engine.isNotCannonThrow(); -// -// if(typeof normalLength == 'undefined') { -// normalLength = 10; -// } -// -// if(typeof scale == 'undefined') { -// scale = new graphics.instance.Vector3(1, 1, 1); -// } -// -// if(typeof opacity == 'undefined') { -// opacity = 0.5; -// } -// -// if(typeof wireframeColor == 'undefined') { -// wireframeColor = 0xfefefe; -// } -// -// -// var graphicsGeometry = new graphics.instance.Geometry(); -// var wireframeMesh = new graphics.instance.Mesh( -// graphicsGeometry, -// new graphics.instance.MeshBasicMaterial({ -// color: wireframeColor, -// wireframe: true, -// opacity: opacity -// }) -// ); -// -// for(var i = 0, l = convexPolyMeshShape.instance.vertices.length; i < l; i++) { -// var vertex = convexPolyMeshShape.instance.vertices[i]; -// graphicsGeometry.vertices.push(new graphics.instance.Vector3(vertex.x, vertex.y, vertex.z)); -// } -// -// for(var i = 0, l = convexPolyMeshShape.instance.faces.length; i < l; i++) { -// var face = convexPolyMeshShape.instance.faces[i]; -// -// var i0 = face[0]; -// var i1 = face[1]; -// var i2 = face[2]; -// -// graphicsGeometry.faces.push(new graphics.instance.Face3(i0, i1, i2)); -// -// // Center point on the current triangle -// var centroid = new graphics.instance.Vector3() -// .add(graphicsGeometry.vertices[i0]) -// .add(graphicsGeometry.vertices[i1]) -// .add(graphicsGeometry.vertices[i2]) -// .divideScalar(3); -// -// var normalVec3 = convexPolyMeshShape.instance.faceNormals[i]; -// var normal = new graphics.instance.Vector3( -// normalVec3.x, -// normalVec3.y, -// normalVec3.z -// ); -// -// var arrow = new graphics.instance.ArrowHelper( -// normal, -// centroid, -// normalLength, -// new graphics.instance.Color( -// normal.x, -// normal.y, -// normal.z -// ) -// ); -// -// wireframeMesh.add( arrow ); -// } -// -// wireframeMesh.scale.x = scale.x; -// wireframeMesh.scale.y = scale.y; -// wireframeMesh.scale.z = scale.z; -// -// return wireframeMesh; -// }; -// -// /** -// * @param graphics GameLib.GraphicsRuntime -// * @param graphicsMesh THREE.Mesh -// * @param mass Number -// * @param friction Number -// * @param createCollisionSubMeshes Boolean -// * @param facesPerSubsection Number -// * @param subsectionsToMerge Number -// * @returns {Object} -// * @constructor -// */ -// GameLib.D3.PhysicsWorld.prototype.generateTriangleMeshShapeDivided = function( -// graphics, -// graphicsMesh, -// mass, -// friction, -// createCollisionSubMeshes, -// facesPerSubsection, -// subsectionsToMerge -// ) { -// graphics.isNotThreeThrow(); -// this.engine.isNotCannonThrow(); -// -// if(mass == null || typeof mass == 'undefined') { -// mass = 0; -// } -// -// if(friction == null || typeof friction == 'undefined') { -// friction = 10; -// } -// -// if(createCollisionSubMeshes == null || typeof createCollisionSubMeshes == 'undefined') { -// createCollisionSubMeshes = false; -// } -// -// var processedFaces = 0; -// var facesPerSubSection = facesPerSubsection || 0; -// var subMeshesToMerge = subsectionsToMerge || 0; -// var totalAmtFaces = graphicsMesh.geometry.faces.length; -// var facesToProcess = createCollisionSubMeshes ? (subMeshesToMerge * facesPerSubSection) : totalAmtFaces; -// -// var pairs = []; // output -// -// var vertices = []; -// var indicies = []; -// -// for(var i = 0; i <= totalAmtFaces; i++) { -// if(processedFaces == facesToProcess || i == totalAmtFaces) { -// -// var body = null; -// -// var meshShape = new this.engine.instance.Trimesh(vertices, indicies); -// -// meshShape.setScale(new this.engine.instance.Vec3( -// graphicsMesh.scale.x, -// graphicsMesh.scale.y, -// graphicsMesh.scale.z -// )); -// -// meshShape.updateAABB(); -// meshShape.updateNormals(); -// meshShape.updateEdges(); -// meshShape.updateBoundingSphereRadius(); -// meshShape.updateTree(); -// -// body = new this.engine.instance.Body({ -// mass: mass, -// friction: friction -// }); -// body.addShape(meshShape); -// -// pairs.push({ -// threeObject : createCollisionSubMeshes ? null : graphicsMesh, -// physicsObject : body -// }); -// -// vertices = []; -// indicies = []; -// processedFaces = 0; -// -// if(i == totalAmtFaces) { -// return pairs; -// } -// } -// -// var face = graphicsMesh.geometry.faces[i]; -// indicies.push(indicies.length); -// indicies.push(indicies.length); -// indicies.push(indicies.length); -// -// var v0 = graphicsMesh.geometry.vertices[face.a]; -// var v1 = graphicsMesh.geometry.vertices[face.b]; -// var v2 = graphicsMesh.geometry.vertices[face.c]; -// -// vertices.push(v0.x, v0.y, v0.z); -// vertices.push(v1.x, v1.y, v1.z); -// vertices.push(v2.x, v2.y, v2.z); -// -// processedFaces++; -// } -// }; -// -// GameLib.D3.PhysicsWorld.prototype.generateConvexPolyShape = function( -// graphics, -// mesh -// ) { -// var processedFaces = 0; -// var facesPerSubSection = 2; // *2 -> SUBDIVISION MESH -// var subMeshesToMerge = 4; // *2 -> SUBDIVISION MESH -// var facesToProcess = subMeshesToMerge * facesPerSubSection; -// -// var vertices = []; -// var indicies = []; -// -// for(var i = 0; i <= mesh.geometry.faces.length; i++) { -// if(processedFaces == facesToProcess || i == mesh.geometry.faces.length) { -// -// // try and create convex poly........... -// var convexIndices = []; -// for(var index = 0; index < indicies.length / 3; index++) { -// convexIndices.push([ indicies[index * 3], indicies[index * 3 + 1], indicies[index * 3 + 2] ]); -// } -// -// var convexVertices = []; -// for(var vert = 0; vert < vertices.length / 3; vert++) { -// convexVertices[vert] = new CANNON.Vec3(vertices[vert * 3] * mesh.scale.x, vertices[vert * 3 + 1] * mesh.scale.y, vertices[vert * 3 + 2] * mesh.scale.z); -// } -// -// var meshShape = new GameLib.D3.Shape(this.engine, GameLib.D3.Shape.SHAPE_TYPE_CONVEX_HULL, {x:1,y:1,z:1},convexVertices, convexIndices); -// -// var body = new GameLib.D3.RigidBody(this.engine, 0, 1); -// body.addShape(meshShape); -// -// this.addRigidBody(body); -// -// vertices = []; -// indicies = []; -// processedFaces = 0; -// -// console.log("SPLIT MESH TO CONVEX POLY"); -// -// if(i == mesh.geometry.faces.length) { -// break; -// } -// } -// -// var face = mesh.geometry.faces[i]; -// indicies.push(indicies.length); -// indicies.push(indicies.length); -// indicies.push(indicies.length); -// -// var v0 = mesh.geometry.vertices[face.a]; -// var v1 = mesh.geometry.vertices[face.b]; -// var v2 = mesh.geometry.vertices[face.c]; -// -// vertices.push(v0.x, v0.y, v0.z); -// vertices.push(v1.x, v1.y, v1.z); -// vertices.push(v2.x, v2.y, v2.z); -// -// processedFaces++; -// } -// -// }; -// -// /** -// * @param graphics GameLib.GraphicsRuntime -// * @param graphicsMesh THREE.Mesh -// * @returns {GameLib.D3.Shape} -// * @constructor -// */ -// GameLib.D3.PhysicsWorld.prototype.generateTriangleMeshShape = function( -// graphics, -// graphicsMesh -// ) { -// -// // - - - - - - - - - - - - - - - - - - - - - - - - - -// // Note: I did not test this yet with the API data. -// // - - - - - - - - - - - - - - - - - - - - - - - - - -// -// var scaledVertices = []; -// for(var i = 0, l = graphicsMesh.geometry.vertices.length; i < l; i++) { -// -// var vertex = graphicsMesh.geometry.vertices[i]; -// -// scaledVertices.push(new this.engine.instance.Vec3( -// vertex.x * graphicsMesh.scale.x, -// vertex.y * graphicsMesh.scale.y, -// vertex.z * graphicsMesh.scale.z -// )); -// } -// -// var triangleFaces = []; -// for(var f = 0, fl = graphicsMesh.geometry.faces.length; f < fl; f++) { -// var i0 = graphicsMesh.geometry.faces[f].a; -// var i1 = graphicsMesh.geometry.faces[f].b; -// var i2 = graphicsMesh.geometry.faces[f].c; -// -// triangleFaces.push([ -// i0, i1, i2 -// ]); -// } -// -// // - - - - - - - - - - - - - - - - - - - -// // Create collision mesh -// // - - - - - - - - - - - - - - - - - - - -// -// var reindexedFaces = {}; -// var vertices = []; -// var faces = []; -// -// var processedFaces = 0; -// var totalFacesToProcess = triangleFaces.length; -// var flLastIndex = 0; -// -// for(var f = 0; f < totalFacesToProcess; f++) { -// -// var i0 = triangleFaces[f][0]; -// var i1 = triangleFaces[f][1]; -// var i2 = triangleFaces[f][2]; -// -// if(typeof reindexedFaces[i0] === 'undefined') { -// vertices.push(scaledVertices[i0].x, scaledVertices[i0].y, scaledVertices[i0].z); -// reindexedFaces[i0] = flLastIndex; -// flLastIndex++; -// } -// -// if(typeof reindexedFaces[i1] === 'undefined') { -// vertices.push(scaledVertices[i1].x, scaledVertices[i1].y, scaledVertices[i1].z); -// reindexedFaces[i1] = flLastIndex; -// flLastIndex++; -// } -// -// if(typeof reindexedFaces[i2] === 'undefined') { -// vertices.push(scaledVertices[i2].x, scaledVertices[i2].y, scaledVertices[i2].z); -// reindexedFaces[i2] = flLastIndex; -// flLastIndex++; -// } -// -// faces.push(reindexedFaces[i0], reindexedFaces[i1], reindexedFaces[i2]); -// -// processedFaces++; -// } -// -// return new GameLib.D3.Shape(this.engine, GameLib.D3.Shape.SHAPE_TYPE_TRIMESH, {x : 1, y : 1, z : 1}, vertices, faces); -// }; -// -// /** -// * @param triangleMeshBody GameLib.D3.RigidBody -// * @param rayscale Number -// * @param maxTriangleDistance Number -// * @param createCompoundShape Boolean -// * @param graphics GameLib.GraphicsRuntime -// * @param triangleMeshShapes GameLib.D3.Shape[] -// * @param createDebugView Boolean -// * @returns {GameLib.D3.RigidBody} -// * @constructor -// */ -// GameLib.D3.PhysicsWorld.prototype.fixupTriangleMeshShape = function( -// triangleMeshBody, -// triangleMeshShapes, -// rayscale, -// maxTriangleDistance, -// createCompoundShape, -// graphics, -// createDebugView -// ) { -// this.engine.isNotCannonThrow(); -// -// graphics.isNotThreeThrow(); -// -// if(rayscale == null || typeof rayscale == 'undefined' || rayscale == 0) { -// rayscale = 10; -// } -// -// if(maxTriangleDistance == null || typeof maxTriangleDistance == 'undefined') { -// maxTriangleDistance = 13; -// } -// -// var world = this.instance; -// -// var raycastResult = new this.engine.instance.RaycastResult(); -// -// var brokenFaceIndicators = []; -// -// var totalFaces = 0; -// var totalBrokenFaces = 0; -// var totalFixedFaces = 0; -// var fixedTriangleMeshObjects = []; -// -// for(var i in triangleMeshShapes) { -// var trimesh = triangleMeshShapes[i].instance; -// -// var brokenFaces = []; -// totalFaces += (trimesh.indices.length / 3); -// -// for(var face = 0; face < trimesh.indices.length / 3; face++) { -// -// var i0 = trimesh.indices[face * 3]; -// var i1 = trimesh.indices[face * 3 + 1]; -// var i2 = trimesh.indices[face * 3 + 2]; -// -// var triangleCenterPoint = new graphics.instance.Vector3() -// .add(new graphics.instance.Vector3( -// trimesh.vertices[i0 * 3], -// trimesh.vertices[i0 * 3 + 1], -// trimesh.vertices[i0 * 3 + 2]) -// ) -// .add(new graphics.instance.Vector3( -// trimesh.vertices[i1 * 3], -// trimesh.vertices[i1 * 3 + 1], -// trimesh.vertices[i1 * 3 + 2]) -// ) -// .add(new graphics.instance.Vector3( -// trimesh.vertices[i2 * 3], -// trimesh.vertices[i2 * 3 + 1], -// trimesh.vertices[i2 * 3 + 2]) -// ) -// .divideScalar(3); -// -// var triangleNormal = new this.engine.instance.Vec3(); -// trimesh.getNormal(face , triangleNormal); -// -// var from = new this.engine.instance.Vec3( -// triangleCenterPoint.x + triangleNormal.x, -// triangleCenterPoint.y + triangleNormal.y, -// triangleCenterPoint.z + triangleNormal.z -// ); -// -// var to = new this.engine.instance.Vec3( -// from.x - triangleNormal.x * rayscale, -// from.y - triangleNormal.y * rayscale, -// from.z - triangleNormal.z * rayscale -// ); -// -// world.raycastClosest(from, to, {}, raycastResult); -// -// // visualize results -// if(createDebugView){ -// var graphicsGeometry = new graphics.instance.Geometry(); -// var wireframeMesh = new graphics.instance.Mesh( -// graphicsGeometry, -// new graphics.instance.MeshBasicMaterial({ -// color: 0xff0000, -// wireframe: true, -// opacity: 1 -// }) -// ); -// -// var arrow = new graphics.instance.ArrowHelper( -// new graphics.instance.Vector3( -// triangleNormal.x, -// triangleNormal.y, -// triangleNormal.z -// ).normalize(), -// -// new graphics.instance.Vector3( -// from.x, -// from.y, -// from.z -// ), -// -// rayscale / 2, -// raycastResult.hasHit ? new graphics.instance.Color(0, 1, 0) -// : new graphics.instance.Color(1, 0, 0) -// ); -// -// wireframeMesh.add( arrow ); -// brokenFaceIndicators.push(wireframeMesh); -// } -// -// if(!raycastResult.hasHit) { -// brokenFaces.push({ -// faceIndex : face, -// -// vertices : [ -// new this.engine.instance.Vec3( -// trimesh.vertices[i0 * 3], -// trimesh.vertices[i0 * 3 + 1], -// trimesh.vertices[i0 * 3 + 2] -// ), -// -// new this.engine.instance.Vec3( -// trimesh.vertices[i1 * 3], -// trimesh.vertices[i1 * 3 + 1], -// trimesh.vertices[i1 * 3 + 2] -// ), -// -// new this.engine.instance.Vec3( -// trimesh.vertices[i2 * 3], -// trimesh.vertices[i2 * 3 + 1], -// trimesh.vertices[i2 * 3 + 2] -// ) -// ], -// -// center : triangleCenterPoint, -// -// parent : trimesh -// }); -// } -// } -// -// // fix up broken faces -// -// var bFaceIndexed = {}; -// for(var b = 0; b < brokenFaces.length; b++) { -// var brokenFace = brokenFaces[b]; -// -// if(brokenFace.marked) { -// continue; -// } -// -// bFaceIndexed[b] = { -// indices : [], -// vertices : [] -// }; -// -// var indicesAmount = bFaceIndexed[b].indices.length; -// -// // add the current broken face itself to the array -// bFaceIndexed[b].indices.push( -// indicesAmount, -// indicesAmount + 1, -// indicesAmount + 2 -// ); -// -// bFaceIndexed[b].vertices.push( -// brokenFace.vertices[0].x, -// brokenFace.vertices[0].y, -// brokenFace.vertices[0].z -// ); -// -// bFaceIndexed[b].vertices.push( -// brokenFace.vertices[1].x, -// brokenFace.vertices[1].y, -// brokenFace.vertices[1].z -// ); -// -// bFaceIndexed[b].vertices.push( -// brokenFace.vertices[2].x, -// brokenFace.vertices[2].y, -// brokenFace.vertices[2].z -// ); -// -// for(var bb = 0; bb < brokenFaces.length; bb++) { -// -// if(bb == b) { -// continue; -// } -// -// var otherBrokenFace = brokenFaces[bb]; -// -// if(otherBrokenFace.marked) { -// continue; -// } -// -// if(brokenFace.center.distanceTo(otherBrokenFace.center) <= maxTriangleDistance) { -// var indicesAmount = bFaceIndexed[b].indices.length; -// -// bFaceIndexed[b].indices.push( -// indicesAmount, -// indicesAmount + 1, -// indicesAmount + 2 -// ); -// -// bFaceIndexed[b].vertices.push( -// otherBrokenFace.vertices[0].x, -// otherBrokenFace.vertices[0].y, -// otherBrokenFace.vertices[0].z -// ); -// -// bFaceIndexed[b].vertices.push( -// otherBrokenFace.vertices[1].x, -// otherBrokenFace.vertices[1].y, -// otherBrokenFace.vertices[1].z -// ); -// -// bFaceIndexed[b].vertices.push( -// otherBrokenFace.vertices[2].x, -// otherBrokenFace.vertices[2].y, -// otherBrokenFace.vertices[2].z -// ); -// -// otherBrokenFace.marked = true; -// } -// } -// } -// -// -// // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// // Decide if we want to create new rigiwyd bodies, or create a compound mesh -// // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// -// for(var e in bFaceIndexed) { -// var element = bFaceIndexed[e]; -// -// var shape = new GameLib.D3.Shape(this.engine, GameLib.D3.Shape.SHAPE_TYPE_TRIMESH, { x : 1, y : 1, z : 1 }, element.vertices, element.indices); -// -// if(createCompoundShape) { -// triangleMeshBody.addShape(shape); -// } else { -// -// var body = new GameLib.D3.RigidBody(this.engine, 0, 12); -// -// //TODO: this is just a hack. -// body.instance.collisionFilterGroup = 1 | 2; // puts this body in two groups. -// -// body.addShape(shape); -// this.addRigidBody(body); -// } -// -// fixedTriangleMeshObjects.push(shape); -// totalFixedFaces += element.indices.length / 3; -// } -// -// // TODO: remove duplicate indices -// /*trimesh.updateNormals(); -// trimesh.updateEdges(); -// trimesh.updateTree(); -// trimesh.updateAABB(); -// trimesh.updateBoundingSphereRadius();*/ -// -// // map faceIndex to flat face index (faceIndex * 3) +0, 1, 2 -> triangle indices -// console.log("i = " + i, brokenFaces); -// totalBrokenFaces += brokenFaces.length; -// } -// -// console.log("total faces", totalFaces); -// console.log("total broken faces", totalBrokenFaces); -// console.log("broken faces in percent", (totalBrokenFaces / totalFaces) * 100); -// console.log("total fixed faces", totalFixedFaces); -// console.log("fixed triangle mesh shapes", fixedTriangleMeshObjects.length); -// -// return { -// brokenFaceIndicators : brokenFaceIndicators, -// fixedTriangleMeshShapes : fixedTriangleMeshObjects -// }; -// }; -/** - * Contains a Poly vertex data structure - * @param localIndex - * @param mvertIndex - * @param uv GameLib.API.Vector2 - * @param materialIndex - * @param edgeIndex - * @constructor - */ -GameLib.D3.PolyVertex = function( - localIndex, - mvertIndex, - uv, - materialIndex, - edgeIndex -) { - this.localIndex = localIndex; - this.mvertIndex = mvertIndex; - this.uv = uv; - this.materialIndex = materialIndex; - this.edgeIndex = edgeIndex; -}; - -/** - * Clone a PolyVertex - * @returns {GameLib.D3.PolyVertex} - */ -GameLib.D3.PolyVertex.prototype.clone = function() { - return new GameLib.D3.PolyVertex( - this.localIndex, - this.mvertIndex, - this.uv.copy(), - this.materialIndex, - this.edgeIndex - ) -}; -/** - * RaycastVehicle Runtime - * @param physics GameLib.GraphicsRuntime - * @param apiRaycastVehicle GameLib.D3.API.RaycastVehicle - * @constructor - */ -GameLib.D3.RaycastVehicle = function ( - physics, - apiRaycastVehicle -) { - - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiRaycastVehicle)) { - apiRaycastVehicle = {}; - } - - if (apiRaycastVehicle instanceof GameLib.D3.RaycastVehicle) { - return apiRaycastVehicle; - } - - GameLib.D3.API.RaycastVehicle.call( - this, - apiRaycastVehicle.id, - apiRaycastVehicle.name, - apiRaycastVehicle.chassis, - apiRaycastVehicle.wheels, - apiRaycastVehicle.raycastWheels, - apiRaycastVehicle.parentPhysicsWorld, - apiRaycastVehicle.parentEntity - ); - - if (this.chassis instanceof GameLib.D3.API.RaycastVehicle) { - this.chassis = new GameLib.D3.RaycastVehicle( - this.physics, - this.chassis - ) - } - - this.wheels = this.wheels.map(function(wheel){ - if (wheel instanceof GameLib.D3.API.RigidBody) { - return new GameLib.D3.RigidBody( - this.physics, - wheel - ) - } else { - return wheel; - } - }.bind(this)); - - this.raycastWheels = this.raycastWheels.map(function(raycastWheel){ - if (raycastWheel instanceof GameLib.D3.API.RaycastWheel) { - return new GameLib.D3.RaycastWheel( - this.physics, - raycastWheel - ) - } else { - return raycastWheel; - } - }.bind(this)); - - GameLib.Component.call( - this, - { - 'chassis' : GameLib.D3.RigidBody, - 'wheels' : [GameLib.D3.RigidBody], - 'raycastWheels' : [GameLib.D3.RaycastWheel], - 'parentPhysicsWorld' : GameLib.D3.PhysicsWorld - } - ); -}; - -GameLib.D3.RaycastVehicle.prototype = Object.create(GameLib.D3.API.RaycastVehicle.prototype); -GameLib.D3.RaycastVehicle.prototype.constructor = GameLib.D3.RaycastVehicle; - -/** - * - * @returns {*} - */ -GameLib.D3.RaycastVehicle.prototype.createInstance = function() { - - /** - * At this point - even though this component exists - the chassis could maybe not been have assigned, failed to - * register as a dependency, and therefore is not present at the time of createInstance() - we will need to call - * delayedInstance somehow... - * @type {GameLib.D3.RaycastVehicle|GameLib.D3.API.RaycastVehicle|*} - */ - - if (GameLib.Utils.UndefinedOrNull(this.chassis)) { - throw new Error('no chassis'); - } - - if (GameLib.Utils.UndefinedOrNull(this.chassis.instance)) { - throw new Error('no chassis instance'); - } - - if (GameLib.Utils.UndefinedOrNull(this.parentPhysicsWorld)) { - throw new Error('no parent world'); - } - - if (GameLib.Utils.UndefinedOrNull(this.parentPhysicsWorld.instance)) { - throw new Error('no parent world instance'); - } - - this.instance = new CANNON.RaycastVehicle({ - chassisBody: this.chassis.instance - }); - - this.raycastWheels.map( - function(wheel){ - - if (GameLib.Utils.UndefinedOrNull(wheel)) { - throw new Error('no wheel'); - } - - if (GameLib.Utils.UndefinedOrNull(wheel.instance)) { - throw new Error('no wheel instance'); - } - - this.instance.addWheel(wheel.instance); - - }.bind(this) - ); - - this.instance.addToWorld(this.parentPhysicsWorld.instance); - - GameLib.Component.prototype.createInstance.call(this); - -}; - -GameLib.D3.RaycastVehicle.prototype.updateInstance = function() { - // this.instance.chassisBody = this.chassis.instance; - //TODO: add / remove wheels? - console.log('TODO: update raycast vehicle instance'); -}; - -/** - * GameLib.D3.RaycastVehicle to GameLib.D3.API.RaycastVehicle - * @returns {GameLib.D3.API.RaycastVehicle} - */ -GameLib.D3.RaycastVehicle.prototype.toApiObject = function() { - - var apiRaycastVehicle = new GameLib.D3.API.RaycastVehicle( - this.id, - this.name, - GameLib.Utils.IdOrNull(this.chassis), - this.wheels.map(function(wheel){ - return GameLib.Utils.IdOrNull(wheel); - }), - this.raycastWheels.map(function(raycastWheel){ - return GameLib.Utils.IdOrNull(raycastWheel); - }), - GameLib.Utils.IdOrNull(this.parentPhysicsWorld), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiRaycastVehicle; -}; - -/** - * GameLib.D3.RaycastVehicle from Object RaycastVehicle - * @param physics - * @param objectComponent - * @returns {GameLib.D3.RaycastVehicle} - * @constructor - */ -GameLib.D3.RaycastVehicle.FromObject = function(physics, objectComponent) { - - var apiRaycastVehicle = GameLib.D3.API.RaycastVehicle.FromObject(objectComponent); - - return new GameLib.D3.RaycastVehicle( - physics, - apiRaycastVehicle - ); -}; - -/** - * RaycastWheel Runtime - * @param physics GameLib.GraphicsRuntime - * @param apiRaycastWheel GameLib.D3.API.RaycastWheel - * @constructor - */ -GameLib.D3.RaycastWheel = function ( - physics, - apiRaycastWheel -) { - - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiRaycastWheel)) { - apiRaycastWheel = {}; - } - - if (apiRaycastWheel instanceof GameLib.D3.RaycastWheel) { - return apiRaycastWheel; - } - - GameLib.D3.API.RaycastWheel.call( - this, - apiRaycastWheel.id, - apiRaycastWheel.name, - apiRaycastWheel.radius, - apiRaycastWheel.directionLocal, - apiRaycastWheel.suspensionStiffness, - apiRaycastWheel.suspensionRestLength, - apiRaycastWheel.frictionSlip, - apiRaycastWheel.dampingRelaxation, - apiRaycastWheel.dampingCompression, - apiRaycastWheel.maxSuspensionForce, - apiRaycastWheel.rollInfluence, - apiRaycastWheel.axleLocal, - apiRaycastWheel.chassisConnectionPointLocal, - apiRaycastWheel.maxSuspensionTravel, - apiRaycastWheel.customSlidingRotationalSpeed, - apiRaycastWheel.useCustomSlidingRotationalSpeed, - apiRaycastWheel.parentMesh, - apiRaycastWheel.parentEntity - ); - - this.directionLocal = new GameLib.Vector3( - this.physics, - this.directionLocal, - this - ); - - this.axleLocal = new GameLib.Vector3( - this.physics, - this.axleLocal, - this - ); - - this.chassisConnectionPointLocal = new GameLib.Vector3( - this.physics, - this.chassisConnectionPointLocal, - this - ); - - GameLib.Component.call( - this, - { - 'parentMesh' : GameLib.D3.Mesh - } - ); -}; - -GameLib.D3.RaycastWheel.prototype = Object.create(GameLib.D3.API.RaycastWheel.prototype); -GameLib.D3.RaycastWheel.prototype.constructor = GameLib.D3.RaycastWheel; - -/** - * - * @returns {*} - */ -GameLib.D3.RaycastWheel.prototype.createInstance = function() { - - this.instance = { - radius: this.radius, - directionLocal: this.directionLocal.instance, - suspensionStiffness: this.suspensionStiffness, - suspensionRestLength: this.suspensionRestLength, - frictionSlip: this.frictionSlip, - dampingRelaxation: this.dampingRelaxation, - dampingCompression: this.dampingCompression, - maxSuspensionForce: this.maxSuspensionForce, - rollInfluence: this.rollInfluence, - axleLocal: this.axleLocal.instance, - chassisConnectionPointLocal: this.chassisConnectionPointLocal.instance, - maxSuspensionTravel: this.maxSuspensionTravel, - customSlidingRotationalSpeed: this.customSlidingRotationalSpeed, - useCustomSlidingRotationalSpeed: this.useCustomSlidingRotationalSpeed - }; - - GameLib.Component.prototype.createInstance.call(this); -}; - -GameLib.D3.RaycastWheel.prototype.updateInstance = function() { - this.instance.radius = this.radius; - this.instance.directionLocal = this.directionLocal.instance; - this.instance.suspensionStiffness = this.suspensionStiffness; - this.instance.suspensionRestLength = this.suspensionRestLength; - this.instance.frictionSlip = this.frictionSlip; - this.instance.dampingRelaxation = this.dampingRelaxation; - this.instance.dampingCompression = this.dampingCompression; - this.instance.maxSuspensionForce = this.maxSuspensionForce; - this.instance.rollInfluence = this.rollInfluence; - this.instance.axleLocal = this.axleLocal.instance; - this.instance.chassisConnectionPointLocal = this.chassisConnectionPointLocal.instance; - this.instance.maxSuspensionTravel = this.maxSuspensionTravel; - this.instance.customSlidingRotationalSpeed = this.customSlidingRotationalSpeed; - this.instance.useCustomSlidingRotationalSpeed = this.useCustomSlidingRotationalSpeed; -}; - -/** - * GameLib.D3.RaycastWheel to GameLib.D3.API.RaycastWheel - * @returns {GameLib.D3.API.RaycastWheel} - */ -GameLib.D3.RaycastWheel.prototype.toApiObject = function() { - - var apiRaycastWheel = new GameLib.D3.API.RaycastWheel( - this.id, - this.name, - this.radius, - this.directionLocal.toApiObject(), - this.suspensionStiffness, - this.suspensionRestLength, - this.frictionSlip, - this.dampingRelaxation, - this.dampingCompression, - this.maxSuspensionForce, - this.rollInfluence, - this.axleLocal.toApiObject(), - this.chassisConnectionPointLocal.toApiObject(), - this.maxSuspensionTravel, - this.customSlidingRotationalSpeed, - this.useCustomSlidingRotationalSpeed, - GameLib.Utils.IdOrNull(this.parentMesh), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiRaycastWheel; -}; - -/** - * GameLib.D3.RaycastWheel from Object RaycastWheel - * @param physics - * @param objectComponent - * @returns {GameLib.D3.RaycastWheel} - * @constructor - */ -GameLib.D3.RaycastWheel.FromObject = function(physics, objectComponent) { - - var apiRaycastWheel = GameLib.D3.API.RaycastWheel.FromObject(objectComponent); - - return new GameLib.D3.RaycastWheel( - physics, - apiRaycastWheel - ); -}; - -GameLib.D3.RaycastWheel.prototype.setChassisLocalConnectionPoint = function() { - - if (!this.parentMesh) { - console.log('you need to set the parent mesh first'); - } - - this.chassisConnectionPointLocal.x = this.parentMesh.position.x; - this.chassisConnectionPointLocal.y = this.parentMesh.position.y; - this.chassisConnectionPointLocal.z = this.parentMesh.position.z; - -}; -/** - * Raycaster for GameLib.D3 - * @param graphics GameLib.GraphicsRuntime - * @param apiRaycaster - * @constructor - */ -GameLib.D3.Raycaster = function( - graphics, - apiRaycaster -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiRaycaster)) { - apiRaycaster = {}; - } - - if (apiRaycaster instanceof GameLib.D3.Raycaster) { - return apiRaycaster; - } - - GameLib.D3.API.Raycaster.call( - this, - apiRaycaster.id, - apiRaycaster.name, - apiRaycaster.position, - apiRaycaster.direction - ); - - this.position = new GameLib.Vector3( - this.graphics, - this.position, - this - ); - - this.direction = new GameLib.Vector3( - this.graphics, - this.direction, - this - ); - - GameLib.Component.call(this); -}; - -GameLib.D3.Raycaster.prototype = Object.create(GameLib.D3.API.Raycaster.prototype); -GameLib.D3.Raycaster.prototype.constructor = GameLib.D3.Raycaster; - -/** - * Creates or updates a raycaster instance - */ -GameLib.D3.Raycaster.prototype.createInstance = function() { - this.instance = new THREE.Raycaster(); - this.instance.set( - this.position.instance, - this.direction.instance - ); - - GameLib.Component.prototype.createInstance.call(this); -}; - -GameLib.D3.Raycaster.prototype.updateInstance = function() { - - this.position.instance.x = this.position.x; - this.position.instance.y = this.position.y; - this.position.instance.z = this.position.z; - - this.direction.instance.x = this.direction.x; - this.direction.instance.y = this.direction.y; - this.direction.instance.z = this.direction.z; - - this.instance.set( - this.position.instance, - this.direction.instance - ); -}; - -GameLib.D3.Raycaster.prototype.toApiObject = function() { - return new GameLib.D3.API.Raycaster( - this.id, - this.name, - this.position.toApiObject(), - this.direction.toApiObject(), - GameLib.Utils.IdOrNull(this.parentEntity) - ) -}; - -GameLib.D3.Raycaster.FromObject = function(graphics, objectRaycaster) { - - var apiRaycaster = GameLib.D3.API.Raycaster.FromObject(objectRaycaster); - - var raycaster = new GameLib.D3.Raycaster( - graphics, - apiRaycaster - ); - - return raycaster; -}; - -/** - * Sets the direction and position of this raycaster - * @param position GameLib.Vector3 - * @param direction GameLib.Vector3 - */ -GameLib.D3.Raycaster.prototype.set = function( - position, - direction -) { - this.position.x = position.x; - this.position.y = position.y; - this.position.z = position.z; - - this.direction.x = direction.x; - this.direction.y = direction.y; - this.direction.z = direction.z; - - this.position.updateInstance(); - this.direction.updateInstance(); -}; - -/** - * Sets the direction of this raycaster - * @param direction GameLib.Vector3 - */ -GameLib.D3.Raycaster.prototype.setDirection = function( - direction -) { - this.direction.x = direction.x; - this.direction.y = direction.y; - this.direction.z = direction.z; - - this.direction.updateInstance(); -}; - -/** - * Sets the position of this raycaster - * @param position GameLib.Vector3 - */ -GameLib.D3.Raycaster.prototype.setPosition = function( - position -) { - this.position.x = position.x; - this.position.y = position.y; - this.position.z = position.z; - - this.position.updateInstance(); -}; - -/** - * Sets the ray position and direction from the mouse coordinates (in proper x and y (-1 to 1)) - * @param mouse - * @param camera - */ -GameLib.D3.Raycaster.prototype.setFromCamera = function( - mouse, - camera -) { - this.instance.setFromCamera( - mouse, - camera.instance - ); - - this.position.x = this.instance.ray.origin.x; - this.position.y = this.instance.ray.origin.y; - this.position.z = this.instance.ray.origin.z; - - this.direction.x = this.instance.ray.direction.x; - this.direction.y = this.instance.ray.direction.y; - this.direction.z = this.instance.ray.direction.z; -}; - -/** - * Gets all interesected GameLib.D3.Mesh objects - * @param meshes [GameLib.D3.Mesh] - */ -GameLib.D3.Raycaster.prototype.getIntersectedObjects = function(meshes) { - - return meshes.reduce( - function (result, mesh) { - - var intersects = this.instance.intersectObject(mesh.instance); - - if (intersects.length > 0) { - result.push( - { - mesh: mesh, - distance : intersects[0].distance - } - ); - } - - return result; - }.bind(this), - [] - ); - - // var intersects = this.instance.intersectObjects(meshInstances); - // - // return intersects.reduce( - // - // function (result, intersect) { - // - // meshes.map( - // function(mesh){ - // if (mesh.instance === intersect.object){ - // result.push( - // { - // mesh : mesh, - // distance : intersect.distance - // } - // ); - // } - // } - // ); - // - // return result; - // }, - // [] - // ); - -}; - - -/** - * Returns the face normal (if any) of an intersection between current ray position, direction and a provided mesh - * @param mesh GameLib.D3.Mesh - * @returns {null | GameLib.Vector3} - */ -GameLib.D3.Raycaster.prototype.getFaceNormal = function(mesh) { - - var normal = null; - - var intersect = this.instance.intersectObject( - mesh.instance - ); - - if (intersect && intersect.length > 0) { - - normal = new GameLib.Vector3( - this.graphics, - new GameLib.API.Vector3( - intersect[0].face.normal.x, - intersect[0].face.normal.y, - intersect[0].face.normal.z - ), - this - ); - } - - return normal; -}; - -/** - * Returns the face normal (if any) of an intersection between current ray position, direction and a provided mesh - * @param mesh GameLib.D3.Mesh - * @returns {null | GameLib.Vector3} - */ -GameLib.D3.Raycaster.prototype.getIntersectPoint = function(mesh) { - - var point = null; - - var intersect = this.instance.intersectObject( - mesh.instance - ); - - if (intersect && intersect.length > 0) { - point = new GameLib.Vector3( - this.graphics, - new GameLib.API.Vector3( - intersect[0].point.x, - intersect[0].point.y, - intersect[0].point.z - ), - this - ); - } - - return point; -}; -/** - * Renders a scene with a camera - * @param graphics GameLib.GraphicsRuntime - * @param apiRenderTarget GameLib.D3.API.RenderTarget - * @constructor - */ -GameLib.D3.RenderTarget = function ( - graphics, - apiRenderTarget -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiRenderTarget)) { - apiRenderTarget = {}; - } - - if (apiRenderTarget instanceof GameLib.D3.RenderTarget) { - return apiRenderTarget; - } - - GameLib.D3.API.RenderTarget.call( - this, - apiRenderTarget.id, - apiRenderTarget.name, - apiRenderTarget.width, - apiRenderTarget.height, - apiRenderTarget.stencilBuffer, - apiRenderTarget.texture - ); - - GameLib.Component.call( - this, - { - 'texture' : GameLib.D3.Texture - } - ); -}; - -GameLib.D3.RenderTarget.prototype = Object.create(GameLib.D3.API.RenderTarget.prototype); -GameLib.D3.RenderTarget.prototype.constructor = GameLib.D3.RenderTarget; - -/** - * Creates a Render Target instance - * @returns {*} - */ -GameLib.D3.RenderTarget.prototype.createInstance = function() { - - if (GameLib.Utils.UndefinedOrNull(this.texture)) { - throw new Error('no texture'); - } - - if (GameLib.Utils.UndefinedOrNull(this.texture.instance)) { - throw new Error('no texture instance'); - } - - this.instance = new THREE.WebGLRenderTarget( - this.width, - this.height, - { - stencilBuffer : this.stencilBuffer - } - ); - - this.instance.texture = this.texture.instance; - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * updates instance - */ -GameLib.D3.RenderTarget.prototype.updateInstance = function() { - - if (this.instance) { - this.instance.setSize(this.width, this.height); - this.instance.stencilBuffer = this.stencilBuffer; - if (this.texture && this.texture.instance) { - this.instance.texture = this.texture.instance; - this.instance.texture.needsUpdate = true; - } else { - this.instance.texture = null; - } - } else { - try { - this.createInstance(); - } catch (error) { - console.error(error); - } - } -}; - -/** - * Render Target to API Render Target - * @returns {GameLib.D3.API.RenderTarget} - */ -GameLib.D3.RenderTarget.prototype.toApiObject = function() { - - var apiRenderTarget = new GameLib.D3.API.RenderTarget( - this.id, - this.name, - this.width, - this.height, - this.stencilBuffer, - GameLib.Utils.IdOrNull(this.texture), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiRenderTarget; -}; - -/** - * - * @param graphics - * @param objectComponent - * @returns {GameLib.D3.RenderTarget} - * @constructor - */ -GameLib.D3.RenderTarget.FromObject = function(graphics, objectComponent) { - - var apiRenderTarget = GameLib.D3.API.RenderTarget.FromObject(objectComponent); - - return new GameLib.D3.RenderTarget( - graphics, - apiRenderTarget - ); -}; - -/** - * Renders a scene with a camera - * @param graphics GameLib.GraphicsRuntime - * @param apiRenderer GameLib.D3.API.Renderer - * @constructor - */ -GameLib.D3.Renderer = function ( - graphics, - apiRenderer -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiRenderer)) { - apiRenderer = {}; - } - - if (apiRenderer instanceof GameLib.D3.Renderer) { - return apiRenderer; - } - - GameLib.D3.API.Renderer.call( - this, - apiRenderer.id, - apiRenderer.name, - apiRenderer.autoClear, - apiRenderer.localClipping, - apiRenderer.width, - apiRenderer.height, - apiRenderer.preserveDrawingBuffer, - apiRenderer.domElement, - apiRenderer.clearColor, - apiRenderer.camera, - apiRenderer.scenes, - apiRenderer.viewports, - apiRenderer.clippingPlanes, - apiRenderer.bufferScene, - apiRenderer.bufferCamera, - apiRenderer.renderTarget, - apiRenderer.defaultScene, - apiRenderer.sortObjects, - apiRenderer.parentEntity - ); - - this.clearColor = new GameLib.Color( - this.graphics, - this.clearColor, - this - ); - - if (this.domElement instanceof GameLib.API.DomElement) { - this.domElement = new GameLib.DomElement( - this.domElement - ); - } - - if (this.camera instanceof GameLib.D3.API.Camera) { - this.camera = new GameLib.D3.Camera( - this.graphics, - this.camera - ) - } - - this.scenes = this.scenes.map(function(scene){ - if (scene instanceof GameLib.D3.API.Scene) { - return new GameLib.D3.Scene( - this.graphics, - scene - ); - } else { - return scene; - } - }.bind(this)); - - this.viewports = this.viewports.map(function(viewport){ - if (viewport instanceof GameLib.D3.API.Viewport) { - return new GameLib.D3.Viewport( - this.graphics, - viewport - ); - } else { - return viewport; - } - }.bind(this)); - - this.clippingPlanes = this.clippingPlanes.map(function(clippingPlane){ - if (clippingPlane instanceof GameLib.D3.API.Mesh) { - return new GameLib.D3.Mesh.Plane( - this.graphics, - clippingPlane, - clippingPlane.width, - clippingPlane.height, - clippingPlane.widthSegments, - clippingPlane.heightSegments, - clippingPlane.heightMapScale, - clippingPlane.isHeightMap, - clippingPlane.isClippingPlane, - clippingPlane.distanceFromOrigin - ); - } else { - return clippingPlane; - } - }.bind(this)); - - if (this.bufferScene instanceof GameLib.D3.API.Scene) { - this.bufferScene = new GameLib.D3.Scene( - this.graphics, - this.bufferScene - ) - } - - if (this.bufferCamera instanceof GameLib.D3.API.Camera) { - this.bufferCamera = new GameLib.D3.Camera( - this.graphics, - this.bufferCamera - ) - } - - if (this.renderTarget instanceof GameLib.D3.API.RenderTarget) { - this.renderTarget = new GameLib.D3.RenderTarget( - this.graphics, - this.renderTarget - ) - } - - GameLib.Component.call( - this, - { - 'domElement' : GameLib.DomElement, - 'camera' : GameLib.D3.Camera, - 'scenes' : [GameLib.D3.Scene], - 'viewports' : [GameLib.D3.Viewport], - 'clippingPlanes': [GameLib.D3.Mesh.Plane], - 'bufferScene' : GameLib.D3.Scene, - 'bufferCamera' : GameLib.D3.Camera, - 'renderTarget' : GameLib.D3.RenderTarget, - 'defaultScene' : GameLib.D3.Scene - } - ); - -}; - -GameLib.D3.Renderer.prototype = Object.create(GameLib.D3.API.Renderer.prototype); -GameLib.D3.Renderer.prototype.constructor = GameLib.D3.Renderer; - -/** - * Create Renderer Instance - * @returns {*} - */ -GameLib.D3.Renderer.prototype.createInstance = function() { - - if (GameLib.Utils.UndefinedOrNull(this.domElement)) { - throw new Error('no dom element'); - } - - if (GameLib.Utils.UndefinedOrNull(this.domElement.instance)) { - throw new Error('no dom element instance'); - } - - this.instance = new THREE.WebGLRenderer( - { - canvas : this.domElement.instance - } - ); - - if (this.clippingPlanes.length > 0) { - this.instance.clippingPlanes = this.clippingPlanes.map( - function(clippingPlane) { - - if (!clippingPlane.isClippingPlane || !clippingPlane.instance || !clippingPlane.instance.clipping) { - throw new Error('is not a clipping plane or no clipping plane instance'); - } - - return clippingPlane.instance.clipping; - } - ) - } - - this.instance.localClippingEnabled = this.localClipping; - - this.instance.setSize( - this.width, - this.height - ); - - this.instance.setClearColor( - new THREE.Color( - this.clearColor.r, - this.clearColor.g, - this.clearColor.b - ), - 1 - this.clearColor.a - ); - - this.instance.domElement.width = this.width; - this.instance.domElement.height = this.height; - - this.instance.autoClear = this.autoClear; - this.instance.preserveDrawingBuffer = this.preserveDrawingBuffer; - - this.instance.sortObjects = this.sortObjects; - - GameLib.Component.prototype.createInstance.call(this); - -}; - -/** - * - */ -GameLib.D3.Renderer.prototype.updateInstance = function(property) { - - if (!this.instance) { - try { - this.createInstance(); - } catch (error) { - console.error(error.message); - } - return; - } - - if (!property) { - console.error('no property for renderer'); - } - - if (property === 'localClipping') { - this.instance.localClippingEnabled = this.localClipping; - } - - if (property === 'width' || 'height') { - this.instance.setSize( - this.width, - this.height - ); - - this.instance.domElement.width = this.width; - this.instance.domElement.height = this.height; - } - - - if (property === 'clearColor') { - this.instance.setClearColor( - new THREE.Color( - this.clearColor.r, - this.clearColor.g, - this.clearColor.b - ), - 1 - this.clearColor.a - ); - } - - - if (property === 'autoClear') { - this.instance.autoClear = this.autoClear; - } - - if (property === 'preserveDrawingBuffer') { - this.instance.preserveDrawingBuffer = this.preserveDrawingBuffer; - } - - if (this.clippingPlanes.length > 0) { - this.instance.clippingPlanes = this.clippingPlanes.map( - function(clippingPlane) { - - if (!clippingPlane.isClippingPlane || !clippingPlane.instance || !clippingPlane.instance.clipping) { - throw new Error('is not a clipping plane or no clipping plane instance'); - } - - return clippingPlane.instance.clipping; - } - ) - } else { - this.instance.clippingPlanes = []; - } - - if (property === 'sortObjects') { - this.instance.sortObjects = this.sortObjects; - } -}; - -/** - * - * @returns {GameLib.D3.API.Renderer} - */ -GameLib.D3.Renderer.prototype.toApiObject = function() { - - var apiRenderer = new GameLib.D3.API.Renderer( - this.id, - this.name, - this.autoClear, - this.localClipping, - this.width, - this.height, - this.preserveDrawingBuffer, - GameLib.Utils.IdOrNull(this.domElement), - this.clearColor.toApiObject(), - GameLib.Utils.IdOrNull(this.camera), - this.scenes.map(function(scene){ - return GameLib.Utils.IdOrNull(scene); - }), - this.viewports.map(function(viewport){ - return GameLib.Utils.IdOrNull(viewport); - }), - this.clippingPlanes.map( - function(clippingPlane) { - return GameLib.Utils.IdOrNull(clippingPlane); - } - ), - GameLib.Utils.IdOrNull(this.bufferScene), - GameLib.Utils.IdOrNull(this.bufferCamera), - GameLib.Utils.IdOrNull(this.renderTarget), - GameLib.Utils.IdOrNull(this.defaultScene), - this.sortObjects, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiRenderer; -}; - -/** - * - * @param graphics - * @param objectComponent - * @returns {GameLib.D3.Renderer} - * @constructor - */ -GameLib.D3.Renderer.FromObject = function(graphics, objectComponent) { - - var apiRenderer = GameLib.D3.API.Renderer.FromObject(objectComponent); - - return new GameLib.D3.Renderer( - graphics, - apiRenderer - ); -}; - -/** - * Convenience render function - */ -GameLib.D3.Renderer.prototype.render = function(delta, scenes) { - - if (!this.instance) { - return; - } - - if (GameLib.Utils.UndefinedOrNull(scenes)) { - scenes = this.scenes; - } - - if (this.viewports.length > 1) { - this.instance.autoClear = false; - } - - if (scenes.length > 1) { - this.instance.autoClear = false; - } - - this.instance.clear(); - - if ( - this.bufferScene && - this.bufferScene.instance && - this.bufferCamera && - this.bufferCamera.instance && - this.renderTarget && - this.renderTarget.instance - ) { - /** - * We have a buffer that should render to an offscreen render target - */ - this.instance.render( - this.bufferScene.instance, - this.bufferCamera.instance, - this.renderTarget.instance - ); - } - - this.viewports.map( - - function(viewport) { - - this.instance.setViewport( - viewport.x * this.width, - viewport.y * this.height, - viewport.width * this.width, - viewport.height * this.height - ); - - scenes.map(function(scene) { - - if (!scene.instance) { - return; - } - - if (!this.camera.instance && !(scene.renderCamera || scene.renderCamera.instance)) { - return; - } - - /** - * A scene's renderCamera instance overrides the default renderer camera - */ - if (scene.renderCamera && scene.renderCamera.instance) { - this.instance.render( - scene.instance, - scene.renderCamera.instance - ) - } else { - this.instance.render( - scene.instance, - this.camera.instance - ) - } - - }.bind(this)); - - }.bind(this) - ); - -}; - -GameLib.D3.Renderer.prototype.setSize = function(width, height) { - this.width = width; - this.height = height; - - if (this.instance) { - this.instance.setSize( - this.width, - this.height - ); - } else { - console.log('renderer not ready to set size'); - } - -}; - - -/** - * RigidBody Runtime - * @param physics GameLib.GraphicsRuntime - * @param apiRigidBody GameLib.D3.API.RigidBody - * @constructor - */ -GameLib.D3.RigidBody = function ( - physics, - apiRigidBody -) { - - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiRigidBody)) { - apiRigidBody = {}; - } - - if (apiRigidBody instanceof GameLib.D3.RigidBody) { - return apiRigidBody; - } - - GameLib.D3.API.RigidBody.call( - this, - apiRigidBody.id, - apiRigidBody.name, - apiRigidBody.mass, - apiRigidBody.friction, - apiRigidBody.position, - apiRigidBody.quaternion, - apiRigidBody.velocity, - apiRigidBody.angularVelocity, - apiRigidBody.linearDamping, - apiRigidBody.angularDamping, - apiRigidBody.allowSleep, - apiRigidBody.sleepSpeedLimit, - apiRigidBody.sleepTimeLimit, - apiRigidBody.collisionFilterGroup, - apiRigidBody.collisionFilterMask, - apiRigidBody.fixedRotation, - apiRigidBody.shapes, - apiRigidBody.kinematic, - apiRigidBody.parentMesh, - apiRigidBody.parentPhysicsWorld, - apiRigidBody.parentEntity - ); - - this.position = new GameLib.Vector3( - this.physics, - this.position, - this - ); - - this.quaternion = new GameLib.Quaternion( - this.physics, - this.quaternion, - this - ); - - this.velocity = new GameLib.Vector3( - this.physics, - this.velocity, - this - ); - - this.angularVelocity = new GameLib.Vector3( - this.physics, - this.angularVelocity, - this - ); - - this.force = new GameLib.Vector3( - this.physics - ); - - this.forcePoint = new GameLib.Vector3( - this.physics - ); - - GameLib.Component.call( - this, - { - 'shapes' : [GameLib.D3.Shape], - 'parentMesh' : GameLib.D3.Mesh, - 'parentPhysicsWorld' : GameLib.D3.PhysicsWorld - } - ); -}; - -GameLib.D3.RigidBody.prototype = Object.create(GameLib.D3.API.RigidBody.prototype); -GameLib.D3.RigidBody.prototype.constructor = GameLib.D3.RigidBody; - -/** - * - * @returns {*} - */ -GameLib.D3.RigidBody.prototype.createInstance = function() { - - this.instance = new CANNON.Body( - { - mass : this.mass, - friction : this.friction, - position : this.position.instance, - quaternion : this.quaternion.instance, - velocity : this.velocity.instance, - angularVelocity : this.angularVelocity.instance, - linearDamping : this.linearDamping, - angularDamping : this.angularDamping, - allowSleep : this.allowSleep, - sleepSpeedLimit : this.sleepSpeedLimit, - sleepTimeLimit : this.sleepTimeLimit, - collisionFilterGroup : this.collisionFilterGroup, - collisionFilterMask : this.collisionFilterMask, - fixedRotation : this.fixedRotation, - kinematic : this.kinematic - } - ); - - this.instance.addEventListener( - "sleepy", - function() { - console.log(this.name + " is feeling sleepy..."); - }.bind(this) - ); - - this.instance.addEventListener( - "sleep", - function() { - console.log(this.name + " fell asleep!"); - }.bind(this) - ); - - this.instance.addEventListener( - "wakeup", - function() { - console.log(this.name + " woke up!"); - }.bind(this) - ); - - this.shapes.map( - function(shape) { - - if (GameLib.Utils.UndefinedOrNull(shape)) { - throw new Error('no shape'); - } - - if (GameLib.Utils.UndefinedOrNull(shape.instance)) { - throw new Error('no shape instance'); - } - - this.instance.addShape(shape.instance) - - }.bind(this) - ); - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * - */ -GameLib.D3.RigidBody.prototype.updateInstance = function() { - - this.instance.mass = this.mass; - this.instance.friction = this.friction; - - this.instance.position.x = this.position.x; - this.instance.position.y = this.position.y; - this.instance.position.z = this.position.z; - - this.quaternion.axis.instance.x = this.quaternion.axis.x; - this.quaternion.axis.instance.y = this.quaternion.axis.y; - this.quaternion.axis.instance.z = this.quaternion.axis.z; - - this.instance.quaternion.setFromAxisAngle( - this.quaternion.axis.instance, - this.quaternion.angle - ); - - this.quaternion.x = this.instance.quaternion.x; - this.quaternion.y = this.instance.quaternion.y; - this.quaternion.z = this.instance.quaternion.z; - this.quaternion.w = this.instance.quaternion.w; - - this.parentMesh.position.setFrom(this.position); - this.parentMesh.quaternion.setFrom(this.quaternion); - this.parentMesh.updateInstance(); - - this.instance.velocity.x = this.velocity.x; - this.instance.velocity.y = this.velocity.y; - this.instance.velocity.z = this.velocity.z; - - this.instance.angularVelocity.x = this.angularVelocity.x; - this.instance.angularVelocity.y = this.angularVelocity.y; - this.instance.angularVelocity.z = this.angularVelocity.z; - - this.instance.linearDamping = this.linearDamping; - this.instance.angularDamping = this.angularDamping; - this.instance.allowSleep = this.allowSleep; - this.instance.sleepSpeedLimit = this.sleepSpeedLimit; - this.instance.sleepTimeLimit = this.sleepTimeLimit; - this.instance.collisionFilterGroup = this.collisionFilterGroup; - this.instance.collisionFilterMask = this.collisionFilterMask; - this.instance.fixedRotation = this.fixedRotation; - this.instance.kinematic = this.kinematic; -}; - -GameLib.D3.RigidBody.prototype.setFromParentMesh = function() { - - if (!this.parentMesh || !this.parentMesh.instance) { - console.log('no parent mesh or instance'); - } - - this.instance.position.x = this.parentMesh.position.x; - this.instance.position.y = this.parentMesh.position.y; - this.instance.position.z = this.parentMesh.position.z; - - this.instance.quaternion.x = this.parentMesh.quaternion.x; - this.instance.quaternion.y = this.parentMesh.quaternion.y; - this.instance.quaternion.z = this.parentMesh.quaternion.z; - this.instance.quaternion.w = this.parentMesh.quaternion.w; - - // this.updateInstance(); - -}; - -/** - * GameLib.D3.RigidBody to GameLib.D3.API.RigidBody - * @returns {GameLib.D3.API.RigidBody} - */ -GameLib.D3.RigidBody.prototype.toApiObject = function() { - - var apiRigidBody = new GameLib.D3.API.RigidBody( - this.id, - this.name, - this.mass, - this.friction, - this.position.toApiObject(), - this.quaternion.toApiObject(), - this.velocity.toApiObject(), - this.angularVelocity.toApiObject(), - this.linearDamping, - this.angularDamping, - this.allowSleep, - this.sleepSpeedLimit, - this.sleepTimeLimit, - this.collisionFilterGroup, - this.collisionFilterMask, - this.fixedRotation, - this.shapes.map(function(shape){return GameLib.Utils.IdOrNull(shape)}), - this.kinematic, - GameLib.Utils.IdOrNull(this.parentMesh), - GameLib.Utils.IdOrNull(this.parentPhysicsWorld), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiRigidBody; -}; - -/** - * GameLib.D3.RigidBody from Object RigidBody - * @param physics - * @param objectComponent - * @returns {GameLib.D3.RigidBody} - * @constructor - */ -GameLib.D3.RigidBody.FromObject = function(physics, objectComponent) { - - var apiRigidBody = GameLib.D3.API.RigidBody.FromObject(objectComponent); - - return new GameLib.D3.RigidBody( - physics, - apiRigidBody - ); -}; - -GameLib.D3.RigidBody.prototype.applyForce = function() { - this.instance.applyForce( - this.force.instance, - this.forcePoint.instance - ) -}; - - -GameLib.D3.RigidBody.prototype.applyLocalForce = function() { - this.instance.applyLocalForce( - this.force.instance, - this.forcePoint.instance - ) -}; - -/** - * Scene Superset - The apiScene properties get moved into the Scene object itself, and then the instance is - * created - * @param graphics - * @param apiScene GameLib.D3.API.Scene - * @constructor - */ -GameLib.D3.Scene = function ( - graphics, - apiScene -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiScene)) { - apiScene = {}; - } - - if (apiScene instanceof GameLib.D3.Scene) { - return apiScene; - } - - GameLib.D3.API.Scene.call( - this, - apiScene.id, - apiScene.name, - apiScene.meshes, - apiScene.lights, - apiScene.textures, - apiScene.materials, - apiScene.images, - apiScene.fog, - apiScene.renderCamera, - apiScene.showGrid, - apiScene.showAxis, - apiScene.gridSize, - apiScene.gridColor, - apiScene.parentEntity - ); - - this.meshes = this.meshes.map( - function(apiMesh) { - - if (apiMesh instanceof GameLib.D3.API.Mesh) { - - apiMesh.parentScene = this; - - return new GameLib.D3.Mesh( - this.graphics, - apiMesh - ); - - } else { - return apiMesh; - } - - }.bind(this) - ); - - this.lights = this.lights.map( - function(apiLight) { - - if (apiLight instanceof GameLib.D3.API.Light) { - - return new GameLib.D3.Light( - this.graphics, - apiLight - ); - - } else { - return apiLight; - } - - }.bind(this) - ); - - this.textures = this.textures.map( - function(apiTexture) { - - if (apiTexture instanceof GameLib.D3.API.Texture) { - - var texture = new GameLib.D3.Texture( - this.graphics, - apiTexture - ); - - return texture; - } else { - return apiTexture; - } - - }.bind(this) - ); - - this.materials = this.materials.map( - function(apiMaterial) { - - if (apiMaterial instanceof GameLib.D3.API.Material) { - - var material = new GameLib.D3.Material( - this.graphics, - apiMaterial - ); - - return material; - - } else { - return apiMaterial; - } - - }.bind(this) - ); - - this.images = this.images.map( - function(apiImage) { - - if (apiImage instanceof GameLib.API.Image) { - - var image = new GameLib.Image( - this.graphics, - apiImage - ); - - return image; - } else { - return apiImage; - } - - }.bind(this) - ); - - if (this.fog instanceof GameLib.D3.API.Fog) { - this.fog = new GameLib.D3.Fog( - this.graphics, - this.fog - ) - } - - if (this.renderCamera instanceof GameLib.D3.API.Camera) { - this.renderCamera = new GameLib.D3.Camera( - this.graphics, - this.renderCamera - ) - } - - if (this.gridColor instanceof GameLib.API.Color) { - this.gridColor = new GameLib.Color( - this.graphics, - this.gridColor, - this - ) - } - - /** - * Runtime scenes have helpers (just used to store which helper belongs to which scene) - * @type {Array} - */ - this.helpers = []; - - this.clones = []; - - this.grid = []; - - this.axis = []; - - this.storeClones = false; - - GameLib.Component.call( - this, - { - 'meshes' : [GameLib.D3.Mesh], - 'lights' : [GameLib.D3.Light], - 'textures' : [GameLib.D3.Texture], - 'materials' : [GameLib.D3.Material], - 'images' : [GameLib.Image], - 'fog' : GameLib.D3.Fog, - 'renderCamera' : GameLib.D3.Camera - } - ); -}; - -GameLib.D3.Scene.prototype = Object.create(GameLib.D3.API.Scene.prototype); -GameLib.D3.Scene.prototype.constructor = GameLib.D3.Scene; - -/** - * Creates an instance scene - * @returns {THREE.Scene} - */ -GameLib.D3.Scene.prototype.createInstance = function() { - - this.instance = new THREE.Scene(); - - this.instance.name = this.name; - - if (this.fog && this.fog.instance) { - this.instance.fog = this.fog.instance; - } - - this.meshes.map( - function(mesh) { - - if (GameLib.Utils.UndefinedOrNull(mesh)) { - throw new Error('no mesh'); - } - - if (GameLib.Utils.UndefinedOrNull(mesh.instance)) { - throw new Error('no mesh instance'); - } - - this.instance.add(mesh.instance); - - mesh.parentScene = this; - - }.bind(this) - ); - - this.lights.map( - function(light) { - - - if (GameLib.Utils.UndefinedOrNull(light)) { - throw new Error('no light'); - } - - if (GameLib.Utils.UndefinedOrNull(light.instance)) { - throw new Error('no light instance'); - } - - this.instance.add(light.instance); - - light.parentScene = this; - - }.bind(this) - ); - - if (this.showGrid) { - this.drawGrid(); - } - - if (this.showAxis) { - this.drawAxis(); - } - - GameLib.Component.prototype.createInstance.call(this); - -}; - -GameLib.D3.Scene.prototype.updateInstance = function(property) { - - if (property === 'name') { - this.instance.name = this.name; - return; - } - - if (this.fog && this.fog.instance !== this.instance.fog) { - this.instance.fog = this.fog.instance; - } - - /** - * Add missing meshes - */ - this.meshes.map( - function(mesh) { - if (this.instance.children.indexOf(mesh.instance === -1)) { - this.instance.add(mesh.instance); - } - }.bind(this) - ); - - /** - * Add missing lights - */ - this.lights.map( - function(light) { - if (this.instance.children.indexOf(light.instance) === -1) { - this.instance.add(light.instance); - } - }.bind(this) - ); - - /** - * Remove extra meshes and lights - */ - this.instance.children.map( - function(instanceObject) { - - var instanceMeshes = this.meshes.map( - function(mesh) { - return mesh.instance; - } - ); - - var instanceLights = this.lights.map( - function(light) { - return light.instance; - } - ); - - if ( - ( - instanceObject instanceof THREE.Mesh || - instanceObject instanceof THREE.Light - ) && - ( - instanceLights.indexOf(instanceObject) === -1 && - instanceMeshes.indexOf(instanceObject) === -1 - ) - ) { - this.instance.remove(instanceObject); - } - - }.bind(this) - ); - - if ( - property === 'showGrid' || - property === 'gridSize' || - property === 'gridColor' - ) { - if (this.showGrid) { - this.drawGrid(); - } else { - this.removeGrid(); - } - } - - if (property === 'showAxis') { - if (this.showAxis) { - this.drawAxis(); - } else { - this.removeAxis(); - } - - } -}; - -/** - * Converts a GameLib.D3.Scene to a GameLib.D3.API.Scene - * @returns {GameLib.D3.API.Scene} - */ -GameLib.D3.Scene.prototype.toApiObject = function() { - - var apiMeshes = this.meshes.reduce( - function(result, mesh) { - - /** - * Do not store any cloned meshes - */ - if ((this.clones.indexOf(mesh) === -1) || this.storeClones) { - result.push(GameLib.Utils.IdOrNull(mesh)); - } - - return result; - }.bind(this), - [] - ); - - var apiLights = this.lights.reduce( - function(result, light) { - - /** - * Do not store any cloned lights - */ - if (this.clones.indexOf(light) === -1 || this.storeClones) { - result.push(GameLib.Utils.IdOrNull(light)); - } - - return result; - - }.bind(this), - [] - ); - - var apiTextures = this.textures.map( - function(texture) { - return GameLib.Utils.IdOrNull(texture); - } - ); - - var apiMaterials = this.materials.map( - function(material) { - return GameLib.Utils.IdOrNull(material); - } - ); - - var apiImages = this.images.map( - function(image) { - return GameLib.Utils.IdOrNull(image); - } - ); - - return new GameLib.D3.API.Scene( - this.id, - this.name, - apiMeshes, - apiLights, - apiTextures, - apiMaterials, - apiImages, - GameLib.Utils.IdOrNull(this.fog), - GameLib.Utils.IdOrNull(this.renderCamera), - this.showGrid, - this.showAxis, - this.gridSize, - this.gridColor.toApiObject(), - GameLib.Utils.IdOrNull(this.parentEntity) - ); -}; - -/** - * Converts a scene Object to a GameLib.D3.Scene object - * @param graphics GameLib.GraphicsRuntime - * @param objectScene Object - * @returns {GameLib.D3.Scene} - * @constructor - */ -GameLib.D3.Scene.FromObject = function( - graphics, - objectScene -) { - var apiScene = GameLib.D3.API.Scene.FromObject(objectScene); - - return new GameLib.D3.Scene( - graphics, - apiScene - ); -}; - - -/** - * Adds a mesh to the scene - * @param object GameLib.D3.Mesh - */ -GameLib.D3.Scene.prototype.addObject = function(object) { - - if (object instanceof GameLib.D3.Mesh) { - if (this.meshes.indexOf(object) === -1) { - this.meshes.push(object); - } - } else if (object instanceof GameLib.D3.API.Mesh) { - object = new GameLib.D3.Mesh( - this.graphics, - object - ); - this.meshes.push(object); - } - - if (object instanceof GameLib.D3.Light) { - if (this.lights.indexOf(object) === -1) { - this.lights.push(object); - } - } else if (object instanceof GameLib.D3.API.Light) { - object = new GameLib.D3.Light( - this.graphics, - object - ); - this.lights.push(object); - } - - object.parentScene = this; - - if ( - this.instance && - object.instance - ) { - if (this.instance.children.indexOf(object.instance) === -1) { - this.instance.add(object.instance); - } - } - -}; - -GameLib.D3.Scene.prototype.addClone = function(component) { - - if (component instanceof GameLib.D3.Mesh || - component instanceof GameLib.D3.Light - ) { - if (this.instance && component.instance) { - this.instance.add(component.instance); - } - - GameLib.Utils.PushUnique(this.clones, component); - - component.parentScene = this; - } -}; - -/** - * - * @param object - */ -GameLib.D3.Scene.prototype.removeObject = function(object) { - - var index = -1; - - if (object instanceof GameLib.D3.Mesh) { - - index = this.meshes.indexOf(object); - if (index !== -1) { - this.meshes.splice(index, 1); - } - - index = this.clones.indexOf(object); - if (index !== -1) { - this.clones.splice(index, 1); - } - - } else if (object instanceof GameLib.D3.Light) { - - index = this.lights.indexOf(object); - if (index !== -1) { - this.lights.splice(index, 1); - } - - index = this.clones.indexOf(object); - if (index !== -1) { - this.clones.splice(index, 1); - } - - } else { - console.warn('Cannot remove this object - what is this ?' + object.toString()); - return; - } - - if (this.instance.children.indexOf(object.instance) !== -1) { - this.instance.remove(object.instance); - } else { - console.warn('no scene instance'); - } - - if (object.parentScene === this) { - object.parentScene = null; - } - - // this.buildIdToObject(); -}; - -GameLib.D3.Scene.prototype.drawGrid = function() { - - this.removeGrid(); - - var lineMaterial = new THREE.LineBasicMaterial({ - color: this.gridColor.toHex(), - linewidth: 1 - }); - - for (var y = -this.gridSize; y <= this.gridSize; y += 1) { - - var Xgeometry = new THREE.Geometry(); - Xgeometry.vertices.push( - new THREE.Vector3( y, 0, this.gridSize * -1 ), - new THREE.Vector3( y, 0, this.gridSize ) - ); - - var lineX = new THREE.Line(Xgeometry, lineMaterial); - - this.instance.add(lineX); - - this.grid.push(lineX); - - var Ygeometry = new THREE.Geometry(); - Ygeometry.vertices.push( - new THREE.Vector3( this.gridSize * -1 , 0, y ), - new THREE.Vector3( this.gridSize, 0, y ) - ); - - var lineY = new THREE.Line(Ygeometry, lineMaterial); - - this.instance.add(lineY); - - this.grid.push(lineY); - } -}; - -GameLib.D3.Scene.prototype.removeGrid = function() { - this.grid.map( - function(object) { - this.instance.remove(object); - }.bind(this) - ); -}; - -GameLib.D3.Scene.prototype.drawAxis = function() { - - this.removeAxis(); - - var Xmaterial = new THREE.LineBasicMaterial({ - color: 0xff0000, - linewidth: 2 - }); - - var Xgeometry = new THREE.Geometry(); - Xgeometry.vertices.push( - new THREE.Vector3( 0, 0, 0 ), - new THREE.Vector3( 100, 0, 0 ) - ); - - var lineX = new THREE.Line(Xgeometry, Xmaterial); - - this.instance.add(lineX); - - this.axis.push(lineX); - - var Ymaterial = new THREE.LineBasicMaterial({ - color: 0x00ff00, - linewidth: 2 - }); - - var Ygeometry = new THREE.Geometry(); - Ygeometry.vertices.push( - new THREE.Vector3( 0, 0, 0 ), - new THREE.Vector3( 0, 100, 0 ) - ); - - var lineY = new THREE.Line(Ygeometry, Ymaterial); - - this.instance.add(lineY); - - this.axis.push(lineY); - - var Zmaterial = new THREE.LineBasicMaterial({ - color: 0x0000ff, - linewidth: 2 - }); - - var Zgeometry = new THREE.Geometry(); - Zgeometry.vertices.push( - new THREE.Vector3( 0, 0, 0 ), - new THREE.Vector3( 0, 0, 100 ) - ); - - var lineZ = new THREE.Line(Zgeometry, Zmaterial); - - this.instance.add(lineZ); - - this.axis.push(lineZ); -}; - -GameLib.D3.Scene.prototype.removeAxis = function() { - this.axis.map( - function(object) { - this.instance.remove(object); - }.bind(this) - ); -}; - -/** - * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created - * @param physics GameLib.PhysicsRuntime - * @param apiShape GameLib.D3.API.Shape - * @constructor - */ -GameLib.D3.Shape = function ( - physics, - apiShape -) { - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiShape)) { - apiShape = { - shapeType : GameLib.D3.API.Shape.SHAPE_TYPE_NONE - }; - } - - if (apiShape instanceof GameLib.D3.Shape) { - return apiShape; - } - - GameLib.D3.API.Shape.call( - this, - apiShape.id, - apiShape.name, - apiShape.shapeType, - apiShape.boundingSphereRadius, - apiShape.collisionResponse, - apiShape.frictionMaterial, - apiShape.parentMesh, - apiShape.parentEntity - ); - - var linkedObjects = { - frictionMaterial : GameLib.D3.FrictionMaterial, - parentMesh : GameLib.D3.Mesh - }; - - GameLib.Component.call( - this, - linkedObjects - ); -}; - -GameLib.D3.Shape.prototype = Object.create(GameLib.D3.API.Shape.prototype); -GameLib.D3.Shape.prototype.constructor = GameLib.D3.Shape; - - -/** - * Creates a shape instance or updates it - */ -GameLib.D3.Shape.prototype.createInstance = function() { - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the mesh instance - */ -GameLib.D3.Shape.prototype.updateInstance = function() { - throw new Error('Do not instantiate this class directly - use a child class instead'); -}; - -/** - * Converts a GameLib.D3.Shape to a GameLib.D3.API.Shape - * @returns {GameLib.D3.API.Shape} - */ -GameLib.D3.Shape.prototype.toApiObject = function() { - - var apiShape = new GameLib.D3.API.Shape( - this.id, - this.name, - this.shapeType, - this.boundingSphereRadius, - this.collisionResponse, - GameLib.Utils.IdOrNull(this.frictionMaterial), - GameLib.Utils.IdOrNull(this.parentMesh), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiShape; -}; - -/** - * Converts a standard object mesh to a GameLib.D3.Shape - * @param physics GameLib.PhysicsRuntime - * @param objectShape {Object} - * @constructor - */ -GameLib.D3.Shape.FromObject = function(physics, objectShape) { - throw ('not implemented'); -}; - -GameLib.D3.Shape.prototype.stopVisualize = function() { - GameLib.Event.Emit( - GameLib.Event.STOP_VISUALIZE, - { - mesh : this.mesh - } - ) -}; - -GameLib.D3.Shape.prototype.visualize = function() { - GameLib.Event.Emit( - GameLib.Event.VISUALIZE, - { - shape : this - } - ) -}; -/** - * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created - * @param physics - * @param apiShape GameLib.D3.API.Shape - * @param halfExtents - * @constructor - */ -GameLib.D3.Shape.Box = function ( - physics, - apiShape, - halfExtents -) { - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiShape)) { - apiShape = { - shapeType : GameLib.D3.API.Shape.SHAPE_TYPE_BOX - }; - } - - if (apiShape instanceof GameLib.D3.Shape.Box) { - return apiShape; - } - - if (GameLib.Utils.UndefinedOrNull(halfExtents)) { - halfExtents = new GameLib.Vector3( - physics, - new GameLib.API.Vector3( - 1,1,1 - ) - ); - } else if (halfExtents instanceof GameLib.API.Vector3) { - halfExtents = new GameLib.Vector3( - this.physics, - halfExtents, - this - ) - } - this.halfExtents = halfExtents; - - GameLib.D3.Shape.call( - this, - this.physics, - apiShape - ); -}; - -GameLib.D3.Shape.Box.prototype = Object.create(GameLib.D3.Shape.prototype); -GameLib.D3.Shape.Box.prototype.constructor = GameLib.D3.Shape.Box; - -/** - * - * @returns {GameLib.D3.Shape.Box|*|SEA3D.Box} - */ -GameLib.D3.Shape.Box.prototype.createInstance = function() { - - if (GameLib.Utils.UndefinedOrNull(this.halfExtents)) { - throw new Error('no halfExtents'); - } - - if (GameLib.Utils.UndefinedOrNull(this.halfExtents.instance)) { - throw new Error('no halfExtents instance'); - } - - this.instance = new CANNON.Box( - this.halfExtents.instance - ); - - GameLib.D3.Shape.prototype.createInstance.call(this); - -}; - -GameLib.D3.Shape.Box.prototype.updateInstance = function() { - this.instance.halfExtents.x = this.halfExtents.x; - this.instance.halfExtents.y = this.halfExtents.y; - this.instance.halfExtents.z = this.halfExtents.z; - this.instance.updateBoundingSphereRadius(); - this.instance.updateConvexPolyhedronRepresentation(); -}; - -GameLib.D3.Shape.Box.prototype.toApiObject = function() { - - var apiShape = GameLib.D3.Shape.prototype.toApiObject.call(this); - - apiShape.halfExtents = this.halfExtents.toApiObject(); - - return apiShape; -}; - -GameLib.D3.Shape.Box.prototype.setFromMesh = function() { - - if (this.parentMesh === null) { - console.log('select a mesh first'); - return; - } - - var box = this.parentMesh.getBoundingBox(); - - this.halfExtents.x = box.x / 2; - this.halfExtents.y = box.y / 2; - this.halfExtents.z = box.z / 2; - - this.halfExtents.updateInstance(); -}; - -GameLib.D3.Shape.Box.FromObject = function(physics, objectShape) { - - var apiShape = GameLib.D3.API.Shape.FromObject(objectShape); - - apiShape.halfExtents = GameLib.API.Vector3.FromObject(objectShape.halfExtents); - - return new GameLib.D3.Shape.Box( - physics, - apiShape, - apiShape.halfExtents - ); - -}; -/** - * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created - * @param physics - * @param apiShape GameLib.D3.API.Shape - * @param faces - * @param uniqueAxes - * @param uniqueEdges - * @param vertices - * @constructor - */ -GameLib.D3.Shape.ConvexHull = function ( - physics, - apiShape, - vertices, - faces, - uniqueAxes, - uniqueEdges -) { - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiShape)) { - apiShape = { - shapeType : GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL - }; - } - - if (apiShape instanceof GameLib.D3.Shape.ConvexHull) { - return apiShape; - } - - if (GameLib.Utils.UndefinedOrNull(vertices)) { - vertices = []; - } - this.vertices = vertices; - - if (GameLib.Utils.UndefinedOrNull(faces)) { - faces = []; - } - this.faces = faces; - - if (GameLib.Utils.UndefinedOrNull(uniqueAxes)) { - uniqueAxes = []; - } - this.uniqueAxes = uniqueAxes; - - if (GameLib.Utils.UndefinedOrNull(uniqueEdges)) { - uniqueEdges = []; - } - this.uniqueEdges = uniqueEdges; - - this.vertices = this.vertices.map(function(vertex){ - if (vertex instanceof GameLib.D3.API.Vertex){ - return new GameLib.D3.Vertex( - this.physics, - vertex - ) - } - return vertex; - }.bind(this)); - - this.faces = this.faces.map(function(face){ - if (face instanceof GameLib.D3.API.Face){ - return new GameLib.D3.Face( - this.physics, - face - ) - } - return face; - }.bind(this)); - - this.uniqueAxes = this.uniqueAxes.map(function(axis){ - if (axis instanceof GameLib.API.Vector3) { - return new GameLib.Vector3( - this.physics, - axis, - this - ) - } - return axis; - }.bind(this)); - - this.uniqueEdges = this.uniqueEdges.map(function(edge){ - if (edge instanceof GameLib.API.Vector3) { - return new GameLib.Vector3( - this.physics, - edge, - this - ) - } - return edge; - }.bind(this)); - - GameLib.D3.Shape.call( - this, - this.physics, - apiShape - ); -}; - -GameLib.D3.Shape.ConvexHull.prototype = Object.create(GameLib.D3.Shape.prototype); -GameLib.D3.Shape.ConvexHull.prototype.constructor = GameLib.D3.Shape.ConvexHull; - -/** - * Create instance - * @returns {GameLib.D3.Shape.ConvexHull} - */ -GameLib.D3.Shape.ConvexHull.prototype.createInstance = function() { - - var faceNormals = []; - - this.instance = new CANNON.ConvexPolyhedron( - this.vertices.map( - function(vertex) { - - if (GameLib.Utils.UndefinedOrNull(vertex)) { - throw new Error('no vertex'); - } - - if (GameLib.Utils.UndefinedOrNull(vertex.position)) { - throw new Error('no vertex position'); - } - - if (GameLib.Utils.UndefinedOrNull(vertex.position.instance)) { - throw new Error('no vertex position instance'); - } - - return vertex.position.instance; - } - ), - this.faces.map( - function(face) { - - if (GameLib.Utils.UndefinedOrNull(face)) { - throw new Error('no face'); - } - - if (GameLib.Utils.UndefinedOrNull(face.normal)) { - throw new Error('no face normal'); - } - - if (GameLib.Utils.UndefinedOrNull(face.normal.instance)) { - throw new Error('no face normal instance'); - } - - if (GameLib.Utils.UndefinedOrNull(face.v0index)) { - throw new Error('no face v0index'); - } - - if (GameLib.Utils.UndefinedOrNull(face.v1index)) { - throw new Error('no face v1index'); - } - - if (GameLib.Utils.UndefinedOrNull(face.v2index)) { - throw new Error('no face v2index'); - } - - faceNormals.push(face.normal.instance); - - return [face.v0index, face.v1index, face.v2index]; - } - ) - ); - - this.instance.faceNormals = faceNormals; - - GameLib.D3.Shape.prototype.createInstance.call(this); -}; - -/** - * Update instance - */ -GameLib.D3.Shape.ConvexHull.prototype.updateInstance = function() { - console.log('todo: update convex hull instance'); - // this.instance.vertices = this.vertices; - // this.instance.indices = this.indices; - // this.instance.updateAABB(); - // this.instance.updateBoundingSphereRadius(); - // this.instance.updateEdges(); - // this.instance.updateNormals(); - // this.instance.updateTree(); -}; - -GameLib.D3.Shape.ConvexHull.prototype.loadFromInstance = function() { - console.log('todo: eventually load the faces and vertices from the instance faces and vertices and normals'); - console.log('todo: this way we can nicely visualize them with our gamelib classes :)'); -}; - -GameLib.D3.Shape.ConvexHull.prototype.toApiObject = function() { - - var apiShape = GameLib.D3.Shape.prototype.toApiObject.call(this); - - apiShape.vertices = this.vertices.map( - function(vertex) { - if (vertex instanceof GameLib.D3.Vertex) { - return vertex.toApiObject(); - } - return vertex; - } - ); - - apiShape.faces = this.faces.map( - function(face) { - if (face instanceof GameLib.D3.Face){ - return face.toApiObject(); - } - return face; - } - ); - - apiShape.uniqueAxes = this.uniqueAxes.map( - function(axis){ - if (axis instanceof GameLib.Vector3) { - return axis.toApiObject(); - } - return axis; - } - ); - - apiShape.uniqueEdges = this.uniqueEdges.map( - function(edge) { - if (edge instanceof GameLib.Vector3) { - return edge.toApiObject(); - } - return edge; - } - ); - - return apiShape; -}; - -GameLib.D3.Shape.ConvexHull.prototype.setFromMesh = function() { - console.log('todo: set convex hull from mesh'); - this.updateInstance(); -}; - -GameLib.D3.Shape.ConvexHull.InheritableProperties = function(physics, objectShape) { - var vertices = objectShape.vertices.map( - function(objectVertex) { - return GameLib.D3.Vertex.FromObject(physics, objectVertex); - } - ); - - var faces = objectShape.faces.map( - function(objectFace) { - return GameLib.D3.Face.FromObject(physics, objectFace); - } - ); - - var uniqueAxes = objectShape.uniqueAxes.map( - function(axis) { - return GameLib.API.Vector3.FromObject(axis); - } - ); - - var uniqueEdges = objectShape.uniqueEdges.map( - function(edge) { - return GameLib.API.Vector3.FromObject(edge); - } - ); - - return { - vertices : vertices, - faces : faces, - uniqueAxes : uniqueAxes, - uniqueEdges : uniqueEdges - }; -}; - -GameLib.D3.Shape.ConvexHull.FromObject = function(physics, objectShape) { - - var apiShape = GameLib.D3.API.Shape.FromObject(objectShape); - - var inheritableProperties = GameLib.D3.Shape.ConvexHull.InheritableProperties(physics, objectShape); - - return new GameLib.D3.Shape.ConvexHull.call( - this, - physics, - apiShape, - inheritableProperties.vertices, - inheritableProperties.faces, - inheritableProperties.uniqueAxes, - inheritableProperties.uniqueEdges - ); -}; -/** - * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created - * @param physics - * @param apiShape GameLib.D3.API.Shape - * @param radiusTop - * @param radiusBottom - * @param height - * @param numSegments - * @constructor - */ -GameLib.D3.Shape.ConvexHull.Cylinder = function ( - physics, - apiShape, - radiusTop, - radiusBottom, - height, - numSegments -) { - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiShape)) { - apiShape = { - shapeType : GameLib.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL_CYLINDER - }; - } - - if (apiShape instanceof GameLib.D3.Shape.ConvexHull.Cylinder) { - return apiShape; - } - - if (GameLib.Utils.UndefinedOrNull(radiusTop)) { - radiusTop = 1; - } - this.radiusTop = radiusTop; - - if (GameLib.Utils.UndefinedOrNull(radiusBottom)) { - radiusBottom = 1; - } - this.radiusBottom = radiusBottom; - - if (GameLib.Utils.UndefinedOrNull(height)) { - height = radiusBottom / 2; - } - this.height = height; - - if (GameLib.Utils.UndefinedOrNull(numSegments)) { - numSegments = 20; - } - this.numSegments = numSegments; - - GameLib.D3.Shape.ConvexHull.call( - this, - this.physics, - apiShape - ); -}; - -GameLib.D3.Shape.ConvexHull.Cylinder.prototype = Object.create(GameLib.D3.Shape.ConvexHull.prototype); -GameLib.D3.Shape.ConvexHull.Cylinder.prototype.constructor = GameLib.D3.Shape.ConvexHull.Cylinder; - -/** - * - * @returns {GameLib.D3.Shape.Cylinder|*|SEA3D.Cylinder} - */ -GameLib.D3.Shape.ConvexHull.Cylinder.prototype.createInstance = function() { - - this.instance = new CANNON.Cylinder( - this.radiusTop, - this.radiusBottom, - this.height, - this.numSegments - ); - - GameLib.D3.Shape.prototype.createInstance.call(this); -}; - -GameLib.D3.Shape.ConvexHull.Cylinder.prototype.updateInstance = function() { - - console.log('todo : update cylinder instance'); - // this.instance.radius = this.radius; - // this.instance.updateAABB(); - // this.instance.updateBoundingCylinderRadius(); - // this.instance.updateEdges(); - // this.instance.updateNormals(); - // this.instance.updateTree(); -}; - -GameLib.D3.Shape.ConvexHull.Cylinder.prototype.setFromMesh = function() { - this.radiusTop = this.parentMesh.dimensions.x / 2; - this.radiusBottom = this.parentMesh.dimensions.x / 2; - this.height = this.parentMesh.dimensions.z; -}; - -GameLib.D3.Shape.ConvexHull.Cylinder.prototype.toApiObject = function() { - - var apiShape = GameLib.D3.Shape.ConvexHull.prototype.toApiObject.call(this); - - apiShape.radiusTop = this.radiusTop; - apiShape.radiusBottom = this.radiusBottom; - apiShape.height = this.height; - apiShape.numSegments = this.numSegments; - - return apiShape; -}; - - -GameLib.D3.Shape.ConvexHull.Cylinder.FromObject = function(physics, objectShape) { - - /** - * Just a reminder that below line is wrong and commented out - we need to call the constructors eventually with - * the right 'this' parameter and args. - * - * var apiShape = GameLib.D3.Shape.ConvexHull.FromObject(physics, objectShape); - * - * Instead, do this: - */ - var apiShape = GameLib.D3.API.Shape.FromObject(objectShape); - - var inheritableProperties = GameLib.D3.Shape.ConvexHull.InheritableProperties(physics, objectShape); - - for (var property in inheritableProperties) { - if (inheritableProperties.hasOwnProperty(property)) { - apiShape[property] = inheritableProperties[property]; - } - } - - return new GameLib.D3.Shape.ConvexHull.Cylinder( - physics, - apiShape, - objectShape.radiusTop, - objectShape.radiusBottom, - objectShape.height, - objectShape.numSegments - ); - -}; -/** - * - * @param physics - * @param apiShape - * @param heightData - * @param minValue - * @param maxValue - * @param elementSize - * @constructor - */ -GameLib.D3.Shape.HeightMap = function ( - physics, - apiShape, - heightData, - minValue, - maxValue, - elementSize -) { - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiShape)) { - apiShape = { - shapeType : GameLib.D3.API.Shape.SHAPE_TYPE_HEIGHT_MAP - }; - } - - if (apiShape instanceof GameLib.D3.Shape.HeightMap) { - return apiShape; - } - - if (GameLib.Utils.UndefinedOrNull(heightData)) { - heightData = [[10, 10, 10], [10, 10, 10], [10, 10, 10]]; - } - this.heightData = heightData; - - if (GameLib.Utils.UndefinedOrNull(minValue)) { - minValue = 0; - } - this.minValue = minValue; - - if (GameLib.Utils.UndefinedOrNull(maxValue)) { - maxValue = 10; - } - this.maxValue = maxValue; - - if (GameLib.Utils.UndefinedOrNull(elementSize)) { - elementSize = 1; - } - this.elementSize = elementSize; - - GameLib.D3.Shape.call( - this, - this.physics, - apiShape - ); -}; - -GameLib.D3.Shape.HeightMap.prototype = Object.create(GameLib.D3.Shape.prototype); -GameLib.D3.Shape.HeightMap.prototype.constructor = GameLib.D3.Shape.HeightMap; - -/** - * Create instance - * @returns {GameLib.D3.Shape.HeightMap} - */ -GameLib.D3.Shape.HeightMap.prototype.createInstance = function() { - - //TODO: initialize properly and throw when errors - - this.instance = new CANNON.Heightfield( - this.heightData, - { - elemSize : this.elementSize - } - ); - - GameLib.D3.Shape.prototype.createInstance.call(this); -}; - -/** - * Update instance - */ -GameLib.D3.Shape.HeightMap.prototype.updateInstance = function() { - this.instance.data = this.heightData; - // this.instance.minValue = this.minValue; - // this.instance.maxValue = this.maxValue; - this.instance.elemSize = this.elemSize; - this.instance.update(); - // this.instance.updateBoundingSphereRadius(); - // this.instance.updateMaxValue(); - // this.instance.updateMinValue(); -}; - - -GameLib.D3.Shape.HeightMap.prototype.toApiObject = function() { - var apiShape = GameLib.D3.Shape.prototype.toApiObject.call(this); - apiShape.heightData = this.heightData; - apiShape.minValue = this.minValue; - apiShape.maxValue = this.maxValue; - apiShape.elemSize = this.elemSize; - return apiShape; -}; - -GameLib.D3.Shape.HeightMap.prototype.setFromMesh = function() { - - if (this.parentMesh === null) { - console.log('select a mesh first'); - return; - } - - if (!this.parentMesh.isHeightMap) { - console.log('not a heightmap mesh'); - return; - } - - var dim1Array = Array.prototype.slice.call(this.parentMesh.getHeightData()); - - // var w = this.parentMesh.widthSegments + 1; - // - // var h = 0; - - // var offset = 0; - - this.heightData = []; - - for (var x = 0; x <= this.parentMesh.widthSegments; x++) { - - this.heightData[x] = []; - - for (var y = 0; y <= this.parentMesh.heightSegments; y++) { - - this.heightData[x][y] = dim1Array[((x * (this.parentMesh.widthSegments + 1)) + y)]; - - } - - } - - - - // this.heightData = dim1Array.reduce( - // function(result, value) { - // - // result[h].push(value); - // - // w--; - // - // if (w === 0) { - // w = this.parentMesh.widthSegments; - // - // if (h < this.parentMesh.heightSegments) { - // h++; - // } - // } - // - // return result; - // }.bind(this), - // result - // ); - - this.updateInstance(); -}; - -GameLib.D3.Shape.HeightMap.FromObject = function(physics, objectShape) { - - var apiShape = GameLib.D3.API.Shape.FromObject(objectShape); - - return new GameLib.D3.Shape.HeightMap( - physics, - apiShape, - objectShape.heightData, - objectShape.minValue, - objectShape.maxValue, - objectShape.elemSize - ); -}; -/** - * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created - * @param physics - * @param apiShape GameLib.D3.API.Shape - * @constructor - */ -GameLib.D3.Shape.Plane = function ( - physics, - apiShape -) { - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiShape)) { - apiShape = { - shapeType : GameLib.D3.API.Shape.SHAPE_TYPE_PLANE - }; - } - - if (apiShape instanceof GameLib.D3.Shape.Plane) { - return apiShape; - } - - GameLib.D3.Shape.call( - this, - this.physics, - apiShape - ); -}; - -GameLib.D3.Shape.Plane.prototype = Object.create(GameLib.D3.Shape.prototype); -GameLib.D3.Shape.Plane.prototype.constructor = GameLib.D3.Shape.Plane; - -/** - * - * @returns {GameLib.D3.Shape.Plane|*|SEA3D.Plane} - */ -GameLib.D3.Shape.Plane.prototype.createInstance = function() { - /** - * A plane is just a plane at z = 0, to rotate it put it inside a rigid body and rotate the body - */ - this.instance = new CANNON.Plane(); - GameLib.D3.Shape.prototype.createInstance.call(this); -}; - -GameLib.D3.Shape.Plane.prototype.updateInstance = function() { -}; - -GameLib.D3.Shape.Plane.FromObject = function(physics, objectShape) { - - var apiShape = GameLib.D3.API.Shape.FromObject(objectShape); - - return new GameLib.D3.Shape.Plane( - physics, - apiShape - ); -}; -/** - * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created - * @param physics - * @param apiShape GameLib.D3.API.Shape - * @param radius - * @constructor - */ -GameLib.D3.Shape.Sphere = function ( - physics, - apiShape, - radius -) { - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiShape)) { - apiShape = { - shapeType : GameLib.D3.API.Shape.SHAPE_TYPE_SPHERE - }; - } - - if (apiShape instanceof GameLib.D3.Shape.Sphere) { - return apiShape; - } - - if (GameLib.Utils.UndefinedOrNull(radius)) { - radius = 1; - } - this.radius = radius; - - GameLib.D3.Shape.call( - this, - this.physics, - apiShape - ); -}; - -GameLib.D3.Shape.Sphere.prototype = Object.create(GameLib.D3.Shape.prototype); -GameLib.D3.Shape.Sphere.prototype.constructor = GameLib.D3.Shape.Sphere; - -/** - * - * @returns {GameLib.D3.Shape.Sphere|*|SEA3D.Sphere} - */ -GameLib.D3.Shape.Sphere.prototype.createInstance = function() { - - this.instance = new CANNON.Sphere( - this.radius - ); - - GameLib.D3.Shape.prototype.createInstance.call(this); -}; - -GameLib.D3.Shape.Sphere.prototype.updateInstance = function() { - this.instance.radius = this.radius; - this.instance.updateBoundingSphereRadius(); -}; - - -GameLib.D3.Shape.Sphere.prototype.toApiObject = function() { - var apiShape = GameLib.D3.Shape.prototype.toApiObject.call(this); - apiShape.radius = this.radius; - return apiShape; -}; - -GameLib.D3.Shape.Sphere.FromObject = function(physics, objectShape) { - - var apiShape = GameLib.D3.API.Shape.FromObject(objectShape); - - return new GameLib.D3.Shape.Sphere( - physics, - apiShape, - objectShape.radius - ); -}; -/** - * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created - * @param physics - * @param apiShape GameLib.D3.API.Shape - * @param vertices - * @param indices - * @constructor - */ -GameLib.D3.Shape.TriMesh = function ( - physics, - apiShape, - vertices, - indices -) { - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiShape)) { - apiShape = { - shapeType : GameLib.D3.API.Shape.SHAPE_TYPE_TRIMESH - }; - } - - if (apiShape instanceof GameLib.D3.Shape.TriMesh) { - return apiShape; - } - - if (GameLib.Utils.UndefinedOrNull(vertices)) { - vertices = []; - } - this.vertices = vertices; - - if (GameLib.Utils.UndefinedOrNull(indices)) { - indices = []; - } - this.indices = indices; - - GameLib.D3.Shape.call( - this, - this.physics, - apiShape - ); -}; - -GameLib.D3.Shape.TriMesh.prototype = Object.create(GameLib.D3.Shape.prototype); -GameLib.D3.Shape.TriMesh.prototype.constructor = GameLib.D3.Shape.TriMesh; - -/** - * Create instance - * @returns {GameLib.D3.Shape.TriMesh} - */ -GameLib.D3.Shape.TriMesh.prototype.createInstance = function() { - - this.instance = new CANNON.TriMesh( - this.vertices, - this.indices - ); - - GameLib.D3.Shape.prototype.createInstance.call(this); - -}; - -/** - * Update instance - */ -GameLib.D3.Shape.TriMesh.prototype.updateInstance = function() { - this.instance.vertices = this.vertices; - this.instance.indices = this.indices; - this.instance.updateAABB(); - this.instance.updateBoundingSphereRadius(); - this.instance.updateEdges(); - this.instance.updateNormals(); - this.instance.updateTree(); -}; -/** - * Skeleton Superset - * @constructor - * @param graphics GameLib.GraphicsRuntime - * @param apiSkeleton GameLib.D3.API.Skeleton - */ -GameLib.D3.Skeleton = function Skeleton( - graphics, - apiSkeleton -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiSkeleton)) { - apiSkeleton = {}; - } - - if (apiSkeleton instanceof GameLib.D3.Skeleton) { - return apiSkeleton; - } - - GameLib.D3.API.Skeleton.call( - this, - apiSkeleton.id, - apiSkeleton.name, - apiSkeleton.bones, - apiSkeleton.boneInverses, - apiSkeleton.useVertexTexture, - apiSkeleton.boneTextureWidth, - apiSkeleton.boneTextureHeight, - apiSkeleton.boneMatrices, - apiSkeleton.boneTexture, - apiSkeleton.parentEntity - ); - - this.bones = this.bones.map( - function(apiBone) { - - if (apiBone instanceof GameLib.D3.API.Bone) { - return new GameLib.D3.Bone( - this.graphics, - apiBone - ) - } else { - console.warn('apiBone not an instance of API.Bone'); - throw new Error('apiBone not an instance of API.Bone'); - } - - }.bind(this) - ); - - this.boneInverses = this.boneInverses.map( - function(boneInverse) { - - if (boneInverse instanceof GameLib.API.Matrix4) { - return new GameLib.Matrix4( - this.graphics, - boneInverse, - this - ); - } else { - console.warn('boneInverse not an instance of API.Matrix4'); - throw new Error('boneInverse not an instance of API.Matrix4'); - } - - }.bind(this) - ); - - this.boneMatrices = this.boneMatrices.map( - function(boneMatrices) { - if (boneMatrices instanceof GameLib.API.Matrix4) { - return new GameLib.Matrix4( - this.graphics, - boneMatrices, - this - ); - } else { - console.warn('boneMatrices not an instance of API.Matrix4'); - throw new Error('boneMatrices not an instance of API.Matrix4'); - } - - }.bind(this) - ); - - GameLib.Component.call( - this, - { - 'bones' : [GameLib.D3.Bone] - } - ); -}; - -GameLib.D3.Skeleton.prototype = Object.create(GameLib.D3.API.Skeleton.prototype); -GameLib.D3.Skeleton.prototype.constructor = GameLib.D3.Skeleton; - - -/** - * Creates an instance skeleton - * @param update boolean - */ -GameLib.D3.Skeleton.prototype.createInstance = function(update) { - - var boneInstances = this.bones.map ( - function (bone) { - - if (GameLib.Utils.UndefinedOrNull(bone)) { - throw new Error('no bone'); - } - - if (GameLib.Utils.UndefinedOrNull(bone.instance)) { - throw new Error('no bone instance'); - } - - return bone.instance; - } - ); - - var parentBoneInstance = this.bones.reduce( - - function (result, bone) { - - if (result) { - return result; - } - - if (bone.parentBoneIds.length === 0) { - return bone.instance; - } - - return null; - }, - null - ); - - if (GameLib.Utils.UndefinedOrNull(parentBoneInstance)) { - throw new Error('could not find parent bone instance'); - } - - this.instance = new THREE.Skeleton(boneInstances); - - this.rootBoneInstance = parentBoneInstance; - - this.instance.useVertexTexture = this.useVertexTexture; - - this.boneIdToBone = {}; - - this.bones.map( - function (bone) { - this.boneIdToBone[bone.id] = bone; - }.bind(this) - ); - - /** - * TODO: check if this code does what its supposed to - */ - this.bones.map( - function (__parentBoneInstance) { - return function(bone) { - bone.childBoneIds.map( - function (childBoneId) { - __parentBoneInstance.add(this.boneIdToBone[childBoneId].instance); - }.bind(this) - ); - }; - }(parentBoneInstance).bind(this) - ); - - this.instance.update(); - - this.instance.calculateInverses(); - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance - */ -GameLib.D3.Skeleton.prototype.updateInstance = function() { - -}; - -/** - * Converts a GameLib.D3.Skeleton to GameLib.D3.API.Skeleton - * @returns {GameLib.D3.API.Skeleton} - */ -GameLib.D3.Skeleton.prototype.toApiObject = function() { - - var apiSkeleton = new GameLib.D3.API.Skeleton( - this.id, - this.name, - this.bones.map( - function (bone) { - return bone.toApiObject(); - } - ), - this.boneInverses.map( - function (boneInverse) { - return boneInverse.toApiObject(); - } - ), - this.useVertexTexture, - this.boneTextureWidth, - this.boneTextureHeight, - this.boneMatrices.map( - function (boneMatrix) { - return boneMatrix.toApiObject(); - } - ), - this.boneTexture, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiSkeleton; -}; - -/** - * Returns a GameLib.D3.Skeleton from a skeleton Object - * @param graphics GameLib.GraphicsRuntime - * @param objectSkeleton Object - * @returns {GameLib.D3.Skeleton} - * @constructor - */ -GameLib.D3.Skeleton.FromObject = function( - graphics, - objectSkeleton -) { - - if (!objectSkeleton) { - return null; - } - - var apiSkeleton = GameLib.D3.API.Skeleton.FromObject(objectSkeleton); - - var skeleton = new GameLib.D3.Skeleton( - graphics, - apiSkeleton - ); - - return skeleton; -}; -/** - * Solver Runtime - * @param physics GameLib.GraphicsRuntime - * @param apiSolver GameLib.D3.API.Solver - * @constructor - */ -GameLib.D3.Solver = function ( - physics, - apiSolver -) { - - this.physics = physics; - this.physics.isNotCannonThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiSolver)) { - apiSolver = {}; - } - - if (apiSolver instanceof GameLib.D3.Solver) { - return apiSolver; - } - - GameLib.D3.API.Solver.call( - this, - apiSolver.id, - apiSolver.name, - apiSolver.solverType, - apiSolver.iterations, - apiSolver.tolerance, - apiSolver.parentEntity - ); - - GameLib.Component.call(this); -}; - -GameLib.D3.Solver.prototype = Object.create(GameLib.D3.API.Solver.prototype); -GameLib.D3.Solver.prototype.constructor = GameLib.D3.Solver; - -/** - * - * @returns {*} - */ -GameLib.D3.Solver.prototype.createInstance = function() { - - if (this.solverType === GameLib.D3.API.Solver.GS_SOLVER) { - this.instance = new CANNON.GSSolver(); - } else if (this.solverType === GameLib.D3.API.Solver.SPLIT_SOLVER) { - this.instance = new CANNON.SplitSolver(); - } else { - throw new Error('unsupported solver type: ' + this.solverType); - } - - this.instance.tolerance = this.tolerance; - this.instance.iterations = this.iterations; - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * - */ -GameLib.D3.Solver.prototype.updateInstance = function() { - - if (this.solverType === GameLib.D3.API.Solver.GS_SOLVER) { - if (!(this.instance instanceof CANNON.GSSolver)) { - this.instance = new CANNON.GSSolver(); - } - } - - if (this.solverType === GameLib.D3.API.Solver.SPLIT_SOLVER) { - if (!(this.instance instanceof CANNON.SplitSolver)) { - this.instance = new CANNON.SplitSolver(); - } - } - - this.instance.iterations = this.iterations; - this.instance.tolerance = this.tolerance; -}; - -/** - * GameLib.D3.Solver to GameLib.D3.API.Solver - * @returns {GameLib.D3.API.Solver} - */ -GameLib.D3.Solver.prototype.toApiObject = function() { - - var apiSolver = new GameLib.D3.API.Solver( - this.id, - this.name, - this.solverType, - this.iterations, - this.tolerance, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiSolver; -}; - -/** - * GameLib.D3.Solver from Object Solver - * @param graphics - * @param objectComponent - * @returns {GameLib.D3.Solver} - * @constructor - */ -GameLib.D3.Solver.FromObject = function(graphics, objectComponent) { - - var apiSolver = GameLib.D3.API.Solver.FromObject(objectComponent); - - return new GameLib.D3.Solver( - graphics, - apiSolver - ); -}; - -/** - * Spline constructor - * @param graphics GameLib.GraphicsRuntime - * @param apiSpline GameLib.D3.API.Spline - * @constructor - */ -GameLib.D3.Spline = function ( - graphics, - apiSpline -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiSpline)) { - apiSpline = {}; - } - - if (apiSpline instanceof GameLib.D3.Spline) { - return apiSpline; - } - - GameLib.D3.API.Spline.call( - this, - apiSpline.id, - apiSpline.name, - apiSpline.vertices, - apiSpline.parentEntity - ); - - this.vertices = this.vertices.map( - function (vertex) { - return new GameLib.Vector3( - graphics, - vertex, - this - ) - } - ); - - GameLib.Component.call(this); -}; - -GameLib.D3.Spline.prototype = Object.create(GameLib.D3.API.Spline.prototype); -GameLib.D3.Spline.prototype.constructor = GameLib.D3.Spline; - -/** - * Creates an instance spline - */ -GameLib.D3.Spline.prototype.createInstance = function() { - - var vertices = this.vertices.map( - function (vertex) { - - if (GameLib.Utils.UndefinedOrNull(vertex)) { - throw new Error('no vertex') - } - - if (GameLib.Utils.UndefinedOrNull(vertex.instance)) { - throw new Error('no vertex instance') - } - - return vertex.instance; - } - ); - - this.instance = THREE.CatmullRomCurve3(vertices); - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance - */ -GameLib.D3.Spline.prototype.updateInstance = function() { - - var vertices = this.vertices.map( - function (vertex) { - - if (GameLib.Utils.UndefinedOrNull(vertex)) { - throw new Error('no vertex') - } - - if (GameLib.Utils.UndefinedOrNull(vertex.instance)) { - throw new Error('no vertex instance') - } - - return vertex.instance; - } - ); - - this.instance = new THREE.CatmullRomCurve3(vertices); -}; - -/** - * Converts a GameLib.D3.Spline to GameLib.D3.API.Spline - * @returns {GameLib.D3.API.Spline} - */ -GameLib.D3.Spline.prototype.toApiObject = function() { - - return new GameLib.D3.API.Spline( - this.id, - this.name, - this.vertices.map( - function (vertex) { - return vertex.toApiObject() - } - ), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - -}; - -/** - * Returns a GameLib.D3.Spline from a spline Object - * @param graphics GameLib.GraphicsRuntime - * @param objectComponent Object - * @returns {GameLib.D3.Spline} - * @constructor - */ -GameLib.D3.Spline.FromObject = function( - graphics, - objectComponent -) { - var apiSpline = GameLib.D3.API.Spline.FromObject(objectComponent); - - return new GameLib.D3.Spline( - graphics, - apiSpline - ); -}; - -/** - * Gets the current point from the spline at the proper value - * @param proper Number (fraction between 0 and 1 indicating position on spline) - * @returns {*} - */ -GameLib.D3.Spline.prototype.getPointAt = function(proper) { - var point = this.instance.getPointAt(proper); - return new GameLib.Vector3( - this.graphics, - new GameLib.API.Vector3(point.x, point.y, point.z), - this, - 0.1 - ); -}; - -/** - * Texture Superset - The apiTexture properties get moved into the Texture object itself, and then the instance is - * created - * @param apiTexture - * @param graphics GameLib.GraphicsRuntime - * @constructor - */ -GameLib.D3.Texture = function( - graphics, - apiTexture -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiTexture)) { - apiTexture = {}; - } - - if (apiTexture instanceof GameLib.D3.Texture) { - return apiTexture; - } - - GameLib.D3.API.Texture.call( - this, - apiTexture.id, - apiTexture.textureType, - apiTexture.name, - apiTexture.image, - apiTexture.images, - apiTexture.wrapS, - apiTexture.wrapT, - apiTexture.repeat, - apiTexture.data, - apiTexture.format, - apiTexture.mapping, - apiTexture.magFilter, - apiTexture.minFilter, - apiTexture.storageType, - apiTexture.anisotropy, - apiTexture.offset, - apiTexture.generateMipmaps, - apiTexture.flipY, - apiTexture.mipmaps, - apiTexture.unpackAlignment, - apiTexture.premultiplyAlpha, - apiTexture.encoding, - apiTexture.canvas, - apiTexture.animated, - apiTexture.reverseAnimation, - apiTexture.forward, - apiTexture.parentEntity - ); - - this.offset = new GameLib.Vector2( - this.graphics, - this.offset, - this - ); - - this.repeat = new GameLib.Vector2( - this.graphics, - this.repeat, - this - ); - - if (this.image instanceof GameLib.API.Image) { - this.image = new GameLib.Image( - this.graphics, - this.image - ); - } - - this.images = this.images.map( - function(image) { - if (image instanceof GameLib.API.Image) { - return new GameLib.Image( - this.graphics, - image - ); - } else { - return image; - } - }.bind(this) - ); - - if (this.canvas instanceof GameLib.API.Canvas) { - this.canvas = new GameLib.Canvas( - this.graphics, - this.canvas - ); - } - - GameLib.Component.call( - this, - { - 'image' : GameLib.Image, - 'images' : [GameLib.Image], - 'canvas' : GameLib.Canvas - } - ); -}; - -GameLib.D3.Texture.prototype = Object.create(GameLib.D3.API.Texture.prototype); -GameLib.D3.Texture.prototype.constructor = GameLib.D3.Texture; - -/** - * Creates an instance of our texture object - * @returns {*} - */ -GameLib.D3.Texture.prototype.createInstance = function() { - - if (this.textureType === GameLib.D3.API.Texture.TEXTURE_TYPE_CUBE) { - - if (this.images.length !== 6) { - throw new Error('not enough images for cube texture'); - } - - var imageInstances = this.images.map( - function(image) { - - if (GameLib.Utils.UndefinedOrNull(image)) { - throw new Error('no image'); - } - - if (GameLib.Utils.UndefinedOrNull(image.instance)) { - throw new Error('no image instance'); - } - - return image.instance - } - ); - - this.instance = new THREE.CubeTexture(imageInstances); - - } else if (this.textureType === GameLib.D3.API.Texture.TEXTURE_TYPE_NORMAL) { - - if ( - GameLib.Utils.UndefinedOrNull(this.image) || - GameLib.Utils.UndefinedOrNull(this.image.instance) - ) { - - this.instance = new THREE.Texture(); - - } else { - - //if (GameLib.Utils.UndefinedOrNull(this.image.instance)) { - // throw new Error('no image instance'); - //} - - this.instance = new THREE.Texture( - this.image.instance - ); - - } - - } else if (this.textureType === GameLib.D3.API.Texture.TEXTURE_TYPE_CANVAS) { - - if (GameLib.Utils.UndefinedOrNull(this.canvas)) { - - this.instance = new THREE.Texture(); - - } else { - - if (GameLib.Utils.UndefinedOrNull(this.canvas.instance)) { - throw new Error('no canvas instance'); - } - - this.instance = new THREE.Texture( - this.canvas.instance - ); - - } - - } - - /** - * Some settings we copy from the instance - */ - this.mapping = this.instance.mapping; - this.encoding = this.instance.encoding; - this.format = this.instance.format; - - /** - * Others we apply to the instance - */ - this.instance.name = this.name; - this.instance.flipY = this.flipY; - this.instance.offset.x = this.offset.x; - this.instance.offset.y = this.offset.y; - this.instance.repeat.x = this.repeat.x; - this.instance.repeat.y = this.repeat.y; - this.instance.wrapS = this.wrapS; - this.instance.wrapT = this.wrapT; - - this.instance.needsUpdate = true; - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.D3.Texture.prototype.updateInstance = function(property) { - - if (GameLib.Utils.UndefinedOrNull(this.instance)) { - try { - this.createInstance(); - return; - } catch (error) { - console.error(error); - } - } - - if (GameLib.Utils.UndefinedOrNull(property)) { - throw new Error('need to specify a property'); - } - - if (property === 'image') { - - if (this.textureType === GameLib.D3.API.Texture.TEXTURE_TYPE_NORMAL) { - - if ( - GameLib.Utils.UndefinedOrNull(this.image) && - this.instance.image - ) { - try { - this.createInstance(); - } catch (error) { - console.error(error); - } - } - - if (this.image && this.image.instance && this.instance.image !== this.image.instance) { - try { - this.createInstance(); - } catch (error) { - console.error(error); - } - } - - } else if (this.textureType === GameLib.D3.API.Texture.TEXTURE_TYPE_CANVAS) { - - if ( - GameLib.Utils.UndefinedOrNull(this.canvas) && - this.instance.canvas - ) { - try { - this.createInstance(); - } catch (error) { - console.error(error); - } - } - - if (this.canvas && this.canvas.instance && this.instance.image !== this.canvas.instance) { - try { - this.createInstance(); - } catch (error) { - console.error(error); - } - } - - } else if (this.textureType === GameLib.D3.API.Texture.TEXTURE_TYPE_CUBE) { - - console.log('todo : cube images change check here'); - - } - - this.publish( - GameLib.Event.IMAGE_CHANGED, - { - texture : this - } - ); - - this.instance.needsUpdate = true; - } - - if (property === 'name') { - this.instance.name = this.name; - } - - if (property === 'flipY') { - this.instance.flipY = this.flipY; - } - - if (property === 'encoding') { - this.instance.encoding = this.encoding; - } - - if (property === 'offset') { - this.instance.offset.x = this.offset.x; - this.instance.offset.y = this.offset.y; - } - - if (property === 'repeat') { - this.instance.repeat.x = this.repeat.x; - this.instance.repeat.y = this.repeat.y; - } - - if (property === 'mapping') { - this.instance.mapping = this.mapping; - } - - if (property === 'format') { - this.instance.format = this.format; - } - - if (property === 'wrapS') { - this.instance.wrapS = this.wrapS; - this.instance.needsUpdate = true; - } - - if (property === 'wrapT') { - this.instance.wrapT = this.wrapT; - this.instance.needsUpdate = true; - } - - if (property === 'animated') { - GameLib.Event.Emit( - GameLib.Event.TEXTURE_ANIMATED_CHANGE, - { - texture : this - } - ) - } -}; - -/** - * Converts a GameLib.D3.Texture to a GameLib.D3.API.Texture - * @returns {GameLib.D3.API.Texture} - */ -GameLib.D3.Texture.prototype.toApiObject = function() { - - var apiTexture = new GameLib.D3.API.Texture( - this.id, - this.textureType, - this.name, - GameLib.Utils.IdOrNull(this.image), - this.images.map( - function(image) { - return GameLib.Utils.IdOrNull(image) - } - ), - this.wrapS, - this.wrapT, - this.repeat.toApiObject(), - this.data, - this.format, - this.mapping, - this.magFilter, - this.minFilter, - this.storageType, - this.anisotropy, - this.offset.toApiObject(), - this.generateMipmaps, - this.flipY, - this.mipmaps, - this.unpackAlignment, - this.premultiplyAlpha, - this.encoding, - GameLib.Utils.IdOrNull(this.canvas), - this.animated, - this.reverseAnimation, - this.forward, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiTexture; - -}; - -/** - * Converts from an Object texture to a GameLib.D3.Texture - * @param graphics GameLib.GraphicsRuntime - * @param objectTexture Object - * @constructor - */ -GameLib.D3.Texture.FromObject = function( - graphics, - objectTexture -) { - var apiTexture = GameLib.D3.API.Texture.FromObject(objectTexture); - - return new GameLib.D3.Texture( - graphics, - apiTexture - ); -}; - -/** - * TriangleEdge - * @param triangle - * @param edge - * @constructor - */ -GameLib.D3.TriangleEdge = function( - triangle, - edge -) { - this.triangle = triangle; - this.edge = edge; -}; -/** - * Runtime Vertex - * @constructor - * @param implementation - * @param apiVertex - */ -GameLib.D3.Vertex = function Vertex( - implementation, - apiVertex -) { - this.implementation = implementation; - if (implementation instanceof GameLib.GraphicsRuntime) { - this.implementation.isNotThreeThrow(); - } else if (implementation instanceof GameLib.PhysicsRuntime) { - this.implementation.isNotCannonThrow(); - } else { - throw new Error('Unhandled implementation : ' + implementation); - } - - if (GameLib.Utils.UndefinedOrNull(apiVertex)) { - apiVertex = {}; - } - - if (apiVertex instanceof GameLib.D3.Vertex) { - return apiVertex; - } - - GameLib.D3.API.Vertex.call( - this, - apiVertex.position, - apiVertex.boneWeights - ); - - this.position = new GameLib.Vector3( - this.implementation, - this.position, - null - ); - - if (implementation instanceof GameLib.GraphicsRuntime) { - this.boneWeights = this.boneWeights.map( - function(apiBoneWeight) { - return new GameLib.D3.BoneWeight( - this.implementation, - apiBoneWeight - ) - }.bind(this) - ) - } -}; - -GameLib.D3.Vertex.prototype = Object.create(GameLib.D3.API.Vertex.prototype); -GameLib.D3.Vertex.prototype.constructor = GameLib.D3.Vertex; - -/** - * Converts a GameLib.D3.Vertex to GameLib.D3.API.Vertex - * @returns {GameLib.D3.API.Vertex} - */ -GameLib.D3.Vertex.prototype.toApiObject = function() { - - return new GameLib.D3.API.Vertex( - this.position.toApiObject(), - this.boneWeights.map(function(boneWeight){ - return boneWeight.toApiObject(); - }) - ); - -}; - -/** - * Returns a GameLib.D3.Vertex from a vertex Object - * @param implementation (graphics or physics object) - * @param objectVertex Object - * @returns {GameLib.D3.Vertex} - * @constructor - */ -GameLib.D3.Vertex.FromObject = function( - implementation, - objectVertex -) { - var apiVertex = GameLib.D3.API.Vertex.FromObject(objectVertex); - - return new GameLib.D3.Vertex( - implementation, - apiVertex - ); -}; - -/** - * Viewport Runtime - * @param graphics GameLib.GraphicsRuntime - * @param apiViewport GameLib.D3.API.Viewport - * @constructor - */ -GameLib.D3.Viewport = function ( - graphics, - apiViewport -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiViewport)) { - apiViewport = {}; - } - - if (apiViewport instanceof GameLib.D3.Viewport) { - return apiViewport; - } - - GameLib.D3.API.Viewport.call( - this, - apiViewport.id, - apiViewport.name, - apiViewport.width, - apiViewport.height, - apiViewport.x, - apiViewport.y, - apiViewport.parentEntity - ); - - GameLib.Component.call(this); -}; - -GameLib.D3.Viewport.prototype = Object.create(GameLib.D3.API.Viewport.prototype); -GameLib.D3.Viewport.prototype.constructor = GameLib.D3.Viewport; - -/** - * - * @returns {boolean} - */ -GameLib.D3.Viewport.prototype.createInstance = function() { - this.instance = true; - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * - */ -GameLib.D3.Viewport.prototype.updateInstance = function() { -}; - -/** - * GameLib.D3.Viewport to GameLib.D3.API.Viewport - * @returns {GameLib.D3.API.Viewport} - */ -GameLib.D3.Viewport.prototype.toApiObject = function() { - - var apiViewport = new GameLib.D3.API.Viewport( - this.id, - this.name, - this.width, - this.height, - this.x, - this.y, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiViewport; -}; - -/** - * GameLib.D3.Viewport from Object Viewport - * @param graphics - * @param objectComponent - * @returns {GameLib.D3.Viewport} - * @constructor - */ -GameLib.D3.Viewport.FromObject = function(graphics, objectComponent) { - - var apiViewport = GameLib.D3.API.Viewport.FromObject(objectComponent); - - return new GameLib.D3.Viewport( - graphics, - apiViewport - ); -}; -/** - * Runtime domElement for updating instance objects - * @param apiDomElement GameLib.API.DomElement - * @constructor - */ -GameLib.DomElement = function (apiDomElement) { - - if (GameLib.Utils.UndefinedOrNull(apiDomElement)) { - apiDomElement = {}; - } - - if (apiDomElement instanceof GameLib.DomElement) { - return apiDomElement; - } - - GameLib.API.DomElement.call( - this, - apiDomElement.id, - apiDomElement.name, - apiDomElement.domElementId, - apiDomElement.parentEntity - ); - - this.fullscreen = false; - - GameLib.Component.call(this); -}; - -GameLib.DomElement.prototype = Object.create(GameLib.API.DomElement.prototype); -GameLib.DomElement.prototype.constructor = GameLib.DomElement; - -/** - * Creates an instance domElement - * @returns {*} - */ -GameLib.DomElement.prototype.createInstance = function() { - this.instance = document.getElementById(this.domElementId); - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates instance domElement - */ -GameLib.DomElement.prototype.updateInstance = function() { - this.instance = document.getElementById(this.domElementId); -}; - -/** - * Converts runtime DomElement to API DomElement - * @returns {GameLib.API.DomElement} - */ -GameLib.DomElement.prototype.toApiObject = function() { - return new GameLib.API.DomElement( - this.id, - this.name, - this.domElementId, - GameLib.Utils.IdOrNull(this.parentEntity) - ); -}; - -/** - * Appends domInstance to DOM instance - * @param domInstance - */ -GameLib.DomElement.prototype.append = function(domInstance) { - this.instance.appendChild(domInstance); -}; - -/** - * Clears DOM instance - */ -GameLib.DomElement.prototype.clear = function() { - this.instance.innerHTML = ''; -}; - - -GameLib.DomElement.prototype.requestFullscreen = function(event) { - - var docEl = document.documentElement; - - if (docEl.requestFullscreen) { - docEl.requestFullscreen(); - } else if (docEl.msRequestFullscreen) { - docEl.msRequestFullscreen(); - } else if (docEl.mozRequestFullScreen) { - docEl.mozRequestFullScreen(); - } else if (docEl.webkitRequestFullscreen) { - docEl.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); - } - - this.fullscreen = true; -}; - - -GameLib.DomElement.prototype.exitFullscreen = function(event) { - - if (document.exitFullscreen) { - document.exitFullscreen(); - } else if (document.msExitFullscreen) { - document.msExitFullscreen(); - } else if (document.mozCancelFullScreen) { - document.mozCancelFullScreen(); - } else if (document.webkitExitFullscreen) { - document.webkitExitFullscreen(); - } - - this.fullscreen = false; -}; - -GameLib.DomElement.FromObject = function(objectDom) { - - var apiDomElement = GameLib.API.DomElement.FromObject(objectDom); - - var domElement = new GameLib.DomElement( - apiDomElement - ); - - return domElement; -}; -/** - * GameLib.EntityManager - * @constructor - */ -GameLib.EntityManager = function(apiEntityManager) { - - if (GameLib.Utils.UndefinedOrNull(apiEntityManager)) { - apiEntityManager = {}; - } - - if (apiEntityManager instanceof GameLib.EntityManager) { - return apiEntityManager; - } - - GameLib.API.EntityManager.call( - this, - apiEntityManager.id, - apiEntityManager.name, - apiEntityManager.entities, - apiEntityManager.defaultEntity, - apiEntityManager.defaultRenderer, - apiEntityManager.parentEntity - ); - - /** - * The 'register' array is a register of each component currently loaded - when the linking - * system starts it also loads all the current components from the entity manager - * @type {Array} - */ - this.register = {}; - - this.idRegister = {}; - - GameLib.Event.Subscribe( - GameLib.Event.COMPONENT_REGISTER, - this.registerComponent.bind(this) - ); - - GameLib.Event.Subscribe( - GameLib.Event.REMOVE_COMPONENT, - this.removeComponent.bind(this) - ); - - GameLib.Component.call( - this, - { - 'entities' : [GameLib.Entity], - 'defaultEntity' : GameLib.Entity, - 'defaultRenderer' : GameLib.D3.Renderer - } - ); -}; - -GameLib.EntityManager.prototype = Object.create(GameLib.API.EntityManager.prototype); -GameLib.EntityManager.prototype.constructor = GameLib.EntityManager; - -GameLib.EntityManager.prototype.createInstance = function() { - this.instance = GameLib.EntityManager.Instance; - GameLib.Component.prototype.createInstance.call(this); -}; - -GameLib.EntityManager.prototype.registerComponent = function(data) { - - var updated = false; - - if (GameLib.Utils.UndefinedOrNull(this.register[data.component.componentType])) { - this.register[data.component.componentType] = {}; - GameLib.Event.Emit( - GameLib.Event.COMPONENT_TYPES_UPDATE, - { - componentType : data.component.componentType, - componentTypes : Object.keys(this.register) - } - ); - updated = true; - } - - if (GameLib.Utils.UndefinedOrNull(this.register[data.component.componentType][data.component.id])) { - this.register[data.component.componentType][data.component.id] = data.component; - updated = true; - } - - if (GameLib.Utils.UndefinedOrNull(this.idRegister[data.component.id])) { - this.idRegister[data.component.id] = data.component; - updated = true; - } - - if (updated) { - GameLib.Event.Emit( - GameLib.Event.REGISTER_UPDATE, - { - componentType : data.component.componentType, - components : this.register[data.component.componentType], - idRegister : this.idRegister, - register : this.register - } - ); - } -}; - -GameLib.EntityManager.prototype.removeComponent = function(data) { - - var updated = true; - - if (GameLib.Utils.UndefinedOrNull(this.register[data.component.componentType]) || - GameLib.Utils.UndefinedOrNull(this.register[data.component.componentType][data.component.id]) || - GameLib.Utils.UndefinedOrNull(this.idRegister[data.component.id]) - ) { - console.warn('register out of sync'); - updated = false; - } else { - delete this.register[data.component.componentType][data.component.id]; - - if (GameLib.Utils.IsEmpty(this.register[data.component.componentType])) { - delete this.register[data.component.componentType]; - GameLib.Event.Emit( - GameLib.Event.COMPONENT_TYPES_UPDATE, - { - componentType : data.component.componentType, - componentTypes : Object.keys(this.register) - } - ); - } - - delete this.idRegister[data.component.id]; - } - - if (updated) { - GameLib.Event.Emit( - GameLib.Event.REGISTER_UPDATE, - { - componentType : data.component.componentType, - components : this.register[data.component.componentType], - idRegister : this.idRegister, - register : this.register - } - ); - } - -}; - -/** - * Creates an GameLib.Entity and adds it to entities array - * @returns {*} - */ -GameLib.EntityManager.prototype.createEntity = function(name) { - - var apiEntity = new GameLib.API.Entity( - null, - name, - null, - null, - this - ); - - var entity = new GameLib.Entity( - apiEntity - ); - - this.entities.push(entity); - - this.defaultEntity = entity; - - GameLib.Event.Emit( - GameLib.Event.NEW_ENTITY, - { - entity : entity - } - ); - - return entity; -}; - -/** - * Returns an entity by ID or null - * @param id - * @returns {*} - */ -GameLib.EntityManager.prototype.findEntityById = function(id) { - - var entity = this.register[GameLib.Component.ENTITY][id]; - - if (entity) { - return entity; - } - - return null; -}; - -GameLib.EntityManager.prototype.findComponentById = function(id) { - return this.idRegister[id]; -}; - -GameLib.EntityManager.prototype.findComponentByName = function(name) { - - return Object.keys(this.idRegister).reduce( - function(result, componentId) { - - if (this.idRegister[componentId].name === name) { - result = this.idRegister[componentId]; - } - - return result; - - }.bind(this), - null - ); - -}; - -GameLib.EntityManager.prototype.findHelperByObject = function(object) { - - if (typeof this.register[GameLib.Component.HELPER] === 'undefined') { - return null; - } - - return Object.keys(this.register[GameLib.Component.HELPER]).reduce( - function(result, helperId) { - - if (this.register[GameLib.Component.HELPER][helperId].object === object) { - result = this.register[GameLib.Component.HELPER][helperId]; - } - - return result; - }.bind(this), - null - ); - -}; - -GameLib.EntityManager.prototype.findSceneByObject = function(object) { - - return Object.keys(this.register[GameLib.Component.SCENE]).reduce( - function(result, sceneId) { - - if ( - this.register[GameLib.Component.SCENE][sceneId].meshes.indexOf(object) !== -1 || - this.register[GameLib.Component.SCENE][sceneId].lights.indexOf(object) !== -1 - ) { - result = this.register[GameLib.Component.SCENE][sceneId]; - } - - return result; - }.bind(this), - null - ); - -}; - - -/** - * Adds an entity to this manager - * @param entity GameLib.Entity - */ -GameLib.EntityManager.prototype.addEntity = function(entity) { - entity.parentEntityManager = this; - this.entities.push(entity); -}; - -/** - * Returns entity by name - * @param name - * @returns {*} - */ -GameLib.EntityManager.prototype.queryByName = function(name) { - return this.entities.reduce( - function(result, entity){ - if (entity.name === name) { - result = entity; - } - return result; - }, - null - ) -}; - -/** - * Removes an entity - do we remove all its components as well? - * @param entity GameLib.D3.Entity - * @returns boolean true if successful - */ -GameLib.EntityManager.prototype.removeEntity = function(entity) { - - var index = this.entities.indexOf(entity); - - if (index === -1) { - console.log('failed to remove entity : ', entity); - return false; - } - this.entities.splice(index, 1); - - entity.parentEntityManager = null; - - return true; -}; - -/** - * Returns all the entities with the following components - * @param components GameLib.Component[] - */ -GameLib.EntityManager.prototype.findEntities = function(components) { - - var entities = this.entities.reduce( - function(result, entity) { - - var hasAllComponents = components.reduce( - function(componentResult, component) { - if (!entity.hasComponent(component)) { - componentResult = false; - } - return componentResult; - }, - true - ); - - if (hasAllComponents) { - result.push(entity); - } - - return result; - }, - [] - ); - - return entities; -}; - -/** - * Returns all actual components of all entities that contain this component - * More efficient - * @param componentTypes (array of component types or a single component type) - */ -GameLib.EntityManager.prototype.queryComponents = function(componentTypes) { - - var result = []; - - if (componentTypes instanceof Array) { - componentTypes.map( - function(componentType) { - - if (typeof this.register[componentType] === 'undefined') { - return; - } - - Object.keys(this.register[componentType]).map( - function(componentId) { - result.push(this.register[componentType][componentId]); - }.bind(this) - ) - }.bind(this) - ) - } else { - - if (typeof this.register[componentTypes] === 'undefined') { - return result; - } - - Object.keys(this.register[componentTypes]).map( - function(componentId) { - result.push(this.register[componentTypes][componentId]); - }.bind(this) - ) - } - - return result; -}; - -/** - * Slower way of retrieving objects - * @param constructors (array of constructors, or a constructor) - * @returns {*} - */ -GameLib.EntityManager.prototype.queryComponentsByConstructor = function(constructors) { - return Object.keys(this.idRegister).reduce( - function(result, componentId) { - if (constructors instanceof Array) { - - constructors.map( - function(constructor) { - if (this.idRegister[componentId] instanceof constructor) { - result.push(this.idRegister[componentId]); - } - }.bind(this) - ) - - } else { - - if (this.idRegister[componentId] instanceof constructors) { - result.push(this.idRegister[componentId]); - } - } - - return result; - }.bind(this), - [] - ); -}; - -/** - * Converts a GameLib.Entity to GameLib.API.Entity - * @returns {GameLib.API.EntityManager} - */ -GameLib.EntityManager.prototype.toApiObject = function() { - - var apiEntities = this.entities.map( - function (entity) { - return GameLib.Utils.IdOrNull(entity); - } - ); - - var apiEntityManager = new GameLib.API.EntityManager( - this.id, - this.name, - apiEntities, - GameLib.Utils.IdOrNull(this.defaultEntity), - GameLib.Utils.IdOrNull(this.defaultRenderer), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiEntityManager; -}; - -/** - * Returns an EntityManager from an Object entity manager - * @param objectEntityManager Object - * @constructor - */ -GameLib.EntityManager.FromObject = function(objectEntityManager) { - - var apiEntityManager = GameLib.API.EntityManager.FromObject(objectEntityManager); - - var entityManager = new GameLib.EntityManager(apiEntityManager); - - return entityManager; -}; - -/** - * Runtime Entity - * @param apiEntity GameLib.D3.API.Entity - * @constructor - */ -GameLib.Entity = function ( - apiEntity -) { - if (GameLib.Utils.UndefinedOrNull(apiEntity)) { - apiEntity = {}; - } - - if (apiEntity instanceof GameLib.Entity) { - return apiEntity; - } - - GameLib.API.Entity.call( - this, - apiEntity.id, - apiEntity.name, - apiEntity.components, - apiEntity.parentEntity, - apiEntity.parentEntityManager - ); - - GameLib.Component.call( - this, - { - 'components' : [GameLib.Component], - 'activeComponent' : GameLib.Component - } - ); -}; - -GameLib.Entity.prototype = Object.create(GameLib.API.Entity.prototype); -GameLib.Entity.prototype.constructor = GameLib.Entity; - -/** - * Creates an entity instance - */ -GameLib.Entity.prototype.createInstance = function() { - /** - * FUCK ecsjs and tiny-ecs - no client-side support and shitty code (only takes constructors as args) - */ - this.instance = true; - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Adds a component to this entity through the instance (should notify the entity manager instance) - * @param component - */ -GameLib.Entity.prototype.addComponent = function(component) { - - GameLib.Utils.PushUnique(this.components, component); - - if (component instanceof GameLib.D3.Mesh) { - - /** - * For meshes, simply get the children components - * @type {Array} - */ - component.getChildrenComponents().map(function(childComponent){ - GameLib.Utils.PushUnique(this.components, childComponent); - childComponent.parentEntity = this; - }.bind(this)) - - } else { - /** - * Here we will dig into this component - find all its 'parentEntity' members - and update them accordingly - */ - component.buildIdToObject(); - - /** - * Also add the child components of this component as components of this entity - */ - for (var property in component.idToObject) { - if (component.idToObject.hasOwnProperty(property) && - component.idToObject[property] !== component && - component.idToObject[property] instanceof GameLib.Component - ) { - GameLib.Utils.PushUnique(this.components, component.idToObject[property]); - component.idToObject[property].parentEntity = this; - } - } - } - - - /** - * Finally, we are the boss component - update my parent entity - * @type {GameLib.Entity} - */ - component.parentEntity = this; - -}; - -/** - * Returns all components of type 'constructor' - * @param constructor - */ -GameLib.Entity.prototype.getComponents = function(constructor) { - - var components = this.components.reduce( - function(result, component) { - if (component instanceof constructor) { - result.push(component); - } - return result; - }, - [] - ); - - return components; -}; - -/** - * Returns the first component or null - * @param constructor - */ -GameLib.Entity.prototype.getFirstComponent = function(constructor) { - - var components = this.getComponents(constructor); - - if (components.length > 0) { - return components[0]; - } - - return null; -}; - -/** - * Returns true when this entity has a certain component, false otherwise - * @param constructor - */ -GameLib.Entity.prototype.hasComponent = function(constructor) { - - var has = this.components.reduce( - function(result, component) { - if (component instanceof constructor) { - result = true; - } - return result; - }, - false - ); - - return has; -}; - -/** - * - * @param component - */ -GameLib.Entity.prototype.removeComponent = function(component) { - - if (GameLib.Utils.UndefinedOrNull(component)) { - component = this.activeComponent; - } - - var childIndex = this.components.indexOf(component); - if (childIndex !== -1) { - this.components.splice(childIndex, 1); - } else { - console.error('component not found'); - } - - /** - * Break the dependency to the parent - */ - component.parentEntity = null; - - return true; -}; - -/** - * Updates an entity instance - */ -GameLib.Entity.prototype.updateInstance = function() { - console.log('entity update instance called'); -}; - -/** - * Converts a GameLib.Entity to GameLib.API.Entity - * @returns {GameLib.API.Entity} - */ -GameLib.Entity.prototype.toApiObject = function() { - - var apiComponents = this.components.map( - function(component) { - return GameLib.Utils.IdOrNull(component); - } - ); - - return new GameLib.API.Entity( - this.id, - this.name, - apiComponents, - GameLib.Utils.IdOrNull(this.parentEntity), - GameLib.Utils.IdOrNull(this.parentEntityManager) - ); - -}; - -/** - * Entity from Object - * @param objectEntity Object - * @param parentEntityManager GameLib.D3.EntityManager - * @returns {GameLib.Entity} - * @constructor - */ -GameLib.Entity.FromObject = function(objectEntity, parentEntityManager) { - - var apiEntity = GameLib.API.Entity.FromObject(objectEntity); - - var entity = new GameLib.Entity( - apiEntity - ); - - if (GameLib.Utils.UndefinedOrNull(parentEntityManager)) { - return entity; - } - - parentEntityManager.addEntity(entity); - - return entity; -}; - -/** - * Graphics - * @param id - * @param name - * @param graphicsType - * @constructor - */ -GameLib.GraphicsRuntime = function( - id, - name, - graphicsType -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Graphics (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(graphicsType)) { - graphicsType = GameLib.GraphicsRuntime.TYPE_THREE_JS; - } - this.graphicsType = graphicsType; - - this.createInstance(); -}; - -/** - * GameLib.GraphicsRuntime Types - * @type {number} - */ -GameLib.GraphicsRuntime.TYPE_THREE_JS = 0x1; - -GameLib.GraphicsRuntime.prototype.createInstance = function() { - if (this.graphicsType === GameLib.GraphicsRuntime.TYPE_THREE_JS) { - this.instance = THREE; - } else { - this.instance = null; - } -}; - -GameLib.GraphicsRuntime.prototype.updateInstance = function(property) { - if (property === 'graphicsType') { - this.createInstance(); - } -}; - -/** - * Logs a warning and throws an error if not cannon - */ -GameLib.GraphicsRuntime.prototype.isNotThreeThrow = function() { - if (this.instance !== THREE) { - console.error('Only THREE supported'); - throw new Error('Only THREE supported'); - } -}; - -/** - * GUI - * @param id - * @param name - * @param guiType - * @constructor - */ -GameLib.GUIRuntime = function( - id, - name, - guiType -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'GUI (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(guiType)) { - guiType = GameLib.GUIRuntime.TYPE_DAT_GUI; - } - this.guiType = guiType; - - this.createInstance(); -}; - -/** - * GameLib.GUIRuntime Types - * @type {number} - */ -GameLib.GUIRuntime.TYPE_DAT_GUI = 0x1; - -GameLib.GUIRuntime.prototype.createInstance = function() { - if (this.guiType === GameLib.GUIRuntime.TYPE_DAT_GUI) { - this.instance = dat.GUI; - } else { - this.instance = null; - } -}; - -GameLib.GUIRuntime.prototype.updateInstance = function(property) { - if (property === 'guiType') { - this.createInstance(); - } -}; - -/** - * Logs a warning and throws an error if not cannon - */ -GameLib.GUIRuntime.prototype.isNotDatGuiThrow = function() { - if (this.instance !== dat.GUI) { - console.error('Only dat.gui supported'); - throw new Error('Only dat.gui supported'); - } -}; - -/** - * GUI component - * @param guiRuntime - * @param apiGUI - * @constructor - */ -GameLib.GUI = function( - guiRuntime, - apiGUI -) { - this.guiRuntime = guiRuntime; - this.guiRuntime.isNotDatGuiThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiGUI)) { - apiGUI = {}; - } - - if (apiGUI instanceof GameLib.GUI) { - return apiGUI; - } - - GameLib.API.GUI.call( - this, - apiGUI.id, - apiGUI.name, - apiGUI.domElement, - apiGUI.parentEntity - ); - - GameLib.Component.call( - this, - { - 'domElement': GameLib.DomElement - } - ); -}; - -GameLib.GUI.prototype = Object.create(GameLib.Component.prototype); -GameLib.GUI.prototype.constructor = GameLib.GUI; - -/** - * Creates a helper instance - */ -GameLib.GUI.prototype.createInstance = function() { - this.instance = new this.guiRuntime.instance( { autoPlace: false } ); - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.GUI.prototype.updateInstance = function(property) { - console.log('todo: implement gui update instance:' + property); -}; - -/** - * Converts a GameLib.GUI to a new GameLib.API.GUI - * @returns {GameLib.API.GUI} - */ -GameLib.GUI.prototype.toApiObject = function() { - - return new GameLib.API.GUI( - this.id, - this.name, - GameLib.Utils.IdOrNull(this.domElement), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - -}; - -/** - * Converts from an Object GUI to a GameLib.GUI - * @param guiRuntime GameLib.GUIRuntime - * @param objectGUI Object - * @returns {GameLib.GUI} - * @constructor - */ -GameLib.GUI.FromObject = function(guiRuntime, objectGUI) { - - var apiGUI = GameLib.API.GUI.FromObject(objectGUI); - - return new GameLib.GUI( - guiRuntime, - apiGUI - ); - -}; - -/** - * Removes empty folders from instance - */ -GameLib.GUI.prototype.removeEmtpyFolders = function() { - this.instance.removeEmptyFolders(); -}; - -/** - * Remove all folders from instance - */ -GameLib.GUI.prototype.removeAllFolders = function() { - this.instance.removeAllFolders(); -}; - -/** - * Adds a folder to instance - * @param folderName - * @returns {*} - */ -GameLib.GUI.prototype.addFolder = function(folderName) { - try { - return this.instance.addFolder(folderName); - } catch (e) { - try { - folderName += ' duplicate (' + GameLib.Utils.RandomId() + ')'; - return this.instance.addFolder(folderName); - } catch (e) { - console.log(e.message); - return null; - } - } -}; - -/** - * Image - * @constructor - * @param apiImage - */ -GameLib.Image = function( - apiImage -) { - - if (GameLib.Utils.UndefinedOrNull(apiImage)) { - apiImage = {}; - } - - if (apiImage instanceof GameLib.Image) { - return apiImage; - } - - GameLib.API.Image.call( - this, - apiImage.id, - apiImage.name, - apiImage.fileName, - apiImage.extension, - apiImage.path, - apiImage.contentType, - apiImage.size, - apiImage.parentEntity - ); - - GameLib.Component.call(this); -}; - -GameLib.Image.prototype = Object.create(GameLib.API.Image.prototype); -GameLib.Image.prototype.constructor = GameLib.Image; - -/** - * Creates an image instance - * @returns {*} - */ -GameLib.Image.prototype.createInstance = function() { - - GameLib.Event.Emit( - GameLib.Event.LOAD_IMAGE, - { - image : this - }, - function(imageInstance) { - this.instance = imageInstance; - GameLib.Component.prototype.createInstance.call(this); - }.bind(this), - function(error) { - console.error(error); - this.instance = null; - GameLib.Component.prototype.createInstance.call(this); - }.bind(this) - ); - -}; - -/** - * Updates the instance with the current state - */ -GameLib.Image.prototype.updateInstance = function(property) { - - if (GameLib.Utils.UndefinedOrNull(property)) { - console.warn('unknown property update for Image: ' + property); - } - - if ( - property === 'fileName' || - property === 'extension' || - property === 'path' - ) { - this.createInstance(); - } -}; - -GameLib.Image.prototype.updateFromRawObject = function(rawObject) { - this.id = rawObject.id; - this.name = rawObject.name; - this.fileName = rawObject.fileName; - this.extension = rawObject.extension; - this.path = rawObject.path; - this.contentType = rawObject.contentType; - this.size = rawObject.size; -}; - -/** - * - * @returns {GameLib.API.Image} - */ -GameLib.Image.prototype.toApiObject = function() { - - var apiImage = new GameLib.API.Image( - this.id, - this.name, - this.fileName, - this.extension, - this.path, - this.contentType, - this.size, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return apiImage; -}; - -/** - * @param objectImage - * @returns {GameLib.Image} - * @constructor - */ -GameLib.Image.FromObject = function(objectImage) { - return new GameLib.Image( - GameLib.API.Image.FromObject(objectImage) - ); -}; - -/** - * Runtime Matrix4 - * @param graphics - * @param parentObject - * @param apiMatrix4 - * @param grain - * @constructor - */ -GameLib.Matrix4 = function( - graphics, - apiMatrix4, - parentObject, - grain -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiMatrix4)) { - apiMatrix4 = {}; - } - - if (apiMatrix4 instanceof GameLib.Matrix4) { - return apiMatrix4; - } - - GameLib.API.Matrix4.call( - this, - apiMatrix4.rows[0], - apiMatrix4.rows[1], - apiMatrix4.rows[2], - apiMatrix4.rows[3] - ); - - if (GameLib.Utils.UndefinedOrNull(parentObject)) { - parentObject = null; - } - this.parentObject = parentObject; - - if (GameLib.Utils.UndefinedOrNull(grain)) { - grain = 0.001; - } - this.grain = grain; - - this.rows = this.rows.map( - function(row) { - if (row instanceof GameLib.API.Vector4) { - return new GameLib.Vector4( - this.graphics, - row, - this, - this.grain - ); - } else { - console.warn('Attempted conversion of wrong instance'); - throw new Error('Attempted conversion of wrong instance'); - } - }.bind(this) - ); - - this.forward = new GameLib.Vector4( - this.graphics, - this.forward, - this, - this.grain - ); - - this.left = new GameLib.Vector4( - this.graphics, - this.left, - this, - this.grain - ); - - this.up = new GameLib.Vector4( - this.graphics, - this.up, - this, - this.grain - ); - - this.createInstance(); -}; - -GameLib.Matrix4.prototype = Object.create(GameLib.API.Matrix4.prototype); -GameLib.Matrix4.prototype.constructor = GameLib.Matrix4; - -/** - * Creates a matrix 4 instance (currently from graphics lib) - * @param update - */ -GameLib.Matrix4.prototype.createInstance = function(update) { - - this.instance = new THREE.Matrix4(); - - /** - * We transpose our matrix when we send it to three since we use a different ordering system - * They say they use - */ - this.instance.set( - this.rows[0].x, - this.rows[1].x, - this.rows[2].x, - this.rows[3].x, - this.rows[0].y, - this.rows[1].y, - this.rows[2].y, - this.rows[3].y, - this.rows[0].z, - this.rows[1].z, - this.rows[2].z, - this.rows[3].z, - this.rows[0].w, - this.rows[1].w, - this.rows[2].w, - this.rows[3].w - ); -}; - -/** - * Updates this instance - */ -GameLib.Matrix4.prototype.updateInstance = function() { - - this.instance.set( - this.rows[0].x, - this.rows[1].x, - this.rows[2].x, - this.rows[3].x, - this.rows[0].y, - this.rows[1].y, - this.rows[2].y, - this.rows[3].y, - this.rows[0].z, - this.rows[1].z, - this.rows[2].z, - this.rows[3].z, - this.rows[0].w, - this.rows[1].w, - this.rows[2].w, - this.rows[3].w - ); - - if (this.parentObject && - this.parentObject.updateInstance) { - this.parentObject.updateInstance(); - } -}; - -/** - * GameLib.Matrix4 to GameLib.API.Matrix4 - * @returns {*} - */ -GameLib.Matrix4.prototype.toApiObject = function () { - - return new GameLib.API.Matrix4( - this.rows[0].toApiObject(), - this.rows[1].toApiObject(), - this.rows[2].toApiObject(), - this.rows[3].toApiObject() - ); - -}; - -/** - * Creates a GameLib.Matrix4 from an Object matrix - * @param graphics GameLib.GraphicsRuntime - * @param objectMatrix Object - * @param parentObject - * @returns {GameLib.Matrix4} - * @constructor - */ -GameLib.Matrix4.FromObject = function(graphics, objectMatrix, parentObject) { - - var apiMatrix = new GameLib.API.Matrix4.FromObject(objectMatrix); - - return new GameLib.Matrix4( - graphics, - parentObject, - apiMatrix - ) -}; - -/** - * Lookat - * @param position - * @param target - * @param up - * @returns {GameLib.Matrix4} - */ -GameLib.Matrix4.prototype.lookAt = function (position, target, up) { - - var pv = new GameLib.API.Vector3(position.x, position.y, position.z); - - var forward = pv.subtract(target).normalize(); - - if (forward.squared() === 0) { - forward.z = 1; - } - - var left = up.cross(forward).normalize(); - - if (left.squared() === 0) { - forward.x += 0.0001; - left = up.cross(forward).normalize(); - } - - var _up = forward.cross(left); - - this.rows[0].x = left.x; - this.rows[0].y = left.y; - this.rows[0].z = left.z; - - this.rows[1].x = _up.x; - this.rows[1].y = _up.y; - this.rows[1].z = _up.z; - - this.rows[2].x = forward.x; - this.rows[2].y = forward.y; - this.rows[2].z = forward.z; - - this.forward.x = forward.x; - this.forward.y = forward.y; - this.forward.z = forward.z; - - this.left.x = left.x; - this.left.y = left.y; - this.left.z = left.z; - - this.up.x = _up.x; - this.up.y = _up.y; - this.up.z = _up.z; - - this.updateInstance(); - - return this; -}; - -/** - * Identity - */ -GameLib.Matrix4.prototype.identity = function () { - this.rows = [ - new GameLib.Vector4( - this.graphics, - new GameLib.API.Vector4(1,0,0,0), - this, - this.grain - ), - new GameLib.Vector4( - this.graphics, - new GameLib.API.Vector4(0,1,0,0), - this, - this.grain - ), - new GameLib.Vector4( - this.graphics, - new GameLib.API.Vector4(0,0,1,0), - this, - this.grain - ), - new GameLib.Vector4( - this.graphics, - new GameLib.API.Vector4(0,0,0,1), - this, - this.grain - ) - ]; -}; - -/** - * Transpose - * @returns {GameLib.Matrix4} - */ -GameLib.Matrix4.prototype.transpose = function () { - - this.temp[0].x = this.rows[0].x; - this.temp[0].y = this.rows[1].x; - this.temp[0].z = this.rows[2].x; - this.temp[0].w = this.rows[3].x; - - this.temp[1].x = this.rows[0].y; - this.temp[1].y = this.rows[1].y; - this.temp[1].z = this.rows[2].y; - this.temp[1].w = this.rows[3].y; - - this.temp[2].x = this.rows[0].z; - this.temp[2].y = this.rows[1].z; - this.temp[2].z = this.rows[2].z; - this.temp[2].w = this.rows[3].z; - - this.temp[3].x = this.rows[0].w; - this.temp[3].y = this.rows[1].w; - this.temp[3].z = this.rows[2].w; - this.temp[3].w = this.rows[3].w; - - this.rows[0].x = this.temp[0].x; - this.rows[0].y = this.temp[0].y; - this.rows[0].z = this.temp[0].z; - this.rows[0].w = this.temp[0].w; - - this.rows[1].x = this.temp[1].x; - this.rows[1].y = this.temp[1].y; - this.rows[1].z = this.temp[1].z; - this.rows[1].w = this.temp[1].w; - - this.rows[2].x = this.temp[2].x; - this.rows[2].y = this.temp[2].y; - this.rows[2].z = this.temp[2].z; - this.rows[2].w = this.temp[2].w; - - this.rows[3].x = this.temp[3].x; - this.rows[3].y = this.temp[3].y; - this.rows[3].z = this.temp[3].z; - this.rows[3].w = this.temp[3].w; - - return this; -}; - -/** - * Runtime Mouse - * @param apiMouse - * @returns {GameLib.Mouse} - * @constructor - */ -GameLib.Mouse = function (apiMouse) { - - if (GameLib.Utils.UndefinedOrNull(apiMouse)){ - apiMouse = {}; - } - - if (apiMouse instanceof GameLib.Mouse) { - return apiMouse; - } - - GameLib.API.Mouse.call( - this, - apiMouse.id, - apiMouse.name, - apiMouse.x, - apiMouse.y, - apiMouse.parentEntity - ); - - GameLib.Component.call(this); -}; - -GameLib.Mouse.prototype = Object.create(GameLib.API.Mouse.prototype); -GameLib.Mouse.prototype.constructor = GameLib.Mouse; - -/** - * createInstance - */ -GameLib.Mouse.prototype.createInstance = function() { - this.instance = true; - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * updateInstance - * @param property - */ -GameLib.Mouse.prototype.updateInstance = function(property) { - if (GameLib.Utils.UndefinedOrNull(property)) { - console.warn('unknown property update for Mouse: ' + property); - } -}; - -/** - * Converts GameLib.Mouse vector to GameLib.API.Mouse - * @returns {GameLib.API.Mouse} - */ -GameLib.Mouse.prototype.toApiObject = function() { - return new GameLib.API.Mouse( - this.id, - this.name, - this.x, - this.y, - this.parentEntity - ); -}; - -/** - * GameLib.Mouse from Object - * @param objectMouse - * @returns {GameLib.Mouse} - * @constructor - */ -GameLib.Mouse.FromObject = function(objectMouse) { - return new GameLib.Mouse( - GameLib.API.Mouse.FromObject(objectMouse) - ); -}; -/** - * Physics - * @param id - * @param name - * @param physicsType - * @constructor - */ -GameLib.PhysicsRuntime = function( - id, - name, - physicsType -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Physics (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(physicsType)) { - physicsType = GameLib.PhysicsRuntime.TYPE_CANNON_JS; - } - this.physicsType = physicsType; - - this.createInstance(); -}; - -/** - * GameLib.PhysicsRuntime Types - * @type {number} - */ -GameLib.PhysicsRuntime.TYPE_CANNON_JS = 0x1; - -GameLib.PhysicsRuntime.prototype.createInstance = function() { - if (this.physicsType === GameLib.PhysicsRuntime.TYPE_CANNON_JS) { - this.instance = CANNON; - } else { - this.instance = null; - } -}; - -GameLib.PhysicsRuntime.prototype.updateInstance = function(property) { - if (property === 'physicsType') { - this.createInstance(); - } -}; - -/** - * Logs a warning and throws an error if not cannon - */ -GameLib.PhysicsRuntime.prototype.isNotCannonThrow = function() { - if (this.instance !== CANNON) { - console.error('Only CANNON supported'); - throw new Error('Only CANNON supported'); - } -}; - -/** - * Runtime quaternion for updating instance objects - * @param implementation - * @param parentObject GameLib.D3.* - * @param apiQuaternion GameLib.API.Quaternion - * @param grain Number - * @constructor - */ -GameLib.Quaternion = function ( - implementation, - apiQuaternion, - parentObject, - grain -) { - this.implementation = implementation; - - if (implementation instanceof GameLib.GraphicsRuntime) { - this.physics = null; - this.graphics = implementation; - this.graphics.isNotThreeThrow(); - } else if (implementation instanceof GameLib.PhysicsRuntime) { - this.graphics = null; - this.physics = implementation; - this.physics.isNotCannonThrow(); - } else { - throw new Error('Unhandled implementation : ' + implementation); - } - - if (GameLib.Utils.UndefinedOrNull(apiQuaternion)) { - apiQuaternion = {}; - } - - if (apiQuaternion instanceof GameLib.Quaternion) { - return apiQuaternion; - } - - GameLib.API.Quaternion.call( - this, - apiQuaternion.x, - apiQuaternion.y, - apiQuaternion.z, - apiQuaternion.w, - apiQuaternion.axis, - apiQuaternion.angle - ); - - if (GameLib.Utils.UndefinedOrNull(parentObject)) { - parentObject = null; - } - this.parentObject = parentObject; - - this.axis = new GameLib.Vector3( - this.implementation, - this.axis, - this, - this.grain - ); - - Object.defineProperty( - this, - 'angle', - GameLib.Utils.LimitToPI('angle', this.angle) - ); - - if (GameLib.Utils.UndefinedOrNull(grain)) { - grain = 0.001; - } - this.grain = grain; - - this.createInstance(); -}; - -GameLib.Quaternion.prototype = Object.create(GameLib.API.Quaternion.prototype); -GameLib.Quaternion.prototype.constructor = GameLib.Quaternion; - -/** - * Creates an instance quaternion - * @returns {*} - */ -GameLib.Quaternion.prototype.createInstance = function() { - - if (this.graphics) { - this.instance = new THREE.Quaternion( - this.x, - this.y, - this.z, - this.w - ); - } - - if (this.physics) { - this.instance = new CANNON.Quaternion( - this.x, - this.y, - this.z, - this.w - ); - } -}; - -/** - * Updates the instance vector, calls updateInstance on the parent object - */ -GameLib.Quaternion.prototype.updateInstance = function(property) { - - this.instance.x = this.x; - this.instance.y = this.y; - this.instance.z = this.z; - this.instance.w = this.w; - - if (this.parentObject && - this.parentObject.updateInstance) { - this.parentObject.updateInstance(property); - } -}; - -/** - * Converts runtime quaternion to API quaternion - * @returns {*} - */ -GameLib.Quaternion.prototype.toApiObject = function() { - return new GameLib.API.Quaternion( - this.x, - this.y, - this.z, - this.w, - this.axis.toApiObject(), - this.angle - ); -}; - -/** - * Checks if quaternion is equal to another quaternion - * @param quaternion - * @returns {boolean} - */ -GameLib.Quaternion.prototype.equals = function(quaternion) { - - return ( - this.x === quaternion.x && - this.y === quaternion.y && - this.z === quaternion.z && - this.w === quaternion.w && - this.axis.equals(quaternion.axis) && - this.angle === quaternion.angle - ); - -}; - -GameLib.Quaternion.prototype.setFrom = function(quaternion) { - this.x = quaternion.x; - this.y = quaternion.y; - this.z = quaternion.z; - this.w = quaternion.w; - this.axis.setFrom(quaternion.axis); - this.angle = quaternion.angle; -}; - -GameLib.Quaternion.prototype.copy = function(quaternion) { -console.log('todo'); -}; -/** - * Creates a Server object - * @param apiServer GameLib.API.Server - * @constructor - */ -GameLib.Server = function( - apiServer -) { - - if (GameLib.Utils.UndefinedOrNull(apiServer)) { - apiServer = {}; - } - - if (apiServer instanceof GameLib.Server) { - return apiServer; - } - - GameLib.API.Server.call( - this, - apiServer.id, - apiServer.name, - apiServer.protocol, - apiServer.ip, - apiServer.port, - apiServer.protocols, - apiServer.parentEntity - ); - - this.connected = false; - - GameLib.Component.call(this); -}; - -GameLib.Server.prototype = Object.create(GameLib.API.Server.prototype); -GameLib.Server.prototype.constructor = GameLib.Server; - -GameLib.Server.prototype.createInstance = function() { - - this.instance = true; - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.Server.prototype.updateInstance = function(property) { - if (property === 'protocol') { - console.log('todo: server protocol update'); - } - if (property === 'ip') { - console.log('todo: server ip update'); - } - if (property === 'port') { - console.log('todo: server port update'); - } - if (property === 'protocols') { - console.log('todo: server protocols update'); - } -}; - -/** - * Converts a GameLib.Server to a new GameLib.API.Server - * @returns {GameLib.API.Server} - */ -GameLib.Server.prototype.toApiObject = function() { - - return new GameLib.API.Server( - this.id, - this.name, - this.protocol, - this.ip, - this.port, - this.protocols, - GameLib.Utils.IdOrNull(this.parentEntity) - ); - -}; - -/** - * Converts from an Object Server to a GameLib.Server - * @param objectServer Object - * @returns {GameLib.Server} - * @constructor - */ -GameLib.Server.FromObject = function(objectServer) { - var apiServer = GameLib.API.Server.FromObject(objectServer); - return new GameLib.Server(apiServer); -}; - -/** - * Creates a Socket object - * @param socket GameLib.Socket - * @param apiSocket GameLib.API.Socket - * @constructor - */ -GameLib.Socket = function( - socket, - apiSocket -) { - - this.socket = socket; - this.socket.isNotWebSocketThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiSocket)) { - apiSocket = {}; - } - - if (apiSocket instanceof GameLib.Socket) { - return apiSocket; - } - - GameLib.API.Socket.call( - this, - apiSocket.id, - apiSocket.name, - apiSocket.socketType, - apiSocket.roomId, - apiSocket.peerId, - apiSocket.server, - apiSocket.parentEntity - ); - - if (this.server instanceof GameLib.API.Server) { - this.server = new GameLib.Server(this.server); - } - - this.connected = false; - - GameLib.Component.call( - this, - { - server : GameLib.Server - } - ); - -}; - -GameLib.Socket.prototype = Object.create(GameLib.API.Socket.prototype); -GameLib.Socket.prototype.constructor = GameLib.Socket; - -GameLib.Socket.prototype.createInstance = function() { - - this.instance = true; - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.Socket.prototype.updateInstance = function(property) { - if (property === 'socketType') { - console.log('todo: implement socket socketType update'); - } - if (property === 'roomId') { - console.log('todo: implement socket roomId update'); - } - if (property === 'peerId') { - console.log('todo: implement socket peerId update'); - } - if (property === 'server') { - console.log('todo: implement socket server update'); - } -}; - -/** - * Converts a GameLib.Socket to a new GameLib.API.Socket - * @returns {GameLib.API.Socket} - */ -GameLib.Socket.prototype.toApiObject = function() { - - return new GameLib.API.Socket( - this.id, - this.name, - this.socketType, - this.roomId, - this.peerId, - GameLib.Utils.IdOrNull(this.server), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - -}; - -/** - * Converts from an Object Socket to a GameLib.Socket - * @param sockets GameLib.SocketsRuntime - * @param objectSocket Object - * @returns {GameLib.Socket} - * @constructor - */ -GameLib.Socket.FromObject = function(sockets, objectSocket) { - var apiSocket = GameLib.API.Socket.FromObject(objectSocket); - return new GameLib.Socket( - sockets, - apiSocket - ); -}; - -/** - * Creates a Cast object - * @param socket GameLib.Socket - * @param apiSocketCast - * @constructor - */ -GameLib.Socket.Cast = function( - socket, - apiSocketCast -) { - - this.socket = socket; - this.socket.isNotWebSocketThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiSocketCast)) { - apiSocketCast = { - socketType : GameLib.API.Socket.TYPE_CAST - }; - } - - if (apiSocketCast instanceof GameLib.Socket.Cast) { - return apiSocketCast; - } - - GameLib.API.Socket.Cast.call( - this, - apiSocketCast, - apiSocketCast.castType, - apiSocketCast.source, - apiSocketCast.sourceProperties - ); - - GameLib.Socket.call( - this, - socket, - apiSocketCast - ); - - GameLib.Component.call( - this, - { - source : GameLib.Component - } - ); -}; - -GameLib.Socket.Cast.prototype = Object.create(GameLib.API.Socket.Cast.prototype); -GameLib.Socket.Cast.prototype.constructor = GameLib.Socket.Cast; - -GameLib.Socket.Cast.prototype.createInstance = function() { - - this.instance = true; - - GameLib.Socket.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.Socket.Cast.prototype.updateInstance = function(property) { - - GameLib.Socket.prototype.updateInstance.call( - this, - property - ); - - if (property === 'castType') { - console.log('todo: implement socket.receive.castType update'); - } - - if (property === 'source') { - if (this.source !== null) { - this.sourceProperties = GameLib.Utils.ObjectPropertiesAsBoolean(this.source); - } else { - this.sourceProperties = {}; - } - - GameLib.Event.Emit( - GameLib.Event.CAST_SOURCE_CHANGED, - { - component:this - } - ) - } - - if (property === 'sourceProperties') { - console.log('todo: implement socket.receive.sourceProperties update'); - } - -}; - -/** - * Converts a GameLib.Socket.Cast to a new GameLib.API.Socket.Cast - * @returns {GameLib.API.Socket.Cast} - */ -GameLib.Socket.Cast.prototype.toApiObject = function() { - - var apiSocket = new GameLib.API.Socket( - this.id, - this.name, - this.socketType, - this.roomId, - this.peerId, - GameLib.Utils.IdOrNull(this.server), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return new GameLib.API.Socket.Cast( - apiSocket, - this.castType, - GameLib.Utils.IdOrNull(this.source), - this.sourceProperties - ); - -}; - -/** - * Converts from an Object Cast to a GameLib.Socket.Cast - * @param sockets GameLib.SocketsRuntime - * @param objectCast Object - * @returns {GameLib.Socket.Cast} - * @constructor - */ -GameLib.Socket.Cast.FromObject = function(sockets, objectCast) { - var apiCast = GameLib.API.Socket.Cast.FromObject(objectCast); - return new GameLib.Socket.Cast( - sockets, - apiCast - ); -}; - -/** - * Creates a Receive object - * @param socket GameLib.Socket - * @param apiSocketReceive GameLib.API.Socket.Receive - * @constructor - */ -GameLib.Socket.Receive = function( - socket, - apiSocketReceive -) { - - this.socket = socket; - this.socket.isNotWebSocketThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiSocketReceive)) { - apiSocketReceive = { - socketType : GameLib.API.Socket.TYPE_RECEIVE - }; - } - - if (apiSocketReceive instanceof GameLib.Socket.Receive) { - return apiSocketReceive; - } - - GameLib.API.Socket.Receive.call( - this, - apiSocketReceive, - apiSocketReceive.receiveType, - apiSocketReceive.destination, - apiSocketReceive.destinationProperties - ); - - GameLib.Socket.call( - this, - socket, - apiSocketReceive - ); - - GameLib.Component.call( - this, - { - destination : GameLib.Component - } - ); - -}; - -GameLib.Socket.Receive.prototype = Object.create(GameLib.API.Socket.Receive.prototype); -GameLib.Socket.Receive.prototype.constructor = GameLib.Socket.Receive; - -GameLib.Socket.Receive.prototype.createInstance = function() { - - this.instance = true; - - GameLib.Socket.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.Socket.Receive.prototype.updateInstance = function(property) { - - GameLib.Socket.prototype.updateInstance.call( - this, - property - ); - - if (property === 'receiveType') { - console.log('todo: implement socket.receive.receiveType update'); - } - - if (property === 'destination') { - - if (this.destination !== null) { - this.destinationProperties = GameLib.Utils.ObjectPropertiesAsBoolean(this.destination); - } else { - this.destinationProperties = {}; - } - - GameLib.Event.Emit( - GameLib.Event.RECEIVE_DESTINATION_CHANGED, - { - component:this - } - ) - } - - if (property === 'destinationProperties') { - console.log('todo: implement socket.receive.destinationProperties update'); - } -}; - -/** - * Converts a GameLib.Socket.Receive to a new GameLib.API.Socket.Receive - * @returns {GameLib.API.Socket.Receive} - */ -GameLib.Socket.Receive.prototype.toApiObject = function() { - - var apiSocket = new GameLib.API.Socket( - this.id, - this.name, - this.socketType, - this.roomId, - this.peerId, - GameLib.Utils.IdOrNull(this.server), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - - return new GameLib.API.Socket.Receive( - apiSocket, - this.receiveType, - this.destination, - this.destinationProperties - ); - -}; - -/** - * Converts from an Object Receive to a GameLib.Socket.Receive - * @param sockets GameLib.SocketsRuntime - * @param objectReceive Object - * @returns {GameLib.Socket.Receive} - * @constructor - */ -GameLib.Socket.Receive.FromObject = function(sockets, objectReceive) { - - var apiSocketReceive = GameLib.API.Socket.Receive.FromObject(objectReceive); - - return new GameLib.Socket.Receive( - sockets, - apiSocketReceive - ); - -}; - -/** - * Sockets - * @param id - * @param name - * @param socketsType - * @constructor - */ -GameLib.SocketsRuntime = function( - id, - name, - socketsType -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Sockets (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(socketsType)) { - socketsType = GameLib.SocketsRuntime.TYPE_WEB_SOCKET; - } - this.socketsType = socketsType; - - this.connections = []; - - this.createInstance(); -}; - -/** - * GameLib.SocketsRuntime Types - * @type {number} - */ -GameLib.SocketsRuntime.TYPE_WEB_SOCKET = 0x1; - -GameLib.SocketsRuntime.prototype.createInstance = function() { - if (this.socketsType === GameLib.SocketsRuntime.TYPE_WEB_SOCKET) { - this.instance = WebSocket; - } else { - this.instance = null; - } -}; - -GameLib.SocketsRuntime.prototype.connect = function(server) { - var connection = new WebSocket(server.protocol + '://' + server.ip + ':' + server.port , server.protocols); - this.connections.push(connection); -}; - -GameLib.SocketsRuntime.prototype.updateInstance = function(property) { - if (property === 'socketsType') { - this.createInstance(); - } -}; - -/** - * Logs a warning and throws an error if not cannon - */ -GameLib.SocketsRuntime.prototype.isNotWebSocketThrow = function() { - if (this.instance !== WebSocket) { - console.error('Only WebSocket supported'); - throw new Error('Only WebSocket supported'); - } -}; - -/** - * Statistics - * @param id - * @param name - * @param statisticsType - * @constructor - */ -GameLib.StatisticsRuntime = function( - id, - name, - statisticsType -) { - if (GameLib.Utils.UndefinedOrNull(id)) { - id = GameLib.Utils.RandomId(); - } - this.id = id; - - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Statistics (' + id + ')'; - } - this.name = name; - - if (GameLib.Utils.UndefinedOrNull(statisticsType)) { - statisticsType = GameLib.StatisticsRuntime.TYPE_STATS; - } - this.statisticsType = statisticsType; - - this.createInstance(); -}; - -/** - * GameLib.StatisticsRuntime Types - * @type {number} - */ -GameLib.StatisticsRuntime.TYPE_STATS = 0x1; - -GameLib.StatisticsRuntime.prototype.createInstance = function() { - if (this.statisticsType === GameLib.StatisticsRuntime.TYPE_STATS) { - this.instance = Stats; - } else { - this.instance = null; - } -}; - -GameLib.StatisticsRuntime.prototype.updateInstance = function(property) { - if (property === 'statisticsType') { - this.createInstance(); - } -}; - -/** - * Logs a warning and throws an error if not cannon - */ -GameLib.StatisticsRuntime.prototype.isNotStatsThrow = function() { - if (this.instance !== Stats) { - console.error('Only stats supported'); - throw new Error('Only stats supported'); - } -}; - -/** - * Stats component for displaying some render statistics (framerate, memory consumption, etc) - * @param statisticsRuntime - * @param apiStats - * @constructor - */ -GameLib.Stats = function( - statisticsRuntime, - apiStats -) { - this.stats = statisticsRuntime; - this.stats.isNotStatsThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiStats)) { - apiStats = {}; - } - - if (apiStats instanceof GameLib.Stats) { - return apiStats; - } - - GameLib.API.Stats.call( - this, - apiStats.id, - apiStats.name, - apiStats.domElement, - apiStats.parentEntity - ); - - GameLib.Component.call( - this, - { - 'domElement': GameLib.DomElement - } - ); -}; - -GameLib.Stats.prototype = Object.create(GameLib.Component.prototype); -GameLib.Stats.prototype.constructor = GameLib.Stats; - -/** - * Creates a helper instance - */ -GameLib.Stats.prototype.createInstance = function() { - - this.instance = this.stats.instance(); - - this.resize(); - - this.domElement.instance.parentElement.appendChild(this.instance.dom); - - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * Updates the instance with the current state - */ -GameLib.Stats.prototype.updateInstance = function() { - this.instance = new this.stats(); -}; - - -/** - * Converts a GameLib.Stats to a new GameLib.API.Stats - * @returns {GameLib.API.Stats} - */ -GameLib.Stats.prototype.toApiObject = function() { - - return new GameLib.API.Stats( - this.id, - this.name, - GameLib.Utils.IdOrNull(this.domElement), - GameLib.Utils.IdOrNull(this.parentEntity) - ); - -}; - -/** - * Converts from an Object Stats to a GameLib.Stats - * @param statisticsRuntime GameLib.StatisticsRuntime - * @param objectStats Object - * @returns {GameLib.Stats} - * @constructor - */ -GameLib.Stats.FromObject = function(statisticsRuntime, objectStats) { - - var apiStats = GameLib.API.Stats.FromObject(objectStats); - - return new GameLib.Stats( - statisticsRuntime, - apiStats - ); - -}; - -GameLib.Stats.prototype.resize = function() { - console.log('override stats resize per implementation'); -}; - - -GameLib.Stats.prototype.start = function() { - this.instance.begin(); -}; - -GameLib.Stats.prototype.end = function() { - this.instance.end(); -}; - -/** - * System takes care of updating all the entities (based on their component data) - * @param apiSystem GameLib.API.System - * @constructor - */ -GameLib.System = function( - apiSystem -) { - - if (GameLib.Utils.UndefinedOrNull(apiSystem)) { - apiSystem = {}; - } - - if (apiSystem instanceof GameLib.System) { - return apiSystem; - } - - GameLib.API.System.call( - this, - apiSystem.id, - apiSystem.name, - apiSystem.systemType, - apiSystem.parentEntity - ); - - this.started = false; - - this.paused = false; - - var linkedObjects = {}; - - if (apiSystem.systemType === GameLib.System.SYSTEM_TYPE_INPUT) { - linkedObjects.mouseControls = [GameLib.Controls.Mouse]; - linkedObjects.keyboardControls = [GameLib.Controls.Keyboard]; - linkedObjects.touchControls = [GameLib.Controls.Touch]; - linkedObjects.editorControls = [GameLib.Controls.D3.Editor]; - } - - if (apiSystem.systemType === GameLib.System.SYSTEM_TYPE_AUDIO) { - linkedObjects.audioComponents = [GameLib.D3.Audio]; - } - - GameLib.Component.call( - this, - linkedObjects - ); - -}; - -GameLib.System.prototype = Object.create(GameLib.API.System.prototype); -GameLib.System.prototype.constructor = GameLib.System; - -GameLib.System.SYSTEM_TYPE_NONE = 0x0; -GameLib.System.SYSTEM_TYPE_RENDER = 0x1; -GameLib.System.SYSTEM_TYPE_ANIMATION = 0x2; -GameLib.System.SYSTEM_TYPE_INPUT = 0x4; -GameLib.System.SYSTEM_TYPE_STORAGE = 0x8; -GameLib.System.SYSTEM_TYPE_GUI = 0x10; -GameLib.System.SYSTEM_TYPE_PHYSICS = 0x20; -GameLib.System.SYSTEM_TYPE_LINKING = 0x40; -GameLib.System.SYSTEM_TYPE_CUSTOM = 0x80; -GameLib.System.SYSTEM_TYPE_VISUALIZATION = 0x100; -GameLib.System.SYSTEM_TYPE_PARTICLE = 0x200; -GameLib.System.SYSTEM_TYPE_AUDIO = 0x400; -GameLib.System.SYSTEM_TYPE_SOCKET = 0x800; -GameLib.System.SYSTEM_TYPE_ALL = 0xFFFF; - -GameLib.System.prototype.createInstance = function() { - this.instance = true; - GameLib.Component.prototype.createInstance.call(this); -}; - -/** - * @callback - * @override - */ -GameLib.System.prototype.start = function() { - this.started = true; - console.log('starting ' + this.name); -}; - -/** - * @callback - * @override - */ -GameLib.System.prototype.stop = function() { - this.started = false; - console.log('stopping ' + this.name); -}; - -/** - * Converts runtime vector to API Vector - * @returns {GameLib.API.System} - */ -GameLib.System.prototype.toApiObject = function() { - return new GameLib.API.System( - this.id, - this.name, - this.systemType, - GameLib.Utils.IdOrNull(this.parentEntity) - ); -}; - -GameLib.System.prototype.restart = function() { - console.log('restarting system : ' + this.name); - this.stop(); - this.start(); -}; -/** - * System takes care of updating all the entities (based on their component data) - * @param apiSystem GameLib.API.System - * @constructor - */ -GameLib.System.Animation = function( - apiSystem -) { - GameLib.System.call( - this, - apiSystem - ); - - this.animations = {}; - this.latest = {}; - this.textures = {}; - this.textureIds = []; - - this.animationMeshAddedSubscription = null; - this.animationMeshRemovedSubscription = null; - this.instanceCreatedSubscription = null; - this.removeComponentSubscription = null; - this.textureAnimatedSubscription = null; - - /** - * Sometimes we want to animate texture instances directly, without the overhead of a GameLib.Texture - */ - this.animateTextureInstanceSubscription = null; -}; - -GameLib.System.Animation.prototype = Object.create(GameLib.System.prototype); -GameLib.System.Animation.prototype.constructor = GameLib.System.Animation; - -GameLib.System.Animation.prototype.start = function() { - - GameLib.System.prototype.start.call(this); - - this.beforeRenderSubscription = GameLib.Event.Subscribe( - GameLib.Event.BEFORE_RENDER, - this.beforeRender.bind(this) - ); - - var animations = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.ANIMATION); - - animations.map(function(animation){ - animation.meshes.map( - function(mesh) { - this.attachAnimation(animation, mesh); - }.bind(this) - ); - this.animations[animation.id] = animation; - }.bind(this)); - - this.animationMeshAddedSubscription = GameLib.Event.Subscribe( - GameLib.Event.ANIMATION_MESH_ADDED, - function(data) { - this.attachAnimation(data.animation, data.mesh); - }.bind(this) - ); - - this.animationMeshRemovedSubscription = GameLib.Event.Subscribe( - GameLib.Event.ANIMATION_MESH_REMOVED, - function(data) { - this.detachAnimation(data.mesh); - }.bind(this) - ); - - this.instanceCreatedSubscription = GameLib.Event.Subscribe( - GameLib.Event.INSTANCE_CREATED, - this.instanceCreated.bind(this) - ); - - this.removeComponentSubscription = GameLib.Event.Subscribe( - GameLib.Event.REMOVE_COMPONENT, - this.removeComponent.bind(this) - ); - - this.textureAnimatedSubscription = GameLib.Event.Subscribe( - GameLib.Event.TEXTURE_ANIMATED_CHANGE, - this.textureAnimatedChange.bind(this) - ); - - this.animateTextureInstanceSubscription = GameLib.Event.Subscribe( - GameLib.Event.ANIMATE_TEXTURE_INSTANCE, - this.animateTextureInstance.bind(this) - ) -}; - -GameLib.System.Animation.prototype.instanceCreated = function(data) { - if ( - data.component instanceof GameLib.D3.Texture && - data.component.animated - ) { - - if (data.component.repeat.x > 1 || data.component.repeat.x < 0) { - console.warn('cannot animate a texture with repeat.x greater than 1 or less than 0'); - data.component.animated = false; - return; - } - - if (data.component.repeat.y > 1 || data.component.repeat.y < 0) { - console.warn('cannot animate a texture with repeat.y greater than 1 or less than 0'); - data.component.animated = false; - return; - } - - this.textures[data.component.id] = data.component; - this.textureIds = Object.keys(this.textures); - } - - if (data.component instanceof GameLib.D3.Animation) { - this.animations[data.component.id] = data.component; - data.component.meshes.map( - function(mesh){ - this.attachAnimation(data.component, mesh) - }.bind(this) - ); - } -}; - -GameLib.System.Animation.prototype.removeComponent = function(data) { - if ( - data.component instanceof GameLib.D3.Texture && - data.component.animated - ) { - if (GameLib.Utils.UndefinedOrNull(this.textures[data.component.id])) { - console.warn('tried to remove an animated texture, which should have been in the list but isnt: ' + data.component.name); - } else { - delete this.textures[data.component.id]; - this.textureIds = Object.keys(this.textures); - } - } - - if (data.component instanceof GameLib.D3.Animation) { - - data.component.meshes.map( - function(mesh){ - this.detachAnimation(mesh) - }.bind(this) - ); - - delete this.animations[data.component.id]; - } -}; - -GameLib.System.Animation.prototype.textureAnimatedChange = function(data) { - - if (data.texture.animated) { - - if (data.texture.repeat.x > 1 || data.texture.repeat.x < 0) { - console.warn('cannot animate a texture with repeat.x greater than 1 or less than 0'); - data.texture.animated = false; - return; - } - - if (data.texture.repeat.y > 1 || data.texture.repeat.y < 0) { - console.warn('cannot animate a texture with repeat.y greater than 1 or less than 0'); - data.texture.animated = false; - return; - } - - this.textures[data.texture.id] = data.texture; - this.textureIds = Object.keys(this.textures); - - } else { - - if (GameLib.Utils.UndefinedOrNull(this.textures[data.texture.id])) { - console.warn('tried to remove an animated texture, which should have been in the list but isnt: ' + data.texture.name); - } else { - delete this.textures[data.texture.id]; - this.textureIds = Object.keys(this.textures); - } - } - -}; - -/** - * This adds a texture instance directly on our textures to be animated - to bypass our GameLib component and linking - * system, which adds too much overhead for managing textures - * @param data - */ -GameLib.System.Animation.prototype.animateTextureInstance = function(data) { - - if (data.texture.repeat.x > 1 || data.texture.repeat.x < 0) { - console.warn('cannot animate a texture with repeat.x greater than 1 or less than 0'); - data.texture.userData.animated = false; - return; - } - - if (data.texture.repeat.y > 1 || data.texture.repeat.y < 0) { - console.warn('cannot animate a texture with repeat.y greater than 1 or less than 0'); - data.texture.userData.animated = false; - return; - } - - data.texture.userData.animated = true; - - this.textures[data.texture.id] = data.texture; - this.textureIds = Object.keys(this.textures); -}; - - -GameLib.System.Animation.prototype.beforeRender = function(data) { - - if (this.paused) { - return; - } - - var delta = data.delta; - - for (var property in this.animations) { - if (this.animations.hasOwnProperty(property)) { - - var processing = []; - - if (this.animations[property].length > 0) { - - var rotationDone = false; - var positionDone = false; - var scaleDone = false; - - for (var i = 0; i < this.animations[property].length; i++) { - if (this.animations[property][i].type === 'rotation' && !rotationDone) { - rotationDone = true; - processing.push(this.animations[property][i]); - } - - if (this.animations[property][i].type === 'position' && !positionDone) { - -// if (this.animations[property][i].animation.blocking.position) { - // positionDone = true; - // } - - processing.push(this.animations[property][i]); - } - - if (this.animations[property][i].type === 'scale' && !scaleDone) { - //scaleDone = true; - processing.push(this.animations[property][i]); - } - - if (scaleDone && positionDone && rotationDone) { - break; - } - } - } - - processing.map( - function(__property) { - return function(animationObject) { - - var done = false; - - var increment = 0; - - if (animationObject.type === 'rotation') { - increment = animationObject.animation.rotationSpeed * delta; - } - - if (animationObject.type === 'position') { - increment = animationObject.animation.translationSpeed * delta; - } - - if (animationObject.type === 'scale') { - increment = animationObject.animation.scaleSpeed * delta; - } - - if (animationObject.from < animationObject.to) { - animationObject.from += increment; - } else { - animationObject.from -= increment; - } - - if (Math.abs(animationObject.from - animationObject.to) < increment) { - animationObject.mesh.instance[animationObject.type][animationObject.axis] = animationObject.to; - done = true; - } else { - animationObject.mesh.instance[animationObject.type][animationObject.axis] = animationObject.from; - } - - if (done) { - var index = this.animations[__property].indexOf(animationObject); - this.animations[__property].splice(index, 1); - } - - }.bind(this); - }.bind(this)(property) - ); - } - } - - this.textureIds.map( - function(textureId) { - - var texture = this.textures[textureId]; - - if (texture.reverseAnimation || (texture.userData && texture.userData.reverseAnimation)) { - - if (texture.forward === true || (texture.userData && texture.userData.forward === true)) { - texture.offset.x += texture.repeat.x; - if (texture.offset.x >= (1 - texture.repeat.x)) { - if (texture.offset.y >= (1 - texture.repeat.y)) { - texture.offset.x = (1 - texture.repeat.x); - texture.offset.y = (1 - texture.repeat.y); - - if (texture.userData) { - texture.userData.forward = false; - } else { - texture.forward = false; - } - - } else { - texture.offset.x = 0; - texture.offset.y += texture.repeat.y; - } - } - } - - if (texture.forward === false || (texture.userData && texture.userData.forward === false)) { - texture.offset.x -= texture.repeat.x; - if (texture.offset.x <= 0) { - texture.offset.x = 0; - if (texture.offset.y < texture.repeat.y) { - texture.offset.x = texture.repeat.x; - texture.offset.y = 0; - if (texture.userData) { - texture.userData.forward = true; - } else { - texture.forward = true; - } - } else { - texture.offset.x = (1 - texture.repeat.x); - texture.offset.y -= texture.repeat.y; - } - } - } - - } else { - - texture.offset.x += texture.repeat.x; - - if (texture.offset.x >= (1 - texture.repeat.x)) { - if (texture.offset.y >= (1 - texture.repeat.y)) { - texture.offset.x = 0; - texture.offset.y = 0; - } else { - texture.offset.x = 0; - texture.offset.y += texture.repeat.y; - } - } - - } - - if (!texture.userData) { - texture.updateInstance('offset'); - } - - }.bind(this) - ) -}; - -GameLib.System.Animation.prototype.detachAnimation = function(mesh) { - - var detached = false; - - if (mesh.backupQuaternionAngleDescriptor) { - Object.defineProperty( - mesh.quaternion, - 'angle', - mesh.backupQuaternionAngleDescriptor - ); - - delete mesh.backupQuaternionAngleDescriptor; - - detached = true; - } - - if (mesh.backupQuaternionAxisXDescriptor) { - Object.defineProperty( - mesh.quaternion.axis, - 'x', - mesh.backupQuaternionAxisXDescriptor - ); - - delete mesh.backupQuaternionAxisXDescriptor; - - detached = true; - } - - if (mesh.backupQuaternionAxisYDescriptor) { - Object.defineProperty( - mesh.quaternion.axis, - 'y', - mesh.backupQuaternionAxisYDescriptor - ); - - delete mesh.backupQuaternionAxisYDescriptor; - - detached = true; - } - - if (mesh.backupQuaternionAxisZDescriptor) { - Object.defineProperty( - mesh.quaternion.axis, - 'z', - mesh.backupQuaternionAxisZDescriptor - ); - - delete mesh.backupQuaternionAxisXDescriptor; - - detached = true; - } - - if (mesh.backupRotationXDescriptor) { - Object.defineProperty( - mesh.rotation, - 'x', - mesh.backupRotationXDescriptor - ); - - delete mesh.backupRotationXDescriptor; - - detached = true; - } - - if (mesh.backupRotationYDescriptor) { - Object.defineProperty( - mesh.rotation, - 'y', - mesh.backupRotationYDescriptor - ); - - delete mesh.backupRotationYDescriptor; - - detached = true; - } - - if (mesh.backupRotationZDescriptor) { - Object.defineProperty( - mesh.rotation, - 'z', - mesh.backupRotationZDescriptor - ); - - delete mesh.backupRotationZDescriptor; - - detached = true; - } - - if (mesh.backupPositionXDescriptor) { - Object.defineProperty( - mesh.position, - 'x', - mesh.backupPositionXDescriptor - ); - - delete mesh.backupPositionXDescriptor; - - detached = true; - } - - if (mesh.backupPositionYDescriptor) { - Object.defineProperty( - mesh.position, - 'y', - mesh.backupPositionYDescriptor - ); - - delete mesh.backupPositionYDescriptor; - - detached = true; - } - - if (mesh.backupPositionZDescriptor) { - Object.defineProperty( - mesh.position, - 'z', - mesh.backupPositionZDescriptor - ); - - delete mesh.backupPositionZDescriptor; - - detached = true; - } - - if (mesh.backupScaleXDescriptor) { - Object.defineProperty( - mesh.scale, - 'x', - mesh.backupScaleXDescriptor - ); - - delete mesh.backupScaleXDescriptor; - - detached = true; - } - - if (mesh.backupScaleYDescriptor) { - Object.defineProperty( - mesh.scale, - 'y', - mesh.backupScaleYDescriptor - ); - - delete mesh.backupScaleYDescriptor; - - detached = true; - } - - if (mesh.backupScaleZDescriptor) { - Object.defineProperty( - mesh.scale, - 'z', - mesh.backupScaleZDescriptor - ); - - delete mesh.backupScaleZDescriptor; - - detached = true; - } - - if (this.latest[mesh.id]) { - - mesh.rotation.x = this.latest[mesh.id].rotation.x; - mesh.rotation.y = this.latest[mesh.id].rotation.y; - mesh.rotation.z = this.latest[mesh.id].rotation.z; - - mesh.position.x = this.latest[mesh.id].position.x; - mesh.position.y = this.latest[mesh.id].position.y; - mesh.position.z = this.latest[mesh.id].position.z; - - mesh.scale.x = this.latest[mesh.id].scale.x; - mesh.scale.y = this.latest[mesh.id].scale.y; - mesh.scale.z = this.latest[mesh.id].scale.z; - - mesh.quaternion.axis.x = this.latest[mesh.id].quaternion.axis.x; - mesh.quaternion.axis.y = this.latest[mesh.id].quaternion.axis.y; - mesh.quaternion.axis.z = this.latest[mesh.id].quaternion.axis.z; - - mesh.quaternion.angle = this.latest[mesh.id].quaternion.angle; - - delete this.latest[mesh.id]; - - detached = true; - } - - if (this.animations[mesh.id]) { - delete this.animations[mesh.id]; - - detached = true; - } - - if (detached) { - mesh.updateInstance('position'); - mesh.updateInstance('rotation'); - mesh.updateInstance('scale'); - } - -}; - -GameLib.System.Animation.prototype.attachAnimation = function(animation, mesh) { - - /** - * Initialize the property with the original mesh z value - */ - this.latest[mesh.id] = { - rotation : { - x : mesh.rotation.x, - y : mesh.rotation.y, - z : mesh.rotation.z - }, - position : { - x : mesh.position.x, - y : mesh.position.y, - z : mesh.position.z - }, - scale : { - x : mesh.scale.x, - y : mesh.scale.y, - z : mesh.scale.z - }, - quaternion : { - axis : { - x : mesh.quaternion.axis.x, - y : mesh.quaternion.axis.y, - z : mesh.quaternion.axis.z - }, - angle : mesh.quaternion.angle - } - }; - - this.animations[mesh.id] = []; - - if (mesh.backupRotationXDescriptor) { - throw new Error('already a backed up x descriptor'); - } - - mesh.backupQuaternionAngleDescriptor = Object.getOwnPropertyDescriptor(mesh.quaternion, 'angle'); - mesh.backupQuaternionAxisXDescriptor = Object.getOwnPropertyDescriptor(mesh.quaternion.axis, 'x'); - mesh.backupQuaternionAxisYDescriptor = Object.getOwnPropertyDescriptor(mesh.quaternion.axis, 'y'); - mesh.backupQuaternionAxisZDescriptor = Object.getOwnPropertyDescriptor(mesh.quaternion.axis, 'z'); - mesh.backupRotationXDescriptor = Object.getOwnPropertyDescriptor(mesh.rotation, 'x'); - mesh.backupRotationYDescriptor = Object.getOwnPropertyDescriptor(mesh.rotation, 'y'); - mesh.backupRotationZDescriptor = Object.getOwnPropertyDescriptor(mesh.rotation, 'z'); - mesh.backupPositionXDescriptor = Object.getOwnPropertyDescriptor(mesh.position, 'x'); - mesh.backupPositionYDescriptor = Object.getOwnPropertyDescriptor(mesh.position, 'y'); - mesh.backupPositionZDescriptor = Object.getOwnPropertyDescriptor(mesh.position, 'z'); - mesh.backupScaleXDescriptor = Object.getOwnPropertyDescriptor(mesh.scale, 'x'); - mesh.backupScaleYDescriptor = Object.getOwnPropertyDescriptor(mesh.scale, 'y'); - mesh.backupScaleZDescriptor = Object.getOwnPropertyDescriptor(mesh.scale, 'z'); - - Object.defineProperty( - mesh.quaternion, - 'angle', - { - 'get': this.getProperty(mesh, 'angle', 'quaternion'), - 'set': this.setProperty(mesh, animation, 'angle', 'quaternion'), - 'configurable': true - } - ); - - Object.defineProperty( - mesh.quaternion.axis, - 'x', - { - 'get': this.getSubProperty(mesh, 'x', 'quaternion', 'axis'), - 'set': this.setSubProperty(mesh, animation, 'x', 'quaternion', 'axis'), - 'configurable': true - } - ); - - Object.defineProperty( - mesh.quaternion.axis, - 'y', - { - 'get': this.getSubProperty(mesh, 'y', 'quaternion', 'axis'), - 'set': this.setSubProperty(mesh, animation, 'y', 'quaternion', 'axis'), - 'configurable': true - } - ); - - Object.defineProperty( - mesh.quaternion.axis, - 'z', - { - 'get': this.getSubProperty(mesh, 'z', 'quaternion', 'axis'), - 'set': this.setSubProperty(mesh, animation, 'z', 'quaternion', 'axis'), - 'configurable': true - } - ); - - Object.defineProperty( - mesh.rotation, - 'x', - { - 'get': this.getProperty(mesh, 'x', 'rotation'), - 'set': this.setProperty(mesh, animation, 'x', 'rotation'), - 'configurable': true - } - ); - - Object.defineProperty( - mesh.rotation, - 'y', - { - 'get': this.getProperty(mesh, 'y', 'rotation'), - 'set': this.setProperty(mesh, animation, 'y', 'rotation'), - 'configurable': true - } - ); - - Object.defineProperty( - mesh.rotation, - 'z', - { - 'get': this.getProperty(mesh, 'z', 'rotation'), - 'set': this.setProperty(mesh, animation, 'z', 'rotation'), - 'configurable': true - } - ); - - Object.defineProperty( - mesh.scale, - 'x', - { - 'get': this.getProperty(mesh, 'x', 'scale'), - 'set': this.setProperty(mesh, animation, 'x', 'scale'), - 'configurable': true - } - ); - - Object.defineProperty( - mesh.scale, - 'y', - { - 'get': this.getProperty(mesh, 'y', 'scale'), - 'set': this.setProperty(mesh, animation, 'y', 'scale'), - 'configurable': true - } - ); - - Object.defineProperty( - mesh.scale, - 'z', - { - 'get': this.getProperty(mesh, 'z', 'scale'), - 'set': this.setProperty(mesh, animation, 'z', 'scale'), - 'configurable': true - } - ); - - Object.defineProperty( - mesh.position, - 'x', - { - 'get': this.getProperty(mesh, 'x', 'position'), - 'set': this.setProperty(mesh, animation, 'x', 'position'), - 'configurable': true - } - ); - - Object.defineProperty( - mesh.position, - 'y', - { - 'get': this.getProperty(mesh, 'y', 'position'), - 'set': this.setProperty(mesh, animation, 'y', 'position'), - 'configurable': true - } - ); - - Object.defineProperty( - mesh.position, - 'z', - { - 'get': this.getProperty(mesh, 'z', 'position'), - 'set': this.setProperty(mesh, animation, 'z', 'position'), - 'configurable': true - } - ); -}; - -// GameLib.System.Animation.prototype.getQuaternionAngle = function(mesh, animation) { -// -// return function() { -// return; -// /** -// * TODO: fix this shit.. -// * Back up the current property descriptor -// */ -// mesh.animationObject = { -// backupAngleDescriptor: Object.getOwnPropertyDescriptor(mesh.quaternion, 'angle'), -// targetAngle: mesh.quaternion.angle, -// angleIncrement: true, -// intermediateAngle: mesh.quaternion.angle, -// subscription: null, -// inProcess: false, -// blocking: animation.blocking//, -// // callbacks : [], -// // storedValues : [] -// }; -// -// var getIntermediateAngle = function () { -// return mesh.animationObject.intermediateAngle; -// }; -// -// var getTargetAngle = function () { -// -// // if (mesh.animationObject.storedValues.length > 0) { -// // return mesh.animationObject.storedValues[mesh.animationObject.storedValues.length - 1]; -// // } -// -// return mesh.animationObject.targetAngle; -// }; -// -// var animateRotation = function (value) { -// -// mesh.animationObject.intermediateAngle += value; -// -// var done = false; -// -// if (mesh.animationObject.angleIncrement) { -// /** -// * We are rotating upwards -// */ -// if (mesh.animationObject.intermediateAngle >= mesh.animationObject.targetAngle) { -// /** -// * We need to stop -// */ -// done = true; -// } -// } else { -// /** -// * We are rotating downwards -// */ -// if (mesh.animationObject.intermediateAngle <= mesh.animationObject.targetAngle) { -// /** -// * We need to stop -// */ -// done = true; -// } -// } -// -// if (done) { -// -// /** -// * We clamp to our target angle -// */ -// mesh.animationObject.intermediateAngle = mesh.animationObject.targetAngle; -// -// /** -// * We limit our intermediate angle between values of -pi and pi -// */ -// while (mesh.animationObject.intermediateAngle > Math.PI) { -// mesh.animationObject.intermediateAngle -= (Math.PI * 2); -// } -// -// while (mesh.animationObject.intermediateAngle < -(Math.PI)) { -// mesh.animationObject.intermediateAngle += (Math.PI * 2); -// } -// -// /** -// * We apply our new intermediate angle to our target -// */ -// mesh.animationObject.targetAngle = mesh.animationObject.intermediateAngle; -// } -// -// /** -// * Apply the actual rotation to the mesh -// */ -// mesh.updateInstanceRotationFromAxisAngle(mesh.quaternion.axis, mesh.animationObject.intermediateAngle); -// -// /** -// * Check again if we are done, we need to do some additional work - -// */ -// if (done) { -// -// if (!mesh.animationObject.subscription) { -// var message = 'mesh animation object subscription went missing for '; -// message += mesh.name + ': '; -// message += animation.name; -// console.warn(message); -// throw new Error(message); -// } -// -// /** -// * Stop subscribing to before render events -// */ -// mesh.animationObject.subscription.remove(); -// -// /** -// * @type {null} -// */ -// mesh.animationObject.subscription = null; -// -// /** -// * For some meshes, when we are done with the animation, we want to apply -// * the current state of the mesh to the object data itself (i.e. update -// * its vertices etc) -// */ -// if (animation.applyToMeshWhenDone) { -// /** -// * Now we say that our intermediate angle is zero, because we will apply our rotation -// * and this will prevent us from re-registering a new 'animationRender' event -// */ -// mesh.animationObject.targetAngle = 0; -// mesh.animationObject.intermediateAngle = 0; -// -// /** -// * Apply our position, rotation and scale to the mesh -// */ -// mesh.applyPositionRotationScale(); -// } -// -// /** -// * Tell our animation component that it is no longer in process... -// * @type {boolean} -// */ -// mesh.animationObject.inProcess = false; -// -// // if (mesh.animationObject.callbacks.length > 0) { -// // var callback = mesh.animationObject.callbacks[0]; -// // mesh.animationObject.callbacks.splice(0,1); -// // callback(); -// // } -// -// // mesh.animationObject.storedValues = []; -// } -// }; -// } -// }; -// -// GameLib.System.Animation.prototype.setQuaternionAngle = function(mesh, animation) { -// -// return function(value) { -// return; -// /** -// * TODO: update this shit -// */ -// /** -// * Check if we have work to do -// */ -// if (mesh.animationObject.intermediateAngle === value) { -// -// mesh.animationObject.inProcess = false; -// -// /** -// * Nothing to do -// */ -// return; -// } -// -// /** -// * Check if we have another animation in process -// */ -// if (mesh.animationObject.inProcess && mesh.animationObject.blocking) { -// -// console.log('another animation is already in process'); -// -// // setTargetAngle(value); -// -// // GameLib.Utils.PushUnique(mesh.animationObject.storedValues, value); -// // -// // mesh.animationObject.callbacks.push( -// // function(__value) { -// // return function(){ -// // mesh.quaternion.angle = __value; -// // } -// // }(value) -// // ); -// -// /** -// * Respond that our angle is actually our target angle (it will be that soon) -// */ -// return; -// } -// -// /** -// * We indicate that we now have an animation in process -// * @type {boolean} -// */ -// mesh.animationObject.inProcess = true; -// -// /** -// * Ok - all good - lets start the animation -// */ -// if (mesh.animationObject.intermediateAngle > value) { -// /** -// * We will rotate towards by decrementing -// */ -// mesh.animationObject.angleIncrement = false; -// } else { -// /** -// * We will rotate towards by incrementing -// */ -// mesh.animationObject.angleIncrement = true; -// } -// -// /** -// * We say what our target angle is - when we reach our target angle, we want -// * to stop our animation -// */ -// mesh.animationObject.targetAngle = value; -// -// /** -// * Now we subscribe to 'before render' events, and slowly increment the value -// * @type {{fn, remove}} -// */ -// mesh.animationObject.subscription = GameLib.Event.Subscribe( -// GameLib.Event.BEFORE_RENDER, -// function(data) { -// -// var increment = Math.abs(animation.rotationSpeed); -// -// if (!mesh.animationObject.angleIncrement) { -// increment *= -1; -// } -// -// animateRotation(data.delta * increment); -// } -// ); -// } -// }; -// -// GameLib.System.Animation.prototype.getQuaternionAxisX = function(mesh, animation) { -// return function() { -// return this.latest[mesh.id].quaternion.axis.x; -// }.bind(this); -// }; -// -// GameLib.System.Animation.prototype.setQuaternionAxisX = function(mesh, animation) { -// return function(value) { -// this.latest[mesh.id].quaternion.axis.x = value; -// }.bind(this); -// }; -// -// GameLib.System.Animation.prototype.getQuaternionAxisY = function(mesh, animation) { -// return function() { -// return this.latest[mesh.id].quaternion.axis.y; -// }.bind(this); -// }; -// -// GameLib.System.Animation.prototype.setQuaternionAxisY = function(mesh, animation) { -// return function(value) { -// this.latest[mesh.id].quaternion.axis.y = value; -// }.bind(this); -// }; -// -// GameLib.System.Animation.prototype.getQuaternionAxisZ = function(mesh, animation) { -// return function() { -// return this.latest[mesh.id].quaternion.axis.z; -// }.bind(this); -// }; -// -// GameLib.System.Animation.prototype.setQuaternionAxisZ = function(mesh, animation) { -// return function(value) { -// this.latest[mesh.id].quaternion.axis.z = value; -// }.bind(this); -// }; - -GameLib.System.Animation.prototype.getSubProperty = function(mesh, axis, property, subProperty) { - return function() { - return this.latest[mesh.id][property][subProperty][axis]; - }.bind(this); -}; - -GameLib.System.Animation.prototype.setSubProperty = function(mesh, animation, axis, property, subProperty) { - return function(value) { - - var from = Number(this.latest[mesh.id][property][subProperty][axis]); - - this.latest[mesh.id][property][subProperty][axis] = value; - - if (property === 'position') { - /** - * Look for other position animations - * TODO:check when not super exausted - */ - // var positionAnimationObject = this.animations[mesh.id].reduce( - // function(result, animationObject) { - // - // if (animationObject.type === 'position') { - // result = animationObject; - // } - // - // return result; - // }, - // null - // ); - - /** - * We found another position animation - just update the 'to' property - */ - // if (positionAnimationObject) { - // positionAnimationObject.to = value; - // return; - // } - } - - this.animations[mesh.id].push( - { - type : property, - axis : axis, - from : from, - to : value, - animation : animation, - mesh : mesh - } - ); - - }.bind(this) -}; - -GameLib.System.Animation.prototype.getProperty = function(mesh, axis, property) { - return function() { - return this.latest[mesh.id][property][axis]; - }.bind(this); -}; - -GameLib.System.Animation.prototype.setProperty = function(mesh, animation, axis, property) { - return function(value) { - - var from = Number(this.latest[mesh.id][property][axis]); - - this.latest[mesh.id][property][axis] = value; - - if (property === 'position') { - /** - * Look for other position animations - * TODO:check when not super exausted - */ - // var positionAnimationObject = this.animations[mesh.id].reduce( - // function(result, animationObject) { - // - // if (animationObject.type === 'position') { - // result = animationObject; - // } - // - // return result; - // }, - // null - // ); - - /** - * We found another position animation - just update the 'to' property - */ - // if (positionAnimationObject) { - // positionAnimationObject.to = value; - // return; - // } - } - - this.animations[mesh.id].push( - { - type : property, - axis : axis, - from : from, - to : value, - animation : animation, - mesh : mesh - } - ); - - }.bind(this) -}; - -/** - * Stop Animation System - */ -GameLib.System.Animation.prototype.stop = function() { - - GameLib.System.prototype.stop.call(this); - - this.beforeRenderSubscription.remove(); - - this.animationMeshAddedSubscription.remove(); - - this.animationMeshRemovedSubscription.remove(); - - Object.keys(this.animations).map( - function(animationId) { - - if ( - this.animations[animationId] && - this.animations[animationId].meshes - ) { - this.animations[animationId].meshes.map( - function (mesh) { - this.detachAnimation(mesh); - }.bind(this) - ) - } - }.bind(this) - ); - - this.animations = {}; - - this.instanceCreatedSubscription.remove(); - - this.removeComponentSubscription.remove(); - - this.textureAnimatedSubscription.remove(); - - this.animateTextureInstanceSubscription.remove(); -}; - - -/** - * System takes care of updating all the entities (based on their component data) - * @param apiSystem GameLib.API.System - * @constructor - */ -GameLib.System.Audio = function( - apiSystem -) { - GameLib.System.call( - this, - apiSystem - ); - - this.instanceCreatedSubscription = null; - - this.removeComponentSubscription = null; - - this.playAudioSubscription = null; - - this.pauseAllAudioSubscription = null; - - this.muteAudioSubscription = null; - - this.continueAllAudioSubscription = null; - - this.stopAudioSubscription = null; - - this.stopAllAudioSubscription = null; - - this.mute = false; - - this.paused = []; - - this.audioComponents = []; - - this.toPlay = []; -}; - -GameLib.System.Audio.prototype = Object.create(GameLib.System.prototype); -GameLib.System.Audio.prototype.constructor = GameLib.System.Audio; - -/** - * Start this system (add all event listeners) - */ -GameLib.System.Audio.prototype.start = function() { - - GameLib.System.prototype.start.call(this); - - this.instanceCreatedSubscription = GameLib.Event.Subscribe( - GameLib.Event.INSTANCE_CREATED, - this.instanceCreated.bind(this) - ); - - this.removeComponentSubscription = GameLib.Event.Subscribe( - GameLib.Event.REMOVE_COMPONENT, - this.removeComponent.bind(this) - ); - - this.playAudioSubscription = GameLib.Event.Subscribe( - GameLib.Event.PLAY_AUDIO, - this.playAudio.bind(this) - ); - - this.pauseAllAudioSubscription = GameLib.Event.Subscribe( - GameLib.Event.PAUSE_ALL_AUDIO, - this.pauseAllAudio.bind(this) - ); - - this.muteAudioSubscription = GameLib.Event.Subscribe( - GameLib.Event.MUTE_AUDIO, - this.muteAudio.bind(this) - ); - - this.continueAllAudioSubscription = GameLib.Event.Subscribe( - GameLib.Event.CONTINUE_ALL_AUDIO, - this.continueAllAudio.bind(this) - ); - - this.stopAudioSubscription = GameLib.Event.Subscribe( - GameLib.Event.STOP_AUDIO, - this.stopAudio.bind(this) - ); - - this.stopAllAudioSubscription = GameLib.Event.Subscribe( - GameLib.Event.STOP_ALL_AUDIO, - this.stopAllAudio.bind(this) - ); - -}; - -/** - * From now on we want to track everything about a component, only from the systems that are active - * @param data - */ -GameLib.System.Audio.prototype.instanceCreated = function(data) { - - if (data.component instanceof GameLib.D3.Audio) { - - GameLib.Utils.PushUnique(this.audioComponents, data.component); - - data.component.instance.onEnded = function() { - this.isPlaying = false; - GameLib.Event.Emit( - GameLib.Event.AUDIO_ENDED, - { - audio : data.component - } - ); - }; - - var index = this.toPlay.indexOf(data.component.name); - - if (index !== -1) { - - GameLib.Event.Emit( - GameLib.Event.PLAY_AUDIO, - { - name : data.component.name - } - ); - - this.toPlay.splice(index, 1); - } - } -}; - -/** - * Removes a particle engine from this system - * @param data - */ -GameLib.System.Audio.prototype.playAudio = function(data) { - - var found = false; - - this.audioComponents.map( - function(audio) { - if (audio.name === data.name) { - - found = true; - - if (!audio.instance) { - console.log('audio not ready yet'); - } - - // if (this.mute && typeof audio.backupVolume === 'undefined') { - // audio.backupVolume = audio.volume; - // audio.volume = 0; - // audio.updateInstance('volume'); - // } - // - // if (!this.mute && typeof audio.backupVolume === 'number') { - // audio.volume = audio.backupVolume; - // delete audio.backupVolume; - // audio.updateInstance('volume'); - // } - - if (audio.overplay) { - if (audio.instance.isPlaying) { - audio.instance.stop(); - } - audio.instance.offset = 0; - audio.instance.play(); - } else if (!audio.instance.isPlaying) { - audio.instance.play(); - } - } - }.bind(this) - ); - - if (!found) { - /** - * This audio still has to load - */ - console.log('delaying audio play until loaded for: ' + data.name); - this.toPlay.push(data.name); - } -}; - -GameLib.System.Audio.prototype.pauseAllAudio = function(data) { - - this.paused = []; - - this.audioComponents.map( - function(audio) { - if (audio.instance.isPlaying) { - this.paused.push(audio); - // audio.currentTime = audio.instance.context.currentTime; - audio.paused = true; - audio.updateInstance('paused'); - - } - }.bind(this) - ) -}; - -GameLib.System.Audio.prototype.continueAllAudio = function(data) { - - this.paused.map( - function(audio) { - // audio.instance.context.currentTime = audio.currentTime; - audio.paused = false; - audio.updateInstance('paused'); - } - ); - - this.paused = []; - -}; - -GameLib.System.Audio.prototype.stopAllAudio = function(data) { - this.audioComponents.map( - function(audio) { - if (audio.instance.isPlaying) { - audio.instance.stop(); - } - } - ) -}; - - -GameLib.System.Audio.prototype.stopAudio = function(data) { - this.audioComponents.map( - function(audio) { - if (audio.name === data.name) { - if (audio.instance.isPlaying) { - audio.instance.stop(); - } - } - } - ) -}; - - -GameLib.System.Audio.prototype.removeComponent = function(data) { - -}; - -GameLib.System.Audio.prototype.muteAudio = function() { - - this.mute = !this.mute; - - if (this.mute) { - this.audioVolumes = this.audioComponents.reduce( - function(result, audio) { - result.push( - { - audio : audio, - volume : audio.volume - } - ); - - audio.volume = 0; - audio.updateInstance('volume'); - - return result; - }, - [] - ); - - GameLib.Event.Emit(GameLib.Event.AUDIO_MUTED, {audioSystem:this}); - - } else { - - this.audioVolumes.map( - function(audioVolume) { - audioVolume.audio.volume = audioVolume.volume; - audioVolume.audio.updateInstance('volume'); - } - ); - - GameLib.Event.Emit(GameLib.Event.AUDIO_UNMUTED, {audioSystem:this}); - } -}; - - -/** - * Stop this system (remove all event listeners) - */ -GameLib.System.Audio.prototype.stop = function() { - - GameLib.System.prototype.stop.call(this); - - this.instanceCreatedSubscription.remove(); - this.removeComponentSubscription.remove(); - this.playAudioSubscription.remove(); - this.pauseAllAudioSubscription.remove(); - this.muteAudioSubscription.remove(); - this.continueAllAudioSubscription.remove(); - this.stopAudioSubscription.remove(); - this.stopAllAudioSubscription.remove(); - -}; - -/** - * System takes care of updating all the entities (based on their component data) - * @param apiSystem GameLib.API.System - * @constructor - */ -GameLib.System.CustomCode = function( - apiSystem -) { - - GameLib.System.call( - this, - apiSystem - ); - - this.instanceCreatedSubscription = null; - this.removeComponentSubscription = null; - this.compileSuccessSubscription = null; - this.compileFailedSubscription = null; - - this.subscriptions = {}; - -}; - -GameLib.System.CustomCode.prototype = Object.create(GameLib.System.prototype); -GameLib.System.CustomCode.prototype.constructor = GameLib.System.CustomCode; - -/** - * Start the rendering system - */ -GameLib.System.CustomCode.prototype.start = function() { - - GameLib.System.prototype.start.call(this); - - GameLib.EntityManager.Instance.queryComponents(GameLib.Component.CUSTOM_CODE).map( - function(component) { - this.subscriptions[component.id] = GameLib.Event.Subscribe( - component.eventId, - component.instance - ); - }.bind(this) - ); - - this.instanceCreatedSubscription = GameLib.Event.Subscribe( - GameLib.Event.INSTANCE_CREATED, - this.instanceCreated.bind(this) - ); - - this.removeComponentSubscription = GameLib.Event.Subscribe( - GameLib.Event.REMOVE_COMPONENT, - this.removeComponent.bind(this) - ); - - this.compileSuccessSubscription = GameLib.Event.Subscribe( - GameLib.Event.COMPILE_SUCCESS, - this.compileSuccess.bind(this) - ); - - this.compileFailedSubscription = GameLib.Event.Subscribe( - GameLib.Event.COMPILE_FAILED, - this.compileFailed.bind(this) - ); - - -}; - -GameLib.System.CustomCode.prototype.instanceCreated = function(data) { - if (data.component instanceof GameLib.CustomCode) { - - if (this.subscriptions[data.component.id]) { - console.warn('a component already existed'); - this.subscriptions[data.component.id].remove(); - } - - this.subscriptions[data.component.id] = GameLib.Event.Subscribe( - data.component.eventId, - data.component.instance - ); - } -}; - -GameLib.System.CustomCode.prototype.removeComponent = function(data) { - if (data.component instanceof GameLib.CustomCode) { - if (this.subscriptions[data.component.id]) { - this.subscriptions[data.component.id].remove(); - delete this.subscriptions[data.component.id]; - } - } -}; - -GameLib.System.CustomCode.prototype.compileSuccess = function(data) { - - if (this.subscriptions[data.component.id]) { - this.subscriptions[data.component.id].remove(); - } - - this.subscriptions[data.component.id] = GameLib.Event.Subscribe( - data.component.eventId, - data.component.instance - ); -}; - -GameLib.System.CustomCode.prototype.compileFailed = function(data) { - if (this.subscriptions[data.component.id]) { - this.subscriptions[data.component.id].remove(); - delete this.subscriptions[data.component.id]; - } -}; - - -/** - * Stop the rendering system - */ -GameLib.System.CustomCode.prototype.stop = function() { - - GameLib.System.prototype.stop.call(this); - - if (this.instanceCreatedSubscription) { - this.instanceCreatedSubscription.remove(); - this.instanceCreatedSubscription = null; - } - - if (this.removeComponentSubscription) { - this.removeComponentSubscription.remove(); - this.removeComponentSubscription = null; - } - - if (this.compileSuccessSubscription) { - this.compileSuccessSubscription.remove(); - this.compileSuccessSubscription = null; - } - - if (this.compileFailedSubscription) { - this.compileFailedSubscription.remove(); - this.compileFailedSubscription = null; - } - - Object.keys(this.subscriptions).map( - function(componentId) { - if (this.subscriptions[componentId]) { - this.subscriptions[componentId].remove(); - delete this.subscriptions[componentId]; - } - }.bind(this) - ); - -}; - - -/** - * System takes care of updating all the entities (based on their component data) - * @param apiSystem GameLib.API.System - * @constructor - */ -GameLib.System.GUI = function( - apiSystem -) { - GameLib.System.call( - this, - apiSystem - ); - - this.guis = []; - - this.components = []; - - /** - * When we want to show a specific set of components - we backup the current components and then restore them - * later when we are done. - * @type {null} - */ - this.backupComponents = []; - - this.exclusiveMode = false; - - this.buildGUISubscription = null; - - this.meshDeletedSubscription = null; - - this.meshSelectedSubscription = null; - - this.meshDeselectedSubscription = null; - - this.newEntitySubscription = null; - - this.meshSelectionObjects = {}; - - this.sourceChangedSubscription = null; - - this.instanceCreatedSubscription = null; - - this.removeComponentSubscription = null; - - this.windowResizeSubscription = null; - -}; - -GameLib.System.GUI.prototype = Object.create(GameLib.System.prototype); -GameLib.System.GUI.prototype.constructor = GameLib.System.GUI; - -GameLib.System.GUI.prototype.windowResize = function(data) { - this.guis.map( - function(gui) { - gui.instance.domElement.getElementsByTagName('ul')[0].style.maxHeight = data.height - 93 + 'px'; - } - ); -}; - -GameLib.System.GUI.prototype.initialize = function(gui) { - - var length = this.guis.length; - - gui.instance.domElement.style.position = 'absolute'; - gui.instance.domElement.style.top = length * 34 + 'px'; - gui.instance.domElement.style.right = '0px'; - - gui.domElement.instance.parentElement.appendChild(gui.instance.domElement); -}; - -GameLib.System.GUI.prototype.instanceCreated = function(data) { - if (data.component instanceof GameLib.GUI) { - GameLib.Utils.PushUnique(this.guis, data.component); - this.initialize(data.component); - } -}; - -GameLib.System.GUI.prototype.removeComponent = function(data) { - - if (data.component instanceof GameLib.GUI) { - var index = this.guis.indexOf(data.component); - - if (index === -1) { - console.warn('gui system out of sync'); - } else { - var gui = this.guis[index]; - - gui.domElement.instance.parentElement.removeChild(gui.instance.domElement); - - this.guis.splice(index, 1); - } - } - -}; - -GameLib.System.GUI.prototype.start = function() { - - GameLib.System.prototype.start.call(this); - - this.instanceCreatedSubscription = GameLib.Event.Subscribe( - GameLib.Event.INSTANCE_CREATED, - this.instanceCreated.bind(this) - ); - - this.removeComponentSubscription = GameLib.Event.Subscribe( - GameLib.Event.REMOVE_COMPONENT, - this.removeComponent.bind(this) - ); - - this.windowResizeSubscription = GameLib.Event.Subscribe( - GameLib.Event.WINDOW_RESIZE, - this.windowResize.bind(this) - ); - - this.guis = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.GUI); - this.guis.map( - function(gui){ - this.initialize(gui); - }.bind(this) - ); - - /** - * Add some GUI behaviour - */ - dat.GUI.prototype.removeEmtpyFolders = function() { - for (var property in this.__folders) { - if (this.__folders.hasOwnProperty(property)){ - - var folder = this.__folders[property]; - - if (folder.__listening.length === 0) { - folder.close(); - this.__ul.removeChild(folder.domElement.parentNode); - delete this.__folders[property]; - this.onResize(); - } - } - } - }; - - dat.GUI.prototype.listen = function(controller) { - const init = this.__listening.length === 0; - this.__listening.push(controller); - - delete this.closed; - - Object.defineProperty(this, 'closed', { - get: function() { - return this.params.closed; - }, - set: function(v) { - // console.log('override here too'); - - this.params.closed = v; - if (this.params.closed) { - this.dom.addClass(this.__ul, 'closed'); - - cancelAnimationFrame(this.animationId); - - } else { - this.dom.removeClass(this.__ul, 'closed'); - - this.updateDisplaysCallback = function() { - - /** - * We store the animationFrameId so we can remove this callback later - */ - this.animationId = requestAnimationFrame(this.updateDisplaysCallback.bind(this)); - - this.__listening.map(function(controller){ - controller.updateDisplay(); - }); - - }.bind(this); - - this.animationId = requestAnimationFrame(this.updateDisplaysCallback); - } - // For browsers that aren't going to respect the CSS transition, - // Lets just check our height against the window height right off - // the bat. - this.onResize(); - - if (this.__closeButton) { - this.__closeButton.innerHTML = v ? 'Open Controls' : 'Close Controls'; - } - }, - configurable: true - }); - - }; - - dat.GUI.prototype.removeAllFolders = function() { - for (var property in this.__folders) { - if (this.__folders.hasOwnProperty(property)){ - - var folder = this.__folders[property]; - - /** - * Theres a big 'TODO' in the controller remove() function to actually remove the listener - * That's what we are going to do now.. - because it really fucks with the framerate eventually - */ - cancelAnimationFrame(folder.animationId); - - folder.__controllers.map( - function(controller) { - controller.remove(); - - } - ); - - folder.__controllers = []; - - folder.__listening = []; - - /** - * Call UpdateDisplays with - */ - folder.close(); - - this.__ul.removeChild(folder.domElement.parentNode); - delete this.__folders[property]; - this.onResize(); - } - } - }; - - this.buildGUISubscription = this.subscribe( - GameLib.Event.BUILD_GUI, - this.buildGUI - ); - - this.meshDeletedSubscription = this.subscribe( - GameLib.Event.REMOVE_MESH, - this.meshDeleted - ); - - this.meshSelectedSubscription = this.subscribe( - GameLib.Event.MESH_SELECTED, - this.meshSelected - ); - - this.meshDeselectedSubscription = this.subscribe( - GameLib.Event.MESH_DESELECTED, - this.meshDeslected - ); - - this.newEntitySubscription = this.subscribe( - GameLib.Event.NEW_ENTITY, - this.newEntity - ); - - this.componentRemovedSubscription = this.subscribe( - GameLib.Event.REMOVE_COMPONENT, - this.removeComponent - ); - - this.sourceChangedSubscription = this.subscribe( - GameLib.Event.CAST_SOURCE_CHANGED, - this.castSourceChanged - ); - - this.destinationChangedSubscription = this.subscribe( - GameLib.Event.RECEIVE_DESTINATION_CHANGED, - this.receiveDestinationChanged - ); - -}; - -GameLib.System.GUI.prototype.onChange = function(property, subProperty, affected) { - return function(value) { - affected.map(function(component){ - - component[property][subProperty] = value; - - if (component instanceof GameLib.D3.Mesh && property === 'rotation') { - component.useQuaternion = false; - } - - if (component instanceof GameLib.D3.Mesh && property === 'quaternion') { - component.useQuaternion = true; - } - - if (typeof component[property].updateInstance === 'function') { - component[property].updateInstance(property); - } else if (typeof component[property][subProperty].updateInstance === 'function') { - component[property][subProperty].updateInstance(subProperty); - } else { - component.updateInstance(property); - } - - }); - } -}; - -GameLib.System.GUI.prototype.controller = function(folder, object, property, subProperty, step, listen, affected, min, max) { - - if (GameLib.Utils.UndefinedOrNull(min)) { - min = -1000; - } - - if (GameLib.Utils.UndefinedOrNull(max)) { - max = 1000; - } - - if ( - // property === 'chassisConnectionPointLocal' || - property === 'axleLocal' || - property === 'directionLocal' - ) { - min = -1; - max = 1; - step = 1; - } - - if ( - // property === 'chassisConnectionPointLocal' || - property === 'offset' || - property === 'repeat' - ) { - min = -1000; - max = 1000; - step = 0.01; - } - - var handle = folder.add( - object[property], - subProperty, - min, - max, - step - ).name(property + '.' + subProperty); - - handle.onChange(this.onChange(property, subProperty, affected)); - - if (listen) { - handle.listen(); - } - - return handle; -}; - -GameLib.System.GUI.prototype.buildQuaternionControl = function(folder, componentTemplate, property) { - - var step = 0.1; - - var object = componentTemplate.template; - - var listen = false; - - if (componentTemplate.affected.length === 1) { - /** - * If the template only affects a single object - put the handle on this so we can listen for changes - */ - object = componentTemplate.affected[0]; - - listen = true; - } - - var affected = componentTemplate.affected; - - this.controller(folder, object, property, 'x', step, listen, affected); - this.controller(folder, object, property, 'y', step, listen, affected); - this.controller(folder, object, property, 'z', step, listen, affected); - this.controller(folder, object, property, 'w', step, listen, affected); - this.controller(folder, object, property, 'angle', 0.001, listen, affected, -Math.PI, Math.PI); - - folder.add( - object[property]['axis'], - 'x', - -1, - 1, - 0.01 - ).name('quaternion.axis.x').onChange( - function(value) { - affected.map(function(component){ - component.useQuaternion = true; - component[property]['axis'].x = Number(value); - component.updateInstance('x'); - }) - } - ); - - folder.add( - object[property]['axis'], - 'y', - -1, - 1, - 0.01 - ).name('quaternion.axis.y').onChange( - function(value) { - affected.map(function(component){ - component.useQuaternion = true; - component[property]['axis'].y = Number(value); - component.updateInstance('y'); - }) - } - ); - - folder.add( - object[property]['axis'], - 'z', - -1, - 1, - 0.01 - ).name('quaternion.axis.z').onChange( - function(value) { - affected.map(function(component){ - component.useQuaternion = true; - component[property]['axis'].z = Number(value); - component.updateInstance('z'); - }) - } - ); - -}; - -GameLib.System.GUI.prototype.buildVectorControl = function(folder, componentTemplate, property) { - - var step = 0.01; - - var object = componentTemplate.template; - - var listen = false; - - if (componentTemplate.affected.length === 1) { - /** - * If the template only affects a single object - put the handle on this so we can listen for changes - */ - object = componentTemplate.affected[0]; - - listen = true; - } - - var affected = componentTemplate.affected; - - var controllers = []; - - if (GameLib.Utils.isVector4(object[property])) { - controllers.push(this.controller(folder, object, property, 'w', step, listen, affected)); - } - - controllers.push(this.controller(folder, object, property, 'x', step, listen, affected)); - controllers.push(this.controller(folder, object, property, 'y', step, listen, affected)); - - if ( - GameLib.Utils.isVector3(object[property]) || - GameLib.Utils.isVector4(object[property]) - ) { - controllers.push(this.controller(folder, object, property, 'z', step, listen, affected)); - } - -}; - -/** - * Builds an Entity Selection control - * @param folder - * @param componentTemplate - * @param property - */ -GameLib.System.GUI.prototype.buildParentSelectionControl = function(folder, componentTemplate, property) { - - var type = GameLib.Utils.UpperCaseUnderscore(property.replace('parent','')); - - var componentType = GameLib.Component[type]; - - var constructor = GameLib.Component.GetComponentConstructor(componentType); - - var options = GameLib.EntityManager.Instance.queryComponentsByConstructor(constructor).reduce( - function(result, object) { - result[object.name] = object; - return result; - }, - { - 'none' : null - } - ); - - var object = componentTemplate.template; - - var affected = componentTemplate.affected; - - folder.add(object, property, options).listen().onChange( - - function(value) { - - var newComponent = null; - - if (value !== 'null') { - newComponent = GameLib.EntityManager.Instance.findComponentById(value); - } - - affected.map( - function(component) { - - component[property] = newComponent; - - if (property === 'parentEntity') { - GameLib.Event.Emit( - GameLib.Event.PARENT_ENTITY_CHANGE, - { - originalEntity : this.initialValue, - newEntity : newComponent, - object : component - } - ); - } - - if (property === 'parentPhysicsWorld') { - GameLib.Event.Emit( - GameLib.Event.PARENT_WORLD_CHANGE, - { - originalWorld : this.initialValue, - newWorld : newComponent, - object : component - } - ) - } - - if (property === 'parentScene') { - GameLib.Event.Emit( - GameLib.Event.PARENT_SCENE_CHANGE, - { - originalScene: this.initialValue, - newScene: newComponent, - object: component - } - ); - } - - }.bind(this) - ); - - if (property === 'parentEntity') { - GameLib.Event.Emit( - GameLib.Event.BUILD_GUI, - null - ); - } - - this.initialValue = newComponent; - } - ); -}; - -GameLib.System.GUI.prototype.buildArrayManagerControl = function( - folder, - componentTemplate, - property -) { - - var constructors = componentTemplate.template.linkedObjects[property]; - - if (constructors instanceof Array) { - /** - * All good - */ - } else { - /** - * There is a data mismatch - */ - console.error('data mismatch - something not an array'); - return; - } - - var object = componentTemplate.template; - - var array = object[property]; - - var addArrayItem = function(item, index){ - - var name = 'invalid item'; - - if (item && item.name) { - name = item.name; - } - - var controller = folder.add( - { - 'remove' : function() { - componentTemplate.affected.map(function(component){ - component[property].splice(index, 1); - folder.remove(controller); - }); - } - }, - 'remove' - ).name('remove ' + property + '[' + index + '] - ' + name); - - folder.updateDisplay(); - }; - - array.map(addArrayItem); - - var idObject = {}; - - var selectionObject = GameLib.EntityManager.Instance.queryComponents(constructors).reduce( - function(result, component) { - result[component.name] = component; - idObject[component.id] = component; - return result; - }, - { - 'none' : null - } - ); - - var activeSelection = { - component: null, - add: function () { - - componentTemplate.affected.map(function (component) { - if (component[property].indexOf(activeSelection.component) === -1) { - component[property].push(activeSelection.component); - - GameLib.Event.Emit( - GameLib.Event.ARRAY_ITEM_ADDED, - { - component : component, - property : property, - item : activeSelection.component - } - ); - - // addArrayItem(activeSelection.component, component[property].length - 1); - } - }); - - GameLib.Event.Emit( - GameLib.Event.BUILD_GUI - ); - } - }; - - folder.add(activeSelection, 'component', selectionObject).name('select ' + property).onChange( - function(value){ - if (value === 'null') { - activeSelection['component'] = null; - } else { - activeSelection['component'] = idObject[value]; - } - } - ).listen(); - - folder.add(activeSelection, 'add').name('add to ' + property); - -}; - -GameLib.System.GUI.prototype.buildColorControl = function(folder, componentTemplate, property) { - - var object = componentTemplate.template; - - var tempObject = { - hexColor : object[property].toHex() - }; - - folder.addColor( - tempObject, - 'hexColor' - ).name(property).listen().onChange( - function(value) { - componentTemplate.affected.map( - function(component) { - component[property].fromHex(value); - component[property].updateInstance(property); - } - ) - } - ); - - folder.add( - tempObject, - 'hexColor' - ).name(property).listen().onChange( - function(value) { - componentTemplate.affected.map( - function(component) { - component[property].fromHex(value); - component[property].updateInstance(property); - } - ) - } - ) - -}; - -GameLib.System.GUI.prototype.buildObjectControl = function(folder, componentTemplate, property) { - - var object = componentTemplate.template[property]; - - if (object === null) { - return; - } - - if ( - property === 'sourceProperties' || - property === 'destinationProperties' - ) { - Object.keys(object).map( - function(propertyId) { - folder.add( - object, - propertyId - ).name(property + '.' + propertyId).listen().onChange( - function(value) { - componentTemplate.affected.map( - function(component){ - component[property][propertyId] = value; - component.updateInstance(property); - } - ); - } - ); - } - ); - } -}; - -GameLib.System.GUI.prototype.buildSelectControl = function(folder, componentTemplate, property) { - - /** - * We need to discover the constructor for this component - */ - var constructors = null; - - if (componentTemplate.template.linkedObjects && componentTemplate.template.linkedObjects[property]) { - constructors = componentTemplate.template.linkedObjects[property]; - } else { - if (componentTemplate.template[property]) { - constructors = componentTemplate.template[property].constructor; - } - } - - if (!constructors) { - console.log('cannot determine constructor'); - return; - } - - var object = componentTemplate.template; - - var objects = GameLib.EntityManager.Instance.queryComponentsByConstructor(constructors); - - var idObject = {}; - - var options = objects.reduce( - function(result, obj) { - result[obj.name] = obj; - idObject[obj.id] = obj; - return result; - }, - { - 'none' : null - } - ); - - folder.add( - object, - property, - options - ).name(property).listen().onChange( - - function (value) { - - var newComponent = null; - - if (value !== 'null') { - newComponent = idObject[value]; - } - - componentTemplate.affected.map( - function(component) { - component[property] = newComponent; - component.updateInstance(property); - } - ); - - this.initialValue = newComponent; - } - ); -}; - -GameLib.System.GUI.prototype.buildControl = function(folder, componentTemplate, property) { - - var object = componentTemplate.template; - - var listen = false; - - if (componentTemplate.affected.length === 1) { - /** - * If the template only affects a single object - put the handle on this so we can listen for changes - */ - object = componentTemplate.affected[0]; - - listen = true; - } - - var componentType = componentTemplate.componentType; - - var controllers = []; - - if ( - GameLib.Utils.isString(object[property]) || - GameLib.Utils.isBoolean(object[property]) - ) { - controllers.push(folder.add(object, property)); - } - - if (GameLib.Utils.isNumber(object[property])) { - - var grain = 0.001; - - if (object.grain) { - grain = object.grain; - } - - if (property === 'componentType') { - - var readOnly = { - componentType : GameLib.Component.GetComponentInfo(object[property]).name - }; - - controllers.push( - folder.add( - readOnly, - 'componentType' - ) - ); - } else if (property === 'systemType') { - controllers.push( - folder.add( - object, - property, - { - 'animation' : GameLib.System.SYSTEM_TYPE_ANIMATION, - 'gui' : GameLib.System.SYSTEM_TYPE_GUI, - 'input' : GameLib.System.SYSTEM_TYPE_INPUT, - 'render' : GameLib.System.SYSTEM_TYPE_RENDER, - 'storage' : GameLib.System.SYSTEM_TYPE_STORAGE, - 'linking' : GameLib.System.SYSTEM_TYPE_LINKING, - 'physics' : GameLib.System.SYSTEM_TYPE_PHYSICS, - 'custom code' : GameLib.System.SYSTEM_TYPE_CUSTOM - } - ) - ); - } else if (property === 'socketType') { - controllers.push( - folder.add( - object, - property, - { - 'none' : GameLib.API.Socket.TYPE_NONE, - 'cast' : GameLib.API.Socket.TYPE_CAST, - 'receive' : GameLib.API.Socket.TYPE_RECEIVE - } - ) - ); - } else if (property === 'castType') { - controllers.push( - folder.add( - object, - property, - { - 'room': GameLib.API.Socket.Cast.CAST_TYPE_ROOM, - 'peer': GameLib.API.Socket.Cast.CAST_TYPE_PEER , - 'all': GameLib.API.Socket.Cast.CAST_TYPE_ALL, - 'all but peer': GameLib.API.Socket.Cast.CAST_TYPE_ALL_BUT_PEER - } - ) - ); - } else if (property === 'receiveType') { - controllers.push( - folder.add( - object, - property, - { - 'room': GameLib.API.Socket.Receive.RECEIVE_TYPE_ROOM, - 'peer': GameLib.API.Socket.Cast.RECEIVE_TYPE_PEER - } - ) - ); - } else if (property === 'opacityType') { - controllers.push( - folder.add( - object, - property, - { - 'constant': GameLib.D3.Particle.OPACITY_TYPE_CONSTANT, - 'decrease': GameLib.D3.Particle.OPACITY_TYPE_DECREASE_LINEAR, - 'increase': GameLib.D3.Particle.OPACITY_TYPE_INCREASE_LINEAR - } - ) - ); - } else if (property === 'positionOffsetType') { - controllers.push( - folder.add( - object, - property, - { - 'constant': GameLib.D3.Particle.POSITION_OFFSET_TYPE_CONSTANT, - 'random': GameLib.D3.Particle.POSITION_OFFSET_TYPE_RANDOM, - 'function': GameLib.D3.Particle.POSITION_OFFSET_TYPE_FUNCTION - } - ) - ); - } else if (property === 'directionType') { - controllers.push( - folder.add( - object, - property, - { - 'constant': GameLib.D3.Particle.DIRECTION_TYPE_CONSTANT, - 'random': GameLib.D3.Particle.DIRECTION_TYPE_RANDOM, - 'random normalized': GameLib.D3.Particle.DIRECTION_TYPE_RANDOM_NORMALIZED, - 'function': GameLib.D3.Particle.DIRECTION_TYPE_FUNCTION - } - ) - ); - } else if (property === 'speedType') { - controllers.push( - folder.add( - object, - property, - { - 'constant': GameLib.D3.Particle.SPEED_TYPE_CONSTANT, - 'linear': GameLib.D3.Particle.SPEED_TYPE_LINEAR, - 'exponential': GameLib.D3.Particle.SPEED_TYPE_EXPONENTIAL, - 'logarithmic': GameLib.D3.Particle.SPEED_TYPE_LOGARITHMIC, - '1 / log': GameLib.D3.Particle.SPEED_TYPE_ONE_OVER_LOG, - 'exp' : GameLib.D3.Particle.SPEED_TYPE_EXP, - '1 / exp' : GameLib.D3.Particle.SPEED_TYPE_ONE_OVER_EXP - } - ) - ); - } else if (property === 'scaleType') { - controllers.push( - folder.add( - object, - property, - { - 'constant': GameLib.D3.Particle.SCALE_TYPE_CONSTANT, - 'linear': GameLib.D3.Particle.SCALE_TYPE_LINEAR, - 'exponential': GameLib.D3.Particle.SCALE_TYPE_EXPONENTIAL, - 'random': GameLib.D3.Particle.SCALE_TYPE_RANDOM, - 'random (x = y)': GameLib.D3.Particle.SCALE_TYPE_RANDOM_X_EQUALS_Y, - 'function': GameLib.D3.Particle.SCALE_TYPE_FUNCTION - } - ) - ); - } else if (property === 'rotationType') { - controllers.push( - folder.add( - object, - property, - { - 'constant': GameLib.D3.Particle.ROTATION_TYPE_CONSTANT, - 'random': GameLib.D3.Particle.ROTATION_TYPE_RANDOM, - 'function': GameLib.D3.Particle.ROTATION_TYPE_FUNCTION - } - ) - ); - } else if (property === 'broadphaseType') { - controllers.push( - folder.add( - object, - property, - { - 'naive': GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE, - 'grid': GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID, - 'sap': GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP - } - ) - ); - } else if (property === 'solverType') { - controllers.push( - folder.add( - object, - property, - { - 'gs': GameLib.D3.API.Solver.GS_SOLVER, - 'split': GameLib.D3.API.Solver.SPLIT_SOLVER - } - ) - ); - } else if (property === 'meshType') { - controllers.push( - folder.add( - object, - property, - { - 'normal' : GameLib.D3.API.Mesh.MESH_TYPE_NORMAL, - 'curve' : GameLib.D3.API.Mesh.MESH_TYPE_CURVE, - 'skinned' : GameLib.D3.API.Mesh.MESH_TYPE_SKINNED, - 'plane' : GameLib.D3.API.Mesh.MESH_TYPE_PLANE, - 'sphere' : GameLib.D3.API.Mesh.MESH_TYPE_SPHERE, - 'box' : GameLib.D3.API.Mesh.MESH_TYPE_BOX, - 'cylinder' : GameLib.D3.API.Mesh.MESH_TYPE_CYLINDER, - 'text' : GameLib.D3.API.Mesh.MESH_TYPE_TEXT - } - ) - ); - } else if (property === 'cameraType') { - controllers.push( - folder.add( - object, - property, - { - 'perspective' : GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE, - 'orthographic' : GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL - } - ) - ); - } else if (property === 'materialType') { - controllers.push( - folder.add( - object, - property, - { - 'standard': GameLib.D3.Material.MATERIAL_TYPE_STANDARD, - 'basic': GameLib.D3.Material.MATERIAL_TYPE_BASIC, - 'phong': GameLib.D3.Material.MATERIAL_TYPE_PHONG, - 'points': GameLib.D3.Material.MATERIAL_TYPE_POINTS, - 'toon': GameLib.D3.Material.MATERIAL_TYPE_TOON, - 'line basic' : GameLib.D3.Material.MATERIAL_TYPE_LINE_BASIC - } - ) - ); - } else if (property === 'side') { - controllers.push( - folder.add( - object, - property, - { - 'double': GameLib.D3.Material.TYPE_DOUBLE_SIDE, - 'front': GameLib.D3.Material.TYPE_FRONT_SIDE, - 'back': GameLib.D3.Material.TYPE_BACK_SIDE - } - ) - ); - } else if (property === 'combine') { - controllers.push( - folder.add( - object, - property, - { - 'multiply': GameLib.D3.Material.TYPE_MULTIPLY_OPERATION, - 'mix': GameLib.D3.Material.TYPE_MIX_OPERATION, - 'add': GameLib.D3.Material.TYPE_ADD_OPERATION - } - ) - ); - } else if (property === 'vertexColors') { - controllers.push( - folder.add( - object, - property, - { - 'none': GameLib.D3.Material.TYPE_NO_COLORS, - 'face': GameLib.D3.Material.TYPE_FACE_COLORS, - 'vertex': GameLib.D3.Material.TYPE_VERTEX_COLORS - } - ) - ); - } else if (property === 'blending') { - controllers.push( - folder.add( - object, - property, - { - 'none': GameLib.D3.Material.TYPE_NO_BLENDING, - 'normal': GameLib.D3.Material.TYPE_NORMAL_BLENDING, - 'additive': GameLib.D3.Material.TYPE_ADDITIVE_BLENDING, - 'subtractive': GameLib.D3.Material.TYPE_SUBTRACTIVE_BLENDING, - 'multiply': GameLib.D3.Material.TYPE_MULTIPLY_BLENDING, - 'custom': GameLib.D3.Material.TYPE_CUSTOM_BLENDING - } - ) - ); - } else if (property === 'blendSrc') { - controllers.push( - folder.add( - object, - property, - { - 'zero': GameLib.D3.Material.TYPE_ZERO_FACTOR, - 'one': GameLib.D3.Material.TYPE_ONE_FACTOR, - 'source color': GameLib.D3.Material.TYPE_SRC_COLOR_FACTOR, - 'one minus source color': GameLib.D3.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR, - 'source alpha': GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR, - 'one minus source alpha': GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR, - 'destination alpha': GameLib.D3.Material.TYPE_DST_ALPHA_FACTOR, - 'one minus destination alpha': GameLib.D3.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR, - 'destination color': GameLib.D3.Material.TYPE_DST_COLOR_FACTOR, - 'one minus destination color': GameLib.D3.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR, - 'source alpha saturate': GameLib.D3.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR - } - ) - ); - } else if (property === 'blendDst') { - controllers.push( - folder.add( - object, - property, - { - 'zero': GameLib.D3.Material.TYPE_ZERO_FACTOR, - 'one': GameLib.D3.Material.TYPE_ONE_FACTOR, - 'source color': GameLib.D3.Material.TYPE_SRC_COLOR_FACTOR, - 'one minus source color': GameLib.D3.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR, - 'source alpha': GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR, - 'one minus source alpha': GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR, - 'destination alpha': GameLib.D3.Material.TYPE_DST_ALPHA_FACTOR, - 'one minus destination alpha': GameLib.D3.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR, - 'destination color': GameLib.D3.Material.TYPE_DST_COLOR_FACTOR, - 'one minus destination color': GameLib.D3.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR, - 'source alpha saturate': GameLib.D3.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR - } - ) - ); - } else if (property === 'blendEquation') { - controllers.push( - folder.add( - object, - property, - { - 'add': GameLib.D3.Material.TYPE_ADD_EQUATION, - 'subtract': GameLib.D3.Material.TYPE_SUBTRACT_EQUATION, - 'reverse subtract': GameLib.D3.Material.TYPE_REVERSE_SUBTRACT_EQUATION, - 'min': GameLib.D3.Material.TYPE_MIN_EQUATION, - 'max': GameLib.D3.Material.TYPE_MAX_EQUATION - } - ) - ); - } else if (property === 'depthFunc') { - controllers.push( - folder.add( - object, - property, - { - 'never': GameLib.D3.Material.TYPE_NEVER_DEPTH, - 'always': GameLib.D3.Material.TYPE_ALWAYS_DEPTH, - 'less depth': GameLib.D3.Material.TYPE_LESS_DEPTH, - 'less equal depth': GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH, - 'equal depth': GameLib.D3.Material.TYPE_EQUAL_DEPTH, - 'greated equal depth': GameLib.D3.Material.TYPE_GREATER_EQUAL_DEPTH, - 'greated depth': GameLib.D3.Material.TYPE_GREATER_DEPTH, - 'not equal depth': GameLib.D3.Material.TYPE_NOT_EQUAL_DEPTH - } - ) - ); - } else if (property === 'wrapS') { - controllers.push( - folder.add( - object, - property, - { - 'repeat': GameLib.D3.API.Texture.TYPE_REPEAT_WRAPPING, - 'clamp': GameLib.D3.API.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING, - 'mirrored repeat': GameLib.D3.API.Texture.TYPE_MIRRORED_REPEAT_WRAPPING - } - ) - ); - } else if (property === 'wrapT') { - controllers.push( - folder.add( - object, - property, - { - 'repeat': GameLib.D3.API.Texture.TYPE_REPEAT_WRAPPING, - 'clamp': GameLib.D3.API.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING, - 'mirrored repeat': GameLib.D3.API.Texture.TYPE_MIRRORED_REPEAT_WRAPPING - } - ) - ); - } else if (property === 'format') { - controllers.push( - folder.add( - object, - property, - { - 'alpha': GameLib.D3.API.Texture.TYPE_ALPHA_FORMAT, - 'rgb': GameLib.D3.API.Texture.TYPE_RGB_FORMAT, - 'rgba': GameLib.D3.API.Texture.TYPE_RGBA_FORMAT, - 'luminance': GameLib.D3.API.Texture.TYPE_LUMINANCE_FORMAT, - 'luminance alpha': GameLib.D3.API.Texture.TYPE_LUMINANCE_ALPHA_FORMAT, - 'depth': GameLib.D3.API.Texture.TYPE_DEPTH_FORMAT - } - ) - ); - } else if (property === 'mapping') { - controllers.push( - folder.add( - object, - property, - { - 'uv': GameLib.D3.API.Texture.TYPE_UV_MAPPING, - 'cube reflection': GameLib.D3.API.Texture.TYPE_CUBE_REFLECTION_MAPPING, - 'cube refraction': GameLib.D3.API.Texture.TYPE_CUBE_REFRACTION_MAPPING, - 'equi rectangular reflection': GameLib.D3.API.Texture.TYPE_EQUI_RECTANGULAR_REFLECTION_MAPPING, - 'equi rectangular refraction': GameLib.D3.API.Texture.TYPE_EQUI_RECTANGULAR_REFRACTION_MAPPING, - 'spherical reflection': GameLib.D3.API.Texture.TYPE_SPHERICAL_REFLECTION_MAPPING, - 'cube uv reflection': GameLib.D3.API.Texture.TYPE_CUBE_UV_REFLECTION_MAPPING, - 'cube uv refraction': GameLib.D3.API.Texture.TYPE_CUBE_UV_REFRACTION_MAPPING - } - ) - ); - } else if (property === 'magFilter') { - controllers.push( - folder.add( - object, - property, - { - 'nearest': GameLib.D3.API.Texture.TYPE_NEAREST_FILTER, - 'nearest mipmap nearest': GameLib.D3.API.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER, - 'nearest mipmap linear': GameLib.D3.API.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER, - 'linear': GameLib.D3.API.Texture.TYPE_LINEAR_FILTER, - 'linear mipmap nearest': GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER, - 'linear mipmap linear': GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER - } - ) - ); - } else if (property === 'minFilter') { - controllers.push( - folder.add( - object, - property, - { - 'nearest': GameLib.D3.API.Texture.TYPE_NEAREST_FILTER, - 'nearest mipmap nearest': GameLib.D3.API.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER, - 'nearest mipmap linear': GameLib.D3.API.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER, - 'linear': GameLib.D3.API.Texture.TYPE_LINEAR_FILTER, - 'linear mipmap nearest': GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER, - 'linear mipmap linear': GameLib.D3.API.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER - } - ) - ); - } else if (componentType === GameLib.Component.TEXTURE && property === 'textureType') { - controllers.push( - folder.add( - object, - property, - { - 'normal': GameLib.D3.API.Texture.TEXTURE_TYPE_NORMAL, - 'cube': GameLib.D3.API.Texture.TEXTURE_TYPE_CUBE, - 'canvas': GameLib.D3.API.Texture.TEXTURE_TYPE_CANVAS - } - ) - ); - } else if (property === 'textureType') { - controllers.push( - folder.add( - object, - property, - { - 'unsigned byte': GameLib.D3.API.Texture.TYPE_UNSIGNED_BYTE, - 'byte': GameLib.D3.API.Texture.TYPE_BYTE, - 'short': GameLib.D3.API.Texture.TYPE_SHORT, - 'unsigned short': GameLib.D3.API.Texture.TYPE_UNSIGNED_SHORT, - 'int': GameLib.D3.API.Texture.TYPE_INT, - 'unsigned int': GameLib.D3.API.Texture.TYPE_UNSIGNED_INT, - 'float': GameLib.D3.API.Texture.TYPE_FLOAT, - 'half float': GameLib.D3.API.Texture.TYPE_HALF_FLOAT - } - ) - ); - } else if (property === 'encoding') { - controllers.push( - folder.add( - object, - property, - { - 'linear': GameLib.D3.API.Texture.TYPE_LINEAR_ENCODING, - 'srgb': GameLib.D3.API.Texture.TYPE_SRGB_ENCODING, - 'gamma': GameLib.D3.API.Texture.TYPE_GAMMA_ENCODING, - 'rgbe': GameLib.D3.API.Texture.TYPE_RGBE_ENCODING, - 'log luv': GameLib.D3.API.Texture.TYPE_LOG_LUV_ENCODING, - 'rgbm7': GameLib.D3.API.Texture.TYPE_RGBM7_ENCODING, - 'rgbm16': GameLib.D3.API.Texture.TYPE_RGBM16_ENCODING, - 'rgbd': GameLib.D3.API.Texture.TYPE_RGBD_ENCODING - } - ) - ); - } else if (property === 'lightType') { - controllers.push( - folder.add( - object, - property, - { - 'ambient': GameLib.D3.Light.LIGHT_TYPE_AMBIENT, - 'directional': GameLib.D3.Light.LIGHT_TYPE_DIRECTIONAL, - 'spot': GameLib.D3.Light.LIGHT_TYPE_SPOT, - 'point': GameLib.D3.Light.LIGHT_TYPE_POINT - } - ) - ); - } else if (property === 'eventId') { - - var options = {}; - - for (var i = 0; i < 200; i++) { - try { - options[GameLib.Event.GetEventName(i)] = i; - } catch (error) { - - } - } - - controllers.push( - folder.add( - object, - property, - options - ) - ); - } else if (property === 'functionType') { - controllers.push( - folder.add( - object, - property, - { - 'rotation': GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION, - 'translation': GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION, - 'scale': GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE - } - ) - ); - } else { - - /** - * Try to guess a scale for this property - */ - if ( - property === 'opacity' || - property === 'opacityFactor' || - property === 'metalness' || - property === 'roughness' || - property === 'volume' - ) { - controllers.push(folder.add(object, property, 0, 1.0, 0.001)); - } else if ( - property === 'shininess' || - property === 'fov' - ) { - controllers.push(folder.add(object, property, -255, 255, 1)); - } else if ( - property === 'aspect' || - property === 'wireframeLineWidth' || - property === 'lineWidth' - ) { - controllers.push(folder.add(object, property, 0, 5, 0.001)); - } else if ( - property === 'bumpScale' || - property === 'normalScale' || - property === 'displacementScale' || - property === 'heightMapScale' || - property === 'intensity' - ) { - controllers.push(folder.add(object, property, -10, 10, 0.001)); - } else if ( - property === 'minX' || - property === 'minY' || - property === 'minZ' || - property === 'maxX' || - property === 'maxY' || - property === 'maxZ' || - property === 'offsetX' - ) { - controllers.push(folder.add(object, property, -1000, 1000, 0.01)); - } else if ( - property === 'widthSegments' || - property === 'radiusSegments' || - property === 'heightSegments' || - property === 'particlesPerSecond' - ) { - controllers.push(folder.add(object, property, 1, 1000, 1)); - } else if ( - property === 'width' || - property === 'height' || - property === 'depth' || - property === 'radius' - ) { - controllers.push(folder.add(object, property, 0, 1000, 0.1)); - } else if ( - property === 'near' || - property === 'distanceGrain' || - property === 'envMapIntensity' - ) { - controllers.push(folder.add(object, property, -10, 100, 0.001)); - } else if ( - property === 'bumpScale' - ) { - controllers.push(folder.add(object, property, 0, 20, 0.001)); - } else if ( - property === 'heightOffset' || - property === 'rotationFactor' - ) { - controllers.push(folder.add(object, property, -100, 100, 0.001)); - } else if ( - property === 'friction' - ) { - controllers.push(folder.add(object, property, 0, 1000, 0.01)); - } else if ( - property === 'radiusTop' || - property === 'radiusBottom' - ) { - controllers.push(folder.add(object, property, 0, 100, 0.1)); - } else if ( - property === 'mass' - ) { - controllers.push(folder.add(object, property, 0, 1000, 0.1)); - } else if ( - property === 'sensitivity' - ) { - controllers.push(folder.add(object, property, 1, 50, 1)); - } else if ( - property === 'density' - ) { - controllers.push(folder.add(object, property, 0, 1, 0.0001)); - } else if ( - property === 'thetaLength' || - property === 'angle' - ) { - controllers.push(folder.add(object, property, -Math.PI * 2, Math.PI * 2, 0.01)); - } else if ( - property === 'port' - ) { - controllers.push(folder.add(object, property, 1, 65536, 1)); - } else { - controllers.push(folder.add(object, property, -1000, 1000, 0.1)); - } - } - } - - controllers.map( - function(controller) { - - if (property === 'name') { - controller.onFinishChange( - function(__handle, __folder) { - return function(value) { - - componentTemplate.affected.map( - function(component){ - component[property] = value; - component.updateInstance(property); - } - ); - - var li = __folder.domElement.getElementsByClassName('title')[0]; - li.innerHTML = value; - } - }(controller, folder) - ); - } else { - controller.onChange( - function (value) { - - if (typeof this.initialValue === 'number') { - value = Number(value); - } - - componentTemplate.affected.map( - function(component){ - component[property] = value; - component.updateInstance(property); - } - ); - } - ); - } - - if (listen) { - controller.listen(); - } - - } - ); - -}; - -/** - * Push the mesh to our backup components, if in exclusiveMode (menu at top is selected), - * otherwise, just to our normal components - * @param data - */ -GameLib.System.GUI.prototype.meshSelected = function(data) { - - if (this.exclusiveMode) { - GameLib.Utils.PushUnique(this.backupComponents, data.mesh); - } else { - GameLib.Utils.PushUnique(this.components, data.mesh); - } - -}; - -/** - * Same as selected above, but removes the mesh from the components - * @param data - */ -GameLib.System.GUI.prototype.meshDeslected = function(data) { - - var index = -1; - - if (this.exclusiveMode) { - index = this.backupComponents.indexOf(data.mesh); - if (index !== -1) { - this.backupComponents.splice(index, 1); - } - } else { - index = this.components.indexOf(data.mesh); - if (index !== -1) { - this.components.splice(index, 1); - } - } - -}; - -/** - * This function responds to the BUILD_GUI event, data contains the components to build a GUI for data. - * - * If we send data with components - go into exclusive mode, backup the currently selected components and rebuild the gui - * - * If we send data without components - go out of exclusive mode, restore the backup of the currently selected components - * and rebuild based on the meshes - * - * If we don't send any data (null or undefined) - some parameters changed and just rebuild the gui. - * - * @param data - */ -GameLib.System.GUI.prototype.buildGUI = function(data) { - - this.guis.map(function(gui){ - - /** - * First, start fresh - remove all folders - */ - gui.instance.destroy(); - - gui.removeAllFolders(); - - // gui.domElement.instance.parentElement.appendChild(gui.instance.domElement); - - if (data) { - - if (data.components) { - - - /** - * Check if we are not already in exclusive mode, because we only want to make a backup if - * it does not already exist - */ - if (!this.exclusiveMode) { - - this.exclusiveMode = true; - - /** - * Backup the current selection - */ - this.backupComponents = this.components.map( - function(component) { - return component; - } - ); - - } - - this.components = data.components.map( - function(component) { - return component; - } - ); - - } else { - - if (this.exclusiveMode) { - this.exclusiveMode = false; - - /** - * Time to restore the backup - */ - this.components = this.backupComponents.map( - function(component) { - return component; - } - ) - } else { - console.log('we are already not in mesh select mode - not doing anything with the backup'); - } - } - } - - /** - * For all mesh components - (if not in exclusive mode) - try to discover all materials, textures, etc - */ - if (!this.exclusiveMode) { - - /** - * We first remove everything which is not a Mesh - */ - this.components = this.components.filter( - function (component) { - return (component instanceof GameLib.D3.Mesh); - } - ); - } - - /** - * Check if we have components to build a GUI for - */ - if (GameLib.Utils.UndefinedOrNull(this.components.length) || this.components.length < 1) { - // console.log('no components selected'); - return; - } - - /** - * Now continue to discover materials, textures, images etc. children of this component - */ - if (!this.exclusiveMode) { - - this.components = this.components.reduce( - function(result, component) { - - var components = component.getChildrenComponents(); - - GameLib.Utils.PushUnique(result, component); - - components.map(function(component){ - GameLib.Utils.PushUnique(result, component); - }); - - return result; - }.bind(this), - [] - ); - } - - /** - * Sort the components by component type - */ - this.components.sort( - - function(a, b) { - - if (a.componentType > b.componentType) { - return 1; - } - - if (a.componentType < b.componentType) { - return -1; - } - - return 0; - } - ); - - /** - * Split the components into groups of componentType - */ - var componentGroups = this.components.reduce( - function(result, component) { - - var componentData = result.pop(); - - if (component.componentType === componentData.componentType) { - /** - * This is the first component - */ - componentData.components.push(component); - result.push(componentData); - return result; - } - - if (component.componentType !== componentData.componentType) { - result.push(componentData); - result.push({ - componentType : component.componentType, - components:[component] - }); - return result; - } - - }, - [ - { - componentType : this.components[0].componentType, - components : [] - } - ] - ); - - /** - * We have all the components split into groups - now add the individual components - */ - this.components.map( - function(component) { - - /** - * Check for possible duplicates - * @type {boolean} - */ - var duplicate = false; - componentGroups.map(function(componentGroup){ - - if ( - componentGroup.componentType === component.componentType && - componentGroup.components.length === 1 && - componentGroup.components[0] === component - ) { - duplicate = true; - } - }); - - if (!duplicate) { - GameLib.Utils.PushUnique( - componentGroups, - { - componentType : component.componentType, - components : [component] - } - ); - } - } - ); - - /** - * componentGroups should now contain the whole list of stuff we want to build GUI for. - */ - componentGroups.map( - - function(componentGroup){ - - if (componentGroup.components.length < 1) { - console.warn('invalid number of components'); - } - - var templateObject = { - template : { - /** - * Doing this here is just to put parentEntity at the top of the gui - */ - 'parentEntity' : componentGroup.components[0].parentEntity - }, - affected : [componentGroup.components[0]], - componentType : componentGroup.componentType - }; - - for (var property in componentGroup.components[0]) { - if ( - componentGroup.components[0].hasOwnProperty(property) || - typeof componentGroup.components[0][property] === 'function' - ) { - - if (typeof componentGroup.components[0][property] === 'function') { - - templateObject.template[property] = function(__property) { - - return function() { - - this.affected.map( - function(component) { - component[__property].bind(component)(); - } - ) - - }.bind(templateObject); - - }(property); - - } else { - - templateObject.template[property] = componentGroup.components[0][property]; - - } - } - } - - var componentTemplate = componentGroup.components.reduce( - - function(result, component) { - - if (component === componentGroup.components[0]) { - /** - * This is the first component, just return - */ - return result; - } - - /** - * Now start to filter out the properties - */ - for (var property in component) { - if ( - component.hasOwnProperty(property) - ) { - if (!result.template.hasOwnProperty(property)) { - continue; - } - - if ( - result.template[property] instanceof GameLib.Vector2 || - result.template[property] instanceof GameLib.Vector3 || - result.template[property] instanceof GameLib.Vector4 || - result.template[property] instanceof GameLib.Quaternion - ) { - if (!result.template[property].equals(component[property])) { - delete result.template[property]; - } - - continue; - } - - if (result.template[property] !== component[property]) { - delete result.template[property]; - } - } - } - - /** - * Store the affected component - */ - result.affected.push(component); - return result; - - }, - templateObject - ); - - /** - * componentTemplate now contains for this particular component type group - all - * the properties which are modifiable, and also the objects affected by this property changes - */ - var name; - - if (GameLib.Utils.UndefinedOrNull(componentTemplate.template.name)) { - name = GameLib.Component.GetComponentName(componentTemplate.componentType) + ' (All Selected (' + componentTemplate.affected.length + '))'; - } else { - name = componentTemplate.template.name; - } - - var folder = gui.addFolder(name); - - if (!folder) { - return; - } - - for (var templateProperty in componentTemplate.template) { - - if ( - componentTemplate.template.hasOwnProperty(templateProperty) || - typeof (componentTemplate.template[templateProperty]) === 'function' - ) { - - if (typeof (componentTemplate.template[templateProperty]) === 'function') { - folder.add(componentTemplate.template, templateProperty); - continue; - } - - /** - * We only want to affect runtime vectors because their onchange will execute updateInstance() - */ - if ( - componentTemplate.template[templateProperty] instanceof GameLib.Vector2 || - componentTemplate.template[templateProperty] instanceof GameLib.Vector3 || - componentTemplate.template[templateProperty] instanceof GameLib.Vector4 - ) { - this.buildVectorControl(folder, componentTemplate, templateProperty); - continue; - } - - if (componentTemplate.template[templateProperty] instanceof GameLib.Quaternion) { - this.buildQuaternionControl(folder, componentTemplate, templateProperty); - } - - if ( - templateProperty === 'parentEntity' || - templateProperty === 'parentPhysicsWorld' || - templateProperty === 'parentMesh' || - templateProperty === 'parentScene' - ) { - this.buildParentSelectionControl(folder, componentTemplate, templateProperty); - continue; - } - - if (componentTemplate.template[templateProperty] instanceof Array) { - - if ( - templateProperty === 'vertices' || - templateProperty === 'faces' - ) { - continue; - } - - if ( - componentTemplate.template.linkedObjects && - componentTemplate.template.linkedObjects[templateProperty] instanceof Array - ) { - this.buildArrayManagerControl(folder, componentTemplate, templateProperty); - } - - continue; - } - - if (componentTemplate.template[templateProperty] instanceof GameLib.Color) { - this.buildColorControl(folder, componentTemplate, templateProperty); - continue; - } - - if (typeof componentTemplate.template[templateProperty] === 'object') { - - if ( - componentTemplate.template[templateProperty] instanceof GameLib.Component || - ( - componentTemplate.template.linkedObjects && - componentTemplate.template.linkedObjects[templateProperty] - ) - ) { - this.buildSelectControl(folder, componentTemplate, templateProperty) - } else { - this.buildObjectControl(folder, componentTemplate, templateProperty); - } - continue; - } - - this.buildControl(folder, componentTemplate, templateProperty); - // if ( - // component.linkedObjects && - // component.linkedObjects[property] - // ) { - // if (property === 'parentEntity') { - // this.buildEntitySelectionControlFromArray( - // folder, - // component, - // property, - // entityManager - // ) - // } else if (component.linkedObjects[property] instanceof Array) { - // this.buildArrayManager( - // folder, - // component, - // property, - // component.linkedObjects[property], - // entityManager - // ) - // } else { - // this.buildSelectControl(folder, component, property, entityManager, component.linkedObjects[property]); - // } - // - // } else if (typeof (component[property]) === 'object') { - // - // if (this.isColor(component[property])) { - // this.buildControl(folder, component, property); - // } else { - // //console.log('ignored: ' + property); - // } - // } else { - // this.buildControl(folder, component, property, entityManager); - // } - - - } - } - }.bind(this) - ); - }.bind(this)); - -}; - -GameLib.System.GUI.prototype.meshDeleted = function(data) { - - data.meshes.map(function(mesh){ - this.meshDeslected({ - mesh : mesh - }) - }.bind(this)); - - this.buildGUI(null); -}; - -GameLib.System.GUI.prototype.removeComponent = function(data) { - - var index = this.backupComponents.indexOf(data.component); - if (index !== -1) { - this.backupComponents.splice(index, 1); - } - - index = this.components.indexOf(data.component); - if (index !== -1) { - this.components.splice(index, 1); - } - -}; - - -GameLib.System.GUI.prototype.newEntity = function(data) { - -}; - -GameLib.System.GUI.prototype.castSourceChanged = function(data) { - this.buildGUI(null); -}; - -GameLib.System.GUI.prototype.receiveDestinationChanged = function(data) { - this.buildGUI(null); -}; - -GameLib.System.GUI.prototype.stop = function() { - - GameLib.System.prototype.stop.call(this); - - this.guis.map(function(gui){ - gui.domElement.instance.parentElement.removeChild(gui.instance.domElement); - }); - - delete dat.GUI.removeEmtpyFolders; - - delete dat.GUI.removeAllFolders; - - this.buildGUISubscription.remove(); - - this.meshDeletedSubscription.remove(); - - this.meshSelectedSubscription.remove(); - - this.meshDeselectedSubscription.remove(); - - this.newEntitySubscription.remove(); - - this.componentRemovedSubscription.remove(); - - this.sourceChangedSubscription.remove(); - - this.destinationChangedSubscription.remove(); - - this.instanceCreatedSubscription.remove(); - - this.removeComponentSubscription.remove(); - - this.windowResizeSubscription.remove(); - - this.guis = []; -}; - - -/** - * System takes care of updating all the entities (based on their component data) - * @param apiSystem GameLib.API.System - * @constructor - */ -GameLib.System.Input = function( - apiSystem -) { - GameLib.System.call( - this, - apiSystem - ); - - this.selectAll = false; - - this.controlLeft = false; - - this.sensitivityCounter = 0; - - this.editorControls = []; - this.touchControls = []; - this.keyboardControls = []; - this.mouseControls = []; - - /** - * Touch Controls - * @type {null} - */ - this.touchStart = null; - this.touchMove = null; - this.touchEnd = null; - this.touchCancel = null; - - /** - * Keyboard Controls - * @type {null} - */ - this.keyboardKeyUp = null; - this.keyboardKeyDown = null; - - /** - * Mouse Controls - * @type {null} - */ - this.mouseDown = null; - this.mouseMove = null; - this.mouseWheel = null; - this.mouseUp = null; - - /** - * Editor Controls - * @type {null} - */ - this.keyDown = null; - this.keyUp = null; - this.mouseDownEdit = null; - this.mouseMoveEdit = null; - this.mouseWheelEdit = null; - this.mouseUpEdit = null; - - this.delayedInstanceEncounteredSubscription = null; - this.instanceCreatedSubscription = null; - this.removeComponentSubscription = null; - - this.mouse = new GameLib.Mouse(); -}; - -GameLib.System.Input.prototype = Object.create(GameLib.System.prototype); -GameLib.System.Input.prototype.constructor = GameLib.System.Input; - -/** - * - */ -GameLib.System.Input.prototype.start = function() { - - GameLib.System.prototype.start.call(this); - - this.editorControls = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.CONTROLS_EDITOR); - - this.touchControls = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.CONTROLS_TOUCH); - - this.keyboardControls = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.CONTROLS_KEYBOARD); - - this.mouseControls = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.CONTROLS_MOUSE); - - this.instanceCreatedSubscription = GameLib.Event.Subscribe( - GameLib.Event.INSTANCE_CREATED, - this.instanceCreated.bind(this) - ); - - this.removeComponentSubscription = GameLib.Event.Subscribe( - GameLib.Event.REMOVE_COMPONENT, - this.removeComponent.bind(this) - ); - - this.delayedInstanceEncounteredSubscription = GameLib.Event.Subscribe( - GameLib.Event.DELAYED_INSTANCE_ENCOUNTERED, - this.delayedInstanceEncountered.bind(this) - ); - - /** - * If we have touch controls - inject them first so we can override editor controls if necessary - */ - this.registerTouchControls(); - - this.registerKeyboardControls(); - - this.registerMouseControls(); - - this.registerEditorControls(); - -}; - -/** - * - */ -GameLib.System.Input.prototype.stop = function() { - - GameLib.System.prototype.stop.call(this); - - this.instanceCreatedSubscription.remove(); - - this.removeComponentSubscription.remove(); - - this.delayedInstanceEncounteredSubscription.remove(); - - this.deRegisterEditorControls(); - - this.deRegisterTouchControls(); - - this.deRegisterKeyboardControls(); - - this.deRegisterMouseControls(); - - this.editorControls = []; - - this.touchControls = []; - - this.keyboardControls = []; - - this.mouseControls = []; - -}; - -/** - * From now on we want to track everything about a component, only from the systems that are active - * @param data - */ -GameLib.System.Input.prototype.instanceCreated = function(data) { - - if (data.component instanceof GameLib.Controls.D3.Editor) { - if (this.editorControls.length > 0) { - console.log('ignoring multiple editor controls') - } else { - this.editorControls.push(data.component); - this.registerEditorControls(); - } - } - - if (data.component instanceof GameLib.Controls.Touch) { - if (this.touchControls.length > 0) { - console.log('ignoring multiple touch controls') - } else { - this.touchControls.push(data.component); - this.registerTouchControls(); - } - } - - if (data.component instanceof GameLib.Controls.Keyboard) { - if (this.keyboardControls.length > 0) { - console.log('ignoring multiple keyboard controls') - } else { - this.keyboardControls.push(data.component); - this.registerKeyboardControls(); - } - } - - if (data.component instanceof GameLib.Controls.Mouse) { - if (this.mouseControls.length > 0) { - console.log('ignoring multiple mouse controls') - } else { - this.mouseControls.push(data.component); - this.registerMouseControls(); - } - } - -}; - -/** - * Removes a particle engine from this system - * @param data - */ -GameLib.System.Input.prototype.removeComponent = function(data) { - - if (data.component instanceof GameLib.Controls.D3.Editor) { - - var index = this.editorControls.indexOf(data.component); - - if (index !== -1) { - - console.log('removing editor controls from system'); - - this.deRegisterEditorControls(); - - this.editorControls.splice(index, 1); - - } else { - console.log('failed to find the editor controls in the system - probably it was ignored - ' + data.component.name); - } - - } - -}; - -/** - * Delayed Instance - we need to check if editControls will block the loading process (since only one will be created) - * @param data - */ -GameLib.System.Input.prototype.delayedInstanceEncountered = function(data) { - - if (data.component instanceof GameLib.Controls.D3.Editor) { - - if (this.editorControls.length === 0) { - /** - * We need to register these controls so instance creation can continue - */ - - this.editorControls.push(data.component); - this.registerEditorControls(); - } else { - /** - * There are already another editor controls, these ones will never get created, we need to - * notify our linking system of this problem so loading can continue - */ - data.component.createInstance(); - } - } - -}; - -GameLib.System.Input.prototype.registerTouchControls = function() { - - if (this.touchControls.length !== 1) { - return; - } - - var touchControl = this.touchControls[0]; - - this.touchSensitivity = touchControl.sensitivity; - - this.touchStart = this.onTouchStart.bind(this); - this.touchMove = this.onTouchMove.bind(this); - this.touchEnd = this.onTouchEnd.bind(this); - this.touchCancel = this.onTouchCancel.bind(this); - - touchControl.domElement.instance.addEventListener( - 'touchstart', - this.touchStart, - false - ); - - touchControl.domElement.instance.addEventListener( - 'touchmove', - this.touchMove, - false - ); - touchControl.domElement.instance.addEventListener( - 'touchend', - this.touchEnd, - false - ); - touchControl.domElement.instance.addEventListener( - 'touchcancel', - this.touchCancel, - false - ); -}; - -GameLib.System.Input.prototype.registerKeyboardControls = function() { - - if (this.keyboardControls.length !== 1) { - return; - } - - var keyboardControl = this.keyboardControls[0]; - - this.keyboardKeyUp = this.onKeyboardKeyUp.bind(this); - this.keyboardKeyDown = this.onKeyboardKeyDown.bind(this); - - keyboardControl.domElement.instance.addEventListener( - 'keyup', - this.keyboardKeyUp, - false - ); - - keyboardControl.domElement.instance.addEventListener( - 'keydown', - this.keyboardKeyDown, - false - ); -}; - -GameLib.System.Input.prototype.registerMouseControls = function() { - - if (this.mouseControls.length !== 1) { - return; - } - - var mouseControl = this.mouseControls[0]; - - this.mouseDown = this.onMouseDown.bind(this); - this.mouseMove = this.onMouseMove.bind(this); - this.mouseWheel = this.onMouseWheel.bind(this); - this.mouseUp = this.onMouseUp.bind(this); - - mouseControl.domElement.instance.addEventListener( - 'mousedown', - this.mouseDown, - false - ); - - mouseControl.domElement.instance.addEventListener( - 'mousemove', - this.mouseMove, - false - ); - mouseControl.domElement.instance.addEventListener( - 'wheel', - this.mouseWheel, - false - ); - - mouseControl.domElement.instance.addEventListener( - 'mouseup', - this.mouseUp, - false - ); -}; - -GameLib.System.Input.prototype.registerEditorControls = function() { - - if (this.editorControls.length !== 1) { - return; - } - - var editorControl = this.editorControls[0]; - - /** - * If we already have mouse controls, we don't want to add another event listener onto the DOM - */ - this.mouseDownEdit = this.onMouseDownEdit.bind(this); - this.mouseMoveEdit = this.onMouseMoveEdit.bind(this); - - editorControl.domElement.instance.addEventListener( - 'mousedown', - this.mouseDownEdit, - false - ); - - editorControl.domElement.instance.addEventListener( - 'mousemove', - this.mouseMoveEdit, - false - ); - - /** - * If we already have keyboard controls, we don't want to add another event listener onto the DOM - */ - if (this.keyboardControls.length > 0) { - /** - * Do Nothing - */ - } else { - - this.keyDown = this.onKeyDown.bind(this); - this.keyUp = this.onKeyUp.bind(this); - - editorControl.domElement.instance.addEventListener( - 'keydown', - this.keyDown, - false - ); - - editorControl.domElement.instance.addEventListener( - 'keyup', - this.keyUp, - false - ); - - } - - editorControl.createInstance(); - - this.mouseWheelEdit = this.onMouseWheelEdit.bind(this); - this.mouseUpEdit = this.onMouseUpEdit.bind(this); - - editorControl.domElement.instance.addEventListener( - 'wheel', - this.mouseWheelEdit, - false - ); - - editorControl.domElement.instance.addEventListener( - 'mouseup', - this.mouseUpEdit, - false - ); - - -}; - -GameLib.System.Input.prototype.deRegisterEditorControls = function() { - - if (this.editorControls.length !== 1) { - return; - } - - var editorControl = this.editorControls[0]; - - editorControl.domElement.instance.removeEventListener( - 'mousedown', - this.mouseDownEdit, - false - ); - - editorControl.domElement.instance.removeEventListener( - 'mousemove', - this.mouseMoveEdit, - false - ); - - if (this.keyboardControls.length < 1) { - editorControl.domElement.instance.removeEventListener( - 'keydown', - this.keyDown, - false - ); - - editorControl.domElement.instance.removeEventListener( - 'keyup', - this.keyUp, - false - ); - } - - editorControl.instance.dispose(); - - editorControl.domElement.instance.removeEventListener( - 'wheel', - this.mouseWheelEdit, - false - ); - - editorControl.domElement.instance.removeEventListener( - 'mouseup', - this.mouseUpEdit, - false - ); - -}; - -GameLib.System.Input.prototype.deRegisterTouchControls = function() { - - if (this.touchControls.length !== 1) { - return; - } - - var touchControl = this.touchControls[0]; - - touchControl.domElement.instance.removeEventListener( - 'touchstart', - this.touchStart, - false - ); - - touchControl.domElement.instance.removeEventListener( - 'touchmove', - this.touchMove, - false - ); - - touchControl.domElement.instance.removeEventListener( - 'touchend', - this.touchEnd, - false - ); - - touchControl.domElement.instance.removeEventListener( - 'touchcancel', - this.touchCancel, - false - ); - -}; - -GameLib.System.Input.prototype.deRegisterKeyboardControls = function() { - - if (this.keyboardControls.length !== 1) { - return; - } - - var keyboardControl = this.keyboardControls[0]; - - keyboardControl.domElement.instance.removeEventListener( - 'keydown', - this.keyboardKeyDown, - false - ); - - keyboardControl.domElement.instance.removeEventListener( - 'keyup', - this.keyboardKeyUp, - false - ); - -}; - - -GameLib.System.Input.prototype.deRegisterMouseControls = function() { - - if (this.mouseControls.length !== 1) { - return; - } - - var mouseControl = this.mouseControls[0]; - - mouseControl.domElement.instance.removeEventListener( - 'mousedown', - this.mouseDown, - false - ); - - mouseControl.domElement.instance.removeEventListener( - 'mousemove', - this.mouseMove, - false - ); - mouseControl.domElement.instance.removeEventListener( - 'wheel', - this.mouseWheel, - false - ); - - mouseControl.domElement.instance.removeEventListener( - 'mouseup', - this.mouseUp, - false - ); - -}; - -GameLib.System.Input.prototype.onKeyboardKeyUp = function(event) { - GameLib.Event.Emit( - GameLib.Event.KEY_DOWN, - { - code : event.code - } - ); - -}; - -GameLib.System.Input.prototype.onKeyboardKeyDown = function(event) { - GameLib.Event.Emit( - GameLib.Event.KEY_UP, - { - code : event.code - } - ); - -}; - -GameLib.System.Input.prototype.onTouchStart = function(event) { - - this.sensitivityCounter = 0; - - this.touches = {}; - - for (var t = 0; t < event.touches.length; t++) { - this.touches[event.touches[t].identifier] = { - left : 0, - right : 0, - up : 0, - down : 0, - lastTouchX : event.touches[t].pageX, - lastTouchY : event.touches[t].pageY, - pageX : event.touches[t].pageX, - pageY : event.touches[t].pageY, - cancelled : false, - ended : false - }; - } - - this.touches.event = event; - - GameLib.Event.Emit( - GameLib.Event.TOUCH_START, - this.touches - ) -}; - -GameLib.System.Input.prototype.onTouchMove = function (event) { - - this.sensitivityCounter++; - - var id = null; - - var leftTouch = null; - var rightTouch = null; - var bottomTouch = null; - var topTouch = null; - - var inward = false; - var outward = false; - var pinch = false; - var zoom = false; - - for (var t = 0; t < event.changedTouches.length; t++) { - - id = event.changedTouches[t].identifier; - - if (this.touches[id]) { - - var diffX = Math.abs(this.touches[id].lastTouchX - event.changedTouches[t].pageX); - var diffY = Math.abs(this.touches[id].lastTouchY - event.changedTouches[t].pageY); - - var left = 0; - var right = 0; - var up = 0; - var down = 0; - - if (this.touches[id].lastTouchX < event.changedTouches[t].pageX) { - right += diffX; - } - - if (this.touches[id].lastTouchX > event.changedTouches[t].pageX) { - left += diffX; - } - - if (this.touches[id].lastTouchY > event.changedTouches[t].pageY) { - up += diffY; - } - - if (this.touches[id].lastTouchY < event.changedTouches[t].pageY) { - down += diffY; - } - - this.touches[id].right = right; - this.touches[id].left = left; - this.touches[id].up = up; - this.touches[id].down = down; - this.touches[id].lastTouchX = event.changedTouches[t].pageX; - this.touches[id].lastTouchY = event.changedTouches[t].pageY; - this.touches[id].pageX = event.changedTouches[t].pageX; - this.touches[id].pageY = event.changedTouches[t].pageY; - } - } - - if (event.changedTouches.length === 2) { - if (event.changedTouches[0].pageX < event.changedTouches[1].pageX) { - leftTouch = this.touches[event.changedTouches[0].identifier]; - rightTouch = this.touches[event.changedTouches[1].identifier]; - } else { - leftTouch = this.touches[event.changedTouches[1].identifier]; - rightTouch = this.touches[event.changedTouches[0].identifier]; - } - - if (event.changedTouches[0].pageY < event.changedTouches[1].pageY) { - bottomTouch = this.touches[event.changedTouches[1].identifier]; - topTouch = this.touches[event.changedTouches[0].identifier]; - } else { - bottomTouch = this.touches[event.changedTouches[0].identifier]; - topTouch = this.touches[event.changedTouches[1].identifier]; - } - } - - if (leftTouch && leftTouch.left && rightTouch && rightTouch.right) { - outward = true; - } - - if (leftTouch && leftTouch.right && rightTouch && rightTouch.left) { - inward = true; - } - - if (bottomTouch && bottomTouch.up && topTouch && topTouch.down) { - pinch = true; - } - - if (bottomTouch && bottomTouch.down && topTouch && topTouch.up) { - zoom = true; - } - - this.touches.event = event; - - this.touches.meta = { - inward : inward, - outward : outward, - pinch : pinch, - zoom : zoom - }; - - if (this.sensitivityCounter >= this.touchSensitivity) { - - this.sensitivityCounter = 0; - - GameLib.Event.Emit( - GameLib.Event.TOUCH_MOVE, - this.touches - ); - - } - -}; - -GameLib.System.Input.prototype.onTouchCancel = function(event) { - - this.sensitivityCounter = 0; - - for (var t = 0; t < event.changedTouches.length; t++) { - this.touches[event.changedTouches[t].identifier].cancelled = true; - this.touches[event.changedTouches[t].identifier].event = event; - GameLib.Event.Emit( - GameLib.Event.TOUCH_CANCEL, - this.touches[event.changedTouches[t].identifier] - ); - delete this.touches[event.changedTouches[t].identifier]; - } -}; - -GameLib.System.Input.prototype.onTouchEnd = function(event) { - - this.sensitivityCounter = 0; - - for (var t = 0; t < event.changedTouches.length; t++) { - this.touches[event.changedTouches[t].identifier].ended = true; - this.touches[event.changedTouches[t].identifier].event = event; - GameLib.Event.Emit( - GameLib.Event.TOUCH_END, - this.touches[event.changedTouches[t].identifier] - ); - delete this.touches[event.changedTouches[t].identifier]; - } -}; - -GameLib.System.Input.prototype.onKeyDown = function(event) { - - console.log('input system emitted keypress ' + event.code); - - GameLib.Event.Emit( - GameLib.Event.KEY_DOWN, - { - code : event.code - } - ); - - var meshes = null; - - if (event.code === 'Delete') { - - meshes = GameLib.EntityManager.Instance.queryComponentsByConstructor(GameLib.D3.Mesh); - - var deletedMeshes = []; - - meshes.map( - function(mesh) { - if (mesh.selected) { - - deletedMeshes.push(mesh); - - mesh.removeHelper(); - - var scene = mesh.parentScene; - scene.removeObject(mesh); - scene.buildIdToObject(); - } - }.bind(this) - ); - - GameLib.Event.Emit( - GameLib.Event.REMOVE_MESH, - { - meshes : deletedMeshes - } - ); - - } - - if (event.code === 'ControlLeft') { - this.controlLeft = true; - } - - if (event.code === 'KeyA') { - - this.selectAll = !this.selectAll; - - meshes = GameLib.EntityManager.Instance.queryComponentsByConstructor(GameLib.D3.Mesh); - - meshes.map(function(mesh){ - if (this.selectAll) { - this.selectMesh(mesh); - } else { - this.deSelectMesh(mesh); - } - }.bind(this)); - - GameLib.Event.Emit( - GameLib.Event.BUILD_GUI, - null - ) - - } - - if (event.code === 'KeyP') { - GameLib.Event.Emit(GameLib.Event.GAME_PAUSE); - } -}; - -GameLib.System.Input.prototype.onKeyUp = function(event) { - - GameLib.Event.Emit( - GameLib.Event.KEY_UP, - { - code : event.code - } - ); - - if (event.code === 'ControlLeft') { - this.controlLeft = false; - } -}; - -GameLib.System.Input.prototype.onMouseDown = function(event) { -// console.log('mouse down'); - - GameLib.Event.Emit( - GameLib.Event.MOUSE_DOWN, - { - event : event - } - ) -}; - -GameLib.System.Input.prototype.onMouseMove = function(event) { -// console.log('mouse move'); - GameLib.Event.Emit( - GameLib.Event.MOUSE_MOVE, - { - event : event - } - ) -}; - -GameLib.System.Input.prototype.onMouseWheel = function(event) { -// console.log('mouse wheel'); - GameLib.Event.Emit( - GameLib.Event.MOUSE_WHEEL, - { - event : event - } - ) -}; - -GameLib.System.Input.prototype.onMouseUp = function(event) { -// console.log('mouse up'); - GameLib.Event.Emit( - GameLib.Event.MOUSE_UP, - { - event : event - } - ) -}; - -GameLib.System.Input.prototype.onMouseDownEdit = function(event) { - - if (event.button === 2) { - - this.editorControls.map( - - function(editorControl) { - - if (this.controlLeft) { - return; - } - - this.mouse.x = (event.offsetX / event.target.width ) * 2 - 1; - this.mouse.y = -(event.offsetY / event.target.height) * 2 + 1; - - var scenes = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.SCENE); - - var intersects = scenes.reduce( - - function (result, scene) { - - editorControl.raycaster.instance.setFromCamera( - this.mouse, - editorControl.camera.instance - ); - - intersects = editorControl.raycaster.getIntersectedObjects(scene.meshes); - - intersects.map(function (intersect) { - result.push(intersect); - }); - - return result; - }.bind(this), - [] - ); - - intersects.sort( - function (a, b) { - if (a.distance < b.distance) { - return -1; - } - - if (a.distance > b.distance) { - return 1; - } - - return 0; - } - ); - - var meshes = intersects.map(function (intersect) { - return intersect.mesh; - }); - - var mesh = meshes[0]; - - if (mesh) { - - /** - * Prevent default action (like context menu or whatever) - */ - event.preventDefault(); - - /** - * Prevent other event listeners for 'mousedown' from executing their actions - */ - event.stopImmediatePropagation(); - - if (mesh.selected) { - this.deSelectMesh(mesh); - } else { - this.selectMesh(mesh); - } - - /** - * Notify our GUI system to build a GUI - */ - GameLib.Event.Emit( - GameLib.Event.BUILD_GUI, - null - ) - } - }.bind(this) - ); - } -}; - -/** - * - * @param event - */ -GameLib.System.Input.prototype.onMouseMoveEdit = function(event) { - -}; - -/** - * Update the camera position etc. after mouse up - * @returns {Function} - * @param event - */ -GameLib.System.Input.prototype.onMouseUpEdit = function(event) { - this.editorControls.map( - function(editorControl) { - editorControl.camera.position.x = editorControl.camera.instance.position.x; - editorControl.camera.position.y = editorControl.camera.instance.position.y; - editorControl.camera.position.z = editorControl.camera.instance.position.z; - - editorControl.camera.quaternion.x = editorControl.camera.instance.quaternion.x; - editorControl.camera.quaternion.y = editorControl.camera.instance.quaternion.y; - editorControl.camera.quaternion.z = editorControl.camera.instance.quaternion.z; - editorControl.camera.quaternion.w = editorControl.camera.instance.quaternion.w; - - editorControl.camera.lookAt.x = editorControl.instance.center.x; - editorControl.camera.lookAt.y = editorControl.instance.center.y; - editorControl.camera.lookAt.z = editorControl.instance.center.z; - editorControl.camera.lookAt.instance.copy(editorControl.instance.center); - } - ); -}; - -/** - * Update our camera position after moving the mouse wheel - * @returns {Function} - * @param event - */ -GameLib.System.Input.prototype.onMouseWheelEdit = function(event) { - this.editorControls.map( - function(editorControl) { - editorControl.camera.position.x = editorControl.camera.instance.position.x; - editorControl.camera.position.y = editorControl.camera.instance.position.y; - editorControl.camera.position.z = editorControl.camera.instance.position.z; - } - ); -}; - -GameLib.System.Input.prototype.selectMesh = function(mesh) { - - /** - * If mesh is already selected, do nothing - */ - if (mesh.selected === true) { - return; - } - - /** - * Notify our component as being 'selected' - * @type {boolean} - */ - mesh.selected = true; - - mesh.createHelper(); - - GameLib.Event.Emit( - GameLib.Event.MESH_SELECTED, - { - mesh : mesh - } - ); -}; - -GameLib.System.Input.prototype.deSelectMesh = function(mesh) { - - mesh.selected = false; - - mesh.removeHelper(); - - GameLib.Event.Emit( - GameLib.Event.MESH_DESELECTED, - { - mesh : mesh - } - ); -}; - - - - - - -// -// console.log('keypressed ' + event.code); -// -// if (event.code === 'KeyV') { -// //todo - change view -// } -// -// -// if (event.code == 'KeyG') { -// if (!this.meshMoveMode) { -// console.log('move mode'); -// this.meshMoveMode = true; -// } -// } -// -// if (event.code == 'KeyX') { -// if (this.meshMoveMode) { -// console.log('move along x'); -// this.meshMoveXMode = true; -// this.meshMoveYMode = false; -// this.meshMoveZMode = false; -// } -// } -// -// if (event.code == 'KeyY') { -// if (this.meshMoveMode) { -// console.log('move along y'); -// this.meshMoveXMode = false; -// this.meshMoveYMode = true; -// this.meshMoveZMode = false; -// } -// } -// -// if (event.code == 'KeyZ') { -// if (this.meshMoveMode) { -// console.log('move along z'); -// this.meshMoveXMode = false; -// this.meshMoveYMode = false; -// this.meshMoveZMode = true; -// } -// } -// -// if (event.code == 'Escape') { -// if (this.meshMoveMode) { -// this.meshMoveMode = false; -// console.log('TODO: implement restore positions'); -// } -// } -// -// if (event.code == 'Enter') { -// if (this.meshMoveMode) { -// this.meshMoveMode = false; -// console.log('TODO: implement apply positions'); -// } -// } -// }; - -// GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity) { -// -// return function(event) { -// -// if (event.button === 2) { -// event.cancelBubble = true; -// -// event.preventDefault(); -// -// if (event.stopPropagation) { -// event.stopPropagation(); -// } -// -// var meshes = entity.queryComponents(GameLib.Component.MESH); -// -// var intersects = this.raycaster.getIntersectedObjects(meshes); -// -// if (intersects.length > 0) { -// -// console.log('object(s) instersected'); -// -// // var index = -1; -// // -// // for (var s = 0; s < this.editor.selectedObjects.length; s++) { -// // if (this.editor.selectedObjects[s].object == intersects[0]) { -// // index = s; -// // break; -// // } -// // } -// // -// // if (index == -1) { -// // /** -// // * The object is not selected, select it -// // */ -// // this.selectObject(intersects[0]); -// // -// // } else { -// // /** -// // * De-select the objec -// // */ -// // var delta = Date.now() - this.editor.selectedObjects[index].lastUpdate; -// // if (delta > this.selectDelayMs) { -// // this.unselectObject(intersects[0]); -// // } -// // } -// // -// // if (this.editor.onSelectionChanged) { -// // this.editor.onSelectionChanged(this.editor); -// // } -// } -// -// return false; -// } -// } -// }; - -// /** -// * Mouse click events -// * @param event -// * @returns {boolean} -// */ -// GameLib.D3.Input.Editor.prototype.onMouseDown = function(event) { -// -// if (event.button === 2) { -// -// -// -// -// -// } -// -// if (event.button == 0) { -// if (this.meshMoveMode) { -// this.meshMoveMode = false; -// this.meshMoveXMode = false; -// this.meshMoveYMode = false; -// this.meshMoveZMode = false; -// } -// } -// }; - -// /** -// * Mouse move events -// * @param event -// */ -// GameLib.D3.Input.Editor.prototype.onMouseMove = function(event) { -// -// // var clientX = event.clientX - this.widthOffset; -// // this.mouse.x = ((clientX / (window.innerWidth - this.widthOffset))) * 2 - 1; -// // this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; -// -// this.mouse.x = event.clientX; -// this.mouse.y = event.clientY; -// -// console.log("mouse (" + this.mouse.x + ", " + this.mouse.y + ")"); -// -// this.raycaster.instance.setFromCamera( -// this.mouse, -// this.camera.instance -// ); -// -// if (this.meshMoveMode) { -// -// var units = event.movementY; -// -// if (this.meshMoveXMode) { -// this.moveSelectedObjects('x', units); -// } -// -// if (this.meshMoveYMode) { -// this.moveSelectedObjects('y', units); -// } -// -// if (this.meshMoveZMode) { -// this.moveSelectedObjects('z', units); -// } -// } -// }; - -// /** -// * Moves selected objects along an axis -// * @param alongAxis -// * @param units -// */ -// GameLib.D3.Input.Editor.prototype.moveSelectedObjects = function(alongAxis, units) { -// -// for (var s = 0; s < this.editor.selectedObjects.length; s++) { -// -// var object = this.editor.selectedObjects[s].object; -// -// if (object.position) { -// if (alongAxis == 'x') { -// object.position.x += units; -// } -// if (alongAxis == 'y') { -// object.position.y += units; -// } -// if (alongAxis == 'z') { -// object.position.z += units; -// } -// -// if (object.updateInstance) { -// object.updateInstance(); -// } -// } -// } -// }; - - -/** - * Linking System takes care of linking components and dependencies (after they have loaded) - - * and managing the relationships between objects - ex. what happens when a parent entity changes, - * or a parent scene changes. - * @param apiSystem GameLib.API.System - * @constructor - */ -GameLib.System.Linking = function( - apiSystem -) { - GameLib.System.call( - this, - apiSystem - ); - - /** - * The dependencies of each component is tracked through this dependencies object - - * it maps the id of the object on which a component depends back to the component which depends on it, - * ex. texture.image = 'abcdefghi', then this.dependencies = {'abcdefghi' : [texture]} - * @type {{}} - */ - this.dependencies = {}; - - this.resolved = []; - - /** - * Components - */ - this.componentCreatedSubscription = null; - this.componentUpdateSubcription = null; - this.componentClonedSubscription = null; - this.registerDependenciesSubscription = null; - this.componentRemoveSubscription = null; - - /** - * Parents - */ - this.parentSceneChangeSubscription = null; - this.parentPhysicsWorldChangeSubscription = null; - this.parentEntityChangeSubscription = null; - - /** - * Instances - */ - this.instanceCreatedSubscription = null; - this.instanceClonedSubscription = null; - - /** - * Meshes - */ - this.removeMeshSubscription = null; - - /** - * Images - */ - this.imageChangedSubscription = null; - - /** - * Materials - */ - this.materialTypeChangedSubscription = null; - - /** - * Arrays - */ - this.arrayItemAddedSubscription = null; - -}; - -GameLib.System.Linking.prototype = Object.create(GameLib.System.prototype); -GameLib.System.Linking.prototype.constructor = GameLib.System.Linking; - -GameLib.System.Linking.prototype.start = function() { - - GameLib.System.prototype.start.call(this); - - /** - * Components - */ - this.componentCreatedSubscription = this.subscribe( - GameLib.Event.COMPONENT_CREATED, - this.componentCreated.bind(this) - ); - - this.componentUpdateSubcription = this.subscribe( - GameLib.Event.COMPONENT_UPDATE, - this.componentUpdate.bind(this) - ); - - this.componentClonedSubscription = this.subscribe( - GameLib.Event.COMPONENT_CLONED, - this.componentCloned.bind(this) - ); - - this.registerDependenciesSubscription = this.subscribe( - GameLib.Event.REGISTER_DEPENDENCIES, - this.registerDependenciesDirect - ); - - this.componentRemoveSubscription = this.subscribe( - GameLib.Event.REMOVE_COMPONENT, - this.removeComponent - ); - - /** - * Parents - */ - this.parentSceneChangeSubscription = this.subscribe( - GameLib.Event.PARENT_SCENE_CHANGE, - this.onParentSceneChange - ); - - this.parentPhysicsWorldChangeSubscription = this.subscribe( - GameLib.Event.PARENT_WORLD_CHANGE, - this.onParentWorldChange - ); - - this.parentEntityChangeSubscription = this.subscribe( - GameLib.Event.PARENT_ENTITY_CHANGE, - this.onParentEntityChange - ); - - /** - * Instances - */ - this.instanceCreatedSubscription = this.subscribe( - GameLib.Event.INSTANCE_CREATED, - this.instanceCreated - ); - - this.instanceClonedSubscription = this.subscribe( - GameLib.Event.INSTANCE_CLONED, - this.instanceCloned - ); - - /** - * Meshes - */ - this.removeMeshSubscription = this.subscribe( - GameLib.Event.REMOVE_MESH, - this.removeMesh - ); - - /** - * Images - */ - this.imageChangedSubscription = this.subscribe( - GameLib.Event.IMAGE_CHANGED, - this.imageChanged - ); - - /** - * Materials - */ - this.materialTypeChangedSubscription = this.subscribe( - GameLib.Event.MATERIAL_TYPE_CHANGED, - this.materialTypeChanged - ); - - /** - * Arrays - */ - this.arrayItemAddedSubscription = this.subscribe( - GameLib.Event.ARRAY_ITEM_ADDED, - this.arrayItemAdded - ); - -}; - -GameLib.System.Linking.prototype.link = function(component, data) { - for (var property in component.linkedObjects) { - if (component.linkedObjects.hasOwnProperty(property)) { - if (component.linkedObjects[property] instanceof Array) { - - var linked = []; - - component[property] = component[property].map(function (entry) { - if (entry === data.component.id) { - - linked.push({ - parent : component, - property : property, - child : data.component - }); - - return data.component; - } else { - return entry; - } - }); - - linked.map(function(link) { - GameLib.Event.Emit( - GameLib.Event.COMPONENT_LINKED, - link - ); - }) - - } else { - if (component[property] && - component[property] === data.component.id) { - component[property] = data.component; - - GameLib.Event.Emit( - GameLib.Event.COMPONENT_LINKED, - { - parent : component, - property : property, - child : data.component - } - ); - } - } - } - } -}; - -GameLib.System.Linking.prototype.resolveDependencies = function(component) { - - if (!component.loaded) { - /** - * This component has not fully loaded - we should resolve dependencies to it later - */ - return false; - } - - /** - * Now find all the components which depend on this component - */ - var parentComponents = this.dependencies[component.id]; - - /** - * If we don't have any components which depend on this component, simply return - */ - if (GameLib.Utils.UndefinedOrNull(parentComponents)) { - - /** - * We don't know about components which depend on this component - but it could still load. - * However, it is stored in the register and dependency list for later use - */ - return false; - } - - /** - * Otherwise, process them all - */ - parentComponents.map( - - function (parentComponent) { - - /** - * Link the parent component to this component - */ - this.link(parentComponent, {component: component}); - - /** - * We record that we linked a child component to a parent component - */ - GameLib.Utils.PushUnique(this.resolved, component); - - /** - * First check if the dependencies have already been met - */ - if ( - GameLib.Utils.UndefinedOrNull(parentComponent.dependencies) || - ( - parentComponent.dependencies instanceof Array && - parentComponent.dependencies.length === 0 - ) - ) { - - /** - * This means - a parent component instance could maybe have been delayed to be created - * because the component constructor or linking system did not know at time of 'createInstance' - * that it required another object to fully become active - */ - if ( - !parentComponent.loaded || - GameLib.Utils.UndefinedOrNull(parentComponent.instance) - ) { - - try { - - parentComponent.performInstanceCreation(); - - } catch (error) { - console.error(error); - } - - } else { - /** - * These dependencies have already been met - the parentComponent properties have changed. - * It is time to 'update' this instance with this information (if any of it is relevant - depends - * on the component) - */ - // parentComponent.updateInstance(); - } - - } else { - - /** - * Remove the actual dependency - */ - var index = parentComponent.dependencies.indexOf(component.id); - if (index !== -1) { - parentComponent.dependencies.splice(index, 1); - } - - /** - * If we now managed to link the objects, and this object has no more dependencies - */ - if (parentComponent.dependencies.length === 0) { - parentComponent.performInstanceCreation(); - } - } - - }.bind(this) - ); - - /** - * We now linked all the components which depends on this component, to this component. Time to cleanup our - * dependencies - */ - delete this.dependencies[component.id]; - - /** - * For now this essentially only notifies the Editor - We have some more work to do however - */ - GameLib.Event.Emit( - GameLib.Event.UNRESOLVED_DEPENDENCIES_UPDATE, - { - dependencies : this.dependencies - } - ); - - /** - * If we happen to have no more dependencies - we linked a bunch of components which are ready to use - */ - if (GameLib.Utils.IsEmpty(this.dependencies)) { - - /** - * This also only notifies the Editor - We still have some more work to here - */ - GameLib.Event.Emit( - GameLib.Event.COMPONENTS_LINKED, - { - components: this.resolved.map( - function(component) { - return component; - } - ) - } - ); - - this.resolved = []; - - } - //else { - - // var keys = Object.keys(this.dependencies); - - /** - * And this is it - we need to check if the dependencies array contains any 'resolved' components - - * If it does - resolve the dependencies of this newly 'resolved' component - */ - // this.resolved = this.resolved.reduce( - // - // function(result, component) { - // - // if (keys.indexOf(component.id) !== -1) { - // /** - // * We found a resolved component - which is a dependency for another component. - // * Resolve the dependencies of this component - this is recursive and should be done carefully - // */ - // this.resolveDependencies(component); - // } else { - // result.push(component); - // } - // - // return result; - // - // }.bind(this), - // [] - // ); - //} - -}; - -GameLib.System.Linking.prototype.registerDependencies = function(component) { - - /** - * We only care about components with unloaded dependencies - - * other components will have already had their instance objects created - */ - if (component.dependencies && - component.dependencies.length > 0) { - - component.dependencies = component.dependencies.reduce( - - function(result, id) { - - /** - * Check if we already processed a component on which this component is dependent - */ - var processedComponent = GameLib.EntityManager.Instance.findComponentById(id); - - if (processedComponent && processedComponent.loaded) { - - /** - * Link the component - */ - this.link(component, {component: processedComponent}); - - GameLib.Utils.PushUnique(this.resolved, processedComponent); - - } else { - - /** - * Create a new link if none exists - */ - if (GameLib.Utils.UndefinedOrNull(this.dependencies[id])) { - this.dependencies[id] = []; - } - - /** - * Don't store duplicate dependencies - */ - if (this.dependencies[id].indexOf(component) === -1) { - this.dependencies[id].push(component); - GameLib.Event.Emit( - GameLib.Event.UNRESOLVED_DEPENDENCIES_UPDATE, - { - dependencies : this.dependencies - } - ); - } - - /** - * Also - we remember that this component has a dependency - */ - result.push(id); - } - - return result; - - }.bind(this), - [] - ); - - if (component.dependencies.length === 0) { - component.performInstanceCreation(); - } - } -}; - -/** - * When a component is created, register its dependencies, and try to resolve them - * @param data - */ -GameLib.System.Linking.prototype.componentCreated = function(data) { - - /** - * Shorthand - */ - var component = data.component; - - /** - * Register any dependencies of this component - */ - this.registerDependencies(component); - - /** - * Resolve any dependencies to this component - */ - this.resolveDependencies(component); - -}; - -/** - * Trigger a component update - * @param data - */ -GameLib.System.Linking.prototype.componentUpdate = function(data){ - - var component = GameLib.EntityManager.Instance.findComponentByName(data.name); - - if (GameLib.Utils.UndefinedOrNull(data.property)) { - console.warn('invalid data format - we expect data.property'); - return; - } - - if (GameLib.Utils.UndefinedOrNull(data.value)) { - console.warn('invalid data format - we expect data.value'); - return; - } - - if (GameLib.Utils.UndefinedOrNull(data.subProperty)) { - component[data.property] = data.value; - } else { - component[data.property][data.subProperty] = data.value; - } - - component.updateInstance(data.property); -}; - -GameLib.System.Linking.prototype.componentCloned = function(data) { - - this.componentCreated(data); - - if (data.component instanceof GameLib.D3.Mesh) { - - if (!(data.parent instanceof GameLib.D3.Mesh)){ - throw new Error('no scene parent'); - } - - if (data.parent.parentScene) { - data.parent.parentScene.addClone(data.component); - } - } - -}; - -/** - * When you want to register dependencies directly - Component constructor does this when it knows the - * component instance cannot be created because it has a bunch of dependencies. So it tells the linking - * system about it, so the linking system can create the instance when the dependency loads or already exists - * @param data - */ -GameLib.System.Linking.prototype.registerDependenciesDirect = function(data) { - this.registerDependencies(data.component); -}; - -GameLib.System.Linking.prototype.removeComponent = function(data) { - - if (!data.component) { - console.error('no component to remove'); - return; - } - - var component = data.component; - - if (component.parentEntity instanceof GameLib.Entity) { - component.parentEntity.removeComponent(component); - } - - if (component instanceof GameLib.D3.Mesh && - component.parentScene instanceof GameLib.D3.Scene) { - - component.removeHelper(); - - component.parentScene.removeObject(component); - } - - if (component instanceof GameLib.D3.Light && - component.parentScene instanceof GameLib.D3.Scene) { - component.parentScene.removeObject(component); - } - - if (component instanceof GameLib.Entity) { - GameLib.EntityManager.Instance.removeEntity(component); - } - - // if (component instanceof GameLib.D3.Particle) { - // // component.mesh.parentScene.removeObject(component.mesh); - // } -}; - -GameLib.System.Linking.prototype.imageChanged = function(data) { - - var materials = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.MATERIAL); - - materials.map(function(material){ - - var textures = material.getTextures(); - - if (textures.indexOf(data.texture) !== -1) { - material.updateInstance('diffuseMap'); - } - - }); - -}; - -GameLib.System.Linking.prototype.arrayItemAdded = function(data) { - if ( - data.component instanceof GameLib.D3.PhysicsWorld && - data.item instanceof GameLib.D3.RigidBody - ) { - data.component.addRigidBody(data.item); - } - - if (data.component instanceof GameLib.D3.Mesh && - data.item instanceof GameLib.D3.Material - ) { - data.component.addMaterial(data.item); - } -}; - -GameLib.System.Linking.prototype.instanceCloned = function(data) { - - // if (data.component instanceof GameLib.D3.Particle) { - // - // var mesh = data.component.mesh; - // - // if (mesh.parentScene && mesh.parentScene.instance) { - // data.instance.userData.scene = mesh.parentScene.instance; - // mesh.parentScene.instance.add(data.instance); - // } - // } - -}; - -GameLib.System.Linking.prototype.instanceCreated = function(data) { - - this.resolveDependencies(data.component); - - if (data.component instanceof GameLib.Image) { - /** - * Find all textures which use this image - */ - GameLib.EntityManager.Instance.queryComponents(GameLib.Component.TEXTURE).map( - function(texture) { - if (texture.image === data.component || - texture.images.indexOf(data.component) !== -1 - ) { - - /** - * Ok - this image is in use - this should notify materials when its image changes - */ - texture.updateInstance('image'); - } - } - ); - } - - /** - * Link all scenes - */ - if (data.component instanceof GameLib.D3.Scene) { - /** - * Check ALL components for 'parentScenes' - this is expensive so it checks the register directly - */ - - Object.keys(GameLib.EntityManager.Instance.idRegister).map( - function(componentId) { - if (GameLib.EntityManager.Instance.idRegister[componentId].parentScene === data.component.id) { - GameLib.EntityManager.Instance.idRegister[componentId].parentScene = data.component; - } - } - ); - } - - if ( - data.component.parentScene && - typeof data.component.parentScene === 'string' - ) { - GameLib.EntityManager.Instance.queryComponents(GameLib.Component.SCENE).map( - function (scene) { - if (data.component.parentScene === scene.id) { - data.component.parentScene = scene; - scene.addObject(data.component); - } - } - ); - } - - if ( - data.component.parentEngine && - typeof data.component.parentEngine === 'string' - ) { - GameLib.EntityManager.Instance.queryComponents(GameLib.Component.PARTICLE_ENGINE).map( - function (particleEngine) { - if (data.component.parentEngine === particleEngine.id) { - data.component.parentEngine = particleEngine; - } - } - ); - } - - /** - * Link all meshes - */ - if (data.component instanceof GameLib.D3.Mesh) { - - /** - * Check if this mesh is a parentMesh to any component- this is an expensive call, so check if we should call it - * Also - it inspects the register directly instead of querying it twice (since it checks ALL components) - */ - if (!data.preventParentMeshCheck) { - - Object.keys(GameLib.EntityManager.Instance.idRegister).map( - function(componentId) { - if (GameLib.EntityManager.Instance.idRegister[componentId].parentMesh === data.component.id) { - GameLib.EntityManager.Instance.idRegister[componentId].parentMesh = data.component; - - /** - * Check if a component has this mesh as a parent - */ - if (GameLib.EntityManager.Instance.idRegister[componentId] instanceof GameLib.D3.Mesh) { - GameLib.EntityManager.Instance.idRegister[componentId].setParentMesh(data.component); - } - } - } - ); - - } - - } - - /** - * Maybe this component has a parent mesh - */ - if ( - data.component.parentMesh && - typeof data.component.parentMesh === 'string' - ) { - GameLib.EntityManager.Instance.queryComponents(GameLib.Component.MESH).map( - function (mesh) { - if (data.component.parentMesh === mesh.id) { - - data.component.parentMesh = mesh; - - if (data.component instanceof GameLib.D3.Mesh) { - data.component.setParentMesh(mesh); - } - } - } - ); - } - - if ( - data.component.parentPhysicsWorld && - typeof data.component.parentPhysicsWorld === 'string' - ) { - GameLib.EntityManager.Instance.queryComponents(GameLib.Component.PHYSICS_WORLD).map( - function (world) { - if (data.component.parentPhysicsWorld === world.id) { - data.component.parentPhysicsWorld = world; - - if (typeof data.component.instance.addToWorld === 'function') { - data.component.instance.addToWorld(world.instance); - console.log('instance added to physics world'); - } - } - } - ); - } - -}; - -GameLib.System.Linking.prototype.materialTypeChanged = function(data) { - - var meshes = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.MESH); - - meshes.map( - function(mesh){ - var inUse = mesh.materials.reduce( - function(result, material) { - if (material === data.material) { - result = true; - } - return result; - }, - false - ); - - if (inUse) { - - if (mesh.materials.length === 1) { - mesh.instance.material = mesh.materials[0].instance - } else { - mesh.instance.material = mesh.materials.map( - function(material) { - return material.instance; - } - ) - } - - mesh.instance.geometry.uvsNeedUpdate = true; - mesh.instance.material.needsUpdate = true; - } - - } - ); - -}; - -/** - * - * @param data - */ -GameLib.System.Linking.prototype.onParentWorldChange = function(data) { - - if ( - data.object instanceof GameLib.D3.RigidBody - ) { - - - if (data.originalWorld instanceof GameLib.D3.PhysicsWorld) { - data.originalWorld.removeRigidBody(data.object); - } - - if (data.newWorld instanceof GameLib.D3.PhysicsWorld) { - data.newWorld.addRigidBody(data.object); - } - } - -}; - -/** - * Defines what should happen when a parent scene changes - * @param data - */ -GameLib.System.Linking.prototype.onParentSceneChange = function(data) { - - if ( - data.object instanceof GameLib.D3.Mesh || - data.object instanceof GameLib.D3.Light - ) { - - /** - * We remove the helper (if any) from the old scene and add it to the new scene - */ - var helper = GameLib.EntityManager.Instance.findHelperByObject(data.object); - if (helper) { - - if (data.originalScene && data.originalScene.instance) { - data.originalScene.instance.remove(helper.instance); - } - data.newScene.instance.add(helper.instance); - } - - /** - * We remove the mesh from the old scene and add it to the new scene - */ - if (data.originalScene && data.originalScene.removeObject) { - data.originalScene.removeObject(data.object); - } - - if (data.newScene) { - data.newScene.addObject(data.object); - } - } - -}; - -/** - * Change parent entity - * @param data - */ -GameLib.System.Linking.prototype.onParentEntityChange = function(data) { - - if (data.originalEntity instanceof GameLib.Entity) { - data.originalEntity.removeComponent(data.object); - } - - if (data.newEntity instanceof GameLib.Entity) { - data.newEntity.addComponent(data.object); - } - - GameLib.Event.Emit( - GameLib.Event.PARENT_ENTITY_CHANGED, - { - originalEntity : data.originalEntity, - newEntity : data.newEntity, - component : data.object - } - ) -}; - -/** - * When a mesh is deleted - build a list of all the mesh children objects - also - find out if any of these - * children objects are in use by another object - if it is - don't delete it, otherwise, do - * @param data - */ -GameLib.System.Linking.prototype.removeMesh = function(data) { - - /** - * First we get the list of all components we would like to delete - */ - var componentsToDelete = data.meshes.reduce( - function(result, mesh) { - - result.push(mesh); - - var components = mesh.getChildrenComponents(); - - components.map(function(component){ - result.push(component); - }); - - return result; - }, - [] - ); - - /** - * Now, we want to get a list of all the meshes which we don't want to delete, and all their children - */ - var meshes = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.MESH); - meshes = meshes.filter(function(mesh){ - return data.meshes.indexOf(mesh) === -1; - }); - - /** - * Now we have a list of meshes still in use in meshes, now find all their children - */ - var componentsInUse = meshes.reduce( - function(result, mesh) { - - result.push(mesh); - - var components = mesh.getChildrenComponents(); - - components.map(function(component){ - result.push(component); - }); - - return result; - }, - [] - ); - - /** - * Now we don't want to remove any children in use, so filter out the components in use - */ - componentsToDelete = componentsToDelete.filter( - function(component) { - return componentsInUse.indexOf(component) === -1; - } - ); - - /** - * componentsToDelete should now be the final list of components to delete - */ - componentsToDelete.map( - function(component){ - component.remove(); - } - ); -}; - -GameLib.System.Linking.prototype.stop = function() { - GameLib.System.prototype.stop.call(this); - /** - * Components - */ - this.componentCreatedSubscription.remove(); - this.componentUpdateSubcription.remove(); - this.componentClonedSubscription.remove(); - this.registerDependenciesSubscription.remove(); - this.componentRemoveSubscription.remove(); - - /** - * Parents - */ - this.parentSceneChangeSubscription.remove(); - this.parentPhysicsWorldChangeSubscription.remove(); - this.parentEntityChangeSubscription.remove(); - - /** - * Instances - */ - this.instanceCreatedSubscription.remove(); - this.instanceClonedSubscription.remove(); - - /** - * Meshes - */ - this.removeMeshSubscription.remove(); - - /** - * Images - */ - this.imageChangedSubscription.remove(); - - /** - * Materials - */ - this.materialTypeChangedSubscription.remove(); - - /** - * Arrays - */ - this.arrayItemAddedSubscription.remove(); -}; - - -/** - * System takes care of updating all the entities (based on their component data) - * @param apiSystem GameLib.API.System - * @constructor - */ -GameLib.System.Particle = function( - apiSystem -) { - GameLib.System.call( - this, - apiSystem - ); - - /** - * this holds a reference to engine components and does some initial setup work so we don't have to do it during render - * like calculate frequency etc.. - * @type {Array} - */ - this.engines = []; - - this.totalTime = 0; - - this.instanceCreatedSubscription = null; - - this.removeComponentSubscription = null; - - this.beforeRenderSubscription = null; -}; - -GameLib.System.Particle.prototype = Object.create(GameLib.System.prototype); -GameLib.System.Particle.prototype.constructor = GameLib.System.Particle; - -/** - * Start this system (add all event listeners) - */ -GameLib.System.Particle.prototype.start = function() { - - GameLib.System.prototype.start.call(this); - - this.particleEngines = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.PARTICLE_ENGINE); - - this.instanceCreatedSubscription = GameLib.Event.Subscribe( - GameLib.Event.INSTANCE_CREATED, - this.instanceCreated.bind(this) - ); - - this.removeComponentSubscription = GameLib.Event.Subscribe( - GameLib.Event.REMOVE_COMPONENT, - this.removeComponent.bind(this) - ); - - this.beforeRenderSubscription = GameLib.Event.Subscribe( - GameLib.Event.BEFORE_RENDER, - this.beforeRender.bind(this) - ); - -}; - -/** - * From now on we want to track everything about a component, only from the systems that are active - * @param data - */ -GameLib.System.Particle.prototype.instanceCreated = function(data) { - if (data.component instanceof GameLib.D3.ParticleEngine) { - this.particleEngines.push(data.component); - } -}; - -/** - * Removes a particle engine from this system - * @param data - */ -GameLib.System.Particle.prototype.removeComponent = function(data) { - - if (data.component instanceof GameLib.D3.ParticleEngine) { - - var index = this.particleEngines.indexOf(data.component); - - if (index !== -1) { - // console.log('removing particle engine from system' + data.component.name); - - this.particleEngines.splice(index, 1); - - } else { - // console.log('failed to find the particle engine in the system : ' + data.component.name); - } - } - -}; - -/** - * This is what actually happens to all particles before render - * @param data - */ -GameLib.System.Particle.prototype.beforeRender = function(data) { - - this.totalTime += data.delta; - - this.particleEngines.map( - function(particleEngine) { - - if ( - GameLib.Utils.UndefinedOrNull(particleEngine.camera) || - GameLib.Utils.UndefinedOrNull(particleEngine.templateParticle) || - GameLib.Utils.UndefinedOrNull(particleEngine.templateParticle.mesh) || - GameLib.Utils.UndefinedOrNull(particleEngine.templateParticle.mesh.parentScene) || - GameLib.Utils.UndefinedOrNull(particleEngine.templateParticle.mesh.parentScene.instance)) { - return; - } - - particleEngine.elapsed += data.delta; - - particleEngine.particles = particleEngine.particles.reduce( - - function(result, particle){ - - var speed = particle.userData.speed; - - if (particle.userData.speedType === GameLib.D3.Particle.SPEED_TYPE_CONSTANT) { - speed = data.delta * particle.userData.speed; - } - - if (particle.userData.speedType === GameLib.D3.Particle.SPEED_TYPE_LINEAR) { - speed = data.delta * particle.userData.speed; - particle.userData.speed += speed; - } - - if (particle.userData.speedType === GameLib.D3.Particle.SPEED_TYPE_EXPONENTIAL) { - speed = Math.pow(particle.userData.speed, 2) * data.delta; - particle.userData.speed += speed; - } - - if (particle.userData.speedType === GameLib.D3.Particle.SPEED_TYPE_LOGARITHMIC) { - speed = Math.log(particle.userData.speed) * data.delta; - particle.userData.speed += speed; - } - - if (particle.userData.speedType === GameLib.D3.Particle.SPEED_TYPE_ONE_OVER_LOG) { - speed = 1 / Math.log(particle.userData.speed) * data.delta; - particle.userData.speed += speed; - } - - if (particle.userData.speedType === GameLib.D3.Particle.SPEED_TYPE_EXP) { - speed = Math.exp(particle.userData.speed) * data.delta; - particle.userData.speed += speed; - } - - if (particle.userData.speedType === GameLib.D3.Particle.SPEED_TYPE_ONE_OVER_EXP) { - speed = 1 / Math.exp(particle.userData.speed) * data.delta; - particle.userData.speed += speed; - } - - particle.position.x += particle.userData.direction.x * speed; - particle.position.y += particle.userData.direction.y * speed; - particle.position.z += particle.userData.direction.z * speed; - - if (particleEngine.templateParticle.scaleType === GameLib.D3.Particle.SCALE_TYPE_CONSTANT) { - /** - * Do nothing - scale should already be set - */ - /* particle.scale.x = particle.userData.scale.x; - particle.scale.y = particle.userData.scale.y; - particle.scale.z = particle.userData.scale.z; - */ - } - - if (particleEngine.templateParticle.scaleType === GameLib.D3.Particle.SCALE_TYPE_LINEAR) { - particle.scale.x += particle.userData.scale.x * data.delta; - particle.scale.y += particle.userData.scale.x * data.delta; - particle.scale.z += particle.userData.scale.x * data.delta; - } - - particle.quaternion.copy(particleEngine.camera.instance.quaternion); - - if (particleEngine.templateParticle.opacityType === GameLib.D3.Particle.OPACITY_TYPE_INCREASE_LINEAR) { - particle.material.opacity += particleEngine.templateParticle.opacityFactor; - } - - if (particleEngine.templateParticle.opacityType === GameLib.D3.Particle.OPACITY_TYPE_DECREASE_LINEAR) { - particle.material.opacity -= particleEngine.templateParticle.opacityFactor; - } - - particle.userData.elapsed += data.delta; - if ( - particle.userData.elapsed > particle.userData.lifeTime || - particle.material.opacity < 0 - ) { - particle.userData.scene.remove(particle); - particle.geometry.dispose(); - //particle.material.map.dispose(); - particle.material.dispose(); - } else { - result.push(particle); - } - - return result; - }, - [] - ); - - if (particleEngine.disabledForRemoval && particleEngine.particles.length === 0) { - GameLib.Event.Emit( - GameLib.Event.REMOVE_PARTICLE_ENGINE, - { - component : particleEngine - } - ) - } - - if (particleEngine.enabled && !particleEngine.disabledForRemoval) { - - var instanceClone = null; - - if (particleEngine.pulse) { - - if (particleEngine.particles.length === 0) { - - particleEngine.elapsed = 0; - - /** - * This is a 'pulse' engine - so spawn all the particles at once and spawn again when all particles - * are gone - */ - for (var i = 0; i < particleEngine.particlesPerSecond; i++) { - instanceClone = particleEngine.templateParticle.cloneInstance(); - particleEngine.particles.push(instanceClone); - } - - } - - } else { - - /** - * This is a 'stream' engine - spawn particles one at a time when its time to do so - */ - if (particleEngine.elapsed > particleEngine.frequency) { - - particleEngine.elapsed = 0; - - instanceClone = particleEngine.templateParticle.cloneInstance(); - particleEngine.particles.push(instanceClone); - } - } - } - - }.bind(this) - ) - -}; - - -/** - * Stop this system (remove all event listeners) - */ -GameLib.System.Particle.prototype.stop = function() { - - GameLib.System.prototype.stop.call(this); - - this.instanceCreatedSubscription.remove(); - this.removeComponentSubscription.remove(); - this.beforeRenderSubscription.remove(); - -}; - -/** - * System takes care of updating all the entities (based on their component data) - * @param apiSystem GameLib.API.System - * @constructor - */ -GameLib.System.Physics = function( - apiSystem -) { - - GameLib.System.call( - this, - apiSystem - ); - - this.worlds = []; - // this.rigidBodies = []; - // this.wheels = []; - // this.vehicles = []; - - // this.worldSubscription = null; - // this.rigidBodySubscription = null; - this.beforeRenderSubscription = null; - this.afterRenderSubscription = null; - - - - -}; - -GameLib.System.Physics.prototype = Object.create(GameLib.System.prototype); -GameLib.System.Physics.prototype.constructor = GameLib.System.Physics; - -GameLib.System.Physics.prototype.start = function() { - - GameLib.System.prototype.start.call(this); - - this.worlds = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.PHYSICS_WORLD); - // this.rigidBodies = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.RIGID_BODY); - // this.wheels = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.RAYCAST_WHEEL); - // this.vehicles = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.RAYCAST_VEHICLE); - - - - // this.worlds.map( - // function(world) { - // world.instance.addEventListener( - // 'postStep', - // function() { - // - // this.vehicles.map( - // function(vehicle) { - // vehicle.instance.wheelInfos.map( - // function(wheelInfo, index) { - // vehicle.instance.updateWheelTransform(index); - // var t = wheelInfo.worldTransform; - // // vehicle.wheels[index].instance.position.copy(t.position); - // // vehicle.wheels[index].instance.quaternion.copy(t.quaternion); - // - // // vehicle.raycastWheels[index].parentMesh.localPosition.x = t.position.x; - // // vehicle.raycastWheels[index].parentMesh.localPosition.y = t.position.y; - // // vehicle.raycastWheels[index].parentMesh.localPosition.z = t.position.z; - // - // // vehicle.raycastWheels[index].parentMesh.updateInstance(); - // } - // ); - // } - // ); - // - // - // }.bind(this) - // ) - // }.bind(this) - // ); - - this.beforeRenderSubscription = this.subscribe( - GameLib.Event.BEFORE_RENDER, - this.beforeRender - ); -}; - -/** - * Update script - */ -GameLib.System.Physics.prototype.beforeRender = function(data) { - - this.worlds.map( - function(world) { - - if (world.instance) { - - world.instance.step(data.delta); - - world.rigidBodies.map( - function(rigidBody){ - rigidBody.position.x = rigidBody.instance.position.x; - rigidBody.position.y = rigidBody.instance.position.y; - rigidBody.position.z = rigidBody.instance.position.z; - - rigidBody.quaternion.x = rigidBody.instance.quaternion.x; - rigidBody.quaternion.y = rigidBody.instance.quaternion.y; - rigidBody.quaternion.z = rigidBody.instance.quaternion.z; - rigidBody.quaternion.w = rigidBody.instance.quaternion.w; - - rigidBody.parentMesh.position.x = rigidBody.instance.position.x; - rigidBody.parentMesh.position.y = rigidBody.instance.position.y; - rigidBody.parentMesh.position.z = rigidBody.instance.position.z; - - rigidBody.parentMesh.quaternion.x = rigidBody.instance.quaternion.x; - rigidBody.parentMesh.quaternion.y = rigidBody.instance.quaternion.y; - rigidBody.parentMesh.quaternion.z = rigidBody.instance.quaternion.z; - rigidBody.parentMesh.quaternion.w = rigidBody.instance.quaternion.w; - - rigidBody.instance.getVelocityAtWorldPoint(new CANNON.Vec3(0,0,0), rigidBody.velocity.instance); - - rigidBody.velocity.x = rigidBody.velocity.instance.x; - rigidBody.velocity.y = rigidBody.velocity.instance.y; - rigidBody.velocity.z = rigidBody.velocity.instance.z; - - rigidBody.parentMesh.updateRotationFromAxisAngle = false; - - rigidBody.parentMesh.updateInstance(); - - rigidBody.parentMesh.updateRotationFromAxisAngle = true; - } - ) - } - - }.bind(this) - ); -}; - - -GameLib.System.Physics.prototype.stop = function() { - - GameLib.System.prototype.stop.call(this); - - this.worlds = []; - this.rigidBodies = []; - this.wheels = []; - this.vehicles = []; - - if (this.beforeRenderSubscription) { - this.beforeRenderSubscription.remove(); - } - - if (this.afterRenderSubscription) { - this.afterRenderSubscription.remove(); - } - -}; - - -/** - * System takes care of updating all the entities (based on their component data) - * @param apiSystem GameLib.API.System - * @param graphicsRuntime - * @constructor - */ -GameLib.System.Render = function( - apiSystem, - graphicsRuntime -) { - - GameLib.System.call( - this, - apiSystem - ); - - this.renderSubscription = null; - - this.clock = new GameLib.Clock(graphicsRuntime); - - this.delta = null; - - this.animationFrameHook = null; - -}; - -GameLib.System.Render.prototype = Object.create(GameLib.System.prototype); -GameLib.System.Render.prototype.constructor = GameLib.System.Render; - -/** - * Start the rendering system - */ -GameLib.System.Render.prototype.start = function() { - - GameLib.System.prototype.start.call(this); - - this.renderers = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.RENDERER); - - this.statistics = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.STATS); - - this.instanceCreatedSubscription = GameLib.Event.Subscribe( - GameLib.Event.INSTANCE_CREATED, - this.instanceCreated.bind(this) - ); - - this.removeComponentSubscription = GameLib.Event.Subscribe( - GameLib.Event.REMOVE_COMPONENT, - this.removeComponent.bind(this) - ); - - this.renderSubscription = this.subscribe( - GameLib.Event.RENDER, - this.render - ); - - this.windowResizeSubscription = this.subscribe( - GameLib.Event.WINDOW_RESIZE, - this.windowResize - ); - - window.addEventListener( - 'resize', - this.nativeWindowResize, - false - ); - - GameLib.Event.Emit( - GameLib.Event.WINDOW_RESIZE, - { - width : window.innerWidth, - height : window.innerHeight - } - ); - - this.run(); - -}; - -GameLib.System.Render.prototype.run = function() { - - this.animationFrameHook = requestAnimationFrame( this.run.bind(this) ); - - this.delta = this.clock.getDelta(); - - GameLib.Event.Emit( - GameLib.Event.RENDER, - { - delta : this.delta - } - ); - -}; - -GameLib.System.Render.prototype.nativeWindowResize = function() { - GameLib.Event.Emit( - GameLib.Event.WINDOW_RESIZE, - { - width : window.innerWidth, - height : window.innerHeight - } - ); -}; - -GameLib.System.Render.prototype.windowResize = function(data) { - - var aspect = (data.width / data.height); - - var cameras = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.CAMERA); - - cameras.map(function(camera){ - camera.aspect = aspect; - camera.updateInstance('aspect'); - }); - - var renderers = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.RENDERER); - - renderers.map( - function(renderer) { - renderer.setSize( - data.width, - data.height - ); - } - ); - - GameLib.Event.Emit( - GameLib.Event.CUSTOM_CODE_WINDOW_RESIZE, - { - aspect : aspect, - width : data.width, - height : data.height - } - ); - -}; - -/** - * From now on we want to track everything about a component, only from the systems that are active - * @param data - */ -GameLib.System.Render.prototype.instanceCreated = function(data) { - - if (data.component instanceof GameLib.D3.Renderer) { - this.renderers.push(data.component); - } - - if (data.component instanceof GameLib.Stats) { - this.statistics.push(data.component); - } -}; - -/** - * Removes a particle engine from this system - * @param data - */ -GameLib.System.Render.prototype.removeComponent = function(data) { - - if (data.component instanceof GameLib.D3.Renderer) { - - var index = this.renderers.indexOf(data.component); - - if (index !== -1) { - console.log('removing renderer from system'); - - this.renderers.splice(index, 1); - - } else { - console.log('failed to find the renderer in the system : ' + data.component.name); - } - } - -}; - -/** - * Render subscription script - */ -GameLib.System.Render.prototype.render = function(data) { - - if (this.statistics) { - this.statistics.map( - function (statistics) { - statistics.start(); - } - ); - } - - GameLib.Event.Emit( - GameLib.Event.BEFORE_RENDER, - data - ); - - if (this.renderers.length < 1) { - /** - * Do nothing - */ - } else if (this.renderers.length === 1) { - /** - * Quite simple - we have a renderer - it wants to render its stuff - */ - this.renderers[0].render(data.delta); - - } else { - - /** - * If we have multiple renderers, we have a problem - they don't share the same webGL context - - * So, we need to get their scenes and render them individually instead of trying to have both renderers render - * to the same canvas (sharing the same webgl context does not work) - */ - var scenes = this.renderers.reduce( - function(result, renderer) { - renderer.scenes.map( - function(scene){ - result.push(scene); - } - ); - return result; - }, - [] - ); - - var renderer = GameLib.EntityManager.Instance.defaultRenderer; - - if (GameLib.Utils.UndefinedOrNull(renderer)) { - /** - * No default renderer, using first one - */ - renderer = this.renderers[0]; - } - - renderer.render(data.delta, scenes); - - } - - GameLib.Event.Emit( - GameLib.Event.AFTER_RENDER, - data - ); - - if (this.statistics) { - this.statistics.map( - function (statistics) { - statistics.end(); - } - ); - } -}; - -/** - * Stop the rendering system - */ -GameLib.System.Render.prototype.stop = function() { - - GameLib.System.prototype.stop.call(this); - - cancelAnimationFrame(this.animationFrameHook); - - this.instanceCreatedSubscription.remove(); - - this.removeComponentSubscription.remove(); - - this.renderSubscription.remove(); - - window.removeEventListener( - 'resize', - this.nativeWindowResize, - false - ); - - this.windowResizeSubscription.remove(); - - this.renderers.map( - function(renderer) { - if (renderer.statistics) { - renderer.statistics.resize(); - renderer.domElement.instance.parentElement.removeChild(renderer.statistics.instance.dom); - } - } - ); - - this.renderers = []; - -}; - - -/** - * System takes care of updating all the entities (based on their component data) - * @param apiSystem GameLib.API.System - * @constructor - */ -GameLib.System.Socket = function( - apiSystem -) { - GameLib.System.call( - this, - apiSystem - ); - - this.totalTime = 0; - - this.castComponents = []; - - this.receiveComponents = []; - - this.servers = []; - - this.instanceCreatedSubscription = null; - - this.removeComponentSubscription = null; - - this.beforeRenderSubscription = null; -}; - -GameLib.System.Socket.prototype = Object.create(GameLib.System.prototype); -GameLib.System.Socket.prototype.constructor = GameLib.System.Socket; - -/** - * Start this system (add all event listeners) - */ -GameLib.System.Socket.prototype.start = function() { - - GameLib.System.prototype.start.call(this); - - this.castComponents = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.SOCKET_CAST); - this.receiveComponents = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.SOCKET_RECEIVE); - this.servers = GameLib.EntityManager.Instance.queryComponents(GameLib.Component.SERVER); - - this.instanceCreatedSubscription = GameLib.Event.Subscribe( - GameLib.Event.INSTANCE_CREATED, - this.instanceCreated.bind(this) - ); - - this.removeComponentSubscription = GameLib.Event.Subscribe( - GameLib.Event.REMOVE_COMPONENT, - this.removeComponent.bind(this) - ); - - this.beforeRenderSubscription = GameLib.Event.Subscribe( - GameLib.Event.BEFORE_RENDER, - this.beforeRender.bind(this) - ); - -}; - -/** - * Connect to the socket server - * @param socketComponent - */ -GameLib.System.Socket.prototype.connect = function(socketComponent) { - console.log(socketComponent.name + ' is connecting to the server ' + socketComponent.serverIp); -}; - -/** - * Disconnect from the socket server - * @param socketComponent - */ -GameLib.System.Socket.prototype.disconnect = function(socketComponent) { - console.log(socketComponent.name + ' is disconnecting from server ' + socketComponent.serverIp); -}; - - -/** - * From now on we want to track everything about a component, only from the systems that are active - * @param data - */ -GameLib.System.Socket.prototype.instanceCreated = function(data) { - - if (data.component instanceof GameLib.Socket.Cast) { - GameLib.Utils.PushUnique(this.castComponents, data.component); - } - - if (data.component instanceof GameLib.Socket.Receive) { - GameLib.Utils.PushUnique(this.receiveComponents, data.component); - } - - if (data.component instanceof GameLib.Server) { - GameLib.Utils.PushUnique(this.servers, data.component); - } -}; - -/** - * Removes a cast or receive component from this system - * @param data - */ -GameLib.System.Socket.prototype.removeComponent = function(data) { - - var index; - - if (data.component instanceof GameLib.Socket.Cast) { - - index = this.castComponents.indexOf(data.component); - - if (index !== -1) { - this.castComponents.splice(index, 1); - } else { - console.log('Socket System out of Cast Component sync') - } - } - - if (data.component instanceof GameLib.Socket.Receive) { - - index = this.receiveComponents.indexOf(data.component); - - if (index !== -1) { - this.receiveComponents.splice(index, 1); - } else { - console.log('Socket System out of Receive Component sync') - } - } - - - if (data.component instanceof GameLib.Server) { - - index = this.servers.indexOf(data.component); - - if (index !== -1) { - this.servers.splice(index, 1); - } else { - console.log('Socket System out of Server Component sync') - } - } - -}; - -/** - * @param data - */ -GameLib.System.Socket.prototype.beforeRender = function(data) { - - this.totalTime += data.delta; - -}; - - -/** - * Stop this system (remove all event listeners) - */ -GameLib.System.Socket.prototype.stop = function() { - - GameLib.System.prototype.stop.call(this); - - this.instanceCreatedSubscription.remove(); - this.removeComponentSubscription.remove(); - this.beforeRenderSubscription.remove(); - - this.servers = this.servers.reduce( - function(result, serverComponent) { - - if (!serverComponent.disconnect()) { - result.push(serverComponent); - } - - }.bind(this), - [] - ); - - if (this.servers.length !== 0) { - console.warn(this.servers.length + ' connections still open after socket system stopped'); - } - -}; - -/** - * Storage System takes care loading and linking components and dependencies - * @param apiSystem GameLib.API.System - * @param token - * @param apiUploadUrl - * @param onImageLoaded - * @param onImageProgress - * @param onImageError - * @param onComponentLoaded - * @param onComponentProgress - * @param onComponentError - * @constructor - */ -GameLib.System.Storage = function( - apiSystem, - token, - apiUploadUrl, - onImageLoaded, - onImageProgress, - onImageError, - onComponentLoaded, - onComponentProgress, - onComponentError -) { - GameLib.System.call( - this, - apiSystem - ); - - if (GameLib.Utils.UndefinedOrNull(token)) { - token = null; - } - this.token = token; - - if (GameLib.Utils.UndefinedOrNull(apiUploadUrl)) { - console.warn('Need an API Upload URL for a storage system'); - apiUploadUrl = ''; - } - this.apiUploadUrl = apiUploadUrl; - - if (GameLib.Utils.UndefinedOrNull(onImageLoaded)) { - onImageLoaded = null; - } - this.onImageLoaded = onImageLoaded; - - if (GameLib.Utils.UndefinedOrNull(onImageProgress)) { - onImageProgress = null; - } - this.onImageProgress = onImageProgress; - - if (GameLib.Utils.UndefinedOrNull(onImageError)) { - onImageError = null; - } - this.onImageError = onImageError; - - if (GameLib.Utils.UndefinedOrNull(onComponentLoaded)) { - onComponentLoaded = null; - } - this.onComponentLoaded = onComponentLoaded; - - if (GameLib.Utils.UndefinedOrNull(onComponentProgress)) { - onComponentProgress = null; - } - this.onComponentProgress = onComponentProgress; - - if (GameLib.Utils.UndefinedOrNull(onComponentError)) { - onComponentError = null; - } - this.onComponentError = onComponentError; - - this.loaded = []; - this.loading = []; - this.failed = []; - this.otherDependencies = []; - - this.loginSubscription = null; - this.saveSubscription = null; - this.loadSubscription = null; - this.loadImageSubscription = null; - this.blenderDataSubscription = null; - this.imageUploadCompleteSubscription = null; - - this.fetchComponentTypesSubscription = null; - this.fetchComponentsSubscription = null; -}; - -GameLib.System.Storage.prototype = Object.create(GameLib.System.prototype); -GameLib.System.Storage.prototype.constructor = GameLib.System.Storage; - -GameLib.System.Storage.prototype.start = function() { - - GameLib.System.prototype.start.call(this); - - this.loginSubscription = this.subscribe( - GameLib.Event.LOGGED_IN, - function(data) { - this.token = data.token; - } - ); - - this.saveSubscription = this.subscribe( - GameLib.Event.SAVE_COMPONENT, - this.save - ); - - this.loadSubscription = this.subscribe( - GameLib.Event.LOAD_COMPONENT, - this.load - ); - - this.deleteSubscription = this.subscribe( - GameLib.Event.DELETE_COMPONENT, - this.delete - ); - - this.loadImageSubscription = this.subscribe( - GameLib.Event.LOAD_IMAGE, - this.loadImage - ); - - this.loadFontSubscription = this.subscribe( - GameLib.Event.LOAD_FONT, - this.loadFont - ); - - this.blenderDataSubscription = this.subscribe( - GameLib.Event.BLENDER_DATA_RECEIVED, - this.processBlenderData - ); - - this.imageUploadCompleteSubscription = this.subscribe( - GameLib.Event.IMAGE_UPLOAD_COMPLETE, - this.imageUploadComplete - ); - - this.fetchComponentTypesSubscription = this.subscribe( - GameLib.Event.FETCH_COMPONENT_TYPES, - this.fetchComponentTypes - ); - - this.fetchComponentsSubscription = this.subscribe( - GameLib.Event.FETCH_COMPONENTS, - this.fetchComponents - ); - -}; - - -GameLib.System.Storage.prototype.delete = function(data) { - - this.publish( - GameLib.Event.GET_API_URL, - null, - function(urlData) { - - if (typeof XMLHttpRequest === 'undefined') { - console.log('Implement server side delete here'); - return; - } - - data.ids.map(function(id){ - - var xhr = new XMLHttpRequest(); - - xhr.open( - 'POST', - urlData.apiUrl + '/component/delete/' + id - ); - - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("Content-Type", "application/json"); - xhr.setRequestHeader("x-authorization", urlData.passwoid); - - xhr.onreadystatechange = function () { - if (this.readyState === 4) { - try { - var response = JSON.parse(this.responseText) - } catch (error) { - GameLib.Event.Emit( - GameLib.Event.DELETE_COMPONENT_ERROR, - { - message: this.responseText - } - ) - } - - if (response.result === 'success') { - GameLib.Event.Emit( - GameLib.Event.COMPONENT_DELETED, - { - message: response.message || 'Successfully saved the component' - } - ) - } else { - GameLib.Event.Emit( - GameLib.Event.DELETE_COMPONENT_ERROR, - { - message: response.message || 'The server responded but failed to save the component' - } - ) - } - } - }; - - xhr.send(JSON.stringify({ - session : this.token - })); - - }.bind(this)); - }.bind(this), - function(error) { - console.error(error.message); - throw new Error(error.message); - } - ); - - -}; - -/** - * 'Saves' data to somewhere - */ -GameLib.System.Storage.prototype.save = function(data) { - - var event = GameLib.Event.GET_API_URL; - - if (data.remote) { - event = GameLib.Event.GET_REMOTE_API_URL - } - - this.publish( - event, - null, - function(urlData) { - if (typeof XMLHttpRequest === 'undefined') { - console.log('Implement server side save here'); - return; - } - - var xhr = new XMLHttpRequest(); - - xhr.open( - 'POST', - urlData.apiUrl + '/component/create' - ); - - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("Content-Type", "application/json"); - xhr.setRequestHeader("x-authorization", urlData.passwoid); - - xhr.onreadystatechange = function () { - if (this.readyState === 4) { - try { - var response = JSON.parse(this.responseText) - } catch (error) { - GameLib.Event.Emit( - GameLib.Event.SAVE_COMPONENT_ERROR, - { - message: this.responseText, - component : data.apiObject - } - ) - } - - if (response.result === 'success') { - GameLib.Event.Emit( - GameLib.Event.COMPONENT_SAVED, - { - message: response.message || 'Successfully saved the component', - component : data.apiObject - } - ) - } else { - GameLib.Event.Emit( - GameLib.Event.SAVE_COMPONENT_ERROR, - { - message: response.message || 'The server responded but failed to save the component', - component : data.apiObject - } - ) - } - } - }; - - xhr.send(JSON.stringify({ - component : data.apiObject, - session : this.token - })); - } - ); - -}; - -GameLib.System.Storage.prototype.createRuntimeObject = function(responseText, clientErrorCallback) { - - try { - var object = JSON.parse(responseText); - } catch (errorObject) { - - if (this.onComponentError) { - this.onComponentError(errorObject); - } - - if (clientErrorCallback) { - clientErrorCallback({ - message : errorObject.message || 'JSON parse error' - }) - } - - GameLib.Event.Emit( - GameLib.Event.LOAD_COMPONENT_ERROR, - {error: errorObject} - ); - - return null; - } - - if (object.result !== 'success') { - - if (this.onComponentError) { - this.onComponentError(id, object); - } - - if (clientErrorCallback) { - clientErrorCallback({ - message : object.message || 'Server load error' - }) - } - - GameLib.Event.Emit( - GameLib.Event.LOAD_COMPONENT_ERROR, - {error : object} - ); - - return null; - } - - /** - * Now we need to create the runtime component - this happens systematically. - * First, we create an API object from the Object, then a Runtime object from the API object - * Each component has a function 'FromObject' which essentially does this for you - */ - var runtimeComponent = GameLib.Component.ConstructFromObject(object.component[0]); - - if (!runtimeComponent) { - if (clientErrorCallback) { - clientErrorCallback({ - result: 'failure', - message: 'Could not create a runtime component: ' + object.component[0].name - }); - } - } - - return runtimeComponent; -}; - -GameLib.System.Storage.prototype.loadComponent = function(apiUrl, toProcess, includeDependencies, clientCallback, clientErrorCallback) { - - /** - * We just do an initial check if these components to process are already in the register - - * if so we remove them since we probably want to overwrite them with stale DB versions. - * - * We don't override runtime versions of the dependencies of the loading components - since they could be later. - * But we do override runtime versions of the loading component since the user actually selected them and clicked 'load' - */ - toProcess.map( - function(id) { - - GameLib.Utils.PushUnique(this.loading, id); - - var component = GameLib.EntityManager.Instance.findComponentById(id); - - if (component) { - component.remove(); - } - }.bind(this) - ); - - toProcess.map( - - function(id) { - - var xhr = new XMLHttpRequest(); - - xhr.onload = function(__system) { - - return function () { - - var runtimeComponent = __system.createRuntimeObject.bind(__system)(this.responseText); - - if (!runtimeComponent) { - __system.failed.push(id); - return; - } - - if ( - runtimeComponent.parentEntity && - typeof runtimeComponent.parentEntity === 'string' - ) { - GameLib.EntityManager.Instance.queryComponents(GameLib.Component.ENTITY).map( - function (entity) { - if (runtimeComponent.parentEntity === entity.id) { - runtimeComponent.parentEntity = entity; - } - } - ); - } - - GameLib.Event.Emit( - GameLib.Event.COMPONENT_CREATED, - { - component: runtimeComponent - } - ); - - __system.loaded.push(runtimeComponent.id); - - if (includeDependencies) { - - /** - * Before we announce the creation of this component, we should get - * a list of all dependencies of this component, because once we announce - * the creation of this component - the linking system will attempt to resolve - * all dependencies - */ - var dependencies = runtimeComponent.getDependencies(); - - __system.otherDependencies.map( - function(id) { - - var index = dependencies.indexOf(id); - - if (index !== -1) { - dependencies.splice(index, 1); - } - } - ); - - dependencies.map( - function(id) { - GameLib.Utils.PushUnique(this.otherDependencies, id); - }.bind(__system) - ); - - /** - * Don't try to download failed components again - */ - dependencies = dependencies.reduce( - function(result, id) { - if (__system.failed.indexOf(id) === -1) { - result.push(id); - } else { - console.log('ignoring failed component : ' + id); - } - return result; - }.bind(__system), - [] - ); - - /** - * Now - we should systematically check if we have the dependency already - * loaded (in our runtime environment) - if we have - we just ignore loading this dependency (for now) - * - * We don't override runtime versions of the same component in the database because the user - * could be working with it and it should be the latest version. - */ - dependencies = dependencies.reduce( - - function (result, dependency) { - - if (GameLib.EntityManager.Instance.findComponentById(dependency)) { - /** - * Don't add the dependency - */ - } else { - result.push(dependency); - } - - return result; - }, - [] - ); - - /** - * Also check if this dependency is not already in our loaded - */ - dependencies = dependencies.reduce( - function (result, dependency) { - - if (__system.loaded.indexOf(dependency) === -1) { - result.push(dependency); - } - - return result; - }, - [] - ); - - /** - * We should now check our 'loading' list and add all dependencies which are not already in there - */ - dependencies.map( - function (dependency) { - GameLib.Utils.PushUnique(__system.loading, dependency); - } - ); - - __system.loadComponent(apiUrl, dependencies, includeDependencies, clientCallback, clientErrorCallback); - - } - - // GameLib.Event.Emit( - // GameLib.Event.COMPONENT_DOWNLOAD_COMPLETE, - // { - // loaded: __system.loaded - // } - // ); - - GameLib.Event.Emit( - GameLib.Event.LOAD_PROGRESS, - { - loading : __system.loading.length, - loaded : __system.loaded.length - } - ); - - if (__system.onComponentLoaded) { - __system.onComponentLoaded(runtimeComponent); - } - - if (__system.loading.length === __system.loaded.length) { - - console.log('loaded ' + __system.loaded.length + ' components'); - - if (clientCallback) { - clientCallback({ - components : __system.loaded - }) - } - } - - - - } - - }(this); - - xhr.onprogress = function(__id) { - return function (progressEvent) { - - var progress = 0; - - if (progressEvent.total !== 0) { - progress = Math.round(Number(progressEvent.loaded / progressEvent.total) * 100); - } - - if (this.onComponentProgress) { - this.onComponentProgress(__id, progress) - } - }.bind(this); - }(id); - - xhr.onerror = function(__id) { - return function (error) { - console.warn('component load failed for component ID ' + __id); - - if (this.onComponentError) { - this.onComponentError(__id, error) - } - - if (clientErrorCallback) { - clientErrorCallback({ - message : 'xhr request failure' - }) - } - }.bind(this); - }(id); - - xhr.open( - 'GET', - apiUrl + '/component/load/' + id - ); - - - xhr.send(); - - }.bind(this) - - ); - - -}; - -/** - * 'Loads' data from a url - */ -GameLib.System.Storage.prototype.load = function(data, clientCallback, clientErrorCallback) { - - this.publish( - GameLib.Event.GET_API_URL, - null, - function(urlData) { - if (typeof XMLHttpRequest === 'undefined') { - console.log('Implement server side load here'); - return; - } - - if (data.ids && data.ids.length > 0) { - this.loadComponent( - urlData.apiUrl, - data.ids, - data.includeDependencies, - clientCallback, - clientErrorCallback - ); - } else { - console.log('No components selected'); - } - }.bind(this), - function(error) { - console.error(error.message); - throw new Error(error.message); - } - ); - -}; - -GameLib.System.Storage.prototype.xhrLoad = function( - url, - callback, - errorCallback -) { - - if (typeof XMLHttpRequest === 'undefined') { - console.log('Implement server side load here'); - return; - } - - console.log("Loading...", 'success'); - - var xhr = new XMLHttpRequest(); - xhr.open("GET", url); - xhr.setRequestHeader("Accept", "application/json"); - xhr.setRequestHeader("Content-Type", "application/json"); - - xhr.onreadystatechange = function() { - - if (xhr.readyState === 4) { - - if (!xhr.responseText) { - console.log('Invalid response from server'); - errorCallback({message : 'Invalid response from server'}); - return; - } - - try { - var response = JSON.parse(xhr.responseText); - } catch (error) { - error.message = 'Could not parse JSON'; - errorCallback(error); - } - - if (response.result !== 'success') { - return errorCallback({message : response.message || 'Unknown Error Occurred'}); - } - - callback(response); - } - }; - - - xhr.onerror = errorCallback; - - // TODO: authentication data append - // var object = {}; - // object.session = this.session; - // var string = JSON.stringify(object); - // xhr.send(string); - - xhr.send(); -}; - -/** - * Fetches all component types from the provided API url - * @param data - * @param clientCallback - * @param clientErrorCallback - */ -GameLib.System.Storage.prototype.fetchComponentTypes = function(data, clientCallback, clientErrorCallback) { - this.xhrLoad( - data.url, - function(response) { - clientCallback({ - ids : response.ids - }) - }, - clientErrorCallback - ); -}; - -/** - * Fetches all components with the specified type from the provided API url - * @param data - * @param clientCallback - * @param clientErrorCallback - */ -GameLib.System.Storage.prototype.fetchComponents = function(data, clientCallback, clientErrorCallback) { - this.xhrLoad( - data.url, - function(response) { - clientCallback({ - components : response.component - }) - }, - clientErrorCallback - ); -}; - - -/** - * Once we have an image uploaded - we should load them all again - if their runtime version already exist, do nothing, - * otherwise, create the runtime version of it - * @param data - */ -GameLib.System.Storage.prototype.imageUploadComplete = function(data) { - - /** - * Process all images - we have to load them in addition to creating their runtime components - */ - data.images.map(function(rawImage){ - - var image = GameLib.EntityManager.Instance.findComponentById(rawImage.id); - - if (image) { - /** - * We are updating an existing image - */ - image.updateFromRawObject(rawImage); - - /** - * Our symbolic path has changed server side, even though it looks the same - */ - image.updateInstance('path'); - - } else { - /** - * We are creating a new image - */ - GameLib.Component.ConstructFromObject(rawImage); - } - - }.bind(this)); -}; - -/** - * Process Blender Data - Basically does what 'load' does - but because we already have the data we don't have - * a complicated load pattern - we create the runtime components in the best order we can (images load async unfortunately) - * and announce their creation so the linking system can link them - * @param data - */ -GameLib.System.Storage.prototype.processBlenderData = function(data) { - - console.log('loading blender data'); - - /** - * Process all images - we have to load them in addition to creating their runtime components - */ - data.images.map( - function(rawImageObject) { - var image = GameLib.Component.ConstructFromObject(rawImageObject); - GameLib.Event.Emit( - GameLib.Event.COMPONENT_CREATED, - { - component: image - } - ); - }.bind(this) - ); - - /** - * Process all textures - */ - data.textures.map(function(rawTextureObject){ - var texture = GameLib.Component.ConstructFromObject(rawTextureObject); - GameLib.Event.Emit( - GameLib.Event.COMPONENT_CREATED, - { - component: texture - } - ); - }.bind(this)); - - /** - * Process all materials - */ - data.materials.map(function(rawMaterialObject){ - var material = GameLib.Component.ConstructFromObject(rawMaterialObject); - GameLib.Event.Emit( - GameLib.Event.COMPONENT_CREATED, - { - component: material - } - ); - }.bind(this)); - - /** - * Now process all meshes - */ - data.meshes.map(function(rawMeshObject){ - var mesh = GameLib.Component.ConstructFromObject(rawMeshObject); - GameLib.Event.Emit( - GameLib.Event.COMPONENT_CREATED, - { - component: mesh - } - ); - }.bind(this)); - - /** - * And that should be it... - */ -}; - -GameLib.System.Storage.prototype.loadFont = function(data, callback, errorCallback) { - - console.log('loading font : ' + data.font.name); - - this.publish( - GameLib.Event.GET_API_URL, - null, - function(urlData) { - - var url = urlData.apiUrl + '/fonts/' + data.font.url + '?ts=' + Date.now(); - - var loader = new THREE.FontLoader(); - - loader.load( - url, - function ( font ) { - - if (GameLib.Utils.IsEmpty(font.data)) { - - errorCallback({message:'font is empty'}); - - } else { - - callback(font); - - } - } - ); - - }.bind(this), - function(error) { - errorCallback(error); - } - ); - - -}; - -GameLib.System.Storage.prototype.loadImage = function(data, callback, errorCallback) { - - console.log('loading image : ' + data.image.name); - - this.publish( - GameLib.Event.GET_API_URL, - null, - function(urlData) { - - var onLoaded = this.onImageLoaded; - - var onProgress = this.onImageProgress; - - var onError = this.onImageError; - - var image = data.image; - - var url = urlData.apiUrl + image.path + image.fileName + image.extension + '?ts=' + Date.now(); - - var preflight = new XMLHttpRequest(); - - preflight.withCredentials = true; - - preflight.open( - 'OPTIONS', - url - ); - - preflight.setRequestHeader('Content-Type', 'application/json'); - - preflight.onload = function() { - - var xhr = new XMLHttpRequest(); - - xhr.withCredentials = true; - - xhr.open('GET', url); - - xhr.setRequestHeader('Content-Type', image.contentType); - - xhr.responseType = 'blob'; - - xhr.onload = function() { - - var objectUrl = false; - - var url = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAAlC+aJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QoWEQMQBXD4hQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAABRSURBVGje7c8xDQAwCAAwmA3koA/PU8FB0jpo1nRc9uI4AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBgX0fjEoBa8xN1z4AAAAASUVORK5CYII='; - - try { - if (this.response.type !== 'application/json') { - url = window.URL.createObjectURL(this.response); - objectUrl = true; - } - } catch (error) { - if (errorCallback) { - errorCallback({ - result: 'failure', - message: 'invalid server response trying to download image ' + data.image.name - }); - } - } - - var img = document.createElement('img'); - - img.onload = function () { - - if (objectUrl) { - window.URL.revokeObjectURL(url); - } - - if (callback) { - callback(img); - } - - if (onLoaded) { - onLoaded(image, data.createTexture); - } - }; - - img.src = url; - }; - - xhr.onprogress = function(progressEvent) { - - var progress = 0; - - if (progressEvent.total !== 0) { - progress = Math.round(Number(progressEvent.loaded / progressEvent.total) * 100); - } - - if (onProgress) { - onProgress(image, progress); - } - - image.size = progressEvent.total; - }; - - xhr.onerror = function(error) { - console.warn('image load failed for image ' + image.name); - - if (errorCallback) { - errorCallback(error); - } - - if (onError) { - onError(image, error) - } - }; - - xhr.send(); - }; - - preflight.onerror = function(error) { - console.warn('image pre-flight request failed for image ' + image.name); - - if (errorCallback) { - errorCallback(error); - } - - if (onError) { - onError(image, error); - } - }; - - preflight.send(); - }.bind(this), - function(error) { - console.error(error.message); - throw new Error(error.message); - } - ); - - -}; - -GameLib.System.Storage.prototype.stop = function() { - - GameLib.System.prototype.stop.call(this); - - this.loginSubscription.remove(); - this.loadSubscription.remove(); - this.saveSubscription.remove(); - this.loadImageSubscription.remove(); - this.loadFontSubscription.remove(); - this.blenderDataSubscription.remove(); - this.imageUploadCompleteSubscription.remove(); - this.deleteSubscription.remove(); - this.fetchComponentTypesSubscription.remove(); - this.fetchComponentsSubscription.remove(); -}; - - -/** - * System takes care of updating all the entities (based on their component data) - * Visualization System takes care of visualizing all objects which are not meshes (like physics data) - * - * @param apiSystem GameLib.API.System - * @param graphics - * @param physics - * @constructor - */ -GameLib.System.Visualization = function( - apiSystem, - graphics, - physics -) { - - GameLib.System.call( - this, - apiSystem - ); - - if (GameLib.Utils.UndefinedOrNull(graphics)){ - GameLib.Event.Emit( - GameLib.Event.GET_GRAPHICS_RUNTIME, - null, - function(graphicsRuntime) { - graphics = graphicsRuntime; - }.bind(this), - function() { - graphics = null; - }.bind(this) - ); - } - this.graphics = graphics; - - if (GameLib.Utils.UndefinedOrNull(physics)){ - GameLib.Event.Emit( - GameLib.Event.GET_PHYSICS_RUNTIME, - null, - function(physicsRuntime) { - physics = physicsRuntime; - }.bind(this), - function() { - physics = null; - }.bind(this) - ); - } - this.physics = physics; - - this.visualizationSubscription = null; - this.stopVisualizationSubscription = null; - -}; - -GameLib.System.Visualization.prototype = Object.create(GameLib.System.prototype); -GameLib.System.Visualization.prototype.constructor = GameLib.System.Visualization; - -GameLib.System.Visualization.prototype.start = function() { - - GameLib.System.prototype.start.call(this); - - this.visualizationSubscription = this.subscribe( - GameLib.Event.VISUALIZE, - this.visualize - ); - - this.stopVisualizationSubscription = this.subscribe( - GameLib.Event.STOP_VISUALIZE, - this.stopVisualize - ) -}; - - -GameLib.System.Visualization.prototype.visualize = function(data) { - - var shape = data.shape; - - var parentMesh = shape.parentMesh; - - shape.setFromMesh(); - - var apiMesh = new GameLib.D3.API.Mesh(); - - apiMesh.name = 'Visualization Mesh for Shape ' + shape.name; - - if (shape instanceof GameLib.D3.Shape.HeightMap) { - var v0 = new CANNON.Vec3(); - var v1 = new CANNON.Vec3(); - var v2 = new CANNON.Vec3(); - for (var xi = 0; xi < shape.heightData.length - 1; xi++) { - for (var yi = 0; yi < shape.heightData[xi].length - 1; yi++) { - for (var k = 0; k < 2; k++) { - shape.instance.getConvexTrianglePillar(xi, yi, k===0); - v0.copy(shape.instance.pillarConvex.vertices[0]); - v1.copy(shape.instance.pillarConvex.vertices[1]); - v2.copy(shape.instance.pillarConvex.vertices[2]); - v0.vadd(shape.instance.pillarOffset, v0); - v1.vadd(shape.instance.pillarOffset, v1); - v2.vadd(shape.instance.pillarOffset, v2); - apiMesh.vertices.push( - new GameLib.D3.API.Vertex( - new GameLib.API.Vector3(v0.x, v0.y, v0.z) - ), - new GameLib.D3.API.Vertex( - new GameLib.API.Vector3(v1.x, v1.y, v1.z) - ), - new GameLib.D3.API.Vertex( - new GameLib.API.Vector3(v2.x, v2.y, v2.z) - ) - ); - var i = apiMesh.vertices.length - 3; - apiMesh.faces.push( - new GameLib.D3.API.Face( - null, - null, - i, - i+1, - i+2 - ) - ); - } - } - } - } - - new GameLib.D3.Mesh( - this.graphics, - apiMesh - ); - -}; - -GameLib.System.Visualization.prototype.stopVisualize = function(data) { -}; - -GameLib.System.Visualization.prototype.stop = function() { - - GameLib.System.prototype.stop.call(this); - - if (this.visualizationSubscription) { - this.visualizationSubscription.remove(); - } - - if (this.stopVisualizationSubscription) { - this.stopVisualizationSubscription.remove(); - } - -}; - - -/** - * Runtime vector2 for updating instance objects - * @param graphics GameLib.GraphicsRuntime - * @param parentObject GameLib.D3.* - * @param apiVector2 GameLib.API.Vector2 - * @param grain Number - * @constructor - */ -GameLib.Vector2 = function ( - graphics, - apiVector2, - parentObject, - grain -) { - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiVector2)) { - apiVector2 = {}; - apiVector2 = {}; - } - - if (apiVector2 instanceof GameLib.Vector2) { - return apiVector2; - } - - GameLib.API.Vector2.call( - this, - apiVector2.x, - apiVector2.y - ); - - if (GameLib.Utils.UndefinedOrNull(parentObject)) { - parentObject = null; - } - this.parentObject = parentObject; - - if (GameLib.Utils.UndefinedOrNull(grain)) { - grain = 0.001; - } - this.grain = grain; - - this.createInstance(); -}; - -GameLib.Vector2.prototype = Object.create(GameLib.API.Vector2.prototype); -GameLib.Vector2.prototype.constructor = GameLib.Vector2; - - -/** - * Creates an instance vector2 - * @returns {*} - */ -GameLib.Vector2.prototype.createInstance = function() { - this.instance = new THREE.Vector2(this.x, this.y); -}; - -/** - * Updates the instance vector, calls updateInstance on the parent object - */ -GameLib.Vector2.prototype.updateInstance = function(property) { - - this.instance.x = this.x; - this.instance.y = this.y; - - if (this.parentObject && - this.parentObject.updateInstance) { - this.parentObject.updateInstance(property); - } -}; - -/** - * Converts runtime vector to API Vector - * @returns {GameLib.API.Vector2} - */ -GameLib.Vector2.prototype.toApiObject = function() { - return new GameLib.API.Vector2( - this.x, - this.y - ); -}; - -/** - * Copy - * TODO: Test - * @param v optional - * @returns {GameLib.Vector2} - */ -GameLib.Vector2.prototype.copy = function (v) { - - if (GameLib.Utils.UndefinedOrNull(v)) { - - return new GameLib.Vector2( - this.graphics, - new GameLib.API.Vector2( - this.x, - this.y - ), - this.parentObject, - this.grain - ); - - } else { - - this.x = v.x; - this.y = v.y; - - return this; - } -}; - -/** - * Equals - * TODO: Test - * @param v - * @returns {boolean} - */ -GameLib.Vector2.prototype.equals = function(v) { - - if ((this.x == v.x) && - (this.y == v.y)) { - return true; - } else { - return false; - } - -}; - -/** - * Add - * TODO: Test - * @param v - */ -GameLib.Vector2.prototype.add = function(v) { - - if ( - v instanceof GameLib.API.Vector2 || - v instanceof GameLib.API.Vector3 || - v instanceof GameLib.API.Vector4 || - v instanceof GameLib.API.Quaternion - ) { - this.x += v.x; - this.y += v.y; - } else { - console.warn('Could not add Vector2'); - throw new Error('Could not add Vector2'); - } - -}; - -/** - * Subtract - * TODO: Test - * @param v - */ -GameLib.Vector2.prototype.subtract = function(v) { - - if ( - v instanceof GameLib.API.Vector2 || - v instanceof GameLib.API.Vector3 || - v instanceof GameLib.API.Vector4 || - v instanceof GameLib.API.Quaternion - ) { - this.x -= v.x; - this.y -= v.y; - } else { - console.warn('Could not subtract Vector2'); - throw new Error('Could not subtract Vector2'); - } - -}; - -/** - * Multiply - * TODO: Test - * @param v - */ -GameLib.Vector2.prototype.multiply = function(v) { - - if ( - v instanceof GameLib.API.Vector2 || - v instanceof GameLib.API.Vector3 || - v instanceof GameLib.API.Vector4 || - v instanceof GameLib.API.Quaternion - ) { - this.x *= v.x; - this.y *= v.y; - } else if (typeof v == 'number') { - this.x *= v; - this.y *= v; - } else { - console.warn('Could not multiply Vector2'); - throw new Error('Could not multiply Vector2'); - } - -}; - -/** - * Divide - * TODO: Test - * @param v - */ -GameLib.Vector2.prototype.divide = function(v) { - - if ( - v instanceof GameLib.API.Vector2 || - v instanceof GameLib.API.Vector3 || - v instanceof GameLib.API.Vector4 || - v instanceof GameLib.API.Quaternion - ) { - this.x *= (1.0 / v.x); - this.y *= (1.0 / v.y); - } else if (typeof v == 'number') { - this.x *= 1.0 / v; - this.y *= 1.0 / v; - } else { - console.warn('Could not divide Vector2'); - throw new Error('Could not divide Vector2'); - } - -}; - -/** - * Clamp - * TODO: Test - * @param min GameLib.API.Vector2 - * @param max GameLib.API.Vector2 - * @returns {GameLib.Vector2} - */ -GameLib.Vector2.prototype.clamp = function(min, max) { - - this.x = Math.max(min.x, Math.min(max.x, this.x)); - this.y = Math.max(min.y, Math.min(max.y, this.y)); - - return this; - -}; - -/** - * Length - * TODO: Test - * @returns {number} - */ -GameLib.Vector2.prototype.length = function() { - return Math.sqrt( - this.x * this.x + this.y * this.y - ); -}; - -/** - * Dot product - * TODO: Test - * @param v - * @returns {number} - */ -GameLib.Vector2.prototype.dot = function(v) { - return this.x * v.x + this.y * v.y; -}; - -/** - * Normalize - * TODO: Test - */ -GameLib.Vector2.prototype.normalize = function() { - return this.multiply(1.0 / this.length()); -}; - -/** - * TODO: Test - * Angle between this vector and origin - * @returns {number} - */ -GameLib.Vector2.prototype.angle = function() { - var angle = Math.atan2(this.y, this.x); - if ( angle < 0 ) angle += 2 * Math.PI; - return angle; -}; - -/** - * Interpolate to v from here - * TODO: Test - * @param v - * @param alpha - * @returns {GameLib.Vector2} - */ -GameLib.Vector2.prototype.lerp = function ( v, alpha ) { - return new GameLib.Vector2( - this.x + ( v.x - this.x ) * alpha, - this.y + ( v.y - this.y ) * alpha - ); -}; -/** - * Runtime apiVector3 for updating instance objects - * @param implementation GameLib.GraphicsRuntime - * @param apiVector3 GameLib.API.Vector3 - * @param parentObject GameLib.* - * @param grain Number - * @constructor - */ -GameLib.Vector3 = function ( - implementation, - apiVector3, - parentObject, - grain -) { - - this.implementation = implementation; - - if (implementation instanceof GameLib.GraphicsRuntime) { - this.physics = null; - this.graphics = implementation; - this.graphics.isNotThreeThrow(); - } else if (implementation instanceof GameLib.PhysicsRuntime) { - this.graphics = null; - this.physics = implementation; - this.physics.isNotCannonThrow(); - } else { - throw new Error('Unhandled implementation : ' + implementation); - } - - if (GameLib.Utils.UndefinedOrNull(apiVector3)) { - apiVector3 = {}; - } - - if (apiVector3 instanceof GameLib.Vector3) { - return apiVector3; - } - - GameLib.API.Vector3.call( - this, - apiVector3.x, - apiVector3.y, - apiVector3.z - ); - - if (GameLib.Utils.UndefinedOrNull(parentObject)) { - parentObject = this; - } - this.parentObject = parentObject; - - if (GameLib.Utils.UndefinedOrNull(grain)) { - grain = 0.001; - } - this.grain = grain; - - this.createInstance(); -}; - -GameLib.Vector3.prototype = Object.create(GameLib.API.Vector3.prototype); -GameLib.Vector3.prototype.constructor = GameLib.Vector3; - -/** - * Creates an instance vector3 - * @returns {*} - */ -GameLib.Vector3.prototype.createInstance = function() { - - if (this.graphics) { - this.instance = new THREE.Vector3( - this.x, - this.y, - this.z - ); - } else if (this.physics) { - this.instance = new CANNON.Vec3( - this.x, - this.y, - this.z - ) - } - -}; - -/** - * Updates the instance vector, calls updateInstance on the parent object - */ -GameLib.Vector3.prototype.updateInstance = function(property, preventParentUpdate) { - - this.instance.x = this.x; - this.instance.y = this.y; - this.instance.z = this.z; - - if (!preventParentUpdate && - this.parentObject && - this.parentObject !== this && - this.parentObject.updateInstance) { - this.parentObject.updateInstance(property); - } -}; - -/** - * Converts runtime vector to API Vector - */ -GameLib.Vector3.prototype.toApiObject = function() { - return new GameLib.API.Vector3( - this.x, - this.y, - this.z - ); -}; - -/** - * Creates a new copy of this Vector3 - */ -GameLib.Vector3.prototype.copy = function() { - return new GameLib.Vector3( - this.implementation, - new GameLib.API.Vector3( - this.x, - this.y, - this.z - ), - this.parentObject, - this.grain - ) -}; - -GameLib.Vector3.prototype.clone = function() { - return new GameLib.Vector3( - this.implementation, - new GameLib.API.Vector3( - this.x, - this.y, - this.z - ), - this.parentObject, - this.grain - ) -}; - -/** - * Create a negative version of this vector - * @returns {GameLib.Vector3} - */ -GameLib.Vector3.prototype.negativeCopy = function() { - return new GameLib.Vector3( - this.implementation, - new GameLib.API.Vector3( - -this.x, - -this.y, - -this.z - ), - this.parentObject, - this.grain - ) -}; - -/** - * Applies rotation specified by axis / angle to this vector - its a wrapper for three.. - * @param axis - * @param angle - */ -GameLib.Vector3.prototype.applyAxisAngle = function(axis, angle) { - - this.instance.applyAxisAngle( - new THREE.Vector3( - axis.x, - axis.y, - axis.z - ), - angle - ); - - this.x = this.instance.x; - this.y = this.instance.y; - this.z = this.instance.z; -}; - -GameLib.Vector3.prototype.setFrom = function(vector3) { - this.x = vector3.x; - this.y = vector3.y; - this.z = vector3.z; -}; - -/** - * Runtime apiVector4 for updating instance objects - * @param graphics GameLib.GraphicsRuntime - * @param apiVector4 GameLib.API.Vector4 - * @param parentObject GameLib.* - * @param grain Number - * @constructor - */ -GameLib.Vector4 = function ( - graphics, - apiVector4, - parentObject, - grain -) { - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - - if (GameLib.Utils.UndefinedOrNull(apiVector4)) { - apiVector4 = {}; - } - - if (apiVector4 instanceof GameLib.Vector4) { - return apiVector4; - } - - GameLib.API.Vector4.call( - this, - apiVector4.x, - apiVector4.y, - apiVector4.z, - apiVector4.w - ); - - if (GameLib.Utils.UndefinedOrNull(parentObject)) { - parentObject = null; - } - this.parentObject = parentObject; - - if (GameLib.Utils.UndefinedOrNull(grain)) { - grain = 0.001; - } - this.grain = grain; - - this.createInstance(); -}; - -GameLib.Vector4.prototype = Object.create(GameLib.API.Vector4.prototype); -GameLib.Vector4.prototype.constructor = GameLib.Vector4; - -/** - * Creates an instance vector4 - * @returns {*} - */ -GameLib.Vector4.prototype.createInstance = function() { - this.instance = new THREE.Quaternion( - this.x, - this.y, - this.z, - this.w - ); -}; - -/** - * Updates the instance vector, calls updateInstance on the parent object - */ -GameLib.Vector4.prototype.updateInstance = function(property) { - - this.instance.x = this.x; - this.instance.y = this.y; - this.instance.z = this.z; - this.instance.w = this.w; - - if (this.parentObject && - this.parentObject.updateInstance) { - this.parentObject.updateInstance(property); - } -}; - -/** - * Converts runtime vector to API Vector - */ -GameLib.Vector4.prototype.toApiObject = function() { - return new GameLib.API.Vector4( - this.x, - this.y, - this.z, - this.w - ); -}; - - -GameLib.EntityManager.Instance = new GameLib.EntityManager(); - -if (typeof window !== 'undefined') { - window.GameLib = GameLib; -} - -if (typeof module !== 'undefined') { - module.exports = GameLib; -} -//EXTENDING INTERFACES (Generated via gulp) -//END EXTENDING