diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..58dd864 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +build/ +*.swp +package-lock.json diff --git a/README.md b/README.md new file mode 100644 index 0000000..65f9e2e --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +#R3 3D +###### + +A 3D library - based on the Entity Component System model - with the following features: + +* Blender file import (import objects directly from .blend files) +* Saving and Loading of 3D objects to mongoDB API +* Multiple materials textures +* Variety of materials +* Cubemaps +* Stereo camera +* Custom shaders +* Shadows +* Effects +* Audio System +* Particles + + diff --git a/bak/r3-api-ar.js b/bak/r3-api-ar.js new file mode 100644 index 0000000..96ccbb6 --- /dev/null +++ b/bak/r3-api-ar.js @@ -0,0 +1,87 @@ +/** + * R3.API.AR + * @param id + * @param name + * @param parent + * @param video + * @param pathCamera + * @param pathMarker + * @param scene + * @param camera + * @param videoScene + * @param videoCamera + * @constructor + */ +R3.API.AR = function( + id, + name, + parent, + video, + pathCamera, + pathMarker, + scene, + camera, + videoScene, + videoCamera +) { + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = 'AR (' + id + ')'; + } + this.name = name; + + if (R3.Utils.UndefinedOrNull(video)) { + video = new R3.API.Video(); + } + this.video = video; + + if (R3.Utils.UndefinedOrNull(pathCamera)) { + pathCamera = 'data/camera_para.dat'; + } + this.pathCamera = pathCamera; + + if (R3.Utils.UndefinedOrNull(pathMarker)) { + pathMarker = 'data/patt.hiro'; + } + this.pathMarker = pathMarker; + + if (R3.Utils.UndefinedOrNull(scene)) { + scene = null; + } + this.scene = scene; + + if (R3.Utils.UndefinedOrNull(camera)) { + camera = null; + } + this.camera = camera; + + if (R3.Utils.UndefinedOrNull(videoScene)) { + videoScene = new R3.D3.API.Scene( + null, + 'Scene - AR Video' + ); + } + this.videoScene = videoScene; + + if (R3.Utils.UndefinedOrNull(videoCamera)) { + videoCamera = new R3.D3.API.Camera.Orthographic( + { + name : 'Camera Orthgraphic - AR Video' + } + ); + } + this.videoCamera = videoCamera; + + R3.API.Component.call( + this, + R3.Component.AR, + parent + ); +}; + +R3.API.AR.prototype = Object.create(R3.API.Component.prototype); +R3.API.AR.prototype.constructor = R3.API.AR; diff --git a/bak/r3-api-controls-d3-editor.js b/bak/r3-api-controls-d3-editor.js new file mode 100644 index 0000000..d21d94d --- /dev/null +++ b/bak/r3-api-controls-d3-editor.js @@ -0,0 +1,27 @@ +/** + * R3.API.Controls.D3.Editor + * @param apiComponent + * @constructor + */ +R3.API.Controls.D3.Editor = function( + apiComponent +) { + + R3.API.Controls.D3.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.raycaster)) { + apiComponent.raycaster = new R3.D3.API.Raycaster( + { + parent : this + } + ); + } + this.raycaster = apiComponent.raycaster; + +}; + +R3.API.Controls.D3.Editor.prototype = Object.create(R3.API.Controls.D3.prototype); +R3.API.Controls.D3.Editor.prototype.constructor = R3.API.Controls.D3.Editor; diff --git a/bak/r3-api-graphics-runtime-a.js b/bak/r3-api-graphics-runtime-a.js new file mode 100644 index 0000000..587618e --- /dev/null +++ b/bak/r3-api-graphics-runtime-a.js @@ -0,0 +1,64 @@ +/** + * R3.API.GraphicsRuntime + * @param id + * @param name + * @param graphicsType + * @param parent + * @constructor + */ +R3.API.GraphicsRuntime = function( + id, + name, + graphicsType, + parent +) { + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = 'Graphics Runtime (' + id + ')'; + } + this.name = name; + + if (R3.Utils.UndefinedOrNull(graphicsType)) { + graphicsType = null; + } + this.graphicsType = graphicsType; + + R3.API.Component.call( + this, + R3.API.GraphicsRuntime.GetComponentType(this.graphicsType), + parent + ); +}; + +R3.API.GraphicsRuntime.prototype = Object.create(R3.API.Component.prototype); +R3.API.GraphicsRuntime.prototype.constructor = R3.API.GraphicsRuntime; + +R3.API.GraphicsRuntime.GetComponentType = function(graphicsType) { + + var componentType = null; + + switch (graphicsType) { + case R3.API.GraphicsRuntime.GRAPHICS_TYPE_NONE : + componentType = R3.Component.GRAPHICS; + break; + case R3.API.GraphicsRuntime.GRAPHICS_TYPE_THREE_JS : + componentType = R3.Component.GRAPHICS_THREE; + break; + case R3.API.GraphicsRuntime.GRAPHICS_TYPE_IMPACT_JS : + componentType = R3.Component.GRAPHICS_IMPACT; + break; + default: + throw new Error('Invalid graphics type'); + + } + + return componentType; +}; + +R3.API.GraphicsRuntime.GRAPHICS_TYPE_NONE = 0x0; +R3.API.GraphicsRuntime.GRAPHICS_TYPE_THREE_JS = 0x1; +R3.API.GraphicsRuntime.GRAPHICS_TYPE_IMPACT_JS = 0x2; diff --git a/bak/r3-api-graphics-runtime-impact.js b/bak/r3-api-graphics-runtime-impact.js new file mode 100644 index 0000000..1b78a5f --- /dev/null +++ b/bak/r3-api-graphics-runtime-impact.js @@ -0,0 +1,30 @@ +/** + * R3.API.GraphicsRuntime.Impact + * @constructor + * @param apiGraphicsRuntime + */ +R3.API.GraphicsRuntime.Impact = function( + apiGraphicsRuntime +) { + if (R3.Utils.UndefinedOrNull(apiGraphicsRuntime)) { + apiGraphicsRuntime = { + graphicsType : R3.API.GraphicsRuntime.GRAPHICS_TYPE_IMPACT_JS + }; + } + + if (R3.Utils.UndefinedOrNull(apiGraphicsRuntime.graphicsType)) { + apiGraphicsRuntime.graphicsType = R3.API.GraphicsRuntime.GRAPHICS_TYPE_IMPACT_JS; + } + + R3.API.GraphicsRuntime.call( + this, + apiGraphicsRuntime.id, + apiGraphicsRuntime.name, + apiGraphicsRuntime.graphicsType, + apiGraphicsRuntime.parent + ); + +}; + +R3.API.GraphicsRuntime.Impact.prototype = Object.create(R3.API.GraphicsRuntime.prototype); +R3.API.GraphicsRuntime.Impact.prototype.constructor = R3.API.GraphicsRuntime.Impact; diff --git a/bak/r3-api-graphics-runtime-three.js b/bak/r3-api-graphics-runtime-three.js new file mode 100644 index 0000000..78301ad --- /dev/null +++ b/bak/r3-api-graphics-runtime-three.js @@ -0,0 +1,30 @@ +/** + * R3.API.GraphicsRuntime.Three + * @constructor + * @param apiGraphicsRuntime + */ +R3.API.GraphicsRuntime.Three = function( + apiGraphicsRuntime +) { + if (R3.Utils.UndefinedOrNull(apiGraphicsRuntime)) { + apiGraphicsRuntime = { + graphicsType : R3.API.GraphicsRuntime.GRAPHICS_TYPE_THREE_JS + }; + } + + if (R3.Utils.UndefinedOrNull(apiGraphicsRuntime.graphicsType)) { + apiGraphicsRuntime.graphicsType = R3.API.GraphicsRuntime.GRAPHICS_TYPE_THREE_JS; + } + + R3.API.GraphicsRuntime.call( + this, + apiGraphicsRuntime.id, + apiGraphicsRuntime.name, + apiGraphicsRuntime.graphicsType, + apiGraphicsRuntime.parent + ); + +}; + +R3.API.GraphicsRuntime.Three.prototype = Object.create(R3.API.GraphicsRuntime.prototype); +R3.API.GraphicsRuntime.Three.prototype.constructor = R3.API.GraphicsRuntime.Three; diff --git a/bak/r3-api-number.js b/bak/r3-api-number.js new file mode 100644 index 0000000..4afe050 --- /dev/null +++ b/bak/r3-api-number.js @@ -0,0 +1,34 @@ +/** + * R3.API.Number + * @constructor + * @param value + * @param grain + * @param min + * @param max + */ +R3.API.Number = function( + value, + grain, + min, + max +) { + if (R3.Utils.UndefinedOrNull(value)) { + value = 0; + } + this.value = value; + + if (R3.Utils.UndefinedOrNull(grain)) { + grain = 0.1; + } + this.grain = grain; + + if (R3.Utils.UndefinedOrNull(min)) { + min = 0; + } + this.min = min; + + if (R3.Utils.UndefinedOrNull(max)) { + max = 100; + } + this.max = max; +}; \ No newline at end of file diff --git a/bak/r3-api-render-configuration.js b/bak/r3-api-render-configuration.js new file mode 100644 index 0000000..25a4a76 --- /dev/null +++ b/bak/r3-api-render-configuration.js @@ -0,0 +1,107 @@ +/** + * R3.API.RenderConfiguration + * @param id + * @param name + * @param parentEntity + * @param logicalSize + * @param aspectRatio + * @param scaleMode + * @param activeCamera + * @param activeScene + * @param activeScenes + * @param activeComposer + * @param activeEffect + * @param activeRenderer + * @param enableComposer + * @param enableEffect + * @param defaultMode + * @constructor + */ +R3.API.RenderConfiguration = function ( + id, + name, + parentEntity, + +) { + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = "RenderConfiguration (" + this.id + ")"; + } + this.name = name; + + if (R3.Utils.UndefinedOrNull(logicalSize)) { + logicalSize = new R3.API.Vector2( + 480, + 320 + ); + } + this.logicalSize = logicalSize; + + if (R3.Utils.UndefinedOrNull(aspectRatio)) { + aspectRatio = R3.API.Renderer.ASPECT_RATIO_3_2; + } + this.aspectRatio = aspectRatio; + + if (R3.Utils.UndefinedOrNull(scaleMode)) { + scaleMode = R3.API.Renderer.SCALE_MODE_LETTERBOX; + } + this.scaleMode = scaleMode; + + if (R3.Utils.UndefinedOrNull(activeCamera)) { + activeCamera = null; + } + this.activeCamera = activeCamera; + + if (R3.Utils.UndefinedOrNull(activeScene)) { + activeScene = null; + } + this.activeScene = activeScene; + + if (R3.Utils.UndefinedOrNull(activeScenes)) { + activeScenes = []; + } + this.activeScenes = activeScenes; + + if (R3.Utils.UndefinedOrNull(activeRenderer)) { + activeRenderer = null; + } + this.activeRenderer = activeRenderer; + + if (R3.Utils.UndefinedOrNull(activeComposer)) { + activeComposer = null; + } + this.activeComposer = activeComposer; + + if (R3.Utils.UndefinedOrNull(activeEffect)) { + activeEffect = null; + } + this.activeEffect = activeEffect; + + if (R3.Utils.UndefinedOrNull(enableComposer)) { + enableComposer = false; + } + this.enableComposer = enableComposer; + + if (R3.Utils.UndefinedOrNull(enableEffect)) { + enableEffect = false; + } + this.enableEffect = enableEffect; + + + + R3.API.Component.call( + this, + R3.Component.RENDER_CONFIGURATION, + parentEntity + ); + +}; + +R3.API.RenderConfiguration.prototype = Object.create(R3.API.Component.prototype); +R3.API.RenderConfiguration.prototype.constructor = R3.API.RenderConfiguration; + + diff --git a/bak/r3-api-renderer-d3-target.js b/bak/r3-api-renderer-d3-target.js new file mode 100644 index 0000000..ceda4a8 --- /dev/null +++ b/bak/r3-api-renderer-d3-target.js @@ -0,0 +1,63 @@ +/** + * R3.API.Renderer.D3.Target + * @constructor + * @param apiRendererD3 + * @param target + */ +R3.API.Renderer.D3.Target = function( + apiRendererD3, + target +) { + + if (R3.Utils.UndefinedOrNull(apiRendererD3)) { + apiRendererD3 = {}; + } + this.apiRendererD3 = apiRendererD3; + + R3.API.Renderer.D3.call( + this, + this.apiRendererD3, + this.apiRendererD3.autoClear, + this.apiRendererD3.autoClearColor, + this.apiRendererD3.autoClearDepth, + this.apiRendererD3.autoClearStencil, + this.apiRendererD3.gammaFactor, + this.apiRendererD3.gammaInput, + this.apiRendererD3.gammaOutput, + this.apiRendererD3.maxMorphTargets, + this.apiRendererD3.maxMorphNormals, + this.apiRendererD3.physicallyCorrectLights, + this.apiRendererD3.shadowMapEnabled, + this.apiRendererD3.shadowMapAutoUpdate, + this.apiRendererD3.shadowMapNeedsUpdate, + this.apiRendererD3.shadowMapType, + this.apiRendererD3.shadowMapRenderReverseSided, + this.apiRendererD3.shadowMapRenderSingleSided, + this.apiRendererD3.sortObjects, + this.apiRendererD3.toneMapping, + this.apiRendererD3.toneMappingExposure, + this.apiRendererD3.toneMappingWhitePoint, + this.apiRendererD3.premultipliedAlpha, + this.apiRendererD3.antialias, + this.apiRendererD3.stencil, + this.apiRendererD3.preserveDrawingBuffer, + this.apiRendererD3.depth, + this.apiRendererD3.logarithmicDepthBuffer, + this.apiRendererD3.localClippingEnabled, + this.apiRendererD3.clippingPlanes, + this.apiRendererD3.clearColor, + this.apiRendererD3.viewports, + this.apiRendererD3.alpha, + this.apiRendererD3.opacity, + this.apiRendererD3.pixelRatio + ); + + if (R3.Utils.UndefinedOrNull(target)) { + target = new R3.D3.API.RenderTarget(); + } + this.target = target; + +}; + +R3.API.Renderer.D3.Target.prototype = Object.create(R3.API.Renderer.D3.prototype); +R3.API.Renderer.D3.Target.prototype.constructor = R3.API.Renderer.D3.Target; diff --git a/bak/r3-ar.js b/bak/r3-ar.js new file mode 100644 index 0000000..72e1195 --- /dev/null +++ b/bak/r3-ar.js @@ -0,0 +1,482 @@ +/** + * AR object + * @param augmented + * @param apiAR + * @returns {R3.AR} + * @constructor + */ +R3.AR = function( + augmented, + apiAR +) { + this.augmented = augmented; + + if (R3.Utils.UndefinedOrNull(apiAR)) { + apiAR = {}; + } + + R3.API.AR.call( + this, + apiAR.id, + apiAR.name, + apiAR.parent, + apiAR.video, + apiAR.pathCamera, + apiAR.pathMarker, + apiAR.scene, + apiAR.camera, + apiAR.videoScene, + apiAR.videoCamera + ); + + if ( + R3.Utils.Defined(this.video) && + R3.Utils.Defined(this.video.componentType) && + !(this.video instanceof R3.Video) + ) { + this.video = R3.Component.ConstructFromObject(this.video); + } + + if ( + R3.Utils.Defined(this.scene) && + R3.Utils.Defined(this.scene.componentType) && + !(this.scene instanceof R3.D3.Scene) + ) { + this.scene = R3.Component.ConstructFromObject(this.scene); + } + + if ( + R3.Utils.Defined(this.camera) && + R3.Utils.Defined(this.camera.componentType) && + !(this.camera instanceof R3.D3.Camera.Orthographic) + ) { + this.camera = R3.Component.ConstructFromObject(this.camera); + } + + if ( + R3.Utils.Defined(this.videoScene) && + R3.Utils.Defined(this.videoScene.componentType) && + !(this.videoScene instanceof R3.D3.Scene) + ) { + this.videoScene = R3.Component.ConstructFromObject(this.videoScene); + } + + if ( + R3.Utils.Defined(this.videoCamera) && + R3.Utils.Defined(this.videoCamera.componentType) && + !(this.videoCamera instanceof R3.D3.Camera.Orthographic) + ) { + this.videoCamera = R3.Component.ConstructFromObject(this.videoCamera); + } + + R3.Component.call( + this, + { + 'video' : R3.Video, + 'scene' : R3.D3.Scene, + 'camera' : R3.D3.Camera, + 'videoScene' : R3.D3.Scene, + 'videoCamera' : R3.D3.Camera + } + ); + +}; + +R3.AR.prototype = Object.create(R3.Component.prototype); +R3.AR.prototype.constructor = R3.AR; + +/** + * Creates a light instance + * @returns {*} + */ +R3.AR.prototype.createInstance = function() { + + ARController.prototype.setupThree = function(arComponent) { + + return function() { + + if (this.THREE_JS_ENABLED) { + return; + } + + this.THREE_JS_ENABLED = true; + + /* + Listen to getMarker events to keep track of Three.js markers. + */ + this.addEventListener( + 'getMarker', + function (event) { + + if (event.data.type === artoolkit.PATTERN_MARKER) { + + // console.log('found marker'); + + /** + * We want to update the camera + */ + var modelViewMatrix = new THREE.Matrix4().fromArray(event.data.matrix); + + /** + * Apply context._axisTransformMatrix - change artoolkit axis to match usual webgl one + */ + var tmpMatrix = new THREE.Matrix4().copy(this._artoolkitProjectionAxisTransformMatrix); + + tmpMatrix.multiply(modelViewMatrix); + + modelViewMatrix.copy(tmpMatrix); + + /** + * Change axis orientation on marker - artoolkit say Z is normal to the marker - ar.js say Y is normal to the marker + */ + var markerAxisTransformMatrix = new THREE.Matrix4().makeRotationX(Math.PI / 2); + modelViewMatrix.multiply(markerAxisTransformMatrix); + arComponent.camera.instance.matrix.getInverse(modelViewMatrix); + + /** + * Decompose - the matrix into .position, .quaternion, .scale + */ + arComponent.camera.instance.matrix.decompose( + arComponent.camera.instance.position, + arComponent.camera.instance.quaternion, + arComponent.camera.instance.scale + ); + + // get projectionMatrixArr from artoolkit + var projectionMatrixArr = this.camera_mat; + + var projectionMatrix = new THREE.Matrix4().fromArray(projectionMatrixArr); + + // apply context._axisTransformMatrix - change artoolkit axis to match usual webgl one + projectionMatrix.multiply(this._artoolkitProjectionAxisTransformMatrix); + + arComponent.camera.instance.projectionMatrix.copy(projectionMatrix); + + arComponent.camera.updateFromInstance(); + + arComponent.camera.instance.fov = arComponent.camera.fov; + arComponent.camera.instance.near = arComponent.camera.near; + arComponent.camera.instance.far = arComponent.camera.far; + arComponent.camera.instance.filmGauge = arComponent.camera.filmGauge; + arComponent.camera.instance.filmOffset = arComponent.camera.filmOffset; + arComponent.camera.instance.focus = arComponent.camera.focus; + arComponent.camera.instance.zoom = arComponent.camera.zoom; + arComponent.camera.instance.aspect = arComponent.camera.aspect; + arComponent.camera.instance.updateProjectionMatrix(); + + + } + + } + ); + + this.threePatternMarkers = {}; + + this._artoolkitProjectionAxisTransformMatrix = new THREE.Matrix4(); + this._artoolkitProjectionAxisTransformMatrix.multiply(new THREE.Matrix4().makeRotationY(Math.PI)); + this._artoolkitProjectionAxisTransformMatrix.multiply(new THREE.Matrix4().makeRotationZ(Math.PI)); + } + }(this); + + R3.Event.Emit( + R3.Event.GET_RENDER_CONFIGURATION, + null, + function (renderConfiguration) { + + if (this.scene === null) { + this.scene = renderConfiguration.activeScene; + } + + if (this.camera === null) { + this.camera = renderConfiguration.activeCamera; + } + + if (this.renderer === null) { + this.renderer = renderConfiguration.activeRenderer; + } + + }.bind(this) + ); + + if (this.augmented.augmentedType === R3.AugmentedRuntime.JS_AR_TOOLKIT_5) { + + console.warn('Using js artoolkit 5'); + + if (this.scene === null) { + console.warn('there is no default scene to create an AR component with'); + return; + } + + if (this.camera === null) { + console.warn('there is no default camera to create an AR component with'); + return; + } + + ARController.getUserMediaThreeScene( + { + maxARVideoSize: 320, + cameraParam: this.pathCamera, + + onSuccess: function (arScene, + arController, + arCamera) { + + R3.Event.Emit( + R3.Event.GET_RENDER_CONFIGURATION, + null, + function(renderConfiguration) { + + this.videoCamera.instance = arScene.videoCamera; + + this.videoScene.instance = arScene.videoScene; + + this.videoScene.camera = this.videoCamera; + + //arScene.videoScene.children[0].material.map.flipY = true; + + /** + * Also update the video texture before render + */ + this.subscribe( + R3.Event.BEFORE_RENDER, + function() { + arScene.videoScene.children[0].material.map.needsUpdate = true; + } + ); + + if (renderConfiguration.activeScenes.indexOf(this.videoScene) === -1) { + console.log('not adding video scene to default active scenes'); + //renderConfiguration.activeScenes.unshift(this.videoScene); + } + + }.bind(this) + ); + + arController.loadMarker( + this.pathMarker, + function (markerId) { + + var markerRoot = arController.createThreeMarker(markerId); + + markerRoot.add(this.scene.instance); + + this.instance = { + arScene: arScene, + arController: arController, + arCamera: arCamera + }; + + R3.Component.prototype.createInstance.call(this); + + }.bind(this) + ); + + }.bind(this) + } + ); + + return; + } + + if (this.augmented.augmentedType === R3.AugmentedRuntime.AR_JS) { + + console.log('using ar.js'); + + var size = R3.Utils.GetWindowSize(); + + this.arToolkitSource = new THREEx.ArToolkitSource( + { + sourceType: 'webcam', + sourceWidth: size.width, + sourceHeight: size.height, + displayWidth: size.width, + displayHeight: size.height + } + ); + + this.arToolkitSource.init( + + function initialized() { + + this.arToolkitSource.domElement.setAttribute('muted', ''); + + this.video.instance = this.arToolkitSource.domElement; + + this.arToolkitContext = new THREEx.ArToolkitContext( + { + cameraParametersUrl: this.pathCamera, + detectionMode: 'mono', + maxDetectionRate: 30, + canvasWidth: 80*3, + canvasHeight: 60*3 + } + ); + + this.arToolkitContext.init( + + function initialized() { + + this.controls = new THREEx.ArMarkerControls( + this.arToolkitContext, + this.camera.instance, + { + type: 'pattern', + patternUrl: this.pathMarker, + changeMatrixMode: 'cameraTransformMatrix' + } + ); + + this.instance = { + arToolkitContext: this.arToolkitContext, + arToolkitSource: this.arToolkitSource + }; + + this.scene.instance.add(this.camera.instance); + + this.resize(); + + /** + * Copy the projectionmatrix of the context to our camera + * UPDATE - don't do this cause it messes up the projection matrix + */ + // this.camera.instance.projectionMatrix.copy( + // this.arToolkitContext.getProjectionMatrix() + // ); + + + R3.Component.prototype.createInstance.call(this); + + }.bind(this) + ) + + }.bind(this) + ); + } + +}; + +/** + * Updates the instance with the current state + */ +R3.AR.prototype.updateInstance = function(property) { + + if (R3.Utils.UndefinedOrNull(property)) { + console.warn('unknown property update for AR: ' + property); + } + + if (property === 'id') { + return; + } + + if (property === 'name') { + return; + } + + if (property === 'video') { + console.warn('todo: update video'); + return; + } + + if (property === 'pathCamera') { + console.warn('todo: update pathCamera'); + return; + } + + if (property === 'pathMarker') { + console.warn('todo: update pathMarker'); + return; + } + + if (property === 'scene') { + console.warn('todo: update scene'); + return; + } + + if (property === 'camera') { + console.warn('todo: update camera'); + // + // if (this.augmented.augmentedType === R3.AugmentedRuntime.AR_JS) { + // + // if (this.camera) { + // this.controls = new THREEx.ArMarkerControls( + // this.arToolkitContext, + // this.camera.instance, + // { + // type: 'pattern', + // patternUrl: this.pathMarker, + // changeMatrixMode: 'cameraTransformMatrix' + // } + // ); + // } + // } + + return; + } + + if (property === 'videoScene') { + console.warn('todo: update videoScene'); + return; + } + + if (property === 'videoCamera') { + console.warn('todo: update videoCamera'); + return; + } + + R3.Component.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.AR to a R3.API.AR + * @returns {R3.API.AR} + */ +R3.AR.prototype.toApiObject = function() { + + return new R3.API.AR( + this.id, + this.name, + R3.Utils.IdOrNull(this.parent), + R3.Utils.IdOrNull(this.video), + this.pathCamera, + this.pathMarker, + R3.Utils.IdOrNull(this.scene), + R3.Utils.IdOrNull(this.camera), + R3.Utils.IdOrNull(this.videoScene), + R3.Utils.IdOrNull(this.videoCamera) + ); +}; + +R3.AR.prototype.beforeRender = function() { + + if (this.augmented.augmentedType === R3.AugmentedRuntime.JS_AR_TOOLKIT_5) { + this.instance.arScene.process(); + this.instance.arScene.renderOn(renderer.instance); + return; + } + + if (this.augmented.augmentedType === R3.AugmentedRuntime.AR_JS) { + this.arToolkitContext.update( + this.arToolkitSource.domElement + ); + return; + } + +}; + +R3.AR.prototype.resize = function() { + + if (this.augmented.augmentedType === R3.AugmentedRuntime.AR_JS) { + + console.log('updating AR size'); + + this.arToolkitSource.onResizeElement(); + + if (this.arToolkitContext.arController !== null){ + this.arToolkitSource.copyElementSizeTo( + this.arToolkitContext.arController.canvas + ) + } + + } + +}; \ No newline at end of file diff --git a/bak/r3-augmented-runtime.js b/bak/r3-augmented-runtime.js new file mode 100644 index 0000000..0a44c62 --- /dev/null +++ b/bak/r3-augmented-runtime.js @@ -0,0 +1,53 @@ +/** + * Augmented + * @param id + * @param name + * @param augmentedType + * @constructor + */ +R3.AugmentedRuntime = function( + id, + name, + augmentedType +) { + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = 'Augmented (' + id + ')'; + } + this.name = name; + + if (R3.Utils.UndefinedOrNull(augmentedType)) { + augmentedType = R3.AugmentedRuntime.JS_AR_TOOLKIT_5; + } + this.augmentedType = augmentedType; + + this.createInstance(); +}; + +/** + * R3.AugmentedRuntime Types + * @type {number} + */ +R3.AugmentedRuntime.JS_AR_TOOLKIT_5 = 0x1; +R3.AugmentedRuntime.AR_JS = 0x2; + +R3.AugmentedRuntime.prototype.createInstance = function() { + if (this.augmentedType === R3.AugmentedRuntime.JS_AR_TOOLKIT_5) { + this.instance = { + ARController : ARController, + ARCameraParam : ARCameraParam + }; + } else { + this.instance = null; + } +}; + +R3.AugmentedRuntime.prototype.updateInstance = function(property) { + if (property === 'augmentedType') { + this.createInstance(); + } +}; diff --git a/bak/r3-controls-d3-editor.js b/bak/r3-controls-d3-editor.js new file mode 100644 index 0000000..050fd84 --- /dev/null +++ b/bak/r3-controls-d3-editor.js @@ -0,0 +1,48 @@ +/** + * R3.Controls.D3.Editor + * @param apiComponent + * @constructor + */ +R3.Controls.D3.Editor = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Controls.D3.call( + this, + true + ); + +}; + +/** + * Inheritance + * @type {R3.Controls} + */ +R3.Controls.D3.Editor.prototype = Object.create(R3.Controls.D3.prototype); +R3.Controls.D3.Editor.prototype.constructor = R3.Controls.D3.Editor; + +/** + * Create Instance + */ +R3.Controls.D3.Editor.prototype.createInstance = function() { + + this.instance = this.graphics.EditorControls(this); + + __CREATE_INSTANCE__; +}; + +/** + * Update Instance + */ +R3.Controls.D3.Editor.prototype.updateInstance = function(property) { + + if ( + property === 'raycaster' + ) { + console.warn('todo : update raycaster'); + } + + R3.Controls.D3.prototype.updateInstance.call(this, property); +}; diff --git a/bak/r3-d3-api-camera-stereo-anaglyph.js b/bak/r3-d3-api-camera-stereo-anaglyph.js new file mode 100644 index 0000000..5ba0989 --- /dev/null +++ b/bak/r3-d3-api-camera-stereo-anaglyph.js @@ -0,0 +1,81 @@ +/** + * R3.D3.API.Camera.Stereo.Anaglyph + * @constructor + * @param apiStereoCamera + * @param colorMatrixLeft + * @param colorMatrixRight + * @param orthographicCamera + * @param orthographicScene + */ +R3.D3.API.Camera.Stereo.Anaglyph = function( + apiStereoCamera, + colorMatrixLeft, + colorMatrixRight, + orthographicCamera, + orthographicScene, + renderTargetL, + renderTargetR, + shaderMaterial, + meshPlane +) { + + if (R3.Utils.UndefinedOrNull(apiStereoCamera)) { + apiStereoCamera = { + stereoType : R3.D3.API.Camera.Stereo.STEREO_MODE_ANAGLYPH + }; + } + + if (R3.Utils.UndefinedOrNull(apiStereoCamera.stereoType)) { + apiStereoCamera.stereoType = R3.D3.API.Camera.Stereo.STEREO_MODE_ANAGLYPH; + } + + if (R3.Utils.UndefinedOrNull(colorMatrixLeft)) { + colorMatrixLeft = [ + 1.0671679973602295, -0.0016435992438346148, 0.0001777536963345483, // r out + -0.028107794001698494, -0.00019593400065787137, -0.0002875397040043026, // g out + -0.04279090091586113, 0.000015809757314855233, -0.00024287120322696865 // b out + ] + } + this.colorMatrixLeft = colorMatrixLeft; + + if (R3.Utils.UndefinedOrNull(colorMatrixRight)) { + colorMatrixRight = [ + -0.0355340838432312, -0.06440307199954987, 0.018319187685847282, // r out + -0.10269022732973099, 0.8079727292060852, -0.04835830628871918, // g out + 0.0001224992738571018, -0.009558862075209618, 0.567823588848114 // b out + ] + } + this.colorMatrixRight = colorMatrixRight; + + if (R3.Utils.UndefinedOrNull(orthographicCamera)) { + orthographicCamera = new R3.D3.API.Camera.Orthographic(null, null, 0, 1, -1, 1, 1, -1); + } + this.orthographicCamera = orthographicCamera; + + if (R3.Utils.UndefinedOrNull(orthographicScene)) { + orthographicScene = new R3.D3.API.Scene(null, 'Orthographic Stereo Anaglyph Scene'); + } + this.orthographicScene = orthographicScene; + // + // if (R3.Utils.UndefinedOrNull(renderTargetL)) { + // renderTargetL = new R3.D3.API.RenderTarget(null, null, null, ) + // } + // + // renderTargetL, + // renderTargetR, + // shaderMaterial, + // meshPlane + + R3.D3.API.Camera.Stereo.call( + this, + apiStereoCamera, + apiStereoCamera.stereoType, + apiStereoCamera.eyeSep, + apiStereoCamera.main, + apiStereoCamera.cameraL, + apiStereoCamera.cameraR + ); +}; + +R3.D3.API.Camera.Stereo.Anaglyph.prototype = Object.create(R3.D3.API.Camera.Stereo.prototype); +R3.D3.API.Camera.Stereo.Anaglyph.prototype.constructor = R3.D3.API.Camera.Stereo.Anaglyph; diff --git a/bak/r3-d3-api-camera-stereo-normal.js b/bak/r3-d3-api-camera-stereo-normal.js new file mode 100644 index 0000000..4445e16 --- /dev/null +++ b/bak/r3-d3-api-camera-stereo-normal.js @@ -0,0 +1,32 @@ +/** + * R3.D3.API.Camera.Stereo.Normal + * @constructor + * @param apiStereoCamera + */ +R3.D3.API.Camera.Stereo.Normal = function( + apiStereoCamera +) { + + if (R3.Utils.UndefinedOrNull(apiStereoCamera)) { + apiStereoCamera = { + stereoType : R3.D3.API.Camera.Stereo.STEREO_TYPE_NORMAL + }; + } + + if (R3.Utils.UndefinedOrNull(apiStereoCamera.stereoType)) { + apiStereoCamera.stereoType = R3.D3.API.Camera.Stereo.STEREO_TYPE_NORMAL; + } + + R3.D3.API.Camera.Stereo.call( + this, + apiStereoCamera, + apiStereoCamera.stereoType, + apiStereoCamera.eyeSep, + apiStereoCamera.main, + apiStereoCamera.cameraL, + apiStereoCamera.cameraR + ); +}; + +R3.D3.API.Camera.Stereo.Normal.prototype = Object.create(R3.D3.API.Camera.Stereo.prototype); +R3.D3.API.Camera.Stereo.Normal.prototype.constructor = R3.D3.API.Camera.Stereo.Normal; \ No newline at end of file diff --git a/bak/r3-d3-api-composer-render-target.js b/bak/r3-d3-api-composer-render-target.js new file mode 100644 index 0000000..9f63613 --- /dev/null +++ b/bak/r3-d3-api-composer-render-target.js @@ -0,0 +1,30 @@ +/** + * R3.D3.API.Composer.RenderTarget + * @param apiComponent + * + * @property renderTarget + * + * @constructor + */ +R3.D3.API.Composer.RenderTarget = function( + apiComponent +) { + + R3.D3.API.Composer.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.renderTarget)) { + apiComponent.renderTarget = new R3.D3.API.RenderTarget( + { + parent : this + } + ); + } + this.renderTarget = apiComponent.renderTarget + +}; + +R3.D3.API.Composer.RenderTarget.prototype = Object.create(R3.D3.API.Composer.prototype); +R3.D3.API.Composer.RenderTarget.prototype.constructor = R3.D3.API.Composer.RenderTarget; diff --git a/bak/r3-d3-api-composer-renderer.js b/bak/r3-d3-api-composer-renderer.js new file mode 100644 index 0000000..c8ec09a --- /dev/null +++ b/bak/r3-d3-api-composer-renderer.js @@ -0,0 +1,26 @@ +/** + * R3.D3.API.Composer.Renderer + * @param apiComposer + * + * @property renderer + * + * @constructor + */ +R3.D3.API.Composer.Renderer = function( + apiComposer +) { + + R3.D3.API.Composer.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.renderer)) { + apiComponent.renderer = this.getFirstParent(R3.API.Renderer.D3); + } + this.renderer = apiComponent.renderer; + +}; + +R3.D3.API.Composer.Renderer.prototype = Object.create(R3.D3.API.Composer.prototype); +R3.D3.API.Composer.Renderer.prototype.constructor = R3.D3.API.Composer.Renderer; diff --git a/bak/r3-d3-api-editor.js b/bak/r3-d3-api-editor.js new file mode 100644 index 0000000..2caa4f3 --- /dev/null +++ b/bak/r3-d3-api-editor.js @@ -0,0 +1,255 @@ +/** + * Raw Editor API object - should always correspond with the Editor Schema + * @param id + * @param name + * @param baseUrl + * @param path + * @param imageFactory + * @param games [R3.API.D3.Game] + * @param scenes + * @param cameras + * @param composers + * @param viewports + * @param renderers + * @param renderTargets + * @param systems + * @param entityManager + * @param allSelected + * @param selectedObjects + * @param parentEntity + * @constructor + */ +R3.D3.API.Editor = function( + id, + name, + baseUrl, + path, + imageFactory, + games, + scenes, + cameras, + composers, + viewports, + renderers, + renderTargets, + systems, + entityManager, + allSelected, + selectedObjects, + parentEntity +) { + R3.Component.call( + this, + R3.Component.COMPONENT_EDITOR, + { + 'imageFactory' : R3.D3.ImageFactory, + 'games' : [R3.D3.Game], + 'scenes' : [R3.D3.Scene], + 'cameras' : [R3.D3.Camera], + 'composers' : [R3.D3.Composer], + 'viewports' : [R3.D3.Viewport], + 'renderers' : [R3.D3.Renderer], + 'renderTargets' : [R3.D3.RenderTarget], + 'systems' : [R3.System], + 'entityManager' : R3.EntityManager + }, + null, + parentEntity + ); + + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = 'Editor (' + this.id + ')'; + } + this.name = name; + + if (R3.Utils.UndefinedOrNull(baseUrl)) { + baseUrl = ''; + } + this.baseUrl = baseUrl; + + if (R3.Utils.UndefinedOrNull(path)) { + path = ''; + } + this.path = path; + + if (R3.Utils.UndefinedOrNull(imageFactory)) { + imageFactory = null; + } + this.imageFactory = imageFactory; + + if (R3.Utils.UndefinedOrNull(games)) { + games = []; + } + this.games = games; + + if (R3.Utils.UndefinedOrNull(scenes)) { + scenes = []; + } + this.scenes = scenes; + + if (R3.Utils.UndefinedOrNull(cameras)) { + cameras = []; + } + this.cameras = cameras; + + if (R3.Utils.UndefinedOrNull(composers)) { + composers = []; + } + this.composers = composers; + + if (R3.Utils.UndefinedOrNull(viewports)) { + viewports = []; + } + this.viewports = viewports; + + if (R3.Utils.UndefinedOrNull(renderers)) { + renderers = []; + } + this.renderers = renderers; + + if (R3.Utils.UndefinedOrNull(renderTargets)) { + renderTargets = []; + } + this.renderTargets = renderTargets; + + if (R3.Utils.UndefinedOrNull(systems)) { + systems = []; + } + this.systems = systems; + + if (R3.Utils.UndefinedOrNull(entityManager)) { + entityManager = new R3.API.EntityManager(); + } + this.entityManager = entityManager; + + if (R3.Utils.UndefinedOrNull(allSelected)) { + allSelected = false; + } + this.allSelected = allSelected; + + if (R3.Utils.UndefinedOrNull(selectedObjects)) { + selectedObjects = []; + } + this.selectedObjects = selectedObjects; + +}; + +R3.D3.API.Editor.prototype = Object.create(R3.Component.prototype); +R3.D3.API.Editor.prototype.constructor = R3.D3.API.Editor; + +/** + * Creates an API Editor from an Object Editor + * @param objectEditor + * @constructor + */ +R3.D3.API.Editor.FromObjectEditor = function(objectEditor) { + + var apiImageFactory = null; + var apiGames = []; + var apiScenes = []; + var apiCameras = []; + var apiComposers = []; + var apiViewports = []; + var apiRenderers = []; + var apiRenderTargets = []; + var apiSystems = []; + var apiEntityManager = null; + + if (objectEditor.imageFactory) { + apiImageFactory = R3.D3.API.ImageFactory.FromObjectImageFactory(objectEditor.imageFactory); + } + + if (objectEditor.games) { + apiGames = objectEditor.games.map( + function(objectGame){ + return R3.D3.API.Game.FromObjectGame(objectGame); + } + ); + } + + if (objectEditor.scenes) { + apiScenes = objectEditor.scenes.map( + function(objectScene){ + return R3.D3.API.Scene.FromObjectScene(objectScene); + } + ); + } + + if (objectEditor.cameras) { + apiCameras = objectEditor.cameras.map( + function(objectCamera){ + return R3.D3.API.Camera.FromObjectCamera(objectCamera); + } + ); + } + + if (objectEditor.composers) { + apiComposers = objectEditor.composers.map( + function(objectComposer){ + return R3.D3.API.Composer.FromObjectComponent(objectComposer); + } + ); + } + + if (objectEditor.viewports) { + apiViewports = objectEditor.viewports.map( + function(objectViewport){ + return R3.D3.API.Viewport.FromObjectViewport(objectViewport); + } + ); + } + + if (objectEditor.renderers) { + apiRenderers = objectEditor.renderers.map( + function(objectRenderer){ + return R3.D3.API.Renderer.FromObjectComponent(objectRenderer); + } + ); + } + + if (objectEditor.renderTargets) { + apiRenderTargets = objectEditor.renderTargets.map( + function(objectRenderTarget){ + return R3.D3.API.RenderTarget.FromObjectComponent(objectRenderTarget); + } + ); + } + + if (objectEditor.systems) { + apiSystems = objectEditor.systems.map( + function(objectSystem){ + return R3.API.System.FromObjectComponent(objectSystem); + } + ); + } + + if (objectEditor.entityManager) { + apiEntityManager = R3.API.EntityManager.FromObjectEntityManager(objectEditor.entityManager); + } + + return new R3.D3.API.Editor( + objectEditor.id, + objectEditor.name, + objectEditor.baseUrl, + objectEditor.path, + apiImageFactory, + apiGames, + apiScenes, + apiCameras, + apiComposers, + apiViewports, + apiRenderers, + apiRenderTargets, + apiSystems, + apiEntityManager, + objectEditor.allSelected, + objectEditor.selectedObjects, + objectEditor.parentEntity + ); +}; + diff --git a/bak/r3-d3-api-follow.js b/bak/r3-d3-api-follow.js new file mode 100644 index 0000000..2f36174 --- /dev/null +++ b/bak/r3-d3-api-follow.js @@ -0,0 +1,98 @@ +/** + * Follow Component + * @param id + * @param name + * @param currentComponent R3.Component + * @param targetComponent R3.Component + * @param targetPositionOffset R3.API.Vector3 + * @param minDistance + * @param moveSpeed + * @param parentEntity + * @constructor + */ +R3.D3.API.Follow = function ( + id, + name, + currentComponent, + targetComponent, + targetPositionOffset, + minDistance, + moveSpeed, + parentEntity +) { + + R3.Component.call( + this, + R3.Component.COMPONENT_FOLLOW, + { + 'currentComponent': R3.Component, + 'targetComponent': R3.Component + }, + parentEntity + ); + + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = this.constructor.name; + } + this.name = name; + + if (R3.Utils.UndefinedOrNull(currentComponent)) { + currentComponent = null; + } + this.currentComponent = currentComponent; + + if (R3.Utils.UndefinedOrNull(targetComponent)) { + targetComponent = null; + } + this.targetComponent = targetComponent; + + if(R3.Utils.UndefinedOrNull(targetPositionOffset)) { + targetPositionOffset = new R3.API.Vector3(0, 0, 0); + } + this.targetPositionOffset = targetPositionOffset; + + if (R3.Utils.UndefinedOrNull(minDistance)) { + minDistance = 2; + } + this.minDistance = minDistance; + + if (R3.Utils.UndefinedOrNull(moveSpeed)) { + moveSpeed = 12.5; + } + this.moveSpeed = moveSpeed; + + this.target = new R3.API.Vector3(0, 0, 0); + + this.targetToParent = new R3.API.Vector3(0, 0, 0); + + this.rotatedTargetOffset = new R3.API.Vector3(0, 0, 0); + + this.rotated = new R3.API.Quaternion(); +}; + +R3.D3.API.Follow.prototype = Object.create(R3.Component.prototype); +R3.D3.API.Follow.prototype.constructor = R3.D3.API.Follow; + +/** + * Object to R3.D3.API.Follow + * @param objectComponent + * @returns {R3.D3.API.Follow} + * @constructor + */ +R3.D3.API.Follow.FromObject = function(objectComponent) { + return new R3.D3.API.Follow( + objectComponent.id, + objectComponent.name, + objectComponent.currentComponent, + objectComponent.targetComponent, + R3.API.Vector3.FromObject(objectComponent.targetPositionOffset), + objectComponent.minDistance, + objectComponent.moveSpeed, + objectComponent.parentEntity + ); +}; diff --git a/bak/r3-d3-api-game.js b/bak/r3-d3-api-game.js new file mode 100644 index 0000000..343cc3f --- /dev/null +++ b/bak/r3-d3-api-game.js @@ -0,0 +1,215 @@ +/** + * Raw Game API object - should always correspond with the Game Schema + * @param id + * @param name + * @param gameType + * @param imageFactory + * @param width + * @param height + * @param baseUrl + * @param path + * @param cameras + * @param renderers + * @param composers + * @param renderTargets + * @param systems + * @param viewports + * @param entityManager + * @param parentEntity + * @constructor + */ +R3.D3.API.Game = function( + id, + name, + baseUrl, + path, + imageFactory, + gameType, + cameras, + composers, + viewports, + renderers, + renderTargets, + systems, + entityManager, + parentEntity +) { + R3.Component.call( + this, + R3.Component.COMPONENT_GAME, + { + 'imageFactory' : R3.D3.ImageFactory, + 'cameras' : [R3.D3.Camera], + 'composers' : [R3.D3.Composer], + 'viewports' : [R3.D3.Viewport], + 'renderers' : [R3.D3.Renderer], + 'renderTargets' : [R3.D3.RenderTarget], + 'systems' : [R3.System], + 'entityManager' : R3.EntityManager + }, + null, + parentEntity + ); + + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = 'Game (' + this.id + ')'; + } + this.name = name; + + if (R3.Utils.UndefinedOrNull(baseUrl)) { + baseUrl = ''; + console.warn('The base URL required for downloading images is not set - textured meshes will not render properly'); + } + this.baseUrl = baseUrl; + + if (R3.Utils.UndefinedOrNull(path)) { + path = ''; + } + this.path = path; + + if (R3.Utils.UndefinedOrNull(imageFactory)) { + imageFactory = null; + } + this.imageFactory = imageFactory; + + if (R3.Utils.UndefinedOrNull(gameType)) { + gameType = R3.D3.Game.GAME_TYPE_VR_PONG; + } + this.gameType = gameType; + + if (R3.Utils.UndefinedOrNull(cameras)) { + cameras = []; + } + this.cameras = cameras; + + if (R3.Utils.UndefinedOrNull(composers)) { + composers = []; + } + this.composers = composers; + + if (R3.Utils.UndefinedOrNull(viewports)) { + viewports = []; + } + this.viewports = viewports; + + if (R3.Utils.UndefinedOrNull(renderers)) { + renderers = []; + } + this.renderers = renderers; + + if (R3.Utils.UndefinedOrNull(renderTargets)) { + renderTargets = []; + } + this.renderTargets = renderTargets; + + if (R3.Utils.UndefinedOrNull(systems)) { + systems = []; + } + this.systems = systems; + + if (R3.Utils.UndefinedOrNull(entityManager)) { + entityManager = null; + } + this.entityManager = entityManager; + +}; + +R3.D3.API.Game.prototype = Object.create(R3.Component.prototype); +R3.D3.API.Game.prototype.constructor = R3.D3.API.Game; + +/** + * Creates an API camera from an Object camera + * @param objectGame + * @constructor + */ +R3.D3.API.Game.FromObjectGame = function(objectGame) { + + var apiImageFactory = null; + var apiCameras = []; + var apiComposers = []; + var apiViewports = []; + var apiRenderers = []; + var apiRenderTargets = []; + var apiSystems = []; + + var apiEntityManager = null; + + if (objectGame.imageFactory) { + apiImageFactory = R3.D3.API.ImageFactory.FromObjectImageFactory(objectGame.imageFactory); + } + + if (objectGame.cameras) { + apiCameras = objectGame.cameras.map( + function(objectCamera){ + return R3.D3.API.Camera.FromObjectCamera(objectCamera); + } + ); + } + + if (objectGame.composers) { + apiComposers = objectGame.composers.map( + function(objectComposer){ + return R3.D3.API.Composer.FromObjectComponent(objectComposer); + } + ); + } + + if (objectGame.viewports) { + apiViewports = objectGame.viewports.map( + function(objectViewport){ + return R3.D3.API.Viewport.FromObjectViewport(objectViewport); + } + ); + } + + if (objectGame.renderers) { + apiRenderers = objectGame.renderers.map( + function(objectRenderer){ + return R3.D3.API.Renderer.FromObjectComponent(objectRenderer); + } + ); + } + + if (objectGame.renderTargets) { + apiRenderTargets = objectGame.renderTargets.map( + function(objectRenderTarget){ + return R3.D3.API.RenderTarget.FromObjectComponent(objectRenderTarget); + } + ); + } + + if (objectGame.systems) { + apiSystems = objectGame.systems.map( + function(objectSystem){ + return R3.API.System.FromObjectComponent(objectSystem); + } + ); + } + + if (objectGame.entityManager) { + apiEntityManager = R3.API.EntityManager.FromObjectEntityManager(objectGame.entityManager); + } + + return new R3.D3.API.Game( + objectGame.id, + objectGame.name, + objectGame.baseUrl, + objectGame.path, + apiImageFactory, + objectGame.gameType, + apiCameras, + apiComposers, + apiViewports, + apiRenderers, + apiRenderTargets, + apiSystems, + apiEntityManager, + objectGame.parentEntity + ); + +}; diff --git a/bak/r3-d3-api-graphics.js b/bak/r3-d3-api-graphics.js new file mode 100644 index 0000000..d88fb90 --- /dev/null +++ b/bak/r3-d3-api-graphics.js @@ -0,0 +1,39 @@ +/** + * Graphics API + * @param id String + * @param name + * @param graphicsType + * @param parentEntity + * @constructor + */ +R3.D3.API.Graphics = function ( + parentEntity +) { + + R3.Component.call( + this, + R3.Component.COMPONENT_GRAPHICS, + null, + null, + parentEntity + ); + + +}; + +R3.D3.API.Graphics.prototype = Object.create(R3.Component.prototype); +R3.D3.API.Graphics.prototype.constructor = R3.D3.API.Graphics; + +/** + * Object to R3.D3.API.Graphics + * @param objectComponent + * @constructor + */ +R3.D3.API.Graphics.FromObjectComponent = function(objectComponent) { + return new R3.D3.API.Graphics( + objectComponent.id, + objectComponent.name, + objectComponent.graphicsType, + objectComponent.parentEntity + ); +}; diff --git a/bak/r3-d3-api-helper.js b/bak/r3-d3-api-helper.js new file mode 100644 index 0000000..36a9548 --- /dev/null +++ b/bak/r3-d3-api-helper.js @@ -0,0 +1,87 @@ +/** + * This component renders a scene + * @param id String + * @param name String + * @param helperType + * @param object + * @param parentEntity + * @constructor + */ +R3.D3.API.Helper = function ( + id, + name, + helperType, + object, + parentEntity +) { + + R3.Component.call( + this, + R3.Component.COMPONENT_HELPER, + null, + null, + parentEntity + ); + + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = 'Helper (' + id + ')'; + } + this.name = name; + + if (R3.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'); + } + + if (R3.Utils.UndefinedOrNull(helperType)) { + if ( + object instanceof R3.D3.Mesh && + object.meshType != R3.D3.Mesh.TYPE_CURVE + ) { + helperType = R3.D3.Helper.HELPER_TYPE_WIREFRAME; + } + + if (object instanceof R3.D3.Light) { + if (object.lightType == R3.D3.Light.LIGHT_TYPE_DIRECTIONAL) { + helperType = R3.D3.Helper.HELPER_TYPE_DIRECTIONAL_LIGHT; + } + + if (object.lightType == R3.D3.Light.LIGHT_TYPE_POINT) { + helperType = R3.D3.Helper.HELPER_TYPE_POINT_LIGHT; + } + + if (object.lightType == R3.D3.Light.LIGHT_TYPE_SPOT) { + helperType = R3.D3.Helper.HELPER_TYPE_SPOT_LIGHT; + } + } + + if (object instanceof R3.D3.Skeleton) { + helperType = R3.D3.Helper.HELPER_TYPE_SKELETON; + } + } + this.helperType = helperType; + +}; + +R3.D3.API.Helper.prototype = Object.create(R3.Component.prototype); +R3.D3.API.Helper.prototype.constructor = R3.D3.API.Helper; + +/** + * Object to R3.D3.API.Helper + * @param objectComponent + * @constructor + */ +R3.D3.API.Helper.FromObjectComponent = function(objectComponent) { + return new R3.D3.API.Helper( + objectComponent.id, + objectComponent.name, + objectComponent.helperType, + objectComponent.object, + objectComponent.parentEntity + ); +}; diff --git a/bak/r3-d3-api-image-factory.js b/bak/r3-d3-api-image-factory.js new file mode 100644 index 0000000..61754ea --- /dev/null +++ b/bak/r3-d3-api-image-factory.js @@ -0,0 +1,52 @@ +/** + * Raw ImageFactory API object - should always correspond with the ImageFactory Schema + * @param id + * @param name + * @param baseUrl String + * @param parentEntity + * @constructor + */ +R3.D3.API.ImageFactory = function( + id, + name, + baseUrl, + parentEntity +) { + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = 'ImageFactory (' + this.id + ')'; + } + this.name = name; + + if (R3.Utils.UndefinedOrNull(baseUrl)) { + baseUrl = ''; + console.warn('No baseURL defined for image factory'); + } + this.baseUrl = baseUrl; + + if (R3.Utils.UndefinedOrNull(parentEntity)) { + parentEntity = null; + } + this.parentEntity = parentEntity; +}; + +R3.D3.API.ImageFactory.prototype = Object.create(R3.Component.prototype); +R3.D3.API.ImageFactory.prototype.constructor = R3.D3.API.ImageFactory; + +/** + * Returns an API ImageFactory from an Object ImageFactory + * @param objectImageFactory + * @constructor + */ +R3.D3.API.ImageFactory.FromObject = function(objectImageFactory) { + return new R3.D3.API.ImageFactory( + objectImageFactory.id, + objectImageFactory.name, + objectImageFactory.baseUrl, + objectImageFactory.parentEntity + ); +}; diff --git a/bak/r3-d3-api-input-a.js b/bak/r3-d3-api-input-a.js new file mode 100644 index 0000000..ce88a99 --- /dev/null +++ b/bak/r3-d3-api-input-a.js @@ -0,0 +1,5 @@ +/** + * R3.D3.API.Input namespace + * @constructor + */ +R3.D3.API.Input = function() {}; diff --git a/bak/r3-d3-api-input-drive.js b/bak/r3-d3-api-input-drive.js new file mode 100644 index 0000000..648e159 --- /dev/null +++ b/bak/r3-d3-api-input-drive.js @@ -0,0 +1,125 @@ +/** + * This component makes the parentEntity (ex. car) follow the path provided by the spline + * @param id String + * @param name String + * @param domElementId + * @param pathFollowingComponent R3.D3.Mesh + * @param parentEntity + * @param wheelFL + * @param wheelFR + * @param wheelRL + * @param wheelRR + * @param heightOffset + * @param distance + * @param distanceGrain + * @param rotationFactor + * @constructor + */ +R3.D3.API.Input.Drive = function ( + id, + name, + domElementId, + pathFollowingComponent, + parentEntity, + wheelFL, + wheelFR, + wheelRL, + wheelRR, + heightOffset, + distance, + distanceGrain, + rotationFactor +) { + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = 'Input.Drive (' + this.id + ')'; + } + this.name = name; + + if (R3.Utils.UndefinedOrNull(domElementId)) { + domElementId = "divCanvas"; + } + this.domElementId = domElementId; + + if (R3.Utils.UndefinedOrNull(pathFollowingComponent)) { + pathFollowingComponent = null; + } + this.pathFollowingComponent = pathFollowingComponent; + + if (R3.Utils.UndefinedOrNull(parentEntity)) { + parentEntity = null; + } + this.parentEntity = parentEntity; + + if (R3.Utils.UndefinedOrNull(wheelFL)) { + wheelFL = null; + } + this.wheelFL = wheelFL; + + if (R3.Utils.UndefinedOrNull(wheelFR)) { + wheelFR = null; + } + this.wheelFR = wheelFR; + + if (R3.Utils.UndefinedOrNull(wheelRL)) { + wheelRL = null; + } + this.wheelRL = wheelRL; + + if (R3.Utils.UndefinedOrNull(wheelRR)) { + wheelRR = null; + } + this.wheelRR = wheelRR; + + if (R3.Utils.UndefinedOrNull(heightOffset)) { + heightOffset = 0; + } + this.heightOffset = heightOffset; + + if (R3.Utils.UndefinedOrNull(distance)) { + distance = 0; + } + this.distance = distance; + + if (R3.Utils.UndefinedOrNull(distanceGrain)) { + distanceGrain = 0.1; + } + this.distanceGrain = distanceGrain; + + if (R3.Utils.UndefinedOrNull(rotationFactor)) { + rotationFactor = 0.1; + } + this.rotationFactor = rotationFactor; + +}; + +R3.D3.API.Input.Drive.prototype = Object.create(R3.Component.prototype); +R3.D3.API.Input.Drive.prototype.constructor = R3.D3.API.Input.Drive; + +/** + * Object to R3.D3.API.Input.Drive + * @param objectComponent + * @returns {R3.D3.API.Input.Drive} + * @constructor + */ +R3.D3.API.Input.Drive.FromObject = function(objectComponent) { + return new R3.D3.API.Input.Drive( + objectComponent.id, + objectComponent.name, + objectComponent.domElementId, + objectComponent.pathFollowingComponent, + objectComponent.parentEntity, + objectComponent.wheelFL, + objectComponent.wheelFR, + objectComponent.wheelRL, + objectComponent.wheelRR, + objectComponent.heightOffset, + objectComponent.distance, + objectComponent.distanceGrain, + objectComponent.rotationFactor + ); +}; diff --git a/bak/r3-d3-api-input-editor.bak b/bak/r3-d3-api-input-editor.bak new file mode 100644 index 0000000..fa371e9 --- /dev/null +++ b/bak/r3-d3-api-input-editor.bak @@ -0,0 +1,50 @@ +/** + * This component makes the parentEntity (ex. car) follow the path provided by the spline + * @param id String + * @param name String + * @param domElementId + * @param camera R3.D3.Camera + * @param parentEntity + * @constructor + */ +R3.D3.API.Input.Editor = function ( + id, + name, + domElementId, + camera, + parentEntity +) { + R3.Component.call( + this, + R3.Component.COMPONENT_EDITOR_INPUT, + { + 'camera' : R3.D3.Camera + }, + null, + parentEntity + ); + + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = this.constructor.name; + } + this.name = name; + + if (R3.Utils.UndefinedOrNull(domElementId)) { + domElementId = "divCanvas"; + } + this.domElementId = domElementId; + + if (R3.Utils.UndefinedOrNull(camera)) { + camera = null; + } + this.camera = camera; + +}; + +R3.D3.API.Input.Editor.prototype = Object.create(R3.Component.prototype); +R3.D3.API.Input.Editor.prototype.constructor = R3.D3.API.Input.Editor; diff --git a/bak/r3-d3-api-input-editor.js b/bak/r3-d3-api-input-editor.js new file mode 100644 index 0000000..48cffe8 --- /dev/null +++ b/bak/r3-d3-api-input-editor.js @@ -0,0 +1,62 @@ +/** + * This component makes the parentEntity (ex. car) follow the path provided by the spline + * @param id String + * @param name String + * @param domElement + * @param camera + * @param parentEntity + * @constructor + */ +R3.D3.API.Input.Editor = function ( + id, + name, + domElement, + camera, + parentEntity +) { + + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = 'Input Editor (' + this.id + ')'; + } + this.name = name; + + if (R3.Utils.UndefinedOrNull(domElement)) { + domElement = null; + } + this.domElement = domElement; + + if (R3.Utils.UndefinedOrNull(camera)) { + camera = null; + } + this.camera = camera; + + if (R3.Utils.UndefinedOrNull(parentEntity)) { + parentEntity = null; + } + this.parentEntity = parentEntity; + +}; + +R3.D3.API.Input.Editor.prototype = Object.create(R3.Component.prototype); +R3.D3.API.Input.Editor.prototype.constructor = R3.D3.API.Input.Editor; + +/** + * Object to R3.D3.API.Input.Editor + * @param objectComponent + * @returns {R3.D3.API.Input.Editor} + * @constructor + */ +R3.D3.API.Input.Editor.FromObject = function(objectComponent) { + return new R3.D3.API.Input.Editor( + objectComponent.id, + objectComponent.name, + objectComponent.domElement, + objectComponent.camera, + objectComponent.parentEntity + ); +}; diff --git a/bak/r3-d3-api-input-fly.bak b/bak/r3-d3-api-input-fly.bak new file mode 100644 index 0000000..e4778f3 --- /dev/null +++ b/bak/r3-d3-api-input-fly.bak @@ -0,0 +1,46 @@ +/** + * This component makes the parentEntity (ex. car) follow the path provided by the spline + * @param id String + * @param name String + * @param domElementId + * @param camera R3.D3.Camera + * @constructor + */ +R3.D3.API.Input.Fly = function ( + id, + name, + domElementId, + camera +) { + R3.Component.call( + this, + R3.Component.COMPONENT_FLY_INPUT, + { + 'camera' : R3.D3.Camera + } + ); + + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = this.constructor.name; + } + this.name = name; + + if (R3.Utils.UndefinedOrNull(domElementId)) { + domElementId = "divCanvas"; + } + this.domElementId = domElementId; + + if (R3.Utils.UndefinedOrNull(camera)) { + camera = null; + } + this.camera = camera; + +}; + +R3.D3.API.Input.Fly.prototype = Object.create(R3.Component.prototype); +R3.D3.API.Input.Fly.prototype.constructor = R3.D3.API.Input.Fly; diff --git a/bak/r3-d3-api-look-at.js b/bak/r3-d3-api-look-at.js new file mode 100644 index 0000000..7e51376 --- /dev/null +++ b/bak/r3-d3-api-look-at.js @@ -0,0 +1,85 @@ +/** + * Looks from currentPosition to targetPosition (default up is 0,1,0) + * @param id + * @param name + * @param currentComponent R3.Component + * @param targetComponent R3.Component + * @param targetPositionOffset R3.API.Vector3 + * @param rotationSpeed Number + * @param parentEntity + * @constructor + */ +R3.D3.API.LookAt = function ( + id, + name, + currentComponent, + targetComponent, + targetPositionOffset, + rotationSpeed, + parentEntity +) { + + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + if (R3.Utils.UndefinedOrNull(name)) { + name = this.constructor.name; + } + this.name = name; + + if(R3.Utils.UndefinedOrNull(currentComponent)) { + currentComponent = null; + } + this.currentComponent = currentComponent; + + if(R3.Utils.UndefinedOrNull(targetComponent)) { + targetComponent = null; + } + this.targetComponent = targetComponent; + + if(R3.Utils.UndefinedOrNull(targetPositionOffset)) { + targetPositionOffset = new R3.API.Vector3(0, 0, 0); + } + this.targetPositionOffset = targetPositionOffset; + + if (R3.Utils.UndefinedOrNull(rotationSpeed)) { + rotationSpeed = 22.0; + } + this.rotationSpeed = rotationSpeed; + + this.lookAtMatrix = new R3.API.Matrix4(); + + this.up = new R3.API.Vector3(0, 1, 0); + + this.currentRotation = new R3.API.Quaternion(); + + this.targetPosition = new R3.API.Vector3(); + + if(R3.Utils.UndefinedOrNull(parentEntity)) { + parentEntity = null; + } + this.parentEntity = parentEntity; +}; + +R3.D3.API.LookAt.prototype = Object.create(R3.Component.prototype); +R3.D3.API.LookAt.prototype.constructor = R3.D3.API.LookAt; + +/** + * Object to R3.D3.API.LookAt + * @param objectComponent + * @returns {R3.D3.API.LookAt} + * @constructor + */ +R3.D3.API.LookAt.FromObject = function(objectComponent) { + return new R3.D3.API.LookAt( + objectComponent.id, + objectComponent.name, + objectComponent.currentComponent, + objectComponent.targetComponent, + R3.API.Vector3.FromObject(objectComponent.targetPositionOffset), + objectComponent.rotationSpeed, + objectComponent.parentEntity + ); +}; diff --git a/bak/r3-d3-api-mesh-box.js b/bak/r3-d3-api-mesh-box.js new file mode 100644 index 0000000..0c22169 --- /dev/null +++ b/bak/r3-d3-api-mesh-box.js @@ -0,0 +1,72 @@ +/** + * R3.D3.API.Mesh.Box + * @constructor + * @param apiMesh + * @param width + * @param height + * @param depth + */ +R3.D3.API.Mesh.Box = function( + apiMesh, + width, + height, + depth +) { + + if (R3.Utils.UndefinedOrNull(apiMesh)) { + apiMesh = { + meshType : R3.D3.API.Mesh.MESH_TYPE_BOX + }; + } + + if (R3.Utils.UndefinedOrNull(apiMesh.meshType)) { + apiMesh.meshType = R3.D3.API.Mesh.MESH_TYPE_BOX; + } + + if (R3.Utils.UndefinedOrNull(width)) { + width = 1; + } + this.width = width; + + if (R3.Utils.UndefinedOrNull(height)) { + height = 1; + } + this.height = height; + + if (R3.Utils.UndefinedOrNull(depth)) { + depth = 1; + } + this.depth = depth; + + R3.D3.API.Mesh.call( + this, + apiMesh.id, + apiMesh.name, + apiMesh.meshType, + apiMesh.excludeFromEnvironment, + 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.castShadow, + apiMesh.receiveShadow, + apiMesh.parentEntity + ); +}; + +R3.D3.API.Mesh.Box.prototype = Object.create(R3.D3.API.Mesh.prototype); +R3.D3.API.Mesh.Box.prototype.constructor = R3.D3.API.Mesh.Box; diff --git a/bak/r3-d3-api-mesh-curve.js b/bak/r3-d3-api-mesh-curve.js new file mode 100644 index 0000000..d5c6b4e --- /dev/null +++ b/bak/r3-d3-api-mesh-curve.js @@ -0,0 +1,58 @@ +/** + * R3.D3.API.Mesh.Curve + * @constructor + * @param apiMesh + * @param pointSize + */ +R3.D3.API.Mesh.Curve = function( + apiMesh, + pointSize +) { + + if (R3.Utils.UndefinedOrNull(apiMesh)) { + apiMesh = { + meshType : R3.D3.API.Mesh.MESH_TYPE_CURVE + }; + } + + if (R3.Utils.UndefinedOrNull(apiMesh.meshType)) { + apiMesh.meshType = R3.D3.API.Mesh.MESH_TYPE_CURVE; + } + + if (R3.Utils.UndefinedOrNull(pointSize)) { + pointSize = 1; + } + this.pointSize = pointSize; + + R3.D3.API.Mesh.call( + this, + apiMesh.id, + apiMesh.name, + apiMesh.meshType, + apiMesh.excludeFromEnvironment, + 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.castShadow, + apiMesh.receiveShadow, + apiMesh.parentEntity + ); +}; + +R3.D3.API.Mesh.Curve.prototype = Object.create(R3.D3.API.Mesh.prototype); +R3.D3.API.Mesh.Curve.prototype.constructor = R3.D3.API.Mesh.Curve; diff --git a/bak/r3-d3-api-mesh-cylinder.js b/bak/r3-d3-api-mesh-cylinder.js new file mode 100644 index 0000000..7a8b341 --- /dev/null +++ b/bak/r3-d3-api-mesh-cylinder.js @@ -0,0 +1,106 @@ +/** + * R3.D3.API.Mesh.Cylinder + * @constructor + * @param apiMesh + * @param radiusTop + * @param radiusBottom + * @param height + * @param radiusSegments + * @param heightSegments + * @param openEnded + * @param thetaStart + * @param thetaLength + */ +R3.D3.API.Mesh.Cylinder = function( + apiMesh, + radiusTop, + radiusBottom, + height, + radiusSegments, + heightSegments, + openEnded, + thetaStart, + thetaLength +) { + if (R3.Utils.UndefinedOrNull(apiMesh)) { + apiMesh = { + meshType : R3.D3.API.Mesh.MESH_TYPE_CYLINDER + }; + } + + if (R3.Utils.UndefinedOrNull(apiMesh.meshType)) { + apiMesh.meshType = R3.D3.API.Mesh.MESH_TYPE_CYLINDER; + } + + if (R3.Utils.UndefinedOrNull(radiusTop)) { + radiusTop = 1; + } + this.radiusTop = radiusTop; + + if (R3.Utils.UndefinedOrNull(radiusBottom)) { + radiusBottom = 1; + } + this.radiusBottom = radiusBottom; + + if (R3.Utils.UndefinedOrNull(height)) { + height = 5; + } + this.height = height; + + if (R3.Utils.UndefinedOrNull(radiusSegments)) { + radiusSegments = 10; + } + this.radiusSegments = radiusSegments; + + if (R3.Utils.UndefinedOrNull(heightSegments)) { + heightSegments = 10; + } + this.heightSegments = heightSegments; + + if (R3.Utils.UndefinedOrNull(openEnded)) { + openEnded = false; + } + this.openEnded = openEnded; + + if (R3.Utils.UndefinedOrNull(thetaStart)) { + thetaStart = 0; + } + this.thetaStart = thetaStart; + + if (R3.Utils.UndefinedOrNull(thetaLength)) { + thetaLength = Math.PI * 2; + } + this.thetaLength = thetaLength; + + R3.D3.API.Mesh.call( + this, + apiMesh.id, + apiMesh.name, + apiMesh.meshType, + apiMesh.excludeFromEnvironment, + 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.castShadow, + apiMesh.receiveShadow, + apiMesh.parentEntity + ); +}; + +R3.D3.API.Mesh.Cylinder.prototype = Object.create(R3.D3.API.Mesh.prototype); +R3.D3.API.Mesh.Cylinder.prototype.constructor = R3.D3.API.Mesh.Cylinder; diff --git a/bak/r3-d3-api-mesh-line.js b/bak/r3-d3-api-mesh-line.js new file mode 100644 index 0000000..a893841 --- /dev/null +++ b/bak/r3-d3-api-mesh-line.js @@ -0,0 +1,58 @@ +/** + * R3.D3.API.Mesh.Line + * @constructor + * @param apiMesh + * @param lineWidth + */ +R3.D3.API.Mesh.Line = function( + apiMesh, + lineWidth +) { + + if (R3.Utils.UndefinedOrNull(apiMesh)) { + apiMesh = { + meshType : R3.D3.API.Mesh.MESH_TYPE_LINE + }; + } + + if (R3.Utils.UndefinedOrNull(apiMesh.meshType)) { + apiMesh.meshType = R3.D3.API.Mesh.MESH_TYPE_LINE; + } + + if (R3.Utils.UndefinedOrNull(lineWidth)) { + lineWidth = 1; + } + this.lineWidth = lineWidth; + + R3.D3.API.Mesh.call( + this, + apiMesh.id, + apiMesh.name, + apiMesh.meshType, + apiMesh.excludeFromEnvironment, + 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.castShadow, + apiMesh.receiveShadow, + apiMesh.parentEntity + ); +}; + +R3.D3.API.Mesh.Line.prototype = Object.create(R3.D3.API.Mesh.prototype); +R3.D3.API.Mesh.Line.prototype.constructor = R3.D3.API.Mesh.Line; diff --git a/bak/r3-d3-api-mesh-plane.js b/bak/r3-d3-api-mesh-plane.js new file mode 100644 index 0000000..610d4c8 --- /dev/null +++ b/bak/r3-d3-api-mesh-plane.js @@ -0,0 +1,128 @@ +/** + * R3.D3.API.Mesh.Plane + * @constructor + * @param apiMesh + * @param width + * @param height + * @param widthSegments + * @param heightSegments + * @param heightMapScale + * @param isHeightMap + * @param isDotMap + * @param dotMapScale + * @param dotMapOffset + * @param dotMapWeight + * @param dotObject + */ +R3.D3.API.Mesh.Plane = function( + apiMesh, + width, + height, + widthSegments, + heightSegments, + heightMapScale, + isHeightMap, + isDotMap, + dotMapScale, + dotMapOffset, + dotMapWeight, + dotObject +) { + + if (R3.Utils.UndefinedOrNull(apiMesh)) { + apiMesh = { + meshType : R3.D3.API.Mesh.MESH_TYPE_PLANE + }; + } + + if (R3.Utils.UndefinedOrNull(apiMesh.meshType)) { + apiMesh.meshType = R3.D3.API.Mesh.MESH_TYPE_PLANE; + } + + if (R3.Utils.UndefinedOrNull(width)) { + width = 1; + } + this.width = width; + + if (R3.Utils.UndefinedOrNull(height)) { + height = 1; + } + this.height = height; + + if (R3.Utils.UndefinedOrNull(widthSegments)) { + widthSegments = 5; + } + this.widthSegments = widthSegments; + + if (R3.Utils.UndefinedOrNull(heightSegments)) { + heightSegments = 5; + } + this.heightSegments = heightSegments; + + if (R3.Utils.UndefinedOrNull(heightMapScale)) { + heightMapScale = 1; + } + this.heightMapScale = heightMapScale; + + if (R3.Utils.UndefinedOrNull(isHeightMap)) { + isHeightMap = false; + } + this.isHeightMap = isHeightMap; + + if (R3.Utils.UndefinedOrNull(isDotMap)) { + isDotMap = false; + } + this.isDotMap = isDotMap; + + if (R3.Utils.UndefinedOrNull(dotMapScale)) { + dotMapScale = new R3.API.Vector3(0.01, 0.01, 0.01); + } + this.dotMapScale = dotMapScale; + + if (R3.Utils.UndefinedOrNull(dotMapOffset)) { + dotMapOffset = new R3.API.Vector3(1, -1, 5); + } + this.dotMapOffset = dotMapOffset; + + if (R3.Utils.UndefinedOrNull(dotMapWeight)) { + dotMapWeight = new R3.API.Vector3(1, 1, 1); + } + this.dotMapWeight = dotMapWeight; + + if (R3.Utils.UndefinedOrNull(dotObject)) { + dotObject = null; + } + this.dotObject = dotObject; + + R3.D3.API.Mesh.call( + this, + apiMesh.id, + apiMesh.name, + apiMesh.meshType, + apiMesh.excludeFromEnvironment, + 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.castShadow, + apiMesh.receiveShadow, + apiMesh.parentEntity + ); +}; + +R3.D3.API.Mesh.Plane.prototype = Object.create(R3.D3.API.Mesh.prototype); +R3.D3.API.Mesh.Plane.prototype.constructor = R3.D3.API.Mesh.Plane; diff --git a/bak/r3-d3-api-mesh-sphere.js b/bak/r3-d3-api-mesh-sphere.js new file mode 100644 index 0000000..2becca0 --- /dev/null +++ b/bak/r3-d3-api-mesh-sphere.js @@ -0,0 +1,72 @@ +/** + * R3.D3.API.Mesh.Sphere + * @constructor + * @param apiMesh + * @param radius + * @param widthSegments + * @param heightSegments + */ +R3.D3.API.Mesh.Sphere = function( + apiMesh, + radius, + widthSegments, + heightSegments +) { + + if (R3.Utils.UndefinedOrNull(apiMesh)) { + apiMesh = { + meshType : R3.D3.API.Mesh.MESH_TYPE_SPHERE + }; + } + + if (R3.Utils.UndefinedOrNull(apiMesh.meshType)) { + apiMesh.meshType = R3.D3.API.Mesh.MESH_TYPE_SPHERE; + } + + if (R3.Utils.UndefinedOrNull(radius)) { + radius = 1; + } + this.radius = radius; + + if (R3.Utils.UndefinedOrNull(widthSegments)) { + widthSegments = 5; + } + this.widthSegments = widthSegments; + + if (R3.Utils.UndefinedOrNull(heightSegments)) { + heightSegments = 5; + } + this.heightSegments = heightSegments; + + R3.D3.API.Mesh.call( + this, + apiMesh.id, + apiMesh.name, + apiMesh.meshType, + apiMesh.excludeFromEnvironment, + 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.castShadow, + apiMesh.receiveShadow, + apiMesh.parentEntity + ); +}; + +R3.D3.API.Mesh.Sphere.prototype = Object.create(R3.D3.API.Mesh.prototype); +R3.D3.API.Mesh.Sphere.prototype.constructor = R3.D3.API.Mesh.Sphere; diff --git a/bak/r3-d3-api-mesh-text.js b/bak/r3-d3-api-mesh-text.js new file mode 100644 index 0000000..f74b29c --- /dev/null +++ b/bak/r3-d3-api-mesh-text.js @@ -0,0 +1,114 @@ +/** + * R3.D3.API.Mesh.Text + * @constructor + * @param apiMesh + * @param text + * @param font + * @param size + * @param height + * @param curveSegments + * @param bevelEnabled + * @param bevelThickness + * @param bevelSize + * @param bevelSegments + */ +R3.D3.API.Mesh.Text = function( + apiMesh, + text, + font, + size, + height, + curveSegments, + bevelEnabled, + bevelThickness, + bevelSize, + bevelSegments +) { + + if (R3.Utils.UndefinedOrNull(apiMesh)) { + apiMesh = { + meshType : R3.D3.API.Mesh.MESH_TYPE_TEXT + }; + } + + if (R3.Utils.UndefinedOrNull(apiMesh.meshType)) { + apiMesh.meshType = R3.D3.API.Mesh.MESH_TYPE_TEXT; + } + + if (R3.Utils.UndefinedOrNull(text)) { + text = '-= this.maxSpeed) { + this.currentSpeed = this.maxSpeed; + } + this.grain = (this.currentSpeed / 100.0); + + var currentPosition = this.spline.getPointAt(this.currentPathValue); + + this.currentPosition.x = currentPosition.x; + this.currentPosition.y = currentPosition.y; + this.currentPosition.z = currentPosition.z; + + this.currentPathValue += this.grain; + + if (this.currentPathValue >= 1) { + this.currentPathValue = this.currentPathValue - 1; + } + + if (this.currentPathValue < 0) { + this.currentPathValue = 0.0; + } + + var futurePosition = this.spline.getPointAt(this.currentPathValue); + + this.futurePosition.x = futurePosition.x; + this.futurePosition.y = futurePosition.y; + this.futurePosition.z = futurePosition.z; + + this.raycaster.setPosition( + this.currentPosition + ); + + this.raycaster.setDirection( + { + x : -this.up.x, + y : -this.up.y, + z : -this.up.z + } + ); + + var normal = this.raycaster.getFaceNormal(this.raytraceMesh); + + if (normal) { + this.up.x = this.mx(normal.x); + this.up.y = this.my(normal.y); + this.up.z = this.mz(normal.z); + } + + this.rotationMatrix.lookAt( + this.currentPosition, + this.futurePosition, + this.up + ); + + this.rotationVector.setFromRotationMatrix(this.rotationMatrix); + + this.mesh.position.x = this.futurePosition.x; + this.mesh.position.y = this.futurePosition.y; + this.mesh.position.z = this.futurePosition.z; + + /** + * Update Rotation + */ + this.mesh.quaternion.x = this.rotationVector.x; + this.mesh.quaternion.y = this.rotationVector.y; + this.mesh.quaternion.z = this.rotationVector.z; + this.mesh.quaternion.w = this.rotationVector.w; + } +}; \ No newline at end of file diff --git a/bak/r3-d3-physics.js b/bak/r3-d3-physics.js new file mode 100644 index 0000000..1fdd332 --- /dev/null +++ b/bak/r3-d3-physics.js @@ -0,0 +1,32 @@ +/** + * Physics SuperSet Namespace Object + * @param id + * @param name + * @param engine R3.D3.Engine + * @param worlds + * @returns {{World: World}} + * @constructor + */ +R3.D3.Physics = function( + id, + name, + engine, + worlds +) { + this.id = id; + this.name = name; + this.engine = engine; + + if (typeof worlds == 'undefined') { + worlds = []; + } + this.worlds = worlds; +}; + + +/** + * Solver Types + * @type {number} + */ +R3.D3.Physics.SPLIT_SOLVER = 0x1; +R3.D3.Physics.GS_SOLVER = 0x2; \ No newline at end of file diff --git a/bak/r3-d3-raycast-vehicle.js b/bak/r3-d3-raycast-vehicle.js new file mode 100644 index 0000000..a320a0f --- /dev/null +++ b/bak/r3-d3-raycast-vehicle.js @@ -0,0 +1,89 @@ +/** + * Raycast Vehicles :) + * @param engine R3.D3.Engine + * @param chassisBody R3.D3.RigidBody + * @param wheels R3.D3.RaycastWheel[] + * @constructor + */ +R3.D3.RaycastVehicle = function( + engine, + chassisBody, + wheels, + wheelBodies +) { + this.engine = engine; + this.engine.isNotCannonThrow(); + + this.id = R3.Utils.RandomId(); + + this.chassisBody = chassisBody; + + if (typeof wheels == 'undefined') { + wheels = []; + } + this.wheels = wheels; + + if(R3.Utils.UndefinedOrNull(wheelBodies)) { + wheelBodies = []; + } + this.wheelBodies = wheelBodies; + + this.instance = this.createInstance(); + + R3.Utils.Extend(R3.D3.RaycastVehicle, R3.Component); +}; + +/** + * private + * @returns {R3.D3.RaycastVehicle|R3.D3.Physics.RaycastVehicle|*} + */ +R3.D3.RaycastVehicle.prototype.createInstance = function() { + return new this.engine.instance.RaycastVehicle({ + chassisBody: this.chassisBody.instance + }); +}; + +/** + * Adds a raycast wheel to this vehicle + * @param wheel R3.D3.RaycastWheel + * @param wheelRigidBody R3.D3.RigidBody + */ +R3.D3.RaycastVehicle.prototype.addWheel = function ( + wheel, + wheelRigidBody +) { + this.wheels.push(wheel); + this.wheelBodies.push(wheelRigidBody); + wheel.wheelIndex = this.instance.addWheel(wheel.instance); +}; + +/** + * Returns updated wheel info + * @returns {*} + * @constructor + */ +R3.D3.RaycastVehicle.prototype.getWheelInfo = function() { + return this.instance.wheelInfos; +}; + + + +// Override component methods // +R3.D3.RaycastVehicle.prototype.onUpdate = function( + deltaTime, + parentEntity +) { + for (var i = 0; i < this.getWheelInfo().length; i++) { + this.instance.updateWheelTransform(i); + var t = this.getWheelInfo()[i].worldTransform; + var wheelBody = this.wheelBodies[i].instance; + wheelBody.position.copy(t.position); + wheelBody.quaternion.copy(t.quaternion); + } +}; + +R3.D3.RaycastVehicle.prototype.onRegistered = function( + parentScene +) { + +}; \ No newline at end of file diff --git a/bak/r3-d3-raycast-wheel.js b/bak/r3-d3-raycast-wheel.js new file mode 100644 index 0000000..6545a31 --- /dev/null +++ b/bak/r3-d3-raycast-wheel.js @@ -0,0 +1,201 @@ +R3.D3.RaycastWheel = function( + engine, + chassisConnectionPointLocal, + chassisConnectionPointWorld, + directionLocal, + directionWorld, + axleLocal, + axleWorld, + suspensionRestLength, + suspensionMaxLength, + radius, + suspensionStiffness, + dampingCompression, + dampingRelaxation, + frictionSlip, + steering, + rotation, + deltaRotation, + rollInfluence, + maxSuspensionForce, + clippedInvContactDotSuspension, + suspensionRelativeVelocity, + suspensionForce, + skidInfo, + suspensionLength, + maxSuspensionTravel, + useCustomSlidingRotationalSpeed, + customSlidingRotationalSpeed +) { + this.engine = engine; + this.engine.isNotCannonThrow(); + + this.id = R3.Utils.RandomId(); + + if(typeof chassisConnectionPointLocal == 'undefined' || chassisConnectionPointLocal == null) { + chassisConnectionPointLocal = new this.engine.instance.Vec3(); + } + this.chassisConnectionPointLocal = chassisConnectionPointLocal; + + if(typeof chassisConnectionPointWorld == 'undefined' || chassisConnectionPointWorld == null) { + chassisConnectionPointWorld = new this.engine.instance.Vec3(); + } + this.chassisConnectionPointWorld = chassisConnectionPointWorld; + + if(typeof directionLocal == 'undefined' || directionLocal == null) { + directionLocal = new this.engine.instance.Vec3(); + } + this.directionLocal = directionLocal; + + if(typeof directionWorld == 'undefined' || directionWorld == null) { + directionWorld = new this.engine.instance.Vec3(); + } + this.directionWorld = directionWorld; + + if(typeof axleLocal == 'undefined' || axleLocal == null) { + axleLocal = new this.engine.instance.Vec3(); + } + this.axleLocal = axleLocal; + + if(typeof axleWorld == 'undefined' || axleWorld == null) { + axleWorld = new this.engine.instance.Vec3(); + } + this.axleWorld = axleWorld; + + if(typeof suspensionRestLength == 'undefined' || suspensionRestLength == null) { + suspensionRestLength = 1; + } + this.suspensionRestLength = suspensionRestLength; + + if(typeof suspensionMaxLength == 'undefined' || suspensionMaxLength == null) { + suspensionMaxLength = 2; + } + this.suspensionMaxLength = suspensionMaxLength; + + if(typeof radius == 'undefined' || radius == null) { + radius = 1; + } + this.radius = radius; + + if(typeof suspensionStiffness == 'undefined' || suspensionStiffness == null) { + suspensionStiffness = 100; + } + this.suspensionStiffness = suspensionStiffness; + + if(typeof dampingCompression == 'undefined' || dampingCompression == null) { + dampingCompression = 10; + } + this.dampingCompression = dampingCompression; + + if(typeof dampingRelaxation == 'undefined' || dampingRelaxation == null) { + dampingRelaxation = 10; + } + this.dampingRelaxation = dampingRelaxation; + + if(typeof frictionSlip == 'undefined' || frictionSlip == null) { + frictionSlip = 10000; + } + this.frictionSlip = frictionSlip; + + if(typeof steering == 'undefined' || steering == null) { + steering = 0; + } + this.steering = steering; + + if(typeof rotation == 'undefined' || rotation == null) { + rotation = 0; + } + this.rotation = rotation; + + if(typeof deltaRotation == 'undefined' || deltaRotation == null) { + deltaRotation = 0; + } + this.deltaRotation = deltaRotation; + + if(typeof rollInfluence == 'undefined' || rollInfluence == null) { + rollInfluence = 0.01; + } + this.rollInfluence = rollInfluence; + + if(typeof maxSuspensionForce == 'undefined' || maxSuspensionForce == null) { + maxSuspensionForce = Number.MAX_VALUE; + } + this.maxSuspensionForce = maxSuspensionForce; + + if(typeof clippedInvContactDotSuspension == 'undefined' || clippedInvContactDotSuspension == null) { + clippedInvContactDotSuspension = 1; + } + this.clippedInvContactDotSuspension = clippedInvContactDotSuspension; + + if(typeof suspensionRelativeVelocity == 'undefined' || suspensionRelativeVelocity == null) { + suspensionRelativeVelocity = 0; + } + this.suspensionRelativeVelocity = suspensionRelativeVelocity; + + if(typeof suspensionForce == 'undefined' || suspensionForce == null) { + suspensionForce = 0; + } + this.suspensionForce = suspensionForce; + + if(typeof skidInfo == 'undefined' || skidInfo == null) { + skidInfo = 0; + } + this.skidInfo = skidInfo; + + if(typeof suspensionLength == 'undefined' || suspensionLength == null) { + suspensionLength = 0; + } + this.suspensionLength = suspensionLength; + + if(typeof maxSuspensionTravel == 'undefined' || maxSuspensionTravel == null) { + maxSuspensionTravel = 1; + } + this.maxSuspensionTravel = maxSuspensionTravel; + + if(typeof useCustomSlidingRotationalSpeed == 'undefined' || useCustomSlidingRotationalSpeed == null) { + useCustomSlidingRotationalSpeed = false; + } + this.useCustomSlidingRotationalSpeed = useCustomSlidingRotationalSpeed; + + if(typeof customSlidingRotationalSpeed == 'undefined' || customSlidingRotationalSpeed == null) { + customSlidingRotationalSpeed = -0.1; + } + this.customSlidingRotationalSpeed = customSlidingRotationalSpeed; + + this.instance = this.createInstance(); + + // this gets assigned at runtime, when the wheel gets added to a vehicle + this.wheelIndex = -1; +}; + +R3.D3.RaycastWheel.prototype.createInstance = function() { + return { + chassisConnectionPointLocal : this.chassisConnectionPointLocal, + chassisConnectionPointWorld : this.chassisConnectionPointWorld, + directionLocal : this.directionLocal, + directionWorld : this.directionWorld, + axleLocal : this.axleLocal, + axleWorld : this.axleWorld, + suspensionRestLength : this.suspensionRestLength, + suspensionMaxLength : this.suspensionMaxLength, + radius : this.radius, + suspensionStiffness : this.suspensionStiffness, + dampingCompression : this.dampingCompression, + dampingRelaxation : this.dampingRelaxation, + frictionSlip : this.frictionSlip, + steering : this.steering, + rotation : this.rotation, + deltaRotation : this.deltaRotation, + rollInfluence : this.rollInfluence, + maxSuspensionForce : this.maxSuspensionForce, + clippedInvContactDotSuspension : this.clippedInvContactDotSuspension, + suspensionRelativeVelocity : this.suspensionRelativeVelocity, + suspensionForce : this.suspensionForce, + skidInfo : this.skidInfo, + suspensionLength : this.suspensionLength, + maxSuspensionTravel : this.maxSuspensionTravel, + useCustomSlidingRotationalSpeed : this.useCustomSlidingRotationalSpeed, + customSlidingRotationalSpeed : this.customSlidingRotationalSpeed + }; + +}; diff --git a/bak/r3-d3-rigid-body-vehicle.js b/bak/r3-d3-rigid-body-vehicle.js new file mode 100644 index 0000000..1f3db1b --- /dev/null +++ b/bak/r3-d3-rigid-body-vehicle.js @@ -0,0 +1,72 @@ +/** + * Physics Rigid Body Vehicle Superset + * @param engine R3.D3.Engine + * @param chassisBody R3.D3.RigidBody + * @param wheels R3.D3.RigidWheel[] + * @constructor + */ +R3.D3.RigidBodyVehicle = function( + engine, + chassisBody, + wheels +) { + this.id = R3.Utils.RandomId(); + this.engine = engine; + this.engine.isNotCannonThrow(); + + this.chassisBody = chassisBody; + + if (typeof wheels == 'undefined') { + wheels = []; + } + this.wheels = wheels; + + this.instance = this.createInstance(); +}; + +/** + * Returns physics wheelbody info (for updates) + * @returns {Array} + */ +R3.D3.RigidBodyVehicle.prototype.getWheelInfo = function() { + return this.instance.wheelBodies; +}; + +/** + * + * @returns {R3.D3.RigidVehicle} + */ +R3.D3.RigidBodyVehicle.prototype.createInstance = function() { + return new this.engine.instance.RigidVehicle({ + chassisBody: this.chassisBody.instance + }); +}; + +/** + * Adds a wheel to this rigid body vehicle + * @param wheel R3.D3.RigidWheel + */ +R3.D3.RigidBodyVehicle.prototype.addWheel = function(wheel) { + + this.wheels.push(wheel); + + this.instance.addWheel({ + body: wheel.body.instance, + position: new this.engine.instance.Vec3( + wheel.position.x, + wheel.position.y, + wheel.position.z + ), + axis: new this.engine.instance.Vec3( + wheel.axis.x, + wheel.axis.y, + wheel.axis.z + ), + direction: new this.engine.instance.Vec3( + wheel.direction.x, + wheel.direction.y, + wheel.direction.z + ) + }); + +}; diff --git a/bak/r3-d3-rigid-body.js b/bak/r3-d3-rigid-body.js new file mode 100644 index 0000000..e083d5f --- /dev/null +++ b/bak/r3-d3-rigid-body.js @@ -0,0 +1,195 @@ +/** + * RigidBody Superset + * @param engine R3.D3.Engine + * @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 shape R3.D3.Shape + * @param kinematic Boolean + * @returns {R3.D3.Physics.RigidBody} + * @constructor + */ +R3.D3.RigidBody = function( + engine, + mass, + friction, + position, + quaternion, + velocity, + angularVelocity, + linearDamping, + angularDamping, + allowSleep, + sleepSpeedLimit, + sleepTimeLimit, + collisionFilterGroup, + collisionFilterMask, + fixedRotation, + shape, + kinematic +) { + this.id = R3.Utils.RandomId(); + this.position = position || new R3.API.Vector3(); + this.velocity = velocity || new R3.API.Vector3(); + this.angularVelocity = angularVelocity || new R3.API.Vector3(); + this.quaternion = quaternion || new R3.API.Quaternion(0, 0, 0, 1); + this.mass = typeof mass == "undefined" ? 0 : mass; + this.friction = typeof friction == "undefined" ? 5 : friction; + this.linearDamping = typeof linearDamping == "undefined" ? 0.01 : linearDamping; + this.angularDamping = typeof angularDamping == "undefined" ? 0.01 : angularDamping; + this.allowSleep = typeof allowSleep == "undefined" ? true : allowSleep; + this.sleepSpeedLimit = typeof sleepSpeedLimit == "undefined" ? 0.1 : sleepSpeedLimit; + this.sleepTimeLimit = typeof sleepTimeLimit == "undefined" ? 1.0 : sleepTimeLimit; + this.collisionFilterGroup = typeof collisionFilterGroup == "undefined" ? 1 : collisionFilterGroup; + this.collisionFilterMask = typeof collisionFilterMask == "undefined" ? 1 : collisionFilterMask; + this.fixedRotation = typeof fixedRotation == "undefined" ? false : fixedRotation; + this.shape = typeof shape == "undefined" ? null : shape; + this.kinematic = kinematic || false; + + this.engine = engine; + this.engine.isNotCannonThrow(); + this.instance = this.createInstance(); + + // Todo: this should be executed somewhere in r3-z, so that we don't execute it on every construction of an object. + R3.Utils.Extend(R3.D3.RigidBody, R3.Component); +}; + +/** + * private function + * @returns {*} + */ +R3.D3.RigidBody.prototype.createInstance = function() { + + var instance = new this.engine.instance.Body({ + mass: this.mass, + friction: this.friction, + position: new this.engine.instance.Vec3( + this.position.x, + this.position.y, + this.position.z + ), + velocity: new this.engine.instance.Vec3( + this.velocity.x, + this.velocity.y, + this.velocity.z + ), + quaternion: new this.engine.instance.Quaternion( + this.quaternion.x, + this.quaternion.y, + this.quaternion.z, + this.quaternion.w + ), + angularVelocity: new this.engine.instance.Vec3( + this.angularVelocity.x, + this.angularVelocity.y, + this.angularVelocity.z + ), + linearDamping: this.linearDamping, + angularDamping: this.angularDamping, + allowSleep: this.allowSleep, + sleepSpeedLimit: this.sleepSpeedLimit, + sleepTimeLimit: this.sleepTimeLimit, + collisionFilterGroup: this.collisionFilterGroup, + collisionFilterMask: this.collisionFilterMask, + fixedRotation: this.fixedRotation, + shape: this.shape && this.shape.instance ? this.shape.instance : null + }); + + this.instance = instance; + + return instance; +}; + +R3.D3.RigidBody.prototype.toApiRigidBody = function() { + return null; +}; + +/** + * Adds a shape to this rigid body + * @param shape R3.D3.Shape + * @param offset R3.API.Vector3 + * @param orientation R3.API.Quaternion + * @constructor + */ +R3.D3.RigidBody.prototype.addShape = function( + shape, + offset, + orientation +) { + if (!offset || typeof offset == 'undefined') { + offset = new R3.API.Vector3(0,0,0); + } + + if (!orientation || typeof orientation == 'undefined') { + orientation = new R3.API.Quaternion(0,0,0,1); + } + + this.instance.addShape( + shape.instance, + new this.engine.instance.Vec3( + offset.x, + offset.y, + offset.z + ), + new this.engine.instance.Quaternion( + orientation.x, + orientation.y, + orientation.z, + orientation.w + ) + ); +}; + +///////////////////////// Methods to override ////////////////////////// +R3.D3.RigidBody.prototype.onUpdate = function( + deltaTime, + parentEntity +) { + if(parentEntity) { + if (this.kinematic) { + // reapply the entity's transform back to the rigid body, since it is kinematic + this.instance.position.x = parentEntity.position.x; + this.instance.position.y = parentEntity.position.y; + this.instance.position.z = parentEntity.position.z; + + this.instance.quaternion.x = parentEntity.quaternion.x; + this.instance.quaternion.y = parentEntity.quaternion.y; + this.instance.quaternion.z = parentEntity.quaternion.z; + this.instance.quaternion.w = parentEntity.quaternion.w; + + this.instance.inertia.x = 0; + this.instance.inertia.y = 0; + this.instance.inertia.z = 0; + + this.instance.velocity.x = 0; + this.instance.velocity.y = 0; + this.instance.velocity.z = 0; + } else { + var quaternion = new THREE.Quaternion(); + quaternion.copy(this.instance.quaternion); + + var position = new THREE.Vector3(); + position.copy(this.instance.position); + + parentEntity.position.x = position.x; + parentEntity.position.y = position.y; + parentEntity.position.z = position.z; + + parentEntity.quaternion.x = quaternion.x; + parentEntity.quaternion.y = quaternion.y; + parentEntity.quaternion.z = quaternion.z; + parentEntity.quaternion.w = quaternion.w; + } + } +}; \ No newline at end of file diff --git a/bak/r3-d3-rigid-wheel.js b/bak/r3-d3-rigid-wheel.js new file mode 100644 index 0000000..2adb4ce --- /dev/null +++ b/bak/r3-d3-rigid-wheel.js @@ -0,0 +1,20 @@ +/** + * Rigid Wheel superset + * @param body R3.D3.RigidBody + * @param position R3.API.Vector3 + * @param axis R3.API.Vector3 + * @param direction R3.API.Vector3 + * @constructor + */ +R3.D3.RigidWheel = function( + body, + position, + axis, + direction +) { + this.id = R3.Utils.RandomId(); + this.body = body; + this.position = position; + this.axis = axis; + this.direction = direction; +}; diff --git a/bak/r3-d3-selected-object.js b/bak/r3-d3-selected-object.js new file mode 100644 index 0000000..daa8646 --- /dev/null +++ b/bak/r3-d3-selected-object.js @@ -0,0 +1,38 @@ +/** + * Selected Objects + * @param graphics R3.D3.Graphics + * @param object + * @param helper + * @param lastUpdate + * @constructor + */ +R3.D3.SelectedObject = function SelectedObject( + graphics, + object, + helper, + lastUpdate +) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(object)) { + console.warn('Cannot select no object'); + throw new Error('Cannot select no object'); + } + this.object = object; + + if (R3.Utils.UndefinedOrNull(helper)) { + helper = new R3.D3.Helper( + this.graphics, + null, + null, + object + ) + } + this.helper = helper; + + if (R3.Utils.UndefinedOrNull(lastUpdate)) { + lastUpdate = Date.now(); + } + this.lastUpdate = lastUpdate; +}; diff --git a/bak/r3-d3-shape.js b/bak/r3-d3-shape.js new file mode 100644 index 0000000..98e77bc --- /dev/null +++ b/bak/r3-d3-shape.js @@ -0,0 +1,195 @@ +/** + * Physics Shape Superset + * @param engine R3.D3.Engine + * @param shapeType + * @param scale R3.API.Vector3 + * @param vertices Number[] + * @param indices Number[] + * @param radius Number + * @param halfExtensions R3.API.Vector3 + * @param radiusTop Number + * @param radiusBottom Number + * @param height Number + * @param numSegments Number + * @param heightmap R3.D3.Heightmap + * @param elementSize + * @constructor + */ +R3.D3.Shape = function( + engine, + shapeType, + scale, + vertices, + indices, + radius, + halfExtensions, + radiusTop, + radiusBottom, + height, + numSegments, + heightmap +) { + + this.engine = engine; + + this.engine.isNotCannonThrow(); + + this.shapeType = shapeType; + + if (typeof scale == 'undefined') { + scale = new R3.API.Vector3(1, 1, 1) + } + this.scale = scale; + + if (typeof vertices == 'undefined') { + vertices = []; + } + this.vertices = vertices; + + if (typeof indices == 'undefined') { + indices = []; + } + this.indices = indices; + + if (typeof radius == 'undefined') { + radius = 1; + } + this.radius = radius; + + if (typeof halfExtensions == 'undefined') { + halfExtensions = new R3.API.Vector3(1,1,1); + } + this.halfExtensions = halfExtensions; + + if (typeof radiusTop == 'undefined') { + radiusTop = 1; + } + this.radiusTop = radiusTop; + + if (typeof radiusBottom == 'undefined') { + radiusBottom = 1; + } + this.radiusBottom = radiusBottom; + + if (typeof height == 'undefined') { + height = 1; + } + this.height = height; + + if (typeof numSegments == 'undefined') { + numSegments = 1; + } + this.numSegments = numSegments; + + if (typeof heightmap == 'undefined') { + heightmap = new R3.D3.Heightmap(); + } + this.heightmap = heightmap; + + this.instance = this.createInstance(); +}; + +/** + * Shape constants + * @type {number} + */ +R3.D3.Shape.SHAPE_TYPE_SPHERE = 1; +R3.D3.Shape.SHAPE_TYPE_BOX = 2; +R3.D3.Shape.SHAPE_TYPE_TRIMESH = 3; +R3.D3.Shape.SHAPE_TYPE_CYLINDER = 4; +R3.D3.Shape.SHAPE_TYPE_HEIGHT_MAP = 5; +R3.D3.Shape.SHAPE_TYPE_CONVEX_HULL = 6; +R3.D3.Shape.SHAPE_TYPE_PLANE = 7; + +/** + * + */ +R3.D3.Shape.prototype.createInstance = function() { + + var instance = null; + + if (this.shapeType == R3.D3.Shape.SHAPE_TYPE_TRIMESH) { + + } else if (this.shapeType == R3.D3.Shape.SHAPE_TYPE_SPHERE) {; + } else if (this.shapeType == R3.D3.Shape.SHAPE_TYPE_BOX) { + + } else if (this.shapeType == R3.D3.Shape.SHAPE_TYPE_CYLINDER) { + + } else if (this.shapeType == R3.D3.Shape.SHAPE_TYPE_HEIGHT_MAP) { + + } else if (this.shapeType == R3.D3.Shape.SHAPE_TYPE_CONVEX_HULL) { + + instance = new this.engine.instance.ConvexPolyhedron( + this.vertices, this.indices + ); + + } else if(this.shapeType == R3.D3.Shape.SHAPE_TYPE_PLANE) { + instance = new this.engine.instance.Plane(); + } else { + console.warn('Shape type not implemented: ' + this.shapeType); + throw new Error('Shape type not implemented: ' + this.shapeType); + } + + this.instance = instance; + + return instance; +}; + + +/** + * update + */ +R3.D3.Shape.prototype.update = function( + engine +) { + engine.isNotCannonThrow(); + + if(this.shapeType === R3.D3.Shape.SHAPE_TYPE_TRIMESH) { + this.instance.setScale( + new engine.instance.Vec3( + this.scale.x, + this.scale.y, + this.scale.z + ) + ); + this.instance.updateAABB(); + this.instance.updateNormals(); + this.instance.updateEdges(); + this.instance.updateBoundingSphereRadius(); + this.instance.updateTree(); + } +}; + +/** + * Converts a R3.D3.Shape to a R3.D3.API.Shape + * @returns {R3.D3.API.Shape} + */ +R3.D3.Shape.prototype.toApiShape = function() { + + return new R3.D3.API.Shape( + this.engine.toApiEngine(), + this.shapeType, + this.scale.toApiVector(), + this.vertices, + this.indices, + this.radius, + this.halfExtensions, + this.radiusTop, + this.radiusBottom, + this.height, + this.numSegments, + this.heightmap.toApiHeightMap() + ) + +}; + +/** + * Converts from an Object to a Shape + * @param graphics R3.D3.Graphics + * @param objectShape Object + * @constructor + */ +R3.D3.Shape.FromObjectShape = function(graphics, objectShape) { + //todo: implement this still + return null; +}; \ No newline at end of file diff --git a/bak/r3-d3-sky-box.js b/bak/r3-d3-sky-box.js new file mode 100644 index 0000000..07f4fe9 --- /dev/null +++ b/bak/r3-d3-sky-box.js @@ -0,0 +1,69 @@ +R3.D3.SkyBox = function ( + graphics +) { + this.id = null; + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + this.texturesFolder = null; +}; + +R3.D3.SkyBox.prototype.load = function ( + texturesFolder +) { + this.texturesFolder = texturesFolder; + this.textures = []; + this.materials = []; + this.mesh = {}; + this.scene = new this.graphics.instance.Scene(); + this.textureCube = null; + + var textureLoader = new this.graphics.instance.TextureLoader(); + + // this textures are used to display the skybox + this.textures.push(textureLoader.load(this.texturesFolder + "px.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "nx.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "py.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "ny.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "pz.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "nz.png")); + + // assign textures to each cube face + for (var i = 0; i < 6; i ++) { + this.materials.push(new this.graphics.instance.MeshBasicMaterial({ map: this.textures[i] })); + } + + // create cube geometry + this.mesh = new this.graphics.instance.Mesh(new this.graphics.instance.CubeGeometry(1, 1, 1), new this.graphics.instance.MeshFaceMaterial(this.materials)); + this.mesh.applyMatrix(new this.graphics.instance.Matrix4().makeScale(1, 1, -1)); + this.scene.add(this.mesh); + + // Load env textureCube + // this is used for reflections on meshes + // mesh.material.envMap = this.textureCube; + this.textureCube = new this.graphics.instance.CubeTextureLoader().load([ + this.texturesFolder + "px.png", this.texturesFolder + "nx.png", + this.texturesFolder + "py.png", this.texturesFolder + "ny.png", + this.texturesFolder + "pz.png", this.texturesFolder + "nz.png" + ]); +}; + +R3.D3.SkyBox.prototype.render = function ( + threeRenderer, + threeCamera +) { + var cameraPosition = new this.graphics.instance.Vector3(threeCamera.position.x, threeCamera.position.y, threeCamera.position.z); + + threeCamera.position.set(0, 0, 0); + + var gl = threeRenderer.context; + + gl.disable(gl.DEPTH_TEST); + + threeRenderer.render(this.scene, threeCamera); + + gl.enable(gl.DEPTH_TEST); + + threeCamera.position.copy(cameraPosition); +}; diff --git a/bak/r3-d3-world.js b/bak/r3-d3-world.js new file mode 100644 index 0000000..2152ee8 --- /dev/null +++ b/bak/r3-d3-world.js @@ -0,0 +1,914 @@ +/** + * World SuperSet - contains the custom world instance + * @param id + * @param name + * @param engine + * @param gravity + * @param broadphase + * @param solver + * @param rigidBodies + * @constructor + */ +R3.D3.World = function( + id, + name, + engine, + gravity, + broadphase, + solver, + rigidBodies +) { + + this.id = id; + + this.name = name; + + if (typeof gravity == 'undefined') { + gravity = new R3.API.Vector3(0, -9.81, 0); + } + this.gravity = gravity; + + if (typeof broadphase == 'undefined') { + broadphase = new R3.D3.Broadphase( + null, + 'broadPhaseNaive', + R3.D3.Broadphase.BROADPHASE_TYPE_NAIVE, + engine + ); + } + this.broadphase = broadphase; + + if (typeof solver == 'undefined') { + solver = new R3.D3.Solver( + null, + engine, + R3.D3.Solver.GS_SOLVER + ); + } + this.solver = solver; + + if (typeof rigidBodies == 'undefined') { + rigidBodies = []; + } + this.rigidBodies = rigidBodies; + + this.engine = engine; + + this.engine.isNotCannonThrow(); + + this.instance = this.createInstance(); +}; + +/** + * private + * @returns {R3.D3.World|R3.D3.Physics.World|*} + */ +R3.D3.World.prototype.createInstance = function() { + + var instance = new this.engine.instance.World(); + + instance.broadphase = this.broadphase.instance; + + instance.solver = this.solver.instance; + + instance.gravity.x = this.gravity.x; + instance.gravity.y = this.gravity.y; + instance.gravity.z = this.gravity.z; + + instance.name = this.name; + + return instance; +}; + +R3.D3.World.prototype.toApiWorld = function() { + //TODO: create API.World someday + return { + id: this.id, + name: this.name, + engine: this.engine.toApiEngine(), + gravity: this.gravity, + broadphase: this.broadphase.toApiBroadphase(), + solver: this.solver.toApiSolver(), + rigidBodies: this.rigidBodies.map(function(rigidBody){return rigidBody.toApiRigidBody()}) + } +}; + + +R3.D3.World.FromObjectWorld = function(engine, objectWorld) { + + //todo implement this fully + return new R3.D3.World( + objectWorld.id, + objectWorld.name, + engine, + objectWorld.gravity, + null, + null, + null + ); +}; + +/** + * + * @param rigidBody R3.D3.RigidBody + * @constructor + */ +R3.D3.World.prototype.addRigidBody = function( + rigidBody +) { + this.instance.addBody(rigidBody.instance); +}; + +/** + * + * @param vehicle (R3.D3.RigidBodyVehicle | R3.D3.RaycastVehicle) + * @constructor + */ +R3.D3.World.prototype.addVehicle = function( + vehicle +) { + vehicle.instance.addToWorld(this.instance); +}; + +R3.D3.World.prototype.step = function( + fixedStep, + dtStep +) { + this.instance.step(fixedStep, dtStep, 3); + return; + + var now = Date.now() / 1000.0; + //var now = null; + if(!this.lastCallTime){ + // last call time not saved, cant guess elapsed time. Take a simple step. + this.instance.step(fixedStep); + this.lastCallTime = now; + return; + } + + var timeSinceLastCall = (now - this.lastCallTime); + + this.instance.step(fixedStep, timeSinceLastCall, 4); + + this.lastCallTime = now; +}; + +R3.D3.World.prototype.GetIndexedVertices = function( + triangleMeshShape +) { + + if(this.engine.engineType == R3.D3.Physics.TYPE_CANNON) { + + return { + vertices : triangleMeshShape.vertices, + indices : triangleMeshShape.indices + }; + + } else { + // todo: implement this for other physics engines. + return null; + } + +}; + +/** + * @param triangleMeshShape R3.D3.Shape + * @param normalLength Number + * @param scale R3.API.Vector3 + * @param opacity Number + * @param wireframeColor HexCode + * @param graphics THREE + * @returns {THREE.Mesh|this.meshes} + * @constructor + */ +R3.D3.World.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 R3.D3.Shape + * @param normalLength Number + * @param scale R3.API.Vector3 + * @param opacity Number + * @param wireframeColor HexCode + * @param graphics THREE + * @returns {THREE.Mesh|this.meshes} + * @constructor + */ +R3.D3.World.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 R3.D3.Graphics + * @param graphicsMesh THREE.Mesh + * @param mass Number + * @param friction Number + * @param createCollisionSubMeshes Boolean + * @param facesPerSubsection Number + * @param subsectionsToMerge Number + * @returns {Object} + * @constructor + */ +R3.D3.World.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++; + } +}; + +R3.D3.World.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 R3.D3.Shape(this.engine, R3.D3.Shape.SHAPE_TYPE_CONVEX_HULL, {x:1,y:1,z:1},convexVertices, convexIndices); + + var body = new R3.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 R3.D3.Graphics + * @param graphicsMesh THREE.Mesh + * @returns {R3.D3.Shape} + * @constructor + */ +R3.D3.World.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 R3.D3.Shape(this.engine, R3.D3.Shape.SHAPE_TYPE_TRIMESH, {x : 1, y : 1, z : 1}, vertices, faces); +}; + +/** + * @param triangleMeshBody R3.D3.RigidBody + * @param rayscale Number + * @param maxTriangleDistance Number + * @param createCompoundShape Boolean + * @param graphics R3.D3.Graphics + * @param triangleMeshShapes R3.D3.Shape[] + * @param createDebugView Boolean + * @returns {R3.D3.RigidBody} + * @constructor + */ +R3.D3.World.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 R3.D3.Shape(this.engine, R3.D3.Shape.SHAPE_TYPE_TRIMESH, { x : 1, y : 1, z : 1 }, element.vertices, element.indices); + + if(createCompoundShape) { + triangleMeshBody.addShape(shape); + } else { + + var body = new R3.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 + }; +}; \ No newline at end of file diff --git a/bak/r3-dom.js b/bak/r3-dom.js new file mode 100644 index 0000000..de8b858 --- /dev/null +++ b/bak/r3-dom.js @@ -0,0 +1,13 @@ +/** + * Runtime Dom + * @constructor + * @param document DOM Document + * @param window DOM Window + */ +R3.Dom = function( + document, + window +) { + this.document = document; + this.window = window; +}; diff --git a/bak/r3-graphics-runtime-impact.js b/bak/r3-graphics-runtime-impact.js new file mode 100644 index 0000000..76bf3c3 --- /dev/null +++ b/bak/r3-graphics-runtime-impact.js @@ -0,0 +1,116 @@ +/** + * R3.GraphicsRuntime.Impact + * @param apiGraphicsRuntimeImpact + * @constructor + */ +R3.GraphicsRuntime.Impact = function( + apiGraphicsRuntimeImpact +) { + + if (R3.Utils.UndefinedOrNull(apiGraphicsRuntimeImpact)) { + apiGraphicsRuntimeImpact = { + graphicsType : R3.API.GraphicsRuntime.GRAPHICS_TYPE_IMPACT_JS + }; + } + + R3.API.GraphicsRuntime.Impact.call( + this, + apiGraphicsRuntimeImpact + ); + + R3.GraphicsRuntime.call( + this, + this + ); + +}; + +R3.GraphicsRuntime.Impact.prototype = Object.create(R3.GraphicsRuntime.prototype); +R3.GraphicsRuntime.Impact.prototype.constructor = R3.GraphicsRuntime.Impact; + +/** + * Create R3.GraphicsRuntime.Impact Instance + * @returns {*} + */ +R3.GraphicsRuntime.Impact.prototype.createInstance = function() { + + this.instance = ig; + + /** + * We override the game load to lookup the canvas from our r3 and not the DOM, since our canvas + * does not necessarily live inside the DOM + */ + ig.System.inject({ + init : function( canvasId, fps, width, height, scale ) { + this.fps = fps; + + this.clock = new ig.Timer(); + this.canvas = R3.EntityManager.Instance.findComponentById(canvasId).instance; + this.resize( width, height, scale ); + this.context = this.canvas.getContext('2d'); + + this.getDrawPos = ig.System.drawMode; + + // Automatically switch to crisp scaling when using a scale + // other than 1 + if( this.scale !== 1 ) { + ig.System.scaleMode = ig.System.SCALE.CRISP; + } + + ig.System.scaleMode( this.canvas, this.context ); + } + }); + + /** + * We override image loading to specify that it loads from cross-origins + */ + ig.Image.inject({ + load: function( loadCallback ) { + if( this.loaded ) { + if( loadCallback ) { + loadCallback( this.path, true ); + } + return; + } + else if( !this.loaded && ig.ready ) { + this.loadCallback = loadCallback || null; + + this.data = new Image(); + this.data.crossOrigin = 'anonymous'; + this.data.onload = this.onload.bind(this); + this.data.onerror = this.onerror.bind(this); + this.data.src = ig.prefix + this.path + ig.nocache; + } + else { + ig.addResource( this ); + } + + ig.Image.cache[this.path] = this; + } + }); + + R3.GraphicsRuntime.prototype.createInstance.call(this); +}; + +/** + * Update GraphicsRuntime.Impact Instance + */ +R3.GraphicsRuntime.Impact.prototype.updateInstance = function(property) { + + R3.GraphicsRuntime.prototype.updateInstance.call(this, property); +}; + +/** + * + * @returns {R3.API.GraphicsRuntime.Impact} + */ +R3.GraphicsRuntime.Impact.prototype.toApiObject = function() { + + var apiGraphicsRuntime = R3.GraphicsRuntime.prototype.toApiObject.call(this); + + var apiGraphicsRuntimeImpact = new R3.API.GraphicsRuntime.Impact( + apiGraphicsRuntime + ); + + return apiGraphicsRuntimeImpact; +}; diff --git a/bak/r3-matrix-3.js b/bak/r3-matrix-3.js new file mode 100644 index 0000000..8ea9737 --- /dev/null +++ b/bak/r3-matrix-3.js @@ -0,0 +1,37 @@ +/** + * Matrix 3 Maths + * @param row0 R3.API.Vector3 + * @param row1 R3.API.Vector3 + * @param row2 R3.API.Vector3 + * @constructor + */ +R3.Matrix3 = function( + row0, + row1, + row2 +) { + this.identity(); + + if (row0) { + this.rows[0] = row0; + } + + if (row1) { + this.rows[1] = row1; + } + + if (row2) { + this.rows[2] = row2; + } +}; + +/** + * Set matrix to identity + */ +R3.Matrix3.prototype.identity = function () { + this.rows = [ + new R3.API.Vector3(1, 0, 0), + new R3.API.Vector3(0, 1, 0), + new R3.API.Vector3(0, 0, 1) + ]; +}; \ No newline at end of file diff --git a/bak/r3-number.js b/bak/r3-number.js new file mode 100644 index 0000000..20f83e3 --- /dev/null +++ b/bak/r3-number.js @@ -0,0 +1,76 @@ +/** + * Runtime vector2 for updating instance objects + * @param apiNumber R3.API.Number + * @param parentObject + * @constructor + */ +R3.Number = function( + apiNumber, + parentObject +) { + + if (R3.Utils.UndefinedOrNull(apiNumber)) { + apiNumber = {}; + } + + R3.API.Number.call( + this, + apiNumber + ); + + if (R3.Utils.UndefinedOrNull(parentObject)) { + parentObject = null; + } + this.parentObject = parentObject; + + this.createInstance(); +}; + +R3.Number.prototype = Object.create(R3.API.Number.prototype); +R3.Number.prototype.constructor = R3.Number; + + +/** + * Creates an instance vector2 + * @returns {*} + */ +R3.Number.prototype.createInstance = function() { + this.instance = {}; +}; + +/** + * Updates the instance vector, calls updateInstance on the parent object + */ +R3.Number.prototype.updateInstance = function(property, parentProperty) { + + if (property === 'value') { + if (this.parentObject && this.parentObject.updateInstance) { + this.parentObject.updateInstance(parentProperty); + } + } + + if (property === 'grain') { + console.warn('todo: update number instance grain'); + } + + if (property === 'min') { + console.warn('todo: update number instance min'); + } + + if (property === 'max') { + console.warn('todo: update number instance max'); + } +}; + +/** + * Converts runtime vector to API Vector + * @returns {R3.API.Number} + */ +R3.Number.prototype.toApiObject = function() { + return new R3.API.Number( + this.value, + this.grain, + this.min, + this.max + ); +}; \ No newline at end of file diff --git a/bak/r3-render-configuration.js b/bak/r3-render-configuration.js new file mode 100644 index 0000000..2758266 --- /dev/null +++ b/bak/r3-render-configuration.js @@ -0,0 +1,270 @@ +/** + * R3.RenderConfiguration + * @param graphics + * @param apiRenderConfiguration R3.API.RenderConfiguration + * @constructor + */ +R3.RenderConfiguration = function ( + graphics, + apiRenderConfiguration +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiRenderConfiguration)) { + apiRenderConfiguration = {}; + } + + R3.API.RenderConfiguration.call( + this, + apiRenderConfiguration.id, + apiRenderConfiguration.name, + apiRenderConfiguration.parentEntity, + apiRenderConfiguration.logicalSize, + apiRenderConfiguration.aspectRatio, + apiRenderConfiguration.scaleMode, + apiRenderConfiguration.activeCamera, + apiRenderConfiguration.activeScene, + apiRenderConfiguration.activeScenes, + apiRenderConfiguration.activeRenderer, + apiRenderConfiguration.activeComposer, + apiRenderConfiguration.activeEffect, + apiRenderConfiguration.enableComposer, + apiRenderConfiguration.enableEffect, + apiRenderConfiguration.defaultMode + ); + + this.logicalSize = new R3.Vector2( + this.graphics, + this.logicalSize, + this + ); + + R3.Component.call( + this, + { + 'activeCamera' : R3.D3.Camera, + 'activeScene' : R3.D3.Scene, + 'activeScenes' : [R3.D3.Scene], + 'activeRenderer' : R3.Renderer, + 'activeComposer' : R3.D3.Composer, + 'activeEffect' : R3.D3.Effect + } + ); + +}; + +R3.RenderConfiguration.prototype = Object.create(R3.Component.prototype); +R3.RenderConfiguration.prototype.constructor = R3.RenderConfiguration; + +/** + * Create RenderConfiguration Instance + * @returns {*} + */ +R3.RenderConfiguration.prototype.createInstance = function() { + + this.instance = {}; + + R3.Component.prototype.createInstance.call(this); +}; + +/** + * Update RenderConfiguration Instance + */ +R3.RenderConfiguration.prototype.updateInstance = function(property) { + + if ( + property === 'logicalSize' || + property === 'aspectRatio' || + property === 'scaleMode' + ) { + + console.log('todo: implement fixed aspect ratios for different scale modes'); + + if ( + R3.Utils.Defined(this.activeCamera) && + R3.Utils.Defined(this.activeCamera.instance) + ) { + + /** + * For now - just use normal aspect ratio + */ + R3.Event.Emit( + R3.Event.GET_WINDOW_SIZE, + {}, + function(data) { + + if (data.width === data.height) { + console.log('square'); + } + + if (data.width > data.height) { + console.log('landscape'); + } + + if (data.width < data.height) { + console.log('portrait'); + } + + this.activeCamera.aspect = data.width / data.height; + this.activeCamera.updateInstance('aspect'); + + }.bind(this) + ) + } + + return; + } + + if (property === 'activeCamera') { + + if ( + R3.Utils.Defined(this.activeCamera) && + R3.Utils.Defined(this.activeCamera.instance) + ) { + /** + * Update the aspect ratio for the active camera + */ + this.updateInstance('aspectRatio'); + + R3.EntityManager.Instance.queryComponents(R3.Component.PASS_RENDER).map( + function(renderPass) { + renderPass.camera = this.activeCamera; + renderPass.updateInstance('camera'); + }.bind(this) + ) + } + } + + if ( + property === 'activeScene' || + property === 'activeScenes' || + property === 'activeRenderer' + ) { + console.log('todo: active component update'); + return; + } + + if ( + property === 'activeComposer' + ) { + + if (this.activeComposer === null) { + if (this.enableComposer) { + console.warn('no composer active - nothing will render'); + } + return; + } + + if ( + this.activeComposer.passes.length === 0 + ) { + console.warn('this composer has no passes - nothing will render when this composer is enabled'); + } + + return; + } + + if ( + property === 'activeEffect' + ) { + + if (this.activeEffect === null) { + if (this.enableEffect) { + console.warn('no effects active - nothing will render'); + } + } + + return; + } + + if ( + property === 'enableComposer' + ) { + + if (this.enableComposer) { + if (this.enableEffect) { + this.enableComposer = false; + console.warn('Only one of effect or composer can be enabled, not both at the same time'); + return; + } + + if ( + this.activeComposer === null + ) { + console.warn('no composer active - nothing will render'); + return; + } + + if ( + this.activeComposer.passes.length === 0 + ) { + console.warn('this composer has no passes - nothing will render'); + } + + } + + return; + } + + if ( + property === 'enableEffect' + ) { + + if (this.enableEffect) { + if (this.enableComposer) { + this.enableEffect = false; + console.warn('Only one of effect or composer can be enabled, not both at the same time'); + return; + } + + if (this.activeEffect === null) { + console.warn('no effect active - nothing will render'); + } + } + + return; + } + + if ( + property === 'defaultMode' + ) { + console.log('todo: defaultMode change'); + return; + } + + R3.Component.prototype.updateInstance.call(this, property); + +}; + +/** + * + * @returns {R3.API.RenderConfiguration} + */ +R3.RenderConfiguration.prototype.toApiObject = function() { + + var apiRenderConfiguration = new R3.API.RenderConfiguration( + this.id, + this.name, + R3.Utils.IdOrNull(this.parentEntity), + this.logicalSize.toApiObject(), + this.aspectRatio, + this.scaleMode, + R3.Utils.IdOrNull(this.activeCamera), + R3.Utils.IdOrNull(this.activeScene), + this.activeScenes.map( + function(activeScene) { + return R3.Utils.IdOrNull(activeScene); + } + ), + R3.Utils.IdOrNull(this.activeRenderer), + R3.Utils.IdOrNull(this.activeComposer), + R3.Utils.IdOrNull(this.activeEffect), + this.enableComposer, + this.enableEffect, + this.defaultMode + ); + + return apiRenderConfiguration; +}; diff --git a/bak/r3-renderer-d3-target.js b/bak/r3-renderer-d3-target.js new file mode 100644 index 0000000..e5e59c7 --- /dev/null +++ b/bak/r3-renderer-d3-target.js @@ -0,0 +1,540 @@ +/** + * R3.Renderer.D3.Target + * @param graphics R3.Runtime.Graphics + * @param apiRendererD3 R3.API.Renderer.D3 + * @constructor + */ +R3.Renderer.D3.Target = function( + graphics, + apiRendererD3 +) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiRendererD3)) { + apiRendererD3 = { + rendererType : R3.API.Renderer.RENDERER_TYPE_3D + }; + } + + R3.API.Renderer.D3.call( + this, + apiRendererD3, + apiRendererD3.renderMode, + apiRendererD3.autoClear, + apiRendererD3.autoClearColor, + apiRendererD3.autoClearDepth, + apiRendererD3.autoClearStencil, + apiRendererD3.gammaFactor, + apiRendererD3.gammaInput, + apiRendererD3.gammaOutput, + apiRendererD3.maxMorphTargets, + apiRendererD3.maxMorphNormals, + apiRendererD3.physicallyCorrectLights, + apiRendererD3.shadowMapEnabled, + apiRendererD3.shadowMapAutoUpdate, + apiRendererD3.shadowMapNeedsUpdate, + apiRendererD3.shadowMapType, + apiRendererD3.shadowMapRenderReverseSided, + apiRendererD3.shadowMapRenderSingleSided, + apiRendererD3.sortObjects, + apiRendererD3.toneMapping, + apiRendererD3.toneMappingExposure, + apiRendererD3.toneMappingWhitePoint, + apiRendererD3.premultipliedAlpha, + apiRendererD3.antialias, + apiRendererD3.stencil, + apiRendererD3.preserveDrawingBuffer, + apiRendererD3.depth, + apiRendererD3.logarithmicDepthBuffer, + apiRendererD3.localClippingEnabled, + apiRendererD3.renderTarget, + apiRendererD3.clippingPlanes, + apiRendererD3.clearColor, + apiRendererD3.viewports, + apiRendererD3.alpha, + apiRendererD3.opacity, + apiRendererD3.composer, + apiRendererD3.effect, + apiRendererD3.enableComposer, + apiRendererD3.enableEffect + ); + + if (this.renderTarget instanceof R3.D3.API.RenderTarget) { + this.renderTarget = R3.Component.ConstructFromObject(this.renderTarget); + } + + this.clippingPlanes = this.clippingPlanes.reduce( + function(result, clippingPlane) { + + if (clippingPlane instanceof R3.API.Plane) { + clippingPlane = R3.Component.ConstructFromObject(clippingPlane); + } + + result.push(clippingPlane); + + return result; + }, + [] + ); + + this.clearColor = new R3.Color( + this.graphics, + this.clearColor, + this + ); + + this.viewports = this.viewports.reduce( + function(result, viewport) { + + if (viewport instanceof R3.D3.API.Viewport) { + viewport = R3.Component.ConstructFromObject(viewport); + } + + result.push(viewport); + + return result; + }, + [] + ); + + if (this.composer instanceof R3.D3.API.Composer) { + this.composer = R3.Component.ConstructFromObject(this.composer); + } + + if (this.effect instanceof R3.D3.API.Effect) { + this.effect = R3.Component.ConstructFromObject(this.effect); + } + + R3.Renderer.call( + this, + this.graphics, + this + ); + +}; + +R3.Renderer.D3.Target.prototype = Object.create(R3.Renderer.D3.prototype); +R3.Renderer.D3.Target.prototype.constructor = R3.Renderer.D3.Target; + +R3.Renderer.D3.Target.prototype.getSize = function() { + return { + width : this.target.width, + height : this.target.height + } +}; + +/** + * Create R3.Renderer.D3 Instance + * @returns {*} + */ +R3.Renderer.D3.prototype.createInstance = function() { + + if ( + R3.Utils.UndefinedOrNull(this.canvas) || + R3.Utils.UndefinedOrNull(this.canvas.instance) + ) { + console.warn('no canvas instance'); + return; + } + + this.instance = new THREE.WebGLRenderer( + { + canvas : this.canvas.instance, + alpha : this.alpha, + premultipliedAlpha : this.premultipliedAlpha, + antialias : this.antialias, + stencil : this.stencil, + preserveDrawingBuffer : this.preserveDrawingBuffer, + depth : this.depth, + logarithmicDepthBuffer : this.logarithmicDepthBuffer + } + ); + + this.instance.setPixelRatio(window.devicePixelRatio); + + this.instance.autoClear = this.autoClear; + this.instance.autoClearColor = this.autoClearColor; + this.instance.autoClearDepth = this.autoClearDepth; + this.instance.autoClearStencil = this.autoClearStencil; + + this.instance.gammaFactor = this.gammaFactor; + this.instance.gammaInput = this.gammaInput; + this.instance.gammaOutput = this.gammaOutput; + + this.instance.maxMorphTargets = this.maxMorphTargets; + this.instance.maxMorphNormals = this.maxMorphNormals; + + this.instance.physicallyCorrectLights = this.physicallyCorrectLights; + + this.instance.shadowMap.enabled = this.shadowMapEnabled; + this.instance.shadowMap.autoUpdate = this.shadowMapAutoUpdate; + this.instance.shadowMap.needsUpdate = this.shadowMapNeedsUpdate; + this.instance.shadowMap.type = this.shadowMapType; + this.instance.shadowMap.renderReverseSided = this.shadowMapRenderReverseSided; + this.instance.shadowMap.renderSingleSided = this.shadowMapRenderSingleSided; + + this.instance.sortObjects = this.sortObjects; + + this.instance.toneMapping = this.toneMapping; + this.instance.toneMappingExposure = this.toneMappingExposure; + this.instance.toneMappingWhitePoint = this.toneMappingWhitePoint; + + this.instance.premultipliedAlpha = this.premultipliedAlpha; + + this.instance.localClippingEnabled = this.localClippingEnabled; + + if (this.renderTarget) { + this.instance.setRenderTarget(this.renderTarget.instance); + } + + if (this.clippingPlanes.length > 0) { + this.instance.clippingPlanes = this.clippingPlanes.map( + function(clippingPlane) { + return clippingPlane.instance; + } + ) + } + + this.instance.setClearColor( + new THREE.Color( + this.clearColor.r, + this.clearColor.g, + this.clearColor.b + ), + this.opacity + ); + + R3.Renderer.prototype.createInstance.call(this); +}; + +/** + * Update Renderer.D3 Instance + */ +R3.Renderer.D3.prototype.updateInstance = function(property) { + + if (!property) { + throw new Error('no renderer property'); + } + + if (!this.instance) { + throw new Error('no renderer instance'); + } + + if (property === 'renderMode') { + console.log('render mode change'); + return; + } + + if (property === 'autoClear') { + this.instance.autoClear = this.autoClear; + return; + } + + if (property === 'autoClearColor') { + this.instance.autoClearColor = this.autoClearColor; + return; + } + + if (property === 'autoClearDepth') { + this.instance.autoClearDepth = this.autoClearDepth; + return; + } + + if (property === 'autoClearStencil') { + this.instance.autoClearStencil = this.autoClearStencil; + return; + } + + if (property === 'gammaFactor') { + this.instance.gammaFactor = this.gammaFactor; + return; + } + + if (property === 'gammaInput') { + this.instance.gammaInput = this.gammaInput; + return; + } + + if (property === 'gammaOutput') { + this.instance.gammaOutput = this.gammaOutput; + return; + } + + if (property === 'maxMorphTargets') { + this.instance.maxMorphTargets = this.maxMorphTargets; + return; + } + + if (property === 'maxMorphNormals') { + this.instance.maxMorphNormals = this.maxMorphNormals; + return; + } + + if (property === 'physicallyCorrectLights') { + this.instance.physicallyCorrectLights = this.physicallyCorrectLights; + return; + } + + if (property === 'shadowMapEnabled') { + this.instance.shadowMap.enabled = this.shadowMapEnabled; + return; + } + + if (property === 'shadowMapAutoUpdate') { + this.instance.shadowMap.autoUpdate = this.shadowMapAutoUpdate; + return; + } + + if (property === 'shadowMapNeedsUpdate') { + this.instance.shadowMap.needsUpdate = this.shadowMapNeedsUpdate; + return; + } + + if (property === 'shadowMapType') { + this.instance.shadowMap.type = this.shadowMapType; + return; + } + + if (property === 'shadowMapRenderReverseSided') { + this.instance.shadowMap.renderReverseSided = this.shadowMapRenderReverseSided; + return; + } + + if (property === 'shadowMapRenderSingleSided') { + this.instance.shadowMap.renderSingleSided = this.shadowMapRenderSingleSided; + return; + } + + if (property === 'sortObjects') { + this.instance.sortObjects = this.sortObjects; + return; + } + + if (property === 'toneMapping') { + this.instance.toneMapping = this.toneMapping; + return; + } + + if (property === 'toneMappingExposure') { + this.instance.toneMappingExposure = this.toneMappingExposure; + return; + } + + if (property === 'toneMappingWhitePoint') { + this.instance.toneMappingWhitePoint = this.toneMappingWhitePoint; + return; + } + + if (property === 'premultipliedAlpha') { + this.instance.premultipliedAlpha = this.premultipliedAlpha; + return; + } + + if (property === 'premultipliedAlpha') { + this.instance.premultipliedAlpha = this.premultipliedAlpha; + return; + } + + if (property === 'antialias') { + this.instance.antialias = this.antialias; + return; + } + + if (property === 'stencil') { + this.instance.stencil = this.stencil; + return; + } + + if (property === 'preserveDrawingBuffer') { + this.instance.preserveDrawingBuffer = this.preserveDrawingBuffer; + return; + } + + if (property === 'depth') { + this.instance.depth = this.depth; + return; + } + + if (property === 'logarithmicDepthBuffer') { + this.instance.logarithmicDepthBuffer = this.logarithmicDepthBuffer; + return; + } + + if (property === 'localClippingEnabled') { + this.instance.localClippingEnabled = this.localClippingEnabled; + return; + } + + if (property === 'canvas') { + + if (R3.Utils.UndefinedOrNull(this.instance)) { + this.createInstance(); + } else { + console.warn('experimental canvas change for renderer'); + this.instance.dispose(); + this.createInstance(); + } + + return; + } + + if (property === 'renderTarget') { + + if ( + R3.Utils.Defined(this.instance) && + R3.Utils.Defined(this.renderTarget) && + R3.Utils.Defined(this.renderTarget.instance) + ) { + this.instance.setRenderTarget(this.renderTarget.instance); + console.log('updated render target on render instance'); + } + + return; + } + + if (property === 'clippingPlanes') { + console.warn('todo: clipping planes change'); + return; + } + + if ( + property === 'clearColor' || + property === 'opacity' + ) { + this.instance.setClearColor( + new THREE.Color( + this.clearColor.r, + this.clearColor.g, + this.clearColor.b + ), + this.opacity + ); + return; + } + + if (property === 'viewports') { + console.warn('todo: viewports change'); + } + + if (property === 'alpha') { + this.instance.alpha = this.alpha; + return; + } + + R3.Renderer.prototype.updateInstance.call(this, property); +}; + +/** + * Wrapper for clear() + */ +R3.Renderer.D3.prototype.clear = function() { + return this.instance.clear(); +}; + + +/** + * Convenience function to set viewport + * @param x + * @param y + * @param width + * @param height + */ +R3.Renderer.D3.prototype.setViewport = function( + x, + y, + width, + height +) { + this.instance.setViewport( + x, + y, + width, + height + ); +}; + +/** + * Renders to this.renderTarget + * @param scene + * @param camera + */ +R3.Renderer.D3.prototype.renderToTarget = function(scene, camera) { + + this.instance.render( + scene.instance, + camera.instance, + this.renderTarget.instance + ); + +}; + +/** + * Renders normally + * @param scene + * @param camera + */ +R3.Renderer.D3.prototype.render = function(scene, camera) { + this.instance.render( + scene.instance, + camera.instance + ) +}; + + +/** + * + * @returns {R3.API.Renderer.D3} + */ +R3.Renderer.D3.prototype.toApiObject = function() { + + var apiRenderer = R3.Renderer.prototype.toApiObject.call(this); + + var apiRendererD3 = new R3.API.Renderer.D3( + apiRenderer, + this.renderMode, + this.autoClear, + this.autoClearColor, + this.autoClearDepth, + this.autoClearStencil, + this.gammaFactor, + this.gammaInput, + this.gammaOutput, + this.maxMorphTargets, + this.maxMorphNormals, + this.physicallyCorrectLights, + this.shadowMapEnabled, + this.shadowMapAutoUpdate, + this.shadowMapNeedsUpdate, + this.shadowMapType, + this.shadowMapRenderReverseSided, + this.shadowMapRenderSingleSided, + this.sortObjects, + this.toneMapping, + this.toneMappingExposure, + this.toneMappingWhitePoint, + this.premultipliedAlpha, + this.antialias, + this.stencil, + this.preserveDrawingBuffer, + this.depth, + this.logarithmicDepthBuffer, + this.localClippingEnabled, + R3.Utils.IdOrNull(this.renderTarget), + this.clippingPlanes.map( + function(clippingPlane){ + return R3.Utils.IdOrNull(clippingPlane); + } + ), + this.clearColor.toApiObject(), + this.viewports.map( + function(viewport){ + return R3.Utils.IdOrNull(viewport); + } + ), + this.alpha, + this.opacity + ); + + return apiRendererD3; +}; diff --git a/config.js b/config.js new file mode 120000 index 0000000..43250d8 --- /dev/null +++ b/config.js @@ -0,0 +1 @@ +../r3-config/config.js \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..3e9a3af --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,237 @@ +var gulp = require('gulp'); +var concat = require('gulp-concat'); +var sort = require('gulp-sort'); +var minify = require('gulp-minify'); +var replace = require('gulp-string-replace'); + +gulp.task('build', build); +gulp.task('monitor', monitor); + +//__API_COMPONENT__ +var code = 'if (R3.Utils.UndefinedOrNull(apiComponent)) {\n'; +code += '\t\tapiComponent = {};\n'; +code += '\t}\n'; +code += '\n'; +code += '\tR3.API.Component.call(\n'; +code += '\t\tthis,\n'; +code += '\t\tapiComponent.parent,\n'; +code += '\t\tapiComponent.id,\n'; +code += '\t\tapiComponent.name,\n'; +code += '\t\tapiComponent.register,\n'; +code += '\t\tapiComponent.selected,\n'; +code += '\t\tapiComponent.isPublic\n'; +code += '\t)\n'; +code += '\n'; +code += '\tif (R3.Utils.UndefinedOrNull(apiComponent.guiInfo)) {\n'; +code += '\t\tapiComponent.guiInfo = {};\n'; +code += '\t}\n'; +code += '\tthis.guiInfo = apiComponent.guiInfo;\n'; + +//__DEFINE_API_COMPONENT__ +var code1 = 'if (R3.Utils.UndefinedOrNull(apiComponent)) {\n'; +code1 += '\t\tapiComponent = {};\n'; +code1 += '\t}\n'; +code1 += '\n'; +code1 += '\tif (R3.Utils.UndefinedOrNull(apiComponent.guiInfo)) {\n'; +code1 += '\t\tapiComponent.guiInfo = {};\n'; +code1 += '\t}\n'; +code1 += '\tthis.guiInfo = apiComponent.guiInfo;\n'; + +var code2 = 'R3.D3.API.Geometry.Buffer.call(\n'; +code2 += '\t\tthis,\n'; +code2 += '\t\tapiComponent\n'; +code2 += '\t)'; + +var code3 = 'R3.D3.API.Geometry.Normal.call(\n'; +code3 += '\t\tthis,\n'; +code3 += '\t\tapiComponent\n'; +code3 += '\t)'; + +var code4 = 'R3.D3.API.Material.call(\n'; +code4 += '\t\tthis,\n'; +code4 += '\t\tapiComponent\n'; +code4 += '\t)'; + +var code5 = 'if (R3.Utils.UndefinedOrNull(apiTexture)) {\n'; +code5 += '\t\tapiTexture = {};\n'; +code5 += '\t}\n'; +code5 += '\n'; +code5 += '\tR3.D3.API.Texture.call(\n'; +code5 += '\t\tthis,\n'; +code5 += '\t\tapiTexture,\n'; +code5 += '\t\tapiTexture.parentMaterials,\n'; +code5 += '\t\tapiTexture.mipmaps,\n'; +code5 += '\t\tapiTexture.mapping,\n'; +code5 += '\t\tapiTexture.wrapS,\n'; +code5 += '\t\tapiTexture.wrapT,\n'; +code5 += '\t\tapiTexture.magFilter,\n'; +code5 += '\t\tapiTexture.minFilter,\n'; +code5 += '\t\tapiTexture.anisotropy,\n'; +code5 += '\t\tapiTexture.format,\n'; +code5 += '\t\tapiTexture.storageType,\n'; +code5 += '\t\tapiTexture.offset,\n'; +code5 += '\t\tapiTexture.repeat,\n'; +code5 += '\t\tapiTexture.rotation,\n'; +code5 += '\t\tapiTexture.center,\n'; +code5 += '\t\tapiTexture.matrixAutoUpdate,\n'; +code5 += '\t\tapiTexture.generateMipMaps,\n'; +code5 += '\t\tapiTexture.premultiplyAlpha,\n'; +code5 += '\t\tapiTexture.flipY,\n'; +code5 += '\t\tapiTexture.unpackAlignment,\n'; +code5 += '\t\tapiTexture.encoding,\n'; +code5 += '\t\tapiTexture.version,\n'; +code5 += '\t\tapiTexture.animated,\n'; +code5 += '\t\tapiTexture.reverseAnimation,\n'; +code5 += '\t\tapiTexture.forward\n'; +code5 += '\t)'; + +//__RUNTIME_COMPONENT__ +var code6 = 'if (R3.Utils.UndefinedOrNull(apiComponent)) {\n'; +code6 += '\t\tapiComponent = {};\n'; +code6 += '\t}\n'; +code6 += '\n'; +code6 += '\tif (R3.Utils.UndefinedOrNull(this.linkedComponents)) {\n'; +code6 += '\t\tthis.linkedComponents = {};\n'; +code6 += '\t}\n'; +code6 += '\n'; +code6 += '\tthis.initialize(apiComponent)\n'; +code6 += '\n'; +code6 += '\tthis.graphics\t= null;\n'; +code6 += '\tthis.physics\t= null;\n'; +code6 += '\tthis.coder\t\t= null;\n'; +code6 += '\tthis.gui\t\t= null;\n'; +code6 += '\tthis.stats\t\t= null;\n'; +code6 += '\n'; +code6 += '\tR3.Event.Emit(\n'; +code6 += '\t\tR3.Event.GET_RUNTIME,\n'; +code6 += '\t\tthis,\n'; +code6 += '\t\tfunction(runtime) {\n'; +code6 += '\t\t\tif (R3.Utils.UndefinedOrNull(runtime)) {\n'; +code6 += '\t\t\t\treturn;\n'; +code6 += '\t\t\t}\n'; +code6 += '\t\t\tthis.graphics\t= runtime.graphics;\n'; +code6 += '\t\t\tthis.physics\t= runtime.physics;\n'; +code6 += '\t\t\tthis.coder\t\t= runtime.coder;\n'; +code6 += '\t\t\tthis.gui\t\t= runtime.gui;\n'; +code6 += '\t\t\tthis.stats\t\t= runtime.stats;\n'; +code6 += '\t\t}.bind(this)\n'; +code6 += '\t)'; + +//__RUNTIME_COMPONENT_INHERITABLE__ +var code14 = 'if (R3.Utils.UndefinedOrNull(apiComponent)) {\n'; +code14 += '\t\t\tapiComponent = {};\n'; +code14 += '\t\t}\n'; +code14 += '\n'; +code14 += '\t\tthis.initialize(apiComponent)\n'; +code14 += '\n'; +code14 += '\t\tthis.graphics\t= null;\n'; +code14 += '\t\tthis.physics\t= null;\n'; +code14 += '\t\tthis.coder\t\t= null;\n'; +code14 += '\t\tthis.gui\t\t= null;\n'; +code14 += '\t\tthis.stats\t\t= null;\n'; +code14 += '\n'; +code14 += '\t\tR3.Event.Emit(\n'; +code14 += '\t\t\tR3.Event.GET_RUNTIME,\n'; +code14 += '\t\t\tthis,\n'; +code14 += '\t\t\tfunction(runtime) {\n'; +code14 += '\t\t\t\tif (R3.Utils.UndefinedOrNull(runtime)) {\n'; +code14 += '\t\t\t\t\treturn;\n'; +code14 += '\t\t\t\t}\n'; +code14 += '\t\t\t\tthis.graphics\t= runtime.graphics;\n'; +code14 += '\t\t\t\tthis.physics\t= runtime.physics;\n'; +code14 += '\t\t\t\tthis.coder\t\t= runtime.coder;\n'; +code14 += '\t\t\t\tthis.gui\t\t= runtime.gui;\n'; +code14 += '\t\t\t\tthis.stats\t\t= runtime.stats;\n'; +code14 += '\t\t\t}.bind(this)\n'; +code14 += '\t\t)'; + +//__DEREGISTER_COMPONENT__ +var code7 = 'if (R3.Utils.UndefinedOrNull(apiComponent)) {\n'; +code7 += '\t\tapiComponent = {};\n'; +code7 += '\t}\n'; +code7 += '\n'; +code7 += '\tif (R3.Utils.UndefinedOrNull(apiComponent.register)) {\n'; +code7 += '\t\tapiComponent.register = false;\n'; +code7 += '\t}\n'; +code7 += '\n'; +code7 += '\tR3.Event.Emit(\n'; +code7 += '\t\tR3.Event.GET_REGISTER_FACES,\n'; +code7 += '\t\tnull,\n'; +code7 += '\t\tfunction(register) {\n'; +code7 += '\t\t\tif (R3.Utils.UndefinedOrNull(register)) {\n'; +code7 += '\t\t\t\treturn;\n'; +code7 += '\t\t\t}\n'; +code7 += '\t\t\tapiComponent.register = register;\n'; +code7 += '\t\t}\n'; +code7 += '\t)'; + +//__UPGRADE_TO_RUNTIME__ +var code8 = 'R3.Component.call(this)'; + +var code9 = 'R3.Component.prototype.createInstance.call(this)'; + +var code10 = 'R3.Component.prototype.updateInstance.call(this, property)'; + +var code11 = 'R3.D3.Geometry.Buffer.call(\n'; +code11 += '\t\tthis,\n'; +code11 += '\t\ttrue\n'; +code11 += '\t);'; + +//__INHERIT_ONLY__ +var code12 = 'if (R3.Utils.UndefinedOrNull(this.linkedComponents)) {\n'; +code12 += '\t\tthis.linkedComponents = {};\n'; +code12 += '\t}\n'; +code12 += '\t\n'; +code12 += '\tif (inherited !== true && inherited !== false) {\n'; +code12 += '\t\tthrow new Error(R3.GetComponentName(this) + " should not be instantiated directly");\n'; +code12 += '\t}'; + +//__INHERIT_AND_INSTANTIATE__ +var code13 = 'if (R3.Utils.UndefinedOrNull(this.linkedComponents)) {\n'; +code13 += '\t\tthis.linkedComponents = {};\n'; +code13 += '\t}\n'; +code13 += '\t\n'; +code13 += '\tif (R3.Utils.UndefinedOrNull(inherited)) {\n\n'; +code13 += '\t\t' + code14+ '\n'; +code13 += '\t}'; + +function build() { + return gulp.src('./src/r3-*.js') + .pipe(sort()) + .pipe(concat('r3.js')) + .pipe(replace('__DATE__', new Date().toString())) + .pipe(replace('__API_COMPONENT__', code)) + .pipe(replace('__DEFINE_API_COMPONENT__', code1)) + .pipe(replace('__API_GEOMETRY_BUFFER__', code2)) + .pipe(replace('__API_GEOMETRY_NORMAL__', code3)) + .pipe(replace('__API_MATERIAL__', code4)) + .pipe(replace('__API_TEXTURE__', code5)) + .pipe(replace('__RUNTIME_COMPONENT__', code6)) + .pipe(replace('__DEREGISTER_COMPONENT__', code7)) + .pipe(replace('__UPGRADE_TO_RUNTIME__', code8)) + .pipe(replace('__CREATE_INSTANCE__', code9)) + .pipe(replace('__UPDATE_INSTANCE__', code10)) + .pipe(replace('__RUNTIME_BUFFER_COMPONENT__', code11)) + .pipe(replace('__INHERIT_ONLY__', code12)) + .pipe(replace('__INHERIT_AND_INSTANTIATE__', code13)) +// .pipe(minify({ +// ext:{ +// src:'.js', +// min:'-min.js' +// } +// })) + .pipe(gulp.dest('./build/')); +} + + +function monitor() { + gulp.watch('src/*.js', build); +} + +gulp.task( + 'default', + gulp.series( + build, + monitor + ) +); diff --git a/package.json b/package.json new file mode 100644 index 0000000..6cd681f --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "r3", + "description": "R3 Library", + "author": "-= diff --git a/src/build_events.php b/src/build_events.php new file mode 100755 index 0000000..da58c4c --- /dev/null +++ b/src/build_events.php @@ -0,0 +1,85 @@ +#!/usr/bin/php + \ No newline at end of file diff --git a/src/r3-a-0.js b/src/r3-a-0.js new file mode 100644 index 0000000..719bcd7 --- /dev/null +++ b/src/r3-a-0.js @@ -0,0 +1,39 @@ +console.log("Loading R3 compiled at: __DATE__"); + +/** + * R3 Namespace + */ +if (typeof R3 === 'undefined') { + function R3() {} +} + +/** + * R3.D3 Namespace + */ +if (typeof R3.D3 === 'undefined') { + R3.D3 = function(){}; +} + +/** + * R3.D3.API Namespace + * @constructor + */ +if (typeof R3.D3.API === 'undefined') { + R3.D3.API = function(){}; +} + +/** + * R3.API Namespace + */ +if (typeof R3.API === 'undefined') { + R3.API = function(){}; +} + +/** + * R3.D3.Runtime Namespace + * @constructor + */ +if (typeof R3.D3.Runtime === 'undefined') { + R3.D3.Runtime = function(){}; +} + diff --git a/src/r3-a-1-component-info.js b/src/r3-a-1-component-info.js new file mode 100644 index 0000000..e40276e --- /dev/null +++ b/src/r3-a-1-component-info.js @@ -0,0 +1,5168 @@ +R3.COMPONENT_VIDEO = 0x1; +R3.COMPONENT_VECTOR4 = 0x2; +R3.COMPONENT_VECTOR3 = 0x3; +R3.COMPONENT_VECTOR2 = 0x4; +R3.COMPONENT_USER = 0x5; +R3.COMPONENT_STATS = 0x6; +R3.COMPONENT_SPHERE = 0x7; +R3.COMPONENT_SOCKET_RECEIVE = 0x8; +R3.COMPONENT_SOCKET_CAST = 0x9; +R3.COMPONENT_SOCKET = 0xa; +R3.COMPONENT_SERVER = 0xb; +R3.COMPONENT_SCALAR = 0xc; +R3.COMPONENT_RENDERER_D3_CANVAS_TARGET = 0xd; +R3.COMPONENT_RENDERER_D3_CANVAS = 0xe; +R3.COMPONENT_RENDERER_D3 = 0xf; +R3.COMPONENT_RENDERER_D2 = 0x10; +R3.COMPONENT_RENDERER = 0x11; +R3.COMPONENT_QUERY_USERS = 0x12; +R3.COMPONENT_QUERY_USERDEVICES = 0x13; +R3.COMPONENT_QUERY_LOGINS_VPN = 0x14; +R3.COMPONENT_QUERY_LOGINS_DEVICES = 0x15; +R3.COMPONENT_QUERY_LOGINS_APPLICATIONS = 0x16; +R3.COMPONENT_QUERY_LOGINS = 0x17; +R3.COMPONENT_QUERY_DEVICES_UNKNOWN = 0x18; +R3.COMPONENT_QUERY_DEVICES_SQL = 0x19; +R3.COMPONENT_QUERY_DEVICES_KNOWN = 0x1a; +R3.COMPONENT_QUERY_DEVICES = 0x1b; +R3.COMPONENT_QUERY_ALERTS_TIMESERIES = 0x1c; +R3.COMPONENT_QUERY_ALERTS_SUMMARY = 0x1d; +R3.COMPONENT_QUERY_ALERTS_LIST = 0x1e; +R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_VPN = 0x1f; +R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_DEVICES = 0x20; +R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_APPLICATIONS = 0x21; +R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN = 0x22; +R3.COMPONENT_QUERY_ALERTS_BUCKETS = 0x23; +R3.COMPONENT_QUERY_ALERTS = 0x24; +R3.COMPONENT_QUERY = 0x25; +R3.COMPONENT_QUATERNION_POINTS = 0x26; +R3.COMPONENT_QUATERNION = 0x27; +R3.COMPONENT_PROJECT_D3_VR = 0x28; +R3.COMPONENT_PROJECT_D3 = 0x29; +R3.COMPONENT_PROJECT_D2 = 0x2a; +R3.COMPONENT_PROJECT = 0x2b; +R3.COMPONENT_PLANE = 0x2c; +R3.COMPONENT_MOUSE = 0x2d; +R3.COMPONENT_MATRIX4 = 0x2e; +R3.COMPONENT_IMAGE = 0x2f; +R3.COMPONENT_GROUP = 0x30; +R3.COMPONENT_GRAPH_TABLE = 0x31; +R3.COMPONENT_GRAPH_METRIC = 0x32; +R3.COMPONENT_GRAPH_BARCHART_STACKED = 0x33; +R3.COMPONENT_GRAPH_BARCHART = 0x34; +R3.COMPONENT_GRAPH = 0x35; +R3.COMPONENT_FONT = 0x36; +R3.COMPONENT_ENTITY = 0x37; +R3.COMPONENT_DRAWRANGE = 0x38; +R3.COMPONENT_DOMELEMENT = 0x39; +R3.COMPONENT_D3_VIEWPORT_ZOOMEDASPECT = 0x3a; +R3.COMPONENT_D3_VIEWPORT_FIXEDASPECT_VR = 0x3b; +R3.COMPONENT_D3_VIEWPORT_FIXEDASPECT = 0x3c; +R3.COMPONENT_D3_VIEWPORT = 0x3d; +R3.COMPONENT_D3_VERTEX = 0x3e; +R3.COMPONENT_D3_TEXTURE_IMAGE = 0x3f; +R3.COMPONENT_D3_TEXTURE_CUBE = 0x40; +R3.COMPONENT_D3_TEXTURE_CANVAS = 0x41; +R3.COMPONENT_D3_TEXTURE = 0x42; +R3.COMPONENT_D3_TEXT = 0x43; +R3.COMPONENT_D3_SPLINE = 0x44; +R3.COMPONENT_D3_SOLVER = 0x45; +R3.COMPONENT_D3_SKELETON = 0x46; +R3.COMPONENT_D3_SHAPE_TRIMESH = 0x47; +R3.COMPONENT_D3_SHAPE_SPHERE = 0x48; +R3.COMPONENT_D3_SHAPE_PLANE = 0x49; +R3.COMPONENT_D3_SHAPE_HEIGHTMAP = 0x4a; +R3.COMPONENT_D3_SHAPE_CONVEXHULL_CYLINDER = 0x4b; +R3.COMPONENT_D3_SHAPE_CONVEXHULL = 0x4c; +R3.COMPONENT_D3_SHAPE_BOX = 0x4d; +R3.COMPONENT_D3_SHAPE = 0x4e; +R3.COMPONENT_D3_SHADOW_SPOT = 0x4f; +R3.COMPONENT_D3_SHADOW_DIRECTIONAL = 0x50; +R3.COMPONENT_D3_SHADOW = 0x51; +R3.COMPONENT_D3_SHADER_VERTEX = 0x52; +R3.COMPONENT_D3_SHADER_FRAGMENT = 0x53; +R3.COMPONENT_D3_SHADER = 0x54; +R3.COMPONENT_D3_SCENE = 0x55; +R3.COMPONENT_D3_RIGIDBODY = 0x56; +R3.COMPONENT_D3_RENDERTARGET_CUBE = 0x57; +R3.COMPONENT_D3_RENDERTARGET = 0x58; +R3.COMPONENT_D3_RAYCASTER = 0x59; +R3.COMPONENT_D3_RAYCASTWHEEL = 0x5a; +R3.COMPONENT_D3_RAYCASTVEHICLE = 0x5b; +R3.COMPONENT_D3_PHYSICSWORLD = 0x5c; +R3.COMPONENT_D3_PASS_RENDER_SSAO = 0x5d; +R3.COMPONENT_D3_PASS_RENDER = 0x5e; +R3.COMPONENT_D3_PASS_FXAA = 0x5f; +R3.COMPONENT_D3_PASS_COPY = 0x60; +R3.COMPONENT_D3_PASS_BLOOM = 0x61; +R3.COMPONENT_D3_PASS = 0x62; +R3.COMPONENT_D3_MESH_SKELETON = 0x63; +R3.COMPONENT_D3_MESH_PARTICLE_ENGINE = 0x64; +R3.COMPONENT_D3_MESH_PARTICLE = 0x65; +R3.COMPONENT_D3_MESH = 0x66; +R3.COMPONENT_D3_MATERIAL_STANDARD = 0x67; +R3.COMPONENT_D3_MATERIAL_SHADER_RAW = 0x68; +R3.COMPONENT_D3_MATERIAL_SHADER = 0x69; +R3.COMPONENT_D3_MATERIAL_POINTS = 0x6a; +R3.COMPONENT_D3_MATERIAL_PHONG = 0x6b; +R3.COMPONENT_D3_MATERIAL_BASIC = 0x6c; +R3.COMPONENT_D3_MATERIAL = 0x6d; +R3.COMPONENT_D3_LIGHT_SPOT = 0x6e; +R3.COMPONENT_D3_LIGHT_RECTAREA = 0x6f; +R3.COMPONENT_D3_LIGHT_POINT = 0x70; +R3.COMPONENT_D3_LIGHT_HEMISPHERE = 0x71; +R3.COMPONENT_D3_LIGHT_DIRECTIONAL = 0x72; +R3.COMPONENT_D3_LIGHT_AMBIENT = 0x73; +R3.COMPONENT_D3_LIGHT = 0x74; +R3.COMPONENT_D3_HELPER = 0x75; +R3.COMPONENT_D3_GEOMETRY_NORMAL_WIREFRAME = 0x76; +R3.COMPONENT_D3_GEOMETRY_NORMAL_TUBE = 0x77; +R3.COMPONENT_D3_GEOMETRY_NORMAL_TORUSKNOT = 0x78; +R3.COMPONENT_D3_GEOMETRY_NORMAL_TORUS = 0x79; +R3.COMPONENT_D3_GEOMETRY_NORMAL_TEXT = 0x7a; +R3.COMPONENT_D3_GEOMETRY_NORMAL_TETRAHEDRON = 0x7b; +R3.COMPONENT_D3_GEOMETRY_NORMAL_SPHERE = 0x7c; +R3.COMPONENT_D3_GEOMETRY_NORMAL_SHAPE = 0x7d; +R3.COMPONENT_D3_GEOMETRY_NORMAL_RING = 0x7e; +R3.COMPONENT_D3_GEOMETRY_NORMAL_POLYHEDRON = 0x7f; +R3.COMPONENT_D3_GEOMETRY_NORMAL_PLANE = 0x80; +R3.COMPONENT_D3_GEOMETRY_NORMAL_PARAMETRIC = 0x81; +R3.COMPONENT_D3_GEOMETRY_NORMAL_OCTAHEDRON = 0x82; +R3.COMPONENT_D3_GEOMETRY_NORMAL_LATHE = 0x83; +R3.COMPONENT_D3_GEOMETRY_NORMAL_ICOSAHEDRON = 0x84; +R3.COMPONENT_D3_GEOMETRY_NORMAL_EXTRUDE = 0x85; +R3.COMPONENT_D3_GEOMETRY_NORMAL_EDGES = 0x86; +R3.COMPONENT_D3_GEOMETRY_NORMAL_DODECAHEDRON = 0x87; +R3.COMPONENT_D3_GEOMETRY_NORMAL_CYLINDER = 0x88; +R3.COMPONENT_D3_GEOMETRY_NORMAL_CONE = 0x89; +R3.COMPONENT_D3_GEOMETRY_NORMAL_CIRCLE = 0x8a; +R3.COMPONENT_D3_GEOMETRY_NORMAL_BOX = 0x8b; +R3.COMPONENT_D3_GEOMETRY_NORMAL = 0x8c; +R3.COMPONENT_D3_GEOMETRY_BUFFER_TUBE = 0x8d; +R3.COMPONENT_D3_GEOMETRY_BUFFER_TORUSKNOT = 0x8e; +R3.COMPONENT_D3_GEOMETRY_BUFFER_TORUS = 0x8f; +R3.COMPONENT_D3_GEOMETRY_BUFFER_TEXT = 0x90; +R3.COMPONENT_D3_GEOMETRY_BUFFER_TETRAHEDRON = 0x91; +R3.COMPONENT_D3_GEOMETRY_BUFFER_SPHERE = 0x92; +R3.COMPONENT_D3_GEOMETRY_BUFFER_SHAPE = 0x93; +R3.COMPONENT_D3_GEOMETRY_BUFFER_RING = 0x94; +R3.COMPONENT_D3_GEOMETRY_BUFFER_POLYHEDRON = 0x95; +R3.COMPONENT_D3_GEOMETRY_BUFFER_PLANE = 0x96; +R3.COMPONENT_D3_GEOMETRY_BUFFER_PARAMETRIC = 0x97; +R3.COMPONENT_D3_GEOMETRY_BUFFER_OCTAHEDRON = 0x98; +R3.COMPONENT_D3_GEOMETRY_BUFFER_LATHE = 0x99; +R3.COMPONENT_D3_GEOMETRY_BUFFER_INSTANCED = 0x9a; +R3.COMPONENT_D3_GEOMETRY_BUFFER_ICOSAHEDRON = 0x9b; +R3.COMPONENT_D3_GEOMETRY_BUFFER_EXTRUDE = 0x9c; +R3.COMPONENT_D3_GEOMETRY_BUFFER_DODECAHEDRON = 0x9d; +R3.COMPONENT_D3_GEOMETRY_BUFFER_CYLINDER = 0x9e; +R3.COMPONENT_D3_GEOMETRY_BUFFER_CONE = 0x9f; +R3.COMPONENT_D3_GEOMETRY_BUFFER_CIRCLE = 0xa0; +R3.COMPONENT_D3_GEOMETRY_BUFFER_BOX = 0xa1; +R3.COMPONENT_D3_GEOMETRY_BUFFER = 0xa2; +R3.COMPONENT_D3_GEOMETRY = 0xa3; +R3.COMPONENT_D3_FRICTIONMATERIAL = 0xa4; +R3.COMPONENT_D3_FRICTIONCONTACTMATERIAL = 0xa5; +R3.COMPONENT_D3_FOG_NORMAL = 0xa6; +R3.COMPONENT_D3_FOG_EXP = 0xa7; +R3.COMPONENT_D3_FOG = 0xa8; +R3.COMPONENT_D3_FACE_GRAPHICS = 0xa9; +R3.COMPONENT_D3_FACE = 0xaa; +R3.COMPONENT_D3_EFFECT_STEREO = 0xab; +R3.COMPONENT_D3_EFFECT_PARALLAX = 0xac; +R3.COMPONENT_D3_EFFECT_ANAGLYPH = 0xad; +R3.COMPONENT_D3_EFFECT = 0xae; +R3.COMPONENT_D3_COMPOSER = 0xaf; +R3.COMPONENT_D3_CAMERA_PERSPECTIVE_STEREO = 0xb0; +R3.COMPONENT_D3_CAMERA_PERSPECTIVE = 0xb1; +R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC_SCALEDASPECT = 0xb2; +R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC_FIXEDASPECT = 0xb3; +R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC = 0xb4; +R3.COMPONENT_D3_CAMERA_CUBE = 0xb5; +R3.COMPONENT_D3_CAMERA = 0xb6; +R3.COMPONENT_D3_BROADPHASE = 0xb7; +R3.COMPONENT_D3_BONEWEIGHT = 0xb8; +R3.COMPONENT_D3_BONE = 0xb9; +R3.COMPONENT_D3_AUDIO = 0xba; +R3.COMPONENT_D3_ANIMATION = 0xbb; +R3.COMPONENT_D3_OBJECT = 0xbc; +R3.COMPONENT_CUSTOMCODE = 0xbd; +R3.COMPONENT_CURVE_PATH_D2_SHAPE = 0xbe; +R3.COMPONENT_CURVE_PATH_D2 = 0xbf; +R3.COMPONENT_CURVE_PATH = 0xc0; +R3.COMPONENT_CURVE = 0xc1; +R3.COMPONENT_CONTROLS_TOUCH = 0xc2; +R3.COMPONENT_CONTROLS_MOUSE = 0xc3; +R3.COMPONENT_CONTROLS_KEYBOARD = 0xc4; +R3.COMPONENT_CONTROLS_D3_ORBIT = 0xc5; +R3.COMPONENT_CONTROLS_D3_FIRSTPERSON = 0xc6; +R3.COMPONENT_CONTROLS_D3 = 0xc7; +R3.COMPONENT_CONTROLS = 0xc8; +R3.COMPONENT_COLOR = 0xc9; +R3.COMPONENT_CLOCK = 0xca; +R3.COMPONENT_CANVAS = 0xcb; +R3.COMPONENT_BOX3 = 0xcc; +R3.MAX_COMPONENTS = 0xcd; + +/** + * R3.GetComponentType + * @param component + * @returns {number} + */ +R3.GetComponentType = function(component) { + + if (component instanceof R3.Video) { + return R3.COMPONENT_VIDEO; + } + + if (component instanceof R3.Vector4) { + return R3.COMPONENT_VECTOR4; + } + + if (component instanceof R3.Vector3) { + return R3.COMPONENT_VECTOR3; + } + + if (component instanceof R3.Vector2) { + return R3.COMPONENT_VECTOR2; + } + + if (component instanceof R3.User) { + return R3.COMPONENT_USER; + } + + if (component instanceof R3.Stats) { + return R3.COMPONENT_STATS; + } + + if (component instanceof R3.Sphere) { + return R3.COMPONENT_SPHERE; + } + + if (component instanceof R3.Socket.Receive) { + return R3.COMPONENT_SOCKET_RECEIVE; + } + + if (component instanceof R3.Socket.Cast) { + return R3.COMPONENT_SOCKET_CAST; + } + + if (component instanceof R3.Socket) { + return R3.COMPONENT_SOCKET; + } + + if (component instanceof R3.Server) { + return R3.COMPONENT_SERVER; + } + + if (component instanceof R3.Scalar) { + return R3.COMPONENT_SCALAR; + } + + if (component instanceof R3.Renderer.D3.Canvas.Target) { + return R3.COMPONENT_RENDERER_D3_CANVAS_TARGET; + } + + if (component instanceof R3.Renderer.D3.Canvas) { + return R3.COMPONENT_RENDERER_D3_CANVAS; + } + + if (component instanceof R3.Renderer.D3) { + return R3.COMPONENT_RENDERER_D3; + } + + if (component instanceof R3.Renderer.D2) { + return R3.COMPONENT_RENDERER_D2; + } + + if (component instanceof R3.Renderer) { + return R3.COMPONENT_RENDERER; + } + + if (component instanceof R3.Query.Users) { + return R3.COMPONENT_QUERY_USERS; + } + + if (component instanceof R3.Query.UserDevices) { + return R3.COMPONENT_QUERY_USERDEVICES; + } + + if (component instanceof R3.Query.Logins.VPN) { + return R3.COMPONENT_QUERY_LOGINS_VPN; + } + + if (component instanceof R3.Query.Logins.Devices) { + return R3.COMPONENT_QUERY_LOGINS_DEVICES; + } + + if (component instanceof R3.Query.Logins.Applications) { + return R3.COMPONENT_QUERY_LOGINS_APPLICATIONS; + } + + if (component instanceof R3.Query.Logins) { + return R3.COMPONENT_QUERY_LOGINS; + } + + if (component instanceof R3.Query.Devices.Unknown) { + return R3.COMPONENT_QUERY_DEVICES_UNKNOWN; + } + + if (component instanceof R3.Query.Devices.SQL) { + return R3.COMPONENT_QUERY_DEVICES_SQL; + } + + if (component instanceof R3.Query.Devices.Known) { + return R3.COMPONENT_QUERY_DEVICES_KNOWN; + } + + if (component instanceof R3.Query.Devices) { + return R3.COMPONENT_QUERY_DEVICES; + } + + if (component instanceof R3.Query.Alerts.Timeseries) { + return R3.COMPONENT_QUERY_ALERTS_TIMESERIES; + } + + if (component instanceof R3.Query.Alerts.Summary) { + return R3.COMPONENT_QUERY_ALERTS_SUMMARY; + } + + if (component instanceof R3.Query.Alerts.List) { + return R3.COMPONENT_QUERY_ALERTS_LIST; + } + + if (component instanceof R3.Query.Alerts.FirstTimeLogin.VPN) { + return R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_VPN; + } + + if (component instanceof R3.Query.Alerts.FirstTimeLogin.Devices) { + return R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_DEVICES; + } + + if (component instanceof R3.Query.Alerts.FirstTimeLogin.Applications) { + return R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_APPLICATIONS; + } + + if (component instanceof R3.Query.Alerts.FirstTimeLogin) { + return R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN; + } + + if (component instanceof R3.Query.Alerts.Buckets) { + return R3.COMPONENT_QUERY_ALERTS_BUCKETS; + } + + if (component instanceof R3.Query.Alerts) { + return R3.COMPONENT_QUERY_ALERTS; + } + + if (component instanceof R3.Query) { + return R3.COMPONENT_QUERY; + } + + if (component instanceof R3.Quaternion.Points) { + return R3.COMPONENT_QUATERNION_POINTS; + } + + if (component instanceof R3.Quaternion) { + return R3.COMPONENT_QUATERNION; + } + + if (component instanceof R3.Project.D3.VR) { + return R3.COMPONENT_PROJECT_D3_VR; + } + + if (component instanceof R3.Project.D3) { + return R3.COMPONENT_PROJECT_D3; + } + + if (component instanceof R3.Project.D2) { + return R3.COMPONENT_PROJECT_D2; + } + + if (component instanceof R3.Project) { + return R3.COMPONENT_PROJECT; + } + + if (component instanceof R3.Plane) { + return R3.COMPONENT_PLANE; + } + + if (component instanceof R3.Mouse) { + return R3.COMPONENT_MOUSE; + } + + if (component instanceof R3.Matrix4) { + return R3.COMPONENT_MATRIX4; + } + + if (component instanceof R3.Image) { + return R3.COMPONENT_IMAGE; + } + + if (component instanceof R3.Group) { + return R3.COMPONENT_GROUP; + } + + if (component instanceof R3.Graph.Table) { + return R3.COMPONENT_GRAPH_TABLE; + } + + if (component instanceof R3.Graph.Metric) { + return R3.COMPONENT_GRAPH_METRIC; + } + + if (component instanceof R3.Graph.Barchart.Stacked) { + return R3.COMPONENT_GRAPH_BARCHART_STACKED; + } + + if (component instanceof R3.Graph.Barchart) { + return R3.COMPONENT_GRAPH_BARCHART; + } + + if (component instanceof R3.Graph) { + return R3.COMPONENT_GRAPH; + } + + if (component instanceof R3.Font) { + return R3.COMPONENT_FONT; + } + + if (component instanceof R3.Entity) { + return R3.COMPONENT_ENTITY; + } + + if (component instanceof R3.DrawRange) { + return R3.COMPONENT_DRAWRANGE; + } + + if (component instanceof R3.DomElement) { + return R3.COMPONENT_DOMELEMENT; + } + + if (component instanceof R3.D3.Viewport.ZoomedAspect) { + return R3.COMPONENT_D3_VIEWPORT_ZOOMEDASPECT; + } + + if (component instanceof R3.D3.Viewport.FixedAspect.VR) { + return R3.COMPONENT_D3_VIEWPORT_FIXEDASPECT_VR; + } + + if (component instanceof R3.D3.Viewport.FixedAspect) { + return R3.COMPONENT_D3_VIEWPORT_FIXEDASPECT; + } + + if (component instanceof R3.D3.Viewport) { + return R3.COMPONENT_D3_VIEWPORT; + } + + if (component instanceof R3.D3.Vertex) { + return R3.COMPONENT_D3_VERTEX; + } + + if (component instanceof R3.D3.Texture.Image) { + return R3.COMPONENT_D3_TEXTURE_IMAGE; + } + + if (component instanceof R3.D3.Texture.Cube) { + return R3.COMPONENT_D3_TEXTURE_CUBE; + } + + if (component instanceof R3.D3.Texture.Canvas) { + return R3.COMPONENT_D3_TEXTURE_CANVAS; + } + + if (component instanceof R3.D3.Texture) { + return R3.COMPONENT_D3_TEXTURE; + } + + if (component instanceof R3.D3.Text) { + return R3.COMPONENT_D3_TEXT; + } + + if (component instanceof R3.D3.Spline) { + return R3.COMPONENT_D3_SPLINE; + } + + if (component instanceof R3.D3.Solver) { + return R3.COMPONENT_D3_SOLVER; + } + + if (component instanceof R3.D3.Skeleton) { + return R3.COMPONENT_D3_SKELETON; + } + + if (component instanceof R3.D3.Shape.TriMesh) { + return R3.COMPONENT_D3_SHAPE_TRIMESH; + } + + if (component instanceof R3.D3.Shape.Sphere) { + return R3.COMPONENT_D3_SHAPE_SPHERE; + } + + if (component instanceof R3.D3.Shape.Plane) { + return R3.COMPONENT_D3_SHAPE_PLANE; + } + + if (component instanceof R3.D3.Shape.HeightMap) { + return R3.COMPONENT_D3_SHAPE_HEIGHTMAP; + } + + if (component instanceof R3.D3.Shape.ConvexHull.Cylinder) { + return R3.COMPONENT_D3_SHAPE_CONVEXHULL_CYLINDER; + } + + if (component instanceof R3.D3.Shape.ConvexHull) { + return R3.COMPONENT_D3_SHAPE_CONVEXHULL; + } + + if (component instanceof R3.D3.Shape.Box) { + return R3.COMPONENT_D3_SHAPE_BOX; + } + + if (component instanceof R3.D3.Shape) { + return R3.COMPONENT_D3_SHAPE; + } + + if (component instanceof R3.D3.Shadow.Spot) { + return R3.COMPONENT_D3_SHADOW_SPOT; + } + + if (component instanceof R3.D3.Shadow.Directional) { + return R3.COMPONENT_D3_SHADOW_DIRECTIONAL; + } + + if (component instanceof R3.D3.Shadow) { + return R3.COMPONENT_D3_SHADOW; + } + + if (component instanceof R3.D3.Shader.Vertex) { + return R3.COMPONENT_D3_SHADER_VERTEX; + } + + if (component instanceof R3.D3.Shader.Fragment) { + return R3.COMPONENT_D3_SHADER_FRAGMENT; + } + + if (component instanceof R3.D3.Shader) { + return R3.COMPONENT_D3_SHADER; + } + + if (component instanceof R3.D3.Scene) { + return R3.COMPONENT_D3_SCENE; + } + + if (component instanceof R3.D3.RigidBody) { + return R3.COMPONENT_D3_RIGIDBODY; + } + + if (component instanceof R3.D3.RenderTarget.Cube) { + return R3.COMPONENT_D3_RENDERTARGET_CUBE; + } + + if (component instanceof R3.D3.RenderTarget) { + return R3.COMPONENT_D3_RENDERTARGET; + } + + if (component instanceof R3.D3.Raycaster) { + return R3.COMPONENT_D3_RAYCASTER; + } + + if (component instanceof R3.D3.RaycastWheel) { + return R3.COMPONENT_D3_RAYCASTWHEEL; + } + + if (component instanceof R3.D3.RaycastVehicle) { + return R3.COMPONENT_D3_RAYCASTVEHICLE; + } + + if (component instanceof R3.D3.PhysicsWorld) { + return R3.COMPONENT_D3_PHYSICSWORLD; + } + + if (component instanceof R3.D3.Pass.Render.SSAO) { + return R3.COMPONENT_D3_PASS_RENDER_SSAO; + } + + if (component instanceof R3.D3.Pass.Render) { + return R3.COMPONENT_D3_PASS_RENDER; + } + + if (component instanceof R3.D3.Pass.FXAA) { + return R3.COMPONENT_D3_PASS_FXAA; + } + + if (component instanceof R3.D3.Pass.Copy) { + return R3.COMPONENT_D3_PASS_COPY; + } + + if (component instanceof R3.D3.Pass.Bloom) { + return R3.COMPONENT_D3_PASS_BLOOM; + } + + if (component instanceof R3.D3.Pass) { + return R3.COMPONENT_D3_PASS; + } + + if (component instanceof R3.D3.Mesh.Skeleton) { + return R3.COMPONENT_D3_MESH_SKELETON; + } + + if (component instanceof R3.D3.Mesh.Particle.Engine) { + return R3.COMPONENT_D3_MESH_PARTICLE_ENGINE; + } + + if (component instanceof R3.D3.Mesh.Particle) { + return R3.COMPONENT_D3_MESH_PARTICLE; + } + + if (component instanceof R3.D3.Mesh) { + return R3.COMPONENT_D3_MESH; + } + + if (component instanceof R3.D3.Material.Standard) { + return R3.COMPONENT_D3_MATERIAL_STANDARD; + } + + if (component instanceof R3.D3.Material.Shader.Raw) { + return R3.COMPONENT_D3_MATERIAL_SHADER_RAW; + } + + if (component instanceof R3.D3.Material.Shader) { + return R3.COMPONENT_D3_MATERIAL_SHADER; + } + + if (component instanceof R3.D3.Material.Points) { + return R3.COMPONENT_D3_MATERIAL_POINTS; + } + + if (component instanceof R3.D3.Material.Phong) { + return R3.COMPONENT_D3_MATERIAL_PHONG; + } + + if (component instanceof R3.D3.Material.Basic) { + return R3.COMPONENT_D3_MATERIAL_BASIC; + } + + if (component instanceof R3.D3.Material) { + return R3.COMPONENT_D3_MATERIAL; + } + + if (component instanceof R3.D3.Light.Spot) { + return R3.COMPONENT_D3_LIGHT_SPOT; + } + + if (component instanceof R3.D3.Light.RectArea) { + return R3.COMPONENT_D3_LIGHT_RECTAREA; + } + + if (component instanceof R3.D3.Light.Point) { + return R3.COMPONENT_D3_LIGHT_POINT; + } + + if (component instanceof R3.D3.Light.Hemisphere) { + return R3.COMPONENT_D3_LIGHT_HEMISPHERE; + } + + if (component instanceof R3.D3.Light.Directional) { + return R3.COMPONENT_D3_LIGHT_DIRECTIONAL; + } + + if (component instanceof R3.D3.Light.Ambient) { + return R3.COMPONENT_D3_LIGHT_AMBIENT; + } + + if (component instanceof R3.D3.Light) { + return R3.COMPONENT_D3_LIGHT; + } + + if (component instanceof R3.D3.Helper) { + return R3.COMPONENT_D3_HELPER; + } + + if (component instanceof R3.D3.Geometry.Normal.Wireframe) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_WIREFRAME; + } + + if (component instanceof R3.D3.Geometry.Normal.Tube) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_TUBE; + } + + if (component instanceof R3.D3.Geometry.Normal.TorusKnot) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_TORUSKNOT; + } + + if (component instanceof R3.D3.Geometry.Normal.Torus) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_TORUS; + } + + if (component instanceof R3.D3.Geometry.Normal.Text) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_TEXT; + } + + if (component instanceof R3.D3.Geometry.Normal.Tetrahedron) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_TETRAHEDRON; + } + + if (component instanceof R3.D3.Geometry.Normal.Sphere) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_SPHERE; + } + + if (component instanceof R3.D3.Geometry.Normal.Shape) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_SHAPE; + } + + if (component instanceof R3.D3.Geometry.Normal.Ring) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_RING; + } + + if (component instanceof R3.D3.Geometry.Normal.Polyhedron) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_POLYHEDRON; + } + + if (component instanceof R3.D3.Geometry.Normal.Plane) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_PLANE; + } + + if (component instanceof R3.D3.Geometry.Normal.Parametric) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_PARAMETRIC; + } + + if (component instanceof R3.D3.Geometry.Normal.Octahedron) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_OCTAHEDRON; + } + + if (component instanceof R3.D3.Geometry.Normal.Lathe) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_LATHE; + } + + if (component instanceof R3.D3.Geometry.Normal.Icosahedron) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_ICOSAHEDRON; + } + + if (component instanceof R3.D3.Geometry.Normal.Extrude) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_EXTRUDE; + } + + if (component instanceof R3.D3.Geometry.Normal.Edges) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_EDGES; + } + + if (component instanceof R3.D3.Geometry.Normal.Dodecahedron) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_DODECAHEDRON; + } + + if (component instanceof R3.D3.Geometry.Normal.Cylinder) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_CYLINDER; + } + + if (component instanceof R3.D3.Geometry.Normal.Cone) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_CONE; + } + + if (component instanceof R3.D3.Geometry.Normal.Circle) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_CIRCLE; + } + + if (component instanceof R3.D3.Geometry.Normal.Box) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_BOX; + } + + if (component instanceof R3.D3.Geometry.Normal) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL; + } + + if (component instanceof R3.D3.Geometry.Buffer.Tube) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_TUBE; + } + + if (component instanceof R3.D3.Geometry.Buffer.TorusKnot) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_TORUSKNOT; + } + + if (component instanceof R3.D3.Geometry.Buffer.Torus) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_TORUS; + } + + if (component instanceof R3.D3.Geometry.Buffer.Text) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_TEXT; + } + + if (component instanceof R3.D3.Geometry.Buffer.Tetrahedron) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_TETRAHEDRON; + } + + if (component instanceof R3.D3.Geometry.Buffer.Sphere) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_SPHERE; + } + + if (component instanceof R3.D3.Geometry.Buffer.Shape) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_SHAPE; + } + + if (component instanceof R3.D3.Geometry.Buffer.Ring) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_RING; + } + + if (component instanceof R3.D3.Geometry.Buffer.Polyhedron) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_POLYHEDRON; + } + + if (component instanceof R3.D3.Geometry.Buffer.Plane) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_PLANE; + } + + if (component instanceof R3.D3.Geometry.Buffer.Parametric) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_PARAMETRIC; + } + + if (component instanceof R3.D3.Geometry.Buffer.Octahedron) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_OCTAHEDRON; + } + + if (component instanceof R3.D3.Geometry.Buffer.Lathe) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_LATHE; + } + + if (component instanceof R3.D3.Geometry.Buffer.Instanced) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_INSTANCED; + } + + if (component instanceof R3.D3.Geometry.Buffer.Icosahedron) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_ICOSAHEDRON; + } + + if (component instanceof R3.D3.Geometry.Buffer.Extrude) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_EXTRUDE; + } + + if (component instanceof R3.D3.Geometry.Buffer.Dodecahedron) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_DODECAHEDRON; + } + + if (component instanceof R3.D3.Geometry.Buffer.Cylinder) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_CYLINDER; + } + + if (component instanceof R3.D3.Geometry.Buffer.Cone) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_CONE; + } + + if (component instanceof R3.D3.Geometry.Buffer.Circle) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_CIRCLE; + } + + if (component instanceof R3.D3.Geometry.Buffer.Box) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_BOX; + } + + if (component instanceof R3.D3.Geometry.Buffer) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER; + } + + if (component instanceof R3.D3.Geometry) { + return R3.COMPONENT_D3_GEOMETRY; + } + + if (component instanceof R3.D3.FrictionMaterial) { + return R3.COMPONENT_D3_FRICTIONMATERIAL; + } + + if (component instanceof R3.D3.FrictionContactMaterial) { + return R3.COMPONENT_D3_FRICTIONCONTACTMATERIAL; + } + + if (component instanceof R3.D3.Fog.Normal) { + return R3.COMPONENT_D3_FOG_NORMAL; + } + + if (component instanceof R3.D3.Fog.Exp) { + return R3.COMPONENT_D3_FOG_EXP; + } + + if (component instanceof R3.D3.Fog) { + return R3.COMPONENT_D3_FOG; + } + + if (component instanceof R3.D3.Face.Graphics) { + return R3.COMPONENT_D3_FACE_GRAPHICS; + } + + if (component instanceof R3.D3.Face) { + return R3.COMPONENT_D3_FACE; + } + + if (component instanceof R3.D3.Effect.Stereo) { + return R3.COMPONENT_D3_EFFECT_STEREO; + } + + if (component instanceof R3.D3.Effect.Parallax) { + return R3.COMPONENT_D3_EFFECT_PARALLAX; + } + + if (component instanceof R3.D3.Effect.Anaglyph) { + return R3.COMPONENT_D3_EFFECT_ANAGLYPH; + } + + if (component instanceof R3.D3.Effect) { + return R3.COMPONENT_D3_EFFECT; + } + + if (component instanceof R3.D3.Composer) { + return R3.COMPONENT_D3_COMPOSER; + } + + if (component instanceof R3.D3.Camera.Perspective.Stereo) { + return R3.COMPONENT_D3_CAMERA_PERSPECTIVE_STEREO; + } + + if (component instanceof R3.D3.Camera.Perspective) { + return R3.COMPONENT_D3_CAMERA_PERSPECTIVE; + } + + if (component instanceof R3.D3.Camera.Orthographic.ScaledAspect) { + return R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC_SCALEDASPECT; + } + + if (component instanceof R3.D3.Camera.Orthographic.FixedAspect) { + return R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC_FIXEDASPECT; + } + + if (component instanceof R3.D3.Camera.Orthographic) { + return R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC; + } + + if (component instanceof R3.D3.Camera.Cube) { + return R3.COMPONENT_D3_CAMERA_CUBE; + } + + if (component instanceof R3.D3.Camera) { + return R3.COMPONENT_D3_CAMERA; + } + + if (component instanceof R3.D3.Broadphase) { + return R3.COMPONENT_D3_BROADPHASE; + } + + if (component instanceof R3.D3.BoneWeight) { + return R3.COMPONENT_D3_BONEWEIGHT; + } + + if (component instanceof R3.D3.Bone) { + return R3.COMPONENT_D3_BONE; + } + + if (component instanceof R3.D3.Audio) { + return R3.COMPONENT_D3_AUDIO; + } + + if (component instanceof R3.D3.Animation) { + return R3.COMPONENT_D3_ANIMATION; + } + + if (component instanceof R3.D3.Object) { + return R3.COMPONENT_D3_OBJECT; + } + + if (component instanceof R3.D3.API.Viewport.ZoomedAspect) { + return R3.COMPONENT_D3_VIEWPORT_ZOOMEDASPECT; + } + + if (component instanceof R3.D3.API.Viewport.FixedAspect.VR) { + return R3.COMPONENT_D3_VIEWPORT_FIXEDASPECT_VR; + } + + if (component instanceof R3.D3.API.Viewport.FixedAspect) { + return R3.COMPONENT_D3_VIEWPORT_FIXEDASPECT; + } + + if (component instanceof R3.D3.API.Viewport) { + return R3.COMPONENT_D3_VIEWPORT; + } + + if (component instanceof R3.D3.API.Vertex) { + return R3.COMPONENT_D3_VERTEX; + } + + if (component instanceof R3.D3.API.Texture.Image) { + return R3.COMPONENT_D3_TEXTURE_IMAGE; + } + + if (component instanceof R3.D3.API.Texture.Cube) { + return R3.COMPONENT_D3_TEXTURE_CUBE; + } + + if (component instanceof R3.D3.API.Texture.Canvas) { + return R3.COMPONENT_D3_TEXTURE_CANVAS; + } + + if (component instanceof R3.D3.API.Texture) { + return R3.COMPONENT_D3_TEXTURE; + } + + if (component instanceof R3.D3.API.Text) { + return R3.COMPONENT_D3_TEXT; + } + + if (component instanceof R3.D3.API.Spline) { + return R3.COMPONENT_D3_SPLINE; + } + + if (component instanceof R3.D3.API.Solver) { + return R3.COMPONENT_D3_SOLVER; + } + + if (component instanceof R3.D3.API.Skeleton) { + return R3.COMPONENT_D3_SKELETON; + } + + if (component instanceof R3.D3.API.Shape.TriMesh) { + return R3.COMPONENT_D3_SHAPE_TRIMESH; + } + + if (component instanceof R3.D3.API.Shape.Sphere) { + return R3.COMPONENT_D3_SHAPE_SPHERE; + } + + if (component instanceof R3.D3.API.Shape.Plane) { + return R3.COMPONENT_D3_SHAPE_PLANE; + } + + if (component instanceof R3.D3.API.Shape.HeightMap) { + return R3.COMPONENT_D3_SHAPE_HEIGHTMAP; + } + + if (component instanceof R3.D3.API.Shape.ConvexHull.Cylinder) { + return R3.COMPONENT_D3_SHAPE_CONVEXHULL_CYLINDER; + } + + if (component instanceof R3.D3.API.Shape.ConvexHull) { + return R3.COMPONENT_D3_SHAPE_CONVEXHULL; + } + + if (component instanceof R3.D3.API.Shape.Box) { + return R3.COMPONENT_D3_SHAPE_BOX; + } + + if (component instanceof R3.D3.API.Shape) { + return R3.COMPONENT_D3_SHAPE; + } + + if (component instanceof R3.D3.API.Shadow.Spot) { + return R3.COMPONENT_D3_SHADOW_SPOT; + } + + if (component instanceof R3.D3.API.Shadow.Directional) { + return R3.COMPONENT_D3_SHADOW_DIRECTIONAL; + } + + if (component instanceof R3.D3.API.Shadow) { + return R3.COMPONENT_D3_SHADOW; + } + + if (component instanceof R3.D3.API.Shader.Vertex) { + return R3.COMPONENT_D3_SHADER_VERTEX; + } + + if (component instanceof R3.D3.API.Shader.Fragment) { + return R3.COMPONENT_D3_SHADER_FRAGMENT; + } + + if (component instanceof R3.D3.API.Shader) { + return R3.COMPONENT_D3_SHADER; + } + + if (component instanceof R3.D3.API.Scene) { + return R3.COMPONENT_D3_SCENE; + } + + if (component instanceof R3.D3.API.RigidBody) { + return R3.COMPONENT_D3_RIGIDBODY; + } + + if (component instanceof R3.D3.API.RenderTarget.Cube) { + return R3.COMPONENT_D3_RENDERTARGET_CUBE; + } + + if (component instanceof R3.D3.API.RenderTarget) { + return R3.COMPONENT_D3_RENDERTARGET; + } + + if (component instanceof R3.D3.API.Raycaster) { + return R3.COMPONENT_D3_RAYCASTER; + } + + if (component instanceof R3.D3.API.RaycastWheel) { + return R3.COMPONENT_D3_RAYCASTWHEEL; + } + + if (component instanceof R3.D3.API.RaycastVehicle) { + return R3.COMPONENT_D3_RAYCASTVEHICLE; + } + + if (component instanceof R3.D3.API.PhysicsWorld) { + return R3.COMPONENT_D3_PHYSICSWORLD; + } + + if (component instanceof R3.D3.API.Pass.Render.SSAO) { + return R3.COMPONENT_D3_PASS_RENDER_SSAO; + } + + if (component instanceof R3.D3.API.Pass.Render) { + return R3.COMPONENT_D3_PASS_RENDER; + } + + if (component instanceof R3.D3.API.Pass.FXAA) { + return R3.COMPONENT_D3_PASS_FXAA; + } + + if (component instanceof R3.D3.API.Pass.Copy) { + return R3.COMPONENT_D3_PASS_COPY; + } + + if (component instanceof R3.D3.API.Pass.Bloom) { + return R3.COMPONENT_D3_PASS_BLOOM; + } + + if (component instanceof R3.D3.API.Pass) { + return R3.COMPONENT_D3_PASS; + } + + if (component instanceof R3.D3.API.Mesh.Skeleton) { + return R3.COMPONENT_D3_MESH_SKELETON; + } + + if (component instanceof R3.D3.API.Mesh.Particle.Engine) { + return R3.COMPONENT_D3_MESH_PARTICLE_ENGINE; + } + + if (component instanceof R3.D3.API.Mesh.Particle) { + return R3.COMPONENT_D3_MESH_PARTICLE; + } + + if (component instanceof R3.D3.API.Mesh) { + return R3.COMPONENT_D3_MESH; + } + + if (component instanceof R3.D3.API.Material.Standard) { + return R3.COMPONENT_D3_MATERIAL_STANDARD; + } + + if (component instanceof R3.D3.API.Material.Shader.Raw) { + return R3.COMPONENT_D3_MATERIAL_SHADER_RAW; + } + + if (component instanceof R3.D3.API.Material.Shader) { + return R3.COMPONENT_D3_MATERIAL_SHADER; + } + + if (component instanceof R3.D3.API.Material.Points) { + return R3.COMPONENT_D3_MATERIAL_POINTS; + } + + if (component instanceof R3.D3.API.Material.Phong) { + return R3.COMPONENT_D3_MATERIAL_PHONG; + } + + if (component instanceof R3.D3.API.Material.Basic) { + return R3.COMPONENT_D3_MATERIAL_BASIC; + } + + if (component instanceof R3.D3.API.Material) { + return R3.COMPONENT_D3_MATERIAL; + } + + if (component instanceof R3.D3.API.Light.Spot) { + return R3.COMPONENT_D3_LIGHT_SPOT; + } + + if (component instanceof R3.D3.API.Light.RectArea) { + return R3.COMPONENT_D3_LIGHT_RECTAREA; + } + + if (component instanceof R3.D3.API.Light.Point) { + return R3.COMPONENT_D3_LIGHT_POINT; + } + + if (component instanceof R3.D3.API.Light.Hemisphere) { + return R3.COMPONENT_D3_LIGHT_HEMISPHERE; + } + + if (component instanceof R3.D3.API.Light.Directional) { + return R3.COMPONENT_D3_LIGHT_DIRECTIONAL; + } + + if (component instanceof R3.D3.API.Light.Ambient) { + return R3.COMPONENT_D3_LIGHT_AMBIENT; + } + + if (component instanceof R3.D3.API.Light) { + return R3.COMPONENT_D3_LIGHT; + } + + if (component instanceof R3.D3.API.Helper) { + return R3.COMPONENT_D3_HELPER; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Wireframe) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_WIREFRAME; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Tube) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_TUBE; + } + + if (component instanceof R3.D3.API.Geometry.Normal.TorusKnot) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_TORUSKNOT; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Torus) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_TORUS; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Text) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_TEXT; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Tetrahedron) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_TETRAHEDRON; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Sphere) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_SPHERE; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Shape) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_SHAPE; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Ring) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_RING; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Polyhedron) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_POLYHEDRON; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Plane) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_PLANE; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Parametric) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_PARAMETRIC; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Octahedron) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_OCTAHEDRON; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Lathe) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_LATHE; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Icosahedron) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_ICOSAHEDRON; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Extrude) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_EXTRUDE; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Edges) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_EDGES; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Dodecahedron) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_DODECAHEDRON; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Cylinder) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_CYLINDER; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Cone) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_CONE; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Circle) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_CIRCLE; + } + + if (component instanceof R3.D3.API.Geometry.Normal.Box) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL_BOX; + } + + if (component instanceof R3.D3.API.Geometry.Normal) { + return R3.COMPONENT_D3_GEOMETRY_NORMAL; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Tube) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_TUBE; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.TorusKnot) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_TORUSKNOT; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Torus) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_TORUS; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Text) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_TEXT; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Tetrahedron) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_TETRAHEDRON; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Sphere) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_SPHERE; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Shape) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_SHAPE; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Ring) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_RING; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Polyhedron) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_POLYHEDRON; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Plane) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_PLANE; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Parametric) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_PARAMETRIC; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Octahedron) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_OCTAHEDRON; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Lathe) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_LATHE; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Instanced) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_INSTANCED; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Icosahedron) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_ICOSAHEDRON; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Extrude) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_EXTRUDE; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Dodecahedron) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_DODECAHEDRON; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Cylinder) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_CYLINDER; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Cone) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_CONE; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Circle) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_CIRCLE; + } + + if (component instanceof R3.D3.API.Geometry.Buffer.Box) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER_BOX; + } + + if (component instanceof R3.D3.API.Geometry.Buffer) { + return R3.COMPONENT_D3_GEOMETRY_BUFFER; + } + + if (component instanceof R3.D3.API.Geometry) { + return R3.COMPONENT_D3_GEOMETRY; + } + + if (component instanceof R3.D3.API.FrictionMaterial) { + return R3.COMPONENT_D3_FRICTIONMATERIAL; + } + + if (component instanceof R3.D3.API.FrictionContactMaterial) { + return R3.COMPONENT_D3_FRICTIONCONTACTMATERIAL; + } + + if (component instanceof R3.D3.API.Fog.Normal) { + return R3.COMPONENT_D3_FOG_NORMAL; + } + + if (component instanceof R3.D3.API.Fog.Exp) { + return R3.COMPONENT_D3_FOG_EXP; + } + + if (component instanceof R3.D3.API.Fog) { + return R3.COMPONENT_D3_FOG; + } + + if (component instanceof R3.D3.API.Face.Graphics) { + return R3.COMPONENT_D3_FACE_GRAPHICS; + } + + if (component instanceof R3.D3.API.Face) { + return R3.COMPONENT_D3_FACE; + } + + if (component instanceof R3.D3.API.Effect.Stereo) { + return R3.COMPONENT_D3_EFFECT_STEREO; + } + + if (component instanceof R3.D3.API.Effect.Parallax) { + return R3.COMPONENT_D3_EFFECT_PARALLAX; + } + + if (component instanceof R3.D3.API.Effect.Anaglyph) { + return R3.COMPONENT_D3_EFFECT_ANAGLYPH; + } + + if (component instanceof R3.D3.API.Effect) { + return R3.COMPONENT_D3_EFFECT; + } + + if (component instanceof R3.D3.API.Composer) { + return R3.COMPONENT_D3_COMPOSER; + } + + if (component instanceof R3.D3.API.Camera.Perspective.Stereo) { + return R3.COMPONENT_D3_CAMERA_PERSPECTIVE_STEREO; + } + + if (component instanceof R3.D3.API.Camera.Perspective) { + return R3.COMPONENT_D3_CAMERA_PERSPECTIVE; + } + + if (component instanceof R3.D3.API.Camera.Orthographic.ScaledAspect) { + return R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC_SCALEDASPECT; + } + + if (component instanceof R3.D3.API.Camera.Orthographic.FixedAspect) { + return R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC_FIXEDASPECT; + } + + if (component instanceof R3.D3.API.Camera.Orthographic) { + return R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC; + } + + if (component instanceof R3.D3.API.Camera.Cube) { + return R3.COMPONENT_D3_CAMERA_CUBE; + } + + if (component instanceof R3.D3.API.Camera) { + return R3.COMPONENT_D3_CAMERA; + } + + if (component instanceof R3.D3.API.Broadphase) { + return R3.COMPONENT_D3_BROADPHASE; + } + + if (component instanceof R3.D3.API.BoneWeight) { + return R3.COMPONENT_D3_BONEWEIGHT; + } + + if (component instanceof R3.D3.API.Bone) { + return R3.COMPONENT_D3_BONE; + } + + if (component instanceof R3.D3.API.Audio) { + return R3.COMPONENT_D3_AUDIO; + } + + if (component instanceof R3.D3.API.Animation) { + return R3.COMPONENT_D3_ANIMATION; + } + + if (component instanceof R3.D3.API.Object) { + return R3.COMPONENT_D3_OBJECT; + } + + if (component instanceof R3.CustomCode) { + return R3.COMPONENT_CUSTOMCODE; + } + + if (component instanceof R3.Curve.Path.D2.Shape) { + return R3.COMPONENT_CURVE_PATH_D2_SHAPE; + } + + if (component instanceof R3.Curve.Path.D2) { + return R3.COMPONENT_CURVE_PATH_D2; + } + + if (component instanceof R3.Curve.Path) { + return R3.COMPONENT_CURVE_PATH; + } + + if (component instanceof R3.Curve) { + return R3.COMPONENT_CURVE; + } + + if (component instanceof R3.Controls.Touch) { + return R3.COMPONENT_CONTROLS_TOUCH; + } + + if (component instanceof R3.Controls.Mouse) { + return R3.COMPONENT_CONTROLS_MOUSE; + } + + if (component instanceof R3.Controls.Keyboard) { + return R3.COMPONENT_CONTROLS_KEYBOARD; + } + + if (component instanceof R3.Controls.D3.Orbit) { + return R3.COMPONENT_CONTROLS_D3_ORBIT; + } + + if (component instanceof R3.Controls.D3.FirstPerson) { + return R3.COMPONENT_CONTROLS_D3_FIRSTPERSON; + } + + if (component instanceof R3.Controls.D3) { + return R3.COMPONENT_CONTROLS_D3; + } + + if (component instanceof R3.Controls) { + return R3.COMPONENT_CONTROLS; + } + + if (component instanceof R3.Color) { + return R3.COMPONENT_COLOR; + } + + if (component instanceof R3.Clock) { + return R3.COMPONENT_CLOCK; + } + + if (component instanceof R3.Canvas) { + return R3.COMPONENT_CANVAS; + } + + if (component instanceof R3.Box3) { + return R3.COMPONENT_BOX3; + } + + if (component instanceof R3.API.Video) { + return R3.COMPONENT_VIDEO; + } + + if (component instanceof R3.API.Vector4) { + return R3.COMPONENT_VECTOR4; + } + + if (component instanceof R3.API.Vector3) { + return R3.COMPONENT_VECTOR3; + } + + if (component instanceof R3.API.Vector2) { + return R3.COMPONENT_VECTOR2; + } + + if (component instanceof R3.API.User) { + return R3.COMPONENT_USER; + } + + if (component instanceof R3.API.Stats) { + return R3.COMPONENT_STATS; + } + + if (component instanceof R3.API.Sphere) { + return R3.COMPONENT_SPHERE; + } + + if (component instanceof R3.API.Socket.Receive) { + return R3.COMPONENT_SOCKET_RECEIVE; + } + + if (component instanceof R3.API.Socket.Cast) { + return R3.COMPONENT_SOCKET_CAST; + } + + if (component instanceof R3.API.Socket) { + return R3.COMPONENT_SOCKET; + } + + if (component instanceof R3.API.Server) { + return R3.COMPONENT_SERVER; + } + + if (component instanceof R3.API.Scalar) { + return R3.COMPONENT_SCALAR; + } + + if (component instanceof R3.API.Renderer.D3.Canvas.Target) { + return R3.COMPONENT_RENDERER_D3_CANVAS_TARGET; + } + + if (component instanceof R3.API.Renderer.D3.Canvas) { + return R3.COMPONENT_RENDERER_D3_CANVAS; + } + + if (component instanceof R3.API.Renderer.D3) { + return R3.COMPONENT_RENDERER_D3; + } + + if (component instanceof R3.API.Renderer.D2) { + return R3.COMPONENT_RENDERER_D2; + } + + if (component instanceof R3.API.Renderer) { + return R3.COMPONENT_RENDERER; + } + + if (component instanceof R3.API.Query.Users) { + return R3.COMPONENT_QUERY_USERS; + } + + if (component instanceof R3.API.Query.UserDevices) { + return R3.COMPONENT_QUERY_USERDEVICES; + } + + if (component instanceof R3.API.Query.Logins.VPN) { + return R3.COMPONENT_QUERY_LOGINS_VPN; + } + + if (component instanceof R3.API.Query.Logins.Devices) { + return R3.COMPONENT_QUERY_LOGINS_DEVICES; + } + + if (component instanceof R3.API.Query.Logins.Applications) { + return R3.COMPONENT_QUERY_LOGINS_APPLICATIONS; + } + + if (component instanceof R3.API.Query.Logins) { + return R3.COMPONENT_QUERY_LOGINS; + } + + if (component instanceof R3.API.Query.Devices.Unknown) { + return R3.COMPONENT_QUERY_DEVICES_UNKNOWN; + } + + if (component instanceof R3.API.Query.Devices.SQL) { + return R3.COMPONENT_QUERY_DEVICES_SQL; + } + + if (component instanceof R3.API.Query.Devices.Known) { + return R3.COMPONENT_QUERY_DEVICES_KNOWN; + } + + if (component instanceof R3.API.Query.Devices) { + return R3.COMPONENT_QUERY_DEVICES; + } + + if (component instanceof R3.API.Query.Alerts.Timeseries) { + return R3.COMPONENT_QUERY_ALERTS_TIMESERIES; + } + + if (component instanceof R3.API.Query.Alerts.Summary) { + return R3.COMPONENT_QUERY_ALERTS_SUMMARY; + } + + if (component instanceof R3.API.Query.Alerts.List) { + return R3.COMPONENT_QUERY_ALERTS_LIST; + } + + if (component instanceof R3.API.Query.Alerts.FirstTimeLogin.VPN) { + return R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_VPN; + } + + if (component instanceof R3.API.Query.Alerts.FirstTimeLogin.Devices) { + return R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_DEVICES; + } + + if (component instanceof R3.API.Query.Alerts.FirstTimeLogin.Applications) { + return R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_APPLICATIONS; + } + + if (component instanceof R3.API.Query.Alerts.FirstTimeLogin) { + return R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN; + } + + if (component instanceof R3.API.Query.Alerts.Buckets) { + return R3.COMPONENT_QUERY_ALERTS_BUCKETS; + } + + if (component instanceof R3.API.Query.Alerts) { + return R3.COMPONENT_QUERY_ALERTS; + } + + if (component instanceof R3.API.Query) { + return R3.COMPONENT_QUERY; + } + + if (component instanceof R3.API.Quaternion.Points) { + return R3.COMPONENT_QUATERNION_POINTS; + } + + if (component instanceof R3.API.Quaternion) { + return R3.COMPONENT_QUATERNION; + } + + if (component instanceof R3.API.Project.D3.VR) { + return R3.COMPONENT_PROJECT_D3_VR; + } + + if (component instanceof R3.API.Project.D3) { + return R3.COMPONENT_PROJECT_D3; + } + + if (component instanceof R3.API.Project.D2) { + return R3.COMPONENT_PROJECT_D2; + } + + if (component instanceof R3.API.Project) { + return R3.COMPONENT_PROJECT; + } + + if (component instanceof R3.API.Plane) { + return R3.COMPONENT_PLANE; + } + + if (component instanceof R3.API.Mouse) { + return R3.COMPONENT_MOUSE; + } + + if (component instanceof R3.API.Matrix4) { + return R3.COMPONENT_MATRIX4; + } + + if (component instanceof R3.API.Image) { + return R3.COMPONENT_IMAGE; + } + + if (component instanceof R3.API.Group) { + return R3.COMPONENT_GROUP; + } + + if (component instanceof R3.API.Graph.Table) { + return R3.COMPONENT_GRAPH_TABLE; + } + + if (component instanceof R3.API.Graph.Metric) { + return R3.COMPONENT_GRAPH_METRIC; + } + + if (component instanceof R3.API.Graph.Barchart.Stacked) { + return R3.COMPONENT_GRAPH_BARCHART_STACKED; + } + + if (component instanceof R3.API.Graph.Barchart) { + return R3.COMPONENT_GRAPH_BARCHART; + } + + if (component instanceof R3.API.Graph) { + return R3.COMPONENT_GRAPH; + } + + if (component instanceof R3.API.Font) { + return R3.COMPONENT_FONT; + } + + if (component instanceof R3.API.Entity) { + return R3.COMPONENT_ENTITY; + } + + if (component instanceof R3.API.DrawRange) { + return R3.COMPONENT_DRAWRANGE; + } + + if (component instanceof R3.API.DomElement) { + return R3.COMPONENT_DOMELEMENT; + } + + if (component instanceof R3.API.CustomCode) { + return R3.COMPONENT_CUSTOMCODE; + } + + if (component instanceof R3.API.Curve.Path.D2.Shape) { + return R3.COMPONENT_CURVE_PATH_D2_SHAPE; + } + + if (component instanceof R3.API.Curve.Path.D2) { + return R3.COMPONENT_CURVE_PATH_D2; + } + + if (component instanceof R3.API.Curve.Path) { + return R3.COMPONENT_CURVE_PATH; + } + + if (component instanceof R3.API.Curve) { + return R3.COMPONENT_CURVE; + } + + if (component instanceof R3.API.Controls.Touch) { + return R3.COMPONENT_CONTROLS_TOUCH; + } + + if (component instanceof R3.API.Controls.Mouse) { + return R3.COMPONENT_CONTROLS_MOUSE; + } + + if (component instanceof R3.API.Controls.Keyboard) { + return R3.COMPONENT_CONTROLS_KEYBOARD; + } + + if (component instanceof R3.API.Controls.D3.Orbit) { + return R3.COMPONENT_CONTROLS_D3_ORBIT; + } + + if (component instanceof R3.API.Controls.D3.FirstPerson) { + return R3.COMPONENT_CONTROLS_D3_FIRSTPERSON; + } + + if (component instanceof R3.API.Controls.D3) { + return R3.COMPONENT_CONTROLS_D3; + } + + if (component instanceof R3.API.Controls) { + return R3.COMPONENT_CONTROLS; + } + + if (component instanceof R3.API.Color) { + return R3.COMPONENT_COLOR; + } + + if (component instanceof R3.API.Clock) { + return R3.COMPONENT_CLOCK; + } + + if (component instanceof R3.API.Canvas) { + return R3.COMPONENT_CANVAS; + } + + if (component instanceof R3.API.Box3) { + return R3.COMPONENT_BOX3; + } + +}; + +R3.GetComponentInfo = function(componentType) { + + switch (componentType) { + + case R3.COMPONENT_VIDEO : return { + name : 'R3.Video', + constructor : R3.Video, + apiConstructor : R3.API.Video, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_VECTOR4 : return { + name : 'R3.Vector4', + constructor : R3.Vector4, + apiConstructor : R3.API.Vector4, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_VECTOR3 : return { + name : 'R3.Vector3', + constructor : R3.Vector3, + apiConstructor : R3.API.Vector3, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_VECTOR2 : return { + name : 'R3.Vector2', + constructor : R3.Vector2, + apiConstructor : R3.API.Vector2, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_USER : return { + name : 'R3.User', + constructor : R3.User, + apiConstructor : R3.API.User, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_STATS : return { + name : 'R3.Stats', + constructor : R3.Stats, + apiConstructor : R3.API.Stats, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_SPHERE : return { + name : 'R3.Sphere', + constructor : R3.Sphere, + apiConstructor : R3.API.Sphere, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_SOCKET_RECEIVE : return { + name : 'R3.Socket.Receive', + constructor : R3.Socket.Receive, + apiConstructor : R3.API.Socket.Receive, + runtime: R3.Runtime.SOCKETS + }; + case R3.COMPONENT_SOCKET_CAST : return { + name : 'R3.Socket.Cast', + constructor : R3.Socket.Cast, + apiConstructor : R3.API.Socket.Cast, + runtime: R3.Runtime.SOCKETS + }; + case R3.COMPONENT_SOCKET : return { + name : 'R3.Socket', + constructor : R3.Socket, + apiConstructor : R3.API.Socket, + runtime: R3.Runtime.SOCKETS + }; + case R3.COMPONENT_SERVER : return { + name : 'R3.Server', + constructor : R3.Server, + apiConstructor : R3.API.Server, + runtime: R3.Runtime.SOCKETS + }; + case R3.COMPONENT_SCALAR : return { + name : 'R3.Scalar', + constructor : R3.Scalar, + apiConstructor : R3.API.Scalar, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_RENDERER_D3_CANVAS_TARGET : return { + name : 'R3.Renderer.D3.Canvas.Target', + constructor : R3.Renderer.D3.Canvas.Target, + apiConstructor : R3.API.Renderer.D3.Canvas.Target, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_RENDERER_D3_CANVAS : return { + name : 'R3.Renderer.D3.Canvas', + constructor : R3.Renderer.D3.Canvas, + apiConstructor : R3.API.Renderer.D3.Canvas, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_RENDERER_D3 : return { + name : 'R3.Renderer.D3', + constructor : R3.Renderer.D3, + apiConstructor : R3.API.Renderer.D3, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_RENDERER_D2 : return { + name : 'R3.Renderer.D2', + constructor : R3.Renderer.D2, + apiConstructor : R3.API.Renderer.D2, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_RENDERER : return { + name : 'R3.Renderer', + constructor : R3.Renderer, + apiConstructor : R3.API.Renderer, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_QUERY_USERS : return { + name : 'R3.Query.Users', + constructor : R3.Query.Users, + apiConstructor : R3.API.Query.Users, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_USERDEVICES : return { + name : 'R3.Query.UserDevices', + constructor : R3.Query.UserDevices, + apiConstructor : R3.API.Query.UserDevices, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_LOGINS_VPN : return { + name : 'R3.Query.Logins.VPN', + constructor : R3.Query.Logins.VPN, + apiConstructor : R3.API.Query.Logins.VPN, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_LOGINS_DEVICES : return { + name : 'R3.Query.Logins.Devices', + constructor : R3.Query.Logins.Devices, + apiConstructor : R3.API.Query.Logins.Devices, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_LOGINS_APPLICATIONS : return { + name : 'R3.Query.Logins.Applications', + constructor : R3.Query.Logins.Applications, + apiConstructor : R3.API.Query.Logins.Applications, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_LOGINS : return { + name : 'R3.Query.Logins', + constructor : R3.Query.Logins, + apiConstructor : R3.API.Query.Logins, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_DEVICES_UNKNOWN : return { + name : 'R3.Query.Devices.Unknown', + constructor : R3.Query.Devices.Unknown, + apiConstructor : R3.API.Query.Devices.Unknown, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_DEVICES_SQL : return { + name : 'R3.Query.Devices.SQL', + constructor : R3.Query.Devices.SQL, + apiConstructor : R3.API.Query.Devices.SQL, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_DEVICES_KNOWN : return { + name : 'R3.Query.Devices.Known', + constructor : R3.Query.Devices.Known, + apiConstructor : R3.API.Query.Devices.Known, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_DEVICES : return { + name : 'R3.Query.Devices', + constructor : R3.Query.Devices, + apiConstructor : R3.API.Query.Devices, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_ALERTS_TIMESERIES : return { + name : 'R3.Query.Alerts.Timeseries', + constructor : R3.Query.Alerts.Timeseries, + apiConstructor : R3.API.Query.Alerts.Timeseries, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_ALERTS_SUMMARY : return { + name : 'R3.Query.Alerts.Summary', + constructor : R3.Query.Alerts.Summary, + apiConstructor : R3.API.Query.Alerts.Summary, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_ALERTS_LIST : return { + name : 'R3.Query.Alerts.List', + constructor : R3.Query.Alerts.List, + apiConstructor : R3.API.Query.Alerts.List, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_VPN : return { + name : 'R3.Query.Alerts.FirstTimeLogin.VPN', + constructor : R3.Query.Alerts.FirstTimeLogin.VPN, + apiConstructor : R3.API.Query.Alerts.FirstTimeLogin.VPN, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_DEVICES : return { + name : 'R3.Query.Alerts.FirstTimeLogin.Devices', + constructor : R3.Query.Alerts.FirstTimeLogin.Devices, + apiConstructor : R3.API.Query.Alerts.FirstTimeLogin.Devices, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_APPLICATIONS : return { + name : 'R3.Query.Alerts.FirstTimeLogin.Applications', + constructor : R3.Query.Alerts.FirstTimeLogin.Applications, + apiConstructor : R3.API.Query.Alerts.FirstTimeLogin.Applications, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN : return { + name : 'R3.Query.Alerts.FirstTimeLogin', + constructor : R3.Query.Alerts.FirstTimeLogin, + apiConstructor : R3.API.Query.Alerts.FirstTimeLogin, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_ALERTS_BUCKETS : return { + name : 'R3.Query.Alerts.Buckets', + constructor : R3.Query.Alerts.Buckets, + apiConstructor : R3.API.Query.Alerts.Buckets, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY_ALERTS : return { + name : 'R3.Query.Alerts', + constructor : R3.Query.Alerts, + apiConstructor : R3.API.Query.Alerts, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUERY : return { + name : 'R3.Query', + constructor : R3.Query, + apiConstructor : R3.API.Query, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUATERNION_POINTS : return { + name : 'R3.Quaternion.Points', + constructor : R3.Quaternion.Points, + apiConstructor : R3.API.Quaternion.Points, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_QUATERNION : return { + name : 'R3.Quaternion', + constructor : R3.Quaternion, + apiConstructor : R3.API.Quaternion, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_PROJECT_D3_VR : return { + name : 'R3.Project.D3.VR', + constructor : R3.Project.D3.VR, + apiConstructor : R3.API.Project.D3.VR, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_PROJECT_D3 : return { + name : 'R3.Project.D3', + constructor : R3.Project.D3, + apiConstructor : R3.API.Project.D3, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_PROJECT_D2 : return { + name : 'R3.Project.D2', + constructor : R3.Project.D2, + apiConstructor : R3.API.Project.D2, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_PROJECT : return { + name : 'R3.Project', + constructor : R3.Project, + apiConstructor : R3.API.Project, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_PLANE : return { + name : 'R3.Plane', + constructor : R3.Plane, + apiConstructor : R3.API.Plane, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_MOUSE : return { + name : 'R3.Mouse', + constructor : R3.Mouse, + apiConstructor : R3.API.Mouse, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_MATRIX4 : return { + name : 'R3.Matrix4', + constructor : R3.Matrix4, + apiConstructor : R3.API.Matrix4, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_IMAGE : return { + name : 'R3.Image', + constructor : R3.Image, + apiConstructor : R3.API.Image, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_GROUP : return { + name : 'R3.Group', + constructor : R3.Group, + apiConstructor : R3.API.Group, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_GRAPH_TABLE : return { + name : 'R3.Graph.Table', + constructor : R3.Graph.Table, + apiConstructor : R3.API.Graph.Table, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_GRAPH_METRIC : return { + name : 'R3.Graph.Metric', + constructor : R3.Graph.Metric, + apiConstructor : R3.API.Graph.Metric, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_GRAPH_BARCHART_STACKED : return { + name : 'R3.Graph.Barchart.Stacked', + constructor : R3.Graph.Barchart.Stacked, + apiConstructor : R3.API.Graph.Barchart.Stacked, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_GRAPH_BARCHART : return { + name : 'R3.Graph.Barchart', + constructor : R3.Graph.Barchart, + apiConstructor : R3.API.Graph.Barchart, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_GRAPH : return { + name : 'R3.Graph', + constructor : R3.Graph, + apiConstructor : R3.API.Graph, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_FONT : return { + name : 'R3.Font', + constructor : R3.Font, + apiConstructor : R3.API.Font, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_ENTITY : return { + name : 'R3.Entity', + constructor : R3.Entity, + apiConstructor : R3.API.Entity, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_DRAWRANGE : return { + name : 'R3.DrawRange', + constructor : R3.DrawRange, + apiConstructor : R3.API.DrawRange, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_DOMELEMENT : return { + name : 'R3.DomElement', + constructor : R3.DomElement, + apiConstructor : R3.API.DomElement, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_D3_VIEWPORT_ZOOMEDASPECT : return { + name : 'R3.D3.Viewport.ZoomedAspect', + constructor : R3.D3.Viewport.ZoomedAspect, + apiConstructor : R3.D3.API.Viewport.ZoomedAspect, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_VIEWPORT_FIXEDASPECT_VR : return { + name : 'R3.D3.Viewport.FixedAspect.VR', + constructor : R3.D3.Viewport.FixedAspect.VR, + apiConstructor : R3.D3.API.Viewport.FixedAspect.VR, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_VIEWPORT_FIXEDASPECT : return { + name : 'R3.D3.Viewport.FixedAspect', + constructor : R3.D3.Viewport.FixedAspect, + apiConstructor : R3.D3.API.Viewport.FixedAspect, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_VIEWPORT : return { + name : 'R3.D3.Viewport', + constructor : R3.D3.Viewport, + apiConstructor : R3.D3.API.Viewport, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_VERTEX : return { + name : 'R3.D3.Vertex', + constructor : R3.D3.Vertex, + apiConstructor : R3.D3.API.Vertex, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_D3_TEXTURE_IMAGE : return { + name : 'R3.D3.Texture.Image', + constructor : R3.D3.Texture.Image, + apiConstructor : R3.D3.API.Texture.Image, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_TEXTURE_CUBE : return { + name : 'R3.D3.Texture.Cube', + constructor : R3.D3.Texture.Cube, + apiConstructor : R3.D3.API.Texture.Cube, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_TEXTURE_CANVAS : return { + name : 'R3.D3.Texture.Canvas', + constructor : R3.D3.Texture.Canvas, + apiConstructor : R3.D3.API.Texture.Canvas, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_TEXTURE : return { + name : 'R3.D3.Texture', + constructor : R3.D3.Texture, + apiConstructor : R3.D3.API.Texture, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_TEXT : return { + name : 'R3.D3.Text', + constructor : R3.D3.Text, + apiConstructor : R3.D3.API.Text, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_SPLINE : return { + name : 'R3.D3.Spline', + constructor : R3.D3.Spline, + apiConstructor : R3.D3.API.Spline, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_D3_SOLVER : return { + name : 'R3.D3.Solver', + constructor : R3.D3.Solver, + apiConstructor : R3.D3.API.Solver, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_SKELETON : return { + name : 'R3.D3.Skeleton', + constructor : R3.D3.Skeleton, + apiConstructor : R3.D3.API.Skeleton, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_SHAPE_TRIMESH : return { + name : 'R3.D3.Shape.TriMesh', + constructor : R3.D3.Shape.TriMesh, + apiConstructor : R3.D3.API.Shape.TriMesh, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_SHAPE_SPHERE : return { + name : 'R3.D3.Shape.Sphere', + constructor : R3.D3.Shape.Sphere, + apiConstructor : R3.D3.API.Shape.Sphere, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_SHAPE_PLANE : return { + name : 'R3.D3.Shape.Plane', + constructor : R3.D3.Shape.Plane, + apiConstructor : R3.D3.API.Shape.Plane, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_SHAPE_HEIGHTMAP : return { + name : 'R3.D3.Shape.HeightMap', + constructor : R3.D3.Shape.HeightMap, + apiConstructor : R3.D3.API.Shape.HeightMap, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_SHAPE_CONVEXHULL_CYLINDER : return { + name : 'R3.D3.Shape.ConvexHull.Cylinder', + constructor : R3.D3.Shape.ConvexHull.Cylinder, + apiConstructor : R3.D3.API.Shape.ConvexHull.Cylinder, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_SHAPE_CONVEXHULL : return { + name : 'R3.D3.Shape.ConvexHull', + constructor : R3.D3.Shape.ConvexHull, + apiConstructor : R3.D3.API.Shape.ConvexHull, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_SHAPE_BOX : return { + name : 'R3.D3.Shape.Box', + constructor : R3.D3.Shape.Box, + apiConstructor : R3.D3.API.Shape.Box, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_SHAPE : return { + name : 'R3.D3.Shape', + constructor : R3.D3.Shape, + apiConstructor : R3.D3.API.Shape, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_SHADOW_SPOT : return { + name : 'R3.D3.Shadow.Spot', + constructor : R3.D3.Shadow.Spot, + apiConstructor : R3.D3.API.Shadow.Spot, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_SHADOW_DIRECTIONAL : return { + name : 'R3.D3.Shadow.Directional', + constructor : R3.D3.Shadow.Directional, + apiConstructor : R3.D3.API.Shadow.Directional, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_SHADOW : return { + name : 'R3.D3.Shadow', + constructor : R3.D3.Shadow, + apiConstructor : R3.D3.API.Shadow, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_SHADER_VERTEX : return { + name : 'R3.D3.Shader.Vertex', + constructor : R3.D3.Shader.Vertex, + apiConstructor : R3.D3.API.Shader.Vertex, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_SHADER_FRAGMENT : return { + name : 'R3.D3.Shader.Fragment', + constructor : R3.D3.Shader.Fragment, + apiConstructor : R3.D3.API.Shader.Fragment, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_SHADER : return { + name : 'R3.D3.Shader', + constructor : R3.D3.Shader, + apiConstructor : R3.D3.API.Shader, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_SCENE : return { + name : 'R3.D3.Scene', + constructor : R3.D3.Scene, + apiConstructor : R3.D3.API.Scene, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_RIGIDBODY : return { + name : 'R3.D3.RigidBody', + constructor : R3.D3.RigidBody, + apiConstructor : R3.D3.API.RigidBody, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_RENDERTARGET_CUBE : return { + name : 'R3.D3.RenderTarget.Cube', + constructor : R3.D3.RenderTarget.Cube, + apiConstructor : R3.D3.API.RenderTarget.Cube, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_RENDERTARGET : return { + name : 'R3.D3.RenderTarget', + constructor : R3.D3.RenderTarget, + apiConstructor : R3.D3.API.RenderTarget, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_RAYCASTER : return { + name : 'R3.D3.Raycaster', + constructor : R3.D3.Raycaster, + apiConstructor : R3.D3.API.Raycaster, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_RAYCASTWHEEL : return { + name : 'R3.D3.RaycastWheel', + constructor : R3.D3.RaycastWheel, + apiConstructor : R3.D3.API.RaycastWheel, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_RAYCASTVEHICLE : return { + name : 'R3.D3.RaycastVehicle', + constructor : R3.D3.RaycastVehicle, + apiConstructor : R3.D3.API.RaycastVehicle, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_PHYSICSWORLD : return { + name : 'R3.D3.PhysicsWorld', + constructor : R3.D3.PhysicsWorld, + apiConstructor : R3.D3.API.PhysicsWorld, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_PASS_RENDER_SSAO : return { + name : 'R3.D3.Pass.Render.SSAO', + constructor : R3.D3.Pass.Render.SSAO, + apiConstructor : R3.D3.API.Pass.Render.SSAO, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_PASS_RENDER : return { + name : 'R3.D3.Pass.Render', + constructor : R3.D3.Pass.Render, + apiConstructor : R3.D3.API.Pass.Render, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_PASS_FXAA : return { + name : 'R3.D3.Pass.FXAA', + constructor : R3.D3.Pass.FXAA, + apiConstructor : R3.D3.API.Pass.FXAA, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_PASS_COPY : return { + name : 'R3.D3.Pass.Copy', + constructor : R3.D3.Pass.Copy, + apiConstructor : R3.D3.API.Pass.Copy, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_PASS_BLOOM : return { + name : 'R3.D3.Pass.Bloom', + constructor : R3.D3.Pass.Bloom, + apiConstructor : R3.D3.API.Pass.Bloom, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_PASS : return { + name : 'R3.D3.Pass', + constructor : R3.D3.Pass, + apiConstructor : R3.D3.API.Pass, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_MESH_SKELETON : return { + name : 'R3.D3.Mesh.Skeleton', + constructor : R3.D3.Mesh.Skeleton, + apiConstructor : R3.D3.API.Mesh.Skeleton, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_MESH_PARTICLE_ENGINE : return { + name : 'R3.D3.Mesh.Particle.Engine', + constructor : R3.D3.Mesh.Particle.Engine, + apiConstructor : R3.D3.API.Mesh.Particle.Engine, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_MESH_PARTICLE : return { + name : 'R3.D3.Mesh.Particle', + constructor : R3.D3.Mesh.Particle, + apiConstructor : R3.D3.API.Mesh.Particle, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_MESH : return { + name : 'R3.D3.Mesh', + constructor : R3.D3.Mesh, + apiConstructor : R3.D3.API.Mesh, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_MATERIAL_STANDARD : return { + name : 'R3.D3.Material.Standard', + constructor : R3.D3.Material.Standard, + apiConstructor : R3.D3.API.Material.Standard, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_MATERIAL_SHADER_RAW : return { + name : 'R3.D3.Material.Shader.Raw', + constructor : R3.D3.Material.Shader.Raw, + apiConstructor : R3.D3.API.Material.Shader.Raw, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_MATERIAL_SHADER : return { + name : 'R3.D3.Material.Shader', + constructor : R3.D3.Material.Shader, + apiConstructor : R3.D3.API.Material.Shader, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_MATERIAL_POINTS : return { + name : 'R3.D3.Material.Points', + constructor : R3.D3.Material.Points, + apiConstructor : R3.D3.API.Material.Points, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_MATERIAL_PHONG : return { + name : 'R3.D3.Material.Phong', + constructor : R3.D3.Material.Phong, + apiConstructor : R3.D3.API.Material.Phong, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_MATERIAL_BASIC : return { + name : 'R3.D3.Material.Basic', + constructor : R3.D3.Material.Basic, + apiConstructor : R3.D3.API.Material.Basic, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_MATERIAL : return { + name : 'R3.D3.Material', + constructor : R3.D3.Material, + apiConstructor : R3.D3.API.Material, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_LIGHT_SPOT : return { + name : 'R3.D3.Light.Spot', + constructor : R3.D3.Light.Spot, + apiConstructor : R3.D3.API.Light.Spot, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_LIGHT_RECTAREA : return { + name : 'R3.D3.Light.RectArea', + constructor : R3.D3.Light.RectArea, + apiConstructor : R3.D3.API.Light.RectArea, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_LIGHT_POINT : return { + name : 'R3.D3.Light.Point', + constructor : R3.D3.Light.Point, + apiConstructor : R3.D3.API.Light.Point, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_LIGHT_HEMISPHERE : return { + name : 'R3.D3.Light.Hemisphere', + constructor : R3.D3.Light.Hemisphere, + apiConstructor : R3.D3.API.Light.Hemisphere, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_LIGHT_DIRECTIONAL : return { + name : 'R3.D3.Light.Directional', + constructor : R3.D3.Light.Directional, + apiConstructor : R3.D3.API.Light.Directional, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_LIGHT_AMBIENT : return { + name : 'R3.D3.Light.Ambient', + constructor : R3.D3.Light.Ambient, + apiConstructor : R3.D3.API.Light.Ambient, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_LIGHT : return { + name : 'R3.D3.Light', + constructor : R3.D3.Light, + apiConstructor : R3.D3.API.Light, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_HELPER : return { + name : 'R3.D3.Helper', + constructor : R3.D3.Helper, + apiConstructor : R3.D3.API.Helper, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_WIREFRAME : return { + name : 'R3.D3.Geometry.Normal.Wireframe', + constructor : R3.D3.Geometry.Normal.Wireframe, + apiConstructor : R3.D3.API.Geometry.Normal.Wireframe, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_TUBE : return { + name : 'R3.D3.Geometry.Normal.Tube', + constructor : R3.D3.Geometry.Normal.Tube, + apiConstructor : R3.D3.API.Geometry.Normal.Tube, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_TORUSKNOT : return { + name : 'R3.D3.Geometry.Normal.TorusKnot', + constructor : R3.D3.Geometry.Normal.TorusKnot, + apiConstructor : R3.D3.API.Geometry.Normal.TorusKnot, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_TORUS : return { + name : 'R3.D3.Geometry.Normal.Torus', + constructor : R3.D3.Geometry.Normal.Torus, + apiConstructor : R3.D3.API.Geometry.Normal.Torus, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_TEXT : return { + name : 'R3.D3.Geometry.Normal.Text', + constructor : R3.D3.Geometry.Normal.Text, + apiConstructor : R3.D3.API.Geometry.Normal.Text, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_TETRAHEDRON : return { + name : 'R3.D3.Geometry.Normal.Tetrahedron', + constructor : R3.D3.Geometry.Normal.Tetrahedron, + apiConstructor : R3.D3.API.Geometry.Normal.Tetrahedron, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_SPHERE : return { + name : 'R3.D3.Geometry.Normal.Sphere', + constructor : R3.D3.Geometry.Normal.Sphere, + apiConstructor : R3.D3.API.Geometry.Normal.Sphere, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_SHAPE : return { + name : 'R3.D3.Geometry.Normal.Shape', + constructor : R3.D3.Geometry.Normal.Shape, + apiConstructor : R3.D3.API.Geometry.Normal.Shape, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_RING : return { + name : 'R3.D3.Geometry.Normal.Ring', + constructor : R3.D3.Geometry.Normal.Ring, + apiConstructor : R3.D3.API.Geometry.Normal.Ring, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_POLYHEDRON : return { + name : 'R3.D3.Geometry.Normal.Polyhedron', + constructor : R3.D3.Geometry.Normal.Polyhedron, + apiConstructor : R3.D3.API.Geometry.Normal.Polyhedron, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_PLANE : return { + name : 'R3.D3.Geometry.Normal.Plane', + constructor : R3.D3.Geometry.Normal.Plane, + apiConstructor : R3.D3.API.Geometry.Normal.Plane, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_PARAMETRIC : return { + name : 'R3.D3.Geometry.Normal.Parametric', + constructor : R3.D3.Geometry.Normal.Parametric, + apiConstructor : R3.D3.API.Geometry.Normal.Parametric, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_OCTAHEDRON : return { + name : 'R3.D3.Geometry.Normal.Octahedron', + constructor : R3.D3.Geometry.Normal.Octahedron, + apiConstructor : R3.D3.API.Geometry.Normal.Octahedron, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_LATHE : return { + name : 'R3.D3.Geometry.Normal.Lathe', + constructor : R3.D3.Geometry.Normal.Lathe, + apiConstructor : R3.D3.API.Geometry.Normal.Lathe, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_ICOSAHEDRON : return { + name : 'R3.D3.Geometry.Normal.Icosahedron', + constructor : R3.D3.Geometry.Normal.Icosahedron, + apiConstructor : R3.D3.API.Geometry.Normal.Icosahedron, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_EXTRUDE : return { + name : 'R3.D3.Geometry.Normal.Extrude', + constructor : R3.D3.Geometry.Normal.Extrude, + apiConstructor : R3.D3.API.Geometry.Normal.Extrude, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_EDGES : return { + name : 'R3.D3.Geometry.Normal.Edges', + constructor : R3.D3.Geometry.Normal.Edges, + apiConstructor : R3.D3.API.Geometry.Normal.Edges, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_DODECAHEDRON : return { + name : 'R3.D3.Geometry.Normal.Dodecahedron', + constructor : R3.D3.Geometry.Normal.Dodecahedron, + apiConstructor : R3.D3.API.Geometry.Normal.Dodecahedron, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_CYLINDER : return { + name : 'R3.D3.Geometry.Normal.Cylinder', + constructor : R3.D3.Geometry.Normal.Cylinder, + apiConstructor : R3.D3.API.Geometry.Normal.Cylinder, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_CONE : return { + name : 'R3.D3.Geometry.Normal.Cone', + constructor : R3.D3.Geometry.Normal.Cone, + apiConstructor : R3.D3.API.Geometry.Normal.Cone, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_CIRCLE : return { + name : 'R3.D3.Geometry.Normal.Circle', + constructor : R3.D3.Geometry.Normal.Circle, + apiConstructor : R3.D3.API.Geometry.Normal.Circle, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_BOX : return { + name : 'R3.D3.Geometry.Normal.Box', + constructor : R3.D3.Geometry.Normal.Box, + apiConstructor : R3.D3.API.Geometry.Normal.Box, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_NORMAL : return { + name : 'R3.D3.Geometry.Normal', + constructor : R3.D3.Geometry.Normal, + apiConstructor : R3.D3.API.Geometry.Normal, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_TUBE : return { + name : 'R3.D3.Geometry.Buffer.Tube', + constructor : R3.D3.Geometry.Buffer.Tube, + apiConstructor : R3.D3.API.Geometry.Buffer.Tube, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_TORUSKNOT : return { + name : 'R3.D3.Geometry.Buffer.TorusKnot', + constructor : R3.D3.Geometry.Buffer.TorusKnot, + apiConstructor : R3.D3.API.Geometry.Buffer.TorusKnot, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_TORUS : return { + name : 'R3.D3.Geometry.Buffer.Torus', + constructor : R3.D3.Geometry.Buffer.Torus, + apiConstructor : R3.D3.API.Geometry.Buffer.Torus, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_TEXT : return { + name : 'R3.D3.Geometry.Buffer.Text', + constructor : R3.D3.Geometry.Buffer.Text, + apiConstructor : R3.D3.API.Geometry.Buffer.Text, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_TETRAHEDRON : return { + name : 'R3.D3.Geometry.Buffer.Tetrahedron', + constructor : R3.D3.Geometry.Buffer.Tetrahedron, + apiConstructor : R3.D3.API.Geometry.Buffer.Tetrahedron, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_SPHERE : return { + name : 'R3.D3.Geometry.Buffer.Sphere', + constructor : R3.D3.Geometry.Buffer.Sphere, + apiConstructor : R3.D3.API.Geometry.Buffer.Sphere, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_SHAPE : return { + name : 'R3.D3.Geometry.Buffer.Shape', + constructor : R3.D3.Geometry.Buffer.Shape, + apiConstructor : R3.D3.API.Geometry.Buffer.Shape, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_RING : return { + name : 'R3.D3.Geometry.Buffer.Ring', + constructor : R3.D3.Geometry.Buffer.Ring, + apiConstructor : R3.D3.API.Geometry.Buffer.Ring, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_POLYHEDRON : return { + name : 'R3.D3.Geometry.Buffer.Polyhedron', + constructor : R3.D3.Geometry.Buffer.Polyhedron, + apiConstructor : R3.D3.API.Geometry.Buffer.Polyhedron, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_PLANE : return { + name : 'R3.D3.Geometry.Buffer.Plane', + constructor : R3.D3.Geometry.Buffer.Plane, + apiConstructor : R3.D3.API.Geometry.Buffer.Plane, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_PARAMETRIC : return { + name : 'R3.D3.Geometry.Buffer.Parametric', + constructor : R3.D3.Geometry.Buffer.Parametric, + apiConstructor : R3.D3.API.Geometry.Buffer.Parametric, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_OCTAHEDRON : return { + name : 'R3.D3.Geometry.Buffer.Octahedron', + constructor : R3.D3.Geometry.Buffer.Octahedron, + apiConstructor : R3.D3.API.Geometry.Buffer.Octahedron, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_LATHE : return { + name : 'R3.D3.Geometry.Buffer.Lathe', + constructor : R3.D3.Geometry.Buffer.Lathe, + apiConstructor : R3.D3.API.Geometry.Buffer.Lathe, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_INSTANCED : return { + name : 'R3.D3.Geometry.Buffer.Instanced', + constructor : R3.D3.Geometry.Buffer.Instanced, + apiConstructor : R3.D3.API.Geometry.Buffer.Instanced, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_ICOSAHEDRON : return { + name : 'R3.D3.Geometry.Buffer.Icosahedron', + constructor : R3.D3.Geometry.Buffer.Icosahedron, + apiConstructor : R3.D3.API.Geometry.Buffer.Icosahedron, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_EXTRUDE : return { + name : 'R3.D3.Geometry.Buffer.Extrude', + constructor : R3.D3.Geometry.Buffer.Extrude, + apiConstructor : R3.D3.API.Geometry.Buffer.Extrude, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_DODECAHEDRON : return { + name : 'R3.D3.Geometry.Buffer.Dodecahedron', + constructor : R3.D3.Geometry.Buffer.Dodecahedron, + apiConstructor : R3.D3.API.Geometry.Buffer.Dodecahedron, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_CYLINDER : return { + name : 'R3.D3.Geometry.Buffer.Cylinder', + constructor : R3.D3.Geometry.Buffer.Cylinder, + apiConstructor : R3.D3.API.Geometry.Buffer.Cylinder, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_CONE : return { + name : 'R3.D3.Geometry.Buffer.Cone', + constructor : R3.D3.Geometry.Buffer.Cone, + apiConstructor : R3.D3.API.Geometry.Buffer.Cone, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_CIRCLE : return { + name : 'R3.D3.Geometry.Buffer.Circle', + constructor : R3.D3.Geometry.Buffer.Circle, + apiConstructor : R3.D3.API.Geometry.Buffer.Circle, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_BOX : return { + name : 'R3.D3.Geometry.Buffer.Box', + constructor : R3.D3.Geometry.Buffer.Box, + apiConstructor : R3.D3.API.Geometry.Buffer.Box, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY_BUFFER : return { + name : 'R3.D3.Geometry.Buffer', + constructor : R3.D3.Geometry.Buffer, + apiConstructor : R3.D3.API.Geometry.Buffer, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_GEOMETRY : return { + name : 'R3.D3.Geometry', + constructor : R3.D3.Geometry, + apiConstructor : R3.D3.API.Geometry, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_FRICTIONMATERIAL : return { + name : 'R3.D3.FrictionMaterial', + constructor : R3.D3.FrictionMaterial, + apiConstructor : R3.D3.API.FrictionMaterial, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_FRICTIONCONTACTMATERIAL : return { + name : 'R3.D3.FrictionContactMaterial', + constructor : R3.D3.FrictionContactMaterial, + apiConstructor : R3.D3.API.FrictionContactMaterial, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_FOG_NORMAL : return { + name : 'R3.D3.Fog.Normal', + constructor : R3.D3.Fog.Normal, + apiConstructor : R3.D3.API.Fog.Normal, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_FOG_EXP : return { + name : 'R3.D3.Fog.Exp', + constructor : R3.D3.Fog.Exp, + apiConstructor : R3.D3.API.Fog.Exp, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_FOG : return { + name : 'R3.D3.Fog', + constructor : R3.D3.Fog, + apiConstructor : R3.D3.API.Fog, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_FACE_GRAPHICS : return { + name : 'R3.D3.Face.Graphics', + constructor : R3.D3.Face.Graphics, + apiConstructor : R3.D3.API.Face.Graphics, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_FACE : return { + name : 'R3.D3.Face', + constructor : R3.D3.Face, + apiConstructor : R3.D3.API.Face, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_D3_EFFECT_STEREO : return { + name : 'R3.D3.Effect.Stereo', + constructor : R3.D3.Effect.Stereo, + apiConstructor : R3.D3.API.Effect.Stereo, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_EFFECT_PARALLAX : return { + name : 'R3.D3.Effect.Parallax', + constructor : R3.D3.Effect.Parallax, + apiConstructor : R3.D3.API.Effect.Parallax, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_EFFECT_ANAGLYPH : return { + name : 'R3.D3.Effect.Anaglyph', + constructor : R3.D3.Effect.Anaglyph, + apiConstructor : R3.D3.API.Effect.Anaglyph, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_EFFECT : return { + name : 'R3.D3.Effect', + constructor : R3.D3.Effect, + apiConstructor : R3.D3.API.Effect, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_COMPOSER : return { + name : 'R3.D3.Composer', + constructor : R3.D3.Composer, + apiConstructor : R3.D3.API.Composer, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_CAMERA_PERSPECTIVE_STEREO : return { + name : 'R3.D3.Camera.Perspective.Stereo', + constructor : R3.D3.Camera.Perspective.Stereo, + apiConstructor : R3.D3.API.Camera.Perspective.Stereo, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_CAMERA_PERSPECTIVE : return { + name : 'R3.D3.Camera.Perspective', + constructor : R3.D3.Camera.Perspective, + apiConstructor : R3.D3.API.Camera.Perspective, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC_SCALEDASPECT : return { + name : 'R3.D3.Camera.Orthographic.ScaledAspect', + constructor : R3.D3.Camera.Orthographic.ScaledAspect, + apiConstructor : R3.D3.API.Camera.Orthographic.ScaledAspect, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC_FIXEDASPECT : return { + name : 'R3.D3.Camera.Orthographic.FixedAspect', + constructor : R3.D3.Camera.Orthographic.FixedAspect, + apiConstructor : R3.D3.API.Camera.Orthographic.FixedAspect, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC : return { + name : 'R3.D3.Camera.Orthographic', + constructor : R3.D3.Camera.Orthographic, + apiConstructor : R3.D3.API.Camera.Orthographic, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_CAMERA_CUBE : return { + name : 'R3.D3.Camera.Cube', + constructor : R3.D3.Camera.Cube, + apiConstructor : R3.D3.API.Camera.Cube, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_CAMERA : return { + name : 'R3.D3.Camera', + constructor : R3.D3.Camera, + apiConstructor : R3.D3.API.Camera, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_BROADPHASE : return { + name : 'R3.D3.Broadphase', + constructor : R3.D3.Broadphase, + apiConstructor : R3.D3.API.Broadphase, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_D3_BONEWEIGHT : return { + name : 'R3.D3.BoneWeight', + constructor : R3.D3.BoneWeight, + apiConstructor : R3.D3.API.BoneWeight, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_BONE : return { + name : 'R3.D3.Bone', + constructor : R3.D3.Bone, + apiConstructor : R3.D3.API.Bone, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_D3_AUDIO : return { + name : 'R3.D3.Audio', + constructor : R3.D3.Audio, + apiConstructor : R3.D3.API.Audio, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_D3_ANIMATION : return { + name : 'R3.D3.Animation', + constructor : R3.D3.Animation, + apiConstructor : R3.D3.API.Animation, + runtime: R3.Runtime.DEFAULT + }; + case R3.COMPONENT_D3_OBJECT : return { + name : 'R3.D3.Object', + constructor : R3.D3.Object, + apiConstructor : R3.D3.API.Object, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_CUSTOMCODE : return { + name : 'R3.CustomCode', + constructor : R3.CustomCode, + apiConstructor : R3.API.CustomCode, + runtime: R3.Runtime.CODER + }; + case R3.COMPONENT_CURVE_PATH_D2_SHAPE : return { + name : 'R3.Curve.Path.D2.Shape', + constructor : R3.Curve.Path.D2.Shape, + apiConstructor : R3.API.Curve.Path.D2.Shape, + runtime: R3.Runtime.PHYSICS + }; + case R3.COMPONENT_CURVE_PATH_D2 : return { + name : 'R3.Curve.Path.D2', + constructor : R3.Curve.Path.D2, + apiConstructor : R3.API.Curve.Path.D2, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_CURVE_PATH : return { + name : 'R3.Curve.Path', + constructor : R3.Curve.Path, + apiConstructor : R3.API.Curve.Path, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_CURVE : return { + name : 'R3.Curve', + constructor : R3.Curve, + apiConstructor : R3.API.Curve, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_CONTROLS_TOUCH : return { + name : 'R3.Controls.Touch', + constructor : R3.Controls.Touch, + apiConstructor : R3.API.Controls.Touch, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_CONTROLS_MOUSE : return { + name : 'R3.Controls.Mouse', + constructor : R3.Controls.Mouse, + apiConstructor : R3.API.Controls.Mouse, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_CONTROLS_KEYBOARD : return { + name : 'R3.Controls.Keyboard', + constructor : R3.Controls.Keyboard, + apiConstructor : R3.API.Controls.Keyboard, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_CONTROLS_D3_ORBIT : return { + name : 'R3.Controls.D3.Orbit', + constructor : R3.Controls.D3.Orbit, + apiConstructor : R3.API.Controls.D3.Orbit, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_CONTROLS_D3_FIRSTPERSON : return { + name : 'R3.Controls.D3.FirstPerson', + constructor : R3.Controls.D3.FirstPerson, + apiConstructor : R3.API.Controls.D3.FirstPerson, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_CONTROLS_D3 : return { + name : 'R3.Controls.D3', + constructor : R3.Controls.D3, + apiConstructor : R3.API.Controls.D3, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_CONTROLS : return { + name : 'R3.Controls', + constructor : R3.Controls, + apiConstructor : R3.API.Controls, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_COLOR : return { + name : 'R3.Color', + constructor : R3.Color, + apiConstructor : R3.API.Color, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_CLOCK : return { + name : 'R3.Clock', + constructor : R3.Clock, + apiConstructor : R3.API.Clock, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_CANVAS : return { + name : 'R3.Canvas', + constructor : R3.Canvas, + apiConstructor : R3.API.Canvas, + runtime: R3.Runtime.GRAPHICS + }; + case R3.COMPONENT_BOX3 : return { + name : 'R3.Box3', + constructor : R3.Box3, + apiConstructor : R3.API.Box3, + runtime: R3.Runtime.GRAPHICS + }; + default : + throw new Error('Invalid component type: ' + componentType); + + } +}; + +/** + * R3.GetAPIConstructor + * @param runtimeComponent + * @returns constructor + */ +R3.GetAPIConstructor = function(runtimeComponent) { + + if (runtimeComponent instanceof R3.Video){ + return R3.API.Video; + } + if (runtimeComponent instanceof R3.Vector4){ + return R3.API.Vector4; + } + if (runtimeComponent instanceof R3.Vector3){ + return R3.API.Vector3; + } + if (runtimeComponent instanceof R3.Vector2){ + return R3.API.Vector2; + } + if (runtimeComponent instanceof R3.User){ + return R3.API.User; + } + if (runtimeComponent instanceof R3.Stats){ + return R3.API.Stats; + } + if (runtimeComponent instanceof R3.Sphere){ + return R3.API.Sphere; + } + if (runtimeComponent instanceof R3.Socket.Receive){ + return R3.API.Socket.Receive; + } + if (runtimeComponent instanceof R3.Socket.Cast){ + return R3.API.Socket.Cast; + } + if (runtimeComponent instanceof R3.Socket){ + return R3.API.Socket; + } + if (runtimeComponent instanceof R3.Server){ + return R3.API.Server; + } + if (runtimeComponent instanceof R3.Scalar){ + return R3.API.Scalar; + } + if (runtimeComponent instanceof R3.Renderer.D3.Canvas.Target){ + return R3.API.Renderer.D3.Canvas.Target; + } + if (runtimeComponent instanceof R3.Renderer.D3.Canvas){ + return R3.API.Renderer.D3.Canvas; + } + if (runtimeComponent instanceof R3.Renderer.D3){ + return R3.API.Renderer.D3; + } + if (runtimeComponent instanceof R3.Renderer.D2){ + return R3.API.Renderer.D2; + } + if (runtimeComponent instanceof R3.Renderer){ + return R3.API.Renderer; + } + if (runtimeComponent instanceof R3.Query.Users){ + return R3.API.Query.Users; + } + if (runtimeComponent instanceof R3.Query.UserDevices){ + return R3.API.Query.UserDevices; + } + if (runtimeComponent instanceof R3.Query.Logins.VPN){ + return R3.API.Query.Logins.VPN; + } + if (runtimeComponent instanceof R3.Query.Logins.Devices){ + return R3.API.Query.Logins.Devices; + } + if (runtimeComponent instanceof R3.Query.Logins.Applications){ + return R3.API.Query.Logins.Applications; + } + if (runtimeComponent instanceof R3.Query.Logins){ + return R3.API.Query.Logins; + } + if (runtimeComponent instanceof R3.Query.Devices.Unknown){ + return R3.API.Query.Devices.Unknown; + } + if (runtimeComponent instanceof R3.Query.Devices.SQL){ + return R3.API.Query.Devices.SQL; + } + if (runtimeComponent instanceof R3.Query.Devices.Known){ + return R3.API.Query.Devices.Known; + } + if (runtimeComponent instanceof R3.Query.Devices){ + return R3.API.Query.Devices; + } + if (runtimeComponent instanceof R3.Query.Alerts.Timeseries){ + return R3.API.Query.Alerts.Timeseries; + } + if (runtimeComponent instanceof R3.Query.Alerts.Summary){ + return R3.API.Query.Alerts.Summary; + } + if (runtimeComponent instanceof R3.Query.Alerts.List){ + return R3.API.Query.Alerts.List; + } + if (runtimeComponent instanceof R3.Query.Alerts.FirstTimeLogin.VPN){ + return R3.API.Query.Alerts.FirstTimeLogin.VPN; + } + if (runtimeComponent instanceof R3.Query.Alerts.FirstTimeLogin.Devices){ + return R3.API.Query.Alerts.FirstTimeLogin.Devices; + } + if (runtimeComponent instanceof R3.Query.Alerts.FirstTimeLogin.Applications){ + return R3.API.Query.Alerts.FirstTimeLogin.Applications; + } + if (runtimeComponent instanceof R3.Query.Alerts.FirstTimeLogin){ + return R3.API.Query.Alerts.FirstTimeLogin; + } + if (runtimeComponent instanceof R3.Query.Alerts.Buckets){ + return R3.API.Query.Alerts.Buckets; + } + if (runtimeComponent instanceof R3.Query.Alerts){ + return R3.API.Query.Alerts; + } + if (runtimeComponent instanceof R3.Query){ + return R3.API.Query; + } + if (runtimeComponent instanceof R3.Quaternion.Points){ + return R3.API.Quaternion.Points; + } + if (runtimeComponent instanceof R3.Quaternion){ + return R3.API.Quaternion; + } + if (runtimeComponent instanceof R3.Project.D3.VR){ + return R3.API.Project.D3.VR; + } + if (runtimeComponent instanceof R3.Project.D3){ + return R3.API.Project.D3; + } + if (runtimeComponent instanceof R3.Project.D2){ + return R3.API.Project.D2; + } + if (runtimeComponent instanceof R3.Project){ + return R3.API.Project; + } + if (runtimeComponent instanceof R3.Plane){ + return R3.API.Plane; + } + if (runtimeComponent instanceof R3.Mouse){ + return R3.API.Mouse; + } + if (runtimeComponent instanceof R3.Matrix4){ + return R3.API.Matrix4; + } + if (runtimeComponent instanceof R3.Image){ + return R3.API.Image; + } + if (runtimeComponent instanceof R3.Group){ + return R3.API.Group; + } + if (runtimeComponent instanceof R3.Graph.Table){ + return R3.API.Graph.Table; + } + if (runtimeComponent instanceof R3.Graph.Metric){ + return R3.API.Graph.Metric; + } + if (runtimeComponent instanceof R3.Graph.Barchart.Stacked){ + return R3.API.Graph.Barchart.Stacked; + } + if (runtimeComponent instanceof R3.Graph.Barchart){ + return R3.API.Graph.Barchart; + } + if (runtimeComponent instanceof R3.Graph){ + return R3.API.Graph; + } + if (runtimeComponent instanceof R3.Font){ + return R3.API.Font; + } + if (runtimeComponent instanceof R3.Entity){ + return R3.API.Entity; + } + if (runtimeComponent instanceof R3.DrawRange){ + return R3.API.DrawRange; + } + if (runtimeComponent instanceof R3.DomElement){ + return R3.API.DomElement; + } + if (runtimeComponent instanceof R3.D3.Viewport.ZoomedAspect){ + return R3.D3.API.Viewport.ZoomedAspect; + } + if (runtimeComponent instanceof R3.D3.Viewport.FixedAspect.VR){ + return R3.D3.API.Viewport.FixedAspect.VR; + } + if (runtimeComponent instanceof R3.D3.Viewport.FixedAspect){ + return R3.D3.API.Viewport.FixedAspect; + } + if (runtimeComponent instanceof R3.D3.Viewport){ + return R3.D3.API.Viewport; + } + if (runtimeComponent instanceof R3.D3.Vertex){ + return R3.D3.API.Vertex; + } + if (runtimeComponent instanceof R3.D3.Texture.Image){ + return R3.D3.API.Texture.Image; + } + if (runtimeComponent instanceof R3.D3.Texture.Cube){ + return R3.D3.API.Texture.Cube; + } + if (runtimeComponent instanceof R3.D3.Texture.Canvas){ + return R3.D3.API.Texture.Canvas; + } + if (runtimeComponent instanceof R3.D3.Texture){ + return R3.D3.API.Texture; + } + if (runtimeComponent instanceof R3.D3.Text){ + return R3.D3.API.Text; + } + if (runtimeComponent instanceof R3.D3.Spline){ + return R3.D3.API.Spline; + } + if (runtimeComponent instanceof R3.D3.Solver){ + return R3.D3.API.Solver; + } + if (runtimeComponent instanceof R3.D3.Skeleton){ + return R3.D3.API.Skeleton; + } + if (runtimeComponent instanceof R3.D3.Shape.TriMesh){ + return R3.D3.API.Shape.TriMesh; + } + if (runtimeComponent instanceof R3.D3.Shape.Sphere){ + return R3.D3.API.Shape.Sphere; + } + if (runtimeComponent instanceof R3.D3.Shape.Plane){ + return R3.D3.API.Shape.Plane; + } + if (runtimeComponent instanceof R3.D3.Shape.HeightMap){ + return R3.D3.API.Shape.HeightMap; + } + if (runtimeComponent instanceof R3.D3.Shape.ConvexHull.Cylinder){ + return R3.D3.API.Shape.ConvexHull.Cylinder; + } + if (runtimeComponent instanceof R3.D3.Shape.ConvexHull){ + return R3.D3.API.Shape.ConvexHull; + } + if (runtimeComponent instanceof R3.D3.Shape.Box){ + return R3.D3.API.Shape.Box; + } + if (runtimeComponent instanceof R3.D3.Shape){ + return R3.D3.API.Shape; + } + if (runtimeComponent instanceof R3.D3.Shadow.Spot){ + return R3.D3.API.Shadow.Spot; + } + if (runtimeComponent instanceof R3.D3.Shadow.Directional){ + return R3.D3.API.Shadow.Directional; + } + if (runtimeComponent instanceof R3.D3.Shadow){ + return R3.D3.API.Shadow; + } + if (runtimeComponent instanceof R3.D3.Shader.Vertex){ + return R3.D3.API.Shader.Vertex; + } + if (runtimeComponent instanceof R3.D3.Shader.Fragment){ + return R3.D3.API.Shader.Fragment; + } + if (runtimeComponent instanceof R3.D3.Shader){ + return R3.D3.API.Shader; + } + if (runtimeComponent instanceof R3.D3.Scene){ + return R3.D3.API.Scene; + } + if (runtimeComponent instanceof R3.D3.RigidBody){ + return R3.D3.API.RigidBody; + } + if (runtimeComponent instanceof R3.D3.RenderTarget.Cube){ + return R3.D3.API.RenderTarget.Cube; + } + if (runtimeComponent instanceof R3.D3.RenderTarget){ + return R3.D3.API.RenderTarget; + } + if (runtimeComponent instanceof R3.D3.Raycaster){ + return R3.D3.API.Raycaster; + } + if (runtimeComponent instanceof R3.D3.RaycastWheel){ + return R3.D3.API.RaycastWheel; + } + if (runtimeComponent instanceof R3.D3.RaycastVehicle){ + return R3.D3.API.RaycastVehicle; + } + if (runtimeComponent instanceof R3.D3.PhysicsWorld){ + return R3.D3.API.PhysicsWorld; + } + if (runtimeComponent instanceof R3.D3.Pass.Render.SSAO){ + return R3.D3.API.Pass.Render.SSAO; + } + if (runtimeComponent instanceof R3.D3.Pass.Render){ + return R3.D3.API.Pass.Render; + } + if (runtimeComponent instanceof R3.D3.Pass.FXAA){ + return R3.D3.API.Pass.FXAA; + } + if (runtimeComponent instanceof R3.D3.Pass.Copy){ + return R3.D3.API.Pass.Copy; + } + if (runtimeComponent instanceof R3.D3.Pass.Bloom){ + return R3.D3.API.Pass.Bloom; + } + if (runtimeComponent instanceof R3.D3.Pass){ + return R3.D3.API.Pass; + } + if (runtimeComponent instanceof R3.D3.Mesh.Skeleton){ + return R3.D3.API.Mesh.Skeleton; + } + if (runtimeComponent instanceof R3.D3.Mesh.Particle.Engine){ + return R3.D3.API.Mesh.Particle.Engine; + } + if (runtimeComponent instanceof R3.D3.Mesh.Particle){ + return R3.D3.API.Mesh.Particle; + } + if (runtimeComponent instanceof R3.D3.Mesh){ + return R3.D3.API.Mesh; + } + if (runtimeComponent instanceof R3.D3.Material.Standard){ + return R3.D3.API.Material.Standard; + } + if (runtimeComponent instanceof R3.D3.Material.Shader.Raw){ + return R3.D3.API.Material.Shader.Raw; + } + if (runtimeComponent instanceof R3.D3.Material.Shader){ + return R3.D3.API.Material.Shader; + } + if (runtimeComponent instanceof R3.D3.Material.Points){ + return R3.D3.API.Material.Points; + } + if (runtimeComponent instanceof R3.D3.Material.Phong){ + return R3.D3.API.Material.Phong; + } + if (runtimeComponent instanceof R3.D3.Material.Basic){ + return R3.D3.API.Material.Basic; + } + if (runtimeComponent instanceof R3.D3.Material){ + return R3.D3.API.Material; + } + if (runtimeComponent instanceof R3.D3.Light.Spot){ + return R3.D3.API.Light.Spot; + } + if (runtimeComponent instanceof R3.D3.Light.RectArea){ + return R3.D3.API.Light.RectArea; + } + if (runtimeComponent instanceof R3.D3.Light.Point){ + return R3.D3.API.Light.Point; + } + if (runtimeComponent instanceof R3.D3.Light.Hemisphere){ + return R3.D3.API.Light.Hemisphere; + } + if (runtimeComponent instanceof R3.D3.Light.Directional){ + return R3.D3.API.Light.Directional; + } + if (runtimeComponent instanceof R3.D3.Light.Ambient){ + return R3.D3.API.Light.Ambient; + } + if (runtimeComponent instanceof R3.D3.Light){ + return R3.D3.API.Light; + } + if (runtimeComponent instanceof R3.D3.Helper){ + return R3.D3.API.Helper; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Wireframe){ + return R3.D3.API.Geometry.Normal.Wireframe; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Tube){ + return R3.D3.API.Geometry.Normal.Tube; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.TorusKnot){ + return R3.D3.API.Geometry.Normal.TorusKnot; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Torus){ + return R3.D3.API.Geometry.Normal.Torus; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Text){ + return R3.D3.API.Geometry.Normal.Text; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Tetrahedron){ + return R3.D3.API.Geometry.Normal.Tetrahedron; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Sphere){ + return R3.D3.API.Geometry.Normal.Sphere; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Shape){ + return R3.D3.API.Geometry.Normal.Shape; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Ring){ + return R3.D3.API.Geometry.Normal.Ring; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Polyhedron){ + return R3.D3.API.Geometry.Normal.Polyhedron; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Plane){ + return R3.D3.API.Geometry.Normal.Plane; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Parametric){ + return R3.D3.API.Geometry.Normal.Parametric; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Octahedron){ + return R3.D3.API.Geometry.Normal.Octahedron; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Lathe){ + return R3.D3.API.Geometry.Normal.Lathe; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Icosahedron){ + return R3.D3.API.Geometry.Normal.Icosahedron; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Extrude){ + return R3.D3.API.Geometry.Normal.Extrude; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Edges){ + return R3.D3.API.Geometry.Normal.Edges; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Dodecahedron){ + return R3.D3.API.Geometry.Normal.Dodecahedron; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Cylinder){ + return R3.D3.API.Geometry.Normal.Cylinder; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Cone){ + return R3.D3.API.Geometry.Normal.Cone; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Circle){ + return R3.D3.API.Geometry.Normal.Circle; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Box){ + return R3.D3.API.Geometry.Normal.Box; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal){ + return R3.D3.API.Geometry.Normal; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Tube){ + return R3.D3.API.Geometry.Buffer.Tube; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.TorusKnot){ + return R3.D3.API.Geometry.Buffer.TorusKnot; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Torus){ + return R3.D3.API.Geometry.Buffer.Torus; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Text){ + return R3.D3.API.Geometry.Buffer.Text; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Tetrahedron){ + return R3.D3.API.Geometry.Buffer.Tetrahedron; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Sphere){ + return R3.D3.API.Geometry.Buffer.Sphere; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Shape){ + return R3.D3.API.Geometry.Buffer.Shape; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Ring){ + return R3.D3.API.Geometry.Buffer.Ring; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Polyhedron){ + return R3.D3.API.Geometry.Buffer.Polyhedron; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Plane){ + return R3.D3.API.Geometry.Buffer.Plane; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Parametric){ + return R3.D3.API.Geometry.Buffer.Parametric; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Octahedron){ + return R3.D3.API.Geometry.Buffer.Octahedron; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Lathe){ + return R3.D3.API.Geometry.Buffer.Lathe; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Instanced){ + return R3.D3.API.Geometry.Buffer.Instanced; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Icosahedron){ + return R3.D3.API.Geometry.Buffer.Icosahedron; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Extrude){ + return R3.D3.API.Geometry.Buffer.Extrude; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Dodecahedron){ + return R3.D3.API.Geometry.Buffer.Dodecahedron; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Cylinder){ + return R3.D3.API.Geometry.Buffer.Cylinder; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Cone){ + return R3.D3.API.Geometry.Buffer.Cone; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Circle){ + return R3.D3.API.Geometry.Buffer.Circle; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Box){ + return R3.D3.API.Geometry.Buffer.Box; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer){ + return R3.D3.API.Geometry.Buffer; + } + if (runtimeComponent instanceof R3.D3.Geometry){ + return R3.D3.API.Geometry; + } + if (runtimeComponent instanceof R3.D3.FrictionMaterial){ + return R3.D3.API.FrictionMaterial; + } + if (runtimeComponent instanceof R3.D3.FrictionContactMaterial){ + return R3.D3.API.FrictionContactMaterial; + } + if (runtimeComponent instanceof R3.D3.Fog.Normal){ + return R3.D3.API.Fog.Normal; + } + if (runtimeComponent instanceof R3.D3.Fog.Exp){ + return R3.D3.API.Fog.Exp; + } + if (runtimeComponent instanceof R3.D3.Fog){ + return R3.D3.API.Fog; + } + if (runtimeComponent instanceof R3.D3.Face.Graphics){ + return R3.D3.API.Face.Graphics; + } + if (runtimeComponent instanceof R3.D3.Face){ + return R3.D3.API.Face; + } + if (runtimeComponent instanceof R3.D3.Effect.Stereo){ + return R3.D3.API.Effect.Stereo; + } + if (runtimeComponent instanceof R3.D3.Effect.Parallax){ + return R3.D3.API.Effect.Parallax; + } + if (runtimeComponent instanceof R3.D3.Effect.Anaglyph){ + return R3.D3.API.Effect.Anaglyph; + } + if (runtimeComponent instanceof R3.D3.Effect){ + return R3.D3.API.Effect; + } + if (runtimeComponent instanceof R3.D3.Composer){ + return R3.D3.API.Composer; + } + if (runtimeComponent instanceof R3.D3.Camera.Perspective.Stereo){ + return R3.D3.API.Camera.Perspective.Stereo; + } + if (runtimeComponent instanceof R3.D3.Camera.Perspective){ + return R3.D3.API.Camera.Perspective; + } + if (runtimeComponent instanceof R3.D3.Camera.Orthographic.ScaledAspect){ + return R3.D3.API.Camera.Orthographic.ScaledAspect; + } + if (runtimeComponent instanceof R3.D3.Camera.Orthographic.FixedAspect){ + return R3.D3.API.Camera.Orthographic.FixedAspect; + } + if (runtimeComponent instanceof R3.D3.Camera.Orthographic){ + return R3.D3.API.Camera.Orthographic; + } + if (runtimeComponent instanceof R3.D3.Camera.Cube){ + return R3.D3.API.Camera.Cube; + } + if (runtimeComponent instanceof R3.D3.Camera){ + return R3.D3.API.Camera; + } + if (runtimeComponent instanceof R3.D3.Broadphase){ + return R3.D3.API.Broadphase; + } + if (runtimeComponent instanceof R3.D3.BoneWeight){ + return R3.D3.API.BoneWeight; + } + if (runtimeComponent instanceof R3.D3.Bone){ + return R3.D3.API.Bone; + } + if (runtimeComponent instanceof R3.D3.Audio){ + return R3.D3.API.Audio; + } + if (runtimeComponent instanceof R3.D3.Animation){ + return R3.D3.API.Animation; + } + if (runtimeComponent instanceof R3.D3.Object){ + return R3.D3.API.Object; + } + if (runtimeComponent instanceof R3.CustomCode){ + return R3.API.CustomCode; + } + if (runtimeComponent instanceof R3.Curve.Path.D2.Shape){ + return R3.API.Curve.Path.D2.Shape; + } + if (runtimeComponent instanceof R3.Curve.Path.D2){ + return R3.API.Curve.Path.D2; + } + if (runtimeComponent instanceof R3.Curve.Path){ + return R3.API.Curve.Path; + } + if (runtimeComponent instanceof R3.Curve){ + return R3.API.Curve; + } + if (runtimeComponent instanceof R3.Controls.Touch){ + return R3.API.Controls.Touch; + } + if (runtimeComponent instanceof R3.Controls.Mouse){ + return R3.API.Controls.Mouse; + } + if (runtimeComponent instanceof R3.Controls.Keyboard){ + return R3.API.Controls.Keyboard; + } + if (runtimeComponent instanceof R3.Controls.D3.Orbit){ + return R3.API.Controls.D3.Orbit; + } + if (runtimeComponent instanceof R3.Controls.D3.FirstPerson){ + return R3.API.Controls.D3.FirstPerson; + } + if (runtimeComponent instanceof R3.Controls.D3){ + return R3.API.Controls.D3; + } + if (runtimeComponent instanceof R3.Controls){ + return R3.API.Controls; + } + if (runtimeComponent instanceof R3.Color){ + return R3.API.Color; + } + if (runtimeComponent instanceof R3.Clock){ + return R3.API.Clock; + } + if (runtimeComponent instanceof R3.Canvas){ + return R3.API.Canvas; + } + if (runtimeComponent instanceof R3.Box3){ + return R3.API.Box3; + } + throw new Error('Invalid Runtime Constructor : ' + runtimeConstructor); + +}; + +/** + * R3.GetConstructor + * @param apiComponent + * @returns constructor + */ +R3.GetConstructor = function(apiComponent) { + + if (apiComponent instanceof R3.API.Video){ + return R3.Video; + } + if (apiComponent instanceof R3.API.Vector4){ + return R3.Vector4; + } + if (apiComponent instanceof R3.API.Vector3){ + return R3.Vector3; + } + if (apiComponent instanceof R3.API.Vector2){ + return R3.Vector2; + } + if (apiComponent instanceof R3.API.User){ + return R3.User; + } + if (apiComponent instanceof R3.API.Stats){ + return R3.Stats; + } + if (apiComponent instanceof R3.API.Sphere){ + return R3.Sphere; + } + if (apiComponent instanceof R3.API.Socket.Receive){ + return R3.Socket.Receive; + } + if (apiComponent instanceof R3.API.Socket.Cast){ + return R3.Socket.Cast; + } + if (apiComponent instanceof R3.API.Socket){ + return R3.Socket; + } + if (apiComponent instanceof R3.API.Server){ + return R3.Server; + } + if (apiComponent instanceof R3.API.Scalar){ + return R3.Scalar; + } + if (apiComponent instanceof R3.API.Renderer.D3.Canvas.Target){ + return R3.Renderer.D3.Canvas.Target; + } + if (apiComponent instanceof R3.API.Renderer.D3.Canvas){ + return R3.Renderer.D3.Canvas; + } + if (apiComponent instanceof R3.API.Renderer.D3){ + return R3.Renderer.D3; + } + if (apiComponent instanceof R3.API.Renderer.D2){ + return R3.Renderer.D2; + } + if (apiComponent instanceof R3.API.Renderer){ + return R3.Renderer; + } + if (apiComponent instanceof R3.API.Query.Users){ + return R3.Query.Users; + } + if (apiComponent instanceof R3.API.Query.UserDevices){ + return R3.Query.UserDevices; + } + if (apiComponent instanceof R3.API.Query.Logins.VPN){ + return R3.Query.Logins.VPN; + } + if (apiComponent instanceof R3.API.Query.Logins.Devices){ + return R3.Query.Logins.Devices; + } + if (apiComponent instanceof R3.API.Query.Logins.Applications){ + return R3.Query.Logins.Applications; + } + if (apiComponent instanceof R3.API.Query.Logins){ + return R3.Query.Logins; + } + if (apiComponent instanceof R3.API.Query.Devices.Unknown){ + return R3.Query.Devices.Unknown; + } + if (apiComponent instanceof R3.API.Query.Devices.SQL){ + return R3.Query.Devices.SQL; + } + if (apiComponent instanceof R3.API.Query.Devices.Known){ + return R3.Query.Devices.Known; + } + if (apiComponent instanceof R3.API.Query.Devices){ + return R3.Query.Devices; + } + if (apiComponent instanceof R3.API.Query.Alerts.Timeseries){ + return R3.Query.Alerts.Timeseries; + } + if (apiComponent instanceof R3.API.Query.Alerts.Summary){ + return R3.Query.Alerts.Summary; + } + if (apiComponent instanceof R3.API.Query.Alerts.List){ + return R3.Query.Alerts.List; + } + if (apiComponent instanceof R3.API.Query.Alerts.FirstTimeLogin.VPN){ + return R3.Query.Alerts.FirstTimeLogin.VPN; + } + if (apiComponent instanceof R3.API.Query.Alerts.FirstTimeLogin.Devices){ + return R3.Query.Alerts.FirstTimeLogin.Devices; + } + if (apiComponent instanceof R3.API.Query.Alerts.FirstTimeLogin.Applications){ + return R3.Query.Alerts.FirstTimeLogin.Applications; + } + if (apiComponent instanceof R3.API.Query.Alerts.FirstTimeLogin){ + return R3.Query.Alerts.FirstTimeLogin; + } + if (apiComponent instanceof R3.API.Query.Alerts.Buckets){ + return R3.Query.Alerts.Buckets; + } + if (apiComponent instanceof R3.API.Query.Alerts){ + return R3.Query.Alerts; + } + if (apiComponent instanceof R3.API.Query){ + return R3.Query; + } + if (apiComponent instanceof R3.API.Quaternion.Points){ + return R3.Quaternion.Points; + } + if (apiComponent instanceof R3.API.Quaternion){ + return R3.Quaternion; + } + if (apiComponent instanceof R3.API.Project.D3.VR){ + return R3.Project.D3.VR; + } + if (apiComponent instanceof R3.API.Project.D3){ + return R3.Project.D3; + } + if (apiComponent instanceof R3.API.Project.D2){ + return R3.Project.D2; + } + if (apiComponent instanceof R3.API.Project){ + return R3.Project; + } + if (apiComponent instanceof R3.API.Plane){ + return R3.Plane; + } + if (apiComponent instanceof R3.API.Mouse){ + return R3.Mouse; + } + if (apiComponent instanceof R3.API.Matrix4){ + return R3.Matrix4; + } + if (apiComponent instanceof R3.API.Image){ + return R3.Image; + } + if (apiComponent instanceof R3.API.Group){ + return R3.Group; + } + if (apiComponent instanceof R3.API.Graph.Table){ + return R3.Graph.Table; + } + if (apiComponent instanceof R3.API.Graph.Metric){ + return R3.Graph.Metric; + } + if (apiComponent instanceof R3.API.Graph.Barchart.Stacked){ + return R3.Graph.Barchart.Stacked; + } + if (apiComponent instanceof R3.API.Graph.Barchart){ + return R3.Graph.Barchart; + } + if (apiComponent instanceof R3.API.Graph){ + return R3.Graph; + } + if (apiComponent instanceof R3.API.Font){ + return R3.Font; + } + if (apiComponent instanceof R3.API.Entity){ + return R3.Entity; + } + if (apiComponent instanceof R3.API.DrawRange){ + return R3.DrawRange; + } + if (apiComponent instanceof R3.API.DomElement){ + return R3.DomElement; + } + if (apiComponent instanceof R3.D3.API.Viewport.ZoomedAspect){ + return R3.D3.Viewport.ZoomedAspect; + } + if (apiComponent instanceof R3.D3.API.Viewport.FixedAspect.VR){ + return R3.D3.Viewport.FixedAspect.VR; + } + if (apiComponent instanceof R3.D3.API.Viewport.FixedAspect){ + return R3.D3.Viewport.FixedAspect; + } + if (apiComponent instanceof R3.D3.API.Viewport){ + return R3.D3.Viewport; + } + if (apiComponent instanceof R3.D3.API.Vertex){ + return R3.D3.Vertex; + } + if (apiComponent instanceof R3.D3.API.Texture.Image){ + return R3.D3.Texture.Image; + } + if (apiComponent instanceof R3.D3.API.Texture.Cube){ + return R3.D3.Texture.Cube; + } + if (apiComponent instanceof R3.D3.API.Texture.Canvas){ + return R3.D3.Texture.Canvas; + } + if (apiComponent instanceof R3.D3.API.Texture){ + return R3.D3.Texture; + } + if (apiComponent instanceof R3.D3.API.Text){ + return R3.D3.Text; + } + if (apiComponent instanceof R3.D3.API.Spline){ + return R3.D3.Spline; + } + if (apiComponent instanceof R3.D3.API.Solver){ + return R3.D3.Solver; + } + if (apiComponent instanceof R3.D3.API.Skeleton){ + return R3.D3.Skeleton; + } + if (apiComponent instanceof R3.D3.API.Shape.TriMesh){ + return R3.D3.Shape.TriMesh; + } + if (apiComponent instanceof R3.D3.API.Shape.Sphere){ + return R3.D3.Shape.Sphere; + } + if (apiComponent instanceof R3.D3.API.Shape.Plane){ + return R3.D3.Shape.Plane; + } + if (apiComponent instanceof R3.D3.API.Shape.HeightMap){ + return R3.D3.Shape.HeightMap; + } + if (apiComponent instanceof R3.D3.API.Shape.ConvexHull.Cylinder){ + return R3.D3.Shape.ConvexHull.Cylinder; + } + if (apiComponent instanceof R3.D3.API.Shape.ConvexHull){ + return R3.D3.Shape.ConvexHull; + } + if (apiComponent instanceof R3.D3.API.Shape.Box){ + return R3.D3.Shape.Box; + } + if (apiComponent instanceof R3.D3.API.Shape){ + return R3.D3.Shape; + } + if (apiComponent instanceof R3.D3.API.Shadow.Spot){ + return R3.D3.Shadow.Spot; + } + if (apiComponent instanceof R3.D3.API.Shadow.Directional){ + return R3.D3.Shadow.Directional; + } + if (apiComponent instanceof R3.D3.API.Shadow){ + return R3.D3.Shadow; + } + if (apiComponent instanceof R3.D3.API.Shader.Vertex){ + return R3.D3.Shader.Vertex; + } + if (apiComponent instanceof R3.D3.API.Shader.Fragment){ + return R3.D3.Shader.Fragment; + } + if (apiComponent instanceof R3.D3.API.Shader){ + return R3.D3.Shader; + } + if (apiComponent instanceof R3.D3.API.Scene){ + return R3.D3.Scene; + } + if (apiComponent instanceof R3.D3.API.RigidBody){ + return R3.D3.RigidBody; + } + if (apiComponent instanceof R3.D3.API.RenderTarget.Cube){ + return R3.D3.RenderTarget.Cube; + } + if (apiComponent instanceof R3.D3.API.RenderTarget){ + return R3.D3.RenderTarget; + } + if (apiComponent instanceof R3.D3.API.Raycaster){ + return R3.D3.Raycaster; + } + if (apiComponent instanceof R3.D3.API.RaycastWheel){ + return R3.D3.RaycastWheel; + } + if (apiComponent instanceof R3.D3.API.RaycastVehicle){ + return R3.D3.RaycastVehicle; + } + if (apiComponent instanceof R3.D3.API.PhysicsWorld){ + return R3.D3.PhysicsWorld; + } + if (apiComponent instanceof R3.D3.API.Pass.Render.SSAO){ + return R3.D3.Pass.Render.SSAO; + } + if (apiComponent instanceof R3.D3.API.Pass.Render){ + return R3.D3.Pass.Render; + } + if (apiComponent instanceof R3.D3.API.Pass.FXAA){ + return R3.D3.Pass.FXAA; + } + if (apiComponent instanceof R3.D3.API.Pass.Copy){ + return R3.D3.Pass.Copy; + } + if (apiComponent instanceof R3.D3.API.Pass.Bloom){ + return R3.D3.Pass.Bloom; + } + if (apiComponent instanceof R3.D3.API.Pass){ + return R3.D3.Pass; + } + if (apiComponent instanceof R3.D3.API.Mesh.Skeleton){ + return R3.D3.Mesh.Skeleton; + } + if (apiComponent instanceof R3.D3.API.Mesh.Particle.Engine){ + return R3.D3.Mesh.Particle.Engine; + } + if (apiComponent instanceof R3.D3.API.Mesh.Particle){ + return R3.D3.Mesh.Particle; + } + if (apiComponent instanceof R3.D3.API.Mesh){ + return R3.D3.Mesh; + } + if (apiComponent instanceof R3.D3.API.Material.Standard){ + return R3.D3.Material.Standard; + } + if (apiComponent instanceof R3.D3.API.Material.Shader.Raw){ + return R3.D3.Material.Shader.Raw; + } + if (apiComponent instanceof R3.D3.API.Material.Shader){ + return R3.D3.Material.Shader; + } + if (apiComponent instanceof R3.D3.API.Material.Points){ + return R3.D3.Material.Points; + } + if (apiComponent instanceof R3.D3.API.Material.Phong){ + return R3.D3.Material.Phong; + } + if (apiComponent instanceof R3.D3.API.Material.Basic){ + return R3.D3.Material.Basic; + } + if (apiComponent instanceof R3.D3.API.Material){ + return R3.D3.Material; + } + if (apiComponent instanceof R3.D3.API.Light.Spot){ + return R3.D3.Light.Spot; + } + if (apiComponent instanceof R3.D3.API.Light.RectArea){ + return R3.D3.Light.RectArea; + } + if (apiComponent instanceof R3.D3.API.Light.Point){ + return R3.D3.Light.Point; + } + if (apiComponent instanceof R3.D3.API.Light.Hemisphere){ + return R3.D3.Light.Hemisphere; + } + if (apiComponent instanceof R3.D3.API.Light.Directional){ + return R3.D3.Light.Directional; + } + if (apiComponent instanceof R3.D3.API.Light.Ambient){ + return R3.D3.Light.Ambient; + } + if (apiComponent instanceof R3.D3.API.Light){ + return R3.D3.Light; + } + if (apiComponent instanceof R3.D3.API.Helper){ + return R3.D3.Helper; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Wireframe){ + return R3.D3.Geometry.Normal.Wireframe; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Tube){ + return R3.D3.Geometry.Normal.Tube; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.TorusKnot){ + return R3.D3.Geometry.Normal.TorusKnot; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Torus){ + return R3.D3.Geometry.Normal.Torus; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Text){ + return R3.D3.Geometry.Normal.Text; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Tetrahedron){ + return R3.D3.Geometry.Normal.Tetrahedron; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Sphere){ + return R3.D3.Geometry.Normal.Sphere; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Shape){ + return R3.D3.Geometry.Normal.Shape; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Ring){ + return R3.D3.Geometry.Normal.Ring; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Polyhedron){ + return R3.D3.Geometry.Normal.Polyhedron; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Plane){ + return R3.D3.Geometry.Normal.Plane; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Parametric){ + return R3.D3.Geometry.Normal.Parametric; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Octahedron){ + return R3.D3.Geometry.Normal.Octahedron; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Lathe){ + return R3.D3.Geometry.Normal.Lathe; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Icosahedron){ + return R3.D3.Geometry.Normal.Icosahedron; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Extrude){ + return R3.D3.Geometry.Normal.Extrude; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Edges){ + return R3.D3.Geometry.Normal.Edges; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Dodecahedron){ + return R3.D3.Geometry.Normal.Dodecahedron; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Cylinder){ + return R3.D3.Geometry.Normal.Cylinder; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Cone){ + return R3.D3.Geometry.Normal.Cone; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Circle){ + return R3.D3.Geometry.Normal.Circle; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal.Box){ + return R3.D3.Geometry.Normal.Box; + } + if (apiComponent instanceof R3.D3.API.Geometry.Normal){ + return R3.D3.Geometry.Normal; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Tube){ + return R3.D3.Geometry.Buffer.Tube; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.TorusKnot){ + return R3.D3.Geometry.Buffer.TorusKnot; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Torus){ + return R3.D3.Geometry.Buffer.Torus; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Text){ + return R3.D3.Geometry.Buffer.Text; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Tetrahedron){ + return R3.D3.Geometry.Buffer.Tetrahedron; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Sphere){ + return R3.D3.Geometry.Buffer.Sphere; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Shape){ + return R3.D3.Geometry.Buffer.Shape; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Ring){ + return R3.D3.Geometry.Buffer.Ring; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Polyhedron){ + return R3.D3.Geometry.Buffer.Polyhedron; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Plane){ + return R3.D3.Geometry.Buffer.Plane; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Parametric){ + return R3.D3.Geometry.Buffer.Parametric; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Octahedron){ + return R3.D3.Geometry.Buffer.Octahedron; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Lathe){ + return R3.D3.Geometry.Buffer.Lathe; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Instanced){ + return R3.D3.Geometry.Buffer.Instanced; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Icosahedron){ + return R3.D3.Geometry.Buffer.Icosahedron; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Extrude){ + return R3.D3.Geometry.Buffer.Extrude; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Dodecahedron){ + return R3.D3.Geometry.Buffer.Dodecahedron; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Cylinder){ + return R3.D3.Geometry.Buffer.Cylinder; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Cone){ + return R3.D3.Geometry.Buffer.Cone; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Circle){ + return R3.D3.Geometry.Buffer.Circle; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer.Box){ + return R3.D3.Geometry.Buffer.Box; + } + if (apiComponent instanceof R3.D3.API.Geometry.Buffer){ + return R3.D3.Geometry.Buffer; + } + if (apiComponent instanceof R3.D3.API.Geometry){ + return R3.D3.Geometry; + } + if (apiComponent instanceof R3.D3.API.FrictionMaterial){ + return R3.D3.FrictionMaterial; + } + if (apiComponent instanceof R3.D3.API.FrictionContactMaterial){ + return R3.D3.FrictionContactMaterial; + } + if (apiComponent instanceof R3.D3.API.Fog.Normal){ + return R3.D3.Fog.Normal; + } + if (apiComponent instanceof R3.D3.API.Fog.Exp){ + return R3.D3.Fog.Exp; + } + if (apiComponent instanceof R3.D3.API.Fog){ + return R3.D3.Fog; + } + if (apiComponent instanceof R3.D3.API.Face.Graphics){ + return R3.D3.Face.Graphics; + } + if (apiComponent instanceof R3.D3.API.Face){ + return R3.D3.Face; + } + if (apiComponent instanceof R3.D3.API.Effect.Stereo){ + return R3.D3.Effect.Stereo; + } + if (apiComponent instanceof R3.D3.API.Effect.Parallax){ + return R3.D3.Effect.Parallax; + } + if (apiComponent instanceof R3.D3.API.Effect.Anaglyph){ + return R3.D3.Effect.Anaglyph; + } + if (apiComponent instanceof R3.D3.API.Effect){ + return R3.D3.Effect; + } + if (apiComponent instanceof R3.D3.API.Composer){ + return R3.D3.Composer; + } + if (apiComponent instanceof R3.D3.API.Camera.Perspective.Stereo){ + return R3.D3.Camera.Perspective.Stereo; + } + if (apiComponent instanceof R3.D3.API.Camera.Perspective){ + return R3.D3.Camera.Perspective; + } + if (apiComponent instanceof R3.D3.API.Camera.Orthographic.ScaledAspect){ + return R3.D3.Camera.Orthographic.ScaledAspect; + } + if (apiComponent instanceof R3.D3.API.Camera.Orthographic.FixedAspect){ + return R3.D3.Camera.Orthographic.FixedAspect; + } + if (apiComponent instanceof R3.D3.API.Camera.Orthographic){ + return R3.D3.Camera.Orthographic; + } + if (apiComponent instanceof R3.D3.API.Camera.Cube){ + return R3.D3.Camera.Cube; + } + if (apiComponent instanceof R3.D3.API.Camera){ + return R3.D3.Camera; + } + if (apiComponent instanceof R3.D3.API.Broadphase){ + return R3.D3.Broadphase; + } + if (apiComponent instanceof R3.D3.API.BoneWeight){ + return R3.D3.BoneWeight; + } + if (apiComponent instanceof R3.D3.API.Bone){ + return R3.D3.Bone; + } + if (apiComponent instanceof R3.D3.API.Audio){ + return R3.D3.Audio; + } + if (apiComponent instanceof R3.D3.API.Animation){ + return R3.D3.Animation; + } + if (apiComponent instanceof R3.D3.API.Object){ + return R3.D3.Object; + } + if (apiComponent instanceof R3.API.CustomCode){ + return R3.CustomCode; + } + if (apiComponent instanceof R3.API.Curve.Path.D2.Shape){ + return R3.Curve.Path.D2.Shape; + } + if (apiComponent instanceof R3.API.Curve.Path.D2){ + return R3.Curve.Path.D2; + } + if (apiComponent instanceof R3.API.Curve.Path){ + return R3.Curve.Path; + } + if (apiComponent instanceof R3.API.Curve){ + return R3.Curve; + } + if (apiComponent instanceof R3.API.Controls.Touch){ + return R3.Controls.Touch; + } + if (apiComponent instanceof R3.API.Controls.Mouse){ + return R3.Controls.Mouse; + } + if (apiComponent instanceof R3.API.Controls.Keyboard){ + return R3.Controls.Keyboard; + } + if (apiComponent instanceof R3.API.Controls.D3.Orbit){ + return R3.Controls.D3.Orbit; + } + if (apiComponent instanceof R3.API.Controls.D3.FirstPerson){ + return R3.Controls.D3.FirstPerson; + } + if (apiComponent instanceof R3.API.Controls.D3){ + return R3.Controls.D3; + } + if (apiComponent instanceof R3.API.Controls){ + return R3.Controls; + } + if (apiComponent instanceof R3.API.Color){ + return R3.Color; + } + if (apiComponent instanceof R3.API.Clock){ + return R3.Clock; + } + if (apiComponent instanceof R3.API.Canvas){ + return R3.Canvas; + } + if (apiComponent instanceof R3.API.Box3){ + return R3.Box3; + } + throw new Error('Invalid API Constructor : ' + apiConstructor); + +}; + +/** + * R3.GetConstructorFromComponentType + * @param componentType + * @returns constructor + */ +R3.GetConstructorFromComponentType = function(componentType) { + + switch (componentType) { + + case R3.COMPONENT_VIDEO: return R3.Video; + case R3.COMPONENT_VECTOR4: return R3.Vector4; + case R3.COMPONENT_VECTOR3: return R3.Vector3; + case R3.COMPONENT_VECTOR2: return R3.Vector2; + case R3.COMPONENT_USER: return R3.User; + case R3.COMPONENT_STATS: return R3.Stats; + case R3.COMPONENT_SPHERE: return R3.Sphere; + case R3.COMPONENT_SOCKET_RECEIVE: return R3.Socket.Receive; + case R3.COMPONENT_SOCKET_CAST: return R3.Socket.Cast; + case R3.COMPONENT_SOCKET: return R3.Socket; + case R3.COMPONENT_SERVER: return R3.Server; + case R3.COMPONENT_SCALAR: return R3.Scalar; + case R3.COMPONENT_RENDERER_D3_CANVAS_TARGET: return R3.Renderer.D3.Canvas.Target; + case R3.COMPONENT_RENDERER_D3_CANVAS: return R3.Renderer.D3.Canvas; + case R3.COMPONENT_RENDERER_D3: return R3.Renderer.D3; + case R3.COMPONENT_RENDERER_D2: return R3.Renderer.D2; + case R3.COMPONENT_RENDERER: return R3.Renderer; + case R3.COMPONENT_QUERY_USERS: return R3.Query.Users; + case R3.COMPONENT_QUERY_USERDEVICES: return R3.Query.UserDevices; + case R3.COMPONENT_QUERY_LOGINS_VPN: return R3.Query.Logins.VPN; + case R3.COMPONENT_QUERY_LOGINS_DEVICES: return R3.Query.Logins.Devices; + case R3.COMPONENT_QUERY_LOGINS_APPLICATIONS: return R3.Query.Logins.Applications; + case R3.COMPONENT_QUERY_LOGINS: return R3.Query.Logins; + case R3.COMPONENT_QUERY_DEVICES_UNKNOWN: return R3.Query.Devices.Unknown; + case R3.COMPONENT_QUERY_DEVICES_SQL: return R3.Query.Devices.SQL; + case R3.COMPONENT_QUERY_DEVICES_KNOWN: return R3.Query.Devices.Known; + case R3.COMPONENT_QUERY_DEVICES: return R3.Query.Devices; + case R3.COMPONENT_QUERY_ALERTS_TIMESERIES: return R3.Query.Alerts.Timeseries; + case R3.COMPONENT_QUERY_ALERTS_SUMMARY: return R3.Query.Alerts.Summary; + case R3.COMPONENT_QUERY_ALERTS_LIST: return R3.Query.Alerts.List; + case R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_VPN: return R3.Query.Alerts.FirstTimeLogin.VPN; + case R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_DEVICES: return R3.Query.Alerts.FirstTimeLogin.Devices; + case R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN_APPLICATIONS: return R3.Query.Alerts.FirstTimeLogin.Applications; + case R3.COMPONENT_QUERY_ALERTS_FIRSTTIMELOGIN: return R3.Query.Alerts.FirstTimeLogin; + case R3.COMPONENT_QUERY_ALERTS_BUCKETS: return R3.Query.Alerts.Buckets; + case R3.COMPONENT_QUERY_ALERTS: return R3.Query.Alerts; + case R3.COMPONENT_QUERY: return R3.Query; + case R3.COMPONENT_QUATERNION_POINTS: return R3.Quaternion.Points; + case R3.COMPONENT_QUATERNION: return R3.Quaternion; + case R3.COMPONENT_PROJECT_D3_VR: return R3.Project.D3.VR; + case R3.COMPONENT_PROJECT_D3: return R3.Project.D3; + case R3.COMPONENT_PROJECT_D2: return R3.Project.D2; + case R3.COMPONENT_PROJECT: return R3.Project; + case R3.COMPONENT_PLANE: return R3.Plane; + case R3.COMPONENT_MOUSE: return R3.Mouse; + case R3.COMPONENT_MATRIX4: return R3.Matrix4; + case R3.COMPONENT_IMAGE: return R3.Image; + case R3.COMPONENT_GROUP: return R3.Group; + case R3.COMPONENT_GRAPH_TABLE: return R3.Graph.Table; + case R3.COMPONENT_GRAPH_METRIC: return R3.Graph.Metric; + case R3.COMPONENT_GRAPH_BARCHART_STACKED: return R3.Graph.Barchart.Stacked; + case R3.COMPONENT_GRAPH_BARCHART: return R3.Graph.Barchart; + case R3.COMPONENT_GRAPH: return R3.Graph; + case R3.COMPONENT_FONT: return R3.Font; + case R3.COMPONENT_ENTITY: return R3.Entity; + case R3.COMPONENT_DRAWRANGE: return R3.DrawRange; + case R3.COMPONENT_DOMELEMENT: return R3.DomElement; + case R3.COMPONENT_D3_VIEWPORT_ZOOMEDASPECT: return R3.D3.Viewport.ZoomedAspect; + case R3.COMPONENT_D3_VIEWPORT_FIXEDASPECT_VR: return R3.D3.Viewport.FixedAspect.VR; + case R3.COMPONENT_D3_VIEWPORT_FIXEDASPECT: return R3.D3.Viewport.FixedAspect; + case R3.COMPONENT_D3_VIEWPORT: return R3.D3.Viewport; + case R3.COMPONENT_D3_VERTEX: return R3.D3.Vertex; + case R3.COMPONENT_D3_TEXTURE_IMAGE: return R3.D3.Texture.Image; + case R3.COMPONENT_D3_TEXTURE_CUBE: return R3.D3.Texture.Cube; + case R3.COMPONENT_D3_TEXTURE_CANVAS: return R3.D3.Texture.Canvas; + case R3.COMPONENT_D3_TEXTURE: return R3.D3.Texture; + case R3.COMPONENT_D3_TEXT: return R3.D3.Text; + case R3.COMPONENT_D3_SPLINE: return R3.D3.Spline; + case R3.COMPONENT_D3_SOLVER: return R3.D3.Solver; + case R3.COMPONENT_D3_SKELETON: return R3.D3.Skeleton; + case R3.COMPONENT_D3_SHAPE_TRIMESH: return R3.D3.Shape.TriMesh; + case R3.COMPONENT_D3_SHAPE_SPHERE: return R3.D3.Shape.Sphere; + case R3.COMPONENT_D3_SHAPE_PLANE: return R3.D3.Shape.Plane; + case R3.COMPONENT_D3_SHAPE_HEIGHTMAP: return R3.D3.Shape.HeightMap; + case R3.COMPONENT_D3_SHAPE_CONVEXHULL_CYLINDER: return R3.D3.Shape.ConvexHull.Cylinder; + case R3.COMPONENT_D3_SHAPE_CONVEXHULL: return R3.D3.Shape.ConvexHull; + case R3.COMPONENT_D3_SHAPE_BOX: return R3.D3.Shape.Box; + case R3.COMPONENT_D3_SHAPE: return R3.D3.Shape; + case R3.COMPONENT_D3_SHADOW_SPOT: return R3.D3.Shadow.Spot; + case R3.COMPONENT_D3_SHADOW_DIRECTIONAL: return R3.D3.Shadow.Directional; + case R3.COMPONENT_D3_SHADOW: return R3.D3.Shadow; + case R3.COMPONENT_D3_SHADER_VERTEX: return R3.D3.Shader.Vertex; + case R3.COMPONENT_D3_SHADER_FRAGMENT: return R3.D3.Shader.Fragment; + case R3.COMPONENT_D3_SHADER: return R3.D3.Shader; + case R3.COMPONENT_D3_SCENE: return R3.D3.Scene; + case R3.COMPONENT_D3_RIGIDBODY: return R3.D3.RigidBody; + case R3.COMPONENT_D3_RENDERTARGET_CUBE: return R3.D3.RenderTarget.Cube; + case R3.COMPONENT_D3_RENDERTARGET: return R3.D3.RenderTarget; + case R3.COMPONENT_D3_RAYCASTER: return R3.D3.Raycaster; + case R3.COMPONENT_D3_RAYCASTWHEEL: return R3.D3.RaycastWheel; + case R3.COMPONENT_D3_RAYCASTVEHICLE: return R3.D3.RaycastVehicle; + case R3.COMPONENT_D3_PHYSICSWORLD: return R3.D3.PhysicsWorld; + case R3.COMPONENT_D3_PASS_RENDER_SSAO: return R3.D3.Pass.Render.SSAO; + case R3.COMPONENT_D3_PASS_RENDER: return R3.D3.Pass.Render; + case R3.COMPONENT_D3_PASS_FXAA: return R3.D3.Pass.FXAA; + case R3.COMPONENT_D3_PASS_COPY: return R3.D3.Pass.Copy; + case R3.COMPONENT_D3_PASS_BLOOM: return R3.D3.Pass.Bloom; + case R3.COMPONENT_D3_PASS: return R3.D3.Pass; + case R3.COMPONENT_D3_MESH_SKELETON: return R3.D3.Mesh.Skeleton; + case R3.COMPONENT_D3_MESH_PARTICLE_ENGINE: return R3.D3.Mesh.Particle.Engine; + case R3.COMPONENT_D3_MESH_PARTICLE: return R3.D3.Mesh.Particle; + case R3.COMPONENT_D3_MESH: return R3.D3.Mesh; + case R3.COMPONENT_D3_MATERIAL_STANDARD: return R3.D3.Material.Standard; + case R3.COMPONENT_D3_MATERIAL_SHADER_RAW: return R3.D3.Material.Shader.Raw; + case R3.COMPONENT_D3_MATERIAL_SHADER: return R3.D3.Material.Shader; + case R3.COMPONENT_D3_MATERIAL_POINTS: return R3.D3.Material.Points; + case R3.COMPONENT_D3_MATERIAL_PHONG: return R3.D3.Material.Phong; + case R3.COMPONENT_D3_MATERIAL_BASIC: return R3.D3.Material.Basic; + case R3.COMPONENT_D3_MATERIAL: return R3.D3.Material; + case R3.COMPONENT_D3_LIGHT_SPOT: return R3.D3.Light.Spot; + case R3.COMPONENT_D3_LIGHT_RECTAREA: return R3.D3.Light.RectArea; + case R3.COMPONENT_D3_LIGHT_POINT: return R3.D3.Light.Point; + case R3.COMPONENT_D3_LIGHT_HEMISPHERE: return R3.D3.Light.Hemisphere; + case R3.COMPONENT_D3_LIGHT_DIRECTIONAL: return R3.D3.Light.Directional; + case R3.COMPONENT_D3_LIGHT_AMBIENT: return R3.D3.Light.Ambient; + case R3.COMPONENT_D3_LIGHT: return R3.D3.Light; + case R3.COMPONENT_D3_HELPER: return R3.D3.Helper; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_WIREFRAME: return R3.D3.Geometry.Normal.Wireframe; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_TUBE: return R3.D3.Geometry.Normal.Tube; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_TORUSKNOT: return R3.D3.Geometry.Normal.TorusKnot; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_TORUS: return R3.D3.Geometry.Normal.Torus; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_TEXT: return R3.D3.Geometry.Normal.Text; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_TETRAHEDRON: return R3.D3.Geometry.Normal.Tetrahedron; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_SPHERE: return R3.D3.Geometry.Normal.Sphere; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_SHAPE: return R3.D3.Geometry.Normal.Shape; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_RING: return R3.D3.Geometry.Normal.Ring; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_POLYHEDRON: return R3.D3.Geometry.Normal.Polyhedron; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_PLANE: return R3.D3.Geometry.Normal.Plane; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_PARAMETRIC: return R3.D3.Geometry.Normal.Parametric; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_OCTAHEDRON: return R3.D3.Geometry.Normal.Octahedron; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_LATHE: return R3.D3.Geometry.Normal.Lathe; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_ICOSAHEDRON: return R3.D3.Geometry.Normal.Icosahedron; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_EXTRUDE: return R3.D3.Geometry.Normal.Extrude; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_EDGES: return R3.D3.Geometry.Normal.Edges; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_DODECAHEDRON: return R3.D3.Geometry.Normal.Dodecahedron; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_CYLINDER: return R3.D3.Geometry.Normal.Cylinder; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_CONE: return R3.D3.Geometry.Normal.Cone; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_CIRCLE: return R3.D3.Geometry.Normal.Circle; + case R3.COMPONENT_D3_GEOMETRY_NORMAL_BOX: return R3.D3.Geometry.Normal.Box; + case R3.COMPONENT_D3_GEOMETRY_NORMAL: return R3.D3.Geometry.Normal; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_TUBE: return R3.D3.Geometry.Buffer.Tube; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_TORUSKNOT: return R3.D3.Geometry.Buffer.TorusKnot; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_TORUS: return R3.D3.Geometry.Buffer.Torus; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_TEXT: return R3.D3.Geometry.Buffer.Text; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_TETRAHEDRON: return R3.D3.Geometry.Buffer.Tetrahedron; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_SPHERE: return R3.D3.Geometry.Buffer.Sphere; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_SHAPE: return R3.D3.Geometry.Buffer.Shape; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_RING: return R3.D3.Geometry.Buffer.Ring; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_POLYHEDRON: return R3.D3.Geometry.Buffer.Polyhedron; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_PLANE: return R3.D3.Geometry.Buffer.Plane; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_PARAMETRIC: return R3.D3.Geometry.Buffer.Parametric; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_OCTAHEDRON: return R3.D3.Geometry.Buffer.Octahedron; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_LATHE: return R3.D3.Geometry.Buffer.Lathe; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_INSTANCED: return R3.D3.Geometry.Buffer.Instanced; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_ICOSAHEDRON: return R3.D3.Geometry.Buffer.Icosahedron; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_EXTRUDE: return R3.D3.Geometry.Buffer.Extrude; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_DODECAHEDRON: return R3.D3.Geometry.Buffer.Dodecahedron; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_CYLINDER: return R3.D3.Geometry.Buffer.Cylinder; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_CONE: return R3.D3.Geometry.Buffer.Cone; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_CIRCLE: return R3.D3.Geometry.Buffer.Circle; + case R3.COMPONENT_D3_GEOMETRY_BUFFER_BOX: return R3.D3.Geometry.Buffer.Box; + case R3.COMPONENT_D3_GEOMETRY_BUFFER: return R3.D3.Geometry.Buffer; + case R3.COMPONENT_D3_GEOMETRY: return R3.D3.Geometry; + case R3.COMPONENT_D3_FRICTIONMATERIAL: return R3.D3.FrictionMaterial; + case R3.COMPONENT_D3_FRICTIONCONTACTMATERIAL: return R3.D3.FrictionContactMaterial; + case R3.COMPONENT_D3_FOG_NORMAL: return R3.D3.Fog.Normal; + case R3.COMPONENT_D3_FOG_EXP: return R3.D3.Fog.Exp; + case R3.COMPONENT_D3_FOG: return R3.D3.Fog; + case R3.COMPONENT_D3_FACE_GRAPHICS: return R3.D3.Face.Graphics; + case R3.COMPONENT_D3_FACE: return R3.D3.Face; + case R3.COMPONENT_D3_EFFECT_STEREO: return R3.D3.Effect.Stereo; + case R3.COMPONENT_D3_EFFECT_PARALLAX: return R3.D3.Effect.Parallax; + case R3.COMPONENT_D3_EFFECT_ANAGLYPH: return R3.D3.Effect.Anaglyph; + case R3.COMPONENT_D3_EFFECT: return R3.D3.Effect; + case R3.COMPONENT_D3_COMPOSER: return R3.D3.Composer; + case R3.COMPONENT_D3_CAMERA_PERSPECTIVE_STEREO: return R3.D3.Camera.Perspective.Stereo; + case R3.COMPONENT_D3_CAMERA_PERSPECTIVE: return R3.D3.Camera.Perspective; + case R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC_SCALEDASPECT: return R3.D3.Camera.Orthographic.ScaledAspect; + case R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC_FIXEDASPECT: return R3.D3.Camera.Orthographic.FixedAspect; + case R3.COMPONENT_D3_CAMERA_ORTHOGRAPHIC: return R3.D3.Camera.Orthographic; + case R3.COMPONENT_D3_CAMERA_CUBE: return R3.D3.Camera.Cube; + case R3.COMPONENT_D3_CAMERA: return R3.D3.Camera; + case R3.COMPONENT_D3_BROADPHASE: return R3.D3.Broadphase; + case R3.COMPONENT_D3_BONEWEIGHT: return R3.D3.BoneWeight; + case R3.COMPONENT_D3_BONE: return R3.D3.Bone; + case R3.COMPONENT_D3_AUDIO: return R3.D3.Audio; + case R3.COMPONENT_D3_ANIMATION: return R3.D3.Animation; + case R3.COMPONENT_D3_OBJECT: return R3.D3.Object; + case R3.COMPONENT_CUSTOMCODE: return R3.CustomCode; + case R3.COMPONENT_CURVE_PATH_D2_SHAPE: return R3.Curve.Path.D2.Shape; + case R3.COMPONENT_CURVE_PATH_D2: return R3.Curve.Path.D2; + case R3.COMPONENT_CURVE_PATH: return R3.Curve.Path; + case R3.COMPONENT_CURVE: return R3.Curve; + case R3.COMPONENT_CONTROLS_TOUCH: return R3.Controls.Touch; + case R3.COMPONENT_CONTROLS_MOUSE: return R3.Controls.Mouse; + case R3.COMPONENT_CONTROLS_KEYBOARD: return R3.Controls.Keyboard; + case R3.COMPONENT_CONTROLS_D3_ORBIT: return R3.Controls.D3.Orbit; + case R3.COMPONENT_CONTROLS_D3_FIRSTPERSON: return R3.Controls.D3.FirstPerson; + case R3.COMPONENT_CONTROLS_D3: return R3.Controls.D3; + case R3.COMPONENT_CONTROLS: return R3.Controls; + case R3.COMPONENT_COLOR: return R3.Color; + case R3.COMPONENT_CLOCK: return R3.Clock; + case R3.COMPONENT_CANVAS: return R3.Canvas; + case R3.COMPONENT_BOX3: return R3.Box3; + default : + throw new Error('Invalid componentType : ' + componentType); + + } +}; + +/** + * R3.GetComponentName + * @param runtimeComponent + * @returns string + */ +R3.GetComponentName = function(runtimeComponent) { + + if (runtimeComponent instanceof R3.Video){ + return 'R3.Video'; + } + if (runtimeComponent instanceof R3.Vector4){ + return 'R3.Vector4'; + } + if (runtimeComponent instanceof R3.Vector3){ + return 'R3.Vector3'; + } + if (runtimeComponent instanceof R3.Vector2){ + return 'R3.Vector2'; + } + if (runtimeComponent instanceof R3.User){ + return 'R3.User'; + } + if (runtimeComponent instanceof R3.Stats){ + return 'R3.Stats'; + } + if (runtimeComponent instanceof R3.Sphere){ + return 'R3.Sphere'; + } + if (runtimeComponent instanceof R3.Socket.Receive){ + return 'R3.Socket.Receive'; + } + if (runtimeComponent instanceof R3.Socket.Cast){ + return 'R3.Socket.Cast'; + } + if (runtimeComponent instanceof R3.Socket){ + return 'R3.Socket'; + } + if (runtimeComponent instanceof R3.Server){ + return 'R3.Server'; + } + if (runtimeComponent instanceof R3.Scalar){ + return 'R3.Scalar'; + } + if (runtimeComponent instanceof R3.Renderer.D3.Canvas.Target){ + return 'R3.Renderer.D3.Canvas.Target'; + } + if (runtimeComponent instanceof R3.Renderer.D3.Canvas){ + return 'R3.Renderer.D3.Canvas'; + } + if (runtimeComponent instanceof R3.Renderer.D3){ + return 'R3.Renderer.D3'; + } + if (runtimeComponent instanceof R3.Renderer.D2){ + return 'R3.Renderer.D2'; + } + if (runtimeComponent instanceof R3.Renderer){ + return 'R3.Renderer'; + } + if (runtimeComponent instanceof R3.Query.Users){ + return 'R3.Query.Users'; + } + if (runtimeComponent instanceof R3.Query.UserDevices){ + return 'R3.Query.UserDevices'; + } + if (runtimeComponent instanceof R3.Query.Logins.VPN){ + return 'R3.Query.Logins.VPN'; + } + if (runtimeComponent instanceof R3.Query.Logins.Devices){ + return 'R3.Query.Logins.Devices'; + } + if (runtimeComponent instanceof R3.Query.Logins.Applications){ + return 'R3.Query.Logins.Applications'; + } + if (runtimeComponent instanceof R3.Query.Logins){ + return 'R3.Query.Logins'; + } + if (runtimeComponent instanceof R3.Query.Devices.Unknown){ + return 'R3.Query.Devices.Unknown'; + } + if (runtimeComponent instanceof R3.Query.Devices.SQL){ + return 'R3.Query.Devices.SQL'; + } + if (runtimeComponent instanceof R3.Query.Devices.Known){ + return 'R3.Query.Devices.Known'; + } + if (runtimeComponent instanceof R3.Query.Devices){ + return 'R3.Query.Devices'; + } + if (runtimeComponent instanceof R3.Query.Alerts.Timeseries){ + return 'R3.Query.Alerts.Timeseries'; + } + if (runtimeComponent instanceof R3.Query.Alerts.Summary){ + return 'R3.Query.Alerts.Summary'; + } + if (runtimeComponent instanceof R3.Query.Alerts.List){ + return 'R3.Query.Alerts.List'; + } + if (runtimeComponent instanceof R3.Query.Alerts.FirstTimeLogin.VPN){ + return 'R3.Query.Alerts.FirstTimeLogin.VPN'; + } + if (runtimeComponent instanceof R3.Query.Alerts.FirstTimeLogin.Devices){ + return 'R3.Query.Alerts.FirstTimeLogin.Devices'; + } + if (runtimeComponent instanceof R3.Query.Alerts.FirstTimeLogin.Applications){ + return 'R3.Query.Alerts.FirstTimeLogin.Applications'; + } + if (runtimeComponent instanceof R3.Query.Alerts.FirstTimeLogin){ + return 'R3.Query.Alerts.FirstTimeLogin'; + } + if (runtimeComponent instanceof R3.Query.Alerts.Buckets){ + return 'R3.Query.Alerts.Buckets'; + } + if (runtimeComponent instanceof R3.Query.Alerts){ + return 'R3.Query.Alerts'; + } + if (runtimeComponent instanceof R3.Query){ + return 'R3.Query'; + } + if (runtimeComponent instanceof R3.Quaternion.Points){ + return 'R3.Quaternion.Points'; + } + if (runtimeComponent instanceof R3.Quaternion){ + return 'R3.Quaternion'; + } + if (runtimeComponent instanceof R3.Project.D3.VR){ + return 'R3.Project.D3.VR'; + } + if (runtimeComponent instanceof R3.Project.D3){ + return 'R3.Project.D3'; + } + if (runtimeComponent instanceof R3.Project.D2){ + return 'R3.Project.D2'; + } + if (runtimeComponent instanceof R3.Project){ + return 'R3.Project'; + } + if (runtimeComponent instanceof R3.Plane){ + return 'R3.Plane'; + } + if (runtimeComponent instanceof R3.Mouse){ + return 'R3.Mouse'; + } + if (runtimeComponent instanceof R3.Matrix4){ + return 'R3.Matrix4'; + } + if (runtimeComponent instanceof R3.Image){ + return 'R3.Image'; + } + if (runtimeComponent instanceof R3.Group){ + return 'R3.Group'; + } + if (runtimeComponent instanceof R3.Graph.Table){ + return 'R3.Graph.Table'; + } + if (runtimeComponent instanceof R3.Graph.Metric){ + return 'R3.Graph.Metric'; + } + if (runtimeComponent instanceof R3.Graph.Barchart.Stacked){ + return 'R3.Graph.Barchart.Stacked'; + } + if (runtimeComponent instanceof R3.Graph.Barchart){ + return 'R3.Graph.Barchart'; + } + if (runtimeComponent instanceof R3.Graph){ + return 'R3.Graph'; + } + if (runtimeComponent instanceof R3.Font){ + return 'R3.Font'; + } + if (runtimeComponent instanceof R3.Entity){ + return 'R3.Entity'; + } + if (runtimeComponent instanceof R3.DrawRange){ + return 'R3.DrawRange'; + } + if (runtimeComponent instanceof R3.DomElement){ + return 'R3.DomElement'; + } + if (runtimeComponent instanceof R3.D3.Viewport.ZoomedAspect){ + return 'R3.D3.Viewport.ZoomedAspect'; + } + if (runtimeComponent instanceof R3.D3.Viewport.FixedAspect.VR){ + return 'R3.D3.Viewport.FixedAspect.VR'; + } + if (runtimeComponent instanceof R3.D3.Viewport.FixedAspect){ + return 'R3.D3.Viewport.FixedAspect'; + } + if (runtimeComponent instanceof R3.D3.Viewport){ + return 'R3.D3.Viewport'; + } + if (runtimeComponent instanceof R3.D3.Vertex){ + return 'R3.D3.Vertex'; + } + if (runtimeComponent instanceof R3.D3.Texture.Image){ + return 'R3.D3.Texture.Image'; + } + if (runtimeComponent instanceof R3.D3.Texture.Cube){ + return 'R3.D3.Texture.Cube'; + } + if (runtimeComponent instanceof R3.D3.Texture.Canvas){ + return 'R3.D3.Texture.Canvas'; + } + if (runtimeComponent instanceof R3.D3.Texture){ + return 'R3.D3.Texture'; + } + if (runtimeComponent instanceof R3.D3.Text){ + return 'R3.D3.Text'; + } + if (runtimeComponent instanceof R3.D3.Spline){ + return 'R3.D3.Spline'; + } + if (runtimeComponent instanceof R3.D3.Solver){ + return 'R3.D3.Solver'; + } + if (runtimeComponent instanceof R3.D3.Skeleton){ + return 'R3.D3.Skeleton'; + } + if (runtimeComponent instanceof R3.D3.Shape.TriMesh){ + return 'R3.D3.Shape.TriMesh'; + } + if (runtimeComponent instanceof R3.D3.Shape.Sphere){ + return 'R3.D3.Shape.Sphere'; + } + if (runtimeComponent instanceof R3.D3.Shape.Plane){ + return 'R3.D3.Shape.Plane'; + } + if (runtimeComponent instanceof R3.D3.Shape.HeightMap){ + return 'R3.D3.Shape.HeightMap'; + } + if (runtimeComponent instanceof R3.D3.Shape.ConvexHull.Cylinder){ + return 'R3.D3.Shape.ConvexHull.Cylinder'; + } + if (runtimeComponent instanceof R3.D3.Shape.ConvexHull){ + return 'R3.D3.Shape.ConvexHull'; + } + if (runtimeComponent instanceof R3.D3.Shape.Box){ + return 'R3.D3.Shape.Box'; + } + if (runtimeComponent instanceof R3.D3.Shape){ + return 'R3.D3.Shape'; + } + if (runtimeComponent instanceof R3.D3.Shadow.Spot){ + return 'R3.D3.Shadow.Spot'; + } + if (runtimeComponent instanceof R3.D3.Shadow.Directional){ + return 'R3.D3.Shadow.Directional'; + } + if (runtimeComponent instanceof R3.D3.Shadow){ + return 'R3.D3.Shadow'; + } + if (runtimeComponent instanceof R3.D3.Shader.Vertex){ + return 'R3.D3.Shader.Vertex'; + } + if (runtimeComponent instanceof R3.D3.Shader.Fragment){ + return 'R3.D3.Shader.Fragment'; + } + if (runtimeComponent instanceof R3.D3.Shader){ + return 'R3.D3.Shader'; + } + if (runtimeComponent instanceof R3.D3.Scene){ + return 'R3.D3.Scene'; + } + if (runtimeComponent instanceof R3.D3.RigidBody){ + return 'R3.D3.RigidBody'; + } + if (runtimeComponent instanceof R3.D3.RenderTarget.Cube){ + return 'R3.D3.RenderTarget.Cube'; + } + if (runtimeComponent instanceof R3.D3.RenderTarget){ + return 'R3.D3.RenderTarget'; + } + if (runtimeComponent instanceof R3.D3.Raycaster){ + return 'R3.D3.Raycaster'; + } + if (runtimeComponent instanceof R3.D3.RaycastWheel){ + return 'R3.D3.RaycastWheel'; + } + if (runtimeComponent instanceof R3.D3.RaycastVehicle){ + return 'R3.D3.RaycastVehicle'; + } + if (runtimeComponent instanceof R3.D3.PhysicsWorld){ + return 'R3.D3.PhysicsWorld'; + } + if (runtimeComponent instanceof R3.D3.Pass.Render.SSAO){ + return 'R3.D3.Pass.Render.SSAO'; + } + if (runtimeComponent instanceof R3.D3.Pass.Render){ + return 'R3.D3.Pass.Render'; + } + if (runtimeComponent instanceof R3.D3.Pass.FXAA){ + return 'R3.D3.Pass.FXAA'; + } + if (runtimeComponent instanceof R3.D3.Pass.Copy){ + return 'R3.D3.Pass.Copy'; + } + if (runtimeComponent instanceof R3.D3.Pass.Bloom){ + return 'R3.D3.Pass.Bloom'; + } + if (runtimeComponent instanceof R3.D3.Pass){ + return 'R3.D3.Pass'; + } + if (runtimeComponent instanceof R3.D3.Mesh.Skeleton){ + return 'R3.D3.Mesh.Skeleton'; + } + if (runtimeComponent instanceof R3.D3.Mesh.Particle.Engine){ + return 'R3.D3.Mesh.Particle.Engine'; + } + if (runtimeComponent instanceof R3.D3.Mesh.Particle){ + return 'R3.D3.Mesh.Particle'; + } + if (runtimeComponent instanceof R3.D3.Mesh){ + return 'R3.D3.Mesh'; + } + if (runtimeComponent instanceof R3.D3.Material.Standard){ + return 'R3.D3.Material.Standard'; + } + if (runtimeComponent instanceof R3.D3.Material.Shader.Raw){ + return 'R3.D3.Material.Shader.Raw'; + } + if (runtimeComponent instanceof R3.D3.Material.Shader){ + return 'R3.D3.Material.Shader'; + } + if (runtimeComponent instanceof R3.D3.Material.Points){ + return 'R3.D3.Material.Points'; + } + if (runtimeComponent instanceof R3.D3.Material.Phong){ + return 'R3.D3.Material.Phong'; + } + if (runtimeComponent instanceof R3.D3.Material.Basic){ + return 'R3.D3.Material.Basic'; + } + if (runtimeComponent instanceof R3.D3.Material){ + return 'R3.D3.Material'; + } + if (runtimeComponent instanceof R3.D3.Light.Spot){ + return 'R3.D3.Light.Spot'; + } + if (runtimeComponent instanceof R3.D3.Light.RectArea){ + return 'R3.D3.Light.RectArea'; + } + if (runtimeComponent instanceof R3.D3.Light.Point){ + return 'R3.D3.Light.Point'; + } + if (runtimeComponent instanceof R3.D3.Light.Hemisphere){ + return 'R3.D3.Light.Hemisphere'; + } + if (runtimeComponent instanceof R3.D3.Light.Directional){ + return 'R3.D3.Light.Directional'; + } + if (runtimeComponent instanceof R3.D3.Light.Ambient){ + return 'R3.D3.Light.Ambient'; + } + if (runtimeComponent instanceof R3.D3.Light){ + return 'R3.D3.Light'; + } + if (runtimeComponent instanceof R3.D3.Helper){ + return 'R3.D3.Helper'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Wireframe){ + return 'R3.D3.Geometry.Normal.Wireframe'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Tube){ + return 'R3.D3.Geometry.Normal.Tube'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.TorusKnot){ + return 'R3.D3.Geometry.Normal.TorusKnot'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Torus){ + return 'R3.D3.Geometry.Normal.Torus'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Text){ + return 'R3.D3.Geometry.Normal.Text'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Tetrahedron){ + return 'R3.D3.Geometry.Normal.Tetrahedron'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Sphere){ + return 'R3.D3.Geometry.Normal.Sphere'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Shape){ + return 'R3.D3.Geometry.Normal.Shape'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Ring){ + return 'R3.D3.Geometry.Normal.Ring'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Polyhedron){ + return 'R3.D3.Geometry.Normal.Polyhedron'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Plane){ + return 'R3.D3.Geometry.Normal.Plane'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Parametric){ + return 'R3.D3.Geometry.Normal.Parametric'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Octahedron){ + return 'R3.D3.Geometry.Normal.Octahedron'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Lathe){ + return 'R3.D3.Geometry.Normal.Lathe'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Icosahedron){ + return 'R3.D3.Geometry.Normal.Icosahedron'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Extrude){ + return 'R3.D3.Geometry.Normal.Extrude'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Edges){ + return 'R3.D3.Geometry.Normal.Edges'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Dodecahedron){ + return 'R3.D3.Geometry.Normal.Dodecahedron'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Cylinder){ + return 'R3.D3.Geometry.Normal.Cylinder'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Cone){ + return 'R3.D3.Geometry.Normal.Cone'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Circle){ + return 'R3.D3.Geometry.Normal.Circle'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal.Box){ + return 'R3.D3.Geometry.Normal.Box'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Normal){ + return 'R3.D3.Geometry.Normal'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Tube){ + return 'R3.D3.Geometry.Buffer.Tube'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.TorusKnot){ + return 'R3.D3.Geometry.Buffer.TorusKnot'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Torus){ + return 'R3.D3.Geometry.Buffer.Torus'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Text){ + return 'R3.D3.Geometry.Buffer.Text'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Tetrahedron){ + return 'R3.D3.Geometry.Buffer.Tetrahedron'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Sphere){ + return 'R3.D3.Geometry.Buffer.Sphere'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Shape){ + return 'R3.D3.Geometry.Buffer.Shape'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Ring){ + return 'R3.D3.Geometry.Buffer.Ring'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Polyhedron){ + return 'R3.D3.Geometry.Buffer.Polyhedron'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Plane){ + return 'R3.D3.Geometry.Buffer.Plane'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Parametric){ + return 'R3.D3.Geometry.Buffer.Parametric'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Octahedron){ + return 'R3.D3.Geometry.Buffer.Octahedron'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Lathe){ + return 'R3.D3.Geometry.Buffer.Lathe'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Instanced){ + return 'R3.D3.Geometry.Buffer.Instanced'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Icosahedron){ + return 'R3.D3.Geometry.Buffer.Icosahedron'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Extrude){ + return 'R3.D3.Geometry.Buffer.Extrude'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Dodecahedron){ + return 'R3.D3.Geometry.Buffer.Dodecahedron'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Cylinder){ + return 'R3.D3.Geometry.Buffer.Cylinder'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Cone){ + return 'R3.D3.Geometry.Buffer.Cone'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Circle){ + return 'R3.D3.Geometry.Buffer.Circle'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer.Box){ + return 'R3.D3.Geometry.Buffer.Box'; + } + if (runtimeComponent instanceof R3.D3.Geometry.Buffer){ + return 'R3.D3.Geometry.Buffer'; + } + if (runtimeComponent instanceof R3.D3.Geometry){ + return 'R3.D3.Geometry'; + } + if (runtimeComponent instanceof R3.D3.FrictionMaterial){ + return 'R3.D3.FrictionMaterial'; + } + if (runtimeComponent instanceof R3.D3.FrictionContactMaterial){ + return 'R3.D3.FrictionContactMaterial'; + } + if (runtimeComponent instanceof R3.D3.Fog.Normal){ + return 'R3.D3.Fog.Normal'; + } + if (runtimeComponent instanceof R3.D3.Fog.Exp){ + return 'R3.D3.Fog.Exp'; + } + if (runtimeComponent instanceof R3.D3.Fog){ + return 'R3.D3.Fog'; + } + if (runtimeComponent instanceof R3.D3.Face.Graphics){ + return 'R3.D3.Face.Graphics'; + } + if (runtimeComponent instanceof R3.D3.Face){ + return 'R3.D3.Face'; + } + if (runtimeComponent instanceof R3.D3.Effect.Stereo){ + return 'R3.D3.Effect.Stereo'; + } + if (runtimeComponent instanceof R3.D3.Effect.Parallax){ + return 'R3.D3.Effect.Parallax'; + } + if (runtimeComponent instanceof R3.D3.Effect.Anaglyph){ + return 'R3.D3.Effect.Anaglyph'; + } + if (runtimeComponent instanceof R3.D3.Effect){ + return 'R3.D3.Effect'; + } + if (runtimeComponent instanceof R3.D3.Composer){ + return 'R3.D3.Composer'; + } + if (runtimeComponent instanceof R3.D3.Camera.Perspective.Stereo){ + return 'R3.D3.Camera.Perspective.Stereo'; + } + if (runtimeComponent instanceof R3.D3.Camera.Perspective){ + return 'R3.D3.Camera.Perspective'; + } + if (runtimeComponent instanceof R3.D3.Camera.Orthographic.ScaledAspect){ + return 'R3.D3.Camera.Orthographic.ScaledAspect'; + } + if (runtimeComponent instanceof R3.D3.Camera.Orthographic.FixedAspect){ + return 'R3.D3.Camera.Orthographic.FixedAspect'; + } + if (runtimeComponent instanceof R3.D3.Camera.Orthographic){ + return 'R3.D3.Camera.Orthographic'; + } + if (runtimeComponent instanceof R3.D3.Camera.Cube){ + return 'R3.D3.Camera.Cube'; + } + if (runtimeComponent instanceof R3.D3.Camera){ + return 'R3.D3.Camera'; + } + if (runtimeComponent instanceof R3.D3.Broadphase){ + return 'R3.D3.Broadphase'; + } + if (runtimeComponent instanceof R3.D3.BoneWeight){ + return 'R3.D3.BoneWeight'; + } + if (runtimeComponent instanceof R3.D3.Bone){ + return 'R3.D3.Bone'; + } + if (runtimeComponent instanceof R3.D3.Audio){ + return 'R3.D3.Audio'; + } + if (runtimeComponent instanceof R3.D3.Animation){ + return 'R3.D3.Animation'; + } + if (runtimeComponent instanceof R3.D3.Object){ + return 'R3.D3.Object'; + } + if (runtimeComponent instanceof R3.CustomCode){ + return 'R3.CustomCode'; + } + if (runtimeComponent instanceof R3.Curve.Path.D2.Shape){ + return 'R3.Curve.Path.D2.Shape'; + } + if (runtimeComponent instanceof R3.Curve.Path.D2){ + return 'R3.Curve.Path.D2'; + } + if (runtimeComponent instanceof R3.Curve.Path){ + return 'R3.Curve.Path'; + } + if (runtimeComponent instanceof R3.Curve){ + return 'R3.Curve'; + } + if (runtimeComponent instanceof R3.Controls.Touch){ + return 'R3.Controls.Touch'; + } + if (runtimeComponent instanceof R3.Controls.Mouse){ + return 'R3.Controls.Mouse'; + } + if (runtimeComponent instanceof R3.Controls.Keyboard){ + return 'R3.Controls.Keyboard'; + } + if (runtimeComponent instanceof R3.Controls.D3.Orbit){ + return 'R3.Controls.D3.Orbit'; + } + if (runtimeComponent instanceof R3.Controls.D3.FirstPerson){ + return 'R3.Controls.D3.FirstPerson'; + } + if (runtimeComponent instanceof R3.Controls.D3){ + return 'R3.Controls.D3'; + } + if (runtimeComponent instanceof R3.Controls){ + return 'R3.Controls'; + } + if (runtimeComponent instanceof R3.Color){ + return 'R3.Color'; + } + if (runtimeComponent instanceof R3.Clock){ + return 'R3.Clock'; + } + if (runtimeComponent instanceof R3.Canvas){ + return 'R3.Canvas'; + } + if (runtimeComponent instanceof R3.Box3){ + return 'R3.Box3'; + } + throw new Error('Invalid Runtime Constructor : ' + runtimeConstructor); + +}; diff --git a/src/r3-a-2-event-0.js b/src/r3-a-2-event-0.js new file mode 100644 index 0000000..d8784a2 --- /dev/null +++ b/src/r3-a-2-event-0.js @@ -0,0 +1,174 @@ +/** + * Event Core + * @constructor + */ +R3.Event = function() { +}; + +/** + * Some nice Events handling + * @type {{}} + */ +R3.Event.Subscriptions = {}; + +/** + * Subscribe to some events + * @param eventName + * @param callback + */ +R3.Event.prototype.subscribe = function( + eventName, + callback +) { + return R3.Event.Subscribe(eventName, callback.bind(this)); +}; + +/** + * Publish some event happened with some data + * @param eventName + * @param data + * @param clientCallback + * @param clientErrorCallback + * @returns {number} of callbacks executed + */ +R3.Event.prototype.emit = function( + eventName, + data, + clientCallback, + clientErrorCallback +) { + return R3.Event.Emit( + eventName, + data, + clientCallback, + clientErrorCallback + ); +}; + +/** + * Static Synchrnonous Event - Calls clientCallback directly after the event result is obtained + * @param eventId + * @param data + * @param clientCallback is executed ideally when the event completed + * @param clientErrorCallback + * @returns {number} of callbacks executed + * @constructor + */ +R3.Event.Emit = function( + eventId, + data, + clientCallback, + clientErrorCallback +) { + + if (R3.Event.Subscriptions.hasOwnProperty(eventId)) { + + var subscriptionIds = Object.keys(R3.Event.Subscriptions[eventId]); + + subscriptionIds.map( + function(subscriptionId) { + try { + var result = R3.Event.Subscriptions[eventId][subscriptionId](data); + + if (clientCallback) { + clientCallback(result); + } + + } catch (error) { + if (clientErrorCallback) { + clientErrorCallback(error); + } else { + console.error(error); + } + } + } + ) + } +}; + +/** + * Execute the functions which subscribe to this event, but don't process the client callback - the subscription function + * should execute the client callback + * @param eventId + * @param data + * @param clientCallback + * @param clientErrorCallback + * @returns {number} + * @constructor + */ +R3.Event.Async = function( + eventId, + data, + clientCallback, + clientErrorCallback +) { + if (R3.Event.Subscriptions.hasOwnProperty(eventId)) { + + var subscriptionIds = Object.keys(R3.Event.Subscriptions[eventId]); + + subscriptionIds.map( + function(subscriptionId) { + try { + R3.Event.Subscriptions[eventId][subscriptionId](data, clientCallback, clientErrorCallback); + } catch (error) { + if (clientErrorCallback) { + clientErrorCallback(error); + } else { + console.error(error); + } + } + } + ) + } +}; + +R3.Event.Subscribe = function( + eventName, + fn, +) { + /** + * Todo - maybe eventually store a boolean which indicates if the function has been executed + */ + var subscriptionId = R3.Utils.RandomId(10); + + if (R3.Event.Subscriptions.hasOwnProperty(eventName)) { + + if (R3.Event.Subscriptions[eventName][subscriptionId]) { + throw new Error('A component can only subscribe to a particular event ID once'); + } + + R3.Event.Subscriptions[eventName][subscriptionId] = fn; + } else { + R3.Event.Subscriptions[eventName] = {}; + R3.Event.Subscriptions[eventName][subscriptionId] = fn; + } + + /** + * Return a handle to the caller to allow us to unsubscribe to this event + */ + return { + fn: fn, + remove: function (eventId, subscriptionId) { + + return function () { + + /** + * Stop listening for this event from this component + */ + delete R3.Event.Subscriptions[eventId][subscriptionId]; + + /** + * If the length of listeners is 0, stop referencing this event + * @type {string[]} + */ + var listeners = Object.keys(R3.Event.Subscriptions[eventId]); + if (listeners.length === 0) { + delete R3.Event.Subscriptions[eventId]; + } + } + + }(eventName, subscriptionId), + subscriptionId : subscriptionId + }; + +}; \ No newline at end of file diff --git a/src/r3-a-2-event-1.js b/src/r3-a-2-event-1.js new file mode 100644 index 0000000..f575341 --- /dev/null +++ b/src/r3-a-2-event-1.js @@ -0,0 +1,254 @@ +R3.Event.AFTER_RENDER = 0x1; +R3.Event.AFTER_WINDOW_RESIZE = 0x2; +R3.Event.ANIMATE_TEXTURE_INSTANCE = 0x3; +R3.Event.ANIMATION_COMPILE_FAILED = 0x4; +R3.Event.ANIMATION_COMPILE_SUCCESS = 0x5; +R3.Event.ANIMATION_MESH_ADDED = 0x6; +R3.Event.ANIMATION_MESH_REMOVED = 0x7; +R3.Event.ARRAY_ITEM_ADDED = 0x8; +R3.Event.AUDIO_ENDED = 0x9; +R3.Event.BEFORE_RENDER = 0xa; +R3.Event.BEFORE_WINDOW_RESIZE = 0xb; +R3.Event.BLENDER_DATA_RECEIVED = 0xc; +R3.Event.BUILD_GUI = 0xd; +R3.Event.CANVAS_CHANGE = 0xe; +R3.Event.CANVAS_RESIZE = 0xf; +R3.Event.CAST_SOURCE_CHANGED = 0x10; +R3.Event.CLEAR_GUI = 0x11; +R3.Event.COMPILE_FAILED = 0x12; +R3.Event.COMPILE_SUCCESS = 0x13; +R3.Event.COMPONENTS_LINKED = 0x14; +R3.Event.COMPONENT_CLONED = 0x15; +R3.Event.COMPONENT_CREATED = 0x16; +R3.Event.COMPONENT_DELETED = 0x17; +R3.Event.COMPONENT_DOWNLOAD_COMPLETE = 0x18; +R3.Event.COMPONENT_LINKED = 0x19; +R3.Event.COMPONENT_REGISTER = 0x1a; +R3.Event.COMPONENT_REPLACED = 0x1b; +R3.Event.COMPONENT_SAVED = 0x1c; +R3.Event.COMPONENT_TYPES_UPDATE = 0x1d; +R3.Event.COMPONENT_UPDATE = 0x1e; +R3.Event.CONTINUE_ALL_AUDIO = 0x1f; +R3.Event.CONTROLS_CANVAS_CHANGE = 0x20; +R3.Event.DELETE_COMPONENT = 0x21; +R3.Event.DELETE_COMPONENT_ERROR = 0x22; +R3.Event.DONE_SAVING = 0x23; +R3.Event.ENGINE_FIRED_PARTICLES_ZERO = 0x24; +R3.Event.ENTITY_LOADED = 0x25; +R3.Event.EVENT_ID_UPDATE = 0x26; +R3.Event.EXCLUDE_FROM_ENVIRONMENT = 0x27; +R3.Event.FETCH_COMPONENTS = 0x28; +R3.Event.FETCH_COMPONENT_TYPES = 0x29; +R3.Event.GET_API_URL = 0x2a; +R3.Event.GET_APPLICATION_MODE = 0x2b; +R3.Event.GET_GRAPHICS_RUNTIME = 0x2c; +R3.Event.GET_PHYSICS_RUNTIME = 0x2d; +R3.Event.GET_PROJECT = 0x2e; +R3.Event.GET_PROJECTS = 0x2f; +R3.Event.GET_REMOTE_API_URL = 0x30; +R3.Event.GET_RENDER_CONFIGURATION = 0x31; +R3.Event.GET_RUNTIME = 0x32; +R3.Event.GET_USER = 0x33; +R3.Event.GET_WEBSOCKET_CONFIG = 0x34; +R3.Event.GET_WINDOW_SIZE = 0x35; +R3.Event.GUI_CREATED = 0x36; +R3.Event.GUI_REMOVED = 0x37; +R3.Event.IMAGE_UPLOAD_COMPLETE = 0x38; +R3.Event.INSTANCE_CLONED = 0x39; +R3.Event.INSTANCE_CREATED = 0x3a; +R3.Event.INSTANCE_DISPOSAL = 0x3b; +R3.Event.INSTANCE_LOADED = 0x3c; +R3.Event.KEY_DOWN = 0x3d; +R3.Event.KEY_UP = 0x3e; +R3.Event.LOAD_COMPONENT = 0x3f; +R3.Event.LOAD_COMPONENT_ERROR = 0x40; +R3.Event.LOAD_FONT = 0x41; +R3.Event.LOAD_IMAGE = 0x42; +R3.Event.LOAD_PROGRESS = 0x43; +R3.Event.MATERIAL_TEXTURES_UPDATED = 0x44; +R3.Event.MATERIAL_TYPE_CHANGED = 0x45; +R3.Event.MAXIMUM_PROJECTS = 0x46; +R3.Event.MESH_DESELECTED = 0x47; +R3.Event.MESH_FACE_DESELECTED = 0x48; +R3.Event.MESH_FACE_SELECTED = 0x49; +R3.Event.MESH_SELECTED = 0x4a; +R3.Event.MOUSE_DOWN = 0x4b; +R3.Event.MOUSE_MOVE = 0x4c; +R3.Event.MOUSE_UP = 0x4d; +R3.Event.MOUSE_WHEEL = 0x4e; +R3.Event.MUTE_AUDIO = 0x4f; +R3.Event.NAME_UPDATE = 0x50; +R3.Event.PARENT_SCENE_CHANGE = 0x51; +R3.Event.PARENT_WORLD_CHANGE = 0x52; +R3.Event.PAUSE = 0x53; +R3.Event.PAUSE_ALL_AUDIO = 0x54; +R3.Event.PLAY_AUDIO = 0x55; +R3.Event.PROJECT_LOADED = 0x56; +R3.Event.QUERY = 0x57; +R3.Event.QUERY_INTERVAL_CHANGE = 0x58; +R3.Event.QUERY_PARSED = 0x59; +R3.Event.RECEIVE_DESTINATION_CHANGED = 0x5a; +R3.Event.REGISTER_COMPONENT = 0x5b; +R3.Event.REGISTER_DEPENDENCIES = 0x5c; +R3.Event.REGISTER_UPDATE = 0x5d; +R3.Event.REMOVE_COMPONENT = 0x5e; +R3.Event.REMOVE_MESH = 0x5f; +R3.Event.REMOVE_PARTICLE_ENGINE = 0x60; +R3.Event.RENDERER_SIZE_CHANGE = 0x61; +R3.Event.REPLACE_COMPONENT = 0x62; +R3.Event.RESOLVE_DEPENDENCIES = 0x63; +R3.Event.RESTART = 0x64; +R3.Event.SAVE_COMPONENT = 0x65; +R3.Event.SAVE_COMPONENT_ERROR = 0x66; +R3.Event.SAVING = 0x67; +R3.Event.SELECTION_MODE_CHANGE = 0x68; +R3.Event.SIGN_IN = 0x69; +R3.Event.SIGN_OUT = 0x6a; +R3.Event.START = 0x6b; +R3.Event.STOP_ALL_AUDIO = 0x6c; +R3.Event.STOP_AUDIO = 0x6d; +R3.Event.STOP_VISUALIZE = 0x6e; +R3.Event.TEXTURE_ANIMATED_CHANGE = 0x6f; +R3.Event.TEXTURE_INSTANCE_UPDATED = 0x70; +R3.Event.TOUCH_CANCEL = 0x71; +R3.Event.TOUCH_END = 0x72; +R3.Event.TOUCH_MOVE = 0x73; +R3.Event.TOUCH_START = 0x74; +R3.Event.UNRESOLVED_DEPENDENCIES_UPDATE = 0x75; +R3.Event.VISUALIZE = 0x76; +R3.Event.WINDOW_RESIZE = 0x77; +R3.Event.MAX_EVENTS = 0x78; + +/** + * R3.Event.GetEventName + * @param eventId + * @returns {string} + * @constructor + */ +R3.Event.GetEventName = function(eventId) { + + switch(eventId) { + case 0x1 : return 'after_render'; + case 0x2 : return 'after_window_resize'; + case 0x3 : return 'animate_texture_instance'; + case 0x4 : return 'animation_compile_failed'; + case 0x5 : return 'animation_compile_success'; + case 0x6 : return 'animation_mesh_added'; + case 0x7 : return 'animation_mesh_removed'; + case 0x8 : return 'array_item_added'; + case 0x9 : return 'audio_ended'; + case 0xa : return 'before_render'; + case 0xb : return 'before_window_resize'; + case 0xc : return 'blender_data_received'; + case 0xd : return 'build_gui'; + case 0xe : return 'canvas_change'; + case 0xf : return 'canvas_resize'; + case 0x10 : return 'cast_source_changed'; + case 0x11 : return 'clear_gui'; + case 0x12 : return 'compile_failed'; + case 0x13 : return 'compile_success'; + case 0x14 : return 'components_linked'; + case 0x15 : return 'component_cloned'; + case 0x16 : return 'component_created'; + case 0x17 : return 'component_deleted'; + case 0x18 : return 'component_download_complete'; + case 0x19 : return 'component_linked'; + case 0x1a : return 'component_register'; + case 0x1b : return 'component_replaced'; + case 0x1c : return 'component_saved'; + case 0x1d : return 'component_types_update'; + case 0x1e : return 'component_update'; + case 0x1f : return 'continue_all_audio'; + case 0x20 : return 'controls_canvas_change'; + case 0x21 : return 'delete_component'; + case 0x22 : return 'delete_component_error'; + case 0x23 : return 'done_saving'; + case 0x24 : return 'engine_fired_particles_zero'; + case 0x25 : return 'entity_loaded'; + case 0x26 : return 'event_id_update'; + case 0x27 : return 'exclude_from_environment'; + case 0x28 : return 'fetch_components'; + case 0x29 : return 'fetch_component_types'; + case 0x2a : return 'get_api_url'; + case 0x2b : return 'get_application_mode'; + case 0x2c : return 'get_graphics_runtime'; + case 0x2d : return 'get_physics_runtime'; + case 0x2e : return 'get_project'; + case 0x2f : return 'get_projects'; + case 0x30 : return 'get_remote_api_url'; + case 0x31 : return 'get_render_configuration'; + case 0x32 : return 'get_runtime'; + case 0x33 : return 'get_user'; + case 0x34 : return 'get_websocket_config'; + case 0x35 : return 'get_window_size'; + case 0x36 : return 'gui_created'; + case 0x37 : return 'gui_removed'; + case 0x38 : return 'image_upload_complete'; + case 0x39 : return 'instance_cloned'; + case 0x3a : return 'instance_created'; + case 0x3b : return 'instance_disposal'; + case 0x3c : return 'instance_loaded'; + case 0x3d : return 'key_down'; + case 0x3e : return 'key_up'; + case 0x3f : return 'load_component'; + case 0x40 : return 'load_component_error'; + case 0x41 : return 'load_font'; + case 0x42 : return 'load_image'; + case 0x43 : return 'load_progress'; + case 0x44 : return 'material_textures_updated'; + case 0x45 : return 'material_type_changed'; + case 0x46 : return 'maximum_projects'; + case 0x47 : return 'mesh_deselected'; + case 0x48 : return 'mesh_face_deselected'; + case 0x49 : return 'mesh_face_selected'; + case 0x4a : return 'mesh_selected'; + case 0x4b : return 'mouse_down'; + case 0x4c : return 'mouse_move'; + case 0x4d : return 'mouse_up'; + case 0x4e : return 'mouse_wheel'; + case 0x4f : return 'mute_audio'; + case 0x50 : return 'name_update'; + case 0x51 : return 'parent_scene_change'; + case 0x52 : return 'parent_world_change'; + case 0x53 : return 'pause'; + case 0x54 : return 'pause_all_audio'; + case 0x55 : return 'play_audio'; + case 0x56 : return 'project_loaded'; + case 0x57 : return 'query'; + case 0x58 : return 'query_interval_change'; + case 0x59 : return 'query_parsed'; + case 0x5a : return 'receive_destination_changed'; + case 0x5b : return 'register_component'; + case 0x5c : return 'register_dependencies'; + case 0x5d : return 'register_update'; + case 0x5e : return 'remove_component'; + case 0x5f : return 'remove_mesh'; + case 0x60 : return 'remove_particle_engine'; + case 0x61 : return 'renderer_size_change'; + case 0x62 : return 'replace_component'; + case 0x63 : return 'resolve_dependencies'; + case 0x64 : return 'restart'; + case 0x65 : return 'save_component'; + case 0x66 : return 'save_component_error'; + case 0x67 : return 'saving'; + case 0x68 : return 'selection_mode_change'; + case 0x69 : return 'sign_in'; + case 0x6a : return 'sign_out'; + case 0x6b : return 'start'; + case 0x6c : return 'stop_all_audio'; + case 0x6d : return 'stop_audio'; + case 0x6e : return 'stop_visualize'; + case 0x6f : return 'texture_animated_change'; + case 0x70 : return 'texture_instance_updated'; + case 0x71 : return 'touch_cancel'; + case 0x72 : return 'touch_end'; + case 0x73 : return 'touch_move'; + case 0x74 : return 'touch_start'; + case 0x75 : return 'unresolved_dependencies_update'; + case 0x76 : return 'visualize'; + case 0x77 : return 'window_resize'; + default : + throw new Error('Event type not defined : ' + eventId); + } + +}; diff --git a/src/r3-a-3-api-component.js b/src/r3-a-3-api-component.js new file mode 100644 index 0000000..9421d7f --- /dev/null +++ b/src/r3-a-3-api-component.js @@ -0,0 +1,74 @@ +/** + * API Component Interface - Do not construct objects of this type directly + * @param parent + * @param id + * @param name + * @param register + * @param selected + * @param isPublic + * @constructor + */ +R3.API.Component = function( + parent, + id, + name, + register, + selected, + isPublic +) { + + if (R3.Utils.UndefinedOrNull(parent)) { + parent = null; + } + this.parent = parent; + + if (R3.Utils.UndefinedOrNull(id)) { + id = R3.Utils.RandomId(); + } + this.id = id; + + this.componentType = R3.GetComponentType(this); + + if (R3.Utils.UndefinedOrNull(name)) { + name = R3.Component.GetComponentFriendlyName(this.componentType) + ' (' + this.id + ')'; + } + this.name = name; + + if (R3.Utils.UndefinedOrNull(register)) { + register = true; + } + this.register = register; + + if (R3.Utils.UndefinedOrNull(selected)) { + selected = false; + } + this.selected = selected; + + if (R3.Utils.UndefinedOrNull(isPublic)) { + isPublic = true; + } + this.isPublic = isPublic; + +}; + +R3.API.Component.prototype.constructor = R3.API.Component; + +/** + * Wrapper for R3.Utils.GetFirstParent + * @param constructor + * @returns {*} + */ +R3.API.Component.prototype.getFirstParent = function(constructor) { + return R3.Utils.GetFirstParent(this, constructor); +}; + +/** + * Wrapper for R3.Utils.GetParent + * @param property + * @param index + * @param constructor + * @returns {*} + */ +R3.API.Component.getParent = function(property, index, constructor) { + return R3.Utils.GetParent(this, property, index, constructor); +}; diff --git a/src/r3-a-3-utils.js b/src/r3-a-3-utils.js new file mode 100644 index 0000000..25859f6 --- /dev/null +++ b/src/r3-a-3-utils.js @@ -0,0 +1,1243 @@ +R3.Utils = function() {}; + +/** + * Gets the first parent of the object which is an instance of constructor + * @param object + * @param constructor + * @returns {*} + * @constructor + */ +R3.Utils.GetFirstParent = function(object, constructor) { + + if (R3.Utils.UndefinedOrNull(constructor)) { + throw new Error('You need to specify a constructor'); + } + + if (object.parent === null) { + return null; + } + + if (object.parent instanceof constructor) { + return object.parent; + } else { + return R3.Utils.GetFirstParent(object.parent, constructor); + } + +}; + +R3.Utils.SyntaxHighlight = function(json) { + if (typeof json != 'string') { + json = JSON.stringify(json, undefined, 2); + } + json = json.replace(/&/g, '&').replace(//g, '>'); + return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { + var cls = 'number'; + if (/^"/.test(match)) { + if (/:$/.test(match)) { + cls = 'key'; + } else { + cls = 'string'; + } + } else if (/true|false/.test(match)) { + cls = 'boolean'; + } else if (/null/.test(match)) { + cls = 'null'; + } + return '' + match + ''; + }); +}; + +R3.Utils.GetParentProject = function(component) { + + if (R3.Utils.UndefinedOrNull(component.parent)) { + throw new Error('Parent not found'); + } + + if (component.parent instanceof R3.Project) { + return component.parent; + } + + return R3.Utils.GetParentProject(component.parent); +}; + +R3.Utils.GetParents = function(component, parents) { + + if (R3.Utils.UndefinedOrNull(parents)) { + parents = []; + } + + if (R3.Utils.UndefinedOrNull(component.parent)) { + return parents; + } + + parents.push(component.parent); + + return R3.Utils.GetParents(component.parent, parents); + +}; + +/** + * @return {boolean} + */ +R3.Utils.Instance = function(component) { + return R3.Utils.Defined(component) && R3.Utils.Defined(component.instance); +}; + +/** + * R3.Utils.RemoveFromSelect + * @param select + * @param id + * @returns {boolean} + * @constructor + */ +R3.Utils.RemoveFromSelect = function(select, id) { + + var i; + + for (i = 0; i < select.options.length; i++) { + if (select.options[i].value === id) { + select.remove(i); + return true; + } + } + return false; +}; + +/** + * R3.Utils.GetSelectIndex + * + * Get the select index of given id + * + * @param select + * @param id + * @returns boolean true if successful + * + * @constructor + */ +R3.Utils.SetSelectIndex = function(select, id) { + + var i; + + for (i = 0; i < select.options.length; i++) { + if (select.options[i].value === id) { + select.selectedIndex = i; + return true; + } + } + return false; +}; + +R3.Utils.SortSelect = function(select) { + + var tmp = []; + var i; + + for (i = 1; i < select.options.length; i++) { + tmp[i-1] = []; + tmp[i-1][0] = select.options[i].text; + tmp[i-1][1] = select.options[i].value; + } + + tmp.sort(); + + select.options = [select.options[0]]; + + for (i = 0; i < tmp.length; i++) { + select.options[i+1] = new Option(tmp[i][0], tmp[i][1]); + } + + return; +}; + +/** + * Gets the parent of object whith property of optional type constructor. If index is specified, get the parent of the + * object with property[index] - which means the property should be an array + * @param object + * @param property + * @param index + * @param constructor + * @returns {*} + * @constructor + */ +R3.Utils.GetParent = function(object, property, index, constructor) { + + if (R3.Utils.UndefinedOrNull(constructor)) { + constructor = null; + } + + if (R3.Utils.UndefinedOrNull(index)) { + index = null; + } + + if (object.parent) { + /** + * Parent defined + */ + if (object.parent.hasOwnProperty(property)) { + + if (constructor) { + + if (index) { + + if (object.parent[property][index] instanceof constructor) { + return object.parent[property][index]; + } else { + + if (typeof object.parent.getParent === 'function') { + return object.parent.getParent(property, index, constructor); + } else { + console.warn('getParent not defined on API object : ' + object.parent + ' - you should avoid having these messsages'); + return null; + } + } + + } else { + if (object.parent[property] instanceof constructor) { + return object.parent[property]; + } else { + + if (typeof object.parent.getParent === 'function') { + return object.parent.getParent(property, index, constructor); + } else { + console.warn('getParent not defined on API object : ' + object.parent + ' - you should avoid having these messsages'); + return null; + } + + } + } + + } else { + + if (index) { + return object.parent[property][index]; + } else { + return object.parent[property]; + } + + } + } else { + + /** + * This parent does not have the property - go a level higher + */ + if (typeof object.parent.getParent === 'function') { + return object.parent.getParent(property, index, constructor); + } else { + console.warn('getParent not defined on API object : ' + object.parent + ' - you should avoid having these messsages'); + return null; + } + } + + } else { + /** + * No parent defined + */ + console.warn('property : ' + property + ' of type ' + constructor + ' was not found in the parent chain'); + return null; + } + +}; + + +/** + * Strips image extension from given path + * @param imagePath + * @constructor + */ +R3.Utils.StripImageExtension = function(imagePath) { + return imagePath.replace(/(\.png$|\.gif$|\.jpeg$|\.jpg$)/,'') +}; + +/** + * Returns true if unloaded + * @param component + * @returns {boolean} + * @constructor + */ +R3.Utils.Unloaded = function(component) { + if ( + R3.Utils.UndefinedOrNull(component) || + R3.Utils.UndefinedOrNull(component.instance) + ) { + return true; + } + + return false; +}; + +/** + * + * @param component + * @returns {boolean} + * @constructor + */ +R3.Utils.Loaded = function(component) { + if (component && component.instance) { + return true; + } + + return false; +}; + +R3.Utils.BuildVectorSource = function(result, name, dimension) { + + if (dimension === 2) { + result[name] = {}; + result[name].x = false; + result[name].y = false; + return; + } + + if (dimension === 3) { + result[name] = {}; + result[name].x = false; + result[name].y = false; + result[name].y = false; + return; + } + + if (dimension === 4) { + result[name] = {}; + result[name].x = false; + result[name].y = false; + result[name].z = false; + result[name].w = false; + return; + } + + console.warn('unknown dimension : ' + dimension); +}; + +/** + * Returns all 'instances' of the array, or null if an 'instance' is undefined + * @constructor + * @param array + */ +R3.Utils.GetArrayInstances = function(array) { + return array.reduce( + function(result, object) { + + if (result === null) { + return result; + } + + if (R3.Utils.UndefinedOrNull(object.instance)) { + result = null; + } else { + result.push(object.instance); + } + + return result; + }, + [] + ); +}; + +R3.Utils.SortFacesByMaterialIndex = function(faces) { + + /** + * Sorts faces according to material index because later we will create + * groups for each vertice group + */ + faces.sort(function(a, b) { + + if (a.materialIndex < b.materialIndex) { + return -1; + } + + if (a.materialIndex > b.materialIndex) { + return 1; + } + + return 0; + }); + + return faces; +}; + +R3.Utils.BuildQuaternionSource = function(result, name) { + result[name] = {}; + result[name].axis = {}; + result[name].axis.x = false; + result[name].axis.y = false; + result[name].axis.z = false; + result[name].angle = false; + result[name].x = false; + result[name].y = false; + result[name].z = false; + result[name].w = false; +}; + +R3.Utils.ObjectPropertiesAsBoolean = function(object) { + return Object.keys(object).reduce( + function(result, propertyId) { + + if (typeof object[propertyId] === 'function') { + return result; + } + + result[propertyId] = false; + + // if (object[propertyId] instanceof R3.Vector2) { + // R3.Utils.BuildVectorSource(result, propertyId, 2); + // } + // + // if (object[propertyId] instanceof R3.Vector3) { + // R3.Utils.BuildVectorSource(result, propertyId, 3); + // } + // + // if (object[propertyId] instanceof R3.Vector4) { + // R3.Utils.BuildVectorSource(result, propertyId, 4); + // } + // + // if (object[propertyId] instanceof R3.Quaternion) { + // R3.Utils.BuildQuaternionSource(result, propertyId); + // } + + return result; + + }.bind(this), + {} + ); +}; + +R3.Utils.GetRuntime = function() { + + var result = null; + + R3.Event.Emit( + R3.Event.GET_RUNTIME, + null, + function(runtime) { + result = runtime; + } + ); + + return result; +}; + +/** + * Returns the window size or null + * @returns {*} + * @constructor + */ +R3.Utils.GetWindowSize = function() { + + var size = null; + + R3.Event.Emit( + R3.Event.GET_WINDOW_SIZE, + null, + function(data) { + size = data; + }.bind(this) + ); + + return size; + +}; + +/** + * Convenience function to update object width and height members with window size + * @param object + * @constructor + */ +R3.Utils.UpdateWindowSize = function(object) { + var size = R3.Utils.GetWindowSize(); + object.width = size.width; + object.height = size.height; +}; + + +/** + * Returns id of object with the name if it exists in the array, otherwise null + * @param name + * @param array + * @returns {*} + * @constructor + */ +R3.Utils.ObjectIdWithNameInArray = function(name, array) { + + return array.reduce( + function(result, object) { + + if (result) { + return result; + } + + if (name === object.name) { + return object.id; + } + + return null; + }, + null + ); +}; + +R3.Utils.LoadIdsFromArrayToIdObject = function(array, idToObject) { + +}; + +R3.Utils.LoadIdsFromObjectToIdObject = function(object, idToObject) { + + +}; + +/** + * Gets random int exclusive of maximum but inclusive of minimum + * @param min + * @param max + * @returns {*} + * @constructor + */ +R3.Utils.GetRandomInt = function(min, max) { + min = Math.ceil(min); + max = Math.floor(max); + return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive +}; + +/** + * Gets random int inclusive of minimum and maximum + * @param min + * @param max + * @returns {*} + * @constructor + */ +R3.Utils.GetRandomIntInclusive = function(min, max) { + min = Math.ceil(min); + max = Math.floor(max); + return Math.floor(Math.random() * (max - min + 1)) + min; //The maximum is inclusive and the minimum is inclusive +}; + +R3.Utils.InterpolateArray = function(data, fitCount) { + + var linearInterpolate = function(before, after, atPoint) { + return before + (after - before) * atPoint; + }; + + var newData = []; + + var springFactor = Number((data.length - 1) / (fitCount - 1)); + + newData[0] = data[0]; // for new allocation + + for ( var i = 1; i < fitCount - 1; i++) { + var tmp = i * springFactor; + var before = Number(Math.floor(tmp)).toFixed(); + var after = Number(Math.ceil(tmp)).toFixed(); + var atPoint = tmp - before; + newData[i] = linearInterpolate(data[before], data[after], atPoint); + } + + newData[fitCount - 1] = data[data.length - 1]; // for new allocation + + return newData; +}; + +/** + * Undefined or null check + * @param variable + * @returns {boolean} + * @constructor + */ +R3.Utils.UndefinedOrNull = function( + variable +) { + return typeof variable === 'undefined' || variable === null; +}; + +/** + * The variable is not undefined and not null + * @param variable + * @returns {boolean} + * @constructor + */ +R3.Utils.Defined = function( + variable +) { + return typeof variable !== 'undefined' && variable !== null; +}; + +/** + * Gets function parameters + * @param fn + * @constructor + */ +R3.Utils.GetParameters = function(fn) { + + var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; + var FN_ARG_SPLIT = /,/; + var FN_ARG = /^\s*(_?)(.+?)\1\s*$/; + var STRIP_COMMENTS = /(\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s*=[^,\)]*(('(?:\\'|[^'\r\n])*')|("(?:\\"|[^"\r\n])*"))|(\s*=[^,\)]*))/mg; + + var parameters, + fnText, + argDecl; + + if (typeof fn !== 'function') { + parameters = []; + fnText = fn.toString().replace(STRIP_COMMENTS, ''); + argDecl = fnText.match(FN_ARGS); + argDecl[1].split(FN_ARG_SPLIT).forEach(function(arg) { + arg.replace(FN_ARG, function(all, underscore, name) { + parameters.push(name); + }); + }); + } else { + throw Error("not a function") + } + + return parameters; +}; + +/** + * Returns either an ID of the object or Null + * @param object + * @returns {null} + * @constructor + */ +R3.Utils.IdOrNull = function(object) { + if (R3.Utils.UndefinedOrNull(object)) { + return null; + } else { + if (R3.Utils.UndefinedOrNull(object.id)) { + console.warn('saving an object reference with no ID : ', object); + return null; + } + return object.id; + } +}; + +/** + * Limit a property to values between -pi and +pi + * @param property + * @param objectProperty + * @returns {{configurable?: boolean, enumerable?: boolean, value?, writable?: boolean, get?: Function, set?: Function}} + * @constructor + */ +R3.Utils.LimitToPI = function(property, objectProperty) { + + var store = objectProperty; + + return { + get : function() { + return store; + }, + set : function(value) { + while (value > 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 + */ +R3.Utils.IdArrayOrEmptyArray = function(array) { + if (R3.Utils.UndefinedOrNull(array)) { + return []; + } else { + + return array.map(function(item) { + + if (R3.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 + */ +R3.Utils.Link = function(propertyString, idToObject, parentObject, id) { + + if (!R3.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 + */ +R3.Utils.RandomId = function(length) { + + if (R3.Utils.UndefinedOrNull(length)) { + length = 10; + } + + return Math.random().toString(36).substr(2, length); +}; + +R3.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 R3.D3.Mesh + * @returns {*} + * @constructor + */ +R3.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) + */ +R3.Utils.ResetWindingOrder = function(faces, vertices) { + + var vertexList = new R3.API.Vector3.Points(); + + for (var v = 0; v < vertices.length; v++) { + vertexList.add(new R3.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 ( + R3.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 R3.D3.Face[] + * @param orientationEdge R3.API.Vector2 + * @returns {Array} + */ +R3.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 R3.API.Vector2 + * @param faces R3.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 R3.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 R3.D3.TriangleEdge( + triangle, + edge + ); + } + } + + return null; + } + + var toProcess = [ + new R3.D3.TriangleEdge( + new R3.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 R3.API.Vector2( + triangleEdge.triangle.v0index, + triangleEdge.triangle.v1index + ), + new R3.API.Vector2( + triangleEdge.triangle.v1index, + triangleEdge.triangle.v2index + ), + new R3.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 [] + */ +R3.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 R3.API.Quaternion.Points(); + + for (var i = 0; i < verticesFlat.length; i += 3) { + points.add(new R3.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; +}; + +R3.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); + } +}; + +R3.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; + } + ); +}; + +R3.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 + */ +R3.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 + */ +R3.Utils.IsEmpty = function(obj) { + return (Object.keys(obj).length === 0 && obj.constructor === Object); +}; + +R3.Utils.IsString = function(member) { + return (typeof member === 'string'); +}; + +R3.Utils.IsBoolean = function(member) { + return (member === true || member === false); +}; + +R3.Utils.IsColor = function(member) { + return (member instanceof R3.Color); +}; + +R3.Utils.IsNumber = function(member) { + return (typeof member === 'number'); +}; + +R3.Utils.IsVector2 = function(member) { + return ( + member instanceof R3.API.Vector2 || + member instanceof R3.Vector2 + ); +}; + +R3.Utils.IsVector3 = function(member) { + return ( + member instanceof R3.API.Vector3 || + member instanceof R3.Vector3 + ); +}; + +R3.Utils.IsVector4 = function(member) { + return ( + member instanceof R3.API.Vector4 || + member instanceof R3.Vector4 || + member instanceof R3.API.Quaternion || + member instanceof R3.Quaternion + ); +}; + +R3.Utils.IsObject = function(member) { + var type = typeof member; + return type === 'function' || type === 'object' && !!member; +}; + +/** + * @return {string} + */ +R3.Utils.LowerUnderscore = function(name) { + var string = name.toLowerCase().replace(/\s+/g, '_'); + string = string.replace(/-/g, '_'); + string = string.replace(/\_+/g, '_'); + return string; +}; + +R3.Utils.UpperCaseWordsSpaces = function(input) { + + var word = input.replace(/[-_]/g, ' '); + + word = word.replace(/\s+/, ' '); + + var words = word.split(' '); + + return words.reduce( + function(result, word) { + result += word[0].toUpperCase() + word.substr(1); + return result + ' '; + }, + '' + ).trim(); +}; + +/** + * @return {string} + */ +R3.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; +}; + +/** + * Returns Left Padded Text - ex. length 5, padchar 0, string abc = '00abc' + * @param length + * @param padChar + * @param string + * @returns {string} + * @constructor + */ +R3.Utils.PaddedText = function(length, padChar, string) { + + var pad = ""; + + for (var x = 0; x < length; x++) { + pad += padChar; + } + + return pad.substring(0, pad.length - string.length) + string; +}; \ No newline at end of file diff --git a/src/r3-a-4-component.js b/src/r3-a-4-component.js new file mode 100644 index 0000000..6df92c3 --- /dev/null +++ b/src/r3-a-4-component.js @@ -0,0 +1,1347 @@ +/** + * R3.Component is an R3.Event + * @constructor + */ +R3.Component = function() { + + R3.Event.call(this); + + if (R3.Utils.UndefinedOrNull(this.linkedComponents)) { + this.linkedComponents = {}; + } + + this.dependencies = []; + + this.loaded = false; + + /** + * Use below event subscriptions event to manage this component's idToObject + * @type {null} + */ + this.idToObject = {}; + + this.removeComponentSubscription = R3.Event.Subscribe( + R3.Event.REMOVE_COMPONENT, + this.removeComponent.bind(this) + ); + + this.instanceCreatedSubscription = R3.Event.Subscribe( + R3.Event.INSTANCE_CREATED, + this.instanceCreated.bind(this) + ); + + /** + * This component, no doubt - is a parent to some other components. + * We register this component with the EntityManager, so it can link the parent property of all + * this component's child components to this + */ + + R3.Event.Emit( + R3.Event.REGISTER_COMPONENT, + this + ); + + this.buildVectoredComponents(); + + this.buildLinkedComponents(); + + /** + * At this point we can can *NOT* be sure that this component is fully linked, loaded, and ready to go. + * builtLinkedComponents could be in the process of asynchronously stalling while waiting for some components to + * finish loading. - If you need to be sure all components are linked, loaded and ready to go - the entry point is + * this.performInstanceCreation() + */ + + + // this.linked = false; + // this.building = false; + +// + +// this.cloneNumber = 0; + +// this.isClone = false; + +// this.generateNewImageIds = false; + + // if (this.register) { + // this.emit( + // R3.Event.COMPONENT_REGISTER, + // { + // component : this + // } + // ); + // } + // + // if (this.dependencies.length === 0) { + // + // this.performInstanceCreation(); + // + // } else { + // this.emit( + // R3.Event.REGISTER_DEPENDENCIES, + // { + // component : this + // } + // ); + // } + +}; + +R3.Component.prototype = Object.create(R3.Event.prototype); +R3.Component.prototype.constructor = R3.Component; + +/** + * TODO: don't remove components which are still in use elsewhere - this is important to prevent 'register out + * of sync' messages + */ +R3.Component.prototype.remove = function() { + + Object.keys(this.idToObject).map( + function(componentId){ + + R3.Event.Emit( + R3.Event.REMOVE_COMPONENT, + { + component : this.idToObject[componentId] + } + ); + + }.bind(this) + ); + + R3.Event.Emit( + R3.Event.INSTANCE_DISPOSAL + ); + + delete this; + +}; + +R3.Component.prototype.removeComponent = function(data) { + + var component = data.component; + + /** + * We don't care about colors and vectors etc. for now + */ + if ( + component instanceof R3.Color || + component instanceof R3.Scalar || + component instanceof R3.Vector2 || + component instanceof R3.Vector3 || + component instanceof R3.Vector4 || + component instanceof R3.Matrix4 || + component instanceof R3.Quaternion + ) { + if (R3.Utils.Defined(this.idToObject[component.id])) { + delete this.idToObject[component.id]; + } + } + + /** + * Remove this component from our idToObject + */ + if (R3.Utils.Defined(this.idToObject[component.id])) { + + /** + * This is an interesting object for us - it could live in our linkedComponents + */ + for (var property in this.linkedComponents) { + if (this.linkedComponents.hasOwnProperty(property)) { + + if (this[property] instanceof Array) { + + this[property] = this[property].reduce( + function(result, object) { + if (object === component) { + /** + * No longer store this element + */ + } else { + result.push(object) + } + return result; + }, + [] + ); + + continue; + } + + if (this[property] === component) { + this[property] = null; + } + } + } + + /** + * Finally remove it from our idToObject + */ + delete this.idToObject[component.id]; + } + +}; + +/** + * R3.Component.prototype.instanceCreated + * Traverse all the parents of the component - if we are the parent of this component, add it to the idToObject + * object of this component. Then scan all the properties of this component, if one of them is this new component, + * also add it. + * @param data + */ +R3.Component.prototype.instanceCreated = function(data) { + + /** + * Ignore components already in our idToObject + */ + if (R3.Utils.Defined(this.idToObject[data.component.id])) { + return; + } + + /** + * Save a reference to ourselves + */ + if (data.component === this) { + this.idToObject[this.id] = this; + } + + /** + * Ignore components with no parent + */ + if (R3.Utils.UndefinedOrNull(data.component.parent)) { + return; + } + + /** + * Link the parent to the new Runtime object (it shares the same ID as the API component) + */ + if (data.component.parent.id === this.id) { + data.component.parent = this; + } + + /** + * Now discover the parents + */ + var parents = R3.Utils.GetParents(data.component); + + parents.map( + function(parent) { + if (parent === this) { + this.idToObject[data.component.id] = data.component; + } + }.bind(this) + ); + + /** + * Add all objects in our linkedComponents + */ + for (var property in this.linkedComponents) { + if (this.linkedComponents.hasOwnProperty(property)) { + + if (this[property] instanceof Array) { + + this[property].map( + function(object) { + if (object === data.component) { + this.idToObject[data.component.id] = data.component; + } + }.bind(this) + ); + + continue; + } + + if (this[property] === data.component) { + this.idToObject[data.component.id] = data.component; + } + } + } +}; + +R3.Component.prototype.buildVectoredComponents = function() { + for (var property in this) { + if (this.hasOwnProperty(property)) { + + if (property === 'parent') { + continue; + } + + if ( + this[property] instanceof R3.API.Scalar || + this[property] instanceof R3.API.Vector2 || + this[property] instanceof R3.API.Vector3 || + this[property] instanceof R3.API.Vector4 || + this[property] instanceof R3.API.Quaternion || + this[property] instanceof R3.API.Matrix4 || + this[property] instanceof R3.API.Color + ) { + var constructor = R3.GetConstructor(this[property]); + this[property] = new constructor(this[property]); + + // if (this[property] instanceof R3.Scalar) { + // this['scalar' + property] = this[property]; + // //this.__defineGetter__(property, function(_property){return function() { return this['scalar' + _property].value; }}(property).bind(this)); + // + // Object.defineProperty( + // this, + // property, + // { + // get: function(_property) { + // return function() { + // return this['scalar' + _property].value; + // }; + // }(property), + // set: function(_property) { + // return function(_value) { + // this['scalar' + _property].value = _value; + // }; + // }(property) + // } + // ); + // + // } + } + } + } +}; + +R3.Component.prototype.buildLinkedComponents = function() { + + /** + * Sanity Check + */ + if (R3.Utils.UndefinedOrNull(this.linkedComponents)) { + throw new Error(this.name + ' linkedComponents does not exist - this cannot happen'); + } + + /** + * By the time this function executes, we need to be sure we have the final list of this.linkedComponents + */ + for (var property in this.linkedComponents) { + + if (this.linkedComponents.hasOwnProperty(property)) { + + if (this.hasOwnProperty(property)) { + + /** + * Ignore null or undefined properties + */ + if (R3.Utils.UndefinedOrNull(this[property])) { + continue; + } + + /** + * Ignore properties which are already upgraded to runtime + */ + if (this[property] instanceof R3.Component) { + continue; + } + + /** + * Process Arrays first since they could also be considered as Objects + */ + if (this[property] instanceof Array) { + + /** + * We don't care about empty arrays + */ + if (this[property].length === 0) { + continue; + } + + /** + * Sanity check again - ensure our linked property is also an array and an array of length 1 + */ + var componentName = null; + + if (!(this.linkedComponents[property] instanceof Array)) { + componentName = R3.GetComponentName(this); + throw new Error(componentName + '.' + property + ' and ' + componentName + '.linkedComponents.' + property + ' type mismatch'); + } + + if (this.linkedComponents[property].length !== 1) { + componentName = R3.GetComponentName(this); + throw new Error(componentName + '.linkedObjects size should be 1'); + } + + /** + * Construct the runtime object if it is loaded + * The constructor *is NOT* the constructor of the 'linkedComponent' property - its the constructor of + * property + */ + + this[property] = this[property].reduce( + + function (component, _property) { + + return function (result, item, index) { + + if (typeof item === 'string') { + + /** + * This object is not loaded yet - we should notify (a storage system perhaps) that it should be loaded and add it as a dependency + */ + var dependencyString = R3.GetComponentName(component) + '.' + _property + '[' + index + ']' + '(' + item + ')'; + R3.Utils.PushUnique(component.dependencies, dependencyString); + + R3.Event.Async( + R3.Event.LOAD_COMPONENT, + { + componentId: item, + }, + function (__component, __property, __index, __id, __dependencyString) { + return function (rawComponent) { + + if (R3.Utils.UndefinedOrNull(__component[__property])) { + throw new Error('The component took too long to load and the component property was damaged: ' + R3.GetComponentName(__component) + '.' + __property); + } + + if (R3.Utils.UndefinedOrNull(__component[__property][__index])) { + throw new Error('The component took too long to load and the component property was damaged inside: ' + R3.GetComponentName(__component) + '.' + __property + '[' + __index + ']'); + } + + if (__component[__property][__index] !== __id) { + throw new Error('The component loaded however it no longer exists as an id: ' + R3.GetComponentName(__component) + '.' + __property + '[' + __index + '] !==' + __id); + } + + var Constructor = R3.GetConstructorFromComponentType(rawComponent.componentType); + + __component[__property][__index] = new Constructor(rawComponent); + + var deleteIndex = __component.dependencies.indexOf(__dependencyString); + + if (deleteIndex === -1) { + throw new Error('The dependency ' + __dependencyString + ' was removed during the time that the component was loading'); + } + + __component.dependencies = __component.dependencies.splice(deleteIndex, 1); + + if (__component.dependencies.length === 0) { + + __component.performInstanceCreation(); + + } + + } + }(component, _property, index, item, dependencyString), + function (__component, __property) { + return function (__error) { + console.error('Failed to load ' + R3.GetComponentName(__component) + '.' + __property + ' because of ' + __error); + }; + }(component, _property) + ); + + result.push(item); + return result; + + } + + /** + * Now check if this item is already a Component - if so, ignore it + */ + if (item instanceof R3.Component) { + result.push(item); + return result; + } + + /** + * Now check if it is an API Component - if so - upgrade it to runtime + * All runtime objects call their API constructor implicitly - so no need to call the api constructor + */ + var constructor = null; + + if (item instanceof R3.API.Component) { + + /** + * We have the possibility that this component has already been fully constructed + */ + var constructed = R3.EntityManager.Instance.findComponentById(item.id); + if (constructed) { + result.push(constructed); + } else { + constructor = R3.GetConstructor(item); + result.push(new constructor(item)); + } + + return result; + } + + /** + * This is a problem - we need to know the component type of this object because + * we cannot figure out what type of component this is from the linkedObjects property - + * since the linkedObjects[property] could be a pure virtual class + */ + if (item instanceof Object) { + + var componentType = item.componentType; + + if (R3.Utils.UndefinedOrNull(componentType)) { + throw new Error('You need to specify the component type if you want to pass in a pure Object') + } + + constructor = R3.GetConstructorFromComponentType(componentType); + result.push(new constructor(item)); + return result; + } + + throw new Error('Unhandled situation - could not process : ' + R3.GetComponentName(component) + '.' + _property + '[' + index + ']'); + + }; + + }(this, property), + [] + ); + + continue; + } + + /** + * Check if this is a straight-forward load of a component + */ + if (typeof this[property] === 'string') { + + /** + * This object is not loaded yet - we should notify (a storage system perhaps) that it should be loaded and add it as a dependency + */ + var dependencyString = R3.GetComponentName(this) + '.' + property + '(' + this[property] + ')'; + R3.Utils.PushUnique(this.dependencies, dependencyString); + + R3.Event.Async( + R3.Event.LOAD_COMPONENT, + { + componentId: this[property], + }, + function (__component, __property, __id, __dependencyString) { + + return function (rawComponent) { + + if (R3.Utils.UndefinedOrNull(__component[__property])) { + throw new Error('The component took too long to load and the component property was damaged: ' + R3.GetComponentName(__component) + '.' + __property); + } + + if (__component[__property] !== __id) { + throw new Error('The component loaded however it no longer exists as an id: ' + R3.GetComponentName(__component) + '.' + __property + ' !==' + __id); + } + + var Constructor = R3.GetConstructorFromComponentType(rawComponent.componentType); + + __component[__property] = new Constructor(rawComponent); + + var deleteIndex = __component.dependencies.indexOf(__dependencyString); + + if (deleteIndex === -1) { + throw new Error('The dependency ' + __dependencyString + ' was removed during the time that the component was loading'); + } + + __component.dependencies = __component.dependencies.splice(deleteIndex, 1); + + if (__component.dependencies.length === 0) { + __component.performInstanceCreation(); + } + + } + + }(this, property, this[property], dependencyString), + function (__component, __property) { + return function (__error) { + console.error('Failed to load ' + R3.GetComponentName(__component) + '.' + __property + ' because of ' + __error); + }; + }(this, property) + ); + + continue; + } + + var Constructor = null; + + /** + * Check if this is an API Component which needs to upgrade to a Runtime Component + * All runtime objects call their API constructor implicitly - so no need to call the api constructor + */ + if (this[property] instanceof R3.API.Component) { + + /** + * We have the possibility that this component has already been fully constructed + */ + var Constructed = R3.EntityManager.Instance.findComponentById(this[property].id); + if (Constructed) { + this[property] = Constructed; + } else { + Constructor = R3.GetConstructor(this[property]); + this[property] = new Constructor(this[property]); + } + + continue; + } + + /** + * If this is a normal Object, we need to know the componentType since linkedObjects[property] can be + * a pure virtual class + */ + if (this[property] instanceof Object) { + var componentType = this[property].componentType; + + if (R3.Utils.UndefinedOrNull(componentType)) { + throw new Error('You need to specify the component type if you want to pass in a pure Object') + } + + Constructor = R3.GetConstructorFromComponentType(componentType); + this[property] = new Constructor(this[property]); + continue; + } + + throw new Error('Unhandled situation - property is neither string, nor array nor object'); + } + } + } + + if (this.dependencies.length === 0) { + this.performInstanceCreation(); + } + +}; + +/** + * 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 + * Try to create the instance + * Error Log if failed + * Don't do anything if we are not fully linked + */ +R3.Component.prototype.performInstanceCreation = function() { + + this.linked = true; + + delete this.dependencies; + + this.createInstance(); +}; + +/** + * The mother of all createInstance. + */ +R3.Component.prototype.createInstance = function() { + + if (R3.Utils.UndefinedOrNull(this.instance)) { + throw new Error(R3.GetComponentName(this) + ' has no instance at time of createInstance'); + } + + R3.Event.Emit( + R3.Event.INSTANCE_CREATED, + { + component: this + } + ); + + /** + * idToObject can now be trusted + */ + + this.loaded = true; + + if (this instanceof R3.Project) { + R3.Event.Emit( + R3.Event.PROJECT_LOADED, + { + component:this + } + ) + } + + if (this instanceof R3.Entity) { + R3.Event.Emit( + R3.Event.ENTITY_LOADED, + { + component: this + } + ) + } + + /** + * Use this event to know that the object has now loaded and all 'INSTANCE_CREATED' events have been handled. + * The idToObject property of this component can now be trusted. + */ + R3.Event.Emit( + R3.Event.INSTANCE_LOADED, + { + component: this + } + ); +}; + +R3.Component.prototype.updateInstance = function(property) { + + if (property === 'id') { + console.warn('TODO: update id'); + return; + } + + if (property === 'name') { + console.warn('TODO: update name'); + return; + } + + if (property === 'parent') { + console.warn('TODO: update parent'); + return; + } + +}; + +/** + * R3.Component.prototype.updateFromInstance + * + * - Updates the component by its instance data + * + * @param property + */ +R3.Component.prototype.updateFromInstance = function(property) { + + if ( + this[property] instanceof R3.Color + ) { + this[property].r = this.instance[property].r; + this[property].g = this.instance[property].g; + this[property].b = this.instance[property].b; + this[property].a = this.instance[property].a; + return; + } + + if ( + this[property] instanceof R3.Vector2 + ) { + this[property].x = this.instance[property].x; + this[property].y = this.instance[property].y; + return; + } + + if ( + this[property] instanceof R3.Vector3 + ) { + this[property].x = this.instance[property].x; + this[property].y = this.instance[property].y; + this[property].z = this.instance[property].z; + return; + } + + if ( + this[property] instanceof R3.Vector4 || + this[property] instanceof R3.Quaternion + ) { + this[property].x = this.instance[property].x; + this[property].y = this.instance[property].y; + this[property].z = this.instance[property].z; + this[property].w = this.instance[property].w; + return; + } + + if ( + this[property] instanceof R3.Matrix4 + ) { + throw new Error('TODO : implement this code - no use case yet'); + } + + if (R3.Utils.IsObject(this[property])) { + throw new Error('TODO : update component object from instance object'); + } + + this[property] = this.instance[property]; +}; + +R3.Component.prototype.toString = function() { + return this.id; +}; + +R3.Component.prototype.getParentProject = function() { + + if (this instanceof R3.Project) { + return this; + } + + if (this.parent === null) { + return null; + } + + if (this.parent instanceof R3.Project) { + return this.parent; + } + + return this.parent.getParentProject(); + +}; + +/** + * Returns the runtime friendly name + * @param runtime + * @returns string + * @constructor + */ +R3.Component.GetRuntimeName = function(runtime) { + + if (runtime === R3.Runtime.GRAPHICS) { + return 'Graphics'; + } + + if (runtime === R3.Runtime.PHYSICS) { + return 'Physics'; + } + + if (runtime === R3.Runtime.GUI) { + return 'GUI'; + } + + if (runtime === R3.Runtime.STATISTICS) { + return 'Statistics'; + } + + if (runtime === R3.Runtime.SOCKETS) { + return 'Sockets'; + } + + if (runtime === R3.Runtime.CODER) { + return 'Coder'; + } + + return 'Default'; +}; + +/** + * Gets a friendly name for the component + * @param componentType + * @returns {string} + * @constructor + */ +R3.Component.GetComponentFriendlyName = function(componentType) { + + var name = R3.GetComponentInfo(componentType).name; + + name = name.replace('R3.D3.',''); + name = name.replace('R3.',''); + name = name.replace(/\./g, ' '); + + return name; +}; + +/** + * @return {null || Object} + */ +R3.Component.GetComponentRuntime = function(component) { + + return R3.GetComponentInfo(component.componentType).runtime; +}; + +R3.Component.prototype.initialize = function(apiComponent) { + + if (apiComponent instanceof R3.API.Component) { + + /** + * The API Constructor has already been called - lets not duplicate work and copy the properties over + */ + for (var property in apiComponent) { + if (apiComponent.hasOwnProperty(property)) { + this[property] = apiComponent[property]; + } + } + + return; + } + + var apiConstructor = R3.GetAPIConstructor(this); + + apiConstructor.call( + this, + apiComponent + ); + +}; + +R3.Component.prototype.getPropertyValue = function(item) { + + /** + * We found data that we need to process - here we have to pay attention. + * For linked objects - we only store the ID + */ + if (item instanceof R3.Component) { + return R3.Utils.IdOrNull(item); + } + + /** + * Handle colors, vectors and matrices - they are not components so they have their own toApiObject functions + */ + if ( + item instanceof R3.Color || + item instanceof R3.Vector2 || + item instanceof R3.Vector3 || + item instanceof R3.Vector4 || + item instanceof R3.Quaternion || + item instanceof R3.Matrix4 + ) { + return item.toApiObject(); + } + + /** + * If we get to this point and we still have an Object - we throw an error + */ + if (R3.Utils.IsObject(item)) { + return JSON.stringify(item); + } + + return item; +}; + +/** + * Returns all components of type 'constructor' - slower than queryComponents + * @param constructor + */ +R3.Component.prototype.findComponentsByConstructor = function(constructor) { + + return Object.keys(this.idToObject).reduce( + function(result, id) { + if (this.idToObject[id] instanceof constructor) { + result.push(this.idToObject[id]); + } + return result; + }.bind(this), + [] + ); + +}; + +/** + * Components are linked at runtime - for storing, we just store the ID + * @returns {*} + */ +R3.Component.prototype.toApiObject = function() { + + var info = R3.GetComponentInfo(this.componentType); + + var apiConstructor = info.apiConstructor; + + var apiObject = new apiConstructor(); + + for (var property in apiObject) { + + if (apiObject.hasOwnProperty(property)) { + + /** + * Check if the current component also has this property + */ + if (this.hasOwnProperty(property)) { + + if (this[property] instanceof R3.Runtime) { + + /** + * Check if this is a runtime object - we ignore those + */ + continue; + } + + /** + * Check if this property is an array of something + */ + if (this[property] instanceof Array) { + + /** + * Quick sanity check that the apiObject also thinks this is an array + */ + if (!apiObject[property] instanceof Array) { + throw new Error('The API Object ' + apiObject + ' does not seem to think ' + property + ' is an array'); + } + + /** + * Loop through the array - assign the contents of + * the array to the apiObject + */ + apiObject[property] = this[property].reduce( + function(result, item, index) { + + if (item instanceof R3.Runtime) { + throw new Error('Please don\'t store Runtime Objects in Arrays'); + } + + if (item instanceof Array) { + result[index] = item.reduce( + function (subResult, subItem) { + subResult.push(this.getPropertyValue(subItem)); + return subResult; + }.bind(this), + [] + ) + } else { + result.push(this.getPropertyValue(item)); + } + + return result; + + }.bind(this), + [] + ); + + } else { + + /** + * This is not an array, so get the proper value directly from the property + */ + apiObject[property] = this.getPropertyValue(this[property]); + } + } + } + } + + return apiObject; +}; + +/** + * Gets all children components of this Object (all linked objects only - no object references i.e. string ids) + * @returns {Array} + */ +// R3.Component.prototype.getChildrenComponents = function() { +// +// var components = []; +// +// Object.keys(this.idToObject).map( +// function(objectId) { +// if (this.id !== objectId) { +// components.push(this.idToObject[objectId]); +// } +// }.bind(this) +// ); +// +// return components; +// }; +// +// R3.Component.prototype.processComponent = function(object) { +// if (object instanceof R3.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 + */ +// R3.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.linkedComponents) { +// if ( +// this.linkedComponents.hasOwnProperty(property) && +// this.hasOwnProperty(property) && +// this[property] && +// property.indexOf('parent') !== 0 +// ) { +// +// if (this.linkedComponents[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 R3.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; +// }; + +R3.Component.prototype.generateNewIds = function() { + + // this.buildIdToObject(); + + var codeComponents = R3.EntityManager.Instance.queryComponents(R3.Component.CUSTOM_CODE); + + for (var property in this.idToObject) { + if (this.idToObject.hasOwnProperty(property)) { + + var oldId = this.idToObject[property].id; + var newId = R3.Utils.RandomId(); + + this.idToObject[property].id = newId; + this.idToObject[property].name = this.idToObject[property].name.replace(oldId,newId); + + if (this.generateNewImageIds) { + + // TODO: replace image filenames - but then also copy them server side? + if (this.idToObject[property].fileName) { + this.idToObject[property].fileName = this.idToObject[property].fileName.replace(oldId,newId); + } + } + + codeComponents.map(function(codeComponent){ + codeComponent.code = codeComponent.code.replace(oldId,newId); + }); + } + } + +}; + +// +// +// R3.Component.prototype.replace = function(componentType) { +// +// var replacement = R3.Component.Construct(componentType); +// +// R3.Event.Emit( +// R3.Event.REPLACE_COMPONENT, +// { +// current : this, +// replacement : replacement +// } +// ); +// +// if (this.parent && this.parent.loaded) { +// this.parent.addComponent(replacement); +// } +// +// this.remove(); +// +// R3.Event.Emit( +// R3.Event.COMPONENT_REPLACED +// ); +// }; + +// +// R3.Component.prototype.clone = function() { +// +// var apiObject = this.toApiObject(); +// +// this.cloneNumber += 1; +// +// apiObject.id = R3.Utils.RandomId(); +// +// apiObject.name = this.name + ' Clone (' + this.cloneNumber + ')'; +// +// var runtimeComponent = R3.Component.ConstructFromObject(apiObject); +// +// runtimeComponent.isClone = true; +// +// R3.Event.Emit( +// R3.Event.COMPONENT_CLONED, +// { +// parent : this, +// component : runtimeComponent +// } +// ); +// +// runtimeComponent.parent = null; +// +// return runtimeComponent; +// }; +// +// /** +// * Clones only the instance +// */ +// R3.Component.prototype.cloneInstance = function() { +// +// var clone = null; +// +// if ( +// this.instance && +// this.instance.clone && +// typeof (this.instance.clone === 'function')) { +// +// clone = this.instance.clone(); +// +// R3.Event.Emit( +// R3.Event.INSTANCE_CLONED, +// { +// component : this, +// instance : clone +// } +// ) +// } +// +// return clone; +// }; + +R3.Component.prototype.saveToRemoteAPI = function() { + this.save(true); +}; + +R3.Component.prototype.save = function(remote) { + + R3.Event.Emit( + R3.Event.SAVE_COMPONENT, + { + component : this, + remote : remote + }, + function success(result) { + console.log(result); + }, + function error(error) { + console.log(error); + } + ); + +}; + +/** + * @return {null|Object} + */ +// R3.Component.GetRuntimeObject = function(info) { +// +// var runtime = null; +// +// R3.Event.Emit( +// R3.Event.GET_RUNTIME, +// null, +// function(runtimeObject) { +// runtime = runtimeObject; +// } +// ); +// +// if (info.runtime instanceof R3.Runtime.Graphics) { +// +// if (R3.Utils.UndefinedOrNull(runtime.graphics)) { +// console.warn('no runtime graphics: ', info); +// return null; +// } +// +// return runtime.graphics; +// +// } else if (info.runtime === R3.Runtime.PHYSICS) { +// +// if (R3.Utils.UndefinedOrNull(runtime.physics)) { +// console.warn('no runtime physics ', info); +// return null; +// } +// +// return runtime.physics; +// +// } else if (info.runtime === R3.Runtime.GUI) { +// +// if (R3.Utils.UndefinedOrNull(runtime.gui)) { +// console.warn('no runtime gui ', info); +// return null; +// } +// +// return runtime.gui; +// +// } else if (info.runtime === R3.Runtime.SOCKETS) { +// +// if (R3.Utils.UndefinedOrNull(runtime.sockets)) { +// console.warn('no runtime sockets ', info); +// return null; +// } +// +// return runtime.sockets; +// +// } else if (info.runtime === R3.Runtime.STATISTICS) { +// +// if (R3.Utils.UndefinedOrNull(runtime.statistics)) { +// console.warn('no runtime statistics ', info); +// return null; +// } +// +// return runtime.statistics; +// +// } else if (info.runtime === R3.Runtime.DEFAULT) { +// +// return null; +// +// } else { +// throw new Error('unknown runtime object found: ' + info); +// } +// +// return null; +// }; + +// R3.Component.Construct = function(componentType) { +// +// var info = R3.GetComponentInfo(componentType); +// +// var componentClass = info.constructor; +// +// var runtime = R3.Component.GetRuntimeObject(info); +// +// if (runtime) { +// return new componentClass(runtime); +// } else { +// return new componentClass(); +// } +// +// }; + +R3.Component.ConstructFromObject = function(rawComponentObject) { + + var info = R3.GetComponentInfo(rawComponentObject.componentType); + + return new info.constructor(rawComponentObject); + +}; diff --git a/src/r3-api-box3.js b/src/r3-api-box3.js new file mode 100644 index 0000000..68658be --- /dev/null +++ b/src/r3-api-box3.js @@ -0,0 +1,39 @@ +/** + * R3.API.Box3 + * @param apiComponent + * @constructor + */ +R3.API.Box3 = function( + apiComponent +) { + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.min)) { + apiComponent.min = new R3.API.Vector3( + { + parent : this, + register : true + }, + 0, + 0, + 0 + ); + } + this.min = apiComponent.min; + + if (R3.Utils.UndefinedOrNull(apiComponent.max)) { + apiComponent.max = new R3.API.Vector3( + { + parent : this, + register : true + }, + 1, + 1, + 1 + ); + } + this.max = apiComponent.max; +}; + +R3.API.Box3.prototype = Object.create(R3.API.Component.prototype); +R3.API.Box3.prototype.constructor = R3.API.Box3; diff --git a/src/r3-api-canvas.js b/src/r3-api-canvas.js new file mode 100644 index 0000000..4fdc71b --- /dev/null +++ b/src/r3-api-canvas.js @@ -0,0 +1,60 @@ +/** + * R3.API.Canvas + * @param apiComponent + * @constructor + */ +R3.API.Canvas = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.autoUpdateSize)) { + apiComponent.autoUpdateSize = true; + } + this.autoUpdateSize = apiComponent.autoUpdateSize; + + if (R3.Utils.UndefinedOrNull(apiComponent.width)) { + apiComponent.width = 450; + } + this.width = apiComponent.width; + this.guiInfo.width = { + range: [0, 5120], + step: 1, + dp: 0 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.height)) { + apiComponent.height = 450; + } + this.height = apiComponent.height; + this.guiInfo.height = { + range: [0, 5120], + step: 1, + dp: 0 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.tabIndex)) { + apiComponent.tabIndex = 1; + } + this.tabIndex = apiComponent.tabIndex; + this.guiInfo.tabIndex = { + range: [0, 100], + step: 1, + dp: 0 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.texts)) { + apiComponent.texts = []; + } + this.texts = apiComponent.texts; + + if (R3.Utils.UndefinedOrNull(apiComponent.textBaseline)) { + apiComponent.textBaseline = 'middle'; + } + this.textBaseline = apiComponent.textBaseline; + +}; + +R3.API.Canvas.prototype = Object.create(R3.API.Component.prototype); +R3.API.Canvas.prototype.constructor = R3.API.Canvas; diff --git a/src/r3-api-clock.js b/src/r3-api-clock.js new file mode 100644 index 0000000..da57a2d --- /dev/null +++ b/src/r3-api-clock.js @@ -0,0 +1,20 @@ +/** + * R3.API.Clock + * @constructor + * @param apiComponent + */ +R3.API.Clock = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.delta)) { + apiComponent.delta = 0; + } + this.delta = apiComponent.delta; + +}; + +R3.API.Clock.prototype = Object.create(R3.API.Component.prototype); +R3.API.Clock.prototype.constructor = R3.API.Clock; diff --git a/src/r3-api-color.js b/src/r3-api-color.js new file mode 100644 index 0000000..9c23cd3 --- /dev/null +++ b/src/r3-api-color.js @@ -0,0 +1,35 @@ +/** + * API Color + * @param apiComponent + * @constructor + */ +R3.API.Color = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.r)) { + apiComponent.r = 1; + } + this.r = apiComponent.r; + + if (R3.Utils.UndefinedOrNull(apiComponent.g)) { + apiComponent.g = 1; + } + this.g = apiComponent.g; + + if (R3.Utils.UndefinedOrNull(apiComponent.b)) { + apiComponent.b = 1; + } + this.b = apiComponent.b; + + if (R3.Utils.UndefinedOrNull(apiComponent.a)) { + apiComponent.a = 0; + } + this.a = apiComponent.a; + +}; + +R3.API.Color.prototype = Object.create(R3.API.Component.prototype); +R3.API.Color.prototype.constructor = R3.API.Color; diff --git a/src/r3-api-controls-0.js b/src/r3-api-controls-0.js new file mode 100644 index 0000000..55a35a1 --- /dev/null +++ b/src/r3-api-controls-0.js @@ -0,0 +1,22 @@ +/** + * R3.API.Controls + * @param apiComponent + * + * @property canvas + * + * @constructor + */ +R3.API.Controls = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.canvas)) { + apiComponent.canvas = null; + } + this.canvas = apiComponent.canvas; +}; + +R3.API.Controls.prototype = Object.create(R3.API.Component.prototype); +R3.API.Controls.prototype.constructor = R3.API.Controls; diff --git a/src/r3-api-controls-d3-0.js b/src/r3-api-controls-d3-0.js new file mode 100644 index 0000000..36578e1 --- /dev/null +++ b/src/r3-api-controls-d3-0.js @@ -0,0 +1,34 @@ +/** + * R3.API.Controls.D3 + * @param apiComponent + * + * @property camera + * @property enabled + * + * @constructor + */ +R3.API.Controls.D3 = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__ + + R3.API.Controls.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.camera)) { + apiComponent.camera = null; + } + this.camera = apiComponent.camera; + + if (R3.Utils.UndefinedOrNull(apiComponent.enabled)) { + apiComponent.enabled = true; + } + this.enabled = apiComponent.enabled; + +}; + +R3.API.Controls.D3.prototype = Object.create(R3.API.Controls.prototype); +R3.API.Controls.D3.prototype.constructor = R3.API.Controls.D3; diff --git a/src/r3-api-controls-d3-firstPerson.js b/src/r3-api-controls-d3-firstPerson.js new file mode 100644 index 0000000..c28ca34 --- /dev/null +++ b/src/r3-api-controls-d3-firstPerson.js @@ -0,0 +1,84 @@ +/** + * R3.API.Controls.D3.FirstPerson + * @param apiComponent + * @constructor + */ +R3.API.Controls.D3.FirstPerson = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.movementSpeed)) { + apiComponent.movementSpeed = 1.0; + } + this.movementSpeed = apiComponent.movementSpeed; + + if (R3.Utils.UndefinedOrNull(apiComponent.lookSpeed)) { + apiComponent.lookSpeed = 0.005; + } + this.lookSpeed = apiComponent.lookSpeed; + + if (R3.Utils.UndefinedOrNull(apiComponent.lookVertical)) { + apiComponent.lookVertical = true; + } + this.lookVertical = apiComponent.lookVertical; + + if (R3.Utils.UndefinedOrNull(apiComponent.autoForward)) { + apiComponent.autoForward = false; + } + this.autoForward = apiComponent.autoForward; + + if (R3.Utils.UndefinedOrNull(apiComponent.activeLook)) { + apiComponent.activeLook = false; + } + this.activeLook = apiComponent.activeLook; + + if (R3.Utils.UndefinedOrNull(apiComponent.heightSpeed)) { + apiComponent.heightSpeed = false; + } + this.heightSpeed = apiComponent.heightSpeed; + + if (R3.Utils.UndefinedOrNull(apiComponent.heightCoef)) { + apiComponent.heightCoef = 1.0; + } + this.heightCoef = apiComponent.heightCoef; + + if (R3.Utils.UndefinedOrNull(apiComponent.heightMin)) { + apiComponent.heightMin = 0.0; + } + this.heightMin = apiComponent.heightMin; + + if (R3.Utils.UndefinedOrNull(apiComponent.heightMax)) { + apiComponent.heightMax = 1.0; + } + this.heightMax = apiComponent.heightMax; + + if (R3.Utils.UndefinedOrNull(apiComponent.constrainVertical)) { + apiComponent.constrainVertical = false; + } + this.constrainVertical = apiComponent.constrainVertical; + + if (R3.Utils.UndefinedOrNull(apiComponent.verticalMin)) { + apiComponent.verticalMin = 0; + } + this.verticalMin = apiComponent.verticalMin; + + if (R3.Utils.UndefinedOrNull(apiComponent.verticalMax)) { + apiComponent.verticalMax = Math.PI; + } + this.verticalMax = apiComponent.verticalMax; + + if (R3.Utils.UndefinedOrNull(apiComponent.autoSpeedFactor)) { + apiComponent.autoSpeedFactor = 0; + } + this.autoSpeedFactor = apiComponent.autoSpeedFactor; + + R3.API.Controls.D3.call( + this, + apiComponent + ); +}; + +R3.API.Controls.D3.FirstPerson.prototype = Object.create(R3.API.Controls.D3.prototype); +R3.API.Controls.D3.FirstPerson.prototype.constructor = R3.API.Controls.D3.FirstPerson; diff --git a/src/r3-api-controls-d3-orbit.js b/src/r3-api-controls-d3-orbit.js new file mode 100644 index 0000000..542386e --- /dev/null +++ b/src/r3-api-controls-d3-orbit.js @@ -0,0 +1,89 @@ +/** + * R3.API.Controls.D3.Orbit + * @param apiComponent + * @constructor + */ +R3.API.Controls.D3.Orbit = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.target)) { + apiComponent.target = null; + } + this.target = apiComponent.target; + + if (R3.Utils.UndefinedOrNull(apiComponent.minPolarAngle)) { + apiComponent.minPolarAngle = 0; + } + this.minPolarAngle = apiComponent.minPolarAngle; + + if (R3.Utils.UndefinedOrNull(apiComponent.maxPolarAngle)) { + apiComponent.maxPolarAngle = Math.PI; + } + this.maxPolarAngle = apiComponent.maxPolarAngle; + + if (R3.Utils.UndefinedOrNull(apiComponent.enableDamping)) { + apiComponent.enableDamping = false; + } + this.enableDamping = apiComponent.enableDamping; + + if (R3.Utils.UndefinedOrNull(apiComponent.dampingFactor)) { + apiComponent.dampingFactor = 0.25; + } + this.dampingFactor = apiComponent.dampingFactor; + + if (R3.Utils.UndefinedOrNull(apiComponent.enableZoom)) { + apiComponent.enableZoom = true; + } + this.enableZoom = apiComponent.enableZoom; + + if (R3.Utils.UndefinedOrNull(apiComponent.zoomSpeed)) { + apiComponent.zoomSpeed = 1.0; + } + this.zoomSpeed = apiComponent.zoomSpeed; + + if (R3.Utils.UndefinedOrNull(apiComponent.enableRotate)) { + apiComponent.enableRotate = true; + } + this.enableRotate = apiComponent.enableRotate; + + if (R3.Utils.UndefinedOrNull(apiComponent.rotateSpeed)) { + apiComponent.rotateSpeed = 1.0; + } + this.rotateSpeed = apiComponent.rotateSpeed; + + if (R3.Utils.UndefinedOrNull(apiComponent.enablePan)) { + apiComponent.enablePan = true; + } + this.enablePan = apiComponent.enablePan; + + if (R3.Utils.UndefinedOrNull(apiComponent.keyPanSpeed)) { + apiComponent.keyPanSpeed = 7.0; + } + this.keyPanSpeed = apiComponent.keyPanSpeed; + + if (R3.Utils.UndefinedOrNull(apiComponent.autoRotate)) { + apiComponent.autoRotate = false; + } + this.autoRotate = apiComponent.autoRotate; + + if (R3.Utils.UndefinedOrNull(apiComponent.autoRotateSpeed)) { + apiComponent.autoRotateSpeed = 2.0; + } + this.autoRotateSpeed = apiComponent.autoRotateSpeed; + + if (R3.Utils.UndefinedOrNull(apiComponent.enableKeys)) { + apiComponent.enableKeys = false; + } + this.enableKeys = apiComponent.enableKeys; + + R3.API.Controls.D3.call( + this, + apiComponent + ); +}; + +R3.API.Controls.D3.Orbit.prototype = Object.create(R3.API.Controls.D3.prototype); +R3.API.Controls.D3.Orbit.prototype.constructor = R3.API.Controls.D3.Orbit; diff --git a/src/r3-api-controls-keyboard.js b/src/r3-api-controls-keyboard.js new file mode 100644 index 0000000..653b390 --- /dev/null +++ b/src/r3-api-controls-keyboard.js @@ -0,0 +1,19 @@ +/** + * R3.API.Controls.Keyboard + * @param apiComponent + * @constructor + */ +R3.API.Controls.Keyboard = function( + apiComponent +) { + + __API_COMPONENT__; + + R3.API.Controls.call( + this, + apiComponent + ); +}; + +R3.API.Controls.Keyboard.prototype = Object.create(R3.API.Controls.prototype); +R3.API.Controls.Keyboard.prototype.constructor = R3.API.Controls.Keyboard; diff --git a/src/r3-api-controls-mouse.js b/src/r3-api-controls-mouse.js new file mode 100644 index 0000000..d94f5b5 --- /dev/null +++ b/src/r3-api-controls-mouse.js @@ -0,0 +1,19 @@ +/** + * R3.API.Controls.Mouse + * @param apiComponent + * @constructor + */ +R3.API.Controls.Mouse = function( + apiComponent +) { + + __API_COMPONENT__; + + R3.API.Controls.call( + this, + apiComponent + ); +}; + +R3.API.Controls.Mouse.prototype = Object.create(R3.API.Controls.prototype); +R3.API.Controls.Mouse.prototype.constructor = R3.API.Controls.Mouse; diff --git a/src/r3-api-controls-touch.js b/src/r3-api-controls-touch.js new file mode 100644 index 0000000..142af6c --- /dev/null +++ b/src/r3-api-controls-touch.js @@ -0,0 +1,28 @@ +/** + * R3.API.Controls.Touch + * @param apiComponent + * + * @property sensitivity + * + * @constructor + */ +R3.API.Controls.Touch = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.sensitivity)) { + apiComponent.sensitivity = 5; + } + this.sensitivity = apiComponent.sensitivity; + + R3.API.Controls.call( + this, + apiComponent + ); + +}; + +R3.API.Controls.Touch.prototype = Object.create(R3.API.Controls.prototype); +R3.API.Controls.Touch.prototype.constructor = R3.API.Controls.Touch; diff --git a/src/r3-api-curve-0.js b/src/r3-api-curve-0.js new file mode 100644 index 0000000..c180dab --- /dev/null +++ b/src/r3-api-curve-0.js @@ -0,0 +1,20 @@ +/** + * R3.API.Curve + * @param apiComponent + * @constructor + */ +R3.API.Curve = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.arcLenghDivisions)) { + apiComponent.arcLenghDivisions = 200; + } + this.arcLenghDivisions = apiComponent.arcLenghDivisions; + +}; + +R3.API.Curve.prototype = Object.create(R3.API.Curve.prototype); +R3.API.Curve.prototype.constructor = R3.API.Curve; diff --git a/src/r3-api-curve-path-0.js b/src/r3-api-curve-path-0.js new file mode 100644 index 0000000..7e34f71 --- /dev/null +++ b/src/r3-api-curve-path-0.js @@ -0,0 +1,36 @@ +/** + * R3.API.Curve.Path + * @constructor + * @param apiCurve + * @param curves + * @param autoClose + */ +R3.API.Curve.Path = function( + apiCurve, + curves, + autoClose +) { + if (R3.Utils.UndefinedOrNull(apiComponent.apiCurve)) { + apiComponent.apiCurve = {} + } + this.apiCurve = apiComponent.apiCurve; + + R3.API.Curve.call( + this, + apiCurve, + apiCurve.arcLenghDivisions + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.curves)) { + apiComponent.curves = []; + } + this.curves = apiComponent.curves; + + if (R3.Utils.UndefinedOrNull(apiComponent.autoClose)) { + apiComponent.autoClose = false; + } + this.autoClose = apiComponent.autoClose; +}; + +R3.API.Curve.Path.prototype = Object.create(R3.API.Curve.prototype); +R3.API.Curve.Path.prototype.constructor = R3.API.Curve.Path; diff --git a/src/r3-api-curve-path-d2-0.js b/src/r3-api-curve-path-d2-0.js new file mode 100644 index 0000000..3de4e79 --- /dev/null +++ b/src/r3-api-curve-path-d2-0.js @@ -0,0 +1,32 @@ +/** + * R3.API.Curve.Path.D2 + * @constructor + * @param apiCurvePath + * @param points + */ +R3.API.Curve.Path.D2 = function( + apiCurvePath, + points +) { + + if (R3.Utils.UndefinedOrNull(apiComponent.apiCurvePath)) { + apiComponent.apiCurvePath = {} + } + this.apiCurvePath = apiComponent.apiCurvePath; + + R3.API.Curve.Path.call( + this, + apiCurvePath, + apiCurvePath.curves, + apiCurvePath.autoClose + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.points)) { + apiComponent.points = []; + } + this.points = apiComponent.points; + +}; + +R3.API.Curve.Path.D2.prototype = Object.create(R3.API.Curve.Path.prototype); +R3.API.Curve.Path.D2.prototype.constructor = R3.API.Curve.Path.D2; diff --git a/src/r3-api-curve-path-d2-shape.js b/src/r3-api-curve-path-d2-shape.js new file mode 100644 index 0000000..1591d29 --- /dev/null +++ b/src/r3-api-curve-path-d2-shape.js @@ -0,0 +1,21 @@ +/** + * R3.API.Curve.Path.D2.Shape + * @constructor + * @param apiCurvePathD2 + */ +R3.API.Curve.Path.D2.Shape = function( + apiCurvePathD2 +) { + if (R3.Utils.UndefinedOrNull(apiComponent.apiCurvePathD2)) { + apiComponent.apiCurvePathD2 = {}; + } + + R3.API.Curve.Path.call( + this, + apiCurvePathD2, + apiCurvePathD2.points + ); +}; + +R3.API.Curve.Path.D2.Shape.prototype = Object.create(R3.API.Curve.Path.D2.prototype); +R3.API.Curve.Path.D2.Shape.prototype.constructor = R3.API.Curve.Path.D2.Shape; diff --git a/src/r3-api-customCode.js b/src/r3-api-customCode.js new file mode 100644 index 0000000..9dece80 --- /dev/null +++ b/src/r3-api-customCode.js @@ -0,0 +1,124 @@ +/** + * R3.API.CustomCode + * @param apiComponent + * @constructor + */ +R3.API.CustomCode = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.eventId)) { + apiComponent.eventId = R3.Event.KEY_UP; + } + this.eventId = apiComponent.eventId; + + if (R3.Utils.UndefinedOrNull(apiComponent.compiled)) { + apiComponent.compiled = true; + } + this.compiled = apiComponent.compiled; + + if (R3.Utils.UndefinedOrNull(apiComponent.domId)) { + apiComponent.domId = 'r3-code-editor'; + } + this.domId = apiComponent.domId; + + if (R3.Utils.UndefinedOrNull(apiComponent.code)) { + + if (this.eventId === R3.Event.BEFORE_RENDER) { + apiComponent.code = "var project = data;\n" + + "\n" + + "if (!project.loaded) {\n" + + "\treturn;\n" + + "}\n" + + "\n" + + "/**\n" + + " * Only respond to before_render events for my parent project\n" + + " */\n" + + "if (project !== this.getParentProject()) {\n" + + "\treturn;\n" + + "}\n" + + "\n" + + "if (!this.initialized) {\n" + + "\n" + + "\t/**\n" + + "\t * Set some initialization code here\n" + + "\t */\n" + + "\tthis.totalTime = 0;\n" + + "\tproject.cameras[1].position.y = 10;\n" + + "\n" + + "\tthis.initialized = true;\n" + + "}\n" + + "\n" + + "if (project.applicationMode === R3.API.Project.APPLICATION_MODE_RUN) {\n" + + "\n" + + "\tthis.totalTime += project.clock.delta;\n" + + "\t\n" + + "\tproject.cameras[1].position.x = 15 * Math.sin(this.totalTime * 0.1);\n" + + "\tproject.cameras[1].position.z = 15 * Math.cos(this.totalTime * 0.1);\n" + + "\tproject.cameras[1].lookAt.x = 0;\n" + + "\tproject.cameras[1].lookAt.y = 0;\n" + + "\tproject.cameras[1].lookAt.z = 0;\n" + + "\n" + + "\tproject.cameras[1].updateInstance('position');\n" + + "\tproject.cameras[1].updateInstance('lookAt');\n" + + "}\n" + + "\n" + + "return null;"; + } else if (this.eventId === R3.Event.PROJECT_LOADED) { + apiComponent.code = "var project = data.component;\n" + + "\n" + + "/**\n" + + " * Only respond to project loaded events for my parent project\n" + + " */\n" + + "if (project !== this.getParentProject()) {\n" + + "\treturn;\n" + + "}\n" + + "\n" + + "if (!this.initialized) {\n" + + "\n" + + "\t/**\n" + + "\t * Set some initialization code here\n" + + "\t */\n" + + "\tconsole.log(project.name + ' Loaded');" + + "\t\n" + + "\tthis.initialized = true;\n" + + "}\n" + + "\n" + + "\n" + + "return null;"; + } else { + apiComponent.code = "var project = this.getParentProject();\n" + + "\n" + + "if (!project || !project.loaded) {\n" + + "\treturn;\n" + + "}\n" + + "\n" + + "/**\n" + + " * Ignore events which don't belong to my project\n" + + " */\n" + + "if (project !== data.project) {\n" + + "\treturn;\n" + + "}\n" + + "\n" + + "if (!this.initialized) {\n" + + "\n" + + "\t/**\n" + + "\t * Set some initialization code here\n" + + "\t */\n" + + "\t\n" + + "\tthis.initialized = true;\n" + + "}\n" + + "\n" + + "\n" + + "return null;"; + } + + apiComponent.code += "\n\n//@ sourceURL=" + R3.Utils.LowerUnderscore(this.name) + ".js"; + } + this.code = apiComponent.code; +}; + +R3.API.CustomCode.prototype = Object.create(R3.API.Component.prototype); +R3.API.CustomCode.prototype.constructor = R3.API.CustomCode; diff --git a/src/r3-api-domElement.js b/src/r3-api-domElement.js new file mode 100644 index 0000000..5de3245 --- /dev/null +++ b/src/r3-api-domElement.js @@ -0,0 +1,20 @@ +/** + * API DomElement + * @param apiComponent + * @constructor + */ +R3.API.DomElement = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.domElementId)) { + apiComponent.domElementId = ''; + } + this.domElementId = apiComponent.domElementId; + +}; + +R3.API.DomElement.prototype = Object.create(R3.API.Component.prototype); +R3.API.DomElement.prototype.constructor = R3.API.DomElement; diff --git a/src/r3-api-drawRange.js b/src/r3-api-drawRange.js new file mode 100644 index 0000000..f3d8d4f --- /dev/null +++ b/src/r3-api-drawRange.js @@ -0,0 +1,25 @@ +/** + * R3.API.DrawRange + * @param apiComponent + * @constructor + */ +R3.API.DrawRange = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.start)) { + apiComponent.start = 0; + } + this.start = apiComponent.start; + + if (R3.Utils.UndefinedOrNull(apiComponent.count)) { + apiComponent.count = Infinity; + } + this.count = apiComponent.count; + +}; + +R3.API.DrawRange.prototype = Object.create(R3.API.Component.prototype); +R3.API.DrawRange.prototype.constructor = R3.API.DrawRange; diff --git a/src/r3-api-entity.js b/src/r3-api-entity.js new file mode 100644 index 0000000..ee9ef9b --- /dev/null +++ b/src/r3-api-entity.js @@ -0,0 +1,20 @@ +/** + * R3.API.Entity + * @param apiComponent + * @constructor + */ +R3.API.Entity = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.components)) { + apiComponent.components = []; + } + this.components = apiComponent.components; + +}; + +R3.API.Entity.prototype = Object.create(R3.API.Component.prototype); +R3.API.Entity.prototype.constructor = R3.API.Entity; diff --git a/src/r3-api-font.js b/src/r3-api-font.js new file mode 100644 index 0000000..dd622d4 --- /dev/null +++ b/src/r3-api-font.js @@ -0,0 +1,20 @@ +/** + * R3.API.Font + * @param apiComponent + * @constructor + */ +R3.API.Font = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.path)) { + apiComponent.path = ''; + } + this.path = apiComponent.path; + +}; + +R3.API.Font.prototype = Object.create(R3.API.Component.prototype); +R3.API.Font.prototype.constructor = R3.API.Font; diff --git a/src/r3-api-graph-0.js b/src/r3-api-graph-0.js new file mode 100644 index 0000000..50be83b --- /dev/null +++ b/src/r3-api-graph-0.js @@ -0,0 +1,23 @@ +/** + * R3.API.Graph + * @param apiComponent + * + * @property domElement + * + * @constructor + */ +R3.API.Graph = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.query)) { + apiComponent.query = null; + } + this.query = apiComponent.query; + +}; + +R3.API.Graph.prototype = Object.create(R3.API.Component.prototype); +R3.API.Graph.prototype.constructor = R3.API.Graph; diff --git a/src/r3-api-graph-barchart-0.js b/src/r3-api-graph-barchart-0.js new file mode 100644 index 0000000..b52d9b5 --- /dev/null +++ b/src/r3-api-graph-barchart-0.js @@ -0,0 +1,24 @@ +/** + * R3.API.Graph.Barchart + * @param apiComponent + * @constructor + */ +R3.API.Graph.Barchart = function( + apiComponent +) { + + R3.API.Graph.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.domElement)) { + apiComponent.domElement = null; + } + this.domElement = apiComponent.domElement; + +}; + +R3.API.Graph.Barchart.prototype = Object.create(R3.API.Graph.prototype); +R3.API.Graph.Barchart.prototype.constructor = R3.API.Graph.Barchart; + diff --git a/src/r3-api-graph-barchart-stacked.js b/src/r3-api-graph-barchart-stacked.js new file mode 100644 index 0000000..ae5a8bb --- /dev/null +++ b/src/r3-api-graph-barchart-stacked.js @@ -0,0 +1,23 @@ +/** + * R3.API.Graph.Barchart + * @param apiComponent + * @constructor + */ +R3.API.Graph.Barchart.Stacked = function( + apiComponent +) { + + R3.API.Graph.Barchart.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.domElement)) { + apiComponent.domElement = null; + } + this.domElement = apiComponent.domElement; + +}; + +R3.API.Graph.Barchart.Stacked.prototype = Object.create(R3.API.Graph.Barchart.prototype); +R3.API.Graph.Barchart.Stacked.prototype.constructor = R3.API.Graph.Barchart.Stacked; diff --git a/src/r3-api-graph-metric.js b/src/r3-api-graph-metric.js new file mode 100644 index 0000000..5c9a63a --- /dev/null +++ b/src/r3-api-graph-metric.js @@ -0,0 +1,23 @@ +/** + * R3.API.Graph.Metric + * @param apiComponent + * @constructor + */ +R3.API.Graph.Metric = function( + apiComponent +) { + + R3.API.Graph.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.domElements)) { + apiComponent.domElements = []; + } + this.domElements = apiComponent.domElements; + +}; + +R3.API.Graph.Metric.prototype = Object.create(R3.API.Graph.prototype); +R3.API.Graph.Metric.prototype.constructor = R3.API.Graph.Metric; diff --git a/src/r3-api-graph-table.js b/src/r3-api-graph-table.js new file mode 100644 index 0000000..54b528f --- /dev/null +++ b/src/r3-api-graph-table.js @@ -0,0 +1,38 @@ +/** + * R3.API.Graph.Table + * @param apiComponent + * @constructor + */ +R3.API.Graph.Table = function( + apiComponent +) { + + R3.API.Graph.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.domElement)) { + apiComponent.domElement = null; + } + this.domElement = apiComponent.domElement; + + if (R3.Utils.UndefinedOrNull(apiComponent.columns)) { + apiComponent.columns = []; + } + this.columns = apiComponent.columns; + + if (R3.Utils.UndefinedOrNull(apiComponent.rows)) { + apiComponent.rows = []; + } + this.rows = apiComponent.rows; + + if (R3.Utils.UndefinedOrNull(apiComponent.pageSize)) { + apiComponent.pageSize = 10; + } + this.pageSize = apiComponent.pageSize; + +}; + +R3.API.Graph.Table.prototype = Object.create(R3.API.Graph.prototype); +R3.API.Graph.Table.prototype.constructor = R3.API.Graph.Table; diff --git a/src/r3-api-group.js b/src/r3-api-group.js new file mode 100644 index 0000000..dcad033 --- /dev/null +++ b/src/r3-api-group.js @@ -0,0 +1,29 @@ +/** + * R3.API.Group + * @param apiComponent + * @constructor + */ +R3.API.Group = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.start)) { + apiComponent.start = 0; + } + this.start = apiComponent.start; + + if (R3.Utils.UndefinedOrNull(apiComponent.count)) { + apiComponent.count = 0; + } + this.count = apiComponent.count; + + if (R3.Utils.UndefinedOrNull(apiComponent.materialIndex)) { + apiComponent.materialIndex = 0; + } + this.materialIndex = apiComponent.materialIndex; +}; + +R3.API.Group.prototype = Object.create(R3.API.Component.prototype); +R3.API.Group.prototype.constructor = R3.API.Group; diff --git a/src/r3-api-image.js b/src/r3-api-image.js new file mode 100644 index 0000000..ab60175 --- /dev/null +++ b/src/r3-api-image.js @@ -0,0 +1,63 @@ +/** + * R3.API.Image + * @param apiComponent + * @constructor + */ +R3.API.Image = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.fileName)) { + apiComponent.fileName = R3.Utils.LowerUnderscore(name); + } + this.fileName = apiComponent.fileName; + + if (R3.Utils.UndefinedOrNull(apiComponent.extension)) { + apiComponent.extension = '.unknown'; + } + this.extension = apiComponent.extension; + + if (R3.Utils.UndefinedOrNull(apiComponent.path)) { + apiComponent.path = '/'; + } + this.path = apiComponent.path; + + if (R3.Utils.UndefinedOrNull(apiComponent.contentType)) { + + apiComponent.contentType = 'application/octet-stream'; + + if (this.extension.match(/(png)$/i)) { + apiComponent.contentType = 'image/png'; + } + + if (this.extension.match(/(jpg|jpeg)$/i)) { + apiComponent.contentType = 'image/jpeg'; + } + + if (this.extension.match(/(gif)$/i)) { + apiComponent.contentType = 'image/gif'; + } + } + this.contentType = apiComponent.contentType; + + if (R3.Utils.UndefinedOrNull(apiComponent.size)) { + apiComponent.size = 0; + } + this.size = apiComponent.size; + + if (R3.Utils.UndefinedOrNull(apiComponent.width)) { + apiComponent.width = 0; + } + this.width = apiComponent.width; + + if (R3.Utils.UndefinedOrNull(apiComponent.height)) { + apiComponent.height = 0; + } + this.height = apiComponent.height; + +}; + +R3.API.Image.prototype = Object.create(R3.API.Component.prototype); +R3.API.Image.prototype.constructor = R3.API.Image; diff --git a/src/r3-api-matrix4.js b/src/r3-api-matrix4.js new file mode 100644 index 0000000..855a027 --- /dev/null +++ b/src/r3-api-matrix4.js @@ -0,0 +1,231 @@ +/** + * R3.API.Matrix4 + * @param apiComponent + * + * @property rows [R3.API.Vector4] + * + * @constructor + */ +R3.API.Matrix4 = function ( + apiComponent +) { + __DEREGISTER_COMPONENT__; + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.rows)) { + + apiComponent.rows = []; + + apiComponent.rows.push( + new R3.API.Vector4( + { + parent : this, + register : this.register, + x : 1, + y : 0, + z : 0, + w : 0 + } + ) + ); + + apiComponent.rows.push( + new R3.API.Vector4( + { + parent : this, + register : this.register, + x : 0, + y : 1, + z : 0, + w : 0 + } + ) + ); + + apiComponent.rows.push( + new R3.API.Vector4( + { + parent : this, + register : this.register, + x : 0, + y : 0, + z : 1, + w : 0 + } + ) + ); + + apiComponent.rows.push( + new R3.API.Vector4( + { + parent : this, + register : this.register, + x : 0, + y : 0, + z : 0, + w : 1 + } + ) + ); + } + this.rows = apiComponent.rows; + +}; + +R3.API.Matrix4.prototype = Object.create(R3.API.Component.prototype); +R3.API.Matrix4.prototype.constructor = R3.API.Matrix4; + +R3.API.Matrix4.prototype.rotationMatrixX = function(radians) { + + this.identity(); + + this.rows[1] = new R3.API.Vector4( + { + parent : this, + register : this.register, + x : 0, + y : Math.cos(radians), + z : -1 * Math.sin(radians), + w : 0 + } + ); + + this.rows[2] = new R3.API.Vector4( + { + parent : this, + register : this.register, + x : 0, + y : Math.sin(radians), + z : Math.cos(radians), + w : 0 + } + ); + + return this; +}; + +R3.API.Matrix4.prototype.rotationMatrixY = function(radians) { + + this.identity(); + + this.rows[0] = new R3.API.Vector4( + { + parent : this, + register : this.register, + x : Math.cos(radians), + y : 0, + z : Math.sin(radians), + w : 0 + } + ); + + this.rows[2] = new R3.API.Vector4( + { + parent : this, + register : this.register, + x : -1 * Math.sin(radians), + y : 0, + z : Math.cos(radians), + w : 0 + } + ); + + return this; +}; + +R3.API.Matrix4.prototype.rotationMatrixZ = function(radians) { + + this.identity(); + + this.rows[0] = new R3.API.Vector4( + { + parent : this, + register : this.register, + x : Math.cos(radians), + y : -1 * Math.sin(radians), + z : 0, + w : 0 + } + ); + + this.rows[1] = new R3.API.Vector4( + { + parent : this, + register : this.register, + x : Math.sin(radians), + y : Math.cos(radians), + z : 0, + w : 0 + } + ); + + return this; +}; + +R3.API.Matrix4.prototype.rotateX = function(radians, point) { + this.identity(); + this.rotationMatrixX(radians); + return this.multiply(point); +}; + +R3.API.Matrix4.prototype.rotateY = function(radians, point) { + this.identity(); + this.rotationMatrixY(radians); + return this.multiply(point); +}; + +R3.API.Matrix4.prototype.rotateZ = function(radians, point) { + this.identity(); + this.rotationMatrixZ(radians); + return this.multiply(point); +}; + +R3.API.Matrix4.prototype.multiply = function(mvp) { + if (mvp instanceof R3.API.Quaternion || mvp instanceof R3.API.Vector4) { + return new R3.API.Quaternion( + { + parent : this, + register : this.register, + x : this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z + this.rows[0].w * mvp.w, + y : this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z + this.rows[1].w * mvp.w, + z : this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z + this.rows[2].w * mvp.w, + 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 R3.API.Vector3) { + return new R3.API.Vector3( + { + parent : this, + register : this.register, + x : this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z, + y : this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z, + z : this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z + } + ); + } +}; + +R3.API.Matrix4.prototype.identity = function() { + + this.rows[0].x = 1; + this.rows[0].y = 0; + this.rows[0].z = 0; + this.rows[0].w = 0; + + this.rows[1].x = 0; + this.rows[1].y = 1; + this.rows[1].z = 0; + this.rows[1].w = 0; + + this.rows[2].x = 0; + this.rows[2].y = 0; + this.rows[2].z = 1; + this.rows[2].w = 0; + + this.rows[3].x = 0; + this.rows[3].y = 0; + this.rows[3].z = 0; + this.rows[3].w = 1; + +}; diff --git a/src/r3-api-mouse.js b/src/r3-api-mouse.js new file mode 100644 index 0000000..0680142 --- /dev/null +++ b/src/r3-api-mouse.js @@ -0,0 +1,26 @@ +/** + * R3.API.Mouse + * @param apiComponent + * @constructor + */ +R3.API.Mouse = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.position)) { + apiComponent.position = new R3.API.Vector2( + { + parent : this, + register : true, + name : this.name + ' - Position' + } + ); + } + this.position = apiComponent.position; + +}; + +R3.API.Mouse.prototype = Object.create(R3.API.Component.prototype); +R3.API.Mouse.prototype.constructor = R3.API.Mouse; diff --git a/src/r3-api-plane.js b/src/r3-api-plane.js new file mode 100644 index 0000000..43bce65 --- /dev/null +++ b/src/r3-api-plane.js @@ -0,0 +1,34 @@ +/** + * R3.API.Plane + * @param apiComponent + * @constructor + */ +R3.API.Plane = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.normal)) { + apiComponent.normal = new R3.API.Vector3( + { + register : true, + parent : this, + x : 0, + y : 0, + z : 0 + } + ); + } + this.normal = apiComponent.normal; + + if (R3.Utils.UndefinedOrNull(apiComponent.constant)) { + apiComponent.constant = 0; + } + this.constant = apiComponent.constant; + +}; + + +R3.API.Plane.prototype = Object.create(R3.API.Component.prototype); +R3.API.Plane.prototype.constructor = R3.API.Plane; diff --git a/src/r3-api-project-0.js b/src/r3-api-project-0.js new file mode 100644 index 0000000..b8d8c27 --- /dev/null +++ b/src/r3-api-project-0.js @@ -0,0 +1,123 @@ +/** + * R3.API.Project + * @param apiComponent + * + * @property users + * @property isPublic + * @property entities + * @property controls + * @property images + * @property code + * @property applicationMode + * + * @constructor + */ +R3.API.Project = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.entities)) { + apiComponent.entities = []; + } + this.entities = apiComponent.entities; + + if (R3.Utils.UndefinedOrNull(apiComponent.controls)) { + apiComponent.controls = [] + } + this.controls = apiComponent.controls; + + if (R3.Utils.UndefinedOrNull(apiComponent.images)) { + apiComponent.images = [] + } + this.images = apiComponent.images; + + if (R3.Utils.UndefinedOrNull(apiComponent.code)) { + apiComponent.code = [ + new R3.API.CustomCode( + { + parent : this, + name : this.name + ' - Code - Project Loaded', + eventId : R3.Event.PROJECT_LOADED + } + ), + new R3.API.CustomCode( + { + parent : this, + name : this.name + ' - Code - Before Render', + eventId : R3.Event.BEFORE_RENDER + } + ), + new R3.API.CustomCode( + { + parent : this, + name : this.name + ' - Code - Key Up', + eventId : R3.Event.KEY_UP + } + ), + new R3.API.CustomCode( + { + parent : this, + name : this.name + ' - Code - Key Down', + eventId : R3.Event.KEY_DOWN + } + ), + new R3.API.CustomCode( + { + parent : this, + name : this.name + ' - Code - Mouse Up', + eventId : R3.Event.MOUSE_UP + } + ), + new R3.API.CustomCode( + { + parent : this, + name : this.name + ' - Code - Mouse Down', + eventId : R3.Event.MOUSE_DOWN + } + ), + new R3.API.CustomCode( + { + parent : this, + name : this.name + ' - Code - Mouse Move', + eventId : R3.Event.MOUSE_MOVE + } + ), + new R3.API.CustomCode( + { + parent : this, + name : this.name + ' - Code - Touch Start', + eventId : R3.Event.TOUCH_START + } + ), + new R3.API.CustomCode( + { + parent : this, + name : this.name + ' - Code - Touch End', + eventId : R3.Event.TOUCH_END + } + ) + ] + } + this.code = apiComponent.code; + + if (R3.Utils.UndefinedOrNull(apiComponent.applicationMode)) { + apiComponent.applicationMode = R3.API.Project.APPLICATION_MODE_EDIT; + } + this.applicationMode = apiComponent.applicationMode; + +}; + +R3.API.Project.prototype = Object.create(R3.API.Component.prototype); +R3.API.Project.prototype.constructor = R3.API.Project; + +R3.API.Project.CAMERA_INDEX_EDIT = 0x0; +R3.API.Project.CAMERA_INDEX_RUN = 0x1; + +R3.API.Project.APPLICATION_MODE_EDIT = R3.API.Project.CAMERA_INDEX_EDIT; +R3.API.Project.APPLICATION_MODE_RUN = R3.API.Project.CAMERA_INDEX_RUN; + +R3.API.Project.RENDERER_INDEX_MAIN = 0x0; + +R3.API.Project.RENDER_TARGET_INDEX_NONE = -0x1; \ No newline at end of file diff --git a/src/r3-api-project-d2.js b/src/r3-api-project-d2.js new file mode 100644 index 0000000..c2c3f13 --- /dev/null +++ b/src/r3-api-project-d2.js @@ -0,0 +1,63 @@ +/** + * R3.API.Project + * @param apiComponent + * + * @property renderers + * @property controls + * + * @constructor + */ +R3.API.Project.D2 = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.renderers)) { + apiComponent.renderers = [ + new R3.API.Renderer.D2( + { + parent : this, + name : this.name + ' - 2D Renderer' + } + ) + ]; + } + this.renderers = apiComponent.renderers; + + if (R3.Utils.UndefinedOrNull(apiComponent.controls)) { + apiComponent.controls = [ + new R3.API.Controls.Mouse( + { + parent : this, + name : this.name + ' - Mouse Controls', + canvas : this.renderers[0].canvas + } + ), + new R3.API.Controls.Keyboard( + { + parent : this, + name : this.name + ' - Keyboard Controls', + canvas : this.renderers[0].canvas + } + ), + new R3.API.Controls.Touch( + { + parent : this, + name : this.name + ' - Touch Controls', + canvas : this.renderers[0].canvas + } + ) + ] + } + this.controls = apiComponent.controls; + + R3.API.Project.call( + this, + apiComponent + ); + +}; + +R3.API.Project.D2.prototype = Object.create(R3.API.Project.prototype); +R3.API.Project.D2.prototype.constructor = R3.API.Project.D2; diff --git a/src/r3-api-project-d3-0.js b/src/r3-api-project-d3-0.js new file mode 100644 index 0000000..ace3e31 --- /dev/null +++ b/src/r3-api-project-d3-0.js @@ -0,0 +1,159 @@ +/** + * R3.API.Project + * @param apiComponent + * + * @property renderers + * @property renderTargets + * @property cameras + * @property controls + * @property audios + * + * @constructor + */ +R3.API.Project.D3 = function( + apiComponent +) { + + /** + * Override everything not coming from DB + */ + __API_COMPONENT__; + + /** + * This means we need to construct the cameras first if they are not coming from the database + */ + if (R3.Utils.UndefinedOrNull(apiComponent.cameras)) { + var editCamera = new R3.D3.API.Camera.Perspective( + { + parent : this, + name : this.name + ' - Edit Camera' + } + ); + var runCamera = new R3.D3.API.Camera.Perspective( + { + parent : this, + name : this.name + ' - Run Camera' + } + ); + apiComponent.cameras = [editCamera, runCamera]; + } + this.cameras = apiComponent.cameras; + + if (R3.Utils.UndefinedOrNull(apiComponent.mouse)) { + apiComponent.mouse = new R3.API.Mouse( + { + parent: this, + name: this.name + ' - Mouse' + } + ); + } + this.mouse = apiComponent.mouse; + + if (R3.Utils.UndefinedOrNull(apiComponent.raycaster)) { + apiComponent.raycaster = new R3.D3.API.Raycaster( + { + parent: this, + name: this.name + ' - Raycaster' + } + ); + } + this.raycaster = apiComponent.raycaster; + + if (R3.Utils.UndefinedOrNull(apiComponent.clock)) { + apiComponent.clock = new R3.API.Clock( + { + parent: this, + name: this.name + ' - Clock' + } + ); + } + this.clock = apiComponent.clock; + + /** + * And we should also override here the renderers if they are not coming from the API + */ + if (R3.Utils.UndefinedOrNull(apiComponent.renderers)) { + apiComponent.renderers = [ + new R3.API.Renderer.D3.Canvas( + { + parent : this, + name : this.name + ' - 3D Canvas Renderer' + } + ) + ]; + } + this.renderers = apiComponent.renderers; + + /** + * Now override the controls before initializing the other API properties + */ + if (R3.Utils.UndefinedOrNull(apiComponent.controls)) { + apiComponent.controls = [ + new R3.API.Controls.Mouse( + { + parent : this, + name : this.name + ' - Mouse Controls', + canvas : this.renderers[0].canvas + } + ), + new R3.API.Controls.Keyboard( + { + parent : this, + name : this.name + ' - Keyboard Controls', + canvas : this.renderers[0].canvas + } + ), + new R3.API.Controls.Touch( + { + parent : this, + name : this.name + ' - Touch Controls', + canvas : this.renderers[0].canvas + } + ), + new R3.API.Controls.D3.Orbit( + { + parent : this, + name : this.name + ' - Orbit Controls', + camera : this.cameras[0], + canvas : this.renderers[0].canvas + } + ) + ]; + } + + if (R3.Utils.UndefinedOrNull(apiComponent.composer)) { + apiComponent.composer = new R3.D3.API.Composer( + { + parent : this, + name : this.name + ' - Composer', + renderer : this.renderers[0], + camera : this.cameras[0] + } + ); + } + this.composer = apiComponent.composer; + + if (R3.Utils.UndefinedOrNull(apiComponent.effect)) { + apiComponent.effect = null; + } + this.effect = apiComponent.effect; + + if (R3.Utils.UndefinedOrNull(apiComponent.renderTargets)) { + apiComponent.renderTargets = []; + } + this.renderTargets = apiComponent.renderTargets; + + if (R3.Utils.UndefinedOrNull(apiComponent.audios)) { + apiComponent.audios = []; + } + this.audios = apiComponent.audios; + + R3.API.Project.call( + this, + apiComponent + ); + +}; + +R3.API.Project.D3.prototype = Object.create(R3.API.Project.prototype); +R3.API.Project.D3.prototype.constructor = R3.API.Project.D3; diff --git a/src/r3-api-project-d3-vr.js b/src/r3-api-project-d3-vr.js new file mode 100644 index 0000000..b8e5d1c --- /dev/null +++ b/src/r3-api-project-d3-vr.js @@ -0,0 +1,85 @@ +/** + * R3.API.Project + * @param apiComponent + * + * @property renderers + * @property renderTargets + * @property cameras + * @property controls + * @property audios + * + * @constructor + */ +R3.API.Project.D3.VR = function( + apiComponent +) { + + /** + * Override everything not coming from DB + */ + __API_COMPONENT__; + + /** + * This means we need to construct the cameras first if they are not coming from the database + */ + if (R3.Utils.UndefinedOrNull(apiComponent.cameras)) { + var editCamera = new R3.D3.API.Camera.Perspective.Stereo( + { + parent : this, + name : this.name + ' - Stereo Edit Camera' + } + ); + var runCamera = new R3.D3.API.Camera.Perspective.Stereo( + { + parent : this, + name : this.name + ' - Run Camera' + } + ); + apiComponent.cameras = [editCamera, runCamera]; + } + this.cameras = apiComponent.cameras; + + /** + * And we should also override here the renderers if they are not coming from the API + */ + if (R3.Utils.UndefinedOrNull(apiComponent.renderers)) { + + apiComponent.renderers = [ + new R3.API.Renderer.D3.Canvas( + { + parent : this, + name : this.name + ' - Canvas Renderer', + viewports : [ + new R3.D3.API.Viewport.FixedAspect.VR( + { + parent : this, + name : this.name + ' - Fixed Aspect VR Left Viewport', + side : R3.D3.API.Viewport.FixedAspect.VR.VIEWPORT_LEFT + } + ), + new R3.D3.API.Viewport.FixedAspect.VR( + { + parent : this, + name : this.name + ' - Fixed Aspect VR Right Viewport', + side : R3.D3.API.Viewport.FixedAspect.VR.VIEWPORT_RIGHT + } + ) + ] + } + ) + ]; + + apiComponent.renderers[0].viewports[0].parent = apiComponent.renderers[0]; + apiComponent.renderers[0].viewports[1].parent = apiComponent.renderers[0]; + } + this.renderers = apiComponent.renderers; + + R3.API.Project.D3.call( + this, + apiComponent + ); + +}; + +R3.API.Project.D3.VR.prototype = Object.create(R3.API.Project.D3.prototype); +R3.API.Project.D3.VR.prototype.constructor = R3.API.Project.D3.VR; diff --git a/src/r3-api-quaternion-0.js b/src/r3-api-quaternion-0.js new file mode 100644 index 0000000..9aa5b51 --- /dev/null +++ b/src/r3-api-quaternion-0.js @@ -0,0 +1,221 @@ +/** + * R3.API.Quaternion + * @param apiComponent + * @constructor + */ +R3.API.Quaternion = function( + apiComponent +) { + + __DEREGISTER_COMPONENT__; + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.x)) { + apiComponent.x = 0; + } + this.x = apiComponent.x; + + if (R3.Utils.UndefinedOrNull(apiComponent.y)) { + apiComponent.y = 0; + } + this.y = apiComponent.y; + + if (R3.Utils.UndefinedOrNull(apiComponent.z)) { + apiComponent.z = 0; + } + this.z = apiComponent.z; + + if (R3.Utils.UndefinedOrNull(apiComponent.w)) { + apiComponent.w = 1; + } + this.w = apiComponent.w; + + if (R3.Utils.UndefinedOrNull(apiComponent.axis)) { + + var name = 'Quaternion Axis'; + + if (this.parent && this.parent.name) { + name = this.parent.name + ' - Quaternion Axis'; + } + + apiComponent.axis = new R3.API.Vector3( + { + parent : this.parent, + name : name, + register : this.register + } + ); + } + this.axis = apiComponent.axis; + + if (R3.Utils.UndefinedOrNull(apiComponent.angle)) { + apiComponent.angle = 0; + } + this.angle = apiComponent.angle; +}; + +R3.API.Quaternion.prototype = Object.create(R3.API.Component.prototype); +R3.API.Quaternion.prototype.constructor = R3.API.Quaternion; + +R3.API.Quaternion.prototype.translate = function(v) { + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; +}; + +R3.API.Quaternion.prototype.copy = function() { + return new R3.API.Quaternion( + this + ); +}; + +/** + * Note, this normalize function leaves 'w' component untouched + */ +R3.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; +}; + +R3.API.Quaternion.prototype.multiply = function(q) { + + var x, y, z, w; + var a = q; + var b = this; + + if (q instanceof R3.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 R3.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"); + } +}; + +R3.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; +}; + +R3.API.Quaternion.prototype.subtract = function(v) { + + if (v instanceof R3.API.Vector3) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + } + + if (v instanceof R3.API.Quaternion) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + this.w -= v.w; + } + + return this; +}; + +R3.API.Quaternion.prototype.magnitude = function() { + return Math.sqrt( + (this.x * this.x) + + (this.y * this.y) + + (this.z * this.z) + + (this.w * this.w) + ); +}; + +R3.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 R3.Matrix4 + */ +R3.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 R3.Quaternion + * @param t + * @returns {R3.Quaternion} + */ +R3.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; +}; diff --git a/src/r3-api-quaternion-points.js b/src/r3-api-quaternion-points.js new file mode 100644 index 0000000..b143152 --- /dev/null +++ b/src/r3-api-quaternion-points.js @@ -0,0 +1,303 @@ +/** + * R3.API.Quaternion.Points + * @param apiComponent + * @constructor + */ +R3.API.Quaternion.Points = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.vectors)) { + apiComponent.vectors = []; + } + + this.vectors = apiComponent.vectors; +}; + +R3.API.Quaternion.Points.prototype = Object.create(R3.API.Component.prototype); +R3.API.Quaternion.Points.prototype.constructor = R3.API.Quaternion.Points; + +R3.API.Quaternion.Points.prototype.add = function(vector) { + + if (vector instanceof R3.API.Vector3) { + vector = new R3.API.Quaternion( + { + parent : this, + register : true, + x : vector.x, + y : vector.y, + z : vector.z, + w : 1 + } + ) + } + + if (!vector instanceof R3.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; +}; + +R3.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; +}; + +R3.API.Quaternion.Points.prototype.maximizeXDistance = function(grain) { + +// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); + + var multiplier = 0; + + var rotationMatrixY = new R3.API.Matrix4( + { + parent : this + } + ).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 R3.API.Matrix4( + { + parent : this, + register : true + } + ).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)); + +}; + +R3.API.Quaternion.Points.prototype.maximizeYDistance = function(grain) { + +// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); + + var multiplier = 0; + + var rotationMatrixX = new R3.API.Matrix4( + { + parent : this, + register : true + } + ).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 R3.API.Matrix4( + { + parent : this, + register : true + } + ).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)); + +}; + + +R3.API.Quaternion.Points.prototype.lookAt = function(at, up) { + + var polyCenter = this.average(); + + console.log("poly center : " + JSON.stringify(polyCenter)); + + var lookAtMatrix = new R3.API.Matrix4({ + parent : this + }).lookAt(polyCenter, at, up); + + lookAtMatrix.rows[0] = new R3.API.Quaternion( + { + parent : this, + register : true, + x : 1, + y : 0, + z : 0, + w : 0 + } + ); + + lookAtMatrix.rows[1] = new R3.API.Quaternion( + { + parent : this, + register : true, + x : 0, + y : 0, + z : 1, + w : 0 + } + ); + + lookAtMatrix.rows[2] = new R3.API.Quaternion( + { + parent : this, + register : true, + x : 0, + y : 1, + z : 0, + w : 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])); + } +}; + +R3.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 R3.API.Vector3( + { + parent : this, + x : Math.abs(maxX - minX), + y : Math.abs(maxY - minY), + z : Math.abs(maxY - minZ) + } + ) +}; + +R3.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 R3.API.Vector3( + { + parent : this, + register : true, + x : averageX / this.vectors.length, + y : averageY / this.vectors.length, + z : averageZ / this.vectors.length + } + ); +}; + +R3.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; +}; + + +R3.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); + } +}; \ No newline at end of file diff --git a/src/r3-api-query-0.js b/src/r3-api-query-0.js new file mode 100644 index 0000000..092c2de --- /dev/null +++ b/src/r3-api-query-0.js @@ -0,0 +1,86 @@ +/** + * R3.API.Query + * @param apiComponent + * + * @property path + * @property start + * @property end + * @property timezone + * @property size + * @property text + * + * @constructor + */ +R3.API.Query = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.path)) { + apiComponent.path = null; + } + this.path = apiComponent.path; + + if (R3.Utils.UndefinedOrNull(apiComponent.start)) { + apiComponent.start = 'now-365d'; + } + this.start = apiComponent.start; + + if (R3.Utils.UndefinedOrNull(apiComponent.end)) { + apiComponent.end = 'now+4h'; + } + this.end = apiComponent.end; + + if (R3.Utils.UndefinedOrNull(apiComponent.timeZone)) { + apiComponent.timeZone = 'Europe/Berlin'; + } + this.timeZone = apiComponent.timeZone; + + if (R3.Utils.UndefinedOrNull(apiComponent.size)) { + apiComponent.size = 100; + } + this.size = apiComponent.size; + + if (R3.Utils.UndefinedOrNull(apiComponent.text)) { + apiComponent.text = '{}'; + } + this.text = apiComponent.text; + + if (R3.Utils.UndefinedOrNull(apiComponent.httpMethod)) { + apiComponent.httpMethod = 'POST'; + } + this.httpMethod = apiComponent.httpMethod; + + if (R3.Utils.UndefinedOrNull(apiComponent.tooltips)) { + apiComponent.tooltips = []; + } + this.tooltips = apiComponent.tooltips; +}; + +R3.API.Query.prototype = Object.create(R3.API.Component.prototype); +R3.API.Query.prototype.constructor = R3.API.Query; + +R3.API.Query.QUERY_SIZE = 'QUERY_SIZE'; +R3.API.Query.QUERY_START = 'QUERY_START'; +R3.API.Query.QUERY_END = 'QUERY_END'; +R3.API.Query.QUERY_TIMEZONE = 'QUERY_TIMEZONE'; +R3.API.Query.QUERY_TIME_INTERVAL = 'QUERY_TIME_INTERVAL'; +R3.API.Query.QUERY_BUCKET_FIELD = 'QUERY_BUCKET_FIELD'; +R3.API.Query.QUERY_LOGIN_TYPE = 'QUERY_LOGIN_TYPE'; +R3.API.Query.QUERY_ACKNOWLEDGED = 'QUERY_ACKNOWLEDGED'; + +R3.API.Query.LOGIN_TYPE_ALL = 'local|remote|application|vpn'; +R3.API.Query.LOGIN_TYPE_DEVICE = 'local|remote'; +R3.API.Query.LOGIN_TYPE_APPLICATION = 'application'; +R3.API.Query.LOGIN_TYPE_VPN = 'vpn'; + +R3.API.Query.ACKNOWLEDGED_ALL = ''; +R3.API.Query.ACKNOWLEDGED_TRUE = ',\n' + + ' {\n' + + ' "term" : { "acknowledged": true }\n' + + ' }'; +R3.API.Query.ACKNOWLEDGED_FALSE = ',\n' + + ' {\n' + + ' "term" : { "acknowledged": false }\n' + + ' }'; \ No newline at end of file diff --git a/src/r3-api-query-alerts-0.js b/src/r3-api-query-alerts-0.js new file mode 100644 index 0000000..e74e5ba --- /dev/null +++ b/src/r3-api-query-alerts-0.js @@ -0,0 +1,25 @@ +/** + * R3.API.Query.Alerts + * @param apiComponent + * @constructor + */ +R3.API.Query.Alerts = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.path)) { + apiComponent.path = '/alerts/_search'; + } + this.path = apiComponent.path; + + R3.API.Query.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Alerts.prototype = Object.create(R3.API.Query.prototype); +R3.API.Query.Alerts.prototype.constructor = R3.API.Query.Alerts; diff --git a/src/r3-api-query-alerts-buckets.js b/src/r3-api-query-alerts-buckets.js new file mode 100644 index 0000000..37cf915 --- /dev/null +++ b/src/r3-api-query-alerts-buckets.js @@ -0,0 +1,103 @@ +/** + * R3.API.Query.Alerts.Buckets + * @param apiComponent + * + * @property bucketField BUCKET_FIELD + * + * @constructor + */ +R3.API.Query.Alerts.Buckets = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__ + + /** + * Override default size + */ + if (R3.Utils.UndefinedOrNull(apiComponent)) { + apiComponent = { + size : 100 + }; + } + + if (R3.Utils.UndefinedOrNull(apiComponent.size)) { + apiComponent.size = 100; + } + + /** + * Override default text + */ + if (R3.Utils.UndefinedOrNull(apiComponent.text)) { + apiComponent.text = '{\n' + + ' "version": false,\n' + + ' "size": ' + R3.API.Query.QUERY_SIZE + ',\n' + + ' "sort": [\n' + + ' {\n' + + ' "priority": {\n' + + ' "order": "asc"\n' + + ' },\n' + + ' "acknowledged": {\n' + + ' "order": "asc"\n' + + ' },\n' + + ' "' + R3.API.Query.QUERY_BUCKET_FIELD + '": {\n' + + ' "order": "asc"\n' + + ' }\n' + + ' }\n' + + ' ], \n' + + ' "_source": {\n' + + ' "includes": ["*"]\n' + + ' }, \n' + + ' "aggs": {\n' + + ' "descriptions": {\n' + + ' "terms" : { "field" : "' + R3.API.Query.QUERY_BUCKET_FIELD + '" },\n' + + ' "aggs": {\n' + + ' "priorities": {\n' + + ' "histogram": {\n' + + ' "field": "priority",\n' + + ' "interval": "1",\n' + + ' "min_doc_count": 0\n' + + ' }\n' + + ' }\n' + + ' }\n' + + ' }\n' + + ' }, \n' + + ' "query": {\n' + + ' "bool": {\n' + + ' "must": [\n' + + ' {\n' + + ' "range": {\n' + + ' "timestamp": {\n' + + ' "format": "strict_date_optional_time",\n' + + ' "gte" : "' + R3.API.Query.QUERY_START + '", \n' + + ' "lt" : "' + R3.API.Query.QUERY_END + '"\n' + + ' }\n' + + ' }\n' + + ' }\n' + + ' ]\n' + + ' }\n' + + ' } \n' + + '}\n'; + } + this.text = apiComponent.text; + + if (R3.Utils.UndefinedOrNull(apiComponent.bucketField)) { + apiComponent.bucketField = R3.API.Query.Alerts.Buckets.BUCKET_FIELD_ALERT_TYPE; + } + this.bucketField = apiComponent.bucketField; + + R3.API.Query.Alerts.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Alerts.Buckets.prototype = Object.create(R3.API.Query.Alerts.prototype); +R3.API.Query.Alerts.Buckets.prototype.constructor = R3.API.Query.Alerts.Buckets; + +R3.API.Query.Alerts.Buckets.BUCKET_FIELD_ALERT_TYPE = 'alert_type.keyword'; +R3.API.Query.Alerts.Buckets.BUCKET_FIELD_COUNTRY = 'geo.country.keyword'; +R3.API.Query.Alerts.Buckets.BUCKET_FIELD_HOSTNAME = 'device.hostname.keyword'; +R3.API.Query.Alerts.Buckets.BUCKET_FIELD_IP_V4 = 'device.ip_v4.keyword'; +R3.API.Query.Alerts.Buckets.BUCKET_FIELD_USERNAME = 'login.username.keyword'; diff --git a/src/r3-api-query-alerts-firstTimeLogin-0.js b/src/r3-api-query-alerts-firstTimeLogin-0.js new file mode 100644 index 0000000..6e1854c --- /dev/null +++ b/src/r3-api-query-alerts-firstTimeLogin-0.js @@ -0,0 +1,67 @@ +/** + * R3.API.Query.Alerts.FirstTimeLogin + * @param apiComponent + * @constructor + */ +R3.API.Query.Alerts.FirstTimeLogin = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.loginType)) { + apiComponent.loginType = R3.API.Query.LOGIN_TYPE_ALL; + } + this.loginType = apiComponent.loginType; + + if (R3.Utils.UndefinedOrNull(apiComponent.text)) { + apiComponent.text = '{\n' + + ' "version": false,\n' + + ' "size": ' + R3.API.Query.QUERY_SIZE + ',\n' + + ' "sort": [\n' + + ' {\n' + + ' "login.destination_ip.keyword": {\n' + + ' "order": "asc"\n' + + ' }\n' + + ' }\n' + + ' ],\n' + + ' "_source": {\n' + + ' "includes": ["*"]\n' + + ' },\n' + + ' "query": {\n' + + ' "bool": {\n' + + ' "must": [\n' + + ' {\n' + + ' "range": {\n' + + ' "timestamp": {\n' + + ' "format": "strict_date_optional_time",\n' + + ' "gte" : "' + R3.API.Query.QUERY_START + '",\n' + + ' "lt" : "' + R3.API.Query.QUERY_END + '"\n' + + ' }\n' + + ' }\n' + + ' },\n' + + ' {\n' + + ' "term" : { "acknowledged": "false" }\n' + + ' },\n' + + ' {\n' + + ' "term" : { "alert_type.keyword": "First Time Login" }\n' + + ' },\n' + + ' {\n' + + ' "regexp" : { "login.type.keyword": "' + R3.API.Query.QUERY_LOGIN_TYPE + '" }\n' + + ' }\n' + + ' ]\n' + + ' }\n' + + ' }\n' + + '}'; + } + this.text = apiComponent.text; + + R3.API.Query.Alerts.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Alerts.FirstTimeLogin.prototype = Object.create(R3.API.Query.Alerts.prototype); +R3.API.Query.Alerts.FirstTimeLogin.prototype.constructor = R3.API.Query.Alerts.FirstTimeLogin; diff --git a/src/r3-api-query-alerts-firstTimeLogin-applications.js b/src/r3-api-query-alerts-firstTimeLogin-applications.js new file mode 100644 index 0000000..4339b87 --- /dev/null +++ b/src/r3-api-query-alerts-firstTimeLogin-applications.js @@ -0,0 +1,27 @@ +/** + * R3.API.Query.Alerts.FirstTimeLogin.Applications + * @param apiComponent + * @constructor + */ +R3.API.Query.Alerts.FirstTimeLogin.Applications = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__; + + /** + * Override the loginType + */ + if (R3.Utils.UndefinedOrNull(apiComponent.loginType)) { + apiComponent.loginType = R3.API.Query.LOGIN_TYPE_APPLICATION; + } + + R3.API.Query.Alerts.FirstTimeLogin.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Alerts.FirstTimeLogin.Applications.prototype = Object.create(R3.API.Query.Alerts.FirstTimeLogin.prototype); +R3.API.Query.Alerts.FirstTimeLogin.Applications.prototype.constructor = R3.API.Query.Alerts.FirstTimeLogin.Applications; diff --git a/src/r3-api-query-alerts-firstTimeLogin-devices.js b/src/r3-api-query-alerts-firstTimeLogin-devices.js new file mode 100644 index 0000000..fdde334 --- /dev/null +++ b/src/r3-api-query-alerts-firstTimeLogin-devices.js @@ -0,0 +1,27 @@ +/** + * R3.API.Query.Alerts.FirstTimeLogin.Devices + * @param apiComponent + * @constructor + */ +R3.API.Query.Alerts.FirstTimeLogin.Devices = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__; + + /** + * Override the loginType + */ + if (R3.Utils.UndefinedOrNull(apiComponent.loginType)) { + apiComponent.loginType = R3.API.Query.LOGIN_TYPE_DEVICE; + } + + R3.API.Query.Alerts.FirstTimeLogin.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Alerts.FirstTimeLogin.Devices.prototype = Object.create(R3.API.Query.Alerts.FirstTimeLogin.prototype); +R3.API.Query.Alerts.FirstTimeLogin.Devices.prototype.constructor = R3.API.Query.Alerts.FirstTimeLogin.Devices; diff --git a/src/r3-api-query-alerts-firstTimeLogin-vpn.js b/src/r3-api-query-alerts-firstTimeLogin-vpn.js new file mode 100644 index 0000000..9cd2011 --- /dev/null +++ b/src/r3-api-query-alerts-firstTimeLogin-vpn.js @@ -0,0 +1,27 @@ +/** + * R3.API.Query.Alerts.FirstTimeLogin.VPN + * @param apiComponent + * @constructor + */ +R3.API.Query.Alerts.FirstTimeLogin.VPN = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__; + + /** + * Override the loginType + */ + if (R3.Utils.UndefinedOrNull(apiComponent.loginType)) { + apiComponent.loginType = R3.API.Query.LOGIN_TYPE_VPN; + } + + R3.API.Query.Alerts.FirstTimeLogin.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Alerts.FirstTimeLogin.VPN.prototype = Object.create(R3.API.Query.Alerts.FirstTimeLogin.prototype); +R3.API.Query.Alerts.FirstTimeLogin.VPN.prototype.constructor = R3.API.Query.Alerts.FirstTimeLogin.VPN; diff --git a/src/r3-api-query-alerts-list.js b/src/r3-api-query-alerts-list.js new file mode 100644 index 0000000..3daaae5 --- /dev/null +++ b/src/r3-api-query-alerts-list.js @@ -0,0 +1,80 @@ +/** + * R3.API.Query.Alerts.List + * @param apiComponent + * @constructor + */ +R3.API.Query.Alerts.List = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__ + + /** + * Override default size + */ + if (R3.Utils.UndefinedOrNull(apiComponent)) { + apiComponent = { + size : 100 + }; + } + + if (R3.Utils.UndefinedOrNull(apiComponent.size)) { + apiComponent.size = 100; + } + + if (R3.Utils.UndefinedOrNull(apiComponent.columns)) { + apiComponent.columns = []; + } + this.columns = apiComponent.columns; + + if (R3.Utils.UndefinedOrNull(apiComponent.rows)) { + apiComponent.rows = []; + } + this.rows = apiComponent.rows; + + if (R3.Utils.UndefinedOrNull(apiComponent.text)) { + apiComponent.text = '{\n' + + ' "version": false,\n' + + ' "size": ' + R3.API.Query.QUERY_SIZE + ',\n' + + ' "sort": [\n' + + ' {\n' + + ' "priority": {\n' + + ' "order": "asc",\n' + + ' "unmapped_type": "boolean"\n' + + ' },\n' + + ' "alert_type.keyword": {\n' + + ' "order": "asc",\n' + + ' "unmapped_type": "boolean"\n' + + ' }\n' + + ' }\n' + + ' ],\n' + + ' "_source": {\n' + + ' "includes": ["*"]\n' + + ' },\n' + + ' "query": {\n' + + ' "bool": {\n' + + ' "must": [\n' + + ' {\n' + + ' "range": {\n' + + ' "timestamp": {\n' + + ' "format": "strict_date_optional_time",\n' + + ' "gte": "' + R3.API.Query.QUERY_START + '",\n' + + ' "lt": "' + R3.API.Query.QUERY_END + '"\n' + + ' }\n' + + ' }\n' + + ' }\n' + + ' ]\n' + + ' }\n' + + ' }\n' + + '}'; + } + this.text = apiComponent.text; + + R3.API.Query.Alerts.call( + this, + apiComponent + ); +}; + +R3.API.Query.Alerts.List.prototype = Object.create(R3.API.Query.Alerts.prototype); +R3.API.Query.Alerts.List.prototype.constructor = R3.API.Query.Alerts.List; diff --git a/src/r3-api-query-alerts-summary.js b/src/r3-api-query-alerts-summary.js new file mode 100644 index 0000000..3cf2854 --- /dev/null +++ b/src/r3-api-query-alerts-summary.js @@ -0,0 +1,71 @@ +/** + * R3.API.Query.Alerts.Summary + * @param apiComponent + * + * @priorities + * + * @constructor + */ +R3.API.Query.Alerts.Summary = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.priorities)) { + apiComponent.priorities = []; + } + this.priorities = apiComponent.priorities; + + if (R3.Utils.UndefinedOrNull(apiComponent.text)) { + apiComponent.text = '{\n' + + ' "version": false,\n' + + ' "size": ' + R3.API.Query.QUERY_SIZE + ',\n' + + ' "sort": [\n' + + ' {\n' + + ' "timestamp": {\n' + + ' "order": "desc",\n' + + ' "unmapped_type": "boolean"\n' + + ' }\n' + + ' }\n' + + ' ],\n' + + ' "_source": {\n' + + ' "includes": ["*"]\n' + + ' },\n' + + ' "aggs": {\n' + + ' "priorities": {\n' + + ' "histogram": {\n' + + ' "field": "priority",\n' + + ' "interval": "1",\n' + + ' "min_doc_count": 0\n' + + ' }\n' + + ' }\n' + + ' },\n' + + ' "query": {\n' + + ' "bool": {\n' + + ' "must": [\n' + + ' {\n' + + ' "range": {\n' + + ' "timestamp": {\n' + + ' "format": "strict_date_optional_time",\n' + + ' "gte": "' + R3.API.Query.QUERY_START + '",\n' + + ' "lt": "' + R3.API.Query.QUERY_END + '"\n' + + ' }\n' + + ' }\n' + + ' }\n' + + ' ]\n' + + ' }\n' + + ' }\n' + + '}\n'; + } + this.text = apiComponent.text; + + R3.API.Query.Alerts.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Alerts.Summary.prototype = Object.create(R3.API.Query.Alerts.prototype); +R3.API.Query.Alerts.Summary.prototype.constructor = R3.API.Query.Alerts.Summary; diff --git a/src/r3-api-query-alerts-timeseries.js b/src/r3-api-query-alerts-timeseries.js new file mode 100644 index 0000000..f2d311c --- /dev/null +++ b/src/r3-api-query-alerts-timeseries.js @@ -0,0 +1,78 @@ +/** + * R3.API.Query.Alerts.Timeseries + * @param apiComponent + * @constructor + */ +R3.API.Query.Alerts.Timeseries = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.text)) { + apiComponent.text = '{\n' + + ' "version": false,\n' + + ' "size": ' + R3.API.Query.QUERY_SIZE + ',\n' + + ' "sort": [\n' + + ' {\n' + + ' "timestamp": {\n' + + ' "order": "desc",\n' + + ' "unmapped_type": "boolean"\n' + + ' }\n' + + ' }\n' + + ' ],\n' + + ' "_source": {\n' + + ' "includes": ["*"]\n' + + ' },\n' + + ' "aggs": {\n' + + ' "mins": {\n' + + ' "date_histogram": {\n' + + ' "field": "timestamp",\n' + + ' "calendar_interval": "' + R3.API.Query.QUERY_TIME_INTERVAL + '",\n' + + ' "time_zone": "' + R3.API.Query.QUERY_TIMEZONE + '",\n' + + ' "min_doc_count": 0,\n' + + ' "format" : "yyyy-MM-dd"\n' + + ' },\n' + + ' "aggs": {\n' + + ' "priorities": {\n' + + ' "histogram": {\n' + + ' "field": "priority",\n' + + ' "interval": "1",\n' + + ' "min_doc_count": 0\n' + + ' }\n' + + ' }\n' + + ' }\n' + + ' }\n' + + ' },\n' + + ' "query": {\n' + + ' "bool": {\n' + + ' "must": [\n' + + ' {\n' + + ' "range": {\n' + + ' "timestamp": {\n' + + ' "format": "strict_date_optional_time",\n' + + ' "gte" : "' + R3.API.Query.QUERY_START + '",\n' + + ' "lt" : "' + R3.API.Query.QUERY_END + '"\n' + + ' }\n' + + ' }\n' + + ' }\n' + + ' ]\n' + + ' }\n' + + ' }\n' + + '}\n'; + } + this.text = apiComponent.text; + + if (R3.Utils.UndefinedOrNull(apiComponent.timeInterval)) { + apiComponent.timeInterval = '1d'; + } + this.timeInterval = apiComponent.timeInterval; + + R3.API.Query.Alerts.call( + this, + apiComponent + ); +}; + +R3.API.Query.Alerts.Timeseries.prototype = Object.create(R3.API.Query.Alerts.prototype); +R3.API.Query.Alerts.Timeseries.prototype.constructor = R3.API.Query.Alerts.Timeseries; diff --git a/src/r3-api-query-devices-0.js b/src/r3-api-query-devices-0.js new file mode 100644 index 0000000..015a6c3 --- /dev/null +++ b/src/r3-api-query-devices-0.js @@ -0,0 +1,62 @@ +/** + * R3.API.Query.Devices + * @param apiComponent + * @constructor + */ +R3.API.Query.Devices = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.path)) { + apiComponent.path = '/devices/_search'; + } + this.path = apiComponent.path; + + if (R3.Utils.UndefinedOrNull(apiComponent.acknowledged)) { + apiComponent.acknowledged = R3.API.Query.ACKNOWLEDGED_ALL; + } + this.acknowledged = apiComponent.acknowledged; + + if (R3.Utils.UndefinedOrNull(apiComponent.text)) { + apiComponent.text = '{\n' + + ' "version": false,\n' + + ' "size": ' + R3.API.Query.QUERY_SIZE + ',\n' + + ' "sort": [\n' + + ' {\n' + + ' "ip_v4.keyword": {\n' + + ' "order": "asc"\n' + + ' }\n' + + ' }\n' + + ' ],\n' + + ' "_source": {\n' + + ' "includes": ["*"]\n' + + ' },\n' + + ' "query": {\n' + + ' "bool": {\n' + + ' "must": [\n' + + ' {\n' + + ' "range": {\n' + + ' "timestamp": {\n' + + ' "format": "strict_date_optional_time",\n' + + ' "gte" : "' + R3.API.Query.QUERY_START + '",\n' + + ' "lt" : "' + R3.API.Query.QUERY_END + '"\n' + + ' }\n' + + ' }\n' + + ' }' + R3.API.Query.QUERY_ACKNOWLEDGED + '\n' + + ' ]\n' + + ' }\n' + + ' }\n' + + '}'; + } + this.text = apiComponent.text; + + R3.API.Query.call( + this, + apiComponent + ); +}; + +R3.API.Query.Devices.prototype = Object.create(R3.API.Query.prototype); +R3.API.Query.Devices.prototype.constructor = R3.API.Query.Devices; diff --git a/src/r3-api-query-devices-known.js b/src/r3-api-query-devices-known.js new file mode 100644 index 0000000..7617ea7 --- /dev/null +++ b/src/r3-api-query-devices-known.js @@ -0,0 +1,25 @@ +/** + * R3.API.Query.Devices.Known + * @param apiComponent + * @constructor + */ +R3.API.Query.Devices.Known = function( + apiComponent +) { + + __API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.acknowledged)) { + apiComponent.acknowledged = R3.API.Query.ACKNOWLEDGED_TRUE; + } + this.acknowledged = apiComponent.acknowledged; + + R3.API.Query.Devices.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Devices.Known.prototype = Object.create(R3.API.Query.Devices.prototype); +R3.API.Query.Devices.Known.prototype.constructor = R3.API.Query.Devices.Known; diff --git a/src/r3-api-query-devices-sql.js b/src/r3-api-query-devices-sql.js new file mode 100644 index 0000000..7640b15 --- /dev/null +++ b/src/r3-api-query-devices-sql.js @@ -0,0 +1,35 @@ +/** + * R3.API.Query.Devices.SQL + * @param apiComponent + * @constructor + */ +R3.API.Query.Devices.SQL = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.path)) { + apiComponent.path = '/crud/devices.json'; + } + this.path = apiComponent.path; + + if (R3.Utils.UndefinedOrNull(apiComponent.httpMethod)) { + apiComponent.httpMethod = 'GET'; + } + this.httpMethod = apiComponent.httpMethod; + + if (R3.Utils.UndefinedOrNull(apiComponent.text)) { + apiComponent.text = ''; + } + this.text = apiComponent.text; + + R3.API.Query.Devices.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Devices.SQL.prototype = Object.create(R3.API.Query.Devices.prototype); +R3.API.Query.Devices.SQL.prototype.constructor = R3.API.Query.Devices.SQL; diff --git a/src/r3-api-query-devices-unknown.js b/src/r3-api-query-devices-unknown.js new file mode 100644 index 0000000..66f3032 --- /dev/null +++ b/src/r3-api-query-devices-unknown.js @@ -0,0 +1,25 @@ +/** + * R3.API.Query.Devices.Unknown + * @param apiComponent + * @constructor + */ +R3.API.Query.Devices.Unknown = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.acknowledged)) { + apiComponent.acknowledged = R3.API.Query.ACKNOWLEDGED_FALSE; + } + this.acknowledged = apiComponent.acknowledged; + + R3.API.Query.Devices.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Devices.Unknown.prototype = Object.create(R3.API.Query.Devices.prototype); +R3.API.Query.Devices.Unknown.prototype.constructor = R3.API.Query.Devices.Unknown; diff --git a/src/r3-api-query-logins-0.js b/src/r3-api-query-logins-0.js new file mode 100644 index 0000000..2817804 --- /dev/null +++ b/src/r3-api-query-logins-0.js @@ -0,0 +1,65 @@ +/** + * R3.API.Query.Logins + * @param apiComponent + * @constructor + */ +R3.API.Query.Logins = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.path)) { + apiComponent.path = '/logins/_search'; + } + this.path = apiComponent.path; + + if (R3.Utils.UndefinedOrNull(apiComponent.loginType)) { + apiComponent.loginType = R3.API.Query.LOGIN_TYPE_ALL; + } + this.loginType = apiComponent.loginType; + + if (R3.Utils.UndefinedOrNull(apiComponent.text)) { + apiComponent.text = '{\n' + + ' "version": false,\n' + + ' "size": ' + R3.API.Query.QUERY_SIZE + ',\n' + + ' "sort": [\n' + + ' {\n' + + ' "timestamp": {\n' + + ' "order": "asc"\n' + + ' }\n' + + ' }\n' + + ' ],\n' + + ' "_source": {\n' + + ' "includes": ["*"]\n' + + ' },\n' + + ' "query": {\n' + + ' "bool": {\n' + + ' "must": [\n' + + ' {\n' + + ' "range": {\n' + + ' "timestamp": {\n' + + ' "format": "strict_date_optional_time",\n' + + ' "gte" : "' + R3.API.Query.QUERY_START + '",\n' + + ' "lt" : "' + R3.API.Query.QUERY_END + '"\n' + + ' }\n' + + ' }\n' + + ' },\n' + + ' {\n' + + ' "regexp" : { "type.keyword": "(' + R3.API.Query.QUERY_LOGIN_TYPE + ')" }\n' + + ' }\n' + + ' ]\n' + + ' }\n' + + ' }\n' + + '}'; + } + this.text = apiComponent.text; + + R3.API.Query.call( + this, + apiComponent + ); +}; + +R3.API.Query.Logins.prototype = Object.create(R3.API.Query.prototype); +R3.API.Query.Logins.prototype.constructor = R3.API.Query.Logins; diff --git a/src/r3-api-query-logins-applications.js b/src/r3-api-query-logins-applications.js new file mode 100644 index 0000000..7a8bfe7 --- /dev/null +++ b/src/r3-api-query-logins-applications.js @@ -0,0 +1,27 @@ +/** + * R3.API.Query.Logins.Applications + * @param apiComponent + * @constructor + */ +R3.API.Query.Logins.Applications = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__; + + /** + * Override the loginType + */ + if (R3.Utils.UndefinedOrNull(apiComponent.loginType)) { + apiComponent.loginType = R3.API.Query.LOGIN_TYPE_APPLICATION; + } + + R3.API.Query.Logins.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Logins.Applications.prototype = Object.create(R3.API.Query.Logins.prototype); +R3.API.Query.Logins.Applications.prototype.constructor = R3.API.Query.Logins.Applications; diff --git a/src/r3-api-query-logins-devices.js b/src/r3-api-query-logins-devices.js new file mode 100644 index 0000000..8435e88 --- /dev/null +++ b/src/r3-api-query-logins-devices.js @@ -0,0 +1,27 @@ +/** + * R3.API.Query.Logins.Devices + * @param apiComponent + * @constructor + */ +R3.API.Query.Logins.Devices = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__; + + /** + * Override the loginType + */ + if (R3.Utils.UndefinedOrNull(apiComponent.loginType)) { + apiComponent.loginType = R3.API.Query.LOGIN_TYPE_DEVICE; + } + + R3.API.Query.Logins.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Logins.Devices.prototype = Object.create(R3.API.Query.Logins.prototype); +R3.API.Query.Logins.Devices.prototype.constructor = R3.API.Query.Logins.Devices; diff --git a/src/r3-api-query-logins-vpn.js b/src/r3-api-query-logins-vpn.js new file mode 100644 index 0000000..b80b841 --- /dev/null +++ b/src/r3-api-query-logins-vpn.js @@ -0,0 +1,27 @@ +/** + * R3.API.Query.Logins.VPN + * @param apiComponent + * @constructor + */ +R3.API.Query.Logins.VPN = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__; + + /** + * Override the loginType + */ + if (R3.Utils.UndefinedOrNull(apiComponent.loginType)) { + apiComponent.loginType = R3.API.Query.LOGIN_TYPE_VPN; + } + + R3.API.Query.Logins.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Logins.VPN.prototype = Object.create(R3.API.Query.Logins.prototype); +R3.API.Query.Logins.VPN.prototype.constructor = R3.API.Query.Logins.VPN; diff --git a/src/r3-api-query-userDevices-0.js b/src/r3-api-query-userDevices-0.js new file mode 100644 index 0000000..ce086fb --- /dev/null +++ b/src/r3-api-query-userDevices-0.js @@ -0,0 +1,34 @@ +/** + * R3.API.Query.UserDevices + * @param apiComponent + * @constructor + */ +R3.API.Query.UserDevices = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.path)) { + apiComponent.path = '/crud/user_devices.json'; + } + this.path = apiComponent.path; + + if (R3.Utils.UndefinedOrNull(apiComponent.httpMethod)) { + apiComponent.httpMethod = 'GET'; + } + this.httpMethod = apiComponent.httpMethod; + + if (R3.Utils.UndefinedOrNull(apiComponent.text)) { + apiComponent.text = ''; + } + this.text = apiComponent.text; + + R3.API.Query.call( + this, + apiComponent + ); +}; + +R3.API.Query.UserDevices.prototype = Object.create(R3.API.Query.prototype); +R3.API.Query.UserDevices.prototype.constructor = R3.API.Query.UserDevices; diff --git a/src/r3-api-query-users.js b/src/r3-api-query-users.js new file mode 100644 index 0000000..2551630 --- /dev/null +++ b/src/r3-api-query-users.js @@ -0,0 +1,35 @@ +/** + * R3.API.Query.Users + * @param apiComponent + * @constructor + */ +R3.API.Query.Users = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.path)) { + apiComponent.path = '/crud/users.json'; + } + this.path = apiComponent.path; + + if (R3.Utils.UndefinedOrNull(apiComponent.httpMethod)) { + apiComponent.httpMethod = 'GET'; + } + this.httpMethod = apiComponent.httpMethod; + + if (R3.Utils.UndefinedOrNull(apiComponent.text)) { + apiComponent.text = ''; + } + this.text = apiComponent.text; + + R3.API.Query.call( + this, + apiComponent + ); + +}; + +R3.API.Query.Users.prototype = Object.create(R3.API.Query.prototype); +R3.API.Query.Users.prototype.constructor = R3.API.Query.Users; diff --git a/src/r3-api-renderer-0.js b/src/r3-api-renderer-0.js new file mode 100644 index 0000000..d3a7cd0 --- /dev/null +++ b/src/r3-api-renderer-0.js @@ -0,0 +1,28 @@ +/** + * R3.API.Renderer + * @constructor + * @param apiComponent + */ +R3.API.Renderer = function( + apiComponent +) { + __DEFINE_API_COMPONENT__ +}; + +R3.API.Renderer.prototype = Object.create(R3.API.Component.prototype); +R3.API.Renderer.prototype.constructor = R3.API.Renderer; + +R3.API.Renderer.MODE_CANVAS = 0x1; +R3.API.Renderer.MODE_TARGET = 0x2; +R3.API.Renderer.MODE_CANVAS_AND_TARGET = 0x3; + +R3.API.Renderer.SHADOW_MAP_TYPE_BASIC = 0; +R3.API.Renderer.SHADOW_MAP_TYPE_PCF = 1; +R3.API.Renderer.SHADOW_MAP_TYPE_PCF_SOFT = 2; + +R3.API.Renderer.TONE_MAPPING_NONE = 0; +R3.API.Renderer.TONE_MAPPING_LINEAR = 1; +R3.API.Renderer.TONE_MAPPING_REINHARD = 2; +R3.API.Renderer.TONE_MAPPING_UNCHARTED_2 = 3; +R3.API.Renderer.TONE_MAPPING_CINEON = 4; +R3.API.Renderer.TONE_MAPPING_ACES_FILMIC = 5; diff --git a/src/r3-api-renderer-d2.js b/src/r3-api-renderer-d2.js new file mode 100644 index 0000000..4b70d7a --- /dev/null +++ b/src/r3-api-renderer-d2.js @@ -0,0 +1,33 @@ +/** + * R3.API.Renderer.D2 + * @param apiComponent + * + * @property canvas + * + * @constructor + */ +R3.API.Renderer.D2 = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.canvas)) { + apiComponent.canvas = new R3.API.Canvas( + { + parent : this, + name : this.name + ' - Canvas' + } + ); + } + this.canvas = apiComponent.canvas; + + R3.API.Renderer.call( + this, + apiComponent + ); + +}; + +R3.API.Renderer.D2.prototype = Object.create(R3.API.Renderer.prototype); +R3.API.Renderer.D2.prototype.constructor = R3.API.Renderer.D2; diff --git a/src/r3-api-renderer-d3-0.js b/src/r3-api-renderer-d3-0.js new file mode 100644 index 0000000..7a1a093 --- /dev/null +++ b/src/r3-api-renderer-d3-0.js @@ -0,0 +1,295 @@ +/** + * R3.API.Renderer.D3 + * @param apiComponent + * + * @property autoClear + * @property autoClearColor + * @property autoClearDepth + * @property autoClearStencil + * @property gammaFactor + * @property gammaInput + * @property gammaOutput + * @property maxMorphTargets + * @property maxMorphNormals + * @property physicallyCorrectLights + * @property shadowMapEnabled + * @property shadowMapAutoUpdate + * @property shadowMapNeedsUpdate + * @property shadowMapType + * @property shadowMapRenderReverseSided + * @property shadowMapRenderSingleSided + * @property sortObjects + * @property toneMapping + * @property toneMappingExposure + * @property toneMappingWhitePoint + * @property premultipliedAlpha + * @property antialias + * @property stencil + * @property preserveDrawingBuffer + * @property depth + * @property logarithmicDepthBuffer + * @property localClippingEnabled + * @property clippingPlanes + * @property clearColor + * @property viewports + * @property alpha + * @property opacity + * @property pixelRatio + * + * @constructor + */ +R3.API.Renderer.D3 = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.autoClear)) { + apiComponent.autoClear = true; + } + this.autoClear = apiComponent.autoClear; + + if (R3.Utils.UndefinedOrNull(apiComponent.autoClearColor)) { + apiComponent.autoClearColor = true; + } + this.autoClearColor = apiComponent.autoClearColor; + + if (R3.Utils.UndefinedOrNull(apiComponent.autoClearDepth)) { + apiComponent.autoClearDepth = true; + } + this.autoClearDepth = apiComponent.autoClearDepth; + + if (R3.Utils.UndefinedOrNull(apiComponent.autoClearStencil)) { + apiComponent.autoClearStencil = true; + } + this.autoClearStencil = apiComponent.autoClearStencil; + + if (R3.Utils.UndefinedOrNull(apiComponent.gammaFactor)) { + apiComponent.gammaFactor = 2; + } + this.gammaFactor = apiComponent.gammaFactor; + + if (R3.Utils.UndefinedOrNull(apiComponent.gammaInput)) { + apiComponent.gammaInput = false; + } + this.gammaInput = apiComponent.gammaInput; + + if (R3.Utils.UndefinedOrNull(apiComponent.gammaOutput)) { + apiComponent.gammaOutput = false; + } + this.gammaOutput = apiComponent.gammaOutput; + + if (R3.Utils.UndefinedOrNull(apiComponent.maxMorphTargets)) { + apiComponent.maxMorphTargets = 8; + } + this.maxMorphTargets = apiComponent.maxMorphTargets; + + if (R3.Utils.UndefinedOrNull(apiComponent.maxMorphNormals)) { + apiComponent.maxMorphNormals = 4; + } + this.maxMorphNormals = apiComponent.maxMorphNormals; + + if (R3.Utils.UndefinedOrNull(apiComponent.physicallyCorrectLights)) { + apiComponent.physicallyCorrectLights = false; + } + this.physicallyCorrectLights = apiComponent.physicallyCorrectLights; + + if (R3.Utils.UndefinedOrNull(apiComponent.shadowMapEnabled)) { + apiComponent.shadowMapEnabled = false; + } + this.shadowMapEnabled = apiComponent.shadowMapEnabled; + + if (R3.Utils.UndefinedOrNull(apiComponent.shadowMapAutoUpdate)) { + apiComponent.shadowMapAutoUpdate = true; + } + this.shadowMapAutoUpdate = apiComponent.shadowMapAutoUpdate; + + if (R3.Utils.UndefinedOrNull(apiComponent.shadowMapNeedsUpdate)) { + apiComponent.shadowMapNeedsUpdate = false; + } + this.shadowMapNeedsUpdate = apiComponent.shadowMapNeedsUpdate; + + if (R3.Utils.UndefinedOrNull(apiComponent.shadowMapType)) { + apiComponent.shadowMapType = R3.API.Renderer.SHADOW_MAP_TYPE_BASIC; + } + this.shadowMapType = apiComponent.shadowMapType; + + if (R3.Utils.UndefinedOrNull(apiComponent.sortObjects)) { + apiComponent.sortObjects = true; + } + this.sortObjects = apiComponent.sortObjects; + + if (R3.Utils.UndefinedOrNull(apiComponent.toneMapping)) { + apiComponent.toneMapping = R3.API.Renderer.TONE_MAPPING_LINEAR; + } + this.toneMapping = apiComponent.toneMapping; + this.guiInfo.toneMapping = { + options : [ + { + name : 'none', + value : R3.API.Renderer.TONE_MAPPING_NONE + }, + { + name : 'linear', + value : R3.API.Renderer.TONE_MAPPING_LINEAR + }, + { + name : 'reinhard', + value : R3.API.Renderer.TONE_MAPPING_REINHARD + }, + { + name : 'uncharted 2', + value : R3.API.Renderer.TONE_MAPPING_UNCHARTED_2 + }, + { + name : 'cineon', + value : R3.API.Renderer.TONE_MAPPING_CINEON + }, + { + name : 'filmic', + value : R3.API.Renderer.TONE_MAPPING_ACES_FILMIC + }, + ] + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.toneMappingExposure)) { + apiComponent.toneMappingExposure = 1; + } + this.toneMappingExposure = apiComponent.toneMappingExposure; + this.guiInfo.toneMappingExposure = { + range: [0, 16], + step: 0.001, + dp: 3 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.toneMappingWhitePoint)) { + apiComponent.toneMappingWhitePoint = 1; + } + this.toneMappingWhitePoint = apiComponent.toneMappingWhitePoint; + this.guiInfo.toneMappingWhitePoint = { + range: [0, 16], + step: 0.001, + dp: 3 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.premultipliedAlpha)) { + apiComponent.premultipliedAlpha = true; + } + this.premultipliedAlpha = apiComponent.premultipliedAlpha; + + if (R3.Utils.UndefinedOrNull(apiComponent.antialias)) { + apiComponent.antialias = false; + } + this.antialias = apiComponent.antialias; + + if (R3.Utils.UndefinedOrNull(apiComponent.stencil)) { + apiComponent.stencil = true; + } + this.stencil = apiComponent.stencil; + + if (R3.Utils.UndefinedOrNull(apiComponent.preserveDrawingBuffer)) { + apiComponent.preserveDrawingBuffer = false; + } + this.preserveDrawingBuffer = apiComponent.preserveDrawingBuffer; + + if (R3.Utils.UndefinedOrNull(apiComponent.depth)) { + apiComponent.depth = true; + } + this.depth = apiComponent.depth; + + if (R3.Utils.UndefinedOrNull(apiComponent.logarithmicDepthBuffer)) { + apiComponent.logarithmicDepthBuffer = false; + } + this.logarithmicDepthBuffer = apiComponent.logarithmicDepthBuffer; + + if (R3.Utils.UndefinedOrNull(apiComponent.localClippingEnabled)) { + apiComponent.localClippingEnabled = false; + } + this.localClippingEnabled = apiComponent.localClippingEnabled; + + if (R3.Utils.UndefinedOrNull(apiComponent.clippingPlanes)) { + apiComponent.clippingPlanes = []; + } + this.clippingPlanes = apiComponent.clippingPlanes; + + if (R3.Utils.UndefinedOrNull(apiComponent.clearColor)) { + apiComponent.clearColor = new R3.API.Color( + { + parent : this, + register : true, + name : this.name + ' - Clear Color', + r : 0, + g : 0.129, + b : 0.184 + } + ); + } + this.clearColor = apiComponent.clearColor; + + if (R3.Utils.UndefinedOrNull(apiComponent.viewports)) { + apiComponent.viewports = [ + new R3.D3.API.Viewport.FixedAspect( + { + parent : this, + name : this.name + ' - Fixed Aspect Viewport' + } + ) + ]; + } + this.viewports = apiComponent.viewports; + + if (R3.Utils.UndefinedOrNull(apiComponent.scenes)) { + apiComponent.scenes = [new R3.D3.API.Scene( + { + parent : this, + name : this.name + ' - Scene', + viewports : this.viewports + } + )]; + } + this.scenes = apiComponent.scenes; + + if (R3.Utils.UndefinedOrNull(apiComponent.alpha)) { + apiComponent.alpha = true; + } + this.alpha = apiComponent.alpha; + + if (R3.Utils.UndefinedOrNull(apiComponent.opacity)) { + apiComponent.opacity = 1; + } + this.opacity = apiComponent.opacity; + this.guiInfo.opacity = { + range: [0, 1], + step: 0.001, + dp: 3 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.pixelRatio)) { + apiComponent.pixelRatio = window.devicePixelRatio; + } + this.pixelRatio = apiComponent.pixelRatio; + this.guiInfo.pixelRatio = { + range: [0, 4], + step: 0.001, + dp: 3 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.enableComposer)) { + apiComponent.enableComposer = true; + } + this.enableComposer = apiComponent.enableComposer; + + if (R3.Utils.UndefinedOrNull(apiComponent.enableEffect)) { + apiComponent.enableEffect = false; + } + this.enableEffect = apiComponent.enableEffect; + + R3.API.Renderer.call( + this, + apiComponent + ); + +}; + +R3.API.Renderer.D3.prototype = Object.create(R3.API.Renderer.prototype); +R3.API.Renderer.D3.prototype.constructor = R3.API.Renderer.D3; diff --git a/src/r3-api-renderer-d3-canvas-0.js b/src/r3-api-renderer-d3-canvas-0.js new file mode 100644 index 0000000..73d20ff --- /dev/null +++ b/src/r3-api-renderer-d3-canvas-0.js @@ -0,0 +1,69 @@ +/** + * R3.API.Renderer.D3.Canvas + * @param apiComponent + * + * @property canvas + * + * @constructor + */ +R3.API.Renderer.D3.Canvas = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.canvas)) { + apiComponent.canvas = new R3.API.Canvas( + { + parent : this, + name : this.name + ' - Canvas' + } + ); + } + this.canvas = apiComponent.canvas; + + R3.API.Renderer.D3.call( + this, + apiComponent + ); + +}; + +R3.API.Renderer.D3.Canvas.prototype = Object.create(R3.API.Renderer.D3.prototype); +R3.API.Renderer.D3.Canvas.prototype.constructor = R3.API.Renderer.D3.Canvas; + +R3.API.Renderer.D3.Canvas.prototype.getSize = function(viewport) { + + if (R3.Utils.UndefinedOrNull(viewport)) { + viewport = null; + } + + if (viewport) { + return { + width : this.canvas.width * viewport.width, + height : this.canvas.height * viewport.height + } + } + + return { + width : this.canvas.width, + height : this.canvas.height + } + +}; + +R3.API.Renderer.D3.Canvas.prototype.getCanvasAspectRatio = function() { + + return this.canvas.width / this.canvas.height; + +}; + +R3.API.Renderer.D3.Canvas.prototype.getCanvasSize = function() { + + return { + width : this.canvas.width, + height : this.canvas.height, + aspectRatio : this.canvas.width / this.canvas.height + }; + +}; \ No newline at end of file diff --git a/src/r3-api-renderer-d3-canvas-target.js b/src/r3-api-renderer-d3-canvas-target.js new file mode 100644 index 0000000..3d486d3 --- /dev/null +++ b/src/r3-api-renderer-d3-canvas-target.js @@ -0,0 +1,40 @@ +/** + * R3.API.Renderer.D3.Canvas.Target + * @param apiComponent + * + * @property target + * + * @constructor + */ +R3.API.Renderer.D3.Canvas.Target = function( + apiComponent +) { + + R3.API.Renderer.D3.Canvas.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.target)) { + apiComponent.target = new R3.D3.API.RenderTarget( + { + parent : this + } + ); + } + this.target = apiComponent.target; +}; + +R3.API.Renderer.D3.Canvas.Target.prototype = Object.create(R3.API.Renderer.D3.Canvas.prototype); +R3.API.Renderer.D3.Canvas.Target.prototype.constructor = R3.API.Renderer.D3.Canvas.Target; + +/** + * Return the size of the target instead of the canvas + * @returns {{width: *, height: *}} + */ +R3.API.Renderer.D3.Canvas.Target.prototype.getSize = function() { + return { + width : this.target.width, + height : this.target.height + } +}; diff --git a/src/r3-api-scalar.js b/src/r3-api-scalar.js new file mode 100644 index 0000000..c2fdae9 --- /dev/null +++ b/src/r3-api-scalar.js @@ -0,0 +1,74 @@ +/** + * R3.API.Scalar + * @param apiComponent + * + * @property x + * @property y + * + * @constructor + */ +R3.API.Scalar = function( + apiComponent +) { + + __DEREGISTER_COMPONENT__; + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.value)) { + apiComponent.value = 0; + } + this.value = apiComponent.value; + + if (R3.Utils.UndefinedOrNull(apiComponent.range)) { + apiComponent.range = [-1, 1]; + } + this.range = apiComponent.range; + + if (R3.Utils.UndefinedOrNull(apiComponent.step)) { + apiComponent.step = 0.01; + } + this.step = apiComponent.step; + + if (R3.Utils.UndefinedOrNull(apiComponent.dp)) { + apiComponent.dp = 2; + } + this.dp = apiComponent.dp; + +}; + +R3.API.Scalar.prototype = Object.create(R3.API.Component.prototype); +R3.API.Scalar.prototype.constructor = R3.API.Scalar; + +/** + * Equals + * @param scalar + * @returns {boolean} + */ +R3.API.Scalar.prototype.equals = function(scalar) { + + if (this.value === scalar.value) { + return true; + } else { + return false; + } + +}; + +/** + * Add + * @param v + */ +R3.API.Scalar.prototype.add = function(scalar) { + this.value += scalar.value; + return this; +}; + +/** + * Subtract + * @param v + */ +R3.API.Scalar.prototype.subtract = function(scalar) { + this.value -= scalar.value; + return this; +}; diff --git a/src/r3-api-server.js b/src/r3-api-server.js new file mode 100644 index 0000000..7bf0259 --- /dev/null +++ b/src/r3-api-server.js @@ -0,0 +1,70 @@ +/** + * R3.API.Server + * @param apiComponent + * @property protocol + * @property context + * @property application + * @property domain + * @property ip + * @property preferIp - Set to true to use IP instead of resolving DNS at getUrl() runtime + * @property port + * @property protocols + * @constructor + */ +R3.API.Server = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.protocol)) { + apiComponent.protocol = R3.API.Server.PROTOCOL_HTTP_SSL; + } + this.protocol = apiComponent.protocol; + + if (R3.Utils.UndefinedOrNull(apiComponent.context)) { + apiComponent.context = null; + } + this.context = apiComponent.context; + + if (R3.Utils.UndefinedOrNull(apiComponent.application)) { + apiComponent.application = null; + } + this.application = apiComponent.application; + + if (R3.Utils.UndefinedOrNull(apiComponent.domain)) { + apiComponent.domain = null; + } + this.domain = apiComponent.domain; + + if (R3.Utils.UndefinedOrNull(apiComponent.ip)) { + apiComponent.ip = '127.0.0.1'; + } + this.ip = apiComponent.ip; + + if (R3.Utils.UndefinedOrNull(apiComponent.preferIp)) { + apiComponent.preferIp = false; + } + this.preferIp = apiComponent.preferIp; + + if (R3.Utils.UndefinedOrNull(apiComponent.port)) { + apiComponent.port = R3.API.Server.PORT_SECURE; + } + this.port = apiComponent.port; + + if (R3.Utils.UndefinedOrNull(apiComponent.protocols)) { + apiComponent.protocols = []; + } + this.protocols = apiComponent.protocols; +}; + +R3.API.Server.prototype = Object.create(R3.API.Component.prototype); +R3.API.Server.prototype.constructor = R3.API.Server; + +R3.API.Server.PROTOCOL_HTTP = 'http'; +R3.API.Server.PROTOCOL_HTTP_SSL = 'https'; +R3.API.Server.PROTOCOL_WEBSOCKET = 'ws'; +R3.API.Server.PROTOCOL_WEBSOCKET_SSL = 'wss'; + +R3.API.Server.PORT_INSECURE = 80; +R3.API.Server.PORT_SECURE = 443; diff --git a/src/r3-api-socket-0.js b/src/r3-api-socket-0.js new file mode 100644 index 0000000..8f39efd --- /dev/null +++ b/src/r3-api-socket-0.js @@ -0,0 +1,57 @@ +/** + * R3.API.Socket + * @param apiComponent + * @property roomId + * @property peerId + * @property server + * @constructor + */ +R3.API.Socket = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.roomId)) { + apiComponent.roomId = 'room_' + R3.Utils.RandomId(); + } + this.roomId = apiComponent.roomId; + + if (R3.Utils.UndefinedOrNull(apiComponent.peerId)) { + apiComponent.peerId = null; + } + this.peerId = apiComponent.peerId; + + if (R3.Utils.UndefinedOrNull(apiComponent.server)) { + R3.Event.Emit( + R3.Event.GET_WEBSOCKET_CONFIG, + 'hello', + function(websocketConfig) { + if (websocketConfig) { + apiComponent.server = new R3.API.Server( + { + parent : this, + protocol : websocketConfig.protocol, + context : websocketConfig.context, + application : websocketConfig.application, + domain : websocketConfig.domain + } + ); + } else { + apiComponent.server = new R3.API.Server( + { + parent : this, + protocol : R3.API.Server.PROTOCOL_WEBSOCKET_SSL + } + ); + } + } + ); + + } + this.server = apiComponent.server; + +}; + +R3.API.Socket.prototype = Object.create(R3.API.Component.prototype); +R3.API.Socket.prototype.constructor = R3.API.Socket; diff --git a/src/r3-api-socket-cast.js b/src/r3-api-socket-cast.js new file mode 100644 index 0000000..e5a9f4c --- /dev/null +++ b/src/r3-api-socket-cast.js @@ -0,0 +1,41 @@ +/** + * R3.API.Socket.Cast + * @param apiComponent + * @property castType + * @property source + * @property sourceProperties + * @constructor + */ +R3.API.Socket.Cast = function( + apiComponent +) { + + R3.API.Socket.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.castType)) { + apiComponent.castType = R3.API.Socket.Cast.CAST_TYPE_ROOM; + } + this.castType = apiComponent.castType; + + if (R3.Utils.UndefinedOrNull(apiComponent.source)) { + apiComponent.source = null; + } + this.source = apiComponent.source; + + if (R3.Utils.UndefinedOrNull(apiComponent.sourceProperties)) { + apiComponent.sourceProperties = null; + } + this.sourceProperties = apiComponent.sourceProperties; + +}; + +R3.API.Socket.Cast.prototype = Object.create(R3.API.Socket.prototype); +R3.API.Socket.Cast.prototype.constructor = R3.API.Socket.Cast; + +R3.API.Socket.Cast.CAST_TYPE_ROOM = 0x1; +R3.API.Socket.Cast.CAST_TYPE_PEER = 0x2; +R3.API.Socket.Cast.CAST_TYPE_ALL = 0x3; +R3.API.Socket.Cast.CAST_TYPE_ALL_BUT_PEER = 0x4; diff --git a/src/r3-api-socket-receive.js b/src/r3-api-socket-receive.js new file mode 100644 index 0000000..6178850 --- /dev/null +++ b/src/r3-api-socket-receive.js @@ -0,0 +1,39 @@ +/** + * R3.API.Socket.Receive + * @param apiComponent + * @property receiveType + * @property destination + * @property destinationProperties + * @constructor + */ +R3.API.Socket.Receive = function( + apiComponent +) { + + R3.API.Socket.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.receiveType)) { + apiComponent.receiveType = R3.API.Socket.Receive.RECEIVE_TYPE_ROOM; + } + this.receiveType = apiComponent.receiveType; + + if (R3.Utils.UndefinedOrNull(apiComponent.destination)) { + apiComponent.destination = null; + } + this.destination = apiComponent.destination; + + if (R3.Utils.UndefinedOrNull(apiComponent.destinationProperties)) { + apiComponent.destinationProperties = null; + } + this.destinationProperties = apiComponent.destinationProperties; + +}; + +R3.API.Socket.Receive.prototype = Object.create(R3.API.Socket.prototype); +R3.API.Socket.Receive.prototype.constructor = R3.API.Socket.Receive; + +R3.API.Socket.Receive.RECEIVE_TYPE_ROOM = 0x1; +R3.API.Socket.Receive.RECEIVE_TYPE_PEER = 0x2; diff --git a/src/r3-api-sphere.js b/src/r3-api-sphere.js new file mode 100644 index 0000000..33c059c --- /dev/null +++ b/src/r3-api-sphere.js @@ -0,0 +1,35 @@ +/** + * R3.API.Sphere + * @param apiComponent + * + * @property center + * @property radius + * + * @constructor + */ +R3.API.Sphere = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.center)) { + apiComponent.center = new R3.API.Vector3( + { + parent : this, + x : 0, + y : 0, + z : 0 + } + ); + } + this.center = apiComponent.center; + + if (R3.Utils.UndefinedOrNull(apiComponent.radius)) { + apiComponent.radius = 1; + } + this.radius = apiComponent.radius; +}; + +R3.API.Sphere.prototype = Object.create(R3.API.Sphere.prototype); +R3.API.Sphere.prototype.constructor = R3.API.Sphere; diff --git a/src/r3-api-stats.js b/src/r3-api-stats.js new file mode 100644 index 0000000..8f8d284 --- /dev/null +++ b/src/r3-api-stats.js @@ -0,0 +1,23 @@ +/** + * Raw Stats API object - should always correspond with the Stats Schema + * @param apiComponent + * + * @property domElement + * + * @constructor + */ +R3.API.Stats = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.domElement)) { + apiComponent.domElement = null; + } + this.domElement = apiComponent.domElement; + +}; + +R3.API.Stats.prototype = Object.create(R3.API.Component.prototype); +R3.API.Stats.prototype.constructor = R3.API.Stats; diff --git a/src/r3-api-user.js b/src/r3-api-user.js new file mode 100644 index 0000000..3b1418d --- /dev/null +++ b/src/r3-api-user.js @@ -0,0 +1,65 @@ +/** + * R3.API.User + * @param apiComponent + * + * @property googleId + * @property fullName + * @property givenName + * @property familyName + * @property imageUrl + * @property email + * @property uploadFolder + * @property idToken + * + * @constructor + */ +R3.API.User = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.googleId)) { + throw new Error('invalid user - no google ID'); + } + this.googleId = apiComponent.googleId; + + if (R3.Utils.UndefinedOrNull(apiComponent.fullName)) { + apiComponent.fullName = 'unknown full name'; + } + this.fullName = apiComponent.fullName; + + if (R3.Utils.UndefinedOrNull(apiComponent.givenName)) { + apiComponent.givenName = 'unknown given name'; + } + this.givenName = apiComponent.givenName; + + if (R3.Utils.UndefinedOrNull(apiComponent.familyName)) { + apiComponent.familyName = 'unknown family name'; + } + this.familyName = apiComponent.familyName; + + if (R3.Utils.UndefinedOrNull(apiComponent.imageUrl)) { + apiComponent.imageUrl = 'unknown image URL'; + } + this.imageUrl = apiComponent.imageUrl; + + if (R3.Utils.UndefinedOrNull(apiComponent.email)) { + throw new Error('invalid user - no email address'); + } + this.email = apiComponent.email; + + if (R3.Utils.UndefinedOrNull(apiComponent.uploadFolder)) { + apiComponent.uploadFolder = email.replace('/','_DS_'); + } + this.uploadFolder = apiComponent.uploadFolder; + + if (R3.Utils.UndefinedOrNull(apiComponent.idToken)) { + apiComponent.idToken = 'unknown ID token'; + } + this.idToken = apiComponent.idToken; + +}; + +R3.API.User.prototype = Object.create(R3.API.Component.prototype); +R3.API.User.prototype.constructor = R3.API.User; diff --git a/src/r3-api-vector2.js b/src/r3-api-vector2.js new file mode 100644 index 0000000..fd68aee --- /dev/null +++ b/src/r3-api-vector2.js @@ -0,0 +1,160 @@ +/** + * R3.API.Vector2 + * @param apiComponent + * + * @property x + * @property y + * + * @constructor + */ +R3.API.Vector2 = function( + apiComponent +) { + + __DEREGISTER_COMPONENT__; + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.x)) { + apiComponent.x = 0; + } + this.x = apiComponent.x; + + if (R3.Utils.UndefinedOrNull(apiComponent.y)) { + apiComponent.y = 0; + } + this.y = apiComponent.y; +}; + +R3.API.Vector2.prototype = Object.create(R3.API.Component.prototype); +R3.API.Vector2.prototype.constructor = R3.API.Vector2; + +/** + * Equals + * TODO: Test + * @param v + * @returns {boolean} + */ +R3.API.Vector2.prototype.equals = function(v) { + + if ((this.x === v.x) && + (this.y === v.y)) { + return true; + } else { + return false; + } + +}; + +/** + * Add + * TODO: Test + * @param v + */ +R3.API.Vector2.prototype.add = function(v) { + this.x += v.x; + this.y += v.y; + return this; +}; + +/** + * Subtract + * TODO: Test + * @param v + */ +R3.API.Vector2.prototype.subtract = function(v) { + this.x -= v.x; + this.y -= v.y; + return this; +}; + +/** + * Multiply + * TODO: Test + * @param v + */ +R3.API.Vector2.prototype.multiply = function(v) { + this.x *= v.x; + this.y *= v.y; + return this; +}; + +/** + * Divide + * TODO: Test + * @param v + */ +R3.API.Vector2.prototype.divide = function(v) { + this.x *= (1.0 / v.x); + this.y *= (1.0 / v.y); + return this; +}; + +/** + * Clamp + * TODO: Test + * @param min R3.API.Vector2 + * @param max R3.API.Vector2 + * @returns {R3.API.Vector2} + */ +R3.API.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} + */ +R3.API.Vector2.prototype.length = function() { + return Math.sqrt( + this.x * this.x + this.y * this.y + ); +}; + +/** + * Dot product + * TODO: Test + * @param v + * @returns {number} + */ +R3.API.Vector2.prototype.dot = function(v) { + return this.x * v.x + this.y * v.y; +}; + +/** + * Normalize + * TODO: Test + */ +R3.API.Vector2.prototype.normalize = function() { + return this.multiply(1.0 / this.length()); +}; + +/** + * TODO: Test + * Angle between this vector and origin + * @returns {number} + */ +R3.API.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 {R3.API.Vector2} + */ +R3.API.Vector2.prototype.lerp = function( v, alpha ) { + this.x += ( v.x - this.x ) * alpha; + this.y += ( v.y - this.y ) * alpha; + return this; +}; \ No newline at end of file diff --git a/src/r3-api-vector3.js b/src/r3-api-vector3.js new file mode 100644 index 0000000..19b2d62 --- /dev/null +++ b/src/r3-api-vector3.js @@ -0,0 +1,265 @@ +/** + * R3.API.Vector3 + * @param apiComponent + * + * @property x + * @property y + * @property z + * + * @constructor + */ +R3.API.Vector3 = function( + apiComponent +) { + + __DEREGISTER_COMPONENT__; + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.x)) { + apiComponent.x = 0; + } + this.x = apiComponent.x; + + if (R3.Utils.UndefinedOrNull(apiComponent.y)) { + apiComponent.y = 0; + } + this.y = apiComponent.y; + + if (R3.Utils.UndefinedOrNull(apiComponent.z)) { + apiComponent.z = 0; + } + this.z = apiComponent.z; + +}; + +R3.API.Vector3.prototype = Object.create(R3.API.Component.prototype); +R3.API.Vector3.prototype.constructor = R3.API.Vector3; + +R3.API.Vector3.prototype.setFrom = function(vector3) { + this.x = vector3.x; + this.y = vector3.y; + this.z = vector3.z; + return this; +}; + +R3.API.Vector3.prototype.negate = function() { + this.x = -this.x; + this.y = -this.y; + this.z = -this.z; + return this; +}; + +R3.API.Vector3.prototype.subtract = function(v) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + return this; +}; + +R3.API.Vector3.prototype.sub = function(v) { + return this.subtract(v); +}; + +R3.API.Vector3.prototype.equals = function(v) { + return this.x === v.x && this.y === v.y && this.z === v.z; +}; + +R3.API.Vector3.prototype.cross = function(v) { + var x = this.y * v.z - this.z * v.y; + var y = this.z * v.x - this.x * v.z; + var z = this.x * v.y - this.y * v.x; + this.x = x; + this.y = y; + this.z = z; + return this; +}; + +R3.API.Vector3.prototype.lookAt = function(at, up) { + console.warn('todo: implement R3.API.Vector3.prototype.lookAt()'); + // var lookAtMatrix = R3.API.Matrix4.lookAt(this, at, up); +// return this.multiply(lookAtMatrix); +}; + +R3.API.Vector3.prototype.translate = function(v) { + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; +}; + +R3.API.Vector3.prototype.add = function(v) { + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; +}; + +R3.API.Vector3.prototype.squared = function() { + return this.x * this.x + this.y * this.y + this.z * this.z; +}; + +R3.API.Vector3.prototype.copy = function() { + return new R3.API.Vector3( + this + ); +}; + +R3.API.Vector3.prototype.set = function(x, y, z) { + this.x = x; + this.y = y; + this.z = z; +}; + +R3.API.Vector3.prototype.lerp = function( v, alpha ) { + + var x = this.x + ( v.x - this.x ) * alpha; + var y = this.y + ( v.y - this.y ) * alpha; + var z = this.z + ( v.z - this.z ) * alpha; + + this.x = x; + this.y = y; + this.z = z; + + return this; +}; + +R3.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} + */ +R3.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 | R3.API.Vector3 | R3.Vector4 | R3.API.Matrix3 | R3.API.Matrix4} + * @param cross boolean true if you want the cross product, otherwise returns the scalar (dot or inner) product + * @returns {R3.API.Vector3 | Number} + */ +R3.API.Vector3.prototype.multiply = function(object, cross) { + + var x, y, z; + + var a = object; + var b = this; + + if (R3.Utils.UndefinedOrNull(apiComponent.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 R3.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"); + } +}; + + +R3.API.Vector3.prototype.dot = function(v) { + return (this.x * v.x) + (this.y * v.y) + (this.z * v.z); +}; + +R3.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); + + this.x *= invLength; + this.y *= invLength; + this.z *= invLength; + + return this; +}; + +R3.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; +}; + +R3.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; +}; + +R3.API.Vector3.prototype.length = function() { + return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); +}; + +R3.API.Vector3.prototype.reflect = function(normal) { + return this.sub( v1.copy( normal ).multiply( 2 * this.dot( normal ) ) ); +}; + +R3.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 ) ); +}; diff --git a/src/r3-api-vector4.js b/src/r3-api-vector4.js new file mode 100644 index 0000000..2bedf2b --- /dev/null +++ b/src/r3-api-vector4.js @@ -0,0 +1,43 @@ +/** + * R3.API.Vector4 + * @param apiComponent + * + * @property x + * @property y + * @property z + * @property w + * + * @constructor + */ +R3.API.Vector4 = function( + apiComponent +) { + + __DEREGISTER_COMPONENT__; + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.x)) { + apiComponent.x = 0; + } + this.x = apiComponent.x; + + if (R3.Utils.UndefinedOrNull(apiComponent.y)) { + apiComponent.y = 0; + } + this.y = apiComponent.y; + + if (R3.Utils.UndefinedOrNull(apiComponent.z)) { + apiComponent.z = 0; + } + this.z = apiComponent.z; + + if (R3.Utils.UndefinedOrNull(apiComponent.w)) { + apiComponent.w = 0; + } + this.w = apiComponent.w; + +}; + +R3.API.Vector4.prototype = Object.create(R3.API.Component.prototype); +R3.API.Vector4.prototype.constructor = R3.API.Vector4; diff --git a/src/r3-api-video.js b/src/r3-api-video.js new file mode 100644 index 0000000..ca3808d --- /dev/null +++ b/src/r3-api-video.js @@ -0,0 +1,56 @@ +/** + * R3.API.Video + * @param apiComponent + * + * @property autoUpdateSize + * @property width + * @property height + * @property offset + * @property source + * + * @constructor + */ +R3.API.Video = function( + apiComponent, +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.autoUpdateSize)) { + apiComponent.autoUpdateSize = true; + } + this.autoUpdateSize = apiComponent.autoUpdateSize; + + var size = R3.Utils.GetWindowSize(); + + if (R3.Utils.UndefinedOrNull(apiComponent.width)) { + apiComponent.width = size.width; + } + this.width = apiComponent.width; + + if (R3.Utils.UndefinedOrNull(apiComponent.height)) { + apiComponent.height = size.height; + } + this.height = apiComponent.height; + + if (R3.Utils.UndefinedOrNull(apiComponent.offset)) { + apiComponent.offset = new R3.API.Vector2( + { + parent : this, + register : true, + x : 0, + y : 0 + } + ); + } + this.offset = apiComponent.offset; + + if (R3.Utils.UndefinedOrNull(apiComponent.source)) { + apiComponent.source = null; + } + this.source = apiComponent.source; + +}; + +R3.API.Video.prototype = Object.create(R3.API.Component.prototype); +R3.API.Video.prototype.constructor = R3.API.Video; diff --git a/src/r3-box3.js b/src/r3-box3.js new file mode 100644 index 0000000..6c54736 --- /dev/null +++ b/src/r3-box3.js @@ -0,0 +1,67 @@ +/** + * R3.Box3 + * @param apiComponent + * @constructor + */ +R3.Box3 = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.Box3.prototype = Object.create(R3.Component.prototype); +R3.Box3.prototype.constructor = R3.Box3; + +/** + * Creates an instance R3.Box3 + * @returns {*} + */ +R3.Box3.prototype.createInstance = function() { + + switch (this.parent.runtime) { + case R3.Runtime.GRAPHICS : + this.instance = this.graphics.Box3( + this.min, + this.max + ); + break; + case R3.Runtime.PHYSICS : + this.instance = this.physics.Box3( + this.min, + this.max + ); + break; + default: + throw new Error('unhandled component runtime: ' + this.componentRuntime); + } + + __CREATE_INSTANCE__; + +}; + +/** + * Updates R3.Box3 instance + * @param property + */ +R3.Box3.prototype.updateInstance = function(property) { + + if (property === 'min') { + this.instance.min.x = this.min.x; + this.instance.min.y = this.min.y; + this.instance.min.z = this.min.z; + return; + } + + if (property === 'max') { + this.instance.max.x = this.max.x; + this.instance.max.y = this.max.y; + this.instance.max.z = this.max.z; + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-canvas.js b/src/r3-canvas.js new file mode 100644 index 0000000..8747adc --- /dev/null +++ b/src/r3-canvas.js @@ -0,0 +1,275 @@ +/** + * R3.Canvas + * @param apiComponent + * @constructor + */ +R3.Canvas = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.context = null; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Canvas.prototype = Object.create(R3.Component.prototype); +R3.Canvas.prototype.constructor = R3.Canvas; + +/** + * Creates a light instance + * @returns {*} + */ +R3.Canvas.prototype.createInstance = function() { + + this.instance = this.graphics.Canvas(this); + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.Canvas.prototype.updateInstance = function(property) { + + if (R3.Utils.UndefinedOrNull(property)) { + console.warn('unknown property update for Canvas: ' + property); + } + + if (property === 'id') { + this.instance.setAttribute('id', this.id); + return; + } + + if (property === 'tabIndex') { + this.instance.setAttribute('tabIndex', this.tabIndex); + return; + } + + if (property === 'width') { + this.instance.setAttribute('width', this.width); + this.instance.setAttribute('style', 'width:' + this.width + 'px;height:' + this.height + 'px'); + R3.Event.Emit( + R3.Event.CANVAS_RESIZE, + this + ); + return; + } + + if (property === 'height') { + this.instance.setAttribute('height', this.height); + this.instance.setAttribute('style', 'width:' + this.width + 'px;height:' + this.height + 'px'); + R3.Event.Emit( + R3.Event.CANVAS_RESIZE, + this + ); + return; + } + + if (property === 'autoUpdateSize') { + /** + * TODO : whatever - can't remember what the purpose of this stupid property was... + */ + console.log('whatever'); + return; + + /** + * We cannot control everything about the canvas - this is dependent on where the canvas lives and its + * dimensions can also be controlled via CSS - + * + * This means - autoUpdateSize works a little different for this component - instead of getting our size and + * applying it, it gets our canvas size and applies it, or applies our size to the canvas - of course + * the user settings override this. + */ + if (this.autoUpdateSize) { + + /** + * Update from our canvas size + */ + this.width = this.instance.getAttribute('width'); + this.height = this.instance.getAttribute('height'); + } else { + + /** + * Command our canvas to take a size - this is not guaranteed however - CSS wins + */ + this.instance.setAttribute('width', this.width); + this.instance.setAttribute('height', this.height); + } + return; + } + + if (property === 'texts') { + this.writeText(); + return; + } + + if (property === 'textBaseLine') { + if (!this.context) { + this.context = this.instance.getContext('2d'); + } + this.context.textBaseline = this.textBaseline; + return; + } + + __UPDATE_INSTANCE__; +}; + +R3.Canvas.prototype.writeText = function() { + + var parentTexture = this.getFirstParent(R3.D3.Texture); + + this.clear(); + + this.texts.map( + + function(text){ + + if (!this.context) { + this.context = this.instance.getContext('2d'); + } + + this.context.fillStyle = text.fillStyle; + this.context.font = text.font; + this.context.fillText(text.value, text.offset.x, text.offset.y); + + if (parentTexture && parentTexture.instance) { + parentTexture.instance.needsUpdate = true; + } + + }.bind(this) + ); +}; + +R3.Canvas.prototype.clear = function() { + + if (!this.context) { + this.context = this.instance.getContext('2d'); + } + + this.context.clearRect(0, 0, this.width, this.height); +}; + +R3.Canvas.prototype.filledRectangle = function( + x, + y, + width, + height, + fillStyle +) { + + if (!this.context) { + this.context = this.instance.getContext('2d'); + } + + if (fillStyle) { + this.context.fillStyle = fillStyle; + } + + this.context.fillRect(x, y, width, height); +}; + +R3.Canvas.prototype.outlineRectangle = function( + x, + y, + width, + height, + lineWidth, + strokeStyle +) { + + if (!this.context) { + this.context = this.instance.getContext('2d'); + } + + if (lineWidth) { + this.context.lineWidth = lineWidth; + } + + if (strokeStyle) { + this.context.strokeStyle = strokeStyle; + } + + this.context.fillRect(x, y, width, height); +}; + +R3.Canvas.prototype.line = function( + x, + y, + endX, + endY, + lineWidth, + strokeStyle +) { + + if (!this.context) { + this.context = this.instance.getContext('2d'); + } + + if (lineWidth) { + this.context.lineWidth = lineWidth; + } + + if (strokeStyle) { + this.context.strokeStyle = strokeStyle; + } + + this.context.beginPath(); + this.context.moveTo(x, y); + this.context.lineTo(endX, endY); + this.context.stroke(); +}; + +R3.Canvas.prototype.text = function( + text, + x, + y, + font, + fillStyle +) { + + if (!this.context) { + this.context = this.instance.getContext('2d'); + } + + if (font) { + this.context.font = font; + } + + if (fillStyle) { + this.context.fillStyle = fillStyle; + } + + this.context.fillText(text, x, y); +}; + +R3.Canvas.prototype.image = function( + image, + x, + y, + width, + height, + sx, + sy, + swidth, + sheight +) { + + if (!this.context) { + this.context = this.instance.getContext('2d'); + } + + if (sx && sy && swidth && sheight) { + this.context.drawImage(image, sx, sy, swidth, sheight, x, y, width, height); + return; + } + + if (width && height) { + this.context.drawImage(image, x, y, width, height); + return; + } + + this.context.drawImage(image, x, y); +}; diff --git a/src/r3-clock.js b/src/r3-clock.js new file mode 100644 index 0000000..3f69e1a --- /dev/null +++ b/src/r3-clock.js @@ -0,0 +1,45 @@ +/** + * R3.Clock + * @param apiComponent + * @constructor + */ +R3.Clock = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +} ; + +R3.Clock.prototype = Object.create(R3.Component.prototype); +R3.Clock.prototype.constructor = R3.Clock; + +/** + * R3.Clock.prototype.createInstance + */ +R3.Clock.prototype.createInstance = function() { + + this.instance = this.graphics.Clock(); + + __CREATE_INSTANCE__; +}; + +/** + * R3.Clock.prototype.updateInstance + * @param property + */ +R3.Clock.prototype.updateInstance = function(property) { + + __UPDATE_INSTANCE; + +}; + +R3.Clock.prototype.getDelta = function() { + + this.delta = this.instance.getDelta(); + + return this.delta; + +}; diff --git a/src/r3-color.js b/src/r3-color.js new file mode 100644 index 0000000..7512b28 --- /dev/null +++ b/src/r3-color.js @@ -0,0 +1,132 @@ +/** + * R3.Color + * @param apiComponent + * @constructor + */ +R3.Color = function( + apiComponent +) { + + __DEREGISTER_COMPONENT__; + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Color.prototype = Object.create(R3.Component.prototype); +R3.Color.prototype.constructor = R3.Color; + +/** + * Creates an instance color + * @returns {*} + */ +R3.Color.prototype.createInstance = function() { + + this.instance = this.graphics.Color( + this.r, + this.g, + this.b, + this.a + ); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance color, calls updateInstance on the parent object + */ +R3.Color.prototype.updateInstance = function(property) { + + if (property === 'r') { + this.instance.r = this.r; + return; + } + + if (property === 'g') { + this.instance.g = this.g; + return; + } + + if (property === 'b') { + this.instance.b = this.b; + return; + } + + if (property === 'a') { + this.instance.a = this.a; + return; + } + + __UPDATE_INSTANCE__; +}; + + +/** + * Converts the current color to HTML hex format (ex. #ffffff) + * @returns {string} + */ +R3.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} + */ +R3.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; + + this.instance.r = this.r; + this.instance.g = this.g; + this.instance.b = this.b; +}; diff --git a/src/r3-controls-0.js b/src/r3-controls-0.js new file mode 100644 index 0000000..3c391ab --- /dev/null +++ b/src/r3-controls-0.js @@ -0,0 +1,37 @@ +/** + * R3.Controls + * @constructor + */ +R3.Controls = function( + inherited +) { + + __INHERIT_ONLY__ + + this.linkedComponents.canvas = R3.Canvas; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Controls.prototype = Object.create(R3.Component.prototype); +R3.Controls.prototype.constructor = R3.Controls; + +/** + * R3.Controls.prototype.updateInstance + * @param property + */ +R3.Controls.prototype.updateInstance = function(property) { + + if (property === 'canvas') { + R3.Event.Emit( + R3.Event.CONTROLS_CANVAS_CHANGE, + { + component: this + } + ); + return; + } + + __UPDATE_INSTANCE__; +}; diff --git a/src/r3-controls-d3-0.js b/src/r3-controls-d3-0.js new file mode 100644 index 0000000..9d173ec --- /dev/null +++ b/src/r3-controls-d3-0.js @@ -0,0 +1,37 @@ +/** + * R3.Controls.D3 + * @constructor + */ +R3.Controls.D3 = function( + inherited +) { + + __INHERIT_ONLY__ + + this.linkedComponents.camera = R3.D3.Camera; + + R3.Controls.call( + this, + true + ); + +}; + +R3.Controls.D3.prototype = Object.create(R3.Controls.prototype); +R3.Controls.D3.prototype.constructor = R3.Controls.D3; + +R3.Controls.D3.prototype.updateInstance = function(property) { + + if (property === 'camera') { + console.warn('update camera instance update'); + return; + } + + if (property === 'enabled') { + this.instance.enabled = this.enabled; + return; + } + + R3.Controls.prototype.updateInstance.call(this, property); + +}; \ No newline at end of file diff --git a/src/r3-controls-d3-firstPerson.js b/src/r3-controls-d3-firstPerson.js new file mode 100644 index 0000000..902f4b2 --- /dev/null +++ b/src/r3-controls-d3-firstPerson.js @@ -0,0 +1,107 @@ +/** + * R3.Controls.D3.FirstPerson + * @param apiComponent + * @constructor + */ +R3.Controls.D3.FirstPerson = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Controls.D3.call( + this, + true + ); + +}; + +/** + * Inheritance + * @type {R3.Controls} + */ +R3.Controls.D3.FirstPerson.prototype = Object.create(R3.Controls.D3.prototype); +R3.Controls.D3.FirstPerson.prototype.constructor = R3.Controls.D3.FirstPerson; + +/** + * Create Instance + */ +R3.Controls.D3.FirstPerson.prototype.createInstance = function() { + + this.instance = this.graphics.FirstPersonControls(this); + + __CREATE_INSTANCE__; +}; + +/** + * Update Instance + */ +R3.Controls.D3.FirstPerson.prototype.updateInstance = function(property) { + + if (property === 'movementSpeed') { + this.instance.movementSpeed = this.movementSpeed; + return; + } + + if (property === 'lookSpeed') { + this.instance.lookSpeed = this.lookSpeed; + return; + } + + if (property === 'lookVertical') { + this.instance.lookVertical = this.lookVertical; + return; + } + + if (property === 'autoForward') { + this.instance.autoForward = this.autoForward; + return; + } + + if (property === 'activeLook') { + this.instance.activeLook = this.activeLook; + return; + } + + if (property === 'heightSpeed') { + this.instance.heightSpeed = this.heightSpeed; + return; + } + + if (property === 'heightCoef') { + this.instance.heightCoef = this.heightCoef; + return; + } + + if (property === 'heightMin') { + this.instance.heightMin = this.heightMin; + return; + } + + if (property === 'heightMax') { + this.instance.heightMax = this.heightMax; + return; + } + + if (property === 'constrainVertical') { + this.instance.constrainVertical = this.constrainVertical; + return; + } + + if (property === 'verticalMin') { + this.instance.verticalMin = this.verticalMin; + return; + } + + if (property === 'verticalMax') { + this.instance.verticalMax = this.verticalMax; + return; + } + + if (property === 'autoSpeedFactor') { + this.instance.autoSpeedFactor = this.autoSpeedFactor; + return; + } + + R3.Controls.D3.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-controls-d3-orbit.js b/src/r3-controls-d3-orbit.js new file mode 100644 index 0000000..8b3955f --- /dev/null +++ b/src/r3-controls-d3-orbit.js @@ -0,0 +1,115 @@ +/** + * R3.Controls.D3.Orbit + * @param apiComponent + * @constructor + */ +R3.Controls.D3.Orbit = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.linkedComponents.target = R3.D3.Object; + + R3.Controls.D3.call( + this, + true + ); + +}; + +R3.Controls.D3.Orbit.prototype = Object.create(R3.Controls.D3.prototype); +R3.Controls.D3.Orbit.prototype.constructor = R3.Controls.D3.Orbit; + +/** + * Create Instance + */ +R3.Controls.D3.Orbit.prototype.createInstance = function() { + + this.instance = this.graphics.OrbitControls(this); + + __CREATE_INSTANCE__; +}; + +/** + * Update Instance + */ +R3.Controls.D3.Orbit.prototype.updateInstance = function(property) { + + if (property === 'target') { + + if (this.target && this.target.instance) { + this.instance.target = this.target.instance.position; + } else { + this.instance.target = new this.graphics.Vector3(); + } + return; + } + + if (property === 'minPolarAngle') { + this.instance.minPolarAngle = this.minPolarAngle; + return; + } + + if (property === 'maxPolarAngle') { + this.instance.maxPolarAngle = this.maxPolarAngle; + return; + } + + if (property === 'enableDamping') { + this.instance.enableDamping = this.enableDamping; + return; + } + + if (property === 'dampingFactor') { + this.instance.dampingFactor = this.dampingFactor; + return; + } + + if (property === 'enableZoom') { + this.instance.enableZoom = this.enableZoom; + return; + } + + if (property === 'zoomSpeed') { + this.instance.zoomSpeed = this.zoomSpeed; + return; + } + + if (property === 'enableRotate') { + this.instance.enableRotate = this.enableRotate; + return; + } + + if (property === 'rotateSpeed') { + this.instance.rotateSpeed = this.rotateSpeed; + return; + } + + if (property === 'enablePan') { + this.instance.enablePan = this.enablePan; + return; + } + + if (property === 'keyPanSpeed') { + this.instance.keyPanSpeed = this.keyPanSpeed; + return; + } + + if (property === 'autoRotate') { + this.instance.autoRotate = this.autoRotate; + return; + } + + if (property === 'autoRotateSpeed') { + this.instance.autoRotateSpeed = this.autoRotateSpeed; + return; + } + + if (property === 'enableKeys') { + this.instance.enableKeys = this.enableKeys; + return; + } + + R3.Controls.D3.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-controls-keyboard.js b/src/r3-controls-keyboard.js new file mode 100644 index 0000000..6f426db --- /dev/null +++ b/src/r3-controls-keyboard.js @@ -0,0 +1,39 @@ +/** + * R3.Controls.Keyboard + * @param apiComponent + * @constructor + */ +R3.Controls.Keyboard = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Controls.call( + this, + true + ); +}; + +/** + * Inheritance + * @type {R3.Controls} + */ +R3.Controls.Keyboard.prototype = Object.create(R3.Controls.prototype); +R3.Controls.Keyboard.prototype.constructor = R3.Controls.Keyboard; + +/** + * Create Instance + * @returns + */ +R3.Controls.Keyboard.prototype.createInstance = function() { + this.instance = true; + __CREATE_INSTANCE__; +}; + +/** + * Update Instance + */ +R3.Controls.Keyboard.prototype.updateInstance = function(property) { + R3.Controls.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-controls-mouse.js b/src/r3-controls-mouse.js new file mode 100644 index 0000000..d6b8161 --- /dev/null +++ b/src/r3-controls-mouse.js @@ -0,0 +1,39 @@ +/** + * R3.Controls.Mouse + * @param apiComponent + * @constructor + */ +R3.Controls.Mouse = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Controls.call( + this, + true + ); +}; + +/** + * Inheritance + * @type {R3.Controls} + */ +R3.Controls.Mouse.prototype = Object.create(R3.Controls.prototype); +R3.Controls.Mouse.prototype.constructor = R3.Controls.Mouse; + +/** + * Create Instance + * @returns + */ +R3.Controls.Mouse.prototype.createInstance = function() { + this.instance = true; + __CREATE_INSTANCE__; +}; + +/** + * Update Instance + */ +R3.Controls.Mouse.prototype.updateInstance = function(property) { + R3.Controls.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-controls-touch.js b/src/r3-controls-touch.js new file mode 100644 index 0000000..18c46d0 --- /dev/null +++ b/src/r3-controls-touch.js @@ -0,0 +1,40 @@ +/** + * R3.Controls.Touch + * @param apiComponent + * @constructor + */ +R3.Controls.Touch = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Controls.call( + this, + true + ); + +}; + +/** + * Inheritance + * @type {R3.Controls} + */ +R3.Controls.Touch.prototype = Object.create(R3.Controls.prototype); +R3.Controls.Touch.prototype.constructor = R3.Controls.Touch; + +/** + * Create Instance + * @returns + */ +R3.Controls.Touch.prototype.createInstance = function() { + this.instance = true; + __CREATE_INSTANCE__; +}; + +/** + * Update Instance + */ +R3.Controls.Touch.prototype.updateInstance = function(property) { + R3.Controls.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-curve-0.js b/src/r3-curve-0.js new file mode 100644 index 0000000..b1b7051 --- /dev/null +++ b/src/r3-curve-0.js @@ -0,0 +1,56 @@ +/** + * R3.Curve + * @param apiComponent + * @param inherited + * @constructor + */ +R3.Curve = function( + apiComponent, + inherited +) { + + if (R3.Utils.UndefinedOrNull(inherited)) { + inherited = false; + } + + if (inherited) { + /** + * Do not construct a runtime object of this class - the child is the runtime object + */ + } else { + + __RUNTIME_COMPONENT__; + + } + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Curve.prototype = Object.create(R3.Component.prototype); +R3.Curve.prototype.constructor = R3.Curve; + +/** + * Create Instance + */ +R3.Curve.prototype.createInstance = function() { + + this.instance = this.graphics.Curve(this.arcLenghDivisions); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Curve.prototype.updateInstance = function(property) { + + if (property === 'arcLenghDivisions') { + this.instance.arcLenghDivisions = this.arcLenghDivisions; + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-curve-path-0.js b/src/r3-curve-path-0.js new file mode 100644 index 0000000..7452065 --- /dev/null +++ b/src/r3-curve-path-0.js @@ -0,0 +1,63 @@ +/** + * R3.Curve.Path + * @param apiComponent + * @param inherited + * @constructor + */ +R3.Curve.Path = function( + apiComponent, + inherited +) { + + if (R3.Utils.UndefinedOrNull(inherited)) { + inherited = false; + } + + if (inherited) { + /** + * Do not construct a runtime object of this class - the child is the runtime object + */ + } else { + + __RUNTIME_COMPONENT__; + + } + + R3.Curve.call( + this, + apiComponent, + true + ) +}; + +R3.Curve.Path.prototype = Object.create(R3.Curve.prototype); +R3.Curve.Path.prototype.constructor = R3.Curve.Path; + +/** + * Creates a camera instance + * @returns {*} + */ +R3.Curve.Path.prototype.createInstance = function() { + + this.instance = this.graphics.CurvePath(this.curves, this.autoClose); + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.Curve.Path.prototype.updateInstance = function(property) { + + if (property === 'curves') { + console.warn('todo: update curves'); + return; + } + + if (property === 'autoClose') { + this.instance.autoClose = this.autoClose; + return; + } + + R3.Curve.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-curve-path-d2-0.js b/src/r3-curve-path-d2-0.js new file mode 100644 index 0000000..76c2fa1 --- /dev/null +++ b/src/r3-curve-path-d2-0.js @@ -0,0 +1,59 @@ +/** + * R3.Curve.Path.D2 + * @param apiComponent + * @param inherited + * @constructor + */ +R3.Curve.Path.D2 = function( + apiComponent, + inherited +) { + + + if (R3.Utils.UndefinedOrNull(inherited)) { + inherited = false; + } + + if (inherited) { + /** + * Do not construct a runtime object of this class - the child is the runtime object + */ + } else { + + __RUNTIME_COMPONENT__; + + } + + R3.Curve.Path.call( + this, + apiComponent, + true + ); + +}; + +R3.Curve.Path.D2.prototype = Object.create(R3.Curve.Path.prototype); +R3.Curve.Path.D2.prototype.constructor = R3.Curve.Path.D2; + +/** + * Creates a camera instance + * @returns {*} + */ +R3.Curve.Path.D2.prototype.createInstance = function() { + + this.instance = this.graphics.Path(this.points); + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.Curve.Path.D2.prototype.updateInstance = function(property) { + + if (property === 'points') { + console.warn('todo: update points (and test it)'); + } + + R3.Curve.Path.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-curve-path-d2-shape.js b/src/r3-curve-path-d2-shape.js new file mode 100644 index 0000000..5bf155a --- /dev/null +++ b/src/r3-curve-path-d2-shape.js @@ -0,0 +1,56 @@ +/** + * R3.Curve.Path.D2.Shape + * @param apiComponent + * @param inherited + * @constructor + */ +R3.Curve.Path.D2.Shape = function( + apiComponent, + inherited +) { + + if (R3.Utils.UndefinedOrNull(inherited)) { + inherited = false; + } + + if (inherited) { + /** + * Do not construct a runtime object of this class - the child is the runtime object + */ + } else { + + __RUNTIME_COMPONENT__; + + } + /** + * Now we call the parent class but with linkedComponents - indicating that its being called from a child class + * and should not do any runtime instantiation + */ + R3.Curve.Path.D2.call( + this, + apiComponent, + true + ) + +}; + +R3.Curve.Path.D2.Shape.prototype = Object.create(R3.Curve.Path.D2.prototype); +R3.Curve.Path.D2.Shape.prototype.constructor = R3.Curve.Path.D2.Shape; + +/** + * Creates a camera instance + * @returns {*} + */ +R3.Curve.Path.D2.Shape.prototype.createInstance = function() { + + this.instance = this.graphics.Shape(this.points); + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.Curve.Path.D2.Shape.prototype.updateInstance = function(property) { + R3.Curve.Path.D2.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-customCode.js b/src/r3-customCode.js new file mode 100644 index 0000000..5fa59a5 --- /dev/null +++ b/src/r3-customCode.js @@ -0,0 +1,159 @@ +/** + * R3.CustomCode + * @param apiComponent + * @constructor + */ +R3.CustomCode = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.editor = null; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.CustomCode.prototype = Object.create(R3.Component.prototype); +R3.CustomCode.prototype.constructor = R3.CustomCode; + +R3.CustomCode.prototype.createInstance = function() { + + try { + + this.compiled = false; + + this.instance = new Function('data', this.code).bind(this); + + this.compiled = true; + + } 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.compiled = false; + + this.instance = new Function('data', "console.log('compilation failed for : " + this.name + "');").bind(this); + + } + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.CustomCode.prototype.updateInstance = function(property) { + + if (property === 'name') { + R3.Event.Emit( + R3.Event.NAME_UPDATE, + { + component : this + } + ); + return; + } + + if (property === 'code') { + + try { + this.compiled = false; + this.instance = new Function('data', this.code).bind(this); + this.compiled = true; + this.emit( + R3.Event.COMPILE_SUCCESS, + { + component: this + } + ) + } catch (error) { + this.compiled = false; + this.instance = new Function('data', "console.log('compilation update failed for : " + this.name + "');").bind(this); + this.emit( + R3.Event.COMPILE_FAILED, + { + component: this + } + ) + } + + return; + } + + if (property === 'eventId') { + this.emit( + R3.Event.EVENT_ID_UPDATE, + { + component : this + } + ) + } + + __UPDATE_INSTANCE__; +}; + +R3.CustomCode.prototype.launchEditor = function(){ + + if (this instanceof R3.D3.Shader.Vertex) { + this.editor = this.coder.instance( + document.body, + { + value: this.code, + mode: 'x-shader/x-vertex', + lineNumbers: true, + scrollbarStyle: 'overlay', + indentWithTabs: true, + indentUnit: 4 + } + ); + } else if (this instanceof R3.D3.Shader.Fragment) { + this.editor = this.coder.instance( + document.body, + { + value: this.code, + mode: 'x-shader/x-fragment', + lineNumbers: true, + scrollbarStyle: 'overlay', + indentWithTabs: true, + indentUnit: 4 + } + ); + } else { + this.editor = this.coder.instance( + document.body, + { + value: this.code, + mode: 'javascript', + theme : 'darcula', + lineNumbers: true, + scrollbarStyle: 'overlay', + indentWithTabs: true, + indentUnit: 4 + } + ); + } + + this.editor.setOption("extraKeys", { + 'Ctrl-/': function() { + this.editor.execCommand('toggleComment') + }.bind(this) + } + ); + + this.editor.on('change', function(){ + + this.code = this.editor.getValue(); + + this.updateInstance('code'); + + }.bind(this)) + + this.editor.getWrapperElement().setAttribute('id', this.domId); +}; + +R3.CustomCode.prototype.closeEditor = function(){ + var dom = this.editor.getWrapperElement(); + dom.parentElement.removeChild(dom); +}; \ No newline at end of file diff --git a/src/r3-d3-api-0-object.js b/src/r3-d3-api-0-object.js new file mode 100644 index 0000000..340a33e --- /dev/null +++ b/src/r3-d3-api-0-object.js @@ -0,0 +1,101 @@ +/** + * R3.D3.API.Object + * @param apiComponent + * + * @property useQuaternion + * @property position + * @property quaternion + * @property rotation + * @property scale + * @property up + * @property lookAt + * + * @constructor + */ +R3.D3.API.Object = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.useQuaternion)) { + apiComponent.useQuaternion = false; + } + this.useQuaternion = apiComponent.useQuaternion; + + if (R3.Utils.UndefinedOrNull(apiComponent.position)) { + apiComponent.position = new R3.API.Vector3( + { + parent : this, + name : this.name + ' - Position', + register : true + } + ); + } + this.position = apiComponent.position; + + if (R3.Utils.UndefinedOrNull(apiComponent.quaternion)) { + apiComponent.quaternion = new R3.API.Quaternion( + { + parent : this, + name : this.name + ' - Quaternion', + register : true + } + ); + } + this.quaternion = apiComponent.quaternion; + + if (R3.Utils.UndefinedOrNull(apiComponent.rotation)) { + apiComponent.rotation = new R3.API.Vector3( + { + parent : this, + name : this.name + ' - Rotation', + register : true + } + ); + } + this.rotation = apiComponent.rotation; + + if (R3.Utils.UndefinedOrNull(apiComponent.scale)) { + apiComponent.scale = new R3.API.Vector3( + { + parent : this, + register : true, + name : this.name + ' - Scale', + x : 1, + y : 1, + z : 1 + } + ); + } + this.scale = apiComponent.scale; + + if (R3.Utils.UndefinedOrNull(apiComponent.up)) { + apiComponent.up = new R3.API.Vector3( + { + parent : this, + register : true, + name : this.name + ' - Up', + x : 0, + y : 1, + z : 0 + } + ); + } + this.up = apiComponent.up; + + if (R3.Utils.UndefinedOrNull(apiComponent.lookAt)) { + apiComponent.lookAt = new R3.API.Vector3( + { + parent : this, + name : this.name + ' - LookAt', + register : true + } + ); + } + this.lookAt = apiComponent.lookAt; + +}; + +R3.D3.API.Object.prototype = Object.create(R3.API.Component.prototype); +R3.D3.API.Object.prototype.constructor = R3.D3.API.Object; diff --git a/src/r3-d3-api-animation.js b/src/r3-d3-api-animation.js new file mode 100644 index 0000000..d5c308c --- /dev/null +++ b/src/r3-d3-api-animation.js @@ -0,0 +1,79 @@ +/** + * R3.D3.API.Animation + * @param apiComponent + * + * @property rotationSpeed + * @property translationSpeed + * @property scaleSpeed + * @property rotationFn + * @property translationFn + * @property scaleFn + * @property blocking + * @property applyToMeshWhenDone + * @property functionType + * + * @constructor + */ +R3.D3.API.Animation = function( + apiComponent, +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.rotationSpeed)) { + apiComponent.rotationSpeed = 0; + } + this.rotationSpeed = apiComponent.rotationSpeed; + + if (R3.Utils.UndefinedOrNull(apiComponent.translationSpeed)) { + apiComponent.translationSpeed = 0; + } + this.translationSpeed = apiComponent.translationSpeed; + + if (R3.Utils.UndefinedOrNull(apiComponent.scaleSpeed)) { + apiComponent.scaleSpeed = 0; + } + this.scaleSpeed = apiComponent.scaleSpeed; + + if (R3.Utils.UndefinedOrNull(apiComponent.rotationFn)) { + apiComponent.rotationFn = null; + } + this.rotationFn = apiComponent.rotationFn; + + if (R3.Utils.UndefinedOrNull(apiComponent.translationFn)) { + apiComponent.translationFn = null; + } + this.translationFn = apiComponent.translationFn; + + if (R3.Utils.UndefinedOrNull(apiComponent.scaleFn)) { + apiComponent.scaleFn = null; + } + this.scaleFn = apiComponent.scaleFn; + + if (R3.Utils.UndefinedOrNull(apiComponent.blocking)) { + apiComponent.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 = apiComponent.blocking; + + if (R3.Utils.UndefinedOrNull(apiComponent.applyToMeshWhenDone)) { + apiComponent.applyToMeshWhenDone = true; + } + this.applyToMeshWhenDone = apiComponent.applyToMeshWhenDone; + + if (R3.Utils.UndefinedOrNull(apiComponent.functionType)) { + apiComponent.functionType = R3.D3.API.Animation.ANIMATION_FUNCTION_TYPE_ROTATION; + } + this.functionType = apiComponent.functionType; + +}; + +R3.D3.API.Animation.prototype = Object.create(R3.API.Component.prototype); +R3.D3.API.Animation.prototype.constructor = R3.D3.API.Animation; + +R3.D3.API.Animation.ANIMATION_FUNCTION_TYPE_ROTATION = 1; +R3.D3.API.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION = 2; +R3.D3.API.Animation.ANIMATION_FUNCTION_TYPE_SCALE = 3; \ No newline at end of file diff --git a/src/r3-d3-api-audio.js b/src/r3-d3-api-audio.js new file mode 100644 index 0000000..0c57b15 --- /dev/null +++ b/src/r3-d3-api-audio.js @@ -0,0 +1,59 @@ +/** + * R3.D3.API.Audio + * @param apiComponent + * + * @property path + * @property loop + * @property volume + * @property camera + * @property paused + * + * @constructor + */ +R3.D3.API.Audio = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.path)) { + apiComponent.path = ''; + } + this.path = apiComponent.path; + + if (R3.Utils.UndefinedOrNull(apiComponent.loop)) { + apiComponent.loop = false; + } + this.loop = apiComponent.loop; + + if (R3.Utils.UndefinedOrNull(apiComponent.volume)) { + apiComponent.volume = 0.5; + } + this.volume = apiComponent.volume; + + if (R3.Utils.UndefinedOrNull(apiComponent.camera)) { + + R3.Event.Emit( + R3.Event.GET_PROJECT, + null, + function(project) { + apiComponent.camera = project.cameras[R3.API.Project.CAMERA_INDEX_RUN]; + } + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.camera)) { + throw new Error('unhandled state : no project runtime camera for audio component'); + } + + } + this.camera = apiComponent.camera; + + if (R3.Utils.UndefinedOrNull(apiComponent.paused)) { + apiComponent.paused = false; + } + this.paused = apiComponent.paused; + +}; + +R3.D3.API.Audio.prototype = Object.create(R3.API.Component.prototype); +R3.D3.API.Audio.prototype.constructor = R3.D3.API.Audio; diff --git a/src/r3-d3-api-bone.js b/src/r3-d3-api-bone.js new file mode 100644 index 0000000..a801478 --- /dev/null +++ b/src/r3-d3-api-bone.js @@ -0,0 +1,27 @@ +/** + * R3.D3.API.Bone + * @param apiComponent + * + * @property children + * @property parent + * + * @constructor + */ +R3.D3.API.Bone = function( + apiComponent +) { + + R3.D3.API.Object.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.children)) { + apiComponent.children = []; + } + this.children = apiComponent.children; + +}; + +R3.D3.API.Bone.prototype = Object.create(R3.D3.API.Object.prototype); +R3.D3.API.Bone.prototype.constructor = R3.D3.API.Bone; diff --git a/src/r3-d3-api-boneWeight.js b/src/r3-d3-api-boneWeight.js new file mode 100644 index 0000000..ce23dc8 --- /dev/null +++ b/src/r3-d3-api-boneWeight.js @@ -0,0 +1,29 @@ +/** + * R3.D3.API.BoneWeight + * @param apiComponent + * + * @property boneIndex + * @property weight + * + * @constructor + */ +R3.D3.API.BoneWeight = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.boneIndex)) { + apiComponent.boneIndex = 0; + } + this.boneIndex = apiComponent.boneIndex; + + if (R3.Utils.UndefinedOrNull(apiComponent.weight)) { + apiComponent.weight = 0; + } + this.weight = apiComponent.weight; + +}; + +R3.D3.API.BoneWeight.prototype = Object.create(R3.API.Component.prototype); +R3.D3.API.BoneWeight.prototype.constructor = R3.D3.API.BoneWeight; diff --git a/src/r3-d3-api-broadphase.js b/src/r3-d3-api-broadphase.js new file mode 100644 index 0000000..a25a73a --- /dev/null +++ b/src/r3-d3-api-broadphase.js @@ -0,0 +1,32 @@ +/** + * R3.D3.API.Broadphase + * @param apiComponent + * + * @property broadphaseType + * + * @constructor + */ +R3.D3.API.Broadphase = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.broadphaseType)) { + apiComponent.broadphaseType = R3.D3.API.Broadphase.BROADPHASE_TYPE_NAIVE; + } + this.broadphaseType = apiComponent.broadphaseType; + +}; + +R3.D3.API.Broadphase.prototype = Object.create(R3.API.Component.prototype); +R3.D3.API.Broadphase.prototype.constructor = R3.D3.API.Broadphase; + +/** + * Broadphase Types + * @type {number} + */ +R3.D3.API.Broadphase.BROADPHASE_TYPE_NAIVE = 0x1; +R3.D3.API.Broadphase.BROADPHASE_TYPE_GRID = 0x2; +R3.D3.API.Broadphase.BROADPHASE_TYPE_SAP = 0x3; + diff --git a/src/r3-d3-api-camera-0.js b/src/r3-d3-api-camera-0.js new file mode 100644 index 0000000..a97324e --- /dev/null +++ b/src/r3-d3-api-camera-0.js @@ -0,0 +1,44 @@ +/** + * R3.D3.API.Camera + * @param apiComponent + * + * @property aspect + * @property autoAspect - automatically update the aspect ratio of this camera if the viewport aspect changes + * + * @constructor + */ +R3.D3.API.Camera = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.aspectRatio)) { + apiComponent.aspectRatio = R3.D3.API.Camera.ASPECT_RATIO_1_1; + } + this.aspectRatio = apiComponent.aspectRatio; + this.guiInfo.aspectRatio = { + range: [0, 4], + step: 0.0001, + dp: 4 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.autoAspect)) { + apiComponent.autoAspect = true; + } + this.autoAspect = apiComponent.autoAspect; + + R3.D3.API.Object.call( + this, + apiComponent + ); +}; + +R3.D3.API.Camera.prototype = Object.create(R3.D3.API.Object.prototype); +R3.D3.API.Camera.prototype.constructor = R3.D3.API.Camera; + +R3.D3.API.Camera.ASPECT_RATIO_1_1 = 1; +R3.D3.API.Camera.ASPECT_RATIO_3_2 = 3/2; +R3.D3.API.Camera.ASPECT_RATIO_4_3 = 4/3; +R3.D3.API.Camera.ASPECT_RATIO_16_9 = 16/9; +R3.D3.API.Camera.ASPECT_RATIO_16_10 = 16/10; \ No newline at end of file diff --git a/src/r3-d3-api-camera-cube.js b/src/r3-d3-api-camera-cube.js new file mode 100644 index 0000000..bb2a7bc --- /dev/null +++ b/src/r3-d3-api-camera-cube.js @@ -0,0 +1,63 @@ +/** + * R3.D3.API.Camera.Cube + * + * CubeCamera's have hardcoded fov=90 and aspect=1 + * + * @param apiComponent + * + * @property near + * @property far + * @property fov + * @property cubeResolution + * @property renderTarget + * + * @constructor + */ +R3.D3.API.Camera.Cube = function( + apiComponent +) { + + __API_COMPONENT__; + + /** + * Following two properties are hardcoded for Cube Cameras + * @type {number} + */ + this.aspectRatio = 1; + + this.fov = 90; + + if (R3.Utils.UndefinedOrNull(apiComponent.near)) { + apiComponent.near = 0.1; + } + this.near = apiComponent.near; + + if (R3.Utils.UndefinedOrNull(apiComponent.far)) { + apiComponent.far = 2000; + } + this.far = apiComponent.far; + + if (R3.Utils.UndefinedOrNull(apiComponent.cubeResolution)) { + apiComponent.cubeResolution = 128; + } + this.cubeResolution = apiComponent.cubeResolution; + + if (R3.Utils.UndefinedOrNull(apiComponent.renderTarget)) { + apiComponent.renderTarget = new R3.D3.API.RenderTarget.Cube( + { + parent : this, + name : this.name + ' - Cube RenderTarget' + } + ); + } + this.renderTarget = apiComponent.renderTarget; + + R3.D3.API.Camera.call( + this, + apiComponent + ); + +}; + +R3.D3.API.Camera.Cube.prototype = Object.create(R3.D3.API.Camera.prototype); +R3.D3.API.Camera.Cube.prototype.constructor = R3.D3.API.Camera.Cube; diff --git a/src/r3-d3-api-camera-orthographic-0.js b/src/r3-d3-api-camera-orthographic-0.js new file mode 100644 index 0000000..d73b9c7 --- /dev/null +++ b/src/r3-d3-api-camera-orthographic-0.js @@ -0,0 +1,60 @@ +/** + * R3.D3.API.Camera.Orthographic + * + * Base class for Orthographic Cameras - to define an aspect ratio for the camera, use FixedAspect child class, to + * manually set the camera size, use the ScaledAspect child class + * + * @param apiComponent + * + * @property near + * @property far + * @property zoom + * + * @constructor + */ +R3.D3.API.Camera.Orthographic = function( + apiComponent +) { + + /** + * Override the lookAt vector for Orthographic cameras + */ + __DEFINE_API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.lookAt)) { + apiComponent.lookAt = new R3.API.Vector3( + { + parent : this, + register :true, + x : 0, + y : 0, + z : 10 + } + ); + } + this.lookAt = apiComponent.lookAt; + + if (R3.Utils.UndefinedOrNull(apiComponent.near)) { + apiComponent.near = 0.1; + } + this.near = apiComponent.near; + + if (R3.Utils.UndefinedOrNull(apiComponent.far)) { + apiComponent.far = 2000; + } + this.far = apiComponent.far; + + if (R3.Utils.UndefinedOrNull(apiComponent.zoom)) { + apiComponent.zoom = 1; + } + this.zoom = apiComponent.zoom; + + R3.D3.API.Camera.call( + this, + apiComponent + ); + +}; + +R3.D3.API.Camera.Orthographic.prototype = Object.create(R3.D3.API.Camera.prototype); +R3.D3.API.Camera.Orthographic.prototype.constructor = R3.D3.API.Camera.Orthographic; diff --git a/src/r3-d3-api-camera-orthographic-fixedAspect.js b/src/r3-d3-api-camera-orthographic-fixedAspect.js new file mode 100644 index 0000000..a1ed136 --- /dev/null +++ b/src/r3-d3-api-camera-orthographic-fixedAspect.js @@ -0,0 +1,24 @@ +/** + * R3.D3.API.Camera.Orthographic.FixedAspect + * + * - This camera calculates left, right, top and bottom coordinates from the provided aspect ratio. It uses the + * inherited default values for near and far values for the Z space + * + * @param apiComponent + * @constructor + */ +R3.D3.API.Camera.Orthographic.FixedAspect = function( + apiComponent +) { + + __API_COMPONENT__ + + R3.D3.API.Camera.Orthographic.call( + this, + apiComponent + ); + +}; + +R3.D3.API.Camera.Orthographic.FixedAspect.prototype = Object.create(R3.D3.API.Camera.Orthographic.prototype); +R3.D3.API.Camera.Orthographic.FixedAspect.prototype.constructor = R3.D3.API.Camera.Orthographic.FixedAspect; diff --git a/src/r3-d3-api-camera-orthographic-scaledAspect.js b/src/r3-d3-api-camera-orthographic-scaledAspect.js new file mode 100644 index 0000000..49ce20a --- /dev/null +++ b/src/r3-d3-api-camera-orthographic-scaledAspect.js @@ -0,0 +1,51 @@ +/** + * R3.D3.API.Camera.Orthographic.ScaledAspect + * + * This camera does not automatically adjust its left, right, top and bottom values - it assumes they have been defined + * and are correct. It uses the inherited default near and far values for the Z space. It essentially ignores aspect + * ratio (you should manage that yourself to get things looking pretty) + * + * @param apiComponent + * + * @property left + * @property right + * @property top + * @property bottom + * + * @constructor + */ +R3.D3.API.Camera.Orthographic.ScaledAspect = function( + apiComponent +) { + + __API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.left)) { + apiComponent.left = -5; + } + this.left = apiComponent.left; + + if (R3.Utils.UndefinedOrNull(apiComponent.right)) { + apiComponent.right = 5; + } + this.right = apiComponent.right; + + if (R3.Utils.UndefinedOrNull(apiComponent.top)) { + apiComponent.top = 5; + } + this.top = apiComponent.top; + + if (R3.Utils.UndefinedOrNull(apiComponent.bottom)) { + apiComponent.bottom = -5; + } + this.bottom = apiComponent.bottom; + + R3.D3.API.Camera.Orthographic.call( + this, + apiComponent + ); + +}; + +R3.D3.API.Camera.Orthographic.ScaledAspect.prototype = Object.create(R3.D3.API.Camera.Orthographic.prototype); +R3.D3.API.Camera.Orthographic.ScaledAspect.prototype.constructor = R3.D3.API.Camera.Orthographic.ScaledAspect; diff --git a/src/r3-d3-api-camera-perspective-0.js b/src/r3-d3-api-camera-perspective-0.js new file mode 100644 index 0000000..0b67140 --- /dev/null +++ b/src/r3-d3-api-camera-perspective-0.js @@ -0,0 +1,115 @@ +/** + * R3.D3.API.Camera.Perspective + * @param apiComponent + * + * @property near + * @property far + * @property fov + * @property filmGauge + * @property filmOffset + * @property focus + * @property zoom + * + * @constructor + */ +R3.D3.API.Camera.Perspective = function( + apiComponent +) { + + /** + * Override the position for Perspective cameras + */ + __API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.position)) { + apiComponent.position = new R3.API.Vector3( + { + parent : this, + register :true, + name : this.name + ' - Position', + x : 15, + y : 15, + z : 15 + } + ); + } + this.position = apiComponent.position; + + if (R3.Utils.UndefinedOrNull(apiComponent.near)) { + apiComponent.near = 0.1; + } + this.near = apiComponent.near; + this.guiInfo.near = { + range: [0, 100], + step: 0.01, + dp: 2 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.far)) { + apiComponent.far = 2000; + } + this.far = apiComponent.far; + this.guiInfo.far = { + range: [0, 2000], + step: 2, + dp: 0 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.fov)) { + apiComponent.fov = 50; + } + this.fov = apiComponent.fov; + this.guiInfo.fov = { + range: [0, 150], + step: 1, + dp: 0 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.filmGauge)) { + apiComponent.filmGauge = 35; + } + this.filmGauge = apiComponent.filmGauge; + this.guiInfo.filmGauge = { + range: [0, 35], + step: 1, + dp: 0 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.filmOffset)) { + apiComponent.filmOffset = 0; + } + this.filmOffset = apiComponent.filmOffset; + this.guiInfo.filmOffset = { + range: [-100, 100], + step: 0.01, + dp: 2 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.focus)) { + apiComponent.focus = 10; + } + this.focus = apiComponent.focus; + this.guiInfo.focus = { + range: [0.1, 25], + step: 0.001, + dp:3 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.zoom)) { + apiComponent.zoom = 1; + } + this.zoom = apiComponent.zoom; + this.guiInfo.zoom = { + range: [0, 100], + step: 0.1, + dp: 1 + }; + + R3.D3.API.Camera.call( + this, + apiComponent + ); +}; + +R3.D3.API.Camera.Perspective.prototype = Object.create(R3.D3.API.Camera.prototype); +R3.D3.API.Camera.Perspective.prototype.constructor = R3.D3.API.Camera.Perspective; diff --git a/src/r3-d3-api-camera-perspective-stereo.js b/src/r3-d3-api-camera-perspective-stereo.js new file mode 100644 index 0000000..d90dcb6 --- /dev/null +++ b/src/r3-d3-api-camera-perspective-stereo.js @@ -0,0 +1,30 @@ +/** + * R3.D3.API.Camera.Perspective.Stereo + * @param apiComponent + * @constructor + */ +R3.D3.API.Camera.Perspective.Stereo = function( + apiComponent +) { + + __API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.eyeSeperation)) { + apiComponent.eyeSeperation = 0.064; + } + this.eyeSeperation = apiComponent.eyeSeperation; + this.guiInfo.eyeSeperation = { + range: [0, 0.3], + step: 0.0001, + dp: 4 + }; + + R3.D3.API.Camera.Perspective.call( + this, + apiComponent + ); + +}; + +R3.D3.API.Camera.Perspective.Stereo.prototype = Object.create(R3.D3.API.Camera.Perspective.prototype); +R3.D3.API.Camera.Perspective.Stereo.prototype.constructor = R3.D3.API.Camera.Perspective.Stereo; diff --git a/src/r3-d3-api-composer.js b/src/r3-d3-api-composer.js new file mode 100644 index 0000000..af23af4 --- /dev/null +++ b/src/r3-d3-api-composer.js @@ -0,0 +1,118 @@ +/** + * R3.D3.API.Composer + * @param apiComponent + * + * @property size + * @property renderer + * @property renderTarget - Specify this to render to target instead + * @property renderTargetA - Used internally during render process + * @property renderTargetB - Used internally during render process + * @property passes + * + * @constructor + */ +R3.D3.API.Composer = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.size)) { + apiComponent.size = new R3.API.Vector2( + { + parent : this, + register : true, + name : this.name + ' - Size', + x : 512, + y : 512 + } + ); + } + this.size = apiComponent.size; + + if (R3.Utils.UndefinedOrNull(apiComponent.renderer)) { + apiComponent.renderer = null; + } + this.renderer = apiComponent.renderer; + + if (R3.Utils.UndefinedOrNull(apiComponent.camera)) { + apiComponent.camera = null; + } + this.camera = apiComponent.camera; + + if (R3.Utils.UndefinedOrNull(apiComponent.rendererTarget)) { + apiComponent.rendererTarget = null; + } + this.rendererTarget = apiComponent.rendererTarget; + + if (R3.Utils.UndefinedOrNull(apiComponent.rendererTargetA)) { + apiComponent.rendererTargetA = null; + } + this.rendererTargetA = apiComponent.rendererTargetA; + + if (R3.Utils.UndefinedOrNull(apiComponent.renderTargetB)) { + apiComponent.renderTargetB = null; + } + this.renderTargetB = apiComponent.renderTargetB; + + if (R3.Utils.UndefinedOrNull(apiComponent.passes)) { + + var passes = []; + + if (this.renderer && this.renderer.scenes) { + /** + * Construct default render passes + */ + passes = this.renderer.scenes.reduce( + function(result, scene) { + + result.push( + new R3.D3.API.Pass.Render( + { + parent : this, + scene : scene, + name : this.name + ' - Render Pass', + camera : this.camera + } + ) + ); + + return result; + }.bind(this), + [] + ); + } + + if (this.renderer) { + passes.push( + new R3.D3.API.Pass.Bloom( + { + parent: this, + name: this.name + ' - Bloom Pass', + renderer: this.renderer + } + ) + ); + } + + if (this.renderer) { + passes.push( + new R3.D3.API.Pass.FXAA( + { + parent: this, + name: this.name + ' - FXAA Pass', + renderer: this.renderer + } + ) + ); + } + + apiComponent.passes = passes; + + } + this.passes = apiComponent.passes; + +}; + +R3.D3.API.Composer.prototype = Object.create(R3.API.Component.prototype); +R3.D3.API.Composer.prototype.constructor = R3.D3.API.Composer; diff --git a/src/r3-d3-api-effect-0.js b/src/r3-d3-api-effect-0.js new file mode 100644 index 0000000..e371303 --- /dev/null +++ b/src/r3-d3-api-effect-0.js @@ -0,0 +1,41 @@ +/** + * R3.D3.API.Effect + * @param apiComponent + * + * @property renderer + * @property viewport + * @property size + * + * @constructor + */ +R3.D3.API.Effect = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.renderer)) { + apiComponent.renderer = this.getFirstParent(R3.API.Renderer.D3); + } + this.renderer = apiComponent.renderer; + + if (R3.Utils.UndefinedOrNull(apiComponent.viewport)) { + apiComponent.viewport = this.getFirstParent(R3.D3.API.Viewport); + } + this.viewport = apiComponent.viewport; + + if (R3.Utils.UndefinedOrNull(apiComponent.size)) { + apiComponent.size = new R3.API.Vector2( + { + parent : this, + x : 512, + y : 512 + } + ); + } + this.size = apiComponent.size; + +}; + +R3.D3.API.Effect.prototype = Object.create(R3.API.Component.prototype); +R3.D3.API.Effect.prototype.constructor = R3.D3.API.Effect; diff --git a/src/r3-d3-api-effect-anaglyph.js b/src/r3-d3-api-effect-anaglyph.js new file mode 100644 index 0000000..7dd6ce3 --- /dev/null +++ b/src/r3-d3-api-effect-anaglyph.js @@ -0,0 +1,18 @@ +/** + * R3.D3.API.Effect.Anaglyph + * @param apiComponent + * @constructor + */ +R3.D3.API.Effect.Anaglyph = function( + apiComponent +) { + + R3.D3.API.Effect.call( + this, + apiComponent + ); + +}; + +R3.D3.API.Effect.Anaglyph.prototype = Object.create(R3.D3.API.Effect.prototype); +R3.D3.API.Effect.Anaglyph.prototype.constructor = R3.D3.API.Effect.Anaglyph; diff --git a/src/r3-d3-api-effect-parallax.js b/src/r3-d3-api-effect-parallax.js new file mode 100644 index 0000000..ede135c --- /dev/null +++ b/src/r3-d3-api-effect-parallax.js @@ -0,0 +1,18 @@ +/** + * R3.D3.API.Effect.Parallax + * @param apiComponent + * @constructor + */ +R3.D3.API.Effect.Parallax = function( + apiComponent +) { + + R3.D3.API.Effect.call( + this, + apiComponent + ); + +}; + +R3.D3.API.Effect.Parallax.prototype = Object.create(R3.D3.API.Effect.prototype); +R3.D3.API.Effect.Parallax.prototype.constructor = R3.D3.API.Effect.Parallax; diff --git a/src/r3-d3-api-effect-stereo.js b/src/r3-d3-api-effect-stereo.js new file mode 100644 index 0000000..0e37d15 --- /dev/null +++ b/src/r3-d3-api-effect-stereo.js @@ -0,0 +1,26 @@ +/** + * R3.D3.API.Effect.Stereo + * @param apiComponent + * + * @property eyeSeperation + * + * @constructor + */ +R3.D3.API.Effect.Stereo = function( + apiComponent +) { + + R3.D3.API.Effect.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.eyeSeperation)) { + apiComponent.eyeSeperation = 0.064; + } + this.eyeSeperation = apiComponent.eyeSeperation; + +}; + +R3.D3.API.Effect.Stereo.prototype = Object.create(R3.D3.API.Effect.prototype); +R3.D3.API.Effect.Stereo.prototype.constructor = R3.D3.API.Effect.Stereo; diff --git a/src/r3-d3-api-face-0.js b/src/r3-d3-api-face-0.js new file mode 100644 index 0000000..f616ecf --- /dev/null +++ b/src/r3-d3-api-face-0.js @@ -0,0 +1,114 @@ +/** + * R3.D3.API.Face + * @param apiComponent + * + * @property vertexIndices + * @property vertices + * @property normal + * + * @constructor + */ +R3.D3.API.Face = function( + apiComponent +) { + + __DEREGISTER_COMPONENT__; + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.vertexIndices)) { + apiComponent.vertexIndices = [0, 1, 2]; + } + this.vertexIndices = apiComponent.vertexIndices; + + if (R3.Utils.UndefinedOrNull(apiComponent.vertices)) { + apiComponent.vertices = [ + new R3.D3.API.Vertex( + { + parent : this, + register : this.register + } + ), + new R3.D3.API.Vertex( + { + parent : this, + register : this.register + } + ), + new R3.D3.API.Vertex( + { + parent : this, + register : this.register + } + ), + ]; + } + this.vertices = apiComponent.vertices; + + if (R3.Utils.UndefinedOrNull(apiComponent.normal)) { + apiComponent.normal = null; + } + this.normal = apiComponent.normal; + +}; + +R3.D3.API.Face.prototype = Object.create(R3.API.Component.prototype); +R3.D3.API.Face.prototype.constructor = R3.D3.API.Face; + +/** + * Clone a Face + * @returns {R3.D3.API.Face} + */ +R3.D3.API.Face.prototype.clone = function(){ + return new R3.D3.API.Face( + null, + this.vertexIndices, + this.vertices, + this.normal + ); +}; + +/** + * Returns true if two triangles are equal (their vertex indices match in some order) + * @param face + * @returns {boolean} + */ +R3.D3.API.Face.prototype.equals = function(face) { + return ( + ( + (this.vertexIndices[0] === face.vertexIndices[0]) && + (this.vertexIndices[1] === face.vertexIndices[1]) && + (this.vertexIndices[2] === face.vertexIndices[2]) + ) + || + ( + (this.vertexIndices[0] === face.vertexIndices[0]) && + (this.vertexIndices[1] === face.vertexIndices[2]) && + (this.vertexIndices[2] === face.vertexIndices[1]) + ) + || + ( + (this.vertexIndices[0] === face.vertexIndices[1]) && + (this.vertexIndices[1] === face.vertexIndices[0]) && + (this.vertexIndices[2] === face.vertexIndices[2]) + ) + || + ( + (this.vertexIndices[0] === face.vertexIndices[1]) && + (this.vertexIndices[1] === face.vertexIndices[2]) && + (this.vertexIndices[2] === face.vertexIndices[0]) + ) + || + ( + (this.vertexIndices[0] === face.vertexIndices[2]) && + (this.vertexIndices[1] === face.vertexIndices[0]) && + (this.vertexIndices[2] === face.vertexIndices[1]) + ) + || + ( + (this.vertexIndices[0] === face.vertexIndices[2]) && + (this.vertexIndices[1] === face.vertexIndices[1]) && + (this.vertexIndices[2] === face.vertexIndices[0]) + ) + ); +}; diff --git a/src/r3-d3-api-face-graphics.js b/src/r3-d3-api-face-graphics.js new file mode 100644 index 0000000..772520b --- /dev/null +++ b/src/r3-d3-api-face-graphics.js @@ -0,0 +1,63 @@ +/** + * R3.D3.API.Face + * @param apiComponent + * + * @property materialIndex + * @property uvs [[v0uv (R3.Vector2), v1uv(R3.Vector2), v2uv(R3.Vector2)]] + * @property color + * @property vertexColors + * + * @constructor + */ +R3.D3.API.Face.Graphics = function( + apiComponent +) { + + R3.D3.API.Face.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.materialIndex)) { + apiComponent.materialIndex = -1; + } + this.materialIndex = apiComponent.materialIndex; + + if (R3.Utils.UndefinedOrNull(apiComponent.uvs)) { + apiComponent.uvs = [[]]; + } + this.uvs = apiComponent.uvs; + + if (R3.Utils.UndefinedOrNull(apiComponent.color)) { + apiComponent.color = new R3.API.Color( + { + parent : this, + register : this.register + } + ); + } + this.color = apiComponent.color; + +}; + +R3.D3.API.Face.Graphics.prototype = Object.create(R3.D3.API.Face.prototype); +R3.D3.API.Face.Graphics.prototype.constructor = R3.D3.API.Face.Graphics; + +/** + * Clone + * @returns {R3.D3.API.Face.Graphics} + */ +R3.D3.API.Face.Graphics.prototype.clone = function(){ + + var apiFace = R3.D3.API.Face.prototype.clone.call( + this + ); + + return new R3.D3.API.Face.Graphics( + apiFace, + this.materialIndex, + this.uvs, + this.color, + this.vertexColors + ); +}; diff --git a/src/r3-d3-api-fog-0.js b/src/r3-d3-api-fog-0.js new file mode 100644 index 0000000..55ddc04 --- /dev/null +++ b/src/r3-d3-api-fog-0.js @@ -0,0 +1,32 @@ +/** + * R3.D3.API.Fog + * @param apiComponent + * + * @property color + * + * @constructor + */ +R3.D3.API.Fog = function( + apiComponent +) { + + __DEFINE_API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.color)) { + apiComponent.fogColor = new R3.API.Color( + { + parent : this, + register : true, + name : this.name + ' - Color', + r : 0, + g : 0.129, + b : 0.184 + } + ); + } + this.fogColor = apiComponent.fogColor; + +}; + +R3.D3.API.Fog.prototype = Object.create(R3.API.Component.prototype); +R3.D3.API.Fog.prototype.constructor = R3.D3.API.Fog; diff --git a/src/r3-d3-api-fog-exp.js b/src/r3-d3-api-fog-exp.js new file mode 100644 index 0000000..3a3ef5a --- /dev/null +++ b/src/r3-d3-api-fog-exp.js @@ -0,0 +1,42 @@ +/** + * R3.D3.API.Fog.Exp + * @param apiComponent + * + * @property density + * + * @constructor + */ +R3.D3.API.Fog.Exp = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.density)) { + apiComponent.density = 0.00025; + } + this.density = apiComponent.density; + this.guiInfo.density = { + range: [0, 0.001], + step: 0.00001, + dp: 5 + }; + + R3.D3.API.Fog.call( + this, + apiComponent + ); +}; + +R3.D3.API.Fog.Exp.prototype = Object.create(R3.D3.API.Fog.prototype); +R3.D3.API.Fog.Exp.prototype.constructor = R3.D3.API.Fog.Exp; + +R3.D3.API.Fog.Exp.GUI = function() { + return { + density : { + grain : 0.00001, + min : 0, + max : 1 + } + }; +}; diff --git a/src/r3-d3-api-fog-normal.js b/src/r3-d3-api-fog-normal.js new file mode 100644 index 0000000..485a954 --- /dev/null +++ b/src/r3-d3-api-fog-normal.js @@ -0,0 +1,44 @@ +/** + * R3.D3.API.Fog.Normal + * @param apiComponent + * + * @property near + * @property far + * + * @constructor + */ +R3.D3.API.Fog.Normal = function( + apiComponent +) { + + __API_COMPONENT__ + + if (R3.Utils.UndefinedOrNull(apiComponent.near)) { + apiComponent.near = 1; + } + this.near = apiComponent.near; + this.guiInfo.near = { + range: [0, 100], + step: 0.1, + dp: 1 + }; + + if (R3.Utils.UndefinedOrNull(apiComponent.far)) { + apiComponent.far = 50; + } + this.far = apiComponent.far; + this.guiInfo.far = { + range: [0, 1000], + step: 1, + dp: 0 + }; + + R3.D3.API.Fog.call( + this, + apiComponent + ); + +}; + +R3.D3.API.Fog.Normal.prototype = Object.create(R3.D3.API.Fog.prototype); +R3.D3.API.Fog.Normal.prototype.constructor = R3.D3.API.Fog.Normal; diff --git a/src/r3-d3-api-frictionContactMaterial.js b/src/r3-d3-api-frictionContactMaterial.js new file mode 100644 index 0000000..c841b9b --- /dev/null +++ b/src/r3-d3-api-frictionContactMaterial.js @@ -0,0 +1,59 @@ +/** + * R3.D3.API.FrictionContactMaterial + * @param apiComponent + * + * @property materials + * @property friction + * @property restitution + * @property contactEquationStiffness + * @property contactEquationRelaxation + * @property frictionEquationStiffness + * @property frictionEquationRelaxation + * + * @constructor + */ +R3.D3.API.FrictionContactMaterial = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.materials)) { + apiComponent.materials = []; + } + this.materials = apiComponent.materials; + + if (R3.Utils.UndefinedOrNull(apiComponent.friction)) { + apiComponent.friction = 0.3; + } + this.friction = apiComponent.friction; + + if (R3.Utils.UndefinedOrNull(apiComponent.restitution)) { + apiComponent.restitution = 0.3; + } + this.restitution = apiComponent.restitution; + + if (R3.Utils.UndefinedOrNull(apiComponent.contactEquationStiffness)) { + apiComponent.contactEquationStiffness = 1e7; + } + this.contactEquationStiffness = apiComponent.contactEquationStiffness; + + if (R3.Utils.UndefinedOrNull(apiComponent.contactEquationRelaxation)) { + apiComponent.contactEquationRelaxation = 3; + } + this.contactEquationRelaxation = apiComponent.contactEquationRelaxation; + + if (R3.Utils.UndefinedOrNull(apiComponent.frictionEquationStiffness)) { + apiComponent.frictionEquationStiffness = 1e7; + } + this.frictionEquationStiffness = apiComponent.frictionEquationStiffness; + + if (R3.Utils.UndefinedOrNull(apiComponent.frictionEquationRelaxation)) { + apiComponent.frictionEquationRelaxation = 3; + } + this.frictionEquationRelaxation = apiComponent.frictionEquationRelaxation; + +}; + +R3.D3.API.FrictionContactMaterial.prototype = Object.create(R3.API.Component.prototype); +R3.D3.API.FrictionContactMaterial.prototype.constructor = R3.D3.API.FrictionContactMaterial; diff --git a/src/r3-d3-api-frictionMaterial.js b/src/r3-d3-api-frictionMaterial.js new file mode 100644 index 0000000..9d34f46 --- /dev/null +++ b/src/r3-d3-api-frictionMaterial.js @@ -0,0 +1,25 @@ +/** + * R3.D3.API.FrictionMaterial + * @param apiComponent + * @constructor + */ +R3.D3.API.FrictionMaterial = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.friction)) { + apiComponent.friction = -1; + } + this.friction = apiComponent.friction; + + if (R3.Utils.UndefinedOrNull(apiComponent.restitution)) { + apiComponent.restitution = -1; + } + this.restitution = apiComponent.restitution; + +}; + +R3.D3.API.FrictionMaterial.prototype = Object.create(R3.API.Component.prototype); +R3.D3.API.FrictionMaterial.prototype.constructor = R3.D3.API.FrictionMaterial; diff --git a/src/r3-d3-api-geometry-0.js b/src/r3-d3-api-geometry-0.js new file mode 100644 index 0000000..85e17ac --- /dev/null +++ b/src/r3-d3-api-geometry-0.js @@ -0,0 +1,106 @@ +/** + * R3.D3.API.Geometry + * @param apiComponent + * + * @property boundingBox + * @property boundingSphere + * @property indexed + * @property vertices + * @property faces + * + * @constructor + */ +R3.D3.API.Geometry = function( + apiComponent +) { + + __API_COMPONENT__; + + if (R3.Utils.UndefinedOrNull(apiComponent.boundingBox)) { + apiComponent.boundingBox = new R3.API.Box3( + { + parent : this + } + ); + } + this.boundingBox = apiComponent.boundingBox; + + if (R3.Utils.UndefinedOrNull(apiComponent.boundingSphere)) { + apiComponent.boundingSphere = new R3.API.Sphere( + { + parent : this + } + ); + } + this.boundingSphere = apiComponent.boundingSphere; + + if (R3.Utils.UndefinedOrNull(apiComponent.indexed)) { + apiComponent.indexed = false; + } + this.indexed = apiComponent.indexed; + + /** + * We need to initialize the vertices before we initialize the faces, so we can pass vertex information to the + * face and calculate the face normal if required + */ + if (R3.Utils.UndefinedOrNull(apiComponent.vertices)) { + apiComponent.vertices = [ + new R3.API.Vertex( + { + parent : this, + register : true + } + ), + new R3.API.Vertex( + { + parent : this, + register : true + } + ), + new R3.API.Vertex( + { + parent : this, + register : true + } + ) + ]; + } + this.vertices = apiComponent.vertices; + + if (R3.Utils.UndefinedOrNull(apiComponent.faces)) { + apiComponent.faces = [ + new R3.D3.API.Face.Graphics( + { + parent : this, + register : true, + vertexIndices : [ + 0, + 1, + 2 + ], + vertices : [ + this.vertices[0], + this.vertices[1], + this.vertices[2] + ] + } + ) + ]; + } + this.faces = apiComponent.faces; + + this.faces = R3.Utils.SortFacesByMaterialIndex(this.faces); + + +}; + +R3.D3.API.Geometry.prototype = Object.create(R3.API.Component.prototype); +R3.D3.API.Geometry.prototype.constructor = R3.D3.API.Geometry; + +R3.D3.API.Geometry.prototype.updateNormals = function() { + throw new Error('Override R3.D3.API.Geometry.prototype.updateNormals in child class'); +}; + +R3.D3.API.Geometry.prototype.updatePositions = function() { + throw new Error('Override R3.D3.API.Geometry.prototype.updateNormals in child class'); +}; diff --git a/src/r3-d3-api-geometry-buffer-0.js b/src/r3-d3-api-geometry-buffer-0.js new file mode 100644 index 0000000..9f0cad0 --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-0.js @@ -0,0 +1,62 @@ +/** + * R3.D3.API.Geometry.Buffer + * @param apiComponent + * + * @property attributes + * @property drawRange + * @property groups + * @property index + * @property morphAttributes + * + * @constructor + */ +R3.D3.API.Geometry.Buffer = function( + apiComponent +) { + + R3.D3.API.Geometry.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.attributes)) { + apiComponent.attributes = []; + } + this.attributes = apiComponent.attributes; + + if (R3.Utils.UndefinedOrNull(apiComponent.groups)) { + apiComponent.groups = []; + } + this.groups = apiComponent.groups; + + if (R3.Utils.UndefinedOrNull(apiComponent.drawRange)) { + apiComponent.drawRange = new R3.API.DrawRange( + { + parent : this + } + ) + } + this.drawRange = apiComponent.drawRange; + + if (R3.Utils.UndefinedOrNull(apiComponent.index)) { + apiComponent.index = null; + } + this.index = apiComponent.index; + + if (R3.Utils.UndefinedOrNull(apiComponent.morphAttributes)) { + apiComponent.morphAttributes = null; + } + this.morphAttributes = apiComponent.morphAttributes; + +}; + +R3.D3.API.Geometry.Buffer.prototype = Object.create(R3.D3.API.Geometry.prototype); +R3.D3.API.Geometry.Buffer.prototype.constructor = R3.D3.API.Geometry.Buffer; + +R3.D3.API.Geometry.Buffer.prototype.updateNormals = function() { + console.warn('todo: R3.D3.API.Geometry.Buffer.prototype.updateNormals'); +}; + +R3.D3.API.Geometry.Buffer.prototype.updatePositions = function() { + console.warn('todo: R3.D3.API.Geometry.Buffer.prototype.updatePositions'); +}; diff --git a/src/r3-d3-api-geometry-buffer-box.js b/src/r3-d3-api-geometry-buffer-box.js new file mode 100644 index 0000000..81fec58 --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-box.js @@ -0,0 +1,53 @@ +/** + * R3.D3.API.Geometry.Buffer.Box + * @param apiComponent + * + * @property width + * @property height + * @property depth + * @property widthSegments + * @property heightSegments + * @property depthSegments + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Box = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.width)) { + apiComponent.width = 1; + } + this.width = apiComponent.width; + + if (R3.Utils.UndefinedOrNull(apiComponent.height)) { + apiComponent.height = 1; + } + this.height = apiComponent.height; + + if (R3.Utils.UndefinedOrNull(apiComponent.depth)) { + apiComponent.depth = 1; + } + this.depth = apiComponent.depth; + + if (R3.Utils.UndefinedOrNull(apiComponent.widthSegments)) { + apiComponent.widthSegments = 1; + } + this.widthSegments = apiComponent.widthSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.heightSegments)) { + apiComponent.heightSegments = 1; + } + this.heightSegments = apiComponent.heightSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.depthSegments)) { + apiComponent.depthSegments = 1; + } + this.depthSegments = apiComponent.depthSegments; + +}; + +R3.D3.API.Geometry.Buffer.Box.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Box.prototype.constructor = R3.D3.API.Geometry.Buffer.Box; diff --git a/src/r3-d3-api-geometry-buffer-circle.js b/src/r3-d3-api-geometry-buffer-circle.js new file mode 100644 index 0000000..9f79cc5 --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-circle.js @@ -0,0 +1,40 @@ +/** + * R3.D3.API.Geometry.Buffer.Circle + * @param apiComponent + * + * @property radius + * @property segments + * @property thetaStart + * @property thetaLength + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Circle = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.radius)) { + apiComponent.radius = 1; + } + this.radius = apiComponent.radius; + + if (R3.Utils.UndefinedOrNull(apiComponent.segments)) { + apiComponent.segments = 8; + } + this.segments = apiComponent.segments; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaStart)) { + apiComponent.thetaStart = 0; + } + this.thetaStart = apiComponent.thetaStart; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaLength)) { + apiComponent.thetaLength = Math.PI * 2; + } + this.thetaLength = apiComponent.thetaLength; +}; + +R3.D3.API.Geometry.Buffer.Circle.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Circle.prototype.constructor = R3.D3.API.Geometry.Buffer.Circle; diff --git a/src/r3-d3-api-geometry-buffer-cone.js b/src/r3-d3-api-geometry-buffer-cone.js new file mode 100644 index 0000000..96a9a57 --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-cone.js @@ -0,0 +1,59 @@ +/** + * R3.D3.API.Geometry.Buffer.Cone + * @param apiComponent + * + * @property radius + * @property height + * @property radialSegments + * @property heightSegments + * @property openEnded + * @property thetaStart + * @property thetaLength + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Cone = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.radius)) { + apiComponent.radius = 1; + } + this.radius = apiComponent.radius; + + if (R3.Utils.UndefinedOrNull(apiComponent.height)) { + apiComponent.height = 100; + } + this.height = apiComponent.height; + + if (R3.Utils.UndefinedOrNull(apiComponent.radialSegments)) { + apiComponent.radialSegments = 8; + } + this.radialSegments = apiComponent.radialSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.heightSegments)) { + apiComponent.heightSegments = 1; + } + this.heightSegments = apiComponent.heightSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.openEnded)) { + apiComponent.openEnded = false; + } + this.openEnded = apiComponent.openEnded; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaStart)) { + apiComponent.thetaStart = 0; + } + this.thetaStart = apiComponent.thetaStart; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaLength)) { + apiComponent.thetaLength = Math.PI * 2; + } + this.thetaLength = apiComponent.thetaLength; + +}; + +R3.D3.API.Geometry.Buffer.Cone.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Cone.prototype.constructor = R3.D3.API.Geometry.Buffer.Cone; diff --git a/src/r3-d3-api-geometry-buffer-cylinder.js b/src/r3-d3-api-geometry-buffer-cylinder.js new file mode 100644 index 0000000..2f795f5 --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-cylinder.js @@ -0,0 +1,65 @@ +/** + * R3.D3.API.Geometry.Buffer.Cylinder + * @param apiComponent + * + * @property radiusTop + * @property radiusBottom + * @property height + * @property radialSegments + * @property heightSegments + * @property openEnded + * @property thetaStart + * @property thetaLength + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Cylinder = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.radiusTop)) { + apiComponent.radiusTop = 1; + } + this.radiusTop = apiComponent.radiusTop; + + if (R3.Utils.UndefinedOrNull(apiComponent.radiusBottom)) { + apiComponent.radiusBottom = 1; + } + this.radiusBottom = apiComponent.radiusBottom; + + if (R3.Utils.UndefinedOrNull(apiComponent.height)) { + apiComponent.height = 100; + } + this.height = apiComponent.height; + + if (R3.Utils.UndefinedOrNull(apiComponent.radialSegments)) { + apiComponent.radialSegments = 8; + } + this.radialSegments = apiComponent.radialSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.heightSegments)) { + apiComponent.heightSegments = 1; + } + this.heightSegments = apiComponent.heightSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.openEnded)) { + apiComponent.openEnded = false; + } + this.openEnded = apiComponent.openEnded; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaStart)) { + apiComponent.thetaStart = 0; + } + this.thetaStart = apiComponent.thetaStart; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaLength)) { + apiComponent.thetaLength = Math.PI * 2; + } + this.thetaLength = apiComponent.thetaLength; + +}; + +R3.D3.API.Geometry.Buffer.Cylinder.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Cylinder.prototype.constructor = R3.D3.API.Geometry.Buffer.Cylinder; diff --git a/src/r3-d3-api-geometry-buffer-dodecahedron.js b/src/r3-d3-api-geometry-buffer-dodecahedron.js new file mode 100644 index 0000000..d3d4b98 --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-dodecahedron.js @@ -0,0 +1,29 @@ +/** + * R3.D3.API.Geometry.Buffer.Dodecahedron + * @param apiComponent + * + * @property radius + * @property detail + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Dodecahedron = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.radius)) { + apiComponent.radius = 1; + } + this.radius = apiComponent.radius; + + if (R3.Utils.UndefinedOrNull(apiComponent.detail)) { + apiComponent.detail = 0; + } + this.detail = apiComponent.detail; + +}; + +R3.D3.API.Geometry.Buffer.Dodecahedron.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Dodecahedron.prototype.constructor = R3.D3.API.Geometry.Buffer.Dodecahedron; diff --git a/src/r3-d3-api-geometry-buffer-extrude.js b/src/r3-d3-api-geometry-buffer-extrude.js new file mode 100644 index 0000000..50479a3 --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-extrude.js @@ -0,0 +1,80 @@ +/** + * R3.D3.API.Geometry.Buffer.Extrude + * @param apiComponent + * + * @property shapes + * @property curveSegments + * @property steps + * @property amount + * @property bevelEnabled + * @property bevelThickness + * @property bevelSize + * @property bevelSegments + * @property extrudePath + * @property frames + * @property UVGenerator + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Extrude = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + throw new Error('todo: implement shapes'); + + if (R3.Utils.UndefinedOrNull(apiComponent.shapes)) { + apiComponent.shapes = []; + } + this.shapes = apiComponent.shapes; + + if (R3.Utils.UndefinedOrNull(apiComponent.curveSegments)) { + apiComponent.curveSegments = 12; + } + this.curveSegments = apiComponent.curveSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.steps)) { + apiComponent.steps = 1; + } + this.steps = apiComponent.steps; + + if (R3.Utils.UndefinedOrNull(apiComponent.amount)) { + apiComponent.amount = 100; + } + this.amount = apiComponent.amount; + + if (R3.Utils.UndefinedOrNull(apiComponent.bevelEnabled)) { + apiComponent.bevelEnabled = true; + } + this.bevelEnabled = apiComponent.bevelEnabled; + + if (R3.Utils.UndefinedOrNull(apiComponent.bevelThickness)) { + apiComponent.bevelThickness = 6; + } + this.bevelThickness = apiComponent.bevelThickness; + + if (R3.Utils.UndefinedOrNull(apiComponent.bevelSegments)) { + apiComponent.bevelSegments = 3; + } + this.bevelSegments = apiComponent.bevelSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.extrudePath)) { + apiComponent.extrudePath = null; + } + this.extrudePath = apiComponent.extrudePath; + + if (R3.Utils.UndefinedOrNull(apiComponent.frames)) { + apiComponent.frames = null; + } + this.frames = apiComponent.frames; + + if (R3.Utils.UndefinedOrNull(apiComponent.UVGenerator)) { + apiComponent.UVGenerator = null; + } + this.UVGenerator = apiComponent.UVGenerator; + +}; + +R3.D3.API.Geometry.Buffer.Extrude.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Extrude.prototype.constructor = R3.D3.API.Geometry.Buffer.Extrude; diff --git a/src/r3-d3-api-geometry-buffer-icosahedron.js b/src/r3-d3-api-geometry-buffer-icosahedron.js new file mode 100644 index 0000000..18fbaf1 --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-icosahedron.js @@ -0,0 +1,29 @@ +/** + * R3.D3.API.Geometry.Buffer.Icosahedron + * @param apiComponent + * + * @property radius + * @property detail + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Icosahedron = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.radius)) { + apiComponent.radius = 1; + } + this.radius = apiComponent.radius; + + if (R3.Utils.UndefinedOrNull(apiComponent.detail)) { + apiComponent.detail = 0; + } + this.detail = apiComponent.detail; + +}; + +R3.D3.API.Geometry.Buffer.Icosahedron.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Icosahedron.prototype.constructor = R3.D3.API.Geometry.Buffer.Icosahedron; diff --git a/src/r3-d3-api-geometry-buffer-instanced.js b/src/r3-d3-api-geometry-buffer-instanced.js new file mode 100644 index 0000000..66773b6 --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-instanced.js @@ -0,0 +1,23 @@ +/** + * R3.D3.API.Geometry.Buffer.Instanced + * @param apiComponent + * + * @property maxInstancedCount + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Instanced = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.maxInstancedCount)) { + apiComponent.maxInstancedCount = null; + } + this.maxInstancedCount = apiComponent.maxInstancedCount; + +}; + +R3.D3.API.Geometry.Buffer.Instanced.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Instanced.prototype.constructor = R3.D3.API.Geometry.Buffer.Instanced; diff --git a/src/r3-d3-api-geometry-buffer-lathe.js b/src/r3-d3-api-geometry-buffer-lathe.js new file mode 100644 index 0000000..8e865ca --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-lathe.js @@ -0,0 +1,41 @@ +/** + * R3.D3.API.Geometry.Buffer.Lathe + * @param apiComponent + * + * @property points [R3.Vector2] (x must be larger than 0) + * @property segments + * @property phiStart + * @property phiLength + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Lathe = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.points)) { + apiComponent.points = []; + } + this.points = apiComponent.points; + + if (R3.Utils.UndefinedOrNull(apiComponent.segments)) { + apiComponent.segments = 12; + } + this.segments = apiComponent.segments; + + if (R3.Utils.UndefinedOrNull(apiComponent.phiStart)) { + apiComponent.phiStart = 0; + } + this.phiStart = apiComponent.phiStart; + + if (R3.Utils.UndefinedOrNull(apiComponent.phiLength)) { + apiComponent.phiLength = Math.PI * 2; + } + this.phiLength = apiComponent.phiLength; + +}; + +R3.D3.API.Geometry.Buffer.Lathe.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Lathe.prototype.constructor = R3.D3.API.Geometry.Buffer.Lathe; diff --git a/src/r3-d3-api-geometry-buffer-octahedron.js b/src/r3-d3-api-geometry-buffer-octahedron.js new file mode 100644 index 0000000..5c4ac29 --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-octahedron.js @@ -0,0 +1,29 @@ +/** + * R3.D3.API.Geometry.Buffer.Octahedron + * @param apiComponent + * + * @property radius + * @property detail + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Octahedron = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.radius)) { + apiComponent.radius = 1; + } + this.radius = apiComponent.radius; + + if (R3.Utils.UndefinedOrNull(apiComponent.detail)) { + apiComponent.detail = 0; + } + this.detail = apiComponent.detail; + +}; + +R3.D3.API.Geometry.Buffer.Octahedron.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Octahedron.prototype.constructor = R3.D3.API.Geometry.Buffer.Octahedron; diff --git a/src/r3-d3-api-geometry-buffer-parametric.js b/src/r3-d3-api-geometry-buffer-parametric.js new file mode 100644 index 0000000..488d627 --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-parametric.js @@ -0,0 +1,35 @@ +/** + * R3.D3.API.Geometry.Buffer.Parametric + * @param apiComponent + * + * @property generatorFn(u,v) => returns Vector3, u and v is values between 0 and 1 + * @property slices + * @property stacks + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Parametric = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.generatorFn)) { + apiComponent.generatorFn = ''; + } + this.generatorFn = apiComponent.generatorFn; + + if (R3.Utils.UndefinedOrNull(apiComponent.slices)) { + apiComponent.slices = 20; + } + this.slices = apiComponent.slices; + + if (R3.Utils.UndefinedOrNull(apiComponent.stacks)) { + apiComponent.stacks = 20; + } + this.stacks = apiComponent.stacks; + +}; + +R3.D3.API.Geometry.Buffer.Parametric.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Parametric.prototype.constructor = R3.D3.API.Geometry.Buffer.Parametric; diff --git a/src/r3-d3-api-geometry-buffer-plane.js b/src/r3-d3-api-geometry-buffer-plane.js new file mode 100644 index 0000000..f12132d --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-plane.js @@ -0,0 +1,41 @@ +/** + * R3.D3.API.Geometry.Buffer.Plane + * @param apiComponent + * + * @property width + * @property height + * @property widthSegments + * @property heightSegments + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Plane = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.width)) { + apiComponent.width = 1; + } + this.width = apiComponent.width; + + if (R3.Utils.UndefinedOrNull(apiComponent.height)) { + apiComponent.height = 1; + } + this.height = apiComponent.height; + + if (R3.Utils.UndefinedOrNull(apiComponent.widthSegments)) { + apiComponent.widthSegments = 1; + } + this.widthSegments = apiComponent.widthSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.heightSegments)) { + apiComponent.heightSegments = 1; + } + this.heightSegments = apiComponent.heightSegments; + +}; + +R3.D3.API.Geometry.Buffer.Plane.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Plane.prototype.constructor = R3.D3.API.Geometry.Buffer.Plane; diff --git a/src/r3-d3-api-geometry-buffer-polyhedron.js b/src/r3-d3-api-geometry-buffer-polyhedron.js new file mode 100644 index 0000000..a2c0e1f --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-polyhedron.js @@ -0,0 +1,41 @@ +/** + * R3.D3.API.Geometry.Buffer.Polyhedron + * @param apiComponent + * + * @property vertices + * @property indices + * @property radius + * @property detail + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Polyhedron = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.vertices)) { + apiComponent.vertices = []; + } + this.vertices = apiComponent.vertices; + + if (R3.Utils.UndefinedOrNull(apiComponent.indices)) { + apiComponent.indices = 1; + } + this.indices = apiComponent.indices; + + if (R3.Utils.UndefinedOrNull(apiComponent.radius)) { + apiComponent.radius = 5; + } + this.radius = apiComponent.radius; + + if (R3.Utils.UndefinedOrNull(apiComponent.detail)) { + apiComponent.detail = 0; + } + this.detail = apiComponent.detail; + +}; + +R3.D3.API.Geometry.Buffer.Polyhedron.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Polyhedron.prototype.constructor = R3.D3.API.Geometry.Buffer.Polyhedron; diff --git a/src/r3-d3-api-geometry-buffer-ring.js b/src/r3-d3-api-geometry-buffer-ring.js new file mode 100644 index 0000000..f7bc8f0 --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-ring.js @@ -0,0 +1,53 @@ +/** + * R3.D3.API.Geometry.Buffer.Ring + * @param apiComponent + * + * @property innerRadius + * @property outerRadius + * @property thetaSegments + * @property phiSegments + * @property thetaStart + * @property thetaLength + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Ring = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.innerRadius)) { + apiComponent.innerRadius = 0.5; + } + this.innerRadius = apiComponent.innerRadius; + + if (R3.Utils.UndefinedOrNull(apiComponent.outerRadius)) { + apiComponent.outerRadius = 1; + } + this.outerRadius = apiComponent.outerRadius; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaSegments)) { + apiComponent.thetaSegments = 8; + } + this.thetaSegments = apiComponent.thetaSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.phiSegments)) { + apiComponent.phiSegments = 8; + } + this.phiSegments = apiComponent.phiSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaStart)) { + apiComponent.thetaStart = 0; + } + this.thetaStart = apiComponent.thetaStart; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaLength)) { + apiComponent.thetaLength = Math.PI * 2; + } + this.thetaLength = apiComponent.thetaLength; + +}; + +R3.D3.API.Geometry.Buffer.Ring.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Ring.prototype.constructor = R3.D3.API.Geometry.Buffer.Ring; diff --git a/src/r3-d3-api-geometry-buffer-shape.js b/src/r3-d3-api-geometry-buffer-shape.js new file mode 100644 index 0000000..c4484f3 --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-shape.js @@ -0,0 +1,29 @@ +/** + * R3.D3.API.Geometry.Buffer.Shape + * @param apiComponent + * + * @property shapes + * @property curveSegments + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Shape = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.shapes)) { + apiComponent.shapes = []; + } + this.shapes = apiComponent.shapes; + + if (R3.Utils.UndefinedOrNull(apiComponent.curveSegments)) { + apiComponent.curveSegments = 12; + } + this.curveSegments = apiComponent.curveSegments; + +}; + +R3.D3.API.Geometry.Buffer.Shape.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Shape.prototype.constructor = R3.D3.API.Geometry.Buffer.Shape; diff --git a/src/r3-d3-api-geometry-buffer-sphere.js b/src/r3-d3-api-geometry-buffer-sphere.js new file mode 100644 index 0000000..00059ce --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-sphere.js @@ -0,0 +1,59 @@ +/** + * R3.D3.API.Geometry.Buffer.Sphere + * @param apiComponent + * + * @property radius + * @property widthSegments + * @property heightSegments + * @property phiStart + * @property phiLength + * @property thetaStart + * @property thetaLength + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Sphere = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.radius)) { + apiComponent.radius = 1; + } + this.radius = apiComponent.radius; + + if (R3.Utils.UndefinedOrNull(apiComponent.widthSegments)) { + apiComponent.widthSegments = 8; + } + this.widthSegments = apiComponent.widthSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.heightSegments)) { + apiComponent.heightSegments = 6; + } + this.heightSegments = apiComponent.heightSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.phiStart)) { + apiComponent.phiStart = 0; + } + this.phiStart = apiComponent.phiStart; + + if (R3.Utils.UndefinedOrNull(apiComponent.phiLength)) { + apiComponent.phiLength = Math.PI * 2; + } + this.phiLength = apiComponent.phiLength; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaStart)) { + apiComponent.thetaStart = 0; + } + this.thetaStart = apiComponent.thetaStart; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaLength)) { + apiComponent.thetaLength = Math.PI; + } + this.thetaLength = apiComponent.thetaLength; + +}; + +R3.D3.API.Geometry.Buffer.Sphere.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Sphere.prototype.constructor = R3.D3.API.Geometry.Buffer.Sphere; diff --git a/src/r3-d3-api-geometry-buffer-tetrahedron.js b/src/r3-d3-api-geometry-buffer-tetrahedron.js new file mode 100644 index 0000000..feb193d --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-tetrahedron.js @@ -0,0 +1,29 @@ +/** + * R3.D3.API.Geometry.Buffer.Tetrahedron + * @param apiComponent + * + * @property radius + * @property detail + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Tetrahedron = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.radius)) { + apiComponent.radius = 1; + } + this.radius = apiComponent.radius; + + if (R3.Utils.UndefinedOrNull(apiComponent.detail)) { + apiComponent.detail = 0; + } + this.detail = apiComponent.detail; + +}; + +R3.D3.API.Geometry.Buffer.Tetrahedron.prototype = Object.create(R3.D3.API.Geometry.Buffer.prototype); +R3.D3.API.Geometry.Buffer.Tetrahedron.prototype.constructor = R3.D3.API.Geometry.Buffer.Tetrahedron; diff --git a/src/r3-d3-api-geometry-buffer-text.js b/src/r3-d3-api-geometry-buffer-text.js new file mode 100644 index 0000000..9fe8d8f --- /dev/null +++ b/src/r3-d3-api-geometry-buffer-text.js @@ -0,0 +1,71 @@ +/** + * R3.D3.API.Geometry.Buffer.Text + * @param apiComponent + * + * @property text + * @property font + * @property size + * @property height + * @property curveSegments + * @property bevelEnabled + * @property bevelThickness + * @property bevelSize + * @property bevelSegments + * + * @constructor + */ +R3.D3.API.Geometry.Buffer.Text = function( + apiComponent +) { + + __API_GEOMETRY_BUFFER__; + + if (R3.Utils.UndefinedOrNull(apiComponent.text)) { + apiComponent.text = '-= returns Vector3, u and v is values between 0 and 1 + * @property slices + * @property stacks + * + * @constructor + */ +R3.D3.API.Geometry.Normal.Parametric = function( + apiComponent +) { + + __API_GEOMETRY_NORMAL__; + + if (R3.Utils.UndefinedOrNull(apiComponent.generatorFn)) { + apiComponent.generatorFn = ''; + } + this.generatorFn = apiComponent.generatorFn; + + if (R3.Utils.UndefinedOrNull(apiComponent.slices)) { + apiComponent.slices = 20; + } + this.slices = apiComponent.slices; + + if (R3.Utils.UndefinedOrNull(apiComponent.stacks)) { + apiComponent.stacks = 20; + } + this.stacks = apiComponent.stacks; + +}; + +R3.D3.API.Geometry.Normal.Parametric.prototype = Object.create(R3.D3.API.Geometry.Normal.prototype); +R3.D3.API.Geometry.Normal.Parametric.prototype.constructor = R3.D3.API.Geometry.Normal.Parametric; diff --git a/src/r3-d3-api-geometry-normal-plane.js b/src/r3-d3-api-geometry-normal-plane.js new file mode 100644 index 0000000..a629094 --- /dev/null +++ b/src/r3-d3-api-geometry-normal-plane.js @@ -0,0 +1,41 @@ +/** + * R3.D3.API.Geometry.Normal.Plane + * @param apiComponent + * + * @property width + * @property height + * @property widthSegments + * @property heightSegments + * + * @constructor + */ +R3.D3.API.Geometry.Normal.Plane = function( + apiComponent +) { + + __API_GEOMETRY_NORMAL__; + + if (R3.Utils.UndefinedOrNull(apiComponent.width)) { + apiComponent.width = 1; + } + this.width = apiComponent.width; + + if (R3.Utils.UndefinedOrNull(apiComponent.height)) { + apiComponent.height = 1; + } + this.height = apiComponent.height; + + if (R3.Utils.UndefinedOrNull(apiComponent.widthSegments)) { + apiComponent.widthSegments = 1; + } + this.widthSegments = apiComponent.widthSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.heightSegments)) { + apiComponent.heightSegments = 1; + } + this.heightSegments = apiComponent.heightSegments; + +}; + +R3.D3.API.Geometry.Normal.Plane.prototype = Object.create(R3.D3.API.Geometry.Normal.prototype); +R3.D3.API.Geometry.Normal.Plane.prototype.constructor = R3.D3.API.Geometry.Normal.Plane; diff --git a/src/r3-d3-api-geometry-normal-polyhedron.js b/src/r3-d3-api-geometry-normal-polyhedron.js new file mode 100644 index 0000000..e93f78d --- /dev/null +++ b/src/r3-d3-api-geometry-normal-polyhedron.js @@ -0,0 +1,41 @@ +/** + * R3.D3.API.Geometry.Normal.Polyhedron + * @param apiComponent + * + * @property vertices + * @property indices + * @property radius + * @property detail + * + * @constructor + */ +R3.D3.API.Geometry.Normal.Polyhedron = function( + apiComponent +) { + + __API_GEOMETRY_NORMAL__; + + if (R3.Utils.UndefinedOrNull(apiComponent.vertices)) { + apiComponent.vertices = []; + } + this.vertices = apiComponent.vertices; + + if (R3.Utils.UndefinedOrNull(apiComponent.indices)) { + apiComponent.indices = 1; + } + this.indices = apiComponent.indices; + + if (R3.Utils.UndefinedOrNull(apiComponent.radius)) { + apiComponent.radius = 5; + } + this.radius = apiComponent.radius; + + if (R3.Utils.UndefinedOrNull(apiComponent.detail)) { + apiComponent.detail = 0; + } + this.detail = apiComponent.detail; + +}; + +R3.D3.API.Geometry.Normal.Polyhedron.prototype = Object.create(R3.D3.API.Geometry.Normal.prototype); +R3.D3.API.Geometry.Normal.Polyhedron.prototype.constructor = R3.D3.API.Geometry.Normal.Polyhedron; diff --git a/src/r3-d3-api-geometry-normal-ring.js b/src/r3-d3-api-geometry-normal-ring.js new file mode 100644 index 0000000..82556e8 --- /dev/null +++ b/src/r3-d3-api-geometry-normal-ring.js @@ -0,0 +1,53 @@ +/** + * R3.D3.API.Geometry.Normal.Ring + * @param apiComponent + * + * @property innerRadius + * @property outerRadius + * @property thetaSegments + * @property phiSegments + * @property thetaStart + * @property thetaLength + * + * @constructor + */ +R3.D3.API.Geometry.Normal.Ring = function( + apiComponent +) { + + __API_GEOMETRY_NORMAL__; + + if (R3.Utils.UndefinedOrNull(apiComponent.innerRadius)) { + apiComponent.innerRadius = 0.5; + } + this.innerRadius = apiComponent.innerRadius; + + if (R3.Utils.UndefinedOrNull(apiComponent.outerRadius)) { + apiComponent.outerRadius = 1; + } + this.outerRadius = apiComponent.outerRadius; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaSegments)) { + apiComponent.thetaSegments = 8; + } + this.thetaSegments = apiComponent.thetaSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.phiSegments)) { + apiComponent.phiSegments = 8; + } + this.phiSegments = apiComponent.phiSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaStart)) { + apiComponent.thetaStart = 0; + } + this.thetaStart = apiComponent.thetaStart; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaLength)) { + apiComponent.thetaLength = Math.PI * 2; + } + this.thetaLength = apiComponent.thetaLength; + +}; + +R3.D3.API.Geometry.Normal.Ring.prototype = Object.create(R3.D3.API.Geometry.Normal.prototype); +R3.D3.API.Geometry.Normal.Ring.prototype.constructor = R3.D3.API.Geometry.Normal.Ring; diff --git a/src/r3-d3-api-geometry-normal-shape.js b/src/r3-d3-api-geometry-normal-shape.js new file mode 100644 index 0000000..9af1db9 --- /dev/null +++ b/src/r3-d3-api-geometry-normal-shape.js @@ -0,0 +1,29 @@ +/** + * R3.D3.API.Geometry.Normal.Shape + * @param apiComponent + * + * @property shapes + * @property curveSegments + * + * @constructor + */ +R3.D3.API.Geometry.Normal.Shape = function( + apiComponent +) { + + __API_GEOMETRY_NORMAL__; + + if (R3.Utils.UndefinedOrNull(apiComponent.shapes)) { + apiComponent.shapes = []; + } + this.shapes = apiComponent.shapes; + + if (R3.Utils.UndefinedOrNull(apiComponent.curveSegments)) { + apiComponent.curveSegments = 12; + } + this.curveSegments = apiComponent.curveSegments; + +}; + +R3.D3.API.Geometry.Normal.Shape.prototype = Object.create(R3.D3.API.Geometry.Normal.prototype); +R3.D3.API.Geometry.Normal.Shape.prototype.constructor = R3.D3.API.Geometry.Normal.Shape; diff --git a/src/r3-d3-api-geometry-normal-sphere.js b/src/r3-d3-api-geometry-normal-sphere.js new file mode 100644 index 0000000..bef21b1 --- /dev/null +++ b/src/r3-d3-api-geometry-normal-sphere.js @@ -0,0 +1,59 @@ +/** + * R3.D3.API.Geometry.Normal.Sphere + * @param apiComponent + * + * @property radius + * @property widthSegments + * @property heightSegments + * @property phiStart + * @property phiLength + * @property thetaStart + * @property thetaLength + * + * @constructor + */ +R3.D3.API.Geometry.Normal.Sphere = function( + apiComponent +) { + + __API_GEOMETRY_NORMAL__; + + if (R3.Utils.UndefinedOrNull(apiComponent.radius)) { + apiComponent.radius = 1; + } + this.radius = apiComponent.radius; + + if (R3.Utils.UndefinedOrNull(apiComponent.widthSegments)) { + apiComponent.widthSegments = 8; + } + this.widthSegments = apiComponent.widthSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.heightSegments)) { + apiComponent.heightSegments = 6; + } + this.heightSegments = apiComponent.heightSegments; + + if (R3.Utils.UndefinedOrNull(apiComponent.phiStart)) { + apiComponent.phiStart = 0; + } + this.phiStart = apiComponent.phiStart; + + if (R3.Utils.UndefinedOrNull(apiComponent.phiLength)) { + apiComponent.phiLength = Math.PI * 2; + } + this.phiLength = apiComponent.phiLength; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaStart)) { + apiComponent.thetaStart = 0; + } + this.thetaStart = apiComponent.thetaStart; + + if (R3.Utils.UndefinedOrNull(apiComponent.thetaLength)) { + apiComponent.thetaLength = Math.PI; + } + this.thetaLength = apiComponent.thetaLength; + +}; + +R3.D3.API.Geometry.Normal.Sphere.prototype = Object.create(R3.D3.API.Geometry.Normal.prototype); +R3.D3.API.Geometry.Normal.Sphere.prototype.constructor = R3.D3.API.Geometry.Normal.Sphere; diff --git a/src/r3-d3-api-geometry-normal-tetrahedron.js b/src/r3-d3-api-geometry-normal-tetrahedron.js new file mode 100644 index 0000000..116b855 --- /dev/null +++ b/src/r3-d3-api-geometry-normal-tetrahedron.js @@ -0,0 +1,29 @@ +/** + * R3.D3.API.Geometry.Normal.Tetrahedron + * @param apiComponent + * + * @property radius + * @property detail + * + * @constructor + */ +R3.D3.API.Geometry.Normal.Tetrahedron = function( + apiComponent +) { + + __API_GEOMETRY_NORMAL__; + + if (R3.Utils.UndefinedOrNull(apiComponent.radius)) { + apiComponent.radius = 1; + } + this.radius = apiComponent.radius; + + if (R3.Utils.UndefinedOrNull(apiComponent.detail)) { + apiComponent.detail = 0; + } + this.detail = apiComponent.detail; + +}; + +R3.D3.API.Geometry.Normal.Tetrahedron.prototype = Object.create(R3.D3.API.Geometry.Normal.prototype); +R3.D3.API.Geometry.Normal.Tetrahedron.prototype.constructor = R3.D3.API.Geometry.Normal.Tetrahedron; diff --git a/src/r3-d3-api-geometry-normal-text.js b/src/r3-d3-api-geometry-normal-text.js new file mode 100644 index 0000000..5c68acc --- /dev/null +++ b/src/r3-d3-api-geometry-normal-text.js @@ -0,0 +1,71 @@ +/** + * R3.D3.API.Geometry.Normal.Text + * @param apiComponent + * + * @property text + * @property font + * @property size + * @property height + * @property curveSegments + * @property bevelEnabled + * @property bevelThickness + * @property bevelSize + * @property bevelSegments + * + * @constructor + */ +R3.D3.API.Geometry.Normal.Text = function( + apiComponent +) { + + __API_GEOMETRY_NORMAL__; + + if (R3.Utils.UndefinedOrNull(apiComponent.text)) { + apiComponent.text = '-= h) : height is respected and width is cut off on edges + * - if the width of the canvas is greater than the width of the viewport - the viewport can be instructed to + * expand to the full width (default), or remain fixed (introducing spaces on the left and right edges), for + * this use the expandWidth boolean + * - with portrait aspect ratios (h > w) : width is respected and height is cut off above and below + * - if the height of the canvas is greater than the height of the viewport - the viewport can be instructed to + * expand to the full height (default), or remain fixed (introducing spaced on the top and bottom edges), for + * this use the expandHeight boolean. + * + * - when an 'expand' happens (either vertically or horizontally) - an R3.Event.VIEWPORT_EXPAND event will be + * triggered. This will allow you to create a 'zoom' effect by listening for this event and bringing the + * 'camera' associated to the zoom viewport closer to the scene. Exactly how much the camera would have to + * come closer to the scene in 3D coordinates, in order to keep the entire 2D space occupied, is out of the + * scope of this comment - but for orthogonal cameras this could be relatively simple + * + * - with 'expandHeight' and 'expandWidth' turned off, the VIEWPORT_TYPE_ZOOMED_ASPECT essentially behaves + * similar to a VIEWPORT_TYPE_FIXED_ASPECT in the case that the entire viewport actually fits into the canvas + * (when did this ever happen? wouldn't life have been great?) + * + * @param apiComponent + * + * @property aspectRatio + * @property expandWidth + * @property expandHeight + * + * @constructor + */ +R3.D3.API.Viewport.ZoomedAspect = function( + apiComponent +) { + + R3.D3.API.Viewport.call( + this, + apiComponent + ); + + if (R3.Utils.UndefinedOrNull(apiComponent.aspectRatio)) { + apiComponent.aspectRatio = R3.D3.API.Viewport.ASPECT_RATIO_16_9; + } + this.aspectRatio = apiComponent.aspectRatio; + + if (R3.Utils.UndefinedOrNull(apiComponent.expandWidth)) { + apiComponent.expandWidth = true; + } + this.expandWidth = apiComponent.expandWidth; + + if (R3.Utils.UndefinedOrNull(apiComponent.expandHeight)) { + apiComponent.expandHeight = true; + } + this.expandHeight = apiComponent.expandHeight; + +}; + +R3.D3.API.Viewport.ZoomedAspect.prototype = Object.create(R3.D3.API.Viewport.prototype); +R3.D3.API.Viewport.ZoomedAspect.prototype.constructor = R3.D3.API.Viewport.ZoomedAspect; diff --git a/src/r3-d3-api-y-object.js b/src/r3-d3-api-y-object.js new file mode 100644 index 0000000..ef8d1a4 --- /dev/null +++ b/src/r3-d3-api-y-object.js @@ -0,0 +1,228 @@ +/** + * R3.D3.Object + * + * This class can be instantiated as is but typically will be inherited + * + * @param apiComponent + * @param inherited + * + * @constructor + */ +R3.D3.Object = function( + apiComponent, + inherited +) { + + __INHERIT_AND_INSTANTIATE__ + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Object.prototype = Object.create(R3.Component.prototype); +R3.D3.Object.prototype.constructor = R3.D3.Object; + +R3.D3.Object.prototype.createInstance = function() { + + if (this.runtime === R3.Runtime.GRAPHICS) { + this.instance = this.graphics.Object(); + } + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the mesh instance + */ +R3.D3.Object.prototype.updateInstance = function(property) { + + if (property === 'useQuaternion') { + console.warn('TODO: update useQuaternion'); + return; + } + + if (property === 'position') { + this.instance.position.x = this.position.x; + this.instance.position.y = this.position.y; + this.instance.position.z = this.position.z; + this.instance.updateProjectionMatrix(); + console.warn('TODO: test update position'); + return; + } + + if (property === 'quaternion') { + console.warn('TODO: update quaternion'); + return; + } + + if (property === 'rotation') { + this.instance.rotation.x = this.rotation.x; + this.instance.rotation.y = this.rotation.y; + this.instance.rotation.z = this.rotation.z; + this.instance.updateProjectionMatrix(); + console.warn('TODO: test update rotation'); + return; + } + + if (property === 'scale') { + console.warn('TODO: update scale'); + return; + } + + if (property === 'up') { + console.warn('TODO: update up'); + return; + } + + if (property === 'lookAt') { + console.warn('TODO: update lookAt'); + return; + } + + __UPDATE_INSTANCE__; + // + // if ( + // || + // property === '' || + // property === 'rotation' + // ) { + // if (this.useQuaternion) { + // + // if (R3.Utils.Defined(this.instance.quaternion)) { + // + // 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.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( + // this.quaternion.axis.instance, + // this.quaternion.angle + // ); + // + // this.rotation.x = this.instance.rotation.x; + // this.rotation.y = this.instance.rotation.y; + // this.rotation.z = this.instance.rotation.z; + // + // this.rotation.instance.x = this.rotation.x; + // this.rotation.instance.y = this.rotation.y; + // this.rotation.instance.z = this.rotation.z; + // } + // + // } else { + // + // if (R3.Utils.Defined(this.instance.rotation)) { + // + // this.rotation.instance.x = this.rotation.x; + // this.rotation.instance.y = this.rotation.y; + // this.rotation.instance.z = this.rotation.z; + // + // this.instance.rotation.x = this.rotation.x; + // this.instance.rotation.y = this.rotation.y; + // this.instance.rotation.z = this.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; + // + // this.quaternion.instance.x = this.quaternion.x; + // this.quaternion.instance.y = this.quaternion.y; + // this.quaternion.instance.z = this.quaternion.z; + // this.quaternion.instance.w = this.quaternion.w; + // } + // } + // + // // if (!this.instance.matrixAutoUpdate) { + // // this.instance.updateMatrixWorld(); + // // this.instance.children.map( + // // function(child){ + // // child.updateMatrixWorld(); + // // } + // // ) + // // } + // + // if (R3.Utils.Defined(this.instance.updateProjectionMatrix)) { + // this.instance.updateProjectionMatrix(); + // } + // } + // + // if (property === 'position') { + // + // if (R3.Utils.Defined(this.instance.position)) { + // + // this.position.instance.x = this.position.x; + // this.position.instance.y = this.position.y; + // this.position.instance.z = this.position.z; + // + // this.instance.position.x = this.position.x; + // this.instance.position.y = this.position.y; + // this.instance.position.z = this.position.z; + // } + // + // if (R3.Utils.Defined(this.instance.updateProjectionMatrix)) { + // this.instance.updateProjectionMatrix(); + // } + // } + // + // if (property === 'scale') { + // + // this.scale.instance.x = this.scale.x; + // this.scale.instance.y = this.scale.y; + // this.scale.instance.z = this.scale.z; + // + // this.instance.scale.x = this.scale.x; + // this.instance.scale.y = this.scale.y; + // this.instance.scale.z = this.scale.z; + // } + // + // if ( + // property === 'up' || + // property === 'lookAt' + // ) { + // + // this.up.instance.x = this.up.x; + // this.up.instance.y = this.up.y; + // this.up.instance.z = this.up.z; + // + // this.instance.up.x = this.up.x; + // this.instance.up.y = this.up.y; + // this.instance.up.z = this.up.z; + // + // this.lookAt.instance.x = this.lookAt.x; + // this.lookAt.instance.y = this.lookAt.y; + // this.lookAt.instance.z = this.lookAt.z; + // + // if (R3.Utils.Defined(this.instance.lookAt)) { + // this.instance.lookAt(this.lookAt.instance); + // } + // + // if (R3.Utils.Defined(this.instance.updateProjectionMatrix)) { + // this.instance.updateProjectionMatrix(); + // } + // + // R3.D3.Object.prototype.updateFromInstance.call(this, 'rotation'); + // } + + +}; + +/** + * R3.D3.Object.prototype.translate + * + * - Translate this object in 3D space + * + * @param vector3 + */ +R3.D3.Object.prototype.translate = function(vector3) { + + this.position.x += vector3.x; + this.position.y += vector3.y; + this.position.z += vector3.z; + + this.updateInstance('position'); +}; diff --git a/src/r3-d3-api-z-animation.js b/src/r3-d3-api-z-animation.js new file mode 100644 index 0000000..ced1fcc --- /dev/null +++ b/src/r3-d3-api-z-animation.js @@ -0,0 +1,222 @@ +/** + * R3.D3.Animation + * @param apiComponent + * @constructor + */ +R3.D3.Animation = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.editor = null; + + /** + * This indicates whether an animation is currently in process - for blocking to take effect + * @type {boolean} + */ + this.inProcess = false; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Animation.prototype = Object.create(R3.Component.prototype); +R3.D3.Animation.prototype.constructor = R3.D3.Animation; + +R3.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.emit( + R3.Event.ANIMATION_COMPILE_FAILED, + { + component : this + } + ) + } + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Animation.prototype.updateInstance = function(property) { + + if (property === 'rotationSpeed') { + console.warn('todo: rotationSpeed update'); + return; + } + + if (property === 'translationSpeed') { + console.warn('todo: translationSpeed update'); + return; + } + + if (property === 'scaleSpeed') { + console.warn('todo: scaleSpeed update'); + return; + } + + if (property === 'rotationFn') { + try { + this.instance.rotation = new Function('data', this.rotationFn).bind(this); + this.emit( + R3.Event.ANIMATION_COMPILE_SUCCESS, + { + component : this, + type : R3.D3.API.Animation.ANIMATION_FUNCTION_TYPE_ROTATION + } + ) + } catch (error) { + console.error(error); + this.emit( + R3.Event.ANIMATION_COMPILE_FAILED, + { + component : this + } + ) + } + return; + } + + if (property === 'translationFn') { + try { + this.instance.translation = new Function('data', this.translationFn).bind(this); + this.emit( + R3.Event.ANIMATION_COMPILE_SUCCESS, + { + component : this, + type : R3.D3.API.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION + } + ); + } catch (error) { + console.error(error); + this.emit( + R3.Event.ANIMATION_COMPILE_FAILED, + { + component : this + } + ) + } + return; + } + + if (property === 'scaleFn') { + try { + this.instance.scale = new Function('data', this.scaleFn).bind(this); + this.emit( + R3.Event.ANIMATION_COMPILE_SUCCESS, + { + component : this, + type : R3.D3.Animation.API.ANIMATION_FUNCTION_TYPE_SCALE + } + ) + } catch (error) { + console.error(error); + this.emit( + R3.Event.ANIMATION_COMPILE_FAILED, + { + component : this + } + ) + } + return; + } + + if (property === 'blocking') { + console.warn('todo: blocking update'); + return; + } + + if (property === 'applyToMeshWhenDone') { + console.warn('todo: applyToMeshWhenDone update'); + return; + } + + if (property === 'functionType') { + console.warn('todo: functionType update'); + return; + } + + __UPDATE_INSTANCE__; + +}; + +R3.D3.Animation.prototype.launchEditor = function(){ + + var property = null; + + if (this.functionType === R3.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION) { + this.rotationFn = '//when the animation is complete, return true\nreturn true;'; + property = 'rotationFn'; + } + + if (this.functionType === R3.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION) { + this.translationFn = '//when the animation is complete, return true\nreturn true;'; + property = 'translationFn'; + } + + if (this.functionType === R3.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'); + } +}; + +R3.D3.Animation.prototype.closeEditor = function(){ + var dom = this.editor.getWrapperElement(); + dom.parentElement.removeChild(dom); +}; diff --git a/src/r3-d3-audio.js b/src/r3-d3-audio.js new file mode 100644 index 0000000..449e305 --- /dev/null +++ b/src/r3-d3-audio.js @@ -0,0 +1,112 @@ +/** + * R3.D3.Audio + * @param apiComponent + * @constructor + */ +R3.D3.Audio = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Audio.prototype = Object.create(R3.Component.prototype); +R3.D3.Audio.prototype.constructor = R3.D3.Audio; + +/** + * Audio create instance + */ +R3.D3.Audio.prototype.createInstance = function() { + + /** + * Call the Audio with 'this' component as caller so Audio can call createInstance + * @type {void|boolean|*} + */ + this.instance = this.graphics.prototype.Audio.call( + this, + this.path, + this.loop, + this.volume, + this.camera + ); + + if (this.instance === true) { + /** + * We are disabling this audio for some reason - stop using M$ ! + */ + __CREATE_INSTANCE__; + } + + /** + * Don't worry about calling R3.Component.prototype.createInstance - this happens asynchronously once the audio + * loaded + */ + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Audio.prototype.updateInstance = function(property) { + + if (this.instance === true) { + return; + } + + if (property === 'path') { + console.warn('todo: update audio path' ); + return; + } + + if (property === 'loop') { + this.instance.setLoop(this.loop); + return; + } + + if (property === 'volume') { + this.instance.setVolume(this.volume); + return; + } + + if (property === 'paused') { + if (this.paused) { + this.instance.pause(); + } else { + this.instance.play(); + } + return; + } + + __UPDATE_INSTANCE__; + +}; + +R3.D3.Audio.prototype.play = function() { + + if (this.instance === true) { + return; + } + + this.instance.play(); +}; + +R3.D3.Audio.prototype.pause = function() { + + if (this.instance === true) { + return; + } + + this.instance.pause(); +}; + +R3.D3.Audio.prototype.stop = function() { + + if (this.instance === true) { + return; + } + + this.instance.stop(); +}; \ No newline at end of file diff --git a/src/r3-d3-bone.js b/src/r3-d3-bone.js new file mode 100644 index 0000000..f01b02e --- /dev/null +++ b/src/r3-d3-bone.js @@ -0,0 +1,50 @@ +/** + * R3.D3.Bone + * @param apiComponent + * @constructor + */ +R3.D3.Bone = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Object.call( + this, + true + ); +}; + +R3.D3.Bone.prototype = Object.create(R3.D3.Object.prototype); +R3.D3.Bone.prototype.constructor = R3.D3.Bone; + +/** + * Creates an instance bone + */ +R3.D3.Bone.prototype.createInstance = function() { + + this.instance = this.graphics.Bone( + this.position, + this.rotation, + this.scale, + this.quaternion, + this.lookAt, + this.up + ); + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance + */ +R3.D3.Bone.prototype.updateInstance = function(property) { + + if (property === 'children') { + console.warn('todo: child bone children update'); + return; + } + + R3.D3.Object.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-d3-boneWeight.js b/src/r3-d3-boneWeight.js new file mode 100644 index 0000000..537612f --- /dev/null +++ b/src/r3-d3-boneWeight.js @@ -0,0 +1,46 @@ +/** + * R3.D3.BoneWeight + * @param apiComponent + * @constructor + */ +R3.D3.BoneWeight = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.BoneWeight.prototype = Object.create(R3.Component.prototype); +R3.D3.BoneWeight.prototype.constructor = R3.D3.BoneWeight; + +/** + * R3.D3.BoneWeight.prototype.createInstance + */ +R3.D3.BoneWeight.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * R3.D3.BoneWeight.prototype.updateInstance + * @param property + */ +R3.D3.BoneWeight.prototype.updateInstance = function(property) { + + if (property === 'boneIndex') { + throw new Error('TODO: update boneIndex'); + } + + if (property === 'weight') { + throw new Error('TODO: update weight'); + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-d3-broadphase.js b/src/r3-d3-broadphase.js new file mode 100644 index 0000000..711280f --- /dev/null +++ b/src/r3-d3-broadphase.js @@ -0,0 +1,42 @@ +/** + * R3.D3.Broadphase + * @param apiComponent + * @constructor + */ +R3.D3.Broadphase = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Broadphase.prototype = Object.create(R3.Component.prototype); +R3.D3.Broadphase.prototype.constructor = R3.D3.Broadphase; + +/** + * R3.D3.Broadphase.prototype.createInstance + */ +R3.D3.Broadphase.prototype.createInstance = function() { + + this.instance = this.physics.Broadphase(this.broadphaseType); + + __CREATE_INSTANCE__; + +}; + +/** + * R3.D3.Broadphase.prototype.updateInstance + */ +R3.D3.Broadphase.prototype.updateInstance = function(property) { + + if (property === 'broadphaseType') { + this.instance = this.physics.Broadphase(this.broadphaseType); + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-d3-camera-0.js b/src/r3-d3-camera-0.js new file mode 100644 index 0000000..b7facaf --- /dev/null +++ b/src/r3-d3-camera-0.js @@ -0,0 +1,52 @@ +/** + * R3.D3.Camera + * + * - This class cannot be instantiated - simply pass it all through to R3.D3.Object - it need apiComponent to pass + * to Object + * + * @constructor + */ +R3.D3.Camera = function( + apiComponent, + inherited +) { + + __INHERIT_ONLY__ + + R3.D3.Object.call( + this, + apiComponent, + true + ); + +}; + +R3.D3.Camera.prototype = Object.create(R3.D3.Object.prototype); +R3.D3.Camera.prototype.constructor = R3.D3.Camera; + +/** + * Updates the instance with the current state + */ +R3.D3.Camera.prototype.updateInstance = function(property) { + + if (property === 'aspectRatio') { + + this.instance.aspect = this.aspectRatio; + + if (typeof this.instance.updateProjectionMatrix === 'function') { + this.instance.updateProjectionMatrix(); + } + + return; + } + + if (property === 'autoAspect') { + + console.log('todo - autoAspect change'); + + return; + } + + R3.D3.Object.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-d3-camera-cube.js b/src/r3-d3-camera-cube.js new file mode 100644 index 0000000..b10f570 --- /dev/null +++ b/src/r3-d3-camera-cube.js @@ -0,0 +1,107 @@ +/** + * R3.D3.Camera.Cube + * @param apiComponent + * @constructor + */ +R3.D3.Camera.Cube = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Camera.call( + this, + apiComponent, + true + ); + +}; + +R3.D3.Camera.Cube.prototype = Object.create(R3.D3.Camera.prototype); +R3.D3.Camera.Cube.prototype.constructor = R3.D3.Camera.Cube; + +/** + * Creates a camera instance + * @returns {*} + */ +R3.D3.Camera.Cube.prototype.createInstance = function() { + + this.instance = this.graphics.CubeCamera( + this.near, + this.far, + this.cubeResolution + ); + + this.renderTarget.instance = this.instance.renderTarget; + + this.renderTarget.updateFromInstance('width'); + this.renderTarget.updateFromInstance('height'); + this.renderTarget.updateFromInstance('scissor'); + this.renderTarget.updateFromInstance('scissorTest'); + this.renderTarget.updateFromInstance('viewport'); + this.renderTarget.updateFromInstance('depthBuffer'); + this.renderTarget.updateFromInstance('depthTexture'); + this.renderTarget.updateFromInstance('stencilBuffer'); + + this.renderTarget.texture.updateFromInstance('wrapS'); + this.renderTarget.texture.updateFromInstance('wrapT'); + this.renderTarget.texture.updateFromInstance('magFilter'); + this.renderTarget.texture.updateFromInstance('minFilter'); + this.renderTarget.texture.updateFromInstance('format'); + this.renderTarget.texture.updateFromInstance('type'); + this.renderTarget.texture.updateFromInstance('anisotropy'); + this.renderTarget.texture.updateFromInstance('encoding'); + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Camera.Cube.prototype.updateInstance = function(property) { + + if ( + property === 'aspectRatio' || + property === 'fov' + ) { + console.warn('Cube camera fov and aspect cannot be changed'); + this.aspectRatio = 1; + this.fov = 90; + } + + if (property === 'near') { + this.instance.near = this.near; + return; + } + + if (property === 'far') { + this.instance.far = this.far; + return; + } + + if (property === 'cubeResolution') { + this.instance.renderTarget.setSize( + this.cubeResolution, + this.cubeResolution + ); + return; + } + + if (property === 'renderTarget') { + console.warn('TODO: renderTarget update'); + return; + } + + R3.D3.Camera.prototype.updateInstance.call(this, property); +}; + +/** + * Updates the render target with renderer and scene information + * @param renderer + * @param scene + */ +R3.D3.Camera.Cube.prototype.update = function(renderer, scene) { + + console.warn('todo: implement R3.D3.Camera.Cube.prototype.update'); + +}; diff --git a/src/r3-d3-camera-orthographic-0.js b/src/r3-d3-camera-orthographic-0.js new file mode 100644 index 0000000..dd1428f --- /dev/null +++ b/src/r3-d3-camera-orthographic-0.js @@ -0,0 +1,46 @@ +/** + * R3.D3.Camera.Orthographic + * + * - This class cannot be instantiated + * + * @constructor + */ +R3.D3.Camera.Orthographic = function( + apiComponent, + inherited +) { + + __INHERIT_ONLY__ + + R3.D3.Camera.call( + this, + apiComponent, + true + ); + +}; + +R3.D3.Camera.Orthographic.prototype = Object.create(R3.D3.Camera.prototype); +R3.D3.Camera.Orthographic.prototype.constructor = R3.D3.Camera.Orthographic; + +/** + * Updates the instance with the current state + */ +R3.D3.Camera.Orthographic.prototype.updateInstance = function(property) { + + if (property === 'near') { + this.instance.near = this.near; + return; + } + + if (property === 'far') { + this.instance.far = this.far; + } + + if (property === 'zoom') { + this.instance.zoom = this.zoom; + this.instance.updateProjectionMatrix() + } + + R3.D3.Camera.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-camera-orthographic-fixedAspect.js b/src/r3-d3-camera-orthographic-fixedAspect.js new file mode 100644 index 0000000..f18244e --- /dev/null +++ b/src/r3-d3-camera-orthographic-fixedAspect.js @@ -0,0 +1,183 @@ +/** + * R3.D3.Camera.Orthographic.FixedAspect + * @param apiComponent + * @constructor + */ +R3.D3.Camera.Orthographic.FixedAspect = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Camera.Orthographic.call( + this, + apiComponent, + true + ); + +}; + +R3.D3.Camera.Orthographic.FixedAspect.prototype = Object.create(R3.D3.Camera.Orthographic.prototype); +R3.D3.Camera.Orthographic.FixedAspect.prototype.constructor = R3.D3.Camera.Orthographic.FixedAspect; + +/** + * Creates a camera instance + * @returns {*} + */ +R3.D3.Camera.Orthographic.FixedAspect.prototype.createInstance = function() { + + /** + * We need to get the viewport width and height + * @type {void|*} + */ + + var dimensions = this.getDimensions(); + + this.instance = this.graphics.OrthographicCamera( + dimensions.left, + dimensions.right, + dimensions.top, + dimensions.bottom, + this.near, + this.far + ); + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Camera.Orthographic.FixedAspect.prototype.updateInstance = function(property) { + + if (property === 'aspect') { + + var dimensions = this.getDimensions(); + + this.instance.left = dimensions.left; + this.instance.right = dimensions.right; + this.instance.top = dimensions.top; + this.instance.bottom = dimensions.bottom; + + this.instance.updateProjectionMatrix(); + + return; + } + + R3.D3.Camera.Orthographic.prototype.updateInstance.call(this, property); +}; + +/** + * This calculates the dimensions of the camera based on the following example info: + * + * aspect = width + * ------ + * height + * + * width = aspect * height; + * height = width / aspect; + * + * aspect > 1 (width > height) (landscape) + * aspect < 1 (height > width) (portrait) + * + * 4 / 3 = 1.33333 (1920 x 1440) + * 16 / 9 = 1.77777 (1920 x 1080) + * + * w h w h + * 9 / 16 = 0.5625 (1080 x 1920) - required + * 3 / 4 = 0.75 (1440 x 1920) - current + * + * @returns {{left: number, right: number, top: number, bottom: number}} + */ +R3.D3.Camera.Orthographic.FixedAspect.prototype.getDimensions = function() { + + + var size = R3.Utils.GetWindowSize(); + + var currentAspect = size.width / size.height; + + var width, height; + + if (currentAspect > 1) { + /** + * Width is greater than height (landscape) + */ + if (this.aspectRatio < 1) { + + /** + * The required aspect is more high than wide - use the full height + */ + width = this.aspectRatio * size.height; + height = size.height; + + } else { + /** + * The required aspect is also more wide than high - so we have another two possibilities: + * a) The required aspect is greater than the current aspect - this means the required aspect is less high + * than the current aspect - we can use the full width + * + * b) The required aspect is less than the current aspect - this means the required aspect is higher than + * the current aspect - we need to determine a new width based on the current height + */ + if (this.aspectRatio > currentAspect) { + /** + * a) + */ + width = size.width; + height = width / this.aspectRatio; + } else { + /** + * b) + */ + height = size.height; + width = this.aspectRatio * height; + } + + } + + } else { + /** + * The height is greater than the width (portrait) + */ + if (this.aspectRatio > 1) { + + /** + * The required aspect is landscape in a portrait mode - use the full width and calculate the new height + */ + width = size.width; + height = width / this.aspectRatio; + + } else { + + /** + * The required aspect is also more high than wide (portrait) - we have again, two possibilities + * a) The required aspect is greater than the current aspect - this means the required aspect does not fit + * the full width of the current aspect - use the full width of the current size and determine a new height + * + * b) The required aspect is less than the current aspect - this means that the required aspect is less wide + * than the current aspect, so we can use the full height of the current size and determine a new width + */ + + if (this.aspectRatio > currentAspect) { + width = size.width; + height = width / this.aspectRatio; + } else { + height = size.height; + width = this.aspectRatio * height; + } + + } + + } + + /** + * We now have the correct width and height of of the camera + */ + return { + left : width / -2, + right : width / 2, + top : height / 2, + bottom : height / -2 + } + +}; diff --git a/src/r3-d3-camera-orthographic-scaledAspect.js b/src/r3-d3-camera-orthographic-scaledAspect.js new file mode 100644 index 0000000..265d192 --- /dev/null +++ b/src/r3-d3-camera-orthographic-scaledAspect.js @@ -0,0 +1,80 @@ +/** + * R3.D3.Camera.Orthographic.ScaledAspect + * @param apiComponent + * @constructor + */ +R3.D3.Camera.Orthographic.ScaledAspect = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Camera.Orthographic.call( + this, + apiComponent, + true + ); + +}; + +R3.D3.Camera.Orthographic.ScaledAspect.prototype = Object.create(R3.D3.Camera.Orthographic.prototype); +R3.D3.Camera.Orthographic.ScaledAspect.prototype.constructor = R3.D3.Camera.Orthographic.ScaledAspect; + +/** + * Creates a camera instance + * @returns {*} + */ +R3.D3.Camera.Orthographic.ScaledAspect.prototype.createInstance = function() { + + this.instance = new this.graphics.OrthographicCamera( + this.left, + this.right, + this.top, + this.bottom, + this.near, + this.far + ); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Camera.Orthographic.ScaledAspect.prototype.updateInstance = function(property) { + + if (property === 'left') { + this.instance.left = this.left; + this.aspectRatio = (this.right - this.left) / (this.top - this.bottom); + this.instance.aspect = this.aspectRatio; + this.instance.updateProjectionMatrix(); + return; + } + + if (property === 'right') { + this.instance.right = this.right; + this.aspectRatio = (this.right - this.left) / (this.top - this.bottom); + this.instance.aspect = this.aspectRatio; + this.instance.updateProjectionMatrix(); + return; + } + + if (property === 'top') { + this.instance.top = this.top; + this.aspectRatio = (this.right - this.left) / (this.top - this.bottom); + this.instance.aspect = this.aspectRatio; + this.instance.updateProjectionMatrix(); + return; + } + + if (property === 'bottom') { + this.instance.bottom = this.bottom; + this.aspectRatio = (this.right - this.left) / (this.top - this.bottom); + this.instance.aspect = this.aspectRatio; + this.instance.updateProjectionMatrix(); + return; + } + + R3.D3.Camera.Orthographic.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-camera-perspective-0.js b/src/r3-d3-camera-perspective-0.js new file mode 100644 index 0000000..4dbf938 --- /dev/null +++ b/src/r3-d3-camera-perspective-0.js @@ -0,0 +1,106 @@ +/** + * R3.D3.Camera.Perspective + * @param apiComponent + * @param inherited + * @constructor + */ +R3.D3.Camera.Perspective = function( + apiComponent, + inherited +) { + + __INHERIT_AND_INSTANTIATE__ + + R3.D3.Camera.call( + this, + apiComponent, + true + ); + +}; + +R3.D3.Camera.Perspective.prototype = Object.create(R3.D3.Camera.prototype); +R3.D3.Camera.Perspective.prototype.constructor = R3.D3.Camera.Perspective; + +/** + * Creates a camera instance + * @returns {*} + */ +R3.D3.Camera.Perspective.prototype.createInstance = function() { + + this.instance = this.graphics.PerspectiveCamera(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Camera.Perspective.prototype.updateInstance = function(property) { + + if (property === 'position') { + this.instance.position.set( + this.position.x, + this.position.y, + this.position.z + ); + this.instance.updateProjectionMatrix(); + return; + } + + if (property === 'lookAt') { + this.instance.lookAt( + this.lookAt.x, + this.lookAt.y, + this.lookAt.z + ); + this.instance.updateProjectionMatrix(); + return; + } + + if (property === 'near') { + this.instance.near = this.near; + this.instance.updateProjectionMatrix(); + return; + } + + if (property === 'far') { + this.instance.far = this.far; + this.instance.updateProjectionMatrix(); + return; + } + + if (property === 'fov') { + this.instance.fov = this.fov; + this.instance.updateProjectionMatrix(); + return; + } + + if (property === 'filmGauge') { + this.instance.filmGauge = this.filmGauge; + this.instance.updateProjectionMatrix(); + return; + } + + if (property === 'filmOffset') { + this.instance.filmOffset = this.filmOffset; + this.instance.updateProjectionMatrix(); + return; + } + + if (property === 'focus') { + this.instance.focus = this.focus; + this.instance.updateProjectionMatrix(); + return; + } + + if (property === 'zoom') { + this.instance.zoom = this.zoom; + this.instance.updateProjectionMatrix(); + return; + } + + R3.D3.Camera.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-d3-camera-perspective-stereo.js b/src/r3-d3-camera-perspective-stereo.js new file mode 100644 index 0000000..de07d91 --- /dev/null +++ b/src/r3-d3-camera-perspective-stereo.js @@ -0,0 +1,108 @@ +/** + * R3.D3.Camera.Perspective.Stereo + * @param apiComponent + * @constructor + */ +R3.D3.Camera.Perspective.Stereo = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Camera.Perspective.call( + this, + apiComponent, + true + ); + +}; + +R3.D3.Camera.Perspective.Stereo.prototype = Object.create(R3.D3.Camera.Perspective.prototype); +R3.D3.Camera.Perspective.Stereo.prototype.constructor = R3.D3.Camera.Perspective.Stereo; + +/** + * Creates a camera instance + * @returns {*} + */ +R3.D3.Camera.Perspective.Stereo.prototype.createInstance = function() { + + this.instance = this.graphics.StereoCamera(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Camera.Perspective.Stereo.prototype.updateInstance = function(property) { + + if (property === 'eyeSeperation') { + this.instance.userData.stereo.eyeSep = this.eyeSeperation; + this.instance.userData.stereo.update(this.instance); + return; + } + + if (property === 'position') { + R3.D3.Camera.Perspective.prototype.updateInstance.call(this, property); + this.instance.userData.stereo.update(this.instance); + return; + } + + if (property === 'lookAt') { + R3.D3.Camera.Perspective.prototype.updateInstance.call(this, property); + this.instance.userData.stereo.update(this.instance); + return; + } + + if (property === 'near') { + R3.D3.Camera.Perspective.prototype.updateInstance.call(this, property); + this.instance.userData.stereo.update(this.instance); + return; + } + + if (property === 'far') { + R3.D3.Camera.Perspective.prototype.updateInstance.call(this, property); + this.instance.userData.stereo.update(this.instance); + return; + } + + if (property === 'fov') { + R3.D3.Camera.Perspective.prototype.updateInstance.call(this, property); + this.instance.userData.stereo.update(this.instance); + return; + } + + if (property === 'filmGauge') { + R3.D3.Camera.Perspective.prototype.updateInstance.call(this, property); + this.instance.userData.stereo.update(this.instance); + return; + } + + if (property === 'filmOffset') { + R3.D3.Camera.Perspective.prototype.updateInstance.call(this, property); + this.instance.userData.stereo.update(this.instance); + return; + } + + if (property === 'focus') { + R3.D3.Camera.Perspective.prototype.updateInstance.call(this, property); + this.instance.userData.stereo.update(this.instance); + return; + } + + if (property === 'zoom') { + R3.D3.Camera.Perspective.prototype.updateInstance.call(this, property); + this.instance.userData.stereo.update(this.instance); + return; + } + + if (property === 'lookAt') { + R3.D3.Camera.Perspective.prototype.updateInstance.call(this, property); + this.instance.userData.stereo.update(this.instance); + return; + } + + R3.D3.Camera.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-d3-composer.js b/src/r3-d3-composer.js new file mode 100644 index 0000000..76ca354 --- /dev/null +++ b/src/r3-d3-composer.js @@ -0,0 +1,97 @@ +/** + * R3.D3.Composer + * @param apiComponent + * @constructor + */ +R3.D3.Composer = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.linkedComponents.renderer = R3.Renderer.D3; + this.linkedComponents.rendererTarget = R3.D3.RenderTarget; + this.linkedComponents.rendererTargetA = R3.D3.RenderTarget; + this.linkedComponents.rendererTargetB = R3.D3.RenderTarget; + this.linkedComponents.passes = [R3.D3.Pass]; + this.linkedComponents.camera = R3.D3.Camera; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.D3.Composer.prototype = Object.create(R3.Component.prototype); +R3.D3.Composer.prototype.constructor = R3.D3.Composer; + +R3.D3.Composer.prototype.createInstance = function() { + + /** + * Right - now we should have the right size of the composer - we can continue + */ + this.instance = this.graphics.Composer(this); + + __CREATE_INSTANCE__; +}; + + +/** + * Updates Composer instance + */ +R3.D3.Composer.prototype.updateInstance = function(property) { + + if (property === 'size') { + this.instance.setSize( + this.size.x, + this.size.y + ); + return; + } + + if (property === 'passes') { + + console.warn('TODO: test composer passes update'); + + this.instance.passes = []; + + this.passes.map( + function(pass) { + + if (R3.Utils.Unloaded(pass)) { + throw new Error('R3.D3.Composer.prototype.updateInstance ' + property + ' not ready'); + } + + this.instance.addPass(pass.instance); + + }.bind(this) + ); + + } + + __UPDATE_INSTANCE__; +}; + +/** + * Convenience function to render + */ +R3.D3.Composer.prototype.render = function() { + this.instance.render(); +}; + +/** + * True if ready + */ +R3.D3.Composer.prototype.ready = function() { + + if (this.passes.length === 0) { + return false; + } + + return this.passes.reduce( + function(result, pass) { + if (!pass.instance) { + result = false; + } + return result; + }, + true + ) +}; diff --git a/src/r3-d3-effect-0.js b/src/r3-d3-effect-0.js new file mode 100644 index 0000000..e428093 --- /dev/null +++ b/src/r3-d3-effect-0.js @@ -0,0 +1,99 @@ +/** + * R3.D3.Effect + * @constructor + * @param inherited + */ +R3.D3.Effect = function( + inherited +) { + + /** + * This class is intended to be inherited only + */ + if (R3.Utils.UndefinedOrNull(inherited)) { + throw new Error('This class can only be inherited'); + } + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Effect.prototype = Object.create(R3.Component.prototype); +R3.D3.Effect.prototype.constructor = R3.D3.Effect; + +R3.D3.Effect.prototype.createInstance = function() { + + this.setSize(); + + this.graphics.updateInstance(this, 'size'); + + R3.Event.Subscribe( + R3.Event.RENDERER_SIZE_CHANGE, + function(renderer) { + + if (renderer === this.renderer) { + + this.setSize(); + + this.graphics.updateInstance(this, 'size'); + } + + }.bind(this) + ); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Effect.prototype.updateInstance = function(property) { + + if (property === 'size') { + + this.setSize(); + + this.graphics.updateInstance(this, 'size'); + + return; + } + + if ( + property === 'renderer' || + property === 'viewport' + ) { + + if (R3.Utils.Unloaded(this.renderer)) { + throw new Error('R3.D3.Effect.prototype.renderer unloaded - this should not be the case'); + } + + this.setSize(); + + this.graphics.updateInstance(this, 'size'); + + return; + } + + __UPDATE_INSTANCE__; + +}; + +R3.D3.Effect.prototype.setSize = function() { + + if (R3.Utils.Unloaded(this.renderer)) { + console.warn('R3.D3.Effect.prototype.renderer unloaded'); + return; + } + + if (R3.Utils.Unloaded(this.viewport)) { + console.warn('R3.D3.Effect.prototype.viewport unloaded'); + return; + } + + var size = this.renderer.getSize(this.viewport); + + this.size.x = size.width; + this.size.y = size.height; + +}; diff --git a/src/r3-d3-effect-anaglyph.js b/src/r3-d3-effect-anaglyph.js new file mode 100644 index 0000000..04799b1 --- /dev/null +++ b/src/r3-d3-effect-anaglyph.js @@ -0,0 +1,42 @@ +/** + * R3.D3.Effect.Anaglyph + * @param apiComponent + * @constructor + */ +R3.D3.Effect.Anaglyph = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Effect.call( + this, + true + ); + +}; + +R3.D3.Effect.Anaglyph.prototype = Object.create(R3.D3.Effect.prototype); +R3.D3.Effect.Anaglyph.prototype.constructor = R3.D3.Effect.Anaglyph; + +/** + * Creates a camera instance + * @returns {*} + */ +R3.D3.Effect.Anaglyph.prototype.createInstance = function() { + + if (R3.Utils.Unloaded(this.renderer)) { + throw new Error('R3.D3.Effect.AnaglyphEffect.prototype.renderer not loaded'); + } + + this.instance = this.graphics.AnaglyphEffect(this.renderer); + + R3.D3.Effect.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Effect.Anaglyph.prototype.updateInstance = function(property) { + R3.D3.Effect.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-effect-parallax.js b/src/r3-d3-effect-parallax.js new file mode 100644 index 0000000..0d11a0e --- /dev/null +++ b/src/r3-d3-effect-parallax.js @@ -0,0 +1,45 @@ +/** + * R3.D3.Effect.Parallax + * @param apiComponent + * @constructor + */ +R3.D3.Effect.Parallax = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Effect.call( + this, + true + ); + +}; + +R3.D3.Effect.Parallax.prototype = Object.create(R3.D3.Effect.prototype); +R3.D3.Effect.Parallax.prototype.constructor = R3.D3.Effect.Parallax; + +/** + * Creates a camera instance + * @returns {*} + */ +R3.D3.Effect.Parallax.prototype.createInstance = function() { + + if (R3.Utils.Unloaded(this.renderer)) { + throw new Error('R3.D3.Effect.Parallax.prototype.renderer not loaded'); + } + + this.instance = this.graphics.ParallaxEffect(this.renderer); + + R3.D3.Effect.prototype.createInstance.call(this); + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Effect.Parallax.prototype.updateInstance = function(property) { + + R3.D3.Effect.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-d3-effect-stereo.js b/src/r3-d3-effect-stereo.js new file mode 100644 index 0000000..9ad8cdd --- /dev/null +++ b/src/r3-d3-effect-stereo.js @@ -0,0 +1,51 @@ +/** + * R3.D3.Effect.Stereo + * @param apiComponent + * @constructor + */ +R3.D3.Effect.Stereo = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Effect.call( + this, + true + ); + +}; + +R3.D3.Effect.Stereo.prototype = Object.create(R3.D3.Effect.prototype); +R3.D3.Effect.Stereo.prototype.constructor = R3.D3.Effect.Stereo; + +/** + * Creates a camera instance + * @returns {*} + */ +R3.D3.Effect.Stereo.prototype.createInstance = function() { + + if (R3.Utils.Unloaded(this.renderer)) { + throw new Error('R3.D3.Effect.Stereo.prototype.renderer not loaded'); + } + + this.instance = this.graphics.StereoEffect( + this.renderer, + this.eyeSeperation + ); + + R3.D3.Effect.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Effect.Stereo.prototype.updateInstance = function(property) { + + if (property === 'eyeSeperation') { + this.graphics.updateInstance(this, property); + return; + } + + R3.D3.Effect.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-face-0.js b/src/r3-d3-face-0.js new file mode 100644 index 0000000..fdc4616 --- /dev/null +++ b/src/r3-d3-face-0.js @@ -0,0 +1,183 @@ +/** + * R3.D3.Face + * @param apiComponent + * @param inherited + * @constructor + */ +R3.D3.Face = function( + apiComponent, + inherited +) { + + if (R3.Utils.UndefinedOrNull(inherited)) { + + __RUNTIME_COMPONENT__; + + } + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Face.prototype = Object.create(R3.Component.prototype); +R3.D3.Face.prototype.constructor = R3.D3.Face; + +/** + * We don't follow the standard procedure for Faces - We don't want them in the EntityManager registry - so + * they don't call component createinstance + * @param parentGeometry + */ +/** + * + */ +R3.D3.Face.prototype.createInstance = function() { + + /** + * At runtime we create the instance - at this point, our vertices should exist so we can calculate the face normal + * and vertex normals if required + */ + this.vertices.map( + function(vertex) { + if (R3.Utils.Unloaded(vertex)) { + throw new Error('Vertex information missing at R3.D3.Face.prototype.createInstance()'); + } + } + ); + + + /** + * Because we have multiple runtimes (graphics and physics) we need to conform to some standard when it comes to + * face winding order and normals - so we calculate the normals our way (we follow three.js standard) and apply + * it to our faces (of type graphics or physics) - of course - we only do this if this information is missing. + */ + if (R3.Utils.UndefinedOrNull(this.normal)) { + + /** + * + * We use the following three.js algorithm : + var pA = new THREE.Vector3(); + var pB = new THREE.Vector3(); + var pC = new THREE.Vector3(); + var cb = new THREE.Vector3(); + var ab = new THREE.Vector3(); + + pA.set( ax, ay, az ); + pB.set( bx, by, bz ); + pC.set( cx, cy, cz ); + cb.subVectors( pC, pB ); + ab.subVectors( pA, pB ); + cb.cross( ab ); + cb.normalize(); + var nx = cb.x; + var ny = cb.y; + var nz = cb.z; + normals.push( nx, ny, nz ); + normals.push( nx, ny, nz ); + normals.push( nx, ny, nz ); + */ + + var edge1 = new R3.API.Vector3( + { + parent : null, + register : false, + x : this.vertices[2].position.x - this.vertices[1].position.x, + y : this.vertices[2].position.y - this.vertices[1].position.y, + z : this.vertices[2].position.z - this.vertices[1].position.z + } + ); + + var edge2 = new R3.API.Vector3( + { + parent : null, + register : false, + x : this.vertices[0].position.x - this.vertices[1].position.x, + y : this.vertices[0].position.y - this.vertices[1].position.y, + z : this.vertices[0].position.z - this.vertices[1].position.z + } + ); + + edge1.cross(edge2); + + edge1.normalize(); + + this.normal.x = edge1.x; + this.normal.y = edge1.y; + this.normal.z = edge1.z; + + this.normal.updateInstance('x'); + this.normal.updateInstance('y'); + this.normal.updateInstance('z'); + + } + + /** + * Now we need to ensure our vertices have normals - if they don't, we assign to them our face normal + */ + this.vertices.map( + function(vertex) { + if (R3.Utils.UndefinedOrNull(vertex.normal)) { + vertex.normal.x = this.normal.x; + vertex.normal.y = this.normal.y; + vertex.normal.z = this.normal.z; + + vertex.normal.updateInstance('x'); + vertex.normal.updateInstance('y'); + vertex.normal.updateInstance('z'); + } + }.bind(this) + ); + + switch (this.parent.runtime) { + case R3.Runtime.GRAPHICS : + + this.instance = this.graphics.Face( + this + ); + + break; + + case R3.Runtime.PHYSICS : + + this.instance = this.physics.Face( + this + ); + + break; + } + + __CREATE_INSTANCE__; + +}; + +R3.D3.Face.prototype.updateInstance = function(property) { + + if (property === 'v0index') { + this.instance.a = this.v0index; + return; + } + + if (property === 'v1index') { + this.instance.b = this.v1index; + return; + } + + if (property === 'v2index') { + this.instance.c = this.v2index; + return; + } + + if (property === 'normal') { + this.instance.normal = this.normal.instance; + return; + } + + __UPDATE_INSTANCE__; +}; + +R3.D3.Face.prototype.createHelper = function() { + console.warn('todo: implement R3.D3.Face.prototype.createHelper()'); +}; + +R3.D3.Face.prototype.removeHelper = function() { + console.warn('todo: implement R3.D3.Face.prototype.removeHelper()'); +}; diff --git a/src/r3-d3-face-graphics.js b/src/r3-d3-face-graphics.js new file mode 100644 index 0000000..dc6ac7d --- /dev/null +++ b/src/r3-d3-face-graphics.js @@ -0,0 +1,131 @@ +/** + * R3.D3.Face.Graphics + * @param apiComponent + * @constructor + */ +R3.D3.Face.Graphics = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Face.call( + this, + apiComponent, + true + ); + +}; + +R3.D3.Face.Graphics.prototype = Object.create(R3.D3.Face.prototype); +R3.D3.Face.Graphics.prototype.constructor = R3.D3.Face.Graphics; + +R3.D3.Face.Graphics.prototype.createInstance = function() { + + this.instance = this.graphics.Face( + this.v0index, + this.v1index, + this.v2index, + this.normal, + this.color, + this.materialIndex, + this.vertexColors + ); + + __CREATE_INSTANCE__; +}; + +R3.D3.Face.Graphics.prototype.updateInstance = function(property) { + + if (property === 'materialIndex') { + this.instance.materialIndex = this.materialIndex; + this.parent.instance.groupsNeedUpdate = true; + return; + } + + if (property === 'uvs') { + this.uvs[uvSet][uvIndex].instance.x = this.uvs[uvSet][uvIndex].x; + this.uvs[uvSet][uvIndex].instance.y = this.uvs[uvSet][uvIndex].y; + this.parent.instance.uvsNeedUpdate = true; + return; + } + + if (property === 'color') { + this.instance.color.r = this.color.r; + this.instance.color.g = this.color.g; + this.instance.color.b = this.color.b; + return; + } + + if (property === 'vertexColors') { + this.instance.vertexColors = this.vertexColors.reduce( + function(result, vertexColor) { + result.push( + this.graphics.Color( + vertexColor.r, + vertexColor.g, + vertexColor.b + ) + ); + return result; + }.bind(this), + [] + ); + return; + } + + R3.D3.Face.prototype.updateInstance.call(this, property); +}; + + +R3.D3.Face.Graphics.prototype.createHelper = function() { + + console.warn('todo: createHelper needs work'); + return; + + this.backupProperties = { + color : { + r: this.color.r, + g: this.color.g, + b: this.color.b + }, + + material : { + emissive : { + r: mesh.materials[this.materialIndex].emissive.r, + g: mesh.materials[this.materialIndex].emissive.g, + b: mesh.materials[this.materialIndex].emissive.b + } + }, + + vertexColors : mesh.materials[this.materialIndex].vertexColors + }; + + this.instance.vertexColors = [ + new THREE.Color(1,0,0), + new THREE.Color(0,1,0), + new THREE.Color(0,0,1) + ]; + + mesh.materials[this.materialIndex].vertexColors = R3.D3.API.Material.TYPE_VERTEX_COLORS; + mesh.materials[this.materialIndex].updateInstance('vertexColors'); + + mesh.instance.geometry.elementsNeedUpdate = true; + +}; + +R3.D3.Face.Graphics.prototype.removeHelper = function() { + + console.warn('todo: removeHelper needs work'); + return; + + this.instance.color.r = this.backupProperties.color.r; + this.instance.color.g = this.backupProperties.color.g; + this.instance.color.b = this.backupProperties.color.b; + + mesh.instance.geometry.colorsNeedUpdate = true; + + mesh.materials[this.materialIndex].vertexColors = this.backupProperties.vertexColors; + mesh.materials[this.materialIndex].updateInstance('vertexColors'); + +}; \ No newline at end of file diff --git a/src/r3-d3-fog-0.js b/src/r3-d3-fog-0.js new file mode 100644 index 0000000..3557b7b --- /dev/null +++ b/src/r3-d3-fog-0.js @@ -0,0 +1,26 @@ +/** + * R3.D3.Fog + * @constructor + */ +R3.D3.Fog = function( + inherited +) { + + __INHERIT_ONLY__ + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Fog.prototype = Object.create(R3.Component.prototype); +R3.D3.Fog.prototype.constructor = R3.D3.Fog; + +R3.D3.Fog.prototype.updateInstance = function(property) { + + if (property === 'fogColor') { + this.graphics.updateInstance(this, property); + return; + } + + __UPDATE_INSTANCE__; +}; diff --git a/src/r3-d3-fog-exp.js b/src/r3-d3-fog-exp.js new file mode 100644 index 0000000..81fcf00 --- /dev/null +++ b/src/r3-d3-fog-exp.js @@ -0,0 +1,36 @@ +/** + * R3.D3.Fog.Exp + * @param apiComponent + * @constructor + */ +R3.D3.Fog.Exp = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Fog.call( + this, + true + ); +}; + +R3.D3.Fog.Exp.prototype = Object.create(R3.D3.Fog.prototype); +R3.D3.Fog.Exp.prototype.constructor = R3.D3.Fog.Exp; + +R3.D3.Fog.Exp.prototype.createInstance = function() { + + this.instance = this.graphics.FogExp(this); + + __CREATE_INSTANCE__; +}; + +R3.D3.Fog.Exp.prototype.updateInstance = function(property) { + + if (property === 'density') { + this.graphics.updateInstance(this, property); + return; + } + + R3.D3.Fog.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-fog-normal.js b/src/r3-d3-fog-normal.js new file mode 100644 index 0000000..ec74537 --- /dev/null +++ b/src/r3-d3-fog-normal.js @@ -0,0 +1,40 @@ +/** + * R3.D3.Fog.Normal + * @param apiComponent + * @constructor + */ +R3.D3.Fog.Normal = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Fog.call( + this, + true + ); + +}; + +R3.D3.Fog.Normal.prototype = Object.create(R3.D3.Fog.prototype); +R3.D3.Fog.Normal.prototype.constructor = R3.D3.Fog.Normal; + +R3.D3.Fog.Normal.prototype.createInstance = function() { + + this.instance = this.graphics.Fog(this); + + __CREATE_INSTANCE__; +}; + +R3.D3.Fog.Normal.prototype.updateInstance = function(property) { + + if ( + property === 'near' || + property === 'far' + ) { + this.graphics.updateInstance(this, property); + return; + } + + R3.D3.Fog.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-frictionContactMaterial.js b/src/r3-d3-frictionContactMaterial.js new file mode 100644 index 0000000..3c202e8 --- /dev/null +++ b/src/r3-d3-frictionContactMaterial.js @@ -0,0 +1,57 @@ +/** + * R3.D3.FrictionContactMaterial + * @param apiComponent + * @constructor + */ +R3.D3.FrictionContactMaterial = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.D3.FrictionContactMaterial.prototype = Object.create(R3.Component.prototype); +R3.D3.FrictionContactMaterial.prototype.constructor = R3.D3.FrictionContactMaterial; + +/** + * + * @returns {*} + */ +R3.D3.FrictionContactMaterial.prototype.createInstance = function() { + + this.instance = this.physics.ContactMaterial( + this.friction, + this.restitution, + this.contactEquationStiffness, + this.materials, + this.contactEquationRelaxation, + this.frictionEquationStiffness, + this.frictionEquationRelaxation + ); + + __CREATE_INSTANCE__; +}; + +/** + * + */ +R3.D3.FrictionContactMaterial.prototype.updateInstance = function(property) { + + if ( + property === 'materials' || + property === 'friction' || + property === 'restitution' || + property === 'contactEquationStiffness' || + property === 'contactEquationRelaxation' || + property === 'frictionEquationStiffness' || + property === 'frictionEquationRelaxation' + ) { + this.physics.updateInstance(this, property); + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-d3-frictionMaterial.js b/src/r3-d3-frictionMaterial.js new file mode 100644 index 0000000..a8986cb --- /dev/null +++ b/src/r3-d3-frictionMaterial.js @@ -0,0 +1,42 @@ +/** + * R3.D3.FrictionMaterial + * @param apiComponent + * @constructor + */ +R3.D3.FrictionMaterial = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.FrictionMaterial.prototype = Object.create(R3.Component.prototype); +R3.D3.FrictionMaterial.prototype.constructor = R3.D3.FrictionMaterial; + +R3.D3.FrictionMaterial.prototype.createInstance = function() { + + this.instance = this.physics.Material( + this.name, + this.friction, + this.restitution + ); + + __CREATE_INSTANCE__; +}; + +R3.D3.FrictionMaterial.prototype.updateInstance = function(property) { + + if ( + property === 'friction' || + property === 'restitution' + ) { + this.physics.updateInstance(this, property); + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-d3-geometry-0.js b/src/r3-d3-geometry-0.js new file mode 100644 index 0000000..b13d0ae --- /dev/null +++ b/src/r3-d3-geometry-0.js @@ -0,0 +1,87 @@ +/** + * R3.D3.Geometry + * @param apiComponent + * @param inherited + * @constructor + */ +R3.D3.Geometry = function( + apiComponent, + inherited +) { + + if (R3.Utils.UndefinedOrNull(inherited)) { + + __RUNTIME_COMPONENT__; + + } + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Geometry.prototype = Object.create(R3.Component.prototype); +R3.D3.Geometry.prototype.constructor = R3.D3.Geometry; + +R3.D3.Geometry.prototype.createInstance = function() { + + if (R3.Utils.UndefinedOrNull(this.instance)) { + /** + * This class is not inherited - create the default Geometry + */ + this.instance = this.graphics.Geometry(this); + } + + this.boundingBox.instance = this.instance.boundingBox; + + this.boundingBox.updateFromInstance('min'); + this.boundingBox.updateFromInstance('max'); + + this.boundingSphere.instance = this.instance.boundingSphere; + + this.boundingSphere.updateFromInstance('center'); + this.boundingSphere.updateFromInstance('radius'); + + __CREATE_INSTANCE__; + +}; + +/** + * Update Instance + * @param property + */ +R3.D3.Geometry.prototype.updateInstance = function(property) { + + if (R3.Utils.UndefinedOrNull(this.instance)) { + console.warn('no geometry instance'); + return; + } + + if (property === 'boundingBox') { + console.log('bounding box is read only'); + this.boundingBox.updateFromInstance('min'); + this.boundingBox.updateFromInstance('max'); + return; + } + + if (property === 'boundingSphere') { + console.log('bounding sphere is read only'); + this.boundingSphere.updateFromInstance('center'); + this.boundingSphere.updateFromInstance('radius'); + return; + } + + if (property === 'indexed') { + console.warn('todo: update indexed'); + return; + } + + if ( + property === 'faces' || + property === 'vertices' + ) { + console.warn('todo: update faces and vertices'); + return; + } + + __UPDATE_INSTANCE__; +}; diff --git a/src/r3-d3-geometry-buffer-0.js b/src/r3-d3-geometry-buffer-0.js new file mode 100644 index 0000000..c15c63c --- /dev/null +++ b/src/r3-d3-geometry-buffer-0.js @@ -0,0 +1,353 @@ +/** + * R3.D3.Geometry.Buffer + * @param apiComponent + * @param inherited + * @constructor + */ +R3.D3.Geometry.Buffer = function( + apiComponent, + inherited +) { + + if (R3.Utils.UndefinedOrNull(inherited)) { + + __RUNTIME_COMPONENT__; + + } + + R3.D3.Geometry.call( + this, + true + ); + +}; + +R3.D3.Geometry.Buffer.prototype = Object.create(R3.D3.Geometry.prototype); +R3.D3.Geometry.Buffer.prototype.constructor = R3.D3.Geometry.Buffer; + +R3.D3.Geometry.Buffer.prototype.createInstance = function() { + + if (R3.Utils.Defined(this.instance)) { + + /** + * This class is not inherited - create the instance + */ + this.instance = this.graphics.GeometryBuffer(this); + + } + + if (this.parent instanceof R3.D3.Mesh) { + + if (this.parent.instance.geometry) { + this.parent.instance.geometry.dispose(); + this.parent.instance.geometry = this.instance; + } + + if (this.parent.selected) { + this.parent.removeHelper(); + this.parent.createHelper(); + } + + } + + /** + * To add a material group to this instance - do this somewhere + * + * this.instance.addGroup( + * 0, + * this.instance.attributes.position.count, + * 0 + * ); + */ + + R3.D3.Geometry.prototype.createInstance.call(this); + +}; + +R3.D3.Geometry.Buffer.prototype.updateInstance = function(property) { + + if (R3.Utils.UndefinedOrNull(this.instance)) { + console.warn('no buffer geometry instance'); + return; + } + + if (property === 'faces') { + console.warn('todo: faces setup - just re-creating the instance for now'); + this.instance = null; + this.createInstance(); + return; + } + + if (property === 'vertices') { + console.warn('todo: vertices setup - just re-creating the instance for now'); + this.instance = null; + this.createInstance(); + return; + } + + if (property === 'attributes') { + console.warn('todo: attributes setup'); + return; + } + + if (property === 'drawRange') { + this.instance.setDrawRange( + this.drawRange.start, + this.drawRange.count + ); + return; + } + + if (property === 'groups') { + + this.instance.clearGroups(); + + this.groups.map( + function(group) { + this.instance.addGroup( + group.start, + group.count, + group.materialIndex + ) + }.bind(this) + ); + + return; + } + + if (property === 'index') { + console.warn('index is read only atm'); + return; + } + + if (property === 'morphAttributes') { + console.warn('morphAttributes is read only atm'); + return; + } + + R3.D3.Geometry.prototype.updateInstance.call(this, property); + +}; + +/** + * Update R3.D3.Geometry.Buffer from instance + */ +R3.D3.Geometry.Buffer.prototype.updateFromInstance = function() { + + console.warn('todo: use case for R3.D3.Geometry.Buffer.prototype.updateFromInstance()'); + return; + + this.faces = []; + this.vertices = []; + + var normalGeometry = new R3.D3.Geometry.Normal(this.graphics); + normalGeometry.instance.fromBufferGeometry(this.instance); + normalGeometry.updateFromInstance(); + + this.faces = normalGeometry.faces.map( + function(face) { + return face; + } + ); + + this.vertices = normalGeometry.vertices.map( + function(vertex) { + return vertex; + } + ); + + /** + * Now - we have to ensure our geometry is 'downgraded' to a normal buffer geometry + */ + this.geometryType = R3.D3.API.Geometry.GEOMETRY_TYPE_BUFFER; + + var componentType = R3.D3.API.Geometry.GetComponentType(R3.D3.API.Geometry.GEOMETRY_TYPE_BUFFER); + + this.replace(componentType); + + normalGeometry.remove(); + + // TODO: ok - after some testing - this code below doesn't work + // + // var vertices = this.instance.getAttribute('position').array; + // + // var uvs = this.instance.getAttribute('uv').array; + // + // this.instance.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 R3.D3.Vertex( + // this.graphics, + // new R3.D3.API.Vertex( + // new R3.Vector3( + // this.graphics, + // new R3.API.Vector3( + // vertices[i*3], + // vertices[i*3 + 1], + // vertices[i*3 + 2] + // ) + // ) + // ) + // ); + // + // var uv = new R3.Vector2( + // this.graphics, + // new R3.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 R3.D3.Face( + // this.graphics, + // new R3.D3.API.Face( + // null, + // null, + // faceIndexes[0], + // faceIndexes[1], + // faceIndexes[2], + // materialIndex, + // [[indexedUvs[0], indexedUvs[1], indexedUvs[2]]] + // ) + // ) + // ); + // + // indexedUvs = []; + // faceIndexes = []; + // } + // } + // + // }.bind(this)); + +}; + +/** + * Clears all groups + */ +R3.D3.Geometry.Buffer.prototype.clearGroups = function() { + this.instance.clearGroups(); + this.groups = this.instance.groups; +}; + +/** + * Clears all material groups and makes the geometry use a single material only + */ +R3.D3.Geometry.Buffer.prototype.toSingleMaterial = function() { + + if (this.instance && this.instance.index) { + + this.instance.clearGroups(); + + this.instance.addGroup( + 0, + this.instance.index.count, + 0 + ); + + this.groups = this.instance.groups.map( + function(group) { + return new R3.Group( + this.graphics, + group, + this + ) + }.bind(this) + ) + + } else { + console.warn('this is not an indexed buffer geometry or geometry not loaded'); + } + +}; + + +/** + * To non-index buffer geometry + */ +R3.D3.Geometry.Buffer.prototype.toNonIndexed = function() { + console.warn('not yet tested fully'); + + this.instance = this.instance.toNonIndexed(); + + this.parentMesh.instance.geometry = this.instance; + +// this.updateFromInstance(); +}; + +R3.D3.Geometry.Buffer.prototype.applyPositionRotationScale = function() { + + console.warn('todo and test'); + /** + * + You want to get the world position of a mesh's geometry, taking into consideration the mesh's transform matrix, mesh.matrix. + Also, your mesh geometry is THREE.BufferGeometry. + + Here is the pattern to follow: + + mesh = new THREE.Mesh( geometry, material ); + mesh.position.set( 10, 10, 10 ); + mesh.rotation.set( - Math.PI / 2, 0, 0 ); + mesh.scale.set( 1, 1, 1 ); + scene.add( mesh ); + + mesh.updateMatrix(); // make sure the mesh's matrix is updated + + var vec = new THREE.Vector3(); + var attribute = mesh.geometry.attributes.position; // we want the position data + var index = 1; // index is zero-based, so this the the 2nd vertex + + vec.fromAttribute( attribute, index ); // extract the x,y,z coordinates + + vec.applyMatrix4( mesh.matrix ); // apply the mesh's matrix transform + */ +}; + +/** + * Buffer geometry needs to do more work after updating vertex normals + */ +R3.D3.Geometry.Buffer.prototype.computeVertexNormals = function() { + this.instance.computeVertexNormals(); + // var attribute = this.instance.getAttribute('normal'); + // attribute.setDynamic(true); +}; + +R3.D3.Geometry.Buffer.prototype.normalizeNormals = function() { + this.instance.normalizeNormals(); + // var attribute = this.instance.getAttribute('normal'); + // attribute.setDynamic(true); +}; \ No newline at end of file diff --git a/src/r3-d3-geometry-buffer-box.js b/src/r3-d3-geometry-buffer-box.js new file mode 100644 index 0000000..ad081ba --- /dev/null +++ b/src/r3-d3-geometry-buffer-box.js @@ -0,0 +1,49 @@ +/** + * R3.D3.Geometry.Buffer.Box + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Box = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Box.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Box.prototype.constructor = R3.D3.Geometry.Buffer.Box; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Box.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferBox(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Box.prototype.updateInstance = function(property) { + + if ( + property === 'width' || + property === 'height' || + property === 'depth' || + property === 'widthSegments' || + property === 'heightSegments' || + property === 'depthSegments' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-circle.js b/src/r3-d3-geometry-buffer-circle.js new file mode 100644 index 0000000..46ce0af --- /dev/null +++ b/src/r3-d3-geometry-buffer-circle.js @@ -0,0 +1,47 @@ +/** + * R3.D3.Geometry.Buffer.Circle + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Circle = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Circle.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Circle.prototype.constructor = R3.D3.Geometry.Buffer.Circle; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Circle.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferCircle(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Circle.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'segments' || + property === 'thetaStart' || + property === 'thetaLength' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-cone.js b/src/r3-d3-geometry-buffer-cone.js new file mode 100644 index 0000000..3fa6ed1 --- /dev/null +++ b/src/r3-d3-geometry-buffer-cone.js @@ -0,0 +1,50 @@ +/** + * R3.D3.Geometry.Buffer.Cone + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Cone = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Cone.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Cone.prototype.constructor = R3.D3.Geometry.Buffer.Cone; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Cone.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferCone(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Cone.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'height' || + property === 'radialSegments' || + property === 'heightSegments' || + property === 'openEnded' || + property === 'thetaStart' || + property === 'thetaLength' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-cylinder.js b/src/r3-d3-geometry-buffer-cylinder.js new file mode 100644 index 0000000..540e0e5 --- /dev/null +++ b/src/r3-d3-geometry-buffer-cylinder.js @@ -0,0 +1,51 @@ +/** + * R3.D3.Geometry.Buffer.Cylinder + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Cylinder = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Cylinder.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Cylinder.prototype.constructor = R3.D3.Geometry.Buffer.Cylinder; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Cylinder.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferCylinder(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Cylinder.prototype.updateInstance = function(property) { + + if ( + property === 'radiusTop' || + property === 'radiusBottom' || + property === 'height' || + property === 'radialSegments' || + property === 'heightSegments' || + property === 'openEnded' || + property === 'thetaStart' || + property === 'thetaLength' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-dodecahedron.js b/src/r3-d3-geometry-buffer-dodecahedron.js new file mode 100644 index 0000000..722b1e0 --- /dev/null +++ b/src/r3-d3-geometry-buffer-dodecahedron.js @@ -0,0 +1,43 @@ +/** + * R3.D3.Geometry.Buffer.Dodecahedron + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Dodecahedron = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; +}; + +R3.D3.Geometry.Buffer.Dodecahedron.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Dodecahedron.prototype.constructor = R3.D3.Geometry.Buffer.Dodecahedron; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Dodecahedron.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferDodecahedron(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Dodecahedron.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'detail' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-extrude.js b/src/r3-d3-geometry-buffer-extrude.js new file mode 100644 index 0000000..3ac3382 --- /dev/null +++ b/src/r3-d3-geometry-buffer-extrude.js @@ -0,0 +1,50 @@ +/** + * R3.D3.Geometry.Buffer.Extrude + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Extrude = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Extrude.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Extrude.prototype.constructor = R3.D3.Geometry.Buffer.Extrude; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Extrude.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferExtrude(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Extrude.prototype.updateInstance = function(property) { + + if ( + property === 'shapes' || + property === 'curveSegments' || + property === 'steps' || + property === 'amount' || + property === 'bevelEnabled' || + property === 'bevelThickness' || + property === 'bevelSize' || + property === 'bevelSegments' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-icosahedron.js b/src/r3-d3-geometry-buffer-icosahedron.js new file mode 100644 index 0000000..09e1b04 --- /dev/null +++ b/src/r3-d3-geometry-buffer-icosahedron.js @@ -0,0 +1,44 @@ +/** + * R3.D3.Geometry.Buffer.Icosahedron + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Icosahedron = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Icosahedron.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Icosahedron.prototype.constructor = R3.D3.Geometry.Buffer.Icosahedron; + +/** + * Create Instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Icosahedron.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferIcosahedron(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Icosahedron.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'detail' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-instanced.js b/src/r3-d3-geometry-buffer-instanced.js new file mode 100644 index 0000000..16e121c --- /dev/null +++ b/src/r3-d3-geometry-buffer-instanced.js @@ -0,0 +1,45 @@ +/** + * R3.D3.Geometry.Buffer.Instanced + * @constructor + * @param apiComponent + */ +R3.D3.Geometry.Buffer.Instanced = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Instanced.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Instanced.prototype.constructor = R3.D3.Geometry.Buffer.Instanced; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Instanced.prototype.createInstance = function() { + + console.warn('todo: implement this fully'); + + this.instance = this.graphics.GeometryBufferInstanced(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Instanced.prototype.updateInstance = function(property) { + + if ( + property === 'maxInstancedCount' + ) { + this.instance.maxInstancedCount = this.maxInstancedCount; + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-lathe.js b/src/r3-d3-geometry-buffer-lathe.js new file mode 100644 index 0000000..d25ddd2 --- /dev/null +++ b/src/r3-d3-geometry-buffer-lathe.js @@ -0,0 +1,46 @@ +/** + * R3.D3.Geometry.Buffer.Lathe + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Lathe = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Lathe.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Lathe.prototype.constructor = R3.D3.Geometry.Buffer.Lathe; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Lathe.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferLathe(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Lathe.prototype.updateInstance = function(property) { + + if ( + property === 'points' || + property === 'segments' || + property === 'phiStart' || + property === 'phiLength' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-octahedron.js b/src/r3-d3-geometry-buffer-octahedron.js new file mode 100644 index 0000000..5fdb7c2 --- /dev/null +++ b/src/r3-d3-geometry-buffer-octahedron.js @@ -0,0 +1,44 @@ +/** + * R3.D3.Geometry.Buffer.Octahedron + * @constructor + * @param apiComponent + */ +R3.D3.Geometry.Buffer.Octahedron = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Octahedron.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Octahedron.prototype.constructor = R3.D3.Geometry.Buffer.Octahedron; + +/** + * Create Instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Octahedron.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferOctahedron(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Octahedron.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'detail' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-parametric.js b/src/r3-d3-geometry-buffer-parametric.js new file mode 100644 index 0000000..18e25ac --- /dev/null +++ b/src/r3-d3-geometry-buffer-parametric.js @@ -0,0 +1,45 @@ +/** + * R3.D3.Geometry.Buffer.Parametric + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Parametric = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Parametric.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Parametric.prototype.constructor = R3.D3.Geometry.Buffer.Parametric; + +/** + * Create Instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Parametric.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferParametric(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Parametric.prototype.updateInstance = function(property) { + + if ( + property === 'generatorFn' || + property === 'slices' || + property === 'stacks' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-plane.js b/src/r3-d3-geometry-buffer-plane.js new file mode 100644 index 0000000..eb6f7ea --- /dev/null +++ b/src/r3-d3-geometry-buffer-plane.js @@ -0,0 +1,46 @@ +/** + * R3.D3.Geometry.Buffer.Plane + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Plane = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Plane.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Plane.prototype.constructor = R3.D3.Geometry.Buffer.Plane; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Plane.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferPlane(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Plane.prototype.updateInstance = function(property) { + + if ( + property === 'width' || + property === 'height' || + property === 'widthSegments' || + property === 'heightSegments' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-polyhedron.js b/src/r3-d3-geometry-buffer-polyhedron.js new file mode 100644 index 0000000..ed543a5 --- /dev/null +++ b/src/r3-d3-geometry-buffer-polyhedron.js @@ -0,0 +1,46 @@ +/** + * R3.D3.Geometry.Buffer.Polyhedron + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Polyhedron = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Polyhedron.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Polyhedron.prototype.constructor = R3.D3.Geometry.Buffer.Polyhedron; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Polyhedron.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferPolyhedron(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Polyhedron.prototype.updateInstance = function(property) { + + if ( + property === 'vertices' || + property === 'indices' || + property === 'radius' || + property === 'detail' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-ring.js b/src/r3-d3-geometry-buffer-ring.js new file mode 100644 index 0000000..439cd4c --- /dev/null +++ b/src/r3-d3-geometry-buffer-ring.js @@ -0,0 +1,48 @@ +/** + * R3.D3.Geometry.Buffer.Ring + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Ring = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Ring.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Ring.prototype.constructor = R3.D3.Geometry.Buffer.Ring; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Ring.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferRing(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Ring.prototype.updateInstance = function(property) { + + if ( + property === 'innerRadius' || + property === 'outerRadius' || + property === 'thetaSegments' || + property === 'phiSegments' || + property === 'thetaStart' || + property === 'thetaLength' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-shape.js b/src/r3-d3-geometry-buffer-shape.js new file mode 100644 index 0000000..272f4fb --- /dev/null +++ b/src/r3-d3-geometry-buffer-shape.js @@ -0,0 +1,44 @@ +/** + * R3.D3.Geometry.Buffer.Shape + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Shape = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Shape.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Shape.prototype.constructor = R3.D3.Geometry.Buffer.Shape; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Shape.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferShape(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Shape.prototype.updateInstance = function(property) { + + if ( + property === 'shapes' || + property === 'curveSegments' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-sphere.js b/src/r3-d3-geometry-buffer-sphere.js new file mode 100644 index 0000000..aa06e22 --- /dev/null +++ b/src/r3-d3-geometry-buffer-sphere.js @@ -0,0 +1,49 @@ +/** + * R3.D3.Geometry.Buffer.Sphere + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Sphere = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Sphere.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Sphere.prototype.constructor = R3.D3.Geometry.Buffer.Sphere; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Sphere.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferSphere(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Sphere.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'widthSegments' || + property === 'heightSegments' || + property === 'phiStart' || + property === 'phiLength' || + property === 'thetaStart' || + property === 'thetaLength' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-tetrahedron.js b/src/r3-d3-geometry-buffer-tetrahedron.js new file mode 100644 index 0000000..e65fea8 --- /dev/null +++ b/src/r3-d3-geometry-buffer-tetrahedron.js @@ -0,0 +1,44 @@ +/** + * R3.D3.Geometry.Buffer.Tetrahedron + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Tetrahedron = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Tetrahedron.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Tetrahedron.prototype.constructor = R3.D3.Geometry.Buffer.Tetrahedron; + +/** + * Create Instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Tetrahedron.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferTetrahedron(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Tetrahedron.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'detail' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-text.js b/src/r3-d3-geometry-buffer-text.js new file mode 100644 index 0000000..02a4eb2 --- /dev/null +++ b/src/r3-d3-geometry-buffer-text.js @@ -0,0 +1,53 @@ +/** + * R3.D3.Geometry.Buffer.Text + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Text = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Text.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Text.prototype.constructor = R3.D3.Geometry.Buffer.Text; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Text.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferText(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Text.prototype.updateInstance = function(property) { + + if ( + property === 'text' || + property === 'font' || + property === 'size' || + property === 'height' || + property === 'curveSegments' || + property === 'bevelEnabled' || + property === 'bevelThickness' || + property === 'bevelSize' || + property === 'bevelSegments' + ) { + this.instance = this.createInstance(); + return; + } + + console.warn('do other properties here'); + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-torus.js b/src/r3-d3-geometry-buffer-torus.js new file mode 100644 index 0000000..1bdacf8 --- /dev/null +++ b/src/r3-d3-geometry-buffer-torus.js @@ -0,0 +1,47 @@ +/** + * R3.D3.Geometry.Buffer.Torus + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Torus = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Torus.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Torus.prototype.constructor = R3.D3.Geometry.Buffer.Torus; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Torus.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferTorus(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Torus.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'tube' || + property === 'radialSegments' || + property === 'tubularSegments' || + property === 'arc' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-torusKnot.js b/src/r3-d3-geometry-buffer-torusKnot.js new file mode 100644 index 0000000..3ffd406 --- /dev/null +++ b/src/r3-d3-geometry-buffer-torusKnot.js @@ -0,0 +1,48 @@ +/** + * R3.D3.Geometry.Buffer.TorusKnot + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.TorusKnot = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.TorusKnot.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.TorusKnot.prototype.constructor = R3.D3.Geometry.Buffer.TorusKnot; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.TorusKnot.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferTorusKnot(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.TorusKnot.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'tube' || + property === 'radialSegments' || + property === 'tubularSegments' || + property === 'p' || + property === 'q' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-buffer-tube.js b/src/r3-d3-geometry-buffer-tube.js new file mode 100644 index 0000000..1c7122c --- /dev/null +++ b/src/r3-d3-geometry-buffer-tube.js @@ -0,0 +1,47 @@ +/** + * R3.D3.Geometry.Buffer.Tube + * @param apiComponent + * @constructor + */ +R3.D3.Geometry.Buffer.Tube = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __RUNTIME_BUFFER_COMPONENT__; + +}; + +R3.D3.Geometry.Buffer.Tube.prototype = Object.create(R3.D3.Geometry.Buffer.prototype); +R3.D3.Geometry.Buffer.Tube.prototype.constructor = R3.D3.Geometry.Buffer.Tube; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Buffer.Tube.prototype.createInstance = function() { + + this.instance = this.graphics.GeometryBufferTube(this); + + R3.D3.Geometry.Buffer.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Buffer.Tube.prototype.updateInstance = function(property) { + + if ( + property === 'path' || + property === 'tubularSegments' || + property === 'radius' || + property === 'radialSegments' || + property === 'closed' + ) { + this.instance = this.createInstance(); + return; + } + + R3.D3.Geometry.Buffer.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-geometry-normal-0.js b/src/r3-d3-geometry-normal-0.js new file mode 100644 index 0000000..f1d701e --- /dev/null +++ b/src/r3-d3-geometry-normal-0.js @@ -0,0 +1,519 @@ +/** + * R3.D3.Geometry.Normal + * @param graphics + * @param apiNormalGeometry + * @property geometryType + * @constructor + */ +R3.D3.Geometry.Normal = function( + graphics, + apiNormalGeometry +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiNormalGeometry)) { + apiNormalGeometry = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL + }; + } + + R3.D3.API.Geometry.Normal.call( + this, + apiNormalGeometry, + apiNormalGeometry.colors, + apiNormalGeometry.lineDistances, + apiNormalGeometry.morphTargets, + apiNormalGeometry.morphNormals, + apiNormalGeometry.skinWeights, + apiNormalGeometry.skinIndices, + apiNormalGeometry.verticesNeedsUpdate, + apiNormalGeometry.elementsNeedUpdate, + apiNormalGeometry.uvsNeedUpdate, + apiNormalGeometry.normalsNeedUpdate, + apiNormalGeometry.colorsNeedUpdate, + apiNormalGeometry.groupsNeedUpdate, + apiNormalGeometry.lineDistancesNeedUpdate + ); + + this.colors = this.colors.map( + function(color) { + return new R3.Color( + this.graphics, + color + ) + }.bind(this) + ); + + this.skinWeights = this.skinWeights.map( + function(skinWeight) { + return new R3.Vector4( + this.graphics, + skinWeight, + this + ) + }.bind(this) + ); + + this.skinIndices = this.skinIndices.map( + function(skinIndex) { + return new R3.Vector4( + this.graphics, + skinIndex, + this + ) + }.bind(this) + ); + + R3.D3.Geometry.call( + this, + this.graphics, + this + ); +}; + +R3.D3.Geometry.Normal.prototype = Object.create(R3.D3.Geometry.prototype); +R3.D3.Geometry.Normal.prototype.constructor = R3.D3.Geometry.Normal; + +R3.D3.Geometry.Normal.prototype.createInstance = function() { + + if (R3.Utils.Defined(this.instance)) { + + /** + * We already have our object - just call our parent and return + */ + R3.D3.Geometry.prototype.createInstance.call(this); + + return; + } + + this.instance = new THREE.Geometry(); + + /** + * Setup colors + */ + this.instance.colors = this.colors.map( + function(color) { + return color.instance; + } + ); + + /** + * Setup faces + */ + this.applyToInstance('faces'); + + /** + * Setup line distances - we let three calculate it and then update our information + */ + this.instance.computeLineDistances(); + this.lineDistances = this.instance.lineDistances; + + /** + * Some more stuff + */ + if (this.morphTargets && this.morphTargets.length > 0) { + this.instance.morphTargets = this.morphTargets; + } + + if (this.morphNormals && this.morphNormals.length > 0) { + this.instance.morphNormals = this.morphNormals; + } + + if (this.skinWeights && this.skinWeights.length > 0) { + this.instance.skinWeights = this.skinWeights.map( + function(skinWeight) { + return skinWeight.instance; + } + ); + } + + if (this.skinIndices && this.skinIndices.length > 0) { + this.instance.skinIndices = this.skinIndices.map( + function(skinIndex) { + return skinIndex.instance; + } + ); + } + + /** + * Setup vertices + */ + this.applyToInstance('vertices'); + + //TODO: Below is actually for blender data - fix this server side and then remove this eventually + this.invertWindingOrder(); + this.computeFaceNormals(); + this.computeVertexNormals(); + + R3.D3.Geometry.prototype.createInstance.call(this); +}; + +R3.D3.Geometry.Normal.prototype.updateInstance = function(property) { + + if (R3.Utils.UndefinedOrNull(this.instance)) { + console.warn('no geometry instance'); + return; + } + + if (property === 'colors') { + this.instance.colors = this.colors.map( + function(color) { + return color.instance; + } + ); + this.instance.colorsNeedUpdate = true; + return; + } + + if (property === 'faces') { + this.applyToInstance(property); + this.instance.elementsNeedUpdate = true; + this.instance.groupsNeedUpdate = true; + return; + } + + if (property === 'lineDistances') { + this.instance.lineDistances = this.lineDistances; + this.instance.lineDistancesNeedUpdate = true; + return; + } + + if (property === 'morphTargets') { + this.instance.morphTargets = this.morphTargets; + return; + } + + if (property === 'morphNormals') { + this.instance.morphNormals = this.morphNormals; + return; + } + + if (property === 'skinWeights') { + + if (this.skinWeights) { + this.instance.skinWeights = this.skinWeights.map( + function(skinWeight) { + return skinWeight.instance; + } + ) + } else { + console.warn('todo : check deleting skinweights'); + delete this.instance.skinWeights; + } + + return; + } + + if (property === 'skinIndices') { + + if (this.skinIndices) { + this.instance.skinIndices = this.skinIndices.map( + function(skinIndex) { + return skinIndex.instance; + } + ) + } else { + console.warn('todo : check deleting skinIndices'); + delete this.instance.skinIndices; + } + + return; + } + + if (property === 'vertices') { + this.applyToInstance(property); + this.instance.verticesNeedUpdate = true; + return; + } + + /** + * Manually trigger updates (and ignore our setting) + */ + if (property === 'verticesNeedsUpdate') { + this.instance.verticesNeedsUpdate = true; + this.verticesNeedUpdate = false; + } + + if (property === 'elementsNeedUpdate') { + this.instance.elementsNeedUpdate = true; + this.elementsNeedUpdate = false; + } + + if (property === 'uvsNeedUpdate') { + this.instance.uvsNeedUpdate = true; + this.uvsNeedUpdate = false; + } + + if (property === 'normalsNeedUpdate') { + this.instance.normalsNeedUpdate = true; + this.normalsNeedUpdate = false; + } + + if (property === 'colorsNeedUpdate') { + this.instance.colorsNeedUpdate = true; + this.colorsNeedUpdate = false; + } + + if (property === 'groupsNeedUpdate') { + this.instance.groupsNeedUpdate = true; + this.groupsNeedUpdate = false; + } + + if (property === 'lineDistancesNeedUpdate') { + this.instance.lineDistancesNeedUpdate = true; + this.lineDistancesNeedUpdate = false; + } + + R3.D3.Geometry.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal to a R3.D3.API.Geometry.Normal + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.prototype.toApiObject = function() { + + var apiGeometry = R3.D3.Geometry.prototype.toApiObject.call(this); + + var apiNormalGeometry = new R3.D3.API.Geometry.Normal( + apiGeometry, + this.colors.map( + function(color) { + return color.toApiObject(); + } + ), + this.lineDistances, + this.morphTargets, + this.morphNormals, + this.skinWeights.map( + function(skinWeight) { + return skinWeight.toApiObject(); + } + ), + this.skinIndices.map( + function(skinIndex) { + return skinIndex.toApiObject(); + } + ) + ); + + return apiNormalGeometry; +}; + +/** + * Update R3.D3.Geometry.Normal from instance + */ +R3.D3.Geometry.Normal.prototype.updateFromInstance = function() { + + var processed = 0; + + this.faces = []; + this.vertices = []; + + this.instance.faces.map(function(face, faceIndex){ + + processed++; + + if (processed % 100 === 0) { + console.log('processed ' + processed + ' faces'); + } + + this.faces.push( + new R3.D3.Face( + this.graphics, + new R3.D3.API.Face( + null, + null, + face.a, + face.b, + face.c, + face.materialIndex, + [[ + new R3.API.Vector2( + this.instance.faceVertexUvs[0][faceIndex][0].x, + this.instance.faceVertexUvs[0][faceIndex][0].y + ), + new R3.API.Vector2( + this.instance.faceVertexUvs[0][faceIndex][1].x, + this.instance.faceVertexUvs[0][faceIndex][1].y + ), + new R3.API.Vector2( + this.instance.faceVertexUvs[0][faceIndex][2].x, + this.instance.faceVertexUvs[0][faceIndex][2].y + ) + ]], + new R3.Color( + this.graphics, + new R3.API.Color(this, + face.color.r, + face.color.g, + face.color.b + ) + ), + face.vertexColors.map(function(vertexColor){ + return new R3.Color( + this.graphics, + new R3.API.Color(this, + vertexColor.r, + vertexColor.g, + vertexColor.b + ) + ) + }.bind(this)), + face.vertexNormals.map(function(vertexNormal){ + return new R3.Vector3( + this.graphics, + new R3.API.Vector3( + vertexNormal.x, + vertexNormal.y, + vertexNormal.z + ) + ) + }.bind(this)), + new R3.Vector3( + this.graphics, + new R3.API.Vector3( + face.normal.x, + face.normal.y, + face.normal.z + ) + ) + ) + ) + ) + }.bind(this)); + + processed = 0; + + this.instance.vertices.map(function(vertex){ + + processed++; + + if (processed % 100 === 0) { + console.log('processed ' + processed + ' vertices'); + } + + this.vertices.push( + new R3.D3.Vertex( + this.graphics, + new R3.D3.API.Vertex( + new R3.Vector3( + this.graphics, + new R3.API.Vector3( + vertex.x, + vertex.y, + vertex.z + ) + ) + ) + ) + ) + + }.bind(this)); + +}; + +R3.D3.Geometry.Normal.prototype.applyToInstance = function(property) { + + if (property === 'faces') { + + this.faces = R3.Utils.SortFacesByMaterialIndex(this.faces); + + var standardUvs = []; + + /** + * Now setup each face and collect UV information during this process + */ + this.instance.faces = this.faces.map( + function(face) { + + if (face.uvs[0].length > 0) { + standardUvs.push( + face.uvs[0].map( + function(uv) { + return uv.instance; + } + ) + ); + } + + if (!face.instance) { + face.createInstance(this); + } + + return face.instance; + }.bind(this) + ); + + /** + * UV data - but only if it exists + */ + if (standardUvs.length > 0) { + this.instance.faceVertexUvs = [standardUvs]; + } + + return; + } + + if (property === 'vertices') { + this.instance.vertices = this.vertices.map( + function(vertex) { + return vertex.position.instance; + } + ); + } +}; + +/** + * Re-compute vertex normals + */ +R3.D3.Geometry.Normal.prototype.computeVertexNormals = function() { + console.log('re-computing vertex normals'); + this.instance.computeVertexNormals(); +}; + +/** + * Re-compute vertex normals + */ +R3.D3.Geometry.Normal.prototype.computeFaceNormals = function() { + console.log('re-computing face normals'); + this.instance.computeFaceNormals(); +}; + +/** + * Invert winding order + */ +R3.D3.Geometry.Normal.prototype.invertWindingOrder = function() { + + this.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; + + } + ); + + if (this.instance) { + this.instance.computeVertexNormals(); + this.instance.computeFaceNormals(); + this.instance.elementsNeedUpdate = true; + this.instance.normalsNeedUpdate = true; + } + +}; + +R3.D3.API.Geometry.Normal.prototype.updateNormals = function() { + console.warn('todo: R3.D3.API.Geometry.Normal.prototype.updateNormals'); +}; + +R3.D3.API.Geometry.Normal.prototype.updatePositions = function() { + console.warn('todo: R3.D3.API.Geometry.Normal.prototype.updatePositions'); +}; diff --git a/src/r3-d3-geometry-normal-box.js b/src/r3-d3-geometry-normal-box.js new file mode 100644 index 0000000..3cd54dd --- /dev/null +++ b/src/r3-d3-geometry-normal-box.js @@ -0,0 +1,97 @@ +/** + * R3.D3.Geometry.Normal.Box + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalBox + * @constructor + */ +R3.D3.Geometry.Normal.Box = function( + graphics, + apiGeometryNormalBox +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalBox)) { + apiGeometryNormalBox = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_BOX + }; + } + + R3.D3.API.Geometry.Normal.Box.call( + this, + apiGeometryNormalBox, + apiGeometryNormalBox.width, + apiGeometryNormalBox.height, + apiGeometryNormalBox.depth, + apiGeometryNormalBox.widthSegments, + apiGeometryNormalBox.heightSegments, + apiGeometryNormalBox.depthSegments + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalBox + ); + +}; + +R3.D3.Geometry.Normal.Box.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Box.prototype.constructor = R3.D3.Geometry.Normal.Box; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Box.prototype.createInstance = function() { + + this.instance = new THREE.BoxGeometry( + this.width, + this.height, + this.depth, + this.widthSegments, + this.heightSegments, + this.depthSegments + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Box.prototype.updateInstance = function(property) { + + if ( + property === 'width' + ) { + this.createInstance(); + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Box to a R3.D3.API.Geometry.Normal.Box + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Box.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalBox = new R3.D3.API.Geometry.Normal.Box( + apiNormalGeometry, + this.width, + this.height, + this.depth, + this.widthSegments, + this.heightSegments, + this.depthSegments + ); + + return apiGeometryNormalBox; +}; diff --git a/src/r3-d3-geometry-normal-circle.js b/src/r3-d3-geometry-normal-circle.js new file mode 100644 index 0000000..7f8461c --- /dev/null +++ b/src/r3-d3-geometry-normal-circle.js @@ -0,0 +1,105 @@ +/** + * R3.D3.Geometry.Normal.Circle + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalCircle + * @constructor + */ +R3.D3.Geometry.Normal.Circle = function( + graphics, + apiGeometryNormalCircle +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalCircle)) { + apiGeometryNormalCircle = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_CIRCLE + }; + } + + R3.D3.API.Geometry.Normal.Circle.call( + this, + apiGeometryNormalCircle, + apiGeometryNormalCircle.radius, + apiGeometryNormalCircle.segments, + apiGeometryNormalCircle.thetaStart, + apiGeometryNormalCircle.thetaLength + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalCircle + ); + +}; + +R3.D3.Geometry.Normal.Circle.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Circle.prototype.constructor = R3.D3.Geometry.Normal.Circle; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Circle.prototype.createInstance = function() { + + this.instance = new THREE.CircleGeometry( + this.radius, + this.segments, + this.thetaStart, + this.thetaLength + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Circle.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'segments' || + property === 'thetaStart' || + property === 'thetaLength' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Circle to a R3.D3.API.Geometry.Normal.Circle + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Circle.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalCircle = new R3.D3.API.Geometry.Normal.Circle( + apiNormalGeometry, + this.radius, + this.segments, + this.thetaStart, + this.thetaLength + ); + + return apiGeometryNormalCircle; +}; diff --git a/src/r3-d3-geometry-normal-cone.js b/src/r3-d3-geometry-normal-cone.js new file mode 100644 index 0000000..42b815f --- /dev/null +++ b/src/r3-d3-geometry-normal-cone.js @@ -0,0 +1,117 @@ +/** + * R3.D3.Geometry.Normal.Cone + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalCone + * @constructor + */ +R3.D3.Geometry.Normal.Cone = function( + graphics, + apiGeometryNormalCone +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalCone)) { + apiGeometryNormalCone = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_CONE + }; + } + + R3.D3.API.Geometry.Normal.Cone.call( + this, + apiGeometryNormalCone, + apiGeometryNormalCone.radius, + apiGeometryNormalCone.height, + apiGeometryNormalCone.radialSegments, + apiGeometryNormalCone.heightSegments, + apiGeometryNormalCone.openEnded, + apiGeometryNormalCone.thetaStart, + apiGeometryNormalCone.thetaLength + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalCone + ); + +}; + +R3.D3.Geometry.Normal.Cone.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Cone.prototype.constructor = R3.D3.Geometry.Normal.Cone; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Cone.prototype.createInstance = function() { + + this.instance = new THREE.ConeGeometry( + this.radius, + this.height, + this.radialSegments, + this.heightSegments, + this.openEnded, + this.thetaStart, + this.thetaLength + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Cone.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'height' || + property === 'radialSegments' || + property === 'heightSegments' || + property === 'openEnded' || + property === 'thetaStart' || + property === 'thetaLength' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Cone to a R3.D3.API.Geometry.Normal.Cone + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Cone.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalCone = new R3.D3.API.Geometry.Normal.Cone( + apiNormalGeometry, + this.radius, + this.height, + this.radialSegments, + this.heightSegments, + this.openEnded, + this.thetaStart, + this.thetaLength + ); + + return apiGeometryNormalCone; +}; diff --git a/src/r3-d3-geometry-normal-cylinder.js b/src/r3-d3-geometry-normal-cylinder.js new file mode 100644 index 0000000..5ed7aef --- /dev/null +++ b/src/r3-d3-geometry-normal-cylinder.js @@ -0,0 +1,121 @@ +/** + * R3.D3.Geometry.Normal.Cylinder + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalCylinder + * @constructor + */ +R3.D3.Geometry.Normal.Cylinder = function( + graphics, + apiGeometryNormalCylinder +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalCylinder)) { + apiGeometryNormalCylinder = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_CYLINDER + }; + } + + R3.D3.API.Geometry.Normal.Cylinder.call( + this, + apiGeometryNormalCylinder, + apiGeometryNormalCylinder.radiusTop, + apiGeometryNormalCylinder.radiusBottom, + apiGeometryNormalCylinder.height, + apiGeometryNormalCylinder.radialSegments, + apiGeometryNormalCylinder.heightSegments, + apiGeometryNormalCylinder.openEnded, + apiGeometryNormalCylinder.thetaStart, + apiGeometryNormalCylinder.thetaLength + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalCylinder + ); + +}; + +R3.D3.Geometry.Normal.Cylinder.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Cylinder.prototype.constructor = R3.D3.Geometry.Normal.Cylinder; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Cylinder.prototype.createInstance = function() { + + this.instance = new THREE.CylinderGeometry( + this.radiusTop, + this.radiusBottom, + this.height, + this.radialSegments, + this.heightSegments, + this.openEnded, + this.thetaStart, + this.thetaLength + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Cylinder.prototype.updateInstance = function(property) { + + if ( + property === 'radiusTop' || + property === 'radiusBottom' || + property === 'height' || + property === 'radialSegments' || + property === 'heightSegments' || + property === 'openEnded' || + property === 'thetaStart' || + property === 'thetaLength' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Cylinder to a R3.D3.API.Geometry.Normal.Cylinder + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Cylinder.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalCylinder = new R3.D3.API.Geometry.Normal.Cylinder( + apiNormalGeometry, + this.radiusTop, + this.radiusBottom, + this.height, + this.radialSegments, + this.heightSegments, + this.openEnded, + this.thetaStart, + this.thetaLength + ); + + return apiGeometryNormalCylinder; +}; diff --git a/src/r3-d3-geometry-normal-dodecahedron.js b/src/r3-d3-geometry-normal-dodecahedron.js new file mode 100644 index 0000000..ab405e8 --- /dev/null +++ b/src/r3-d3-geometry-normal-dodecahedron.js @@ -0,0 +1,97 @@ +/** + * R3.D3.Geometry.Normal.Dodecahedron + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalDodecahedron + * @constructor + */ +R3.D3.Geometry.Normal.Dodecahedron = function( + graphics, + apiGeometryNormalDodecahedron +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalDodecahedron)) { + apiGeometryNormalDodecahedron = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_DODECAHEDRON + }; + } + + R3.D3.API.Geometry.Normal.Dodecahedron.call( + this, + apiGeometryNormalDodecahedron, + apiGeometryNormalDodecahedron.radius, + apiGeometryNormalDodecahedron.detail + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalDodecahedron + ); + +}; + +R3.D3.Geometry.Normal.Dodecahedron.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Dodecahedron.prototype.constructor = R3.D3.Geometry.Normal.Dodecahedron; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Dodecahedron.prototype.createInstance = function() { + + this.instance = new THREE.DodecahedronGeometry( + this.radius, + this.detail + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Dodecahedron.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'detail' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Dodecahedron to a R3.D3.API.Geometry.Normal.Dodecahedron + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Dodecahedron.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalDodecahedron = new R3.D3.API.Geometry.Normal.Dodecahedron( + apiNormalGeometry, + this.radius, + this.detail + ); + + return apiGeometryNormalDodecahedron; +}; diff --git a/src/r3-d3-geometry-normal-edges.js b/src/r3-d3-geometry-normal-edges.js new file mode 100644 index 0000000..9f59967 --- /dev/null +++ b/src/r3-d3-geometry-normal-edges.js @@ -0,0 +1,108 @@ +/** + * R3.D3.Geometry.Normal.Edges + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalEdges + * @constructor + */ +R3.D3.Geometry.Normal.Edges = function( + graphics, + apiGeometryNormalEdges +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalEdges)) { + apiGeometryNormalEdges = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_EDGES + }; + } + + R3.D3.API.Geometry.Normal.Edges.call( + this, + apiGeometryNormalEdges, + apiGeometryNormalEdges.geometry, + apiGeometryNormalEdges.thresholdAngle + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalEdges + ); + +}; + +R3.D3.Geometry.Normal.Edges.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Edges.prototype.constructor = R3.D3.Geometry.Normal.Edges; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Edges.prototype.createInstance = function() { + + if (!this.geometry || !this.geometry.instance) { + console.warn('geometry not ready'); + return; + } + + this.instance = new THREE.EdgesGeometry( + this.geometry.instance, + this.thresholdAngle + ); + + console.log('edges instance created'); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Edges.prototype.updateInstance = function(property) { + + if ( + property === 'geometry' || + property === 'thresholdAngle' + ) { + /** + * Could be that geometry was not ready + */ + if (this.instance) { + this.instance.dispose(); + } + + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Edges to a R3.D3.API.Geometry.Normal.Edges + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Edges.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalEdges = new R3.D3.API.Geometry.Normal.Edges( + apiNormalGeometry, + R3.Utils.IdOrNull(this.geometry), + this.thresholdAngle + ); + + return apiGeometryNormalEdges; +}; diff --git a/src/r3-d3-geometry-normal-extrude.js b/src/r3-d3-geometry-normal-extrude.js new file mode 100644 index 0000000..3b09811 --- /dev/null +++ b/src/r3-d3-geometry-normal-extrude.js @@ -0,0 +1,141 @@ +/** + * R3.D3.Geometry.Normal.Extrude + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalExtrude + * @constructor + */ +R3.D3.Geometry.Normal.Extrude = function( + graphics, + apiGeometryNormalExtrude +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalExtrude)) { + apiGeometryNormalExtrude = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_EXTRUDE + }; + } + + R3.D3.API.Geometry.Normal.Extrude.call( + this, + apiGeometryNormalExtrude, + apiGeometryNormalExtrude.shapes, + apiGeometryNormalExtrude.curveSegments, + apiGeometryNormalExtrude.steps, + apiGeometryNormalExtrude.amount, + apiGeometryNormalExtrude.bevelEnabled, + apiGeometryNormalExtrude.bevelThickness, + apiGeometryNormalExtrude.bevelSize, + apiGeometryNormalExtrude.bevelSegments, + apiGeometryNormalExtrude.extrudePath, + apiGeometryNormalExtrude.frames, + apiGeometryNormalExtrude.UVGenerator + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalExtrude + ); + +}; + +R3.D3.Geometry.Normal.Extrude.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Extrude.prototype.constructor = R3.D3.Geometry.Normal.Extrude; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Extrude.prototype.createInstance = function() { + + this.instance = new THREE.ExtrudeGeometry( + this.shapes.map( + function(shape) { + return shape.instance; + } + ), + { + curveSegments : this.curveSegments, + steps : this.steps, + amount : this.amount, + bevelEnabled : this.bevelEnabled, + bevelThickness : this.bevelThickness, + bevelSize : this.bevelSize, + bevelSegments : this.bevelSegments + } + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Extrude.prototype.updateInstance = function(property) { + + if ( + property === 'shapes' || + property === 'curveSegments' || + property === 'steps' || + property === 'amount' || + property === 'bevelEnabled' || + property === 'bevelThickness' || + property === 'bevelSize' || + property === 'bevelSegments' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + console.warn('do other properties here'); + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Extrude to a R3.D3.API.Geometry.Normal.Extrude + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Extrude.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalExtrude = new R3.D3.API.Geometry.Normal.Extrude( + apiNormalGeometry, + this.shapes.map( + function(shape) { + return R3.Utils.IdOrNull(shape); + } + ), + this.curveSegments, + this.steps, + this.amount, + this.bevelEnabled, + this.bevelThickness, + this.bevelSize, + this.bevelSegments, + R3.Utils.IdOrNull(this.extrudePath), + this.frames.map(function(frame){ + return R3.Utils.IdOrNull(frame); + }), + R3.Utils.IdOrNull(this.UVGenerator) + ); + + return apiGeometryNormalExtrude; +}; diff --git a/src/r3-d3-geometry-normal-icosahedron.js b/src/r3-d3-geometry-normal-icosahedron.js new file mode 100644 index 0000000..007f398 --- /dev/null +++ b/src/r3-d3-geometry-normal-icosahedron.js @@ -0,0 +1,97 @@ +/** + * R3.D3.Geometry.Normal.Icosahedron + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalIcosahedron + * @constructor + */ +R3.D3.Geometry.Normal.Icosahedron = function( + graphics, + apiGeometryNormalIcosahedron +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalIcosahedron)) { + apiGeometryNormalIcosahedron = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_ICOSAHEDRON + }; + } + + R3.D3.API.Geometry.Normal.Icosahedron.call( + this, + apiGeometryNormalIcosahedron, + apiGeometryNormalIcosahedron.radius, + apiGeometryNormalIcosahedron.detail + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalIcosahedron + ); + +}; + +R3.D3.Geometry.Normal.Icosahedron.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Icosahedron.prototype.constructor = R3.D3.Geometry.Normal.Icosahedron; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Icosahedron.prototype.createInstance = function() { + + this.instance = new THREE.IcosahedronGeometry( + this.radius, + this.detail + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Icosahedron.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'detail' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Icosahedron to a R3.D3.API.Geometry.Normal.Icosahedron + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Icosahedron.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalIcosahedron = new R3.D3.API.Geometry.Normal.Icosahedron( + apiNormalGeometry, + this.radius, + this.detail + ); + + return apiGeometryNormalIcosahedron; +}; diff --git a/src/r3-d3-geometry-normal-lathe.js b/src/r3-d3-geometry-normal-lathe.js new file mode 100644 index 0000000..0905aa3 --- /dev/null +++ b/src/r3-d3-geometry-normal-lathe.js @@ -0,0 +1,113 @@ +/** + * R3.D3.Geometry.Normal.Lathe + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalLathe + * @constructor + */ +R3.D3.Geometry.Normal.Lathe = function( + graphics, + apiGeometryNormalLathe +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalLathe)) { + apiGeometryNormalLathe = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_LATHE + }; + } + + R3.D3.API.Geometry.Normal.Lathe.call( + this, + apiGeometryNormalLathe, + apiGeometryNormalLathe.points, + apiGeometryNormalLathe.segments, + apiGeometryNormalLathe.phiStart, + apiGeometryNormalLathe.phiLength + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalLathe + ); + +}; + +R3.D3.Geometry.Normal.Lathe.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Lathe.prototype.constructor = R3.D3.Geometry.Normal.Lathe; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Lathe.prototype.createInstance = function() { + + this.instance = new THREE.LatheGeometry( + this.points.map( + function(point) { + return point.instance; + } + ), + this.segments, + this.phiStart, + this.phiLength + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Lathe.prototype.updateInstance = function(property) { + + if ( + property === 'points' || + property === 'segments' || + property === 'phiStart' || + property === 'phiLength' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Lathe to a R3.D3.API.Geometry.Normal.Lathe + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Lathe.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalLathe = new R3.D3.API.Geometry.Normal.Lathe( + apiNormalGeometry, + this.points.map( + function(point) { + return point.toApiObject(); + } + ), + this.segments, + this.phiStart, + this.phiLength + ); + + return apiGeometryNormalLathe; +}; diff --git a/src/r3-d3-geometry-normal-octahedron.js b/src/r3-d3-geometry-normal-octahedron.js new file mode 100644 index 0000000..6c99026 --- /dev/null +++ b/src/r3-d3-geometry-normal-octahedron.js @@ -0,0 +1,97 @@ +/** + * R3.D3.Geometry.Normal.Octahedron + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalOctahedron + * @constructor + */ +R3.D3.Geometry.Normal.Octahedron = function( + graphics, + apiGeometryNormalOctahedron +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalOctahedron)) { + apiGeometryNormalOctahedron = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_OCTAHEDRON + }; + } + + R3.D3.API.Geometry.Normal.Octahedron.call( + this, + apiGeometryNormalOctahedron, + apiGeometryNormalOctahedron.radius, + apiGeometryNormalOctahedron.detail + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalOctahedron + ); + +}; + +R3.D3.Geometry.Normal.Octahedron.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Octahedron.prototype.constructor = R3.D3.Geometry.Normal.Octahedron; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Octahedron.prototype.createInstance = function() { + + this.instance = new THREE.OctahedronGeometry( + this.radius, + this.detail + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Octahedron.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'detail' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Octahedron to a R3.D3.API.Geometry.Normal.Octahedron + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Octahedron.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalOctahedron = new R3.D3.API.Geometry.Normal.Octahedron( + apiNormalGeometry, + this.radius, + this.detail + ); + + return apiGeometryNormalOctahedron; +}; diff --git a/src/r3-d3-geometry-normal-parametric.js b/src/r3-d3-geometry-normal-parametric.js new file mode 100644 index 0000000..7a2e266 --- /dev/null +++ b/src/r3-d3-geometry-normal-parametric.js @@ -0,0 +1,101 @@ +/** + * R3.D3.Geometry.Normal.Parametric + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalParametric + * @constructor + */ +R3.D3.Geometry.Normal.Parametric = function( + graphics, + apiGeometryNormalParametric +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalParametric)) { + apiGeometryNormalParametric = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_PARAMETRIC + }; + } + + R3.D3.API.Geometry.Normal.Parametric.call( + this, + apiGeometryNormalParametric, + apiGeometryNormalParametric.generatorFn, + apiGeometryNormalParametric.slices, + apiGeometryNormalParametric.stacks + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalParametric + ); + +}; + +R3.D3.Geometry.Normal.Parametric.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Parametric.prototype.constructor = R3.D3.Geometry.Normal.Parametric; + +/** + * Create Instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Parametric.prototype.createInstance = function() { + + this.instance = new THREE.ParametricGeometry( + new Function('u', 'v', this.generatorFn).bind(this), + this.slices, + this.stacks + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Parametric.prototype.updateInstance = function(property) { + + if ( + property === 'generatorFn' || + property === 'slices' || + property === 'stacks' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Parametric to a R3.D3.API.Geometry.Normal.Parametric + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Parametric.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalParametric = new R3.D3.API.Geometry.Normal.Parametric( + apiNormalGeometry, + this.generatorFn, + this.slices, + this.stacks + ); + + return apiGeometryNormalParametric; +}; diff --git a/src/r3-d3-geometry-normal-plane.js b/src/r3-d3-geometry-normal-plane.js new file mode 100644 index 0000000..9a59fab --- /dev/null +++ b/src/r3-d3-geometry-normal-plane.js @@ -0,0 +1,100 @@ +/** + * R3.D3.Geometry.Normal.Plane + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalPlane + * @constructor + */ +R3.D3.Geometry.Normal.Plane = function( + graphics, + apiGeometryNormalPlane +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalPlane)) { + apiGeometryNormalPlane = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_PLANE + }; + } + + R3.D3.API.Geometry.Normal.Plane.call( + this, + apiGeometryNormalPlane, + apiGeometryNormalPlane.width, + apiGeometryNormalPlane.height, + apiGeometryNormalPlane.widthSegments, + apiGeometryNormalPlane.heightSegments + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalPlane + ); + +}; + +R3.D3.Geometry.Normal.Plane.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Plane.prototype.constructor = R3.D3.Geometry.Normal.Plane; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Plane.prototype.createInstance = function() { + + this.instance = new THREE.PlaneGeometry( + this.width, + this.height, + this.widthSegments, + this.heightSegments + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Plane.prototype.updateInstance = function(property) { + + if ( + property === 'width' || + property === 'height' || + property === 'widthSegments' || + property === 'heightSegments' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Plane to a R3.D3.API.Geometry.Normal.Plane + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Plane.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalPlane = new R3.D3.API.Geometry.Normal.Plane( + apiNormalGeometry, + this.width, + this.height, + this.widthSegments, + this.heightSegments + ); + + return apiGeometryNormalPlane; +}; diff --git a/src/r3-d3-geometry-normal-polyhedron.js b/src/r3-d3-geometry-normal-polyhedron.js new file mode 100644 index 0000000..9cdd186 --- /dev/null +++ b/src/r3-d3-geometry-normal-polyhedron.js @@ -0,0 +1,116 @@ +/** + * R3.D3.Geometry.Normal.Polyhedron + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalPolyhedron + * @constructor + */ +R3.D3.Geometry.Normal.Polyhedron = function( + graphics, + apiGeometryNormalPolyhedron +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalPolyhedron)) { + apiGeometryNormalPolyhedron = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_POLYHEDRON + }; + } + + R3.D3.API.Geometry.Normal.Polyhedron.call( + this, + apiGeometryNormalPolyhedron, + apiGeometryNormalPolyhedron.vertices, + apiGeometryNormalPolyhedron.indices, + apiGeometryNormalPolyhedron.radius, + apiGeometryNormalPolyhedron.detail + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalPolyhedron + ); + +}; + +R3.D3.Geometry.Normal.Polyhedron.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Polyhedron.prototype.constructor = R3.D3.Geometry.Normal.Polyhedron; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Polyhedron.prototype.createInstance = function() { + + this.instance = new THREE.PolyhedronGeometry( + this.vertices.map( + function(vertex) { + return vertex.position.instance; + } + ), + this.indices.map( + function(index) { + return index.instance; + } + ), + this.radius, + this.detail + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Polyhedron.prototype.updateInstance = function(property) { + + if ( + property === 'vertices' || + property === 'indices' || + property === 'radius' || + property === 'detail' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Polyhedron to a R3.D3.API.Geometry.Normal.Polyhedron + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Polyhedron.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalPolyhedron = new R3.D3.API.Geometry.Normal.Polyhedron( + apiNormalGeometry, + this.vertices.map( + function(vertex){ + return vertex.toApiObject(); + } + ), + this.indices.map( + function(index){ + return index.toApiObject(); + } + ), + this.radius, + this.detail + ); + + return apiGeometryNormalPolyhedron; +}; diff --git a/src/r3-d3-geometry-normal-ring.js b/src/r3-d3-geometry-normal-ring.js new file mode 100644 index 0000000..1aea04b --- /dev/null +++ b/src/r3-d3-geometry-normal-ring.js @@ -0,0 +1,113 @@ +/** + * R3.D3.Geometry.Normal.Ring + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalRing + * @constructor + */ +R3.D3.Geometry.Normal.Ring = function( + graphics, + apiGeometryNormalRing +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalRing)) { + apiGeometryNormalRing = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_RING + }; + } + + R3.D3.API.Geometry.Normal.Ring.call( + this, + apiGeometryNormalRing, + apiGeometryNormalRing.innerRadius, + apiGeometryNormalRing.outerRadius, + apiGeometryNormalRing.thetaSegments, + apiGeometryNormalRing.phiSegments, + apiGeometryNormalRing.thetaStart, + apiGeometryNormalRing.thetaLength + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalRing + ); + +}; + +R3.D3.Geometry.Normal.Ring.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Ring.prototype.constructor = R3.D3.Geometry.Normal.Ring; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Ring.prototype.createInstance = function() { + + this.instance = new THREE.RingGeometry( + this.innerRadius, + this.outerRadius, + this.thetaSegments, + this.phiSegments, + this.thetaStart, + this.thetaLength + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Ring.prototype.updateInstance = function(property) { + + if ( + property === 'innerRadius' || + property === 'outerRadius' || + property === 'thetaSegments' || + property === 'phiSegments' || + property === 'thetaStart' || + property === 'thetaLength' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Ring to a R3.D3.API.Geometry.Normal.Ring + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Ring.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalRing = new R3.D3.API.Geometry.Normal.Ring( + apiNormalGeometry, + this.innerRadius, + this.outerRadius, + this.thetaSegments, + this.phiSegments, + this.thetaStart, + this.thetaLength + ); + + return apiGeometryNormalRing; +}; diff --git a/src/r3-d3-geometry-normal-shape.js b/src/r3-d3-geometry-normal-shape.js new file mode 100644 index 0000000..26a2707 --- /dev/null +++ b/src/r3-d3-geometry-normal-shape.js @@ -0,0 +1,112 @@ +/** + * R3.D3.Geometry.Normal.Shape + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalShape + * @constructor + */ +R3.D3.Geometry.Normal.Shape = function( + graphics, + apiGeometryNormalShape +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalShape)) { + apiGeometryNormalShape = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_SHAPE + }; + } + + R3.D3.API.Geometry.Normal.Shape.call( + this, + apiGeometryNormalShape, + apiGeometryNormalShape.shapes, + apiGeometryNormalShape.curveSegments + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalShape + ); + +}; + +R3.D3.Geometry.Normal.Shape.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Shape.prototype.constructor = R3.D3.Geometry.Normal.Shape; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Shape.prototype.createInstance = function() { + + if (this.shapes.length === 0) { + console.warn('shapes are not ready for this instance'); + return; + } + + this.instance = new THREE.ShapeGeometry( + this.shapes.map( + function(shape) { + return shape.instance; + } + ), + this.curveSegments + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Shape.prototype.updateInstance = function(property) { + + if ( + property === 'shapes' || + property === 'curveSegments' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + console.warn('do other properties here'); + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Shape to a R3.D3.API.Geometry.Normal.Shape + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Shape.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalShape = new R3.D3.API.Geometry.Normal.Shape( + apiNormalGeometry, + this.shapes.map( + function(shape) { + return R3.Utils.IdOrNull(shape); + } + ), + this.curveSegments + ); + + return apiGeometryNormalShape; +}; diff --git a/src/r3-d3-geometry-normal-sphere.js b/src/r3-d3-geometry-normal-sphere.js new file mode 100644 index 0000000..1a7de41 --- /dev/null +++ b/src/r3-d3-geometry-normal-sphere.js @@ -0,0 +1,117 @@ +/** + * R3.D3.Geometry.Normal.Sphere + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalSphere + * @constructor + */ +R3.D3.Geometry.Normal.Sphere = function( + graphics, + apiGeometryNormalSphere +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalSphere)) { + apiGeometryNormalSphere = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_SPHERE + }; + } + + R3.D3.API.Geometry.Normal.Sphere.call( + this, + apiGeometryNormalSphere, + apiGeometryNormalSphere.radius, + apiGeometryNormalSphere.widthSegments, + apiGeometryNormalSphere.heightSegments, + apiGeometryNormalSphere.phiStart, + apiGeometryNormalSphere.phiLength, + apiGeometryNormalSphere.thetaStart, + apiGeometryNormalSphere.thetaLength + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalSphere + ); + +}; + +R3.D3.Geometry.Normal.Sphere.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Sphere.prototype.constructor = R3.D3.Geometry.Normal.Sphere; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Sphere.prototype.createInstance = function() { + + this.instance = new THREE.SphereGeometry( + this.radius, + this.widthSegments, + this.heightSegments, + this.phiStart, + this.phiLength, + this.thetaStart, + this.thetaLength + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Sphere.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'widthSegments' || + property === 'heightSegments' || + property === 'phiStart' || + property === 'phiLength' || + property === 'thetaStart' || + property === 'thetaLength' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Sphere to a R3.D3.API.Geometry.Normal.Sphere + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Sphere.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalSphere = new R3.D3.API.Geometry.Normal.Sphere( + apiNormalGeometry, + this.radius, + this.widthSegments, + this.heightSegments, + this.phiStart, + this.phiLength, + this.thetaStart, + this.thetaLength + ); + + return apiGeometryNormalSphere; +}; diff --git a/src/r3-d3-geometry-normal-tetrahedron.js b/src/r3-d3-geometry-normal-tetrahedron.js new file mode 100644 index 0000000..bbc2ca1 --- /dev/null +++ b/src/r3-d3-geometry-normal-tetrahedron.js @@ -0,0 +1,97 @@ +/** + * R3.D3.Geometry.Normal.Tetrahedron + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalTetrahedron + * @constructor + */ +R3.D3.Geometry.Normal.Tetrahedron = function( + graphics, + apiGeometryNormalTetrahedron +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalTetrahedron)) { + apiGeometryNormalTetrahedron = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_TETRAHEDRON + }; + } + + R3.D3.API.Geometry.Normal.Tetrahedron.call( + this, + apiGeometryNormalTetrahedron, + apiGeometryNormalTetrahedron.radius, + apiGeometryNormalTetrahedron.detail + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalTetrahedron + ); + +}; + +R3.D3.Geometry.Normal.Tetrahedron.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Tetrahedron.prototype.constructor = R3.D3.Geometry.Normal.Tetrahedron; + +/** + * Create Instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Tetrahedron.prototype.createInstance = function() { + + this.instance = new THREE.TetrahedronGeometry( + this.radius, + this.detail + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Tetrahedron.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'detail' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Tetrahedron to a R3.D3.API.Geometry.Normal.Tetrahedron + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Tetrahedron.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalTetrahedron = new R3.D3.API.Geometry.Normal.Tetrahedron( + apiNormalGeometry, + this.radius, + this.detail + ); + + return apiGeometryNormalTetrahedron; +}; diff --git a/src/r3-d3-geometry-normal-text.js b/src/r3-d3-geometry-normal-text.js new file mode 100644 index 0000000..a7cb5b3 --- /dev/null +++ b/src/r3-d3-geometry-normal-text.js @@ -0,0 +1,141 @@ +/** + * R3.D3.Geometry.Normal.Text + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalText + * @constructor + */ +R3.D3.Geometry.Normal.Text = function( + graphics, + apiGeometryNormalText +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalText)) { + apiGeometryNormalText = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_TEXT + }; + } + + R3.D3.API.Geometry.Normal.Text.call( + this, + apiGeometryNormalText, + apiGeometryNormalText.text, + apiGeometryNormalText.font, + apiGeometryNormalText.size, + apiGeometryNormalText.height, + apiGeometryNormalText.curveSegments, + apiGeometryNormalText.bevelEnabled, + apiGeometryNormalText.bevelThickness, + apiGeometryNormalText.bevelSize, + apiGeometryNormalText.bevelSegments + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalText + ); + +}; + +R3.D3.Geometry.Normal.Text.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Text.prototype.constructor = R3.D3.Geometry.Normal.Text; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Text.prototype.createInstance = function() { + + if (!this.font || !this.font.instance) { + console.warn('font not ready for this instance'); + return; + } + + this.instance = new THREE.TextGeometry( + this.text, + { + font : this.font.instance, + size : this.size, + curveSegments : this.curveSegments, + steps : this.steps, + amount : this.amount, + bevelEnabled : this.bevelEnabled, + bevelThickness : this.bevelThickness, + bevelSize : this.bevelSize, + bevelSegments : this.bevelSegments + } + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Text.prototype.updateInstance = function(property) { + + if ( + property === 'text' || + property === 'font' || + property === 'size' || + property === 'height' || + property === 'curveSegments' || + property === 'bevelEnabled' || + property === 'bevelThickness' || + property === 'bevelSize' || + property === 'bevelSegments' + ) { + /** + * Could be that the instance does not exist - because font was not ready + */ + if (this.instance) { + this.instance.dispose(); + } + + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + console.warn('do other properties here'); + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Text to a R3.D3.API.Geometry.Normal.Text + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Text.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalText = new R3.D3.API.Geometry.Normal.Text( + apiNormalGeometry, + this.text, + R3.Utils.IdOrNull(this.font), + this.size, + this.height, + this.curveSegments, + this.bevelEnabled, + this.bevelThickness, + this.bevelSize, + this.bevelSegments + ); + + return apiGeometryNormalText; +}; diff --git a/src/r3-d3-geometry-normal-torus.js b/src/r3-d3-geometry-normal-torus.js new file mode 100644 index 0000000..e968246 --- /dev/null +++ b/src/r3-d3-geometry-normal-torus.js @@ -0,0 +1,109 @@ +/** + * R3.D3.Geometry.Normal.Torus + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalTorus + * @constructor + */ +R3.D3.Geometry.Normal.Torus = function( + graphics, + apiGeometryNormalTorus +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalTorus)) { + apiGeometryNormalTorus = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_TORUS + }; + } + + R3.D3.API.Geometry.Normal.Torus.call( + this, + apiGeometryNormalTorus, + apiGeometryNormalTorus.radius, + apiGeometryNormalTorus.tube, + apiGeometryNormalTorus.radialSegments, + apiGeometryNormalTorus.tubularSegments, + apiGeometryNormalTorus.arc + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalTorus + ); + +}; + +R3.D3.Geometry.Normal.Torus.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Torus.prototype.constructor = R3.D3.Geometry.Normal.Torus; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Torus.prototype.createInstance = function() { + + this.instance = new THREE.TorusGeometry( + this.radius, + this.tube, + this.radialSegments, + this.tubularSegments, + this.arc + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Torus.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'tube' || + property === 'radialSegments' || + property === 'tubularSegments' || + property === 'arc' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Torus to a R3.D3.API.Geometry.Normal.Torus + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Torus.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalTorus = new R3.D3.API.Geometry.Normal.Torus( + apiNormalGeometry, + this.radius, + this.tube, + this.radialSegments, + this.tubularSegments, + this.arc + ); + + return apiGeometryNormalTorus; +}; diff --git a/src/r3-d3-geometry-normal-torusKnot.js b/src/r3-d3-geometry-normal-torusKnot.js new file mode 100644 index 0000000..2ec51b6 --- /dev/null +++ b/src/r3-d3-geometry-normal-torusKnot.js @@ -0,0 +1,113 @@ +/** + * R3.D3.Geometry.Normal.TorusKnot + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalTorusKnot + * @constructor + */ +R3.D3.Geometry.Normal.TorusKnot = function( + graphics, + apiGeometryNormalTorusKnot +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalTorusKnot)) { + apiGeometryNormalTorusKnot = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_TORUS_KNOT + }; + } + + R3.D3.API.Geometry.Normal.TorusKnot.call( + this, + apiGeometryNormalTorusKnot, + apiGeometryNormalTorusKnot.radius, + apiGeometryNormalTorusKnot.tube, + apiGeometryNormalTorusKnot.radialSegments, + apiGeometryNormalTorusKnot.tubularSegments, + apiGeometryNormalTorusKnot.p, + apiGeometryNormalTorusKnot.q + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalTorusKnot + ); + +}; + +R3.D3.Geometry.Normal.TorusKnot.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.TorusKnot.prototype.constructor = R3.D3.Geometry.Normal.TorusKnot; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.TorusKnot.prototype.createInstance = function() { + + this.instance = new THREE.TorusKnotGeometry( + this.radius, + this.tube, + this.radialSegments, + this.tubularSegments, + this.p, + this.q + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.TorusKnot.prototype.updateInstance = function(property) { + + if ( + property === 'radius' || + property === 'tube' || + property === 'radialSegments' || + property === 'tubularSegments' || + property === 'p' || + property === 'q' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.TorusKnot to a R3.D3.API.Geometry.Normal.TorusKnot + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.TorusKnot.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalTorusKnot = new R3.D3.API.Geometry.Normal.TorusKnot( + apiNormalGeometry, + this.radius, + this.tube, + this.radialSegments, + this.tubularSegments, + this.p, + this.q + ); + + return apiGeometryNormalTorusKnot; +}; diff --git a/src/r3-d3-geometry-normal-tube.js b/src/r3-d3-geometry-normal-tube.js new file mode 100644 index 0000000..bb430f2 --- /dev/null +++ b/src/r3-d3-geometry-normal-tube.js @@ -0,0 +1,109 @@ +/** + * R3.D3.Geometry.Normal.Tube + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalTube + * @constructor + */ +R3.D3.Geometry.Normal.Tube = function( + graphics, + apiGeometryNormalTube +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalTube)) { + apiGeometryNormalTube = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_TUBE + }; + } + + R3.D3.API.Geometry.Normal.Tube.call( + this, + apiGeometryNormalTube, + apiGeometryNormalTube.path, + apiGeometryNormalTube.tubularSegments, + apiGeometryNormalTube.radius, + apiGeometryNormalTube.radialSegments, + apiGeometryNormalTube.closed + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalTube + ); + +}; + +R3.D3.Geometry.Normal.Tube.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Tube.prototype.constructor = R3.D3.Geometry.Normal.Tube; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Tube.prototype.createInstance = function() { + + this.instance = new THREE.TubeGeometry( + this.path.instance, + this.tubularSegments, + this.radius, + this.radialSegments, + this.closed + ); + + this.computeVertexNormals(); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Tube.prototype.updateInstance = function(property) { + + if ( + property === 'path' || + property === 'tubularSegments' || + property === 'radius' || + property === 'radialSegments' || + property === 'closed' + ) { + this.instance.dispose(); + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Tube to a R3.D3.API.Geometry.Normal.Tube + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Tube.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalTube = new R3.D3.API.Geometry.Normal.Tube( + apiNormalGeometry, + R3.Utils.IdOrNull(this.path), + this.tubularSegments, + this.radius, + this.radialSegments, + this.closed + ); + + return apiGeometryNormalTube; +}; diff --git a/src/r3-d3-geometry-normal-wireframe.js b/src/r3-d3-geometry-normal-wireframe.js new file mode 100644 index 0000000..4a37360 --- /dev/null +++ b/src/r3-d3-geometry-normal-wireframe.js @@ -0,0 +1,104 @@ +/** + * R3.D3.Geometry.Normal.Wireframe + * @param graphics R3.Runtime.Graphics + * @param apiGeometryNormalWireframe + * @constructor + */ +R3.D3.Geometry.Normal.Wireframe = function( + graphics, + apiGeometryNormalWireframe +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiGeometryNormalWireframe)) { + apiGeometryNormalWireframe = { + geometryType : R3.D3.API.Geometry.GEOMETRY_TYPE_NORMAL_WIREFRAME + }; + } + + R3.D3.API.Geometry.Normal.Wireframe.call( + this, + apiGeometryNormalWireframe, + apiGeometryNormalWireframe.geometry + ); + + R3.D3.Geometry.Normal.call( + this, + this.graphics, + apiGeometryNormalWireframe + ); + +}; + +R3.D3.Geometry.Normal.Wireframe.prototype = Object.create(R3.D3.Geometry.Normal.prototype); +R3.D3.Geometry.Normal.Wireframe.prototype.constructor = R3.D3.Geometry.Normal.Wireframe; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Geometry.Normal.Wireframe.prototype.createInstance = function() { + + if (!this.geometry || !this.geometry.instance) { + console.warn('geometry not ready'); + return; + } + + this.instance = new THREE.WireframeGeometry( + this.geometry.instance + ); + + console.log('wireframe instance created'); + + R3.D3.Geometry.Normal.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Geometry.Normal.Wireframe.prototype.updateInstance = function(property) { + + if ( + property === 'geometry' + ) { + /** + * Could be that geometry was not ready + */ + if (this.instance) { + this.instance.dispose(); + } + + this.createInstance(); + + if (this.parentMesh && this.parentMesh.instance) { + this.parentMesh.instance.geometry = this.instance; + + if (this.parentMesh.helper) { + this.parentMesh.removeHelper(); + this.parentMesh.createHelper(); + } + } + + return; + } + + R3.D3.Geometry.Normal.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Geometry.Normal.Wireframe to a R3.D3.API.Geometry.Normal.Wireframe + * @returns {R3.D3.API.Geometry.Normal} + */ +R3.D3.Geometry.Normal.Wireframe.prototype.toApiObject = function() { + + var apiNormalGeometry = R3.D3.Geometry.Normal.prototype.toApiObject.call(this); + + var apiGeometryNormalWireframe = new R3.D3.API.Geometry.Normal.Wireframe( + apiNormalGeometry, + R3.Utils.IdOrNull(this.geometry) + ); + + return apiGeometryNormalWireframe; +}; diff --git a/src/r3-d3-helper.js b/src/r3-d3-helper.js new file mode 100644 index 0000000..5a25740 --- /dev/null +++ b/src/r3-d3-helper.js @@ -0,0 +1,41 @@ +/** + * R3.D3.Helper + * @param apiComponent + * @constructor + */ +R3.D3.Helper = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Helper.prototype = Object.create(R3.Component.prototype); +R3.D3.Helper.prototype.constructor = R3.D3.Helper; + +/** + * Creates a helper instance + */ +R3.D3.Helper.prototype.createInstance = function() { + + this.instance = this.graphics.Helper(this); + + if (R3.Utils.UndefinedOrNull(this.instance)) { + console.warn('No helper exists for ' + this.parent); + this.instance = true; + } + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Helper.prototype.updateInstance = function() { + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-d3-light-0.js b/src/r3-d3-light-0.js new file mode 100644 index 0000000..e9bcd52 --- /dev/null +++ b/src/r3-d3-light-0.js @@ -0,0 +1,36 @@ +/** + * R3.D3.Light + * @param inherited + * @constructor + */ +R3.D3.Light = function( + inherited +) { + + if (R3.Utils.UndefinedOrNull(inherited)) { + throw new Error('R3.D3.Light should not be instantiated directly'); + } + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Light.prototype = Object.create(R3.Component.prototype); +R3.D3.Light.prototype.constructor = R3.D3.Light; + +/** + * Updates the instance with the current state + */ +R3.D3.Light.prototype.updateInstance = function(property) { + + if (property === 'color') { + this.instance.color.set(this.color.toHex()); + } + + if (property === 'intensity') { + this.instance.intensity = this.intensity; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-d3-light-ambient.js b/src/r3-d3-light-ambient.js new file mode 100644 index 0000000..a984e07 --- /dev/null +++ b/src/r3-d3-light-ambient.js @@ -0,0 +1,39 @@ +/** + * R3.D3.Light.Ambient + * @param apiComponent + * @constructor + */ +R3.D3.Light.Ambient = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Light.call( + this, + true + ) + +}; + +R3.D3.Light.Ambient.prototype = Object.create(R3.D3.Light.prototype); +R3.D3.Light.Ambient.prototype.constructor = R3.D3.Light.Ambient; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Light.Ambient.prototype.createInstance = function() { + + this.instance = this.graphics.LightAmbient(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Light.Ambient.prototype.updateInstance = function(property) { + R3.D3.Light.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-light-directional.js b/src/r3-d3-light-directional.js new file mode 100644 index 0000000..8e61e95 --- /dev/null +++ b/src/r3-d3-light-directional.js @@ -0,0 +1,70 @@ +/** + * R3.D3.Light.Directional + * @param apiComponent + * @constructor + */ +R3.D3.Light.Directional = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Light.call( + this, + true + ); + +}; + +R3.D3.Light.Directional.prototype = Object.create(R3.D3.Light.prototype); +R3.D3.Light.Directional.prototype.constructor = R3.D3.Light.Directional; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Light.Directional.prototype.createInstance = function() { + + this.instance = this.graphics.LightDirectional(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Light.Directional.prototype.updateInstance = function(property) { + + if (property === 'castShadow') { + this.instance.castShadow = this.castShadow; + return; + } + + if (property === 'position') { + this.instance.position.x = this.position.x; + this.instance.position.y = this.position.y; + this.instance.position.z = this.position.z; + return; + } + + if (property === 'shadow') { + console.warn('R3.D3.Light.Directional.prototype.shadow is read-only'); + + if (R3.Utils.UndefinedOrNull(this.shadow)) { + console.warn('If you store this object now - the shadow component will be created new on next reload') + } + + return; + } + + if (property === 'target') { + /** + * todo : some target validation + */ + this.instance.target = this.target.instance; + return; + } + + R3.D3.Light.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-light-hemisphere.js b/src/r3-d3-light-hemisphere.js new file mode 100644 index 0000000..e5b2f46 --- /dev/null +++ b/src/r3-d3-light-hemisphere.js @@ -0,0 +1,52 @@ +/** + * R3.D3.Light.Directional + * @param apiComponent + * @constructor + */ +R3.D3.Light.Hemisphere = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Light.call( + this, + true + ); + +}; + +R3.D3.Light.Hemisphere.prototype = Object.create(R3.D3.Light.prototype); +R3.D3.Light.Hemisphere.prototype.constructor = R3.D3.Light.Hemisphere; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Light.Hemisphere.prototype.createInstance = function() { + + this.instance = this.graphics.LightHemisphere(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Light.Hemisphere.prototype.updateInstance = function(property) { + + if (property === 'position') { + this.instance.position.x = this.position.x; + this.instance.position.y = this.position.y; + this.instance.position.z = this.position.z; + return; + } + + if (property === 'groundColor') { + this.instance.groundColor.set(this.color.toHex()); + return; + } + + R3.D3.Light.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-light-point.js b/src/r3-d3-light-point.js new file mode 100644 index 0000000..4b5fa12 --- /dev/null +++ b/src/r3-d3-light-point.js @@ -0,0 +1,78 @@ +/** + * R3.D3.Light.Point + * @param apiComponent + * @constructor + */ +R3.D3.Light.Point = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Light.call( + this, + true + ); + +}; + +R3.D3.Light.Point.prototype = Object.create(R3.D3.Light.prototype); +R3.D3.Light.Point.prototype.constructor = R3.D3.Light.Point; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Light.Point.prototype.createInstance = function() { + + this.instance = this.graphics.LightPoint(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Light.Point.prototype.updateInstance = function(property) { + + if (property === 'position') { + this.instance.position.x = this.position.x; + this.instance.position.y = this.position.y; + this.instance.position.z = this.position.z; + return; + } + + if (property === 'decay') { + this.instance.decay = this.decay; + return; + } + + if (property === 'distance') { + this.instance.distance = this.distance; + return; + } + + if (property === 'power') { + this.instance.power = this.power; + return; + } + + if (property === 'castShadow') { + this.instance.castShadow = this.castShadow; + return; + } + + if (property === 'shadow') { + + console.warn('R3.D3.Light.Point.prototype.shadow is read-only'); + + if (R3.Utils.UndefinedOrNull(this.shadow)) { + console.warn('If you store this object now - the shadow component will be created new on next reload') + } + + return; + } + + R3.D3.Light.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-light-rectArea.js b/src/r3-d3-light-rectArea.js new file mode 100644 index 0000000..377b6cf --- /dev/null +++ b/src/r3-d3-light-rectArea.js @@ -0,0 +1,62 @@ +/** + * R3.D3.Light.RectArea + * @param apiComponent + * @constructor + */ +R3.D3.Light.RectArea = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Light.call( + this, + true + ); + +}; + +R3.D3.Light.RectArea.prototype = Object.create(R3.D3.Light.prototype); +R3.D3.Light.RectArea.prototype.constructor = R3.D3.Light.RectArea; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Light.RectArea.prototype.createInstance = function() { + + this.instance = this.graphics.LightRectArea(); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Light.RectArea.prototype.updateInstance = function(property) { + + if (property === 'position') { + this.instance.position.x = this.position.x; + this.instance.position.y = this.position.y; + this.instance.position.z = this.position.z; + return; + } + + if (property === 'width') { + this.instance.width = this.width; + return; + } + + if (property === 'height') { + this.instance.height = this.height; + return; + } + + if (property === 'lookAt') { + this.instance.lookAt(this.lookAt.instance); + return; + } + + R3.D3.Light.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-light-spot.js b/src/r3-d3-light-spot.js new file mode 100644 index 0000000..003cdf4 --- /dev/null +++ b/src/r3-d3-light-spot.js @@ -0,0 +1,100 @@ +/** + * R3.D3.Light.Spot + * @param apiComponent + * @constructor + */ +R3.D3.Light.Spot = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Light.call( + this, + true + ); + +}; + +R3.D3.Light.Spot.prototype = Object.create(R3.D3.Light.prototype); +R3.D3.Light.Spot.prototype.constructor = R3.D3.Light.Spot; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Light.Spot.prototype.createInstance = function() { + + this.instance = this.graphics.LightSpot(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Light.Spot.prototype.updateInstance = function(property, oldTarget) { + + if (property === 'position') { + this.instance.position.x = this.position.x; + this.instance.position.y = this.position.y; + this.instance.position.z = this.position.z; + return; + } + + if (property === 'angle') { + this.instance.angle = this.angle; + return; + } + + if (property === 'castShadow') { + this.instance.castShadow = this.castShadow; + return; + } + + if (property === 'decay') { + this.instance.decay = this.decay; + return; + } + + if (property === 'distance') { + this.instance.distance = this.distance; + return; + } + + if (property === 'penumbra') { + this.instance.penumbra = this.penumbra; + return; + } + + if (property === 'shadow') { + + console.warn('R3.D3.Light.Spot.prototype.shadow is read-only'); + + if (R3.Utils.UndefinedOrNull(this.shadow)) { + console.warn('If you store this object now - the shadow component will be created new on next reload') + } + + return; + } + + if (property === 'target') { + + if (R3.Utils.UndefinedOrNull(this.target)) { + console.warn('If you store this object now - the light will point to the origin on next load'); + return + } + + if (R3.Utils.Unloaded(this.target)) { + console.warn('The target selected is not valid or not loaded - if you save now the light will point to the origin on next load'); + this.target = null; + return; + } + + this.instance.target = this.target.instance; + return; + } + + R3.D3.Light.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-material-0.js b/src/r3-d3-material-0.js new file mode 100644 index 0000000..d40a4df --- /dev/null +++ b/src/r3-d3-material-0.js @@ -0,0 +1,946 @@ +/** + * Material Superset - The apiMaterial properties get moved into the Material object itself, and then the instance is + * created + * @param graphics R3.Runtime.Graphics + * @param apiMaterial R3.D3.API.Material + * @property materialType + * @constructor + * @returns {R3.D3.Material} + */ +/** + * R3.D3.Material + * @param inherited + * @constructor + */ +R3.D3.Material = function( + inherited +) { + + if (R3.Utils.UndefinedOrNull(inherited)) { + throw new Error('R3.D3.Material should not be instantiated directly'); + } + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Material.prototype = Object.create(R3.Component.prototype); +R3.D3.Material.prototype.constructor = R3.D3.Material; + + +R3.D3.Material.prototype.updateInstance = function(property) { + + if (R3.Utils.UndefinedOrNull(this.instance)) { + console.warn('no material instance'); + return; + } + + if (property === 'materialType') { + + var componentType = R3.D3.API.Material.GetComponentType(this.materialType); + + this.replace(componentType); + + return; + } + + if (property === 'alphaTest') { + this.instance.alphaTest = this.alphaTest; + this.instance.needsUpdate = true; + return; + } + + if (property === 'blendDst') { + this.instance.blendDst = this.blendDst; + return; + } + + if (property === 'blendDstAlpha') { + this.instance.blendDstAlpha = this.blendDstAlpha; + return; + } + + if (property === 'blendEquation') { + this.instance.blendEquation = this.blendEquation; + return; + } + + if (property === 'blendEquationAlpha') { + this.instance.blendEquationAlpha = this.blendEquationAlpha; + return; + } + + if (property === 'blending') { + this.instance.blending = this.blending; + return; + } + + if (property === 'blendSrc') { + this.instance.blendSrc = this.blendSrc; + return; + } + + if (property === 'blendSrcAlpha') { + this.instance.blendSrcAlpha = this.blendSrcAlpha; + return; + } + + if (property === 'clipIntersection') { + this.instance.clipIntersection = this.clipIntersection; + return; + } + + if (property === 'clippingPlanes') { + console.warn('todo: implement clipping planes update'); + return; + } + + if (property === 'clipShadows') { + this.instance.clipShadows = this.clipShadows; + return; + } + + if (property === 'colorWrite') { + this.instance.colorWrite = this.colorWrite; + return; + } + + if (property === 'defines') { + this.instance.defines = this.defines; + this.instance.needsUpdate = true; + return; + } + + if (property === 'depthFunc') { + this.instance.depthFunc = this.depthFunc; + return; + } + + if (property === 'depthTest') { + this.instance.depthTest = this.depthTest; + return; + } + + if (property === 'depthWrite') { + this.instance.depthWrite = this.depthWrite; + return; + } + + if (property === 'dithering') { + this.instance.dithering = this.dithering; + console.log('not sure about dithering needsupdate - cannot detect any changes until now'); + return; + } + + if (property === 'flatShading') { + this.instance.flatShading = this.flatShading; + retiurn; + } + + if (property === 'fog') { + this.instance.fog = this.fog; + return; + } + + if (property === 'lights') { + this.instance.lights = this.lights; + return; + } + + if (property === 'opacity') { + this.instance.opacity = this.opacity; + return; + } + + if (property === 'overdraw') { + this.instance.overdraw = this.overdraw; + return; + } + + if (property === 'polygonOffset') { + this.instance.polygonOffset = this.polygonOffset; + return; + } + + if (property === 'polygonOffsetFactor') { + this.instance.polygonOffsetFactor = this.polygonOffsetFactor; + return; + } + + if (property === 'polygonOffsetUnits') { + this.instance.polygonOffsetUnits = this.polygonOffsetUnits; + return; + } + + if (property === 'precision') { + this.instance.precision = this.precision; + return; + } + + if (property === 'premultipliedAlpha') { + this.instance.premultipliedAlpha = this.premultipliedAlpha; + return; + } + + if (property === 'side') { + this.instance.side = this.side; + return; + } + + if (property === 'stencilWrite') { + this.instance.stencilWrite = this.stencilWrite; + return; + } + + if (property === 'stencilFunc') { + this.instance.stencilFunc = this.stencilFunc; + return; + } + + if (property === 'stencilRef') { + this.instance.stencilRef = this.stencilRef; + return; + } + + if (property === 'stencilMask') { + this.instance.stencilMask = this.stencilMask; + return; + } + + if (property === 'stencilFail') { + this.instance.stencilFail = this.stencilFail; + return; + } + + if (property === 'stencilZFail') { + this.instance.stencilZFail = this.stencilZFail; + return; + } + + if (property === 'stencilZPass') { + this.instance.stencilZPass = this.stencilZPass; + return; + } + + if (property === 'transparent') { + this.instance.transparent = this.transparent; + return; + } + + if (property === 'vertexColors') { + this.instance.vertexColors = this.vertexColors; + return; + } + + if (property === 'visible') { + this.instance.visible = this.visible; + return; + } + + if (property === 'needsUpdate') { + /** + * update follows + */ + } + + this.instance.needsUpdate = true; + this.needsUpdate = false; + + __UPDATE_INSTANCE__; +}; + +R3.D3.Material.prototype.assignTexture = function(instanceProperty, property) { + if (this[property] && this[property].instance) { + this.instance[instanceProperty] = this[property].instance; + } else { + this.instance[instanceProperty] = null; + } + this.instance.needsUpdate = true; +}; + +R3.D3.Material.prototype.getTextures = function() { + + var textures = []; + + Object.keys(this.linkedComponents).map( + function(property) { + if (this[property] instanceof R3.D3.Texture) { + textures.push( + { + property: property, + texture: this[property] + } + ); + } + }.bind(this) + ); + + return textures; +}; + + +/* +switch (this.materialType) { + case R3.D3.API.Material.MATERIAL_TYPE_STANDARD : + linkedComponents.alphaMap = R3.D3.Texture; + linkedComponents.aoMap = R3.D3.Texture; + linkedComponents.bumpMap = R3.D3.Texture; + linkedComponents.diffuseMap = R3.D3.Texture; + linkedComponents.displacementMap = R3.D3.Texture; + linkedComponents.emissiveMap = R3.D3.Texture; + linkedComponents.envMap = R3.D3.Texture; + linkedComponents.lightMap = R3.D3.Texture; + linkedComponents.metalnessMap = R3.D3.Texture; + linkedComponents.normalMap = R3.D3.Texture; + linkedComponents.roughnessMap = R3.D3.Texture; + break; + case R3.D3.API.Material.MATERIAL_TYPE_BASIC : + linkedComponents.alphaMap = R3.D3.Texture; + linkedComponents.aoMap = R3.D3.Texture; + linkedComponents.diffuseMap = R3.D3.Texture; + linkedComponents.envMap = R3.D3.Texture; + linkedComponents.lightMap = R3.D3.Texture; + linkedComponents.specularMap = R3.D3.Texture; + break; + case R3.D3.API.Material.MATERIAL_TYPE_PHONG : + linkedComponents.alphaMap = R3.D3.Texture; + linkedComponents.aoMap = R3.D3.Texture; + linkedComponents.bumpMap = R3.D3.Texture; + linkedComponents.diffuseMap = R3.D3.Texture; + linkedComponents.displacementMap = R3.D3.Texture; + linkedComponents.emissiveMap = R3.D3.Texture; + linkedComponents.envMap = R3.D3.Texture; + linkedComponents.lightMap = R3.D3.Texture; + linkedComponents.normalMap = R3.D3.Texture; + linkedComponents.specularMap = R3.D3.Texture; + break; + case R3.D3.API.Material.MATERIAL_TYPE_SHADER : + case R3.D3.API.Material.MATERIAL_TYPE_SHADER_RAW : + linkedComponents.vertexShader = R3.D3.Shader.Vertex; + linkedComponents.fragmentShader = R3.D3.Shader.Fragment; + break; + case R3.D3.API.Material.MATERIAL_TYPE_POINTS : + linkedComponents.diffuseMap = R3.D3.Texture; + break; + default : + throw new Error('unhandled material type: ' + this.materialType); + +} +*/ +// +// +// +// R3.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: this.vertexColors, +// skinning: this.skinning, +// morphTargets: this.morphTargets, +// morphNormals: this.morphNormals +// }); +// }; + + +// R3.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: this.vertexColors, +// skinning: this.skinning, +// morphTargets: this.morphTargets, +// morphNormals: this.morphNormals +// }); +// }; + +// R3.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: R3.D3.API.Material.TYPE_VERTEX_COLORS, +// // fog: this.fog +// }); +// }; +// +// R3.D3.Material.prototype.createLineBasicMaterialInstance = function() { +// +// var linecap = 'round'; +// +// if (this.lineCap === R3.D3.API.Material.LINE_CAP_BUTT) { +// linecap = 'butt'; +// } +// +// if (this.lineCap === R3.D3.API.Material.LINE_CAP_SQUARE) { +// linecap = 'square'; +// } +// +// var linejoin = 'round'; +// +// if (this.lineJoin === R3.D3.API.Material.LINE_JOIN_BEVEL) { +// linejoin = 'bevel'; +// } +// +// if (this.lineJoin === R3.D3.API.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: R3.D3.API.Material.TYPE_VERTEX_COLORS, +// // fog: this.fog +// }); +// }; +// +// R3.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: this.vertexColors, +// skinning: this.skinning, +// morphTargets: this.morphTargets, +// morphNormals: this.morphNormals +// }); +// }; +// +// R3.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: this.vertexColors, +// fog: this.fog +// }); +// }; + +// R3.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 +// */ +// R3.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.emit( +// R3.Event.MATERIAL_TEXTURES_UPDATED, +// { +// material : this +// } +// ); +// } +// +// return textureChanged; +// }; +// +// +// R3.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 = this.vertexColors; +// this.instance.skinning = this.skinning; +// this.instance.morphTargets = this.morphTargets; +// this.instance.morphNormals = this.morphNormals; +// }; +// +// R3.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 = this.vertexColors; +// this.instance.skinning = this.skinning; +// this.instance.morphTargets = this.morphTargets; +// this.instance.morphNormals = this.morphNormals; +// }; +// +// R3.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 = this.vertexColors; +// //this.instance.fog = this.fog; +// }; +// +// R3.D3.Material.prototype.updateLineBasicMaterialInstance = function(property) { +// +// var linecap = 'round'; +// +// if (this.lineCap === R3.D3.API.Material.LINE_CAP_BUTT) { +// linecap = 'butt'; +// } +// +// if (this.lineCap === R3.D3.API.Material.LINE_CAP_SQUARE) { +// linecap = 'square'; +// } +// +// var linejoin = 'round'; +// +// if (this.lineJoin === R3.D3.API.Material.LINE_JOIN_BEVEL) { +// linejoin = 'bevel'; +// } +// +// if (this.lineJoin === R3.D3.API.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 = this.vertexColors; +// //this.instance.fog = this.fog; +// }; +// +// +// R3.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 = this.vertexColors; +// this.instance.skinning = this.skinning; +// this.instance.morphTargets = this.morphTargets; +// this.instance.morphNormals = this.morphNormals; +// }; +// +// R3.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 = this.vertexColors; +// this.instance.fog = this.fog; +// }; +// +// /** +// * Material instance +// * @returns {*} +// */ +// R3.D3.Material.prototype.createInstance = function() { +// +// if (this.materialType === R3.D3.API.Material.MATERIAL_TYPE_STANDARD) { +// +// this.instance = this.createStandardMaterialInstance(); +// +// } else if (this.materialType === R3.D3.API.Material.MATERIAL_TYPE_POINTS) { +// +// this.instance = this.createPointsMaterialInstance(); +// +// } else if (this.materialType === R3.D3.API.Material.MATERIAL_TYPE_PHONG) { +// +// this.instance = this.createPhongMaterialInstance(); +// +// } else if (this.materialType === R3.D3.API.Material.MATERIAL_TYPE_BASIC) { +// +// this.instance = this.createMeshBasicMaterialInstance(); +// +// } else if (this.materialType === R3.D3.API.Material.MATERIAL_TYPE_LINE_BASIC) { +// +// this.instance = this.createLineBasicMaterialInstance(); +// +// } else if (this.materialType === R3.D3.API.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(); +// +// __CREATE_INSTANCE__; +// }; + +/** + * Updates the instance with the current state + */ + + diff --git a/src/r3-d3-material-basic.js b/src/r3-d3-material-basic.js new file mode 100644 index 0000000..0488935 --- /dev/null +++ b/src/r3-d3-material-basic.js @@ -0,0 +1,131 @@ +/** + * R3.D3.Material.Basic + * @param apiComponent + * @constructor + */ +R3.D3.Material.Basic = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Material.call( + this, + true + ); + +}; + +R3.D3.Material.Basic.prototype = Object.create(R3.D3.Material.prototype); +R3.D3.Material.Basic.prototype.constructor = R3.D3.Material.Basic; + +/** + * Creates an instance of our texture object + * @returns {*} + */ +R3.D3.Material.Basic.prototype.createInstance = function() { + + this.instance = this.graphics.MaterialBasic(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Material.Basic.prototype.updateInstance = function(property) { + + if (property === 'alphaMap') { + this.assignTexture('alphaMap', property); + return; + } + + if (property === 'aoMap') { + this.assignTexture('aoMap', property); + return; + } + + if (property === 'aoMapIntensity') { + this.instance.aoMapIntensity = this.aoMapIntensity; + return; + } + + if (property === 'color') { + this.instance.color = this.color.instance; + return; + } + + if (property === 'combine') { + this.instance.combine = this.combine; + this.instance.needsUpdate = true; + return; + } + + if (property === 'envMap') { + this.assignTexture('envMap', property); + return; + } + + if (property === 'lightMap') { + this.assignTexture('lightMap', property); + return; + } + + if (property === 'lightMapIntensity') { + this.instance.lightMapIntensity = this.lightMapIntensity; + return; + } + + if (property === 'diffuseMap') { + this.assignTexture('map', property); + return; + } + + if (property === 'morphTargets') { + this.instance.morphTargets = this.morphTargets; + return; + } + + if (property === 'reflectivity') { + this.instance.reflectivity = this.reflectivity; + return; + } + + if (property === 'refractionRatio') { + this.instance.refractionRatio = this.refractionRatio; + return; + } + + if (property === 'skinning') { + this.instance.skinning = this.skinning; + return; + } + + if (property === 'specularMap') { + this.assignTexture('specularMap', property); + return; + } + + if (property === 'wireframe') { + this.instance.wireframe = this.wireframe; + return; + } + + if (property === 'wireframeLinecap') { + this.instance.wireframeLinecap = this.wireframeLinecap; + return; + } + + if (property === 'wireframeLinejoin') { + this.instance.wireframeLinejoin = this.wireframeLinejoin; + return; + } + + if (property === 'wireframeLinewidth') { + this.instance.wireframeLinewidth = this.wireframeLinewidth; + return; + } + + R3.D3.Material.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-material-phong.js b/src/r3-d3-material-phong.js new file mode 100644 index 0000000..7936c57 --- /dev/null +++ b/src/r3-d3-material-phong.js @@ -0,0 +1,194 @@ +/** + * R3.D3.Material.Phong + * @param apiComponent + * @constructor + */ +R3.D3.Material.Phong = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Material.call( + this, + true + ); + +}; + +R3.D3.Material.Phong.prototype = Object.create(R3.D3.Material.prototype); +R3.D3.Material.Phong.prototype.constructor = R3.D3.Material.Phong; + +/** + * Creates an instance of our texture object + * @returns {*} + */ +R3.D3.Material.Phong.prototype.createInstance = function() { + + this.instance = this.graphics.MaterialPhong(this); + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Material.Phong.prototype.updateInstance = function(property) { + + if (property === 'alphaMap') { + this.assignTexture('alphaMap', property); + return; + } + + if (property === 'aoMap') { + this.assignTexture('aoMap', property); + return; + } + + if (property === 'aoMapIntensity') { + this.instance.aoMapIntensity = this.aoMapIntensity; + return; + } + + if (property === 'bumpMap') { + this.assignTexture('bumpMap', property); + return; + } + + if (property === 'bumpScale') { + this.instance.bumpScale = this.bumpScale; + return; + } + + if (property === 'color') { + this.instance.color = this.color.instance; + return; + } + + if (property === 'combine') { + this.instance.combine = this.combine; + return; + } + + if (property === 'displacementMap') { + this.assignTexture('displacementMap', property); + return; + } + + if (property === 'displacementScale') { + this.instance.displacementScale = this.displacementScale; + return; + } + + if (property === 'displacementBias') { + this.instance.displacementBias = this.displacementBias; + return; + } + + if (property === 'emissive') { + this.instance.emissive = this.emissive.instance; + return; + } + + if (property === 'emissiveMap') { + this.assignTexture('emissiveMap', property); + return; + } + + if (property === 'emissiveIntensity') { + this.instance.emissiveIntensity = this.emissiveIntensity; + return; + } + + if (property === 'envMap') { + this.assignTexture('envMap', property); + return; + } + + if (property === 'lightMap') { + this.assignTexture('lightMap', property); + return; + } + + if (property === 'lightMapIntensity') { + this.instance.lightMapIntensity = this.lightMapIntensity; + return; + } + + if (property === 'diffuseMap') { + this.assignTexture('map', property); + return; + } + + if (property === 'morphNormals') { + this.instance.morphNormals = this.morphNormals; + return; + } + + if (property === 'morphTargets') { + this.instance.morphTargets = this.morphTargets; + return; + } + + if (property === 'normalMap') { + this.assignTexture('normalMap', property); + return; + } + + if (property === 'normalScale') { + this.instance.normalScale = this.normalScale; + return; + } + + if (property === 'reflectivity') { + this.instance.reflectivity = this.reflectivity; + return; + } + + if (property === 'refractionRatio') { + this.instance.refractionRatio = this.refractionRatio; + return; + } + + if (property === 'shininess') { + this.instance.shininess = this.shininess; + return; + } + + if (property === 'skinning') { + this.instance.skinning = this.skinning; + return; + } + + if (property === 'specular') { + this.instance.specular = this.specular.instance; + return; + } + + if (property === 'specularMap') { + this.assignTexture('specularMap', property); + return; + } + + if (property === 'wireframe') { + this.instance.wireframe = this.wireframe; + return; + } + + if (property === 'wireframeLinecap') { + this.instance.wireframeLinecap = this.wireframeLinecap; + return; + } + + if (property === 'wireframeLinejoin') { + this.instance.wireframeLinejoin = this.wireframeLinejoin; + return; + } + + if (property === 'wireframeLinewidth') { + this.instance.wireframeLinewidth = this.wireframeLinewidth; + return; + } + + R3.D3.Material.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-material-points.js b/src/r3-d3-material-points.js new file mode 100644 index 0000000..de80067 --- /dev/null +++ b/src/r3-d3-material-points.js @@ -0,0 +1,65 @@ +/** + * R3.D3.Material.Points + * @param apiComponent + * @constructor + */ +R3.D3.Material.Points = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Material.call( + this, + true + ); + +}; + +R3.D3.Material.Points.prototype = Object.create(R3.D3.Material.prototype); +R3.D3.Material.Points.prototype.constructor = R3.D3.Material.Points; + +/** + * Creates an instance of our texture object + * @returns {*} + */ +R3.D3.Material.Points.prototype.createInstance = function() { + + this.instance = this.graphics.MaterialPoints(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Material.Points.prototype.updateInstance = function(property) { + + if (property === 'color') { + this.instance.color = this.color.instance; + return; + } + + if (property === 'diffuseMap') { + this.assignTexture('map', property); + return; + } + + if (property === 'morphTargets') { + this.instance.morphTargets = this.morphTargets; + return; + } + + if (property === 'size') { + this.instance.size = this.size; + return; + } + + if (property === 'sizeAttenuation') { + this.instance.sizeAttenuation = this.sizeAttenuation; + return; + } + + R3.D3.Material.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-material-shader-0.js b/src/r3-d3-material-shader-0.js new file mode 100644 index 0000000..01711f3 --- /dev/null +++ b/src/r3-d3-material-shader-0.js @@ -0,0 +1,153 @@ +/** + * R3.D3.Material.Shader + * @param apiComponent + * @param inherited + * @constructor + */ +R3.D3.Material.Shader = function( + apiComponent, + inherited +) { + + if (R3.Utils.UndefinedOrNull(inherited)) { + + __RUNTIME_COMPONENT__; + + } + + R3.D3.Material.call( + this, + true + ); + +}; + +R3.D3.Material.Shader.prototype = Object.create(R3.D3.Material.prototype); +R3.D3.Material.Shader.prototype.constructor = R3.D3.Material.Shader; + +R3.D3.Material.Shader.prototype.commonInstance = function() { +}; + +/** + * Creates an instance of our texture object + * @returns {*} + */ +R3.D3.Material.Shader.prototype.createInstance = function() { + + this.instance = this.graphics.MaterialShader(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Material.Shader.prototype.updateInstance = function(property) { + + if (!this.instance) { + + if ( + property === 'vertexShader' || + property === 'fragmentShader' + ) { + this.createInstance(); + } + + /** + * If we don't return here - we risk storing this incomplete type with the entity.. + */ + + return; + } + + if (property === 'clipping') { + this.instance.clipping = this.clipping; + return; + } + + if (property === 'defaultAttributeValues') { + this.instance.defaultAttributeValues = this.defaultAttributeValues; + return; + } + + if (property === 'defines') { + this.instance.defines = this.defines; + return; + } + + if (property === 'extensions') { + this.instance.extensions = this.extensions; + return; + } + + if (property === 'fragmentShader') { + + if (this.fragmentShader && this.fragmentShader.instance) { + this.instance.fragmentShader = this.fragmentShader.instance; + this.instance.needsUpdate = true; + } else { + console.warn('fragment shader for material has been removed or not linked - using last valid fragment shader'); + } + return; + } + + if (property === 'index0AttributeName') { + this.instance.index0AttributeName = this.index0AttributeName; + return; + } + + if (property === 'linewidth') { + this.instance.linewidth = this.linewidth; + return; + } + + if (property === 'morphTargets') { + this.instance.morphTargets = this.morphTargets; + return; + } + + if (property === 'morphNormals') { + this.instance.morphNormals = this.morphNormals; + return; + } + + if (property === 'program') { + console.warn('program is read only'); + return; + } + + if (property === 'skinning') { + this.instance.skinning = this.skinning; + return; + } + + if (property === 'uniforms') { + this.instance.uniforms = this.uniforms; + return; + } + + if (property === 'vertexShader') { + + if (this.vertexShader && this.vertexShader.instance) { + this.instance.vertexShader = this.vertexShader.instance; + this.instance.needsUpdate = true; + } else { + console.warn('vertex shader for material has been removed or not linked - using last valid vertex shader'); + } + + return; + } + + if (property === 'wireframe') { + this.instance.wireframe = this.wireframe; + return; + } + + if (property === 'wireframeLinewidth') { + this.instance.wireframeLinewidth = this.wireframeLinewidth; + return; + } + + R3.D3.Material.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-material-shader-raw.js b/src/r3-d3-material-shader-raw.js new file mode 100644 index 0000000..66f2e36 --- /dev/null +++ b/src/r3-d3-material-shader-raw.js @@ -0,0 +1,42 @@ +/** + * R3.D3.Material.Shader.Raw + * @param apiComponent + * @constructor + */ +R3.D3.Material.Shader.Raw = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Material.Shader.call( + this, + apiComponent, + true + ); + +}; + +R3.D3.Material.Shader.Raw.prototype = Object.create(R3.D3.Material.Shader.prototype); +R3.D3.Material.Shader.Raw.prototype.constructor = R3.D3.Material.Shader.Raw; + +/** + * Creates an instance of our texture object + * @returns {*} + */ +R3.D3.Material.Shader.Raw.prototype.createInstance = function() { + + this.instance = this.graphics.MaterialShaderRaw(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Material.Shader.Raw.prototype.updateInstance = function(property) { + + R3.D3.Material.Shader.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-d3-material-standard.js b/src/r3-d3-material-standard.js new file mode 100644 index 0000000..3b8ffdf --- /dev/null +++ b/src/r3-d3-material-standard.js @@ -0,0 +1,197 @@ +/** + * R3.D3.Material.Standard + * @param apiComponent + * @constructor + */ +R3.D3.Material.Standard = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Material.Shader.call( + this, + apiComponent, + true + ); + + +}; + +R3.D3.Material.Standard.prototype = Object.create(R3.D3.Material.prototype); +R3.D3.Material.Standard.prototype.constructor = R3.D3.Material.Standard; + +/** + * Creates an instance of our texture object + * @returns {*} + */ +R3.D3.Material.Standard.prototype.createInstance = function() { + + this.instance = this.graphics.MaterialStandard(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Material.Standard.prototype.updateInstance = function(property) { + + if (property === 'alphaMap') { + this.assignTexture('alphaMap', property); + return; + } + + if (property === 'aoMap') { + this.assignTexture('aoMap', property); + return; + } + + if (property === 'aoMapIntensity') { + this.instance.aoMapIntensity = this.aoMapIntensity; + return; + } + + if (property === 'bumpMap') { + this.assignTexture('bumpMap', property); + return; + } + + if (property === 'bumpScale') { + this.instance.bumpScale = this.bumpScale; + return; + } + + if (property === 'color') { + this.instance.color = this.color.instance; + return; + } + + if (property === 'displacementMap') { + this.assignTexture('displacementMap', property); + return; + } + + if (property === 'displacementScale') { + this.instance.displacementScale = this.displacementScale; + return; + } + + if (property === 'displacementBias') { + this.instance.displacementBias = this.displacementBias; + return; + } + + if (property === 'emissive') { + this.instance.emissive = this.emissive.instance; + return; + } + + if (property === 'emissiveMap') { + this.assignTexture('emissiveMap', property); + return; + } + + if (property === 'emissiveIntensity') { + this.instance.emissiveIntensity = this.emissiveIntensity; + return; + } + + if (property === 'envMap') { + this.assignTexture('envMap', property); + return; + } + + if (property === 'envMapIntensity') { + this.instance.envMapIntensity = this.envMapIntensity; + return; + } + + if (property === 'lightMap') { + this.assignTexture('lightMap', property); + return; + } + + if (property === 'lightMapIntensity') { + this.instance.lightMapIntensity = this.lightMapIntensity; + return; + } + + if (property === 'diffuseMap') { + this.assignTexture('map', property); + return; + } + + if (property === 'metalness') { + this.instance.metalness = this.metalness; + return; + } + + if (property === 'metalnessMap') { + this.assignTexture('metalnessMap', property); + return; + } + + if (property === 'morphNormals') { + this.instance.morphNormals = this.morphNormals; + return; + } + + if (property === 'morphTargets') { + this.instance.morphTargets = this.morphTargets; + return; + } + + if (property === 'normalMap') { + this.assignTexture('normalMap', property); + return; + } + + if (property === 'normalScale') { + this.instance.normalScale = this.normalScale; + return; + } + + if (property === 'refractionRatio') { + this.instance.refractionRatio = this.refractionRatio; + return; + } + + if (property === 'roughness') { + this.instance.roughness = this.roughness; + return; + } + + if (property === 'roughnessMap') { + this.assignTexture('roughnessMap', property); + return; + } + + if (property === 'skinning') { + this.instance.skinning = this.skinning; + return; + } + + if (property === 'wireframe') { + this.instance.wireframe = this.wireframe; + return; + } + + if (property === 'wireframeLinecap') { + this.instance.wireframeLinecap = this.wireframeLinecap; + return; + } + + if (property === 'wireframeLinejoin') { + this.instance.wireframeLinejoin = this.wireframeLinejoin; + return; + } + + if (property === 'wireframeLinewidth') { + this.instance.wireframeLinewidth = this.wireframeLinewidth; + return; + } + + R3.D3.Material.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-mesh-0.js b/src/r3-d3-mesh-0.js new file mode 100644 index 0000000..78ca76d --- /dev/null +++ b/src/r3-d3-mesh-0.js @@ -0,0 +1,487 @@ +/** + * R3.D3.Mesh + * @param apiComponent + * @param inherited + * @constructor + */ +R3.D3.Mesh = function( + apiComponent, + inherited +) { + + if (R3.Utils.UndefinedOrNull(inherited)) { + __RUNTIME_COMPONENT__; + } + + R3.D3.Object.call( + this, + apiComponent, + true + ); + +}; + +R3.D3.Mesh.prototype = Object.create(R3.D3.Object.prototype); +R3.D3.Mesh.prototype.constructor = R3.D3.Mesh; + +/** + * Creates a mesh instance or updates it + */ +R3.D3.Mesh.prototype.createInstance = function() { + + this.instance = this.graphics.Mesh(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the mesh instance + */ +R3.D3.Mesh.prototype.updateInstance = function(property) { + + if (property === 'geometry') { + + if (R3.Utils.Defined(this.geometry)) { + + if (R3.Utils.UndefinedOrNull(this.geometry.instance)) { + console.warn('the geometry is not linked or constructed properly'); + return; + } + + this.geometry.parentMesh = this; + this.geometry.updateInstance('parentMesh'); + + if (R3.Utils.UndefinedOrNull(this.instance)) { + this.createInstance(); + } else { + this.instance.geometry = this.geometry.instance; + } + + } + + return; + } + + if (property === 'materials') { + + var materialInstances = R3.Utils.GetArrayInstances(this.materials); + + if (materialInstances) { + + if (R3.Utils.UndefinedOrNull(this.instance)) { + this.createInstance(); + } else { + this.instance.material = materialInstances; + } + + return; + + } else { + + console.warn('materials not ready for this mesh ' + this.name); + + if (R3.Utils.UndefinedOrNull(this.instance)) { + /** + * Do nothing + */ + } else { + + console.warn('warning - assigning no material to this mesh instance'); + /** + * Assign no material to this mesh - ok - I guess you know what you are doing. + * @type {null} + */ + this.instance.material = null; + } + + } + + return; + } + + if (property === 'name') { + this.instance.name = this.name; + return; + } + + if (property === 'excludeFromEnvironmentMapMap') { + R3.Event.Emit( + R3.Event.EXCLUDE_FROM_ENVIRONMENT, + { + component : this + } + ) + } + + if (property === 'parentScene') { + /** + * This is handled by LinkingSystem - probably will change soon + */ + } + + if (property === 'parentMesh') { + + /** + * Check if we already have a parent mesh + */ + if (R3.Utils.UndefinedOrNull(this.parentMesh)) { + + /** + * We are detaching this instance from the parent + */ + if (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 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.updateInstance('position'); + + /** + * 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.parentMesh.instance) { + + /** + * Add this as a child to the parent + */ + this.parentMesh.instance.add(this.instance); + } + } + + if (this.parentMesh && this.parentMesh.instance) { + if (this.instance.parent !== this.parentMesh.instance) { + this.instance.parent = this.parentMesh.instance; + } + } + + if (this.helper) { + this.removeHelper(); + this.createHelper(); + } + + return; + } + + if (property === 'renderOrder') { + this.instance.renderOrder = this.renderOrder; + return; + } + + if (property === 'visible') { + this.instance.visible = this.visible; + return; + } + + if (property === 'castShadow') { + this.instance.castShadow = this.castShadow; + return; + } + + if (property === 'receiveShadow') { + this.instance.receiveShadow = this.receiveShadow; + return; + } + + if (property === 'drawMode') { + this.instance.drawMode = this.drawMode; + return; + } + + R3.D3.Object.prototype.updateInstance.call(this, property); + + /** + * Update our helper (if any) + */ + if ( + property === 'useQuaternion' || + property === 'position' || + property === 'rotation' || + property === 'quaternion' || + property === 'scale' || + property === 'up' || + property === 'lookAt' + ) { + if (this.helper) { + this.removeHelper(); + this.createHelper(); + } + } +}; + +R3.D3.Mesh.prototype.clone = function() { + + var name = this.name + '(' + this.cloneNumber + ')'; + + if (this.cloneNumber > 0) { + name = this.name.replace('(' + this.cloneNumber + ')', '(' + (this.cloneNumber + 1) + ')'); + } + + this.cloneNumber += 1; + + var x = this.position.x; + var y = this.position.y; + var z = this.position.z; + + if (this.cloneDirection.x < 0) { + x += this.geometry.boundingBox.min.x * 2; + } + + if (this.cloneDirection.x > 0) { + x += this.geometry.boundingBox.max.x * 2; + } + + if (this.cloneDirection.y < 0) { + y += this.geometry.boundingBox.min.y * 2; + } + + if (this.cloneDirection.y > 0) { + y += this.geometry.boundingBox.max.y * 2; + } + + if (this.cloneDirection.z < 0) { + z += this.geometry.boundingBox.min.z * 2; + } + + if (this.cloneDirection.z > 0) { + z += this.geometry.boundingBox.max.z * 2; + } + + var mesh = new R3.D3.Mesh( + this.graphics, + { + name : name, + materials : this.materials, + geometry : this.geometry, + position: new R3.API.Vector3(x, y, z), + scale: this.scale.toApiObject(), + rotation: this.rotation.toApiObject(), + quaternion: this.quaternion.toApiObject(), + useQuaternion: this.useQuaternion, + castShadow : this.castShadow, + receiveShadow : this.receiveShadow, + visible : this.visible + } + ); + + this.parentScene.addClone(mesh); + + return mesh; +}; + +/** + * Centers the mesh around origin + */ +R3.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; +}; + +/** + * Applies position, rotation and scale to the object vertice data, resets scale, rotation and sets position to origin. + */ +R3.D3.Mesh.prototype.applyPositionRotationScale = function() { + + /** + * Ensure our instance matrix is up to date + */ + this.instance.updateMatrix(); + + /** + * Apply our instance matrix to the geometry + */ + this.instance.geometry.applyMatrix(this.instance.matrix); + + /** + * Update our geometry from the instance + */ + this.geometry.updateFromInstance(); + + /** + * Reset position + * @type {number} + */ + this.position.x = 0; + this.position.y = 0; + this.position.z = 0; + this.updateInstance('position'); + + /** + * Reset scale + * @type {number} + */ + this.scale.x = 1; + this.scale.y = 1; + this.scale.z = 1; + this.updateInstance('scale'); + + /** + * 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.updateInstance('rotation'); +}; + +/** + * Gets all children components of this Mesh (all linked objects only - no object references i.e. string ids) + * @returns {Array} + */ +// R3.D3.Mesh.prototype.getChildrenComponents = function() { +// +// var children = R3.Component.prototype.getChildrenComponents.call(this); +// +// /** +// * Push RigidBodies +// */ +// R3.EntityManager.Instance.queryComponents(R3.Component.RIGID_BODY).map( +// function(rigidBody) { +// +// if (rigidBody.parentMesh === this) { +// R3.Utils.PushUnique(children, rigidBody); +// } +// +// }.bind(this) +// ); +// +// /** +// * Push Shapes +// */ +// R3.EntityManager.Instance.queryComponents(R3.Component.SHAPE).map( +// function(shape) { +// +// if (shape.parentMesh === this) { +// R3.Utils.PushUnique(children, shape); +// } +// +// }.bind(this) +// ); +// +// return children; +// }; + +/** + * Convenience function for creating a helper for this Mesh - should be called from Systems only + */ +R3.D3.Mesh.prototype.createHelper = function() { + + if (R3.Utils.UndefinedOrNull(this.parentScene) || + R3.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 R3.D3.Helper( + this.graphics, + null, + this.name + ' Helper', + this, + R3.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); + +}; + +/** + * Convenience function for removing a helper for this Mesh - should be called from Systems only + */ +R3.D3.Mesh.prototype.removeHelper = function() { + + if (R3.Utils.UndefinedOrNull(this.parentScene) || + R3.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; +}; diff --git a/src/r3-d3-mesh-particle-0.js b/src/r3-d3-mesh-particle-0.js new file mode 100644 index 0000000..dbbe982 --- /dev/null +++ b/src/r3-d3-mesh-particle-0.js @@ -0,0 +1,253 @@ +/** + * R3.D3.Mesh.Particle + * @param apiComponent + * @param inherited + * @constructor + */ +R3.D3.Mesh.Particle = function( + apiComponent, + inherited +) { + + if (R3.Utils.UndefinedOrNull(inherited)) { + __RUNTIME_COMPONENT__; + } + + R3.D3.Mesh.call( + this, + apiComponent, + true + ); + +}; + +R3.D3.Mesh.Particle.prototype = Object.create(R3.D3.Mesh.prototype); +R3.D3.Mesh.Particle.prototype.constructor = R3.D3.Mesh.Particle; + +/** + * Mesh.Particle create instance + */ +R3.D3.Mesh.Particle.prototype.createInstance = function() { + + console.warn('todo : R3.D3.Mesh.Particle.prototype.createInstance'); + + // if (!this.mesh) { + // console.warn('no mesh to clone from - failed dependency check?'); + // return + // } + // + // this.instance = this.mesh.instance; + // + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Mesh.Particle.prototype.updateInstance = function(property) { + + if (!this.instance) { + this.createInstance(); + if (!this.instance) { + return; + } + } + + 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; + } + + if (property === 'mesh') { + if (this.mesh) { + this.createInstance(); + } + } + + __UPDATE_INSTANCE__; +}; + + +/** + * Clones a particle - this only clones 3rd party instances, so we have less overhead of creating these types of objects + */ +R3.D3.Mesh.Particle.prototype.cloneInstance = function() { + + this.updateInstance('positionOffset'); + this.updateInstance('direction'); + this.updateInstance('scale'); + this.updateInstance('rotation'); + + var clone = R3.Component.prototype.cloneInstance.call(this); + + clone.position = this.parentMesh.ParticleEngine.position.instance.clone(); + + clone.material = this.mesh.materials[0].instance.clone(); + + clone.visible = true; + + if (this.positionOffsetType === R3.D3.API.Mesh.Particle.POSITION_OFFSET_TYPE_CONSTANT) { + clone.position.add(this.positionOffset.instance); + } + + var addX = 1; + var addY = 1; + var addZ = 1; + + if (this.positionOffsetType === R3.D3.API.Mesh.Particle.POSITION_OFFSET_TYPE_RANDOM) { + + addX = R3.Utils.GetRandomIntInclusive(1,2); + addY = R3.Utils.GetRandomIntInclusive(1,2); + addZ = R3.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 === R3.D3.API.Mesh.Particle.DIRECTION_TYPE_CONSTANT) { + + /** + * Nothing to do + */ + + } else if ( + this.directionType === R3.D3.API.Mesh.Particle.DIRECTION_TYPE_RANDOM || + this.directionType === R3.D3.API.Mesh.Particle.DIRECTION_TYPE_RANDOM_NORMALIZED + ) { + + addX = R3.Utils.GetRandomIntInclusive(1,2); + addY = R3.Utils.GetRandomIntInclusive(1,2); + addZ = R3.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 === R3.D3.API.Mesh.Particle.DIRECTION_TYPE_RANDOM_NORMALIZED) { + clone.userData.direction.normalize(); + } + + } else { + throw new Error('not yet implemented') + } + + + if (this.scaleType === R3.D3.API.Mesh.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 === R3.D3.API.Mesh.Particle.SCALE_TYPE_RANDOM) { + + add = R3.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 === R3.D3.API.Mesh.Particle.SCALE_TYPE_RANDOM_X_EQUALS_Y) { + + add = R3.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; + } + } + + var fadeIn = true; + + if ( + this.opacityType === R3.D3.API.Mesh.Particle.OPACITY_TYPE_FADE_IN_LINEAR || + this.opacityType === R3.D3.API.Mesh.Particle.OPACITY_TYPE_FADE_IN_OUT_LINEAR + ) { + clone.material.opacity = 0; + fadeIn = true; + } + + if (this.opacityType === R3.D3.API.Mesh.Particle.OPACITY_TYPE_FADE_OUT_LINEAR) { + clone.material.opacity = 1; + fadeIn = false; + } + clone.userData.fadeIn = fadeIn; + 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; +}; diff --git a/src/r3-d3-mesh-particle-engine.js b/src/r3-d3-mesh-particle-engine.js new file mode 100644 index 0000000..16135aa --- /dev/null +++ b/src/r3-d3-mesh-particle-engine.js @@ -0,0 +1,192 @@ +/** + * Creates a Mesh.Particle.Engine object + * @param graphics R3.Runtime.Graphics + * @param apiMesh.Particle.Engine R3.D3.API.Mesh.Particle.Engine + * @constructor + */ +R3.D3.Mesh.Particle.Engine = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + +}; + +R3.D3.Mesh.Particle.Engine.prototype = Object.create(R3.D3.Mesh.Particle.prototype); +R3.D3.Mesh.Particle.Engine.prototype.constructor = R3.D3.Mesh.Particle.Engine; + +/** + * We don't use a 3rd party particle engine right now + * @returns true + */ +R3.D3.Mesh.Particle.Engine.prototype.createInstance = function() { + + this.instance = true; + + // if (this.templateMesh.Particle) { + // + // this.templateMesh.Particle.mesh.position.x = this.position.x; + // this.templateMesh.Particle.mesh.position.y = this.position.y; + // this.templateMesh.Particle.mesh.position.z = this.position.z; + // + // this.templateMesh.Particle.direction.x = this.direction.x; + // this.templateMesh.Particle.direction.y = this.direction.y; + // this.templateMesh.Particle.direction.z = this.direction.z; + // + // this.templateMesh.Particle.scale.x = this.scale.x; + // this.templateMesh.Particle.scale.y = this.scale.y; + // this.templateMesh.Particle.scale.z = this.scale.z; + // } + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Mesh.Particle.Engine.prototype.updateInstance = function(property) { + + // if (property === 'particlesPerSecond') { + // this.frequency = Number(1 / this.particlesPerSecond); + // } + // + // if (property === 'frequency') { + // this.particlesPerSecond = Math.round(1 / this.frequency); + // } + // + // if (property === 'position') { + // this.position.instance.x = this.position.x; + // this.position.instance.y = this.position.y; + // this.position.instance.z = this.position.z; + // this.templateMeshParticle.mesh.position = this.position.clone(); + // this.templateMeshParticle.mesh.updateInstance('position', true); + // } + // + // if (property === 'direction') { + // this.direction.instance.x = this.direction.x; + // this.direction.instance.y = this.direction.y; + // this.direction.instance.z = this.direction.z; + // this.templateMeshParticle.direction = this.direction.clone(); + // this.templateMeshParticle.direction.updateInstance('direction', true); + // } + + __UPDATE_INSTANCE__; +}; + +R3.D3.Mesh.Particle.Engine.prototype.remove = function() { + + // if (this.removeSubscription) { + // console.log('already another remove subscription for ' + this.name); + // return; + // } + // + // this.removeSubscription = R3.Event.Subscribe( + // R3.Event.REMOVE_PARTICLE_ENGINE, + // function(data){ + // if (data.component === this) { + // + // if (this.isClone) { + // /** + // * We only remove the things we cloned, the mesh, particle, and this + // */ + // R3.Event.Emit( + // R3.Event.REMOVE_COMPONENT, + // { + // component: this.templateMeshParticle.mesh + // } + // ); + // + // R3.Event.Emit( + // R3.Event.REMOVE_COMPONENT, + // { + // component: this.templateMeshParticle + // } + // ); + // + // R3.Event.Emit( + // R3.Event.REMOVE_COMPONENT, + // { + // component: this + // } + // ) + // } else { + // R3.Component.prototype.remove.call(this); + // } + // + // this.removeSubscription.remove(); + // + // this.removeSubscription = null; + // } + // }.bind(this) + // ); + + /** + * Below signals the particle system to continue processing the particles, but don't create more, and + * we wait for the system to signal REMOVE_PARTICLE_ENGINE so we can destroy ourselves + * @type {boolean} + */ + this.disabledForRemoval = true; +}; + +// R3.D3.Mesh.Particle.Engine.prototype.getChildrenComponents = function() { +// +// var components = []; +// +// if (this.templateMesh.Particle) { +// components.push(this.templateMesh.Particle); +// +// if (this.templateMesh.Particle.mesh) { +// components.push(this.templateMesh.Particle.mesh); +// +// if (this.templateMesh.Particle.mesh.materials && this.templateMesh.Particle.mesh.materials[0]) { +// +// components.push(this.templateMesh.Particle.mesh.materials[0]); +// +// if (this.templateMesh.Particle.mesh.materials[0].diffuseMap) { +// components.push(this.templateMesh.Particle.mesh.materials[0].diffuseMap); +// } +// } +// } +// } +// +// return components; +// }; + +R3.D3.Mesh.Particle.Engine.prototype.clone = function() { + // var mesh = this.templateMesh.Particle.mesh.clone(); + // var templateMesh.Particle = this.templateMesh.Particle.clone(); + // templateMesh.Particle.mesh = mesh; + // templateMesh.Particle.instance = mesh.instance; + // var engine = R3.Component.prototype.clone.call(this); + // engine.templateMesh.Particle = templateMesh.Particle; + // return engine; +}; + +R3.D3.Mesh.Particle.Engine.prototype.processMeshParticles = function(delta) { + // this.particles = this.particles.reduce( + // function(result, particle){ + // + // particle.position.x += particle.userData.direction.x * delta; + // particle.position.y += particle.userData.direction.y * delta; + // particle.position.z += particle.userData.direction.z * delta; + // + // particle.userData.elapsed += delta; + // if (particle.userData.elapsed > particle.userData.lifeTime) { + // particle.parent.remove(particle); + // } else { + // result.push(particle); + // } + // + // return result; + // }, + // [] + // ); +}; + +R3.D3.Mesh.Particle.Engine.prototype.createNewMeshParticle = function(camera) { + // + // var particle = this.templateMesh.Particle.clone(camera); + // + // this.particles.push(particle); + +}; diff --git a/src/r3-d3-mesh-skeleton.js b/src/r3-d3-mesh-skeleton.js new file mode 100644 index 0000000..61b1882 --- /dev/null +++ b/src/r3-d3-mesh-skeleton.js @@ -0,0 +1,52 @@ +/** + * R3.D3.Mesh + * @param apiComponent + * @constructor + */ +R3.D3.Mesh.Skeleton = function( + apiComponent +) { + + + __RUNTIME_COMPONENT__; + + R3.D3.Mesh.call( + this, + apiComponent, + true + ); + +}; + +R3.D3.Mesh.Skeleton.prototype = Object.create(R3.D3.Mesh.prototype); +R3.D3.Mesh.Skeleton.prototype.constructor = R3.D3.Mesh.Skeleton; + +/** + * Creates a mesh instance or updates it + */ +R3.D3.Mesh.Skeleton.prototype.createInstance = function() { + + this.instance = this.graphics.MeshSkeleton(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the mesh instance + */ +R3.D3.Mesh.Skeleton.prototype.updateInstance = function(property) { + + if (property === 'skeleton') { + throw new Error('todo: skeleton update'); + } + + R3.D3.Mesh.prototype.updateInstance.call(this, property); + +}; + +R3.D3.Mesh.Skeleton.prototype.clone = function() { + + throw new Error('todo: R3.D3.Mesh.Skeleton.prototype.clone()'); + +}; \ No newline at end of file diff --git a/src/r3-d3-pass-0.js b/src/r3-d3-pass-0.js new file mode 100644 index 0000000..4b95cf5 --- /dev/null +++ b/src/r3-d3-pass-0.js @@ -0,0 +1,64 @@ +/** + * R3.D3.Pass + * @param inherited + * @constructor + */ +R3.D3.Pass = function( + inherited +) { + + __INHERIT_ONLY__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Pass.prototype = Object.create(R3.Component.prototype); +R3.D3.Pass.prototype.constructor = R3.D3.Pass; + +/** + * This class has no instance but shares functionality will all passes + * @returns {*} + */ +R3.D3.Pass.prototype.createInstance = function() { + + if (R3.Utils.UndefinedOrNull(this.instance)) { + throw new Error('No R3.D3.Pass.prototype.instance - call the child createInstance() first'); + } + + this.instance.enabled = this.enabled; + this.instance.needsSwap = this.needsSwap; + this.instance.clear = this.clear; + this.instance.renderToScreen = this.renderToScreen; + + __CREATE_INSTANCE__; + +}; + +/** + * Update Pass instance + */ +R3.D3.Pass.prototype.updateInstance = function(property) { + + if (property === 'enabled') { + this.instance.enabled = this.enabled; + return; + } + + if (property === 'needsSwap') { + this.instance.needsSwap = this.needsSwap; + return; + } + + if (property === 'clear') { + this.instance.clear = this.clear; + return; + } + + if (property === 'renderToScreen') { + this.instance.renderToScreen = this.renderToScreen; + return; + } + + __UPDATE_INSTANCE__; +}; diff --git a/src/r3-d3-pass-bloom.js b/src/r3-d3-pass-bloom.js new file mode 100644 index 0000000..2668be9 --- /dev/null +++ b/src/r3-d3-pass-bloom.js @@ -0,0 +1,108 @@ +/** + * R3.D3.Pass.Bloom + * @param apiComponent + * @constructor + */ +R3.D3.Pass.Bloom = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.linkedComponents.renderer = R3.Renderer.D3; + + R3.D3.Pass.call(this, true); +}; + +R3.D3.Pass.Bloom.prototype = Object.create(R3.D3.Pass.prototype); +R3.D3.Pass.Bloom.prototype.constructor = R3.D3.Pass.Bloom; + +/** + * Create Pass.Bloom instance + * @returns {*} + */ +R3.D3.Pass.Bloom.prototype.createInstance = function() { + + this.instance = new this.graphics.PassBloom(this); + + R3.D3.Pass.prototype.createInstance.call(this); + +}; + +/** + * Update Pass.Bloom instance + */ +R3.D3.Pass.Bloom.prototype.updateInstance = function(property) { + // + // if ( + // property === 'autoUpdateSize' || + // property === 'renderer' || + // property === 'viewport' + // + // ) { + // + // if (this.autoUpdateSize) { + // + // this.setSize(); + // + // this.graphics.updateInstance(this, 'size'); + // + // return; + // + // } + // + // return; + // + // } + + if (property === 'size') { + + // if (this.autoUpdateSize) { + // console.warn('Modifying the width and height while R3.D3.Pass.Bloom.prototype.autoUpdateSize is set has no effect'); + // return; + // } + + //this.graphics.updateInstance(this, 'size'); + + this.instance.setSize( + this.size.x, + this.size.y + ); + + return; + } + + if ( + property === 'strength' || + property === 'radius' || + property === 'threshold' + ) { + this.graphics.updateInstance(this, property); + return; + } + + R3.D3.Pass.prototype.updateInstance.call(this, property); + +}; + +/** + * Convenience function to set size + */ +// R3.D3.Pass.Bloom.prototype.setSize = function() { +// +// if (R3.Utils.Unloaded(this.renderer)) { +// console.warn('R3.D3.Pass.Render.Bloom.prototype.renderer unloaded'); +// return; +// } +// +// if (R3.Utils.Unloaded(this.viewport)) { +// console.warn('R3.D3.Pass.Render.Bloom.prototype.viewport unloaded'); +// return; +// } +// +// var size = this.renderer.getSize(this.viewport); +// +// this.size.x = size.width; +// this.size.y = size.height; +// +// }; diff --git a/src/r3-d3-pass-copy.js b/src/r3-d3-pass-copy.js new file mode 100644 index 0000000..788b0fd --- /dev/null +++ b/src/r3-d3-pass-copy.js @@ -0,0 +1,38 @@ +/** + * R3.D3.Pass.Copy + * @param apiComponent + * @constructor + */ +R3.D3.Pass.Copy = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Pass.call(this, true); + +}; + +R3.D3.Pass.Copy.prototype = Object.create(R3.D3.Pass.prototype); +R3.D3.Pass.Copy.prototype.constructor = R3.D3.Pass.Copy; + +/** + * Create Pass.Copy instance + * @returns {*} + */ +R3.D3.Pass.Copy.prototype.createInstance = function() { + + this.instance = this.graphics.PassCopy(); + + R3.D3.Pass.prototype.createInstance.call(this); + +}; + +/** + * Update Pass.Copy instance + */ +R3.D3.Pass.Copy.prototype.updateInstance = function(property) { + + R3.D3.Pass.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-d3-pass-fxaa.js b/src/r3-d3-pass-fxaa.js new file mode 100644 index 0000000..48f5dac --- /dev/null +++ b/src/r3-d3-pass-fxaa.js @@ -0,0 +1,111 @@ +/** + * R3.D3.Pass.FXAA + * @param apiComponent + * @constructor + */ +R3.D3.Pass.FXAA = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.linkedComponents.renderer = R3.Renderer.D3; + + R3.D3.Pass.call(this, true); + +}; + +R3.D3.Pass.FXAA.prototype = Object.create(R3.D3.Pass.prototype); +R3.D3.Pass.FXAA.prototype.constructor = R3.D3.Pass.FXAA; + +/** + * Create Pass.FXAA instance + * @returns {*} + */ +R3.D3.Pass.FXAA.prototype.createInstance = function() { + + // if (this.autoUpdateSize) { + // + // this.setSize(); + // + // } + + this.instance = this.graphics.PassFXAA(this); + + R3.D3.Pass.prototype.createInstance.call(this); + +}; + +/** + * Update Pass.FXAA instance + */ +R3.D3.Pass.FXAA.prototype.updateInstance = function(property) { + + // if ( + // property === 'autoUpdateSize' || + // property === 'renderer' || + // property === 'viewport' + // + // ) { + // + // if (this.autoUpdateSize) { + // + // this.setSize(); + // + // this.graphics.updateInstance(this, 'size'); + // + // return; + // + // } + // + // return; + // + // } + + if ( + property === 'width' || + property === 'height' || + property === 'size' + ) { + + // if (this.autoUpdateSize) { + // console.warn('Modifying the width and height while R3.D3.Pass.FXAA.prototype.autoUpdateSize is set has no effect'); + // return; + // } + + this.instance.uniforms['resolution'].value.set( + 1 / this.width, + 1 / this.height + ); + + //this.graphics.updateInstance(this, 'size'); + + return; + } + + R3.D3.Pass.prototype.updateInstance.call(this, property); + +}; + +/** + * Convenience function to set size + */ +// R3.D3.Pass.FXAA.prototype.setSize = function() { +// +// // if (R3.Utils.Unloaded(this.renderer)) { +// // console.warn('R3.D3.Pass.Render.FXAA.prototype.renderer unloaded'); +// // return; +// // } +// // +// // if (R3.Utils.Unloaded(this.viewport)) { +// // console.warn('R3.D3.Pass.Render.FXAA.prototype.viewport unloaded'); +// // return; +// // } +// // +// // var size = this.renderer.getSize(this.viewport); +// +// this.width = size.width; +// this.height = size.height; +// +// }; +// diff --git a/src/r3-d3-pass-render-0.js b/src/r3-d3-pass-render-0.js new file mode 100644 index 0000000..91d4b32 --- /dev/null +++ b/src/r3-d3-pass-render-0.js @@ -0,0 +1,75 @@ +/** + * R3.D3.Pass.Render + * @param apiComponent + * @param inherited + * @constructor + */ +R3.D3.Pass.Render = function( + apiComponent, + inherited +) { + + __INHERIT_AND_INSTANTIATE__; + + this.linkedComponents.scene = R3.D3.Scene; + this.linkedComponents.camera = R3.D3.Camera; + + R3.D3.Pass.call( + this, + true + ); + +}; + +R3.D3.Pass.Render.prototype = Object.create(R3.D3.Pass.prototype); +R3.D3.Pass.Render.prototype.constructor = R3.D3.Pass.Render; + +/** + * Create Pass.Render instance + * @returns {*} + */ +R3.D3.Pass.Render.prototype.createInstance = function() { + + if (R3.Utils.Unloaded(this.scene)) { + throw new Error('R3.D3.Pass.Render.prototype.scene not ready - loading or linking error'); + } + + if (R3.Utils.Unloaded(this.camera)) { + throw new Error('R3.D3.Pass.Render.prototype.camera not ready - loading or linking error'); + } + + this.instance = this.graphics.PassRender(this); + + R3.D3.Pass.prototype.createInstance.call(this); +}; + +/** + * Update Pass.Render instance + */ +R3.D3.Pass.Render.prototype.updateInstance = function(property) { + + if (property === 'scene') { + + if (R3.Utils.Unloaded(this.scene)) { + throw new Error('R3.D3.Pass.Render.prototype.scene cannot be undefined'); + } + + this.instance.scene = this.scene.instance; + + return; + } + + if (property === 'camera') { + + if (R3.Utils.Unloaded(this.camera)) { + throw new Error('R3.D3.Pass.Render.prototype.camera cannot be undefined'); + } + + this.instance.camera = this.camera.instance; + + return; + } + + R3.D3.Pass.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-d3-pass-render-ssao.js b/src/r3-d3-pass-render-ssao.js new file mode 100644 index 0000000..8de3740 --- /dev/null +++ b/src/r3-d3-pass-render-ssao.js @@ -0,0 +1,135 @@ +/** + * R3.D3.Pass.Render.SSAO + * @param apiComponent + * @constructor + */ +R3.D3.Pass.Render.SSAO = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Pass.Render.call( + this, + apiComponent, + true + ); + +}; + +R3.D3.Pass.Render.SSAO.prototype = Object.create(R3.D3.Pass.Render.prototype); +R3.D3.Pass.Render.SSAO.prototype.constructor = R3.D3.Pass.Render.SSAO; + +/** + * Create Pass.SSAO instance + * @returns {*} + */ +R3.D3.Pass.Render.SSAO.prototype.createInstance = function() { + + if (R3.Utils.Unloaded(this.scene)) { + throw new Error('R3.D3.Pass.Render.SSAO.prototype.scene not ready - loading or linking error'); + } + + if (R3.Utils.Unloaded(this.camera)) { + throw new Error('R3.D3.Pass.Render.SSAO.prototype.camera not ready - loading or linking error'); + } + + if (this.autoUpdateSize) { + + this.setSize(); + + } + + this.instance = this.graphics.PassSSAO( + this.scene, + this.camera, + this.size, + this.radius, + this.onlyAO, + this.aoClamp, + this.lumInfluence + ); + + R3.D3.Pass.prototype.createInstance.call(this); +}; + +/** + * Update Pass.SSAO instance + */ +R3.D3.Pass.Render.SSAO.prototype.updateInstance = function(property) { + + if ( + property === 'scene' || + property === 'camera' + + ) { + R3.D3.Pass.Render.prototype.updateInstance.call(this, property); + return; + } + + if ( + property === 'radius' || + property === 'onlyAO' || + property === 'radius' || + property === 'lumInfluence' + ) { + this.graphics.updateInstance(this, property); + } + + if ( + property === 'autoUpdateSize' || + property === 'renderer' || + property === 'viewport' + + ) { + + if (this.autoUpdateSize) { + + this.setSize(); + + this.graphics.updateInstance(this, 'size'); + + return; + + } + + return; + + } + + if (property === 'size') { + + if (this.autoUpdateSize) { + console.warn('Modifying the width and height while R3.D3.Pass.Render.SSAO.prototype.autoUpdateSize is set has no effect'); + return; + } + + this.graphics.updateInstance(this, 'size'); + + return; + } + + R3.D3.Pass.prototype.updateInstance.call(this, property); +}; + +/** + * Convenience function to set size + */ +R3.D3.Pass.Render.SSAO.prototype.setSize = function() { + + if (R3.Utils.Unloaded(this.renderer)) { + console.warn('R3.D3.Pass.Render.SSAO.prototype.renderer unloaded'); + return; + } + + if (R3.Utils.Unloaded(this.viewport)) { + console.warn('R3.D3.Pass.Render.SSAO.prototype.viewport unloaded'); + return; + } + + var size = this.renderer.getSize(this.viewport); + + this.size.x = size.width; + this.size.y = size.height; + +}; \ No newline at end of file diff --git a/src/r3-d3-physicsWorld.js b/src/r3-d3-physicsWorld.js new file mode 100644 index 0000000..a8581fe --- /dev/null +++ b/src/r3-d3-physicsWorld.js @@ -0,0 +1,1044 @@ +/** + * World SuperSet - contains the custom world instance + * @constructor + * @param physics + * @param apiWorld + */ +R3.D3.PhysicsWorld = function( + physics, + apiWorld +) { + + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (R3.Utils.UndefinedOrNull(apiWorld)) { + apiWorld = {}; + } + + R3.D3.API.PhysicsWorld.call( + this, + apiWorld.id, + apiWorld.name, + apiWorld.gravity, + apiWorld.broadphase, + apiWorld.solver, + apiWorld.rigidBodies, + apiWorld.contactMaterials, + apiWorld.allowSleep, + apiWorld.defaultContactMaterial, + apiWorld.parent + ); + + if (this.gravity instanceof R3.API.Vector3) { + this.gravity = new R3.Vector3( + this.physics, + this.gravity, + this + ); + } + + if (this.broadphase instanceof R3.D3.API.Broadphase) { + this.broadphase = new R3.D3.Broadphase( + this.physics, + this.broadphase + ); + } + + if (this.solver instanceof R3.D3.API.Solver) { + this.solver = new R3.D3.Solver( + this.physics, + this.solver + ); + } + + this.rigidBodies = this.rigidBodies.map( + function(rigidBody) { + if (rigidBody instanceof R3.D3.API.RigidBody) { + return new R3.D3.RigidBody( + this.physics, + rigidBody + ); + } + return rigidBody; + }.bind(this) + ); + + this.contactMaterials = this.contactMaterials.map( + function(contactMaterial) { + if (contactMaterial instanceof R3.D3.API.FrictionContactMaterial) { + return new R3.D3.FrictionContactMaterial( + this.physics, + contactMaterial + ); + } + return contactMaterial; + }.bind(this) + ); + + if (this.defaultContactMaterial instanceof R3.D3.API.FrictionContactMaterial) { + this.defaultContactMaterial = new R3.D3.FrictionContactMaterial( + this.physics, + this.defaultContactMaterial + ) + } + + R3.Component.call( + this, + { + 'broadphase' : R3.D3.Broadphase, + 'solver' : R3.D3.Solver, + 'rigidBodies' : [R3.D3.RigidBody], + 'contactMaterials' : [R3.D3.FrictionContactMaterial], + 'defaultContactMaterial' : R3.D3.FrictionContactMaterial + } + ); +}; + +R3.D3.PhysicsWorld.prototype = Object.create(R3.Component.prototype); +R3.D3.PhysicsWorld.prototype.constructor = R3.D3.PhysicsWorld; + +/** + * private + * @returns {R3.D3.PhysicsWorld|R3.Runtime.Physics.World|*} + */ +R3.D3.PhysicsWorld.prototype.createInstance = function() { + + if (R3.Utils.UndefinedOrNull(this.broadphase)) { + throw new Error('no broadphase'); + } + + if (R3.Utils.UndefinedOrNull(this.broadphase.instance)) { + throw new Error('no broadphase instance'); + } + + if (R3.Utils.UndefinedOrNull(this.solver)) { + throw new Error('no solver'); + } + + if (R3.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 (R3.Utils.UndefinedOrNull(contactMaterial)) { + throw new Error('no contact material'); + } + + if (R3.Utils.UndefinedOrNull(contactMaterial.instance)) { + throw new Error('no contact material instance'); + } + + this.instance.addContactMaterial(contactMaterial.instance); + + }.bind(this) + ); + + this.rigidBodies.map( + function(rigidBody) { + + if (R3.Utils.UndefinedOrNull(rigidBody)) { + throw new Error('no rigidbody'); + } + + if (R3.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; + + __CREATE_INSTANCE__; +}; + +R3.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 {R3.D3.PhysicsWorld} + */ + rigidBody.parentPhysicsWorld = this; + + /** + * Ensure this rigidBody is in our rigidBodies array, just not too many times.. + */ + R3.Utils.PushUnique(this.rigidBodies, rigidBody); + + } else { + console.warn('Attempt to add rigidBody ' + rigidBody.name + ' without an instance'); + } +}; + +/** + * + * @param rigidBody + */ +R3.D3.PhysicsWorld.prototype.removeRigidBody = function(rigidBody) { + + if (!rigidBody instanceof R3.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 {R3.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'); + } + +}; + + +/** + * + */ +R3.D3.PhysicsWorld.prototype.updateInstance = function(property) { + + 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; + + __UPDATE_INSTANCE__; +}; + +/** + * R3.D3.PhysicsWorld to R3.D3.API.PhysicsWorld + * @returns {R3.D3.API.PhysicsWorld} + */ +R3.D3.PhysicsWorld.prototype.toApiObject = function() { + + var apiWorld = new R3.D3.API.PhysicsWorld( + this.id, + this.name, + this.gravity.toApiObject(), + R3.Utils.IdOrNull(this.broadphase), + R3.Utils.IdOrNull(this.solver), + this.rigidBodies.map(function(body){ + return R3.Utils.IdOrNull(body); + }), + this.contactMaterials.map(function(contactMaterial){ + return R3.Utils.IdOrNull(contactMaterial); + }), + this.allowSleep, + R3.Utils.IdOrNull(this.defaultContactMaterial), + R3.Utils.IdOrNull(this.parent) + ); + + return apiWorld; +}; + +/** + * R3.D3.PhysicsWorld from Object World + * @param graphics + * @param objectComponent + * @returns {R3.D3.PhysicsWorld} + * @constructor + */ +R3.D3.PhysicsWorld.FromObject = function(graphics, objectComponent) { + var apiWorld = R3.D3.API.PhysicsWorld.FromObject(objectComponent); + return new R3.D3.PhysicsWorld( + graphics, + apiWorld + ); +}; + +// +// R3.D3.PhysicsWorld.prototype.step = function( +// fixedStep, +// dtStep +// ) { +// +// }; +// +// R3.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 R3.D3.Shape +// * @param normalLength Number +// * @param scale R3.API.Vector3 +// * @param opacity Number +// * @param wireframeColor HexCode +// * @param graphics THREE +// * @returns {THREE.Mesh|this.meshes} +// * @constructor +// */ +// R3.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 R3.Runtime.Graphics +// * @param graphicsMesh THREE.Mesh +// * @param mass Number +// * @param friction Number +// * @param createCollisionSubMeshes Boolean +// * @param facesPerSubsection Number +// * @param subsectionsToMerge Number +// * @returns {Object} +// * @constructor +// */ +// R3.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++; +// } +// }; +// +// R3.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 R3.D3.Shape(this.engine, R3.D3.Shape.SHAPE_TYPE_CONVEX_HULL, {x:1,y:1,z:1},convexVertices, convexIndices); +// +// var body = new R3.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 R3.Runtime.Graphics +// * @param graphicsMesh THREE.Mesh +// * @returns {R3.D3.Shape} +// * @constructor +// */ +// R3.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 R3.D3.Shape(this.engine, R3.D3.Shape.SHAPE_TYPE_TRIMESH, {x : 1, y : 1, z : 1}, vertices, faces); +// }; +// +// /** +// * @param triangleMeshBody R3.D3.RigidBody +// * @param rayscale Number +// * @param maxTriangleDistance Number +// * @param createCompoundShape Boolean +// * @param graphics R3.Runtime.Graphics +// * @param triangleMeshShapes R3.D3.Shape[] +// * @param createDebugView Boolean +// * @returns {R3.D3.RigidBody} +// * @constructor +// */ +// R3.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 R3.D3.Shape(this.engine, R3.D3.Shape.SHAPE_TYPE_TRIMESH, { x : 1, y : 1, z : 1 }, element.vertices, element.indices); +// +// if(createCompoundShape) { +// triangleMeshBody.addShape(shape); +// } else { +// +// var body = new R3.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 +// }; +// }; \ No newline at end of file diff --git a/src/r3-d3-raycastVehicle.js b/src/r3-d3-raycastVehicle.js new file mode 100644 index 0000000..0967f95 --- /dev/null +++ b/src/r3-d3-raycastVehicle.js @@ -0,0 +1,173 @@ +/** + * RaycastVehicle Runtime + * @param physics R3.Runtime.Graphics + * @param apiRaycastVehicle R3.D3.API.RaycastVehicle + * @constructor + */ +R3.D3.RaycastVehicle = function( + physics, + apiRaycastVehicle +) { + + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (R3.Utils.UndefinedOrNull(apiRaycastVehicle)) { + apiRaycastVehicle = {}; + } + + R3.D3.API.RaycastVehicle.call( + this, + apiRaycastVehicle.id, + apiRaycastVehicle.name, + apiRaycastVehicle.chassis, + apiRaycastVehicle.wheels, + apiRaycastVehicle.raycastWheels, + apiRaycastVehicle.parentPhysicsWorld, + apiRaycastVehicle.parent + ); + + if (this.chassis instanceof R3.D3.API.RaycastVehicle) { + this.chassis = new R3.D3.RaycastVehicle( + this.physics, + this.chassis + ) + } + + this.wheels = this.wheels.map(function(wheel){ + if (wheel instanceof R3.D3.API.RigidBody) { + return new R3.D3.RigidBody( + this.physics, + wheel + ) + } else { + return wheel; + } + }.bind(this)); + + this.raycastWheels = this.raycastWheels.map(function(raycastWheel){ + if (raycastWheel instanceof R3.D3.API.RaycastWheel) { + return new R3.D3.RaycastWheel( + this.physics, + raycastWheel + ) + } else { + return raycastWheel; + } + }.bind(this)); + + R3.Component.call( + this, + { + 'chassis' : R3.D3.RigidBody, + 'wheels' : [R3.D3.RigidBody], + 'raycastWheels' : [R3.D3.RaycastWheel], + 'parentPhysicsWorld' : R3.D3.PhysicsWorld + } + ); +}; + +R3.D3.RaycastVehicle.prototype = Object.create(R3.Component.prototype); +R3.D3.RaycastVehicle.prototype.constructor = R3.D3.RaycastVehicle; + +/** + * + * @returns {*} + */ +R3.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 {R3.D3.RaycastVehicle|R3.D3.API.RaycastVehicle|*} + */ + + if (R3.Utils.UndefinedOrNull(this.chassis)) { + throw new Error('no chassis'); + } + + if (R3.Utils.UndefinedOrNull(this.chassis.instance)) { + throw new Error('no chassis instance'); + } + + if (R3.Utils.UndefinedOrNull(this.parentPhysicsWorld)) { + throw new Error('no parent world'); + } + + if (R3.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 (R3.Utils.UndefinedOrNull(wheel)) { + throw new Error('no wheel'); + } + + if (R3.Utils.UndefinedOrNull(wheel.instance)) { + throw new Error('no wheel instance'); + } + + this.instance.addWheel(wheel.instance); + + }.bind(this) + ); + + this.instance.addToWorld(this.parentPhysicsWorld.instance); + + __CREATE_INSTANCE__; + +}; + +R3.D3.RaycastVehicle.prototype.updateInstance = function(property) { + // this.instance.chassisBody = this.chassis.instance; + //TODO: add / remove wheels? + console.log('TODO: update raycast vehicle instance'); + __UPDATE_INSTANCE__; +}; + +/** + * R3.D3.RaycastVehicle to R3.D3.API.RaycastVehicle + * @returns {R3.D3.API.RaycastVehicle} + */ +R3.D3.RaycastVehicle.prototype.toApiObject = function() { + + var apiRaycastVehicle = new R3.D3.API.RaycastVehicle( + this.id, + this.name, + R3.Utils.IdOrNull(this.chassis), + this.wheels.map(function(wheel){ + return R3.Utils.IdOrNull(wheel); + }), + this.raycastWheels.map(function(raycastWheel){ + return R3.Utils.IdOrNull(raycastWheel); + }), + R3.Utils.IdOrNull(this.parentPhysicsWorld), + R3.Utils.IdOrNull(this.parent) + ); + + return apiRaycastVehicle; +}; + +/** + * R3.D3.RaycastVehicle from Object RaycastVehicle + * @param physics + * @param objectComponent + * @returns {R3.D3.RaycastVehicle} + * @constructor + */ +R3.D3.RaycastVehicle.FromObject = function(physics, objectComponent) { + + var apiRaycastVehicle = R3.D3.API.RaycastVehicle.FromObject(objectComponent); + + return new R3.D3.RaycastVehicle( + physics, + apiRaycastVehicle + ); +}; diff --git a/src/r3-d3-raycastWheel.js b/src/r3-d3-raycastWheel.js new file mode 100644 index 0000000..15db839 --- /dev/null +++ b/src/r3-d3-raycastWheel.js @@ -0,0 +1,170 @@ +/** + * RaycastWheel Runtime + * @param physics R3.Runtime.Graphics + * @param apiRaycastWheel R3.D3.API.RaycastWheel + * @constructor + */ +R3.D3.RaycastWheel = function( + physics, + apiRaycastWheel +) { + + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (R3.Utils.UndefinedOrNull(apiRaycastWheel)) { + apiRaycastWheel = {}; + } + + R3.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.parent + ); + + this.directionLocal = new R3.Vector3( + this.physics, + this.directionLocal, + this + ); + + this.axleLocal = new R3.Vector3( + this.physics, + this.axleLocal, + this + ); + + this.chassisConnectionPointLocal = new R3.Vector3( + this.physics, + this.chassisConnectionPointLocal, + this + ); + + R3.Component.call( + this, + { + 'parentMesh' : R3.D3.Mesh + } + ); +}; + +R3.D3.RaycastWheel.prototype = Object.create(R3.Component.prototype); +R3.D3.RaycastWheel.prototype.constructor = R3.D3.RaycastWheel; + +/** + * + * @returns {*} + */ +R3.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 + }; + + __CREATE_INSTANCE__; +}; + +R3.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; +}; + +/** + * R3.D3.RaycastWheel to R3.D3.API.RaycastWheel + * @returns {R3.D3.API.RaycastWheel} + */ +R3.D3.RaycastWheel.prototype.toApiObject = function() { + + var apiRaycastWheel = new R3.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, + R3.Utils.IdOrNull(this.parentMesh), + R3.Utils.IdOrNull(this.parent) + ); + + return apiRaycastWheel; +}; + +/** + * R3.D3.RaycastWheel from Object RaycastWheel + * @param physics + * @param objectComponent + * @returns {R3.D3.RaycastWheel} + * @constructor + */ +R3.D3.RaycastWheel.FromObject = function(physics, objectComponent) { + + var apiRaycastWheel = R3.D3.API.RaycastWheel.FromObject(objectComponent); + + return new R3.D3.RaycastWheel( + physics, + apiRaycastWheel + ); +}; + +R3.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; + +}; \ No newline at end of file diff --git a/src/r3-d3-raycaster.js b/src/r3-d3-raycaster.js new file mode 100644 index 0000000..ae4f010 --- /dev/null +++ b/src/r3-d3-raycaster.js @@ -0,0 +1,216 @@ +/** + * R3.D3.Raycaster + * @param apiComponent + * @constructor + */ +R3.D3.Raycaster = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.linkedComponents.position = R3.Vector3; + this.linkedComponents.direction = R3.Vector3; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.D3.Raycaster.prototype = Object.create(R3.Component.prototype); +R3.D3.Raycaster.prototype.constructor = R3.D3.Raycaster; + +/** + * Creates or updates a raycaster instance + */ +R3.D3.Raycaster.prototype.createInstance = function() { + + this.instance = this.graphics.Raycaster( + this.position, + this.direction + ); + + __CREATE_INSTANCE__; +}; + +R3.D3.Raycaster.prototype.updateInstance = function(property) { + + if ( + property === 'position' + ) { + this.position.instance.x = this.position.x; + this.position.instance.y = this.position.y; + this.position.instance.z = this.position.z; + this.instance.setPosition(this.position.instance); + return; + } + + if (property === 'direction') { + this.direction.instance.x = this.direction.x; + this.direction.instance.y = this.direction.y; + this.direction.instance.z = this.direction.z; + this.instance.setDirection(this.direction.instance); + return; + } + + __UPDATE_INSTANCE__; +}; + +/** + * Sets the direction and position of this raycaster + * @param position R3.Vector3 + * @param direction R3.Vector3 + */ +R3.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.updateInstance('position'); + this.updateInstance('direction'); +}; + +/** + * Sets the direction of this raycaster + * @param direction R3.Vector3 + */ +R3.D3.Raycaster.prototype.setDirection = function( + direction +) { + this.direction.x = direction.x; + this.direction.y = direction.y; + this.direction.z = direction.z; + + this.updateInstance('direction'); +}; + +/** + * Sets the position of this raycaster + * @param position R3.Vector3 + */ +R3.D3.Raycaster.prototype.setPosition = function( + position +) { + this.position.x = position.x; + this.position.y = position.y; + this.position.z = position.z; + + this.updateInstance('position'); +}; + +/** + * Sets the ray position and direction from the mouse coordinates (in proper x and y (-1 to 1)) + * @param mouse + * @param camera + */ +R3.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 R3.D3.Mesh objects + * @param meshes [R3.D3.Mesh] + */ +R3.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, + face: mesh.geometry.faces[intersects[0].faceIndex], + faceIndex: intersects[0].faceIndex, + uv : { + x : intersects[0].uv.x, + y : intersects[0].uv.y + } + } + ); + } + + return result; + }.bind(this), + [] + ); +}; + +/** + * Returns the face normal (if any) of an intersection between current ray position, direction and a provided mesh + * @param mesh R3.D3.Mesh + * @returns {null | R3.Vector3} + */ +R3.D3.Raycaster.prototype.getFaceNormal = function(mesh) { + + var normal = null; + + var intersect = this.instance.intersectObject( + mesh.instance + ); + + if (intersect && intersect.length > 0) { + + normal = new R3.Vector3( + this.graphics, + new R3.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 R3.D3.Mesh + * @returns {null | R3.Vector3} + */ +R3.D3.Raycaster.prototype.getIntersectPoint = function(mesh) { + + var point = null; + + var intersect = this.instance.intersectObject( + mesh.instance + ); + + if (intersect && intersect.length > 0) { + point = new R3.Vector3( + this.graphics, + new R3.API.Vector3( + intersect[0].point.x, + intersect[0].point.y, + intersect[0].point.z + ), + this + ); + } + + return point; +}; diff --git a/src/r3-d3-renderTarget-0.js b/src/r3-d3-renderTarget-0.js new file mode 100644 index 0000000..40284e5 --- /dev/null +++ b/src/r3-d3-renderTarget-0.js @@ -0,0 +1,107 @@ +/** + * R3.D3.RenderTarget + * @param apiComponent + * @constructor + */ +R3.D3.RenderTarget = function( + apiComponent, + inherited +) { + + __INHERIT_AND_INSTANTIATE__ + + this.linkedComponents.texture = R3.D3.Texture; + this.linkedComponents.depthTexture = R3.D3.Texture; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.RenderTarget.prototype = Object.create(R3.Component.prototype); +R3.D3.RenderTarget.prototype.constructor = R3.D3.RenderTarget; + +/** + * Creates a Render Target instance + * @returns {*} + */ +R3.D3.RenderTarget.prototype.createInstance = function() { + + this.instance = this.graphics.RenderTarget( + this.width, + this.height, + this.texture.wrapS, + this.texture.wrapT, + this.texture.magFilter, + this.texture.minFilter, + this.texture.format, + this.texture.storageType, + this.texture.anisotropy, + this.texture.encoding + ); + + this.instance.depthBuffer = this.depthBuffer; + this.instance.stencilBuffer = this.stencilBuffer; + + this.instance.scissor = this.scissor.instance; + this.instance.scissorTest = this.scissorTest.instance; + this.instance.viewport = this.viewport.instance; + + __CREATE_INSTANCE__; +}; + +/** + * updates instance + */ +R3.D3.RenderTarget.prototype.updateInstance = function(property) { + + if ( + property === 'width' || + property === 'height' + ) { + this.instance.setSize(this.width, this.height); + return; + } + + if (property === 'scissor') { + this.instance.scissor = this.scissor.instance; + return; + } + + if (property === 'scissorTest') { + this.instance.scissorTest = this.scissorTest; + return; + } + + if (property === 'viewport') { + this.instance.viewport = this.viewport.instance; + return; + } + + if (property === 'texture') { + console.warn('TODO: update texture'); + return; + } + + if (property === 'depthBuffer') { + this.instance.depthBuffer = this.depthBuffer; + return; + } + + if (property === 'depthTexture') { + console.warn('TODO: update depthTexture'); + return; + } + + if (property === 'stencilBuffer') { + this.instance.stencilBuffer = this.stencilBuffer; + return; + } + + if (property === 'depthBuffer') { + this.instance.depthBuffer = this.depthBuffer; + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-d3-renderTarget-cube.js b/src/r3-d3-renderTarget-cube.js new file mode 100644 index 0000000..a895aa9 --- /dev/null +++ b/src/r3-d3-renderTarget-cube.js @@ -0,0 +1,73 @@ +/** + * Renders a scene with a camera + * @param graphics R3.Runtime.Graphics + * @param apiRenderTargetCube R3.D3.API.RenderTarget.Cube + * @constructor + */ +R3.D3.RenderTarget.Cube = function( + graphics, + apiRenderTargetCube +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiRenderTargetCube)) { + apiRenderTargetCube = { + renderTargetType : R3.D3.API.RenderTarget.TARGET_TYPE_CUBE + }; + } + + R3.D3.API.RenderTarget.Cube.call( + this, + apiRenderTargetCube + ); + + R3.D3.RenderTarget.call( + this, + this.graphics, + this + ); +}; + +R3.D3.RenderTarget.Cube.prototype = Object.create(R3.D3.RenderTarget.prototype); +R3.D3.RenderTarget.Cube.prototype.constructor = R3.D3.RenderTarget.Cube; + +/** + * Creates a Render Target instance + * @returns {*} + */ +R3.D3.RenderTarget.Cube.prototype.createInstance = function() { + + this.instance = new THREE.WebGLRenderTargetCube( + this.width, + this.height, + this.textureParameters + ); + + R3.D3.RenderTarget.prototype.createInstance.call(this); +}; + +/** + * updates instance + */ +R3.D3.RenderTarget.Cube.prototype.updateInstance = function(property) { + R3.D3.RenderTarget.prototype.updateInstance.call(this, property); +}; + +/** + * Render Target to API Render Target + * @returns {R3.D3.API.RenderTarget.Cube} + */ +R3.D3.RenderTarget.Cube.prototype.toApiObject = function() { + + var apiRenderTarget = R3.D3.RenderTarget.prototype.toApiObject.call( + this + ); + + var apiRenderTargetCube = new R3.D3.API.RenderTarget.Cube( + apiRenderTarget + ); + + return apiRenderTargetCube; +}; diff --git a/src/r3-d3-rigidBody.js b/src/r3-d3-rigidBody.js new file mode 100644 index 0000000..0dacc37 --- /dev/null +++ b/src/r3-d3-rigidBody.js @@ -0,0 +1,288 @@ +/** + * RigidBody Runtime + * @param physics R3.Runtime.Graphics + * @param apiRigidBody R3.D3.API.RigidBody + * @constructor + */ +R3.D3.RigidBody = function( + physics, + apiRigidBody +) { + + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (R3.Utils.UndefinedOrNull(apiRigidBody)) { + apiRigidBody = {}; + } + + R3.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.parent + ); + + this.position = new R3.Vector3( + this.physics, + this.position, + this + ); + + this.quaternion = new R3.Quaternion( + this.physics, + this.quaternion, + this + ); + + this.velocity = new R3.Vector3( + this.physics, + this.velocity, + this + ); + + this.angularVelocity = new R3.Vector3( + this.physics, + this.angularVelocity, + this + ); + + this.force = new R3.Vector3( + this.physics + ); + + this.forcePoint = new R3.Vector3( + this.physics + ); + + R3.Component.call( + this, + { + 'shapes' : [R3.D3.Shape], + 'parentMesh' : R3.D3.Mesh, + 'parentPhysicsWorld' : R3.D3.PhysicsWorld + } + ); +}; + +R3.D3.RigidBody.prototype = Object.create(R3.Component.prototype); +R3.D3.RigidBody.prototype.constructor = R3.D3.RigidBody; + +/** + * + * @returns {*} + */ +R3.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 (R3.Utils.UndefinedOrNull(shape)) { + throw new Error('no shape'); + } + + if (R3.Utils.UndefinedOrNull(shape.instance)) { + throw new Error('no shape instance'); + } + + this.instance.addShape(shape.instance) + + }.bind(this) + ); + + __CREATE_INSTANCE__; +}; + +/** + * + */ +R3.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; + + __UPDATE_INSTANCE__; +}; + +R3.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(); + +}; + +/** + * R3.D3.RigidBody to R3.D3.API.RigidBody + * @returns {R3.D3.API.RigidBody} + */ +R3.D3.RigidBody.prototype.toApiObject = function() { + + var apiRigidBody = new R3.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 R3.Utils.IdOrNull(shape)}), + this.kinematic, + R3.Utils.IdOrNull(this.parentMesh), + R3.Utils.IdOrNull(this.parentPhysicsWorld), + R3.Utils.IdOrNull(this.parent) + ); + + return apiRigidBody; +}; + +/** + * R3.D3.RigidBody from Object RigidBody + * @param physics + * @param objectComponent + * @returns {R3.D3.RigidBody} + * @constructor + */ +R3.D3.RigidBody.FromObject = function(physics, objectComponent) { + + var apiRigidBody = R3.D3.API.RigidBody.FromObject(objectComponent); + + return new R3.D3.RigidBody( + physics, + apiRigidBody + ); +}; + +R3.D3.RigidBody.prototype.applyForce = function() { + this.instance.applyForce( + this.force.instance, + this.forcePoint.instance + ) +}; + + +R3.D3.RigidBody.prototype.applyLocalForce = function() { + this.instance.applyLocalForce( + this.force.instance, + this.forcePoint.instance + ) +}; diff --git a/src/r3-d3-scene.js b/src/r3-d3-scene.js new file mode 100644 index 0000000..1851b61 --- /dev/null +++ b/src/r3-d3-scene.js @@ -0,0 +1,421 @@ +/** + * R3.D3.Scene + * @param apiComponent + * @constructor + */ +R3.D3.Scene = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.linkedComponents.meshes = [R3.D3.Mesh]; + this.linkedComponents.lights = [R3.D3.Light]; + this.linkedComponents.viewports = [R3.D3.Viewport]; + this.linkedComponents.fog = R3.D3.Fog; + + this.helpers = []; + + this.clones = []; + + this.grid = []; + + this.axis = []; + + this.storeClones = false; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Scene.prototype = Object.create(R3.Component.prototype); +R3.D3.Scene.prototype.constructor = R3.D3.Scene; + +/** + * Creates an instance scene + * @returns {THREE.Scene} + */ +R3.D3.Scene.prototype.createInstance = function() { + + this.instance = this.graphics.Scene(this); + + if (this.showGrid) { + this.drawGrid(); + } + + if (this.showAxis) { + this.drawAxis(); + } + + __CREATE_INSTANCE__; + +}; + +R3.D3.Scene.prototype.updateInstance = function(property) { + + if (property === 'name') { + this.instance.name = this.name; + return; + } + + if (property === 'fog') { + if (R3.Utils.Instance(this.fog)) { + this.instance.fog = this.fog.instance; + } else { + this.instance.fog = null; + } + } + + if (property === 'meshes') { + + /** + * Add missing meshes + */ + this.meshes.map( + function(mesh) { + if (this.instance.children.indexOf(mesh.instance === -1)) { + this.instance.add(mesh.instance); + } + }.bind(this) + ); + } + + if (property === 'lights') { + + /** + * Add missing lights + */ + this.lights.map( + function(light) { + if (this.instance.children.indexOf(light.instance) === -1) { + this.instance.add(light.instance); + } + }.bind(this) + ); + } + + if ( + property === 'meshes' || + property === 'lights' + ) { + /** + * 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) + ); + return; + } + + 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(); + } + } + + __UPDATE_INSTANCE__; +}; + +/** + * Adds a mesh to the scene + * @param object R3.D3.Mesh + */ +R3.D3.Scene.prototype.addObject = function(object) { + + if (object instanceof R3.D3.Mesh) { + if (this.meshes.indexOf(object.id) === -1) { + R3.Utils.PushUnique(this.meshes, object); + } + } + + if (object instanceof R3.D3.Light) { + if (this.lights.indexOf(object.id) === -1) { + R3.Utils.PushUnique(this.lights, object); + } + } + + object.parentScene = this; + + if ( + this.instance && + object.instance + ) { + if (this.instance.children.indexOf(object.instance) === -1) { + this.instance.add(object.instance); + } + } else { + // console.warn('either scene or mesh instance not ready'); + } + + // if (this.parent) { + // this.parent.addComponent(object); + // } + +}; + +R3.D3.Scene.prototype.addClone = function(component) { + + if (component instanceof R3.D3.Mesh || + component instanceof R3.D3.Light + ) { + if (this.instance && component.instance) { + if (this.instance.children.indexOf(component.instance) === -1) { + this.instance.add(component.instance); + } + } + + component.isClone = true; + + R3.Utils.PushUnique(this.clones, component); + + var index = this.meshes.indexOf(component); + + if (index !== -1) { + this.meshes.splice(index, 1); + } + + component.parentScene = this; + } +}; + +/** + * + * @param object + */ +R3.D3.Scene.prototype.removeObject = function(object) { + + var index = -1; + + if (object instanceof R3.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 R3.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; + } + // + // if (this.parent) { + // this.parent.removeComponent(object); + // } + // this.buildIdToObject(); +}; + +R3.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) { + + if (y === 0) { + continue; + } + + 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); + } +}; + +R3.D3.Scene.prototype.removeGrid = function() { + this.grid.map( + function(object) { + this.instance.remove(object); + }.bind(this) + ); +}; + +R3.D3.Scene.prototype.drawAxis = function() { + + this.removeAxis(); + + var Xmaterial = new THREE.LineBasicMaterial({ + color: 0xff0000, + linewidth: 2 + }); + var Xmaterial2 = new THREE.LineBasicMaterial({ + color: 0x440000, + linewidth: 2 + }); + + var Xgeometry = new THREE.Geometry(); + Xgeometry.vertices.push( + new THREE.Vector3( 0, 0, 0 ), + new THREE.Vector3( 100, 0, 0 ) + ); + + var Xgeometry2 = new THREE.Geometry(); + Xgeometry2.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); + + lineX = new THREE.Line(Xgeometry2, Xmaterial2); + this.instance.add(lineX); + this.axis.push(lineX); + + var Ymaterial = new THREE.LineBasicMaterial({ + color: 0x00ff00, + linewidth: 2 + }); + // var Ymaterial2 = new THREE.LineBasicMaterial({ + // color: 0x008800, + // linewidth: 2 + // }); + + var Ygeometry = new THREE.Geometry(); + Ygeometry.vertices.push( + new THREE.Vector3( 0, 0, 0 ), + new THREE.Vector3( 0, 100, 0 ) + ); + // var Ygeometry2 = new THREE.Geometry(); + // Ygeometry2.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); + + // lineY = new THREE.Line(Ygeometry2, Ymaterial2); + // this.instance.add(lineY); + // this.axis.push(lineY); + + var Zmaterial = new THREE.LineBasicMaterial({ + color: 0x0000ff, + linewidth: 2 + }); + var Zmaterial2 = new THREE.LineBasicMaterial({ + color: 0x000044, + linewidth: 2 + }); + + var Zgeometry = new THREE.Geometry(); + Zgeometry.vertices.push( + new THREE.Vector3( 0, 0, 0 ), + new THREE.Vector3( 0, 0, 100 ) + ); + + var Zgeometry2 = new THREE.Geometry(); + Zgeometry2.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); + + lineZ = new THREE.Line(Zgeometry2, Zmaterial2); + this.instance.add(lineZ); + this.axis.push(lineZ); +}; + +R3.D3.Scene.prototype.removeAxis = function() { + this.axis.map( + function(object) { + this.instance.remove(object); + }.bind(this) + ); +}; diff --git a/src/r3-d3-shader-0.js b/src/r3-d3-shader-0.js new file mode 100644 index 0000000..7b9c9da --- /dev/null +++ b/src/r3-d3-shader-0.js @@ -0,0 +1,97 @@ +/** + * R3.D3.Shader + * @param graphics R3.Runtime.Graphics + * @param apiShader R3.D3.API.Shader + * @constructor + */ +R3.D3.Shader = function( + graphics, + apiShader +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiShader)) { + apiShader = {}; + } + + R3.D3.API.Shader.call( + this, + apiShader.id, + apiShader.name, + apiShader.shaderType, + apiShader.parent, + apiShader.parentMaterialShader, + apiShader.code + ); + + R3.Component.call( + this, + { + parentMaterialShader : R3.D3.Material.Shader + } + ); +}; + +R3.D3.Shader.prototype = Object.create(R3.CustomCode.prototype); +R3.D3.Shader.prototype.constructor = R3.D3.Shader; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Shader.prototype.createInstance = function() { + + this.instance = this.code; + + /** + * We don't actually call the CustomCode createInstance - since these aren't javascript functions, they are + * GLSL code + */ + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Shader.prototype.updateInstance = function(property) { + + if (R3.Utils.UndefinedOrNull(property)) { + console.warn('no property for Shader: ' + this.name); + } + + if (property === 'code') { + this.instance = this.code; + + if (this.parentMaterialShader && this.parentMaterialShader.instance) { + + this.parentMaterialShader.instance.program.destroy(); + +// this.parentMaterialShader.instance.needsUpdate = true; + + } else { + console.warn('parent material shader not running or linked'); + } + + return; + } + + __UPDATE_INSTANCE__; +}; + +/** + * Converts a R3.D3.Shader to a R3.D3.API.Shader + * @returns {R3.D3.API.Shader} + */ +R3.D3.Shader.prototype.toApiObject = function() { + return new R3.D3.API.Shader( + this.id, + this.name, + this.shaderType, + R3.Utils.IdOrNull(this.parent), + R3.Utils.IdOrNull(this.parentMaterialShader), + this.code + ); +}; diff --git a/src/r3-d3-shader-fragment.js b/src/r3-d3-shader-fragment.js new file mode 100644 index 0000000..1e10358 --- /dev/null +++ b/src/r3-d3-shader-fragment.js @@ -0,0 +1,59 @@ +/** + * R3.D3.Shader.Fragment + * @param graphics R3.Runtime.Graphics + * @param apiFragmentShader + * @constructor + */ +R3.D3.Shader.Fragment = function( + graphics, + apiFragmentShader +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiFragmentShader)) { + apiFragmentShader = { + shaderType : R3.D3.API.Shader.SHADER_TYPE_FRAGMENT + }; + } + + R3.D3.API.Shader.Fragment.call( + this, + apiFragmentShader + ); + + R3.D3.Shader.call( + this, + this.graphics, + apiFragmentShader + ); + +}; + +R3.D3.Shader.Fragment.prototype = Object.create(R3.D3.Shader.prototype); +R3.D3.Shader.Fragment.prototype.constructor = R3.D3.Shader.Fragment; + +/** + * Creates a shader instance + * @returns {*} + */ +R3.D3.Shader.Fragment.prototype.createInstance = function() { + R3.D3.Shader.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Shader.Fragment.prototype.updateInstance = function(property) { + R3.D3.Shader.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Shader to a R3.D3.API.Shader + * @returns {R3.D3.API.Shader} + */ +R3.D3.Shader.Fragment.prototype.toApiObject = function() { + var apiShader = R3.D3.Shader.prototype.toApiObject.call(this); + return apiShader; +}; diff --git a/src/r3-d3-shader-vertex.js b/src/r3-d3-shader-vertex.js new file mode 100644 index 0000000..2aa4774 --- /dev/null +++ b/src/r3-d3-shader-vertex.js @@ -0,0 +1,59 @@ +/** + * R3.D3.Shader.Vertex + * @param graphics R3.Runtime.Graphics + * @param apiVertexShader + * @constructor + */ +R3.D3.Shader.Vertex = function( + graphics, + apiVertexShader +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiVertexShader)) { + apiVertexShader = { + shaderType : R3.D3.API.Shader.SHADER_TYPE_VERTEX + }; + } + + R3.D3.API.Shader.Vertex.call( + this, + apiVertexShader + ); + + R3.D3.Shader.call( + this, + this.graphics, + apiVertexShader + ); + +}; + +R3.D3.Shader.Vertex.prototype = Object.create(R3.D3.Shader.prototype); +R3.D3.Shader.Vertex.prototype.constructor = R3.D3.Shader.Vertex; + +/** + * Creates a shader instance + * @returns {*} + */ +R3.D3.Shader.Vertex.prototype.createInstance = function() { + R3.D3.Shader.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Shader.Vertex.prototype.updateInstance = function(property) { + R3.D3.Shader.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Shader to a R3.D3.API.Shader + * @returns {R3.D3.API.Shader} + */ +R3.D3.Shader.Vertex.prototype.toApiObject = function() { + var apiShader = R3.D3.Shader.prototype.toApiObject.call(this); + return apiShader; +}; diff --git a/src/r3-d3-shadow-0.js b/src/r3-d3-shadow-0.js new file mode 100644 index 0000000..2124e13 --- /dev/null +++ b/src/r3-d3-shadow-0.js @@ -0,0 +1,82 @@ +/** + * R3.D3.Shadow + * + * - R3.D3.Shadow components are not intended to be created directly + * + * https://threejs.org/docs/#api/en/lights/shadows/SpotLightShadow + * - "This is used internally by SpotLights for calculating shadows." + * + * https://threejs.org/docs/#api/en/lights/shadows/DirectionalLightShadow + * - "This is not intended to be called directly - it is called internally by DirectionalLight." + * + * - For this reason - we create them as normal components - but instead of creating their instances, they get + * assigned to them through parent objects at create instance time, and the runtime shadow object gets updated + * accordingly + * + * - We also don't create Shadow objects at API level unless they come from the API - this way we know whether or + * not we need to update the shadow with our information or update our information with the shadow information + * + * @param inherited + * + * @constructor + */ +R3.D3.Shadow = function( + inherited +) { + + if (R3.Utils.UndefinedOrNull(inherited)) { + throw new Error('R3.D3.Shadow should not be instantiated directly'); + } + + __UPGRADE_TO_RUNTIME__; +}; + +R3.D3.Shadow.prototype = Object.create(R3.Component.prototype); +R3.D3.Shadow.prototype.constructor = R3.D3.Shadow; + +/** + * Updates the instance with the current state + */ +R3.D3.Shadow.prototype.updateInstance = function(property) { + + if (property === 'camera') { + this.instance.camera = this.camera.instance; + return; + } + + if (property === 'bias') { + this.instance.bias = this.bias; + return; + } + + if (property === 'mapSize') { + this.instance.mapSize.x = this.mapSize.x; + this.instance.mapSize.y = this.mapSize.y; + return; + } + + if (property === 'radius') { + this.instance.radius = this.radius; + return; + } + + __UPDATE_INSTANCE__; + +}; + +/** + * Until this can be moved into a more generic way into R3.Component - we do it this way for now + */ +R3.D3.Shadow.prototype.updateInstanceAll = function() { + this.updateInstance('camera'); + this.updateInstance('bias'); + this.updateInstance('mapSize'); + this.updateInstance('radius'); +}; + +R3.D3.Shadow.prototype.updateFromInstanceAll = function() { + this.updateFromInstance('camera'); + this.updateFromInstance('bias'); + this.updateFromInstance('mapSize'); + this.updateFromInstance('radius'); +}; \ No newline at end of file diff --git a/src/r3-d3-shadow-directional.js b/src/r3-d3-shadow-directional.js new file mode 100644 index 0000000..0d4f7fb --- /dev/null +++ b/src/r3-d3-shadow-directional.js @@ -0,0 +1,55 @@ +/** + * R3.D3.Shadow.Directional + * + * - R3.D3.Shadow components are not intended to be created directly + * + * https://threejs.org/docs/#api/en/lights/shadows/SpotLightShadow + * - "This is used internally by SpotLights for calculating shadows." + * + * https://threejs.org/docs/#api/en/lights/shadows/DirectionalLightShadow + * - "This is not intended to be called directly - it is called internally by DirectionalLight." + * + * - For this reason - we create them as normal components - but instead of creating their instances, they get + * assigned to them through parent objects at create instance time, and the runtime shadow object gets updated + * accordingly + * + * @param apiComponent + * + * @constructor + */ +R3.D3.Shadow.Directional = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Shadow.call( + this, + true + ); + +}; + +R3.D3.Shadow.Directional.prototype = Object.create(R3.D3.Shadow.prototype); +R3.D3.Shadow.Directional.prototype.constructor = R3.D3.Shadow.Directional; + +/** + * Creates a shadow instance + * @returns {*} + */ +R3.D3.Shadow.Directional.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Shadow.Directional.prototype.updateInstance = function(property) { + + R3.D3.Shadow.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-d3-shadow-spot.js b/src/r3-d3-shadow-spot.js new file mode 100644 index 0000000..9e7c265 --- /dev/null +++ b/src/r3-d3-shadow-spot.js @@ -0,0 +1,54 @@ +/** + * R3.D3.Shadow.Spot + * + * - R3.D3.Shadow components are not intended to be created directly + * + * https://threejs.org/docs/#api/en/lights/shadows/SpotLightShadow + * - "This is used internally by SpotLights for calculating shadows." + * + * https://threejs.org/docs/#api/en/lights/shadows/DirectionalLightShadow + * - "This is not intended to be called directly - it is called internally by DirectionalLight." + * + * - For this reason - we create them as normal components - but instead of creating their instances, they get + * assigned to them through parent objects at create instance time, and the runtime shadow object gets updated + * accordingly + * + * @param apiComponent + * + * @constructor + */ +R3.D3.Shadow.Spot = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Shadow.call( + this, + true + ); + +}; + +R3.D3.Shadow.Spot.prototype = Object.create(R3.D3.Shadow.prototype); +R3.D3.Shadow.Spot.prototype.constructor = R3.D3.Shadow.Spot; + +/** + * Creates a shadow instance + * @returns {*} + */ +R3.D3.Shadow.Spot.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Shadow.Spot.prototype.updateInstance = function(property) { + + R3.D3.Shadow.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-d3-shape-0.js b/src/r3-d3-shape-0.js new file mode 100644 index 0000000..769976a --- /dev/null +++ b/src/r3-d3-shape-0.js @@ -0,0 +1,108 @@ +/** + * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created + * @param physics R3.Runtime.Physics + * @param apiShape R3.D3.API.Shape + * @constructor + */ +R3.D3.Shape = function( + physics, + apiShape +) { + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (R3.Utils.UndefinedOrNull(apiShape)) { + apiShape = { + shapeType : R3.D3.API.Shape.SHAPE_TYPE_NONE + }; + } + + R3.D3.API.Shape.call( + this, + apiShape.id, + apiShape.name, + apiShape.shapeType, + apiShape.boundingSphereRadius, + apiShape.collisionResponse, + apiShape.frictionMaterial, + apiShape.parentMesh, + apiShape.parent + ); + + var linkedComponents = { + frictionMaterial : R3.D3.FrictionMaterial, + parentMesh : R3.D3.Mesh + }; + + R3.Component.call( + this, + linkedComponents + ); +}; + +R3.D3.Shape.prototype = Object.create(R3.Component.prototype); +R3.D3.Shape.prototype.constructor = R3.D3.Shape; + + +/** + * Creates a shape instance or updates it + */ +R3.D3.Shape.prototype.createInstance = function() { + __CREATE_INSTANCE__; +}; + +/** + * Updates the mesh instance + */ +R3.D3.Shape.prototype.updateInstance = function(property) { + throw new Error('Do not instantiate this class directly - use a child class instead'); + __UPDATE_INSTANCE__; +}; + +/** + * Converts a R3.D3.Shape to a R3.D3.API.Shape + * @returns {R3.D3.API.Shape} + */ +R3.D3.Shape.prototype.toApiObject = function() { + + var apiShape = new R3.D3.API.Shape( + this.id, + this.name, + this.shapeType, + this.boundingSphereRadius, + this.collisionResponse, + R3.Utils.IdOrNull(this.frictionMaterial), + R3.Utils.IdOrNull(this.parentMesh), + R3.Utils.IdOrNull(this.parent) + ); + + return apiShape; +}; + +/** + * Converts a standard object mesh to a R3.D3.Shape + * @param physics R3.Runtime.Physics + * @param objectShape {Object} + * @constructor + */ +R3.D3.Shape.FromObject = function(physics, objectShape) { + throw ('not implemented'); +}; + +R3.D3.Shape.prototype.stopVisualize = function() { + R3.Event.Emit( + R3.Event.STOP_VISUALIZE, + { + mesh : this.mesh + } + ) +}; + +R3.D3.Shape.prototype.visualize = function() { + R3.Event.Emit( + R3.Event.VISUALIZE, + { + shape : this + } + ) +}; \ No newline at end of file diff --git a/src/r3-d3-shape-box.js b/src/r3-d3-shape-box.js new file mode 100644 index 0000000..d324bf2 --- /dev/null +++ b/src/r3-d3-shape-box.js @@ -0,0 +1,115 @@ +/** + * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created + * @param physics + * @param apiShape R3.D3.API.Shape + * @param halfExtents + * @constructor + */ +R3.D3.Shape.Box = function( + physics, + apiShape, + halfExtents +) { + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (R3.Utils.UndefinedOrNull(apiShape)) { + apiShape = { + shapeType : R3.D3.API.Shape.SHAPE_TYPE_BOX + }; + } + + if (R3.Utils.UndefinedOrNull(halfExtents)) { + halfExtents = new R3.Vector3( + physics, + new R3.API.Vector3( + 1,1,1 + ) + ); + } else if (halfExtents instanceof R3.API.Vector3) { + halfExtents = new R3.Vector3( + this.physics, + halfExtents, + this + ) + } + this.halfExtents = halfExtents; + + R3.D3.Shape.call( + this, + this.physics, + apiShape + ); +}; + +R3.D3.Shape.Box.prototype = Object.create(R3.D3.Shape.prototype); +R3.D3.Shape.Box.prototype.constructor = R3.D3.Shape.Box; + +/** + * + * @returns {R3.D3.Shape.Box|*|SEA3D.Box} + */ +R3.D3.Shape.Box.prototype.createInstance = function() { + + if (R3.Utils.UndefinedOrNull(this.halfExtents)) { + throw new Error('no halfExtents'); + } + + if (R3.Utils.UndefinedOrNull(this.halfExtents.instance)) { + throw new Error('no halfExtents instance'); + } + + this.instance = new CANNON.Box( + this.halfExtents.instance + ); + + R3.D3.Shape.prototype.createInstance.call(this); + +}; + +R3.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(); +}; + +R3.D3.Shape.Box.prototype.toApiObject = function() { + + var apiShape = R3.D3.Shape.prototype.toApiObject.call(this); + + apiShape.halfExtents = this.halfExtents.toApiObject(); + + return apiShape; +}; + +R3.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(); +}; + +R3.D3.Shape.Box.FromObject = function(physics, objectShape) { + + var apiShape = R3.D3.API.Shape.FromObject(objectShape); + + apiShape.halfExtents = R3.API.Vector3.FromObject(objectShape.halfExtents); + + return new R3.D3.Shape.Box( + physics, + apiShape, + apiShape.halfExtents + ); + +}; \ No newline at end of file diff --git a/src/r3-d3-shape-convexHull-0.js b/src/r3-d3-shape-convexHull-0.js new file mode 100644 index 0000000..a6fdcfd --- /dev/null +++ b/src/r3-d3-shape-convexHull-0.js @@ -0,0 +1,281 @@ +/** + * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created + * @param physics + * @param apiShape R3.D3.API.Shape + * @param faces + * @param uniqueAxes + * @param uniqueEdges + * @param vertices + * @constructor + */ +R3.D3.Shape.ConvexHull = function( + physics, + apiShape, + vertices, + faces, + uniqueAxes, + uniqueEdges +) { + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (R3.Utils.UndefinedOrNull(apiShape)) { + apiShape = { + shapeType : R3.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL + }; + } + + if (R3.Utils.UndefinedOrNull(vertices)) { + vertices = []; + } + this.vertices = vertices; + + if (R3.Utils.UndefinedOrNull(faces)) { + faces = []; + } + this.faces = faces; + + if (R3.Utils.UndefinedOrNull(uniqueAxes)) { + uniqueAxes = []; + } + this.uniqueAxes = uniqueAxes; + + if (R3.Utils.UndefinedOrNull(uniqueEdges)) { + uniqueEdges = []; + } + this.uniqueEdges = uniqueEdges; + + this.vertices = this.vertices.map(function(vertex){ + if (vertex instanceof R3.D3.API.Vertex){ + return new R3.D3.Vertex( + this.physics, + vertex + ) + } + return vertex; + }.bind(this)); + + this.faces = this.faces.map(function(face){ + if (face instanceof R3.D3.API.Face){ + return new R3.D3.Face( + this.physics, + face + ) + } + return face; + }.bind(this)); + + this.uniqueAxes = this.uniqueAxes.map(function(axis){ + if (axis instanceof R3.API.Vector3) { + return new R3.Vector3( + this.physics, + axis, + this + ) + } + return axis; + }.bind(this)); + + this.uniqueEdges = this.uniqueEdges.map(function(edge){ + if (edge instanceof R3.API.Vector3) { + return new R3.Vector3( + this.physics, + edge, + this + ) + } + return edge; + }.bind(this)); + + R3.D3.Shape.call( + this, + this.physics, + apiShape + ); +}; + +R3.D3.Shape.ConvexHull.prototype = Object.create(R3.D3.Shape.prototype); +R3.D3.Shape.ConvexHull.prototype.constructor = R3.D3.Shape.ConvexHull; + +/** + * Create instance + * @returns {R3.D3.Shape.ConvexHull} + */ +R3.D3.Shape.ConvexHull.prototype.createInstance = function() { + + var faceNormals = []; + + this.instance = new CANNON.ConvexPolyhedron( + this.vertices.map( + function(vertex) { + + if (R3.Utils.UndefinedOrNull(vertex)) { + throw new Error('no vertex'); + } + + if (R3.Utils.UndefinedOrNull(vertex.position)) { + throw new Error('no vertex position'); + } + + if (R3.Utils.UndefinedOrNull(vertex.position.instance)) { + throw new Error('no vertex position instance'); + } + + return vertex.position.instance; + } + ), + this.faces.map( + function(face) { + + if (R3.Utils.UndefinedOrNull(face)) { + throw new Error('no face'); + } + + if (R3.Utils.UndefinedOrNull(face.normal)) { + throw new Error('no face normal'); + } + + if (R3.Utils.UndefinedOrNull(face.normal.instance)) { + throw new Error('no face normal instance'); + } + + if (R3.Utils.UndefinedOrNull(face.v0index)) { + throw new Error('no face v0index'); + } + + if (R3.Utils.UndefinedOrNull(face.v1index)) { + throw new Error('no face v1index'); + } + + if (R3.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; + + R3.D3.Shape.prototype.createInstance.call(this); +}; + +/** + * Update instance + */ +R3.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(); +}; + +R3.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 r3 classes :)'); +}; + +R3.D3.Shape.ConvexHull.prototype.toApiObject = function() { + + var apiShape = R3.D3.Shape.prototype.toApiObject.call(this); + + apiShape.vertices = this.vertices.map( + function(vertex) { + if (vertex instanceof R3.D3.Vertex) { + return vertex.toApiObject(); + } + return vertex; + } + ); + + apiShape.faces = this.faces.map( + function(face) { + if (face instanceof R3.D3.Face){ + return face.toApiObject(); + } + return face; + } + ); + + apiShape.uniqueAxes = this.uniqueAxes.map( + function(axis){ + if (axis instanceof R3.Vector3) { + return axis.toApiObject(); + } + return axis; + } + ); + + apiShape.uniqueEdges = this.uniqueEdges.map( + function(edge) { + if (edge instanceof R3.Vector3) { + return edge.toApiObject(); + } + return edge; + } + ); + + return apiShape; +}; + +R3.D3.Shape.ConvexHull.prototype.setFromMesh = function() { + console.log('todo: set convex hull from mesh'); + this.updateInstance(); +}; + +R3.D3.Shape.ConvexHull.InheritableProperties = function(physics, objectShape) { + var vertices = objectShape.vertices.map( + function(objectVertex) { + return R3.D3.Vertex.FromObject(physics, objectVertex); + } + ); + + var faces = objectShape.faces.map( + function(objectFace) { + return R3.D3.Face.FromObject(physics, objectFace); + } + ); + + var uniqueAxes = objectShape.uniqueAxes.map( + function(axis) { + return R3.API.Vector3.FromObject(axis); + } + ); + + var uniqueEdges = objectShape.uniqueEdges.map( + function(edge) { + return R3.API.Vector3.FromObject(edge); + } + ); + + return { + vertices : vertices, + faces : faces, + uniqueAxes : uniqueAxes, + uniqueEdges : uniqueEdges + }; +}; + +R3.D3.Shape.ConvexHull.FromObject = function(physics, objectShape) { + + var apiShape = R3.D3.API.Shape.FromObject(objectShape); + + var inheritableProperties = R3.D3.Shape.ConvexHull.InheritableProperties(physics, objectShape); + + return new R3.D3.Shape.ConvexHull.call( + this, + physics, + apiShape, + inheritableProperties.vertices, + inheritableProperties.faces, + inheritableProperties.uniqueAxes, + inheritableProperties.uniqueEdges + ); +}; \ No newline at end of file diff --git a/src/r3-d3-shape-convexHull-cylinder.js b/src/r3-d3-shape-convexHull-cylinder.js new file mode 100644 index 0000000..179b6ba --- /dev/null +++ b/src/r3-d3-shape-convexHull-cylinder.js @@ -0,0 +1,133 @@ +/** + * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created + * @param physics + * @param apiShape R3.D3.API.Shape + * @param radiusTop + * @param radiusBottom + * @param height + * @param numSegments + * @constructor + */ +R3.D3.Shape.ConvexHull.Cylinder = function( + physics, + apiShape, + radiusTop, + radiusBottom, + height, + numSegments +) { + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (R3.Utils.UndefinedOrNull(apiShape)) { + apiShape = { + shapeType : R3.D3.API.Shape.SHAPE_TYPE_CONVEX_HULL_CYLINDER + }; + } + + if (R3.Utils.UndefinedOrNull(radiusTop)) { + radiusTop = 1; + } + this.radiusTop = radiusTop; + + if (R3.Utils.UndefinedOrNull(radiusBottom)) { + radiusBottom = 1; + } + this.radiusBottom = radiusBottom; + + if (R3.Utils.UndefinedOrNull(height)) { + height = radiusBottom / 2; + } + this.height = height; + + if (R3.Utils.UndefinedOrNull(numSegments)) { + numSegments = 20; + } + this.numSegments = numSegments; + + R3.D3.Shape.ConvexHull.call( + this, + this.physics, + apiShape + ); +}; + +R3.D3.Shape.ConvexHull.Cylinder.prototype = Object.create(R3.D3.Shape.ConvexHull.prototype); +R3.D3.Shape.ConvexHull.Cylinder.prototype.constructor = R3.D3.Shape.ConvexHull.Cylinder; + +/** + * + * @returns {R3.D3.Shape.Cylinder|*|SEA3D.Cylinder} + */ +R3.D3.Shape.ConvexHull.Cylinder.prototype.createInstance = function() { + + this.instance = new CANNON.Cylinder( + this.radiusTop, + this.radiusBottom, + this.height, + this.numSegments + ); + + R3.D3.Shape.prototype.createInstance.call(this); +}; + +R3.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(); +}; + +R3.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; +}; + +R3.D3.Shape.ConvexHull.Cylinder.prototype.toApiObject = function() { + + var apiShape = R3.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; +}; + + +R3.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 = R3.D3.Shape.ConvexHull.FromObject(physics, objectShape); + * + * Instead, do this: + */ + var apiShape = R3.D3.API.Shape.FromObject(objectShape); + + var inheritableProperties = R3.D3.Shape.ConvexHull.InheritableProperties(physics, objectShape); + + for (var property in inheritableProperties) { + if (inheritableProperties.hasOwnProperty(property)) { + apiShape[property] = inheritableProperties[property]; + } + } + + return new R3.D3.Shape.ConvexHull.Cylinder( + physics, + apiShape, + objectShape.radiusTop, + objectShape.radiusBottom, + objectShape.height, + objectShape.numSegments + ); + +}; \ No newline at end of file diff --git a/src/r3-d3-shape-heightMap.js b/src/r3-d3-shape-heightMap.js new file mode 100644 index 0000000..3361b42 --- /dev/null +++ b/src/r3-d3-shape-heightMap.js @@ -0,0 +1,171 @@ +/** + * + * @param physics + * @param apiShape + * @param heightData + * @param minValue + * @param maxValue + * @param elementSize + * @constructor + */ +R3.D3.Shape.HeightMap = function( + physics, + apiShape, + heightData, + minValue, + maxValue, + elementSize +) { + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (R3.Utils.UndefinedOrNull(apiShape)) { + apiShape = { + shapeType : R3.D3.API.Shape.SHAPE_TYPE_HEIGHT_MAP + }; + } + + if (R3.Utils.UndefinedOrNull(heightData)) { + heightData = [[10, 10, 10], [10, 10, 10], [10, 10, 10]]; + } + this.heightData = heightData; + + if (R3.Utils.UndefinedOrNull(minValue)) { + minValue = 0; + } + this.minValue = minValue; + + if (R3.Utils.UndefinedOrNull(maxValue)) { + maxValue = 10; + } + this.maxValue = maxValue; + + if (R3.Utils.UndefinedOrNull(elementSize)) { + elementSize = 1; + } + this.elementSize = elementSize; + + R3.D3.Shape.call( + this, + this.physics, + apiShape + ); +}; + +R3.D3.Shape.HeightMap.prototype = Object.create(R3.D3.Shape.prototype); +R3.D3.Shape.HeightMap.prototype.constructor = R3.D3.Shape.HeightMap; + +/** + * Create instance + * @returns {R3.D3.Shape.HeightMap} + */ +R3.D3.Shape.HeightMap.prototype.createInstance = function() { + + //TODO: initialize properly and throw when errors + + this.instance = new CANNON.Heightfield( + this.heightData, + { + elemSize : this.elementSize + } + ); + + R3.D3.Shape.prototype.createInstance.call(this); +}; + +/** + * Update instance + */ +R3.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(); +}; + + +R3.D3.Shape.HeightMap.prototype.toApiObject = function() { + var apiShape = R3.D3.Shape.prototype.toApiObject.call(this); + apiShape.heightData = this.heightData; + apiShape.minValue = this.minValue; + apiShape.maxValue = this.maxValue; + apiShape.elemSize = this.elemSize; + return apiShape; +}; + +R3.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(); +}; + +R3.D3.Shape.HeightMap.FromObject = function(physics, objectShape) { + + var apiShape = R3.D3.API.Shape.FromObject(objectShape); + + return new R3.D3.Shape.HeightMap( + physics, + apiShape, + objectShape.heightData, + objectShape.minValue, + objectShape.maxValue, + objectShape.elemSize + ); +}; \ No newline at end of file diff --git a/src/r3-d3-shape-plane.js b/src/r3-d3-shape-plane.js new file mode 100644 index 0000000..f40d8f5 --- /dev/null +++ b/src/r3-d3-shape-plane.js @@ -0,0 +1,53 @@ +/** + * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created + * @param physics + * @param apiShape R3.D3.API.Shape + * @constructor + */ +R3.D3.Shape.Plane = function( + physics, + apiShape +) { + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (R3.Utils.UndefinedOrNull(apiShape)) { + apiShape = { + shapeType : R3.D3.API.Shape.SHAPE_TYPE_PLANE + }; + } + + R3.D3.Shape.call( + this, + this.physics, + apiShape + ); +}; + +R3.D3.Shape.Plane.prototype = Object.create(R3.D3.Shape.prototype); +R3.D3.Shape.Plane.prototype.constructor = R3.D3.Shape.Plane; + +/** + * + * @returns {R3.D3.Shape.Plane|*|SEA3D.Plane} + */ +R3.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(); + R3.D3.Shape.prototype.createInstance.call(this); +}; + +R3.D3.Shape.Plane.prototype.updateInstance = function() { +}; + +R3.D3.Shape.Plane.FromObject = function(physics, objectShape) { + + var apiShape = R3.D3.API.Shape.FromObject(objectShape); + + return new R3.D3.Shape.Plane( + physics, + apiShape + ); +}; \ No newline at end of file diff --git a/src/r3-d3-shape-sphere.js b/src/r3-d3-shape-sphere.js new file mode 100644 index 0000000..9045f01 --- /dev/null +++ b/src/r3-d3-shape-sphere.js @@ -0,0 +1,71 @@ +/** + * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created + * @param physics + * @param apiShape R3.D3.API.Shape + * @param radius + * @constructor + */ +R3.D3.Shape.Sphere = function( + physics, + apiShape, + radius +) { + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (R3.Utils.UndefinedOrNull(apiShape)) { + apiShape = { + shapeType : R3.D3.API.Shape.SHAPE_TYPE_SPHERE + }; + } + + if (R3.Utils.UndefinedOrNull(radius)) { + radius = 1; + } + this.radius = radius; + + R3.D3.Shape.call( + this, + this.physics, + apiShape + ); +}; + +R3.D3.Shape.Sphere.prototype = Object.create(R3.D3.Shape.prototype); +R3.D3.Shape.Sphere.prototype.constructor = R3.D3.Shape.Sphere; + +/** + * + * @returns {R3.D3.Shape.Sphere|*|SEA3D.Sphere} + */ +R3.D3.Shape.Sphere.prototype.createInstance = function() { + + this.instance = new CANNON.Sphere( + this.radius + ); + + R3.D3.Shape.prototype.createInstance.call(this); +}; + +R3.D3.Shape.Sphere.prototype.updateInstance = function() { + this.instance.radius = this.radius; + this.instance.updateBoundingSphereRadius(); +}; + + +R3.D3.Shape.Sphere.prototype.toApiObject = function() { + var apiShape = R3.D3.Shape.prototype.toApiObject.call(this); + apiShape.radius = this.radius; + return apiShape; +}; + +R3.D3.Shape.Sphere.FromObject = function(physics, objectShape) { + + var apiShape = R3.D3.API.Shape.FromObject(objectShape); + + return new R3.D3.Shape.Sphere( + physics, + apiShape, + objectShape.radius + ); +}; \ No newline at end of file diff --git a/src/r3-d3-shape-triMesh.js b/src/r3-d3-shape-triMesh.js new file mode 100644 index 0000000..2e31911 --- /dev/null +++ b/src/r3-d3-shape-triMesh.js @@ -0,0 +1,70 @@ +/** + * Shape Superset - The apiShape properties get moved into the Shape object itself, and then the instance is created + * @param physics + * @param apiShape R3.D3.API.Shape + * @param vertices + * @param indices + * @constructor + */ +R3.D3.Shape.TriMesh = function( + physics, + apiShape, + vertices, + indices +) { + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (R3.Utils.UndefinedOrNull(apiShape)) { + apiShape = { + shapeType : R3.D3.API.Shape.SHAPE_TYPE_TRIMESH + }; + } + + if (R3.Utils.UndefinedOrNull(vertices)) { + vertices = []; + } + this.vertices = vertices; + + if (R3.Utils.UndefinedOrNull(indices)) { + indices = []; + } + this.indices = indices; + + R3.D3.Shape.call( + this, + this.physics, + apiShape + ); +}; + +R3.D3.Shape.TriMesh.prototype = Object.create(R3.D3.Shape.prototype); +R3.D3.Shape.TriMesh.prototype.constructor = R3.D3.Shape.TriMesh; + +/** + * Create instance + * @returns {R3.D3.Shape.TriMesh} + */ +R3.D3.Shape.TriMesh.prototype.createInstance = function() { + + this.instance = new CANNON.TriMesh( + this.vertices, + this.indices + ); + + R3.D3.Shape.prototype.createInstance.call(this); + +}; + +/** + * Update instance + */ +R3.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(); +}; \ No newline at end of file diff --git a/src/r3-d3-skeleton.js b/src/r3-d3-skeleton.js new file mode 100644 index 0000000..b919bfd --- /dev/null +++ b/src/r3-d3-skeleton.js @@ -0,0 +1,234 @@ +/** + * Skeleton Superset + * @constructor + * @param graphics R3.Runtime.Graphics + * @param apiSkeleton R3.D3.API.Skeleton + */ +R3.D3.Skeleton = function Skeleton( + graphics, + apiSkeleton +) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiSkeleton)) { + apiSkeleton = {}; + } + + R3.D3.API.Skeleton.call( + this, + apiSkeleton.id, + apiSkeleton.name, + apiSkeleton.bones, + apiSkeleton.boneInverses, + apiSkeleton.useVertexTexture, + apiSkeleton.boneTextureWidth, + apiSkeleton.boneTextureHeight, + apiSkeleton.boneMatrices, + apiSkeleton.boneTexture, + apiSkeleton.parent + ); + + + this.bones = this.bones.map( + function(apiBone) { + + if ( + R3.Utils.Defined(apiBone.componentType) && + !(apiBone instanceof R3.D3.Bone) + ) { + return R3.Component.ConstructFromObject(apiBone); + } + + }.bind(this) + ); + + this.boneInverses = this.boneInverses.map( + function(boneInverse) { + + if (boneInverse instanceof R3.API.Matrix4) { + return new R3.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 R3.API.Matrix4) { + return new R3.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) + ); + + R3.Component.call( + this, + { + 'bones' : [R3.D3.Bone] + } + ); +}; + +R3.D3.Skeleton.prototype = Object.create(R3.Component.prototype); +R3.D3.Skeleton.prototype.constructor = R3.D3.Skeleton; + + +/** + * Creates an instance skeleton + * @param update boolean + */ +R3.D3.Skeleton.prototype.createInstance = function(update) { + + var boneInstances = this.bones.map ( + function(bone) { + + if (R3.Utils.UndefinedOrNull(bone)) { + throw new Error('no bone'); + } + + if (R3.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 (R3.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(); + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance + */ +R3.D3.Skeleton.prototype.updateInstance = function(property) { + __UPDATE_INSTANCE__; +}; + +/** + * Converts a R3.D3.Skeleton to R3.D3.API.Skeleton + * @returns {R3.D3.API.Skeleton} + */ +R3.D3.Skeleton.prototype.toApiObject = function() { + + var apiSkeleton = new R3.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, + R3.Utils.IdOrNull(this.parent) + ); + + return apiSkeleton; +}; + +/** + * Returns a R3.D3.Skeleton from a skeleton Object + * @param graphics R3.Runtime.Graphics + * @param objectSkeleton Object + * @returns {R3.D3.Skeleton} + * @constructor + */ +R3.D3.Skeleton.FromObject = function( + graphics, + objectSkeleton +) { + + if (!objectSkeleton) { + return null; + } + + var apiSkeleton = R3.D3.API.Skeleton.FromObject(objectSkeleton); + + var skeleton = new R3.D3.Skeleton( + graphics, + apiSkeleton + ); + + return skeleton; +}; \ No newline at end of file diff --git a/src/r3-d3-solver.js b/src/r3-d3-solver.js new file mode 100644 index 0000000..a9097e7 --- /dev/null +++ b/src/r3-d3-solver.js @@ -0,0 +1,111 @@ +/** + * Solver Runtime + * @param physics R3.Runtime.Graphics + * @param apiSolver R3.D3.API.Solver + * @constructor + */ +R3.D3.Solver = function( + physics, + apiSolver +) { + + this.physics = physics; + this.physics.isNotCannonThrow(); + + if (R3.Utils.UndefinedOrNull(apiSolver)) { + apiSolver = {}; + } + + R3.D3.API.Solver.call( + this, + apiSolver.id, + apiSolver.name, + apiSolver.solverType, + apiSolver.iterations, + apiSolver.tolerance, + apiSolver.parent + ); + + R3.Component.call(this); +}; + +R3.D3.Solver.prototype = Object.create(R3.Component.prototype); +R3.D3.Solver.prototype.constructor = R3.D3.Solver; + +/** + * + * @returns {*} + */ +R3.D3.Solver.prototype.createInstance = function() { + + if (this.solverType === R3.D3.API.Solver.GS_SOLVER) { + this.instance = new CANNON.GSSolver(); + } else if (this.solverType === R3.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; + + __CREATE_INSTANCE__; +}; + +/** + * + */ +R3.D3.Solver.prototype.updateInstance = function(property) { + + if (this.solverType === R3.D3.API.Solver.GS_SOLVER) { + if (!(this.instance instanceof CANNON.GSSolver)) { + this.instance = new CANNON.GSSolver(); + } + } + + if (this.solverType === R3.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; + + __UPDATE_INSTANCE__; +}; + +/** + * R3.D3.Solver to R3.D3.API.Solver + * @returns {R3.D3.API.Solver} + */ +R3.D3.Solver.prototype.toApiObject = function() { + + var apiSolver = new R3.D3.API.Solver( + this.id, + this.name, + this.solverType, + this.iterations, + this.tolerance, + R3.Utils.IdOrNull(this.parent) + ); + + return apiSolver; +}; + +/** + * R3.D3.Solver from Object Solver + * @param graphics + * @param objectComponent + * @returns {R3.D3.Solver} + * @constructor + */ +R3.D3.Solver.FromObject = function(graphics, objectComponent) { + + var apiSolver = R3.D3.API.Solver.FromObject(objectComponent); + + return new R3.D3.Solver( + graphics, + apiSolver + ); +}; diff --git a/src/r3-d3-spline.js b/src/r3-d3-spline.js new file mode 100644 index 0000000..d22c167 --- /dev/null +++ b/src/r3-d3-spline.js @@ -0,0 +1,143 @@ +/** + * Spline constructor + * @param graphics R3.Runtime.Graphics + * @param apiSpline R3.D3.API.Spline + * @constructor + */ +R3.D3.Spline = function( + graphics, + apiSpline +) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiSpline)) { + apiSpline = {}; + } + + R3.D3.API.Spline.call( + this, + apiSpline.id, + apiSpline.name, + apiSpline.vertices, + apiSpline.parent + ); + + this.vertices = this.vertices.map( + function(vertex) { + return new R3.Vector3( + graphics, + vertex, + this + ) + } + ); + + R3.Component.call(this); +}; + +R3.D3.Spline.prototype = Object.create(R3.Component.prototype); +R3.D3.Spline.prototype.constructor = R3.D3.Spline; + +/** + * Creates an instance spline + */ +R3.D3.Spline.prototype.createInstance = function() { + + var vertices = this.vertices.map( + function(vertex) { + + if (R3.Utils.UndefinedOrNull(vertex)) { + throw new Error('no vertex') + } + + if (R3.Utils.UndefinedOrNull(vertex.instance)) { + throw new Error('no vertex instance') + } + + return vertex.instance; + } + ); + + this.instance = THREE.CatmullRomCurve3(vertices); + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance + */ +R3.D3.Spline.prototype.updateInstance = function(property) { + + var vertices = this.vertices.map( + function(vertex) { + + if (R3.Utils.UndefinedOrNull(vertex)) { + throw new Error('no vertex') + } + + if (R3.Utils.UndefinedOrNull(vertex.instance)) { + throw new Error('no vertex instance') + } + + return vertex.instance; + } + ); + + this.instance = new THREE.CatmullRomCurve3(vertices); + + __UPDATE_INSTANCE__; +}; + +/** + * Converts a R3.D3.Spline to R3.D3.API.Spline + * @returns {R3.D3.API.Spline} + */ +R3.D3.Spline.prototype.toApiObject = function() { + + return new R3.D3.API.Spline( + this.id, + this.name, + this.vertices.map( + function(vertex) { + return vertex.toApiObject() + } + ), + R3.Utils.IdOrNull(this.parent) + ); + +}; + +/** + * Returns a R3.D3.Spline from a spline Object + * @param graphics R3.Runtime.Graphics + * @param objectComponent Object + * @returns {R3.D3.Spline} + * @constructor + */ +R3.D3.Spline.FromObject = function( + graphics, + objectComponent +) { + var apiSpline = R3.D3.API.Spline.FromObject(objectComponent); + + return new R3.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 {*} + */ +R3.D3.Spline.prototype.getPointAt = function(proper) { + var point = this.instance.getPointAt(proper); + return new R3.Vector3( + this.graphics, + new R3.API.Vector3(point.x, point.y, point.z), + this, + 0.1 + ); +}; diff --git a/src/r3-d3-text.js b/src/r3-d3-text.js new file mode 100644 index 0000000..da085cb --- /dev/null +++ b/src/r3-d3-text.js @@ -0,0 +1,116 @@ +/** + * Text object + * @param graphics + * @param apiText + * @returns {R3.D3.Text} + * @constructor + */ +R3.D3.Text = function( + graphics, + apiText +) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiText)) { + apiText = {}; + } + + R3.D3.API.Text.call( + this, + apiText.id, + apiText.name, + apiText.offset, + apiText.font, + apiText.fillStyle, + apiText.value, + apiText.parentCanvas, + apiText.parent + ); + + this.offset = new R3.Vector2( + this.graphics, + this.offset, + this + ); + + R3.Component.call(this); +}; + +R3.D3.Text.prototype = Object.create(R3.Component.prototype); +R3.D3.Text.prototype.constructor = R3.D3.Text; + +/** + * Creates a light instance + * @returns {*} + */ +R3.D3.Text.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Text.prototype.updateInstance = function(property) { + + if (R3.Utils.UndefinedOrNull(property)) { + console.warn('unknown property update for Text: ' + property); + } + + if ( + property === 'offset' || + property === 'font' || + property === 'fillStyle' || + property === 'value' + ) { + if (!this.parentCanvas) { + console.warn('no parent canvas set'); + return; + } + + this.parentCanvas.updateInstance('texts'); + } + + if (property === 'parentCanvas') { + + R3.EntityManager.Instance.queryComponents(R3.Component.CANVAS).map( + function(canvas) { + + var index = canvas.texts.indexOf(this); + + if (index !== -1) { + canvas.texts.splice(index, 1); + canvas.texts.updateInstance('texts'); + } + }.bind(this) + ); + + if (this.parentCanvas) { + R3.Utils.PushUnique(this.parentCanvas.texts, this); + this.parentCanvas.updateInstance('texts'); + } + } + + __UPDATE_INSTANCE__; + +}; + +/** + * Converts a R3.D3.Text to a R3.D3.API.Text + * @returns {R3.D3.API.Text} + */ +R3.D3.Text.prototype.toApiObject = function() { + return new R3.D3.API.Text( + this.id, + this.name, + this.offset.toApiObject(), + this.font, + this.fillStyle, + this.value, + R3.Utils.IdOrNull(this.parentCanvas), + R3.Utils.IdOrNull(this.parent) + ); +}; \ No newline at end of file diff --git a/src/r3-d3-texture-0.js b/src/r3-d3-texture-0.js new file mode 100644 index 0000000..07cfe4b --- /dev/null +++ b/src/r3-d3-texture-0.js @@ -0,0 +1,387 @@ +/** + * Texture Superset - The apiTexture properties get moved into the Texture object itself, and then the instance is + * created + * @param apiTexture + * @param graphics R3.Runtime.Graphics + * @param overrideInstance + * @property textureType + * @constructor + */ +R3.D3.Texture = function( + graphics, + apiTexture, + overrideInstance +) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(overrideInstance)) { + overrideInstance = null; + } + this.overrideInstance = overrideInstance; + + if (R3.Utils.UndefinedOrNull(apiTexture)) { + apiTexture = { + textureType : R3.D3.API.Texture.TEXTURE_TYPE_NONE + }; + } + + R3.D3.API.Texture.call( + this, + apiTexture.id, + apiTexture.name, + apiTexture.textureType, + apiTexture.parent, + apiTexture.parentMaterials, + apiTexture.mipmaps, + apiTexture.mapping, + apiTexture.wrapS, + apiTexture.wrapT, + apiTexture.magFilter, + apiTexture.minFilter, + apiTexture.anisotropy, + apiTexture.format, + apiTexture.storageType, + apiTexture.offset, + apiTexture.repeat, + apiTexture.rotation, + apiTexture.center, + apiTexture.matrixAutoUpdate, + apiTexture.generateMipMaps, + apiTexture.premultiplyAlpha, + apiTexture.flipY, + apiTexture.unpackAlignment, + apiTexture.encoding, + apiTexture.version, + apiTexture.animated, + apiTexture.reverseAnimation, + apiTexture.forward + ); + + this.offset = new R3.Vector2( + this.graphics, + this.offset, + this + ); + + this.repeat = new R3.Vector2( + this.graphics, + this.repeat, + this + ); + + this.center = new R3.Vector2( + this.graphics, + this.center, + this + ); + + var linkedComponents = {}; + + switch (apiTexture.textureType) { + case R3.D3.API.Texture.TEXTURE_TYPE_NONE : + break; + case R3.D3.API.Texture.TEXTURE_TYPE_IMAGE : + linkedComponents.image = R3.Image; + break; + case R3.D3.API.Texture.TEXTURE_TYPE_CUBE : + linkedComponents.images = [R3.Image]; + break; + case R3.D3.API.Texture.TEXTURE_TYPE_CANVAS : + linkedComponents.canvas = R3.Canvas; + break; + default : + throw new Error('Unhandled texture type : ' + this.textureType); + } + + R3.Component.call( + this, + linkedComponents + ); +}; + +R3.D3.Texture.prototype = Object.create(R3.Component.prototype); +R3.D3.Texture.prototype.constructor = R3.D3.Texture; + +/** + * Apply our settings to the instance (which are OK to be applied) + */ +R3.D3.Texture.prototype.applyToInstance = function() { + + this.instance.name = this.name; + this.instance.wrapS = this.wrapS; + this.instance.wrapT = this.wrapT; + this.instance.magFilter = this.magFilter; + this.instance.minFilter = this.minFilter; + this.instance.anisotropy = this.anisotropy; + 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.rotation = this.rotation; + this.instance.center.x = this.center.x; + this.instance.center.y = this.center.y; + this.instance.matrixAutoUpdate = this.matrixAutoUpdate; + this.instance.generateMipMaps = this.generateMipMaps; + this.instance.premultiplyAlpha = this.premultiplyAlpha; + this.instance.flipY = this.flipY; + + this.instance.needsUpdate = true; +}; + +/** + * Creates an instance of our texture object + * @returns {*} + */ +R3.D3.Texture.prototype.createInstance = function() { + + if (this.overrideInstance) { + + this.instance = this.overrideInstance; + this.updateFromInstance(); + + } else { + + if (R3.Utils.UndefinedOrNull(this.instance)) { + + /** + * We have no instance - create one + */ + this.instance = new THREE.Texture(); + } + } + + /** + * Some settings we copy from the instance + */ + this.mipmaps = this.instance.mipmaps; + this.mapping = this.instance.mapping; + this.encoding = this.instance.encoding; + this.format = this.instance.format; + this.storageType = this.instance.type; + this.unpackAlignment = this.instance.unpackAlignment; + this.version = this.instance.version; + + /** + * Others we apply to the instance + */ + this.applyToInstance(); + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Texture.prototype.updateInstance = function(property) { + + if (R3.Utils.UndefinedOrNull(this.instance)) { + console.warn('no texture instance'); + return; + } + + if (R3.Utils.UndefinedOrNull(property)) { + console.warn('no texture property'); + return; + } + + if (property === 'name') { + this.instance.name = this.name; + return; + } + + if (property === 'textureType') { + console.warn('todo: texture type change here'); + return; + } + + if (property === 'mipmaps') { + console.warn('todo: mipmaps change here'); + return; + } + + if (property === 'mapping') { + this.instance.mapping = this.mapping; + } + + if (property === 'wrapS') { + this.instance.wrapS = this.wrapS; + } + + if (property === 'wrapT') { + this.instance.wrapT = this.wrapT; + } + + if (property === 'magFilter') { + this.instance.magFilter = this.magFilter; + } + + if (property === 'minFilter') { + this.instance.minFilter = this.minFilter; + } + + if (property === 'anisotropy') { + this.instance.anisotropy = this.anisotropy; + } + + if (property === 'format') { + this.instance.format = this.format; + } + + if (property === 'storageType') { + this.instance.type = this.storageType; + } + + if (property === 'offset') { + this.instance.offset.x = this.offset.x; + this.instance.offset.y = this.offset.y; + return; + } + + if (property === 'repeat') { + this.instance.repeat.x = this.repeat.x; + this.instance.repeat.y = this.repeat.y; + return; + } + + if (property === 'rotation') { + this.instance.rotation = this.rotation; + return; + } + + if (property === 'center') { + this.instance.center.x = this.center.x; + this.instance.center.y = this.center.y; + return; + } + + if (property === 'matrixAutoUpdate') { + this.instance.matrixAutoUpdate = this.matrixAutoUpdate; + return; + } + + if (property === 'generateMipMaps') { + this.instance.generateMipMaps = this.generateMipMaps; + return; + } + + if (property === 'premultiplyAlpha') { + this.instance.premultiplyAlpha = this.premultiplyAlpha; + return; + } + + if (property === 'flipY') { + this.instance.flipY = this.flipY; + } + + if (property === 'unpackAlignment') { + this.instance.unpackAlignment = this.unpackAlignment; + } + + if (property === 'encoding') { + this.instance.encoding = this.encoding; + } + + if (property === 'version') { + console.warn('version is read-only'); + } + + if (property === 'animated') { + R3.Event.Emit( + R3.Event.TEXTURE_ANIMATED_CHANGE, + { + texture: this + } + ) + } + + if (property === 'needsUpdate') { + this.needsUpdate = false; + } + + /** + * So if you don't return earlier - the instance will re-compile its shader + * @type {boolean} + */ + this.instance.needsUpdate = true; + this.version = this.instance.version; + + __UPDATE_INSTANCE__; +}; + +/** + * Converts a R3.D3.Texture to a R3.D3.API.Texture + * @returns {R3.D3.API.Texture} + */ +R3.D3.Texture.prototype.toApiObject = function() { + + var apiTexture = new R3.D3.API.Texture( + this.id, + this.name, + this.textureType, + R3.Utils.IdOrNull(this.parent), + this.parentMaterials.map( + function(parentMaterial) { + return R3.Utils.IdOrNull(parentMaterial); + } + ), + this.mipmaps, + this.mapping, + this.wrapS, + this.wrapT, + this.magFilter, + this.minFilter, + this.anisotropy, + this.format, + this.storageType, + this.offset.toApiObject(), + this.repeat.toApiObject(), + this.rotation, + this.center.toApiObject(), + this.matrixAutoUpdate, + this.generateMipMaps, + this.premultiplyAlpha, + this.flipY, + this.unpackAlignment, + this.encoding, + this.version, + this.animated, + this.reverseAnimation, + this.forward + ); + + return apiTexture; +}; + +/** + * Updates R3.D3.Texture from instance + */ +R3.D3.Texture.prototype.updateFromInstance = function() { + this.name = this.instance.name; + this.mipmaps = this.instance.mipmaps; + this.mapping = this.instance.mapping; + this.wrapS = this.instance.wrapS; + this.wrapT = this.instance.wrapT; + this.magFilter = this.instance.magFilter; + this.minFilter = this.instance.minFilter; + this.anisotropy = this.instance.anisotropy; + this.format = this.instance.format; + this.storageType = this.instance.storageType; + this.offset.x = this.instance.offset.x; + this.offset.y = this.instance.offset.y; + this.repeat.x = this.instance.repeat.x; + this.repeat.y = this.instance.repeat.y; + this.rotation = this.instance.rotation; + this.center.x = this.instance.center.x; + this.center.y = this.instance.center.y; + this.matrixAutoUpdate = this.instance.matrixAutoUpdate; + this.generateMipMaps = this.instance.generateMipMaps; + this.premultiplyAlpha = this.instance.premultiplyAlpha; + this.flipY = this.instance.flipY; + this.unpackAlignment = this.instance.unpackAlignment; + this.encoding = this.instance.encoding; + this.version = this.instance.version; + this.animated = this.instance.animated; + this.reverseAnimation = this.instance.reverseAnimation; + this.forward = this.instance.forward; +}; \ No newline at end of file diff --git a/src/r3-d3-texture-canvas.js b/src/r3-d3-texture-canvas.js new file mode 100644 index 0000000..f320a22 --- /dev/null +++ b/src/r3-d3-texture-canvas.js @@ -0,0 +1,96 @@ +/** + * R3.D3.Texture.Canvas + * @param graphics + * @param apiTextureCanvas + * @constructor + */ +R3.D3.Texture.Canvas = function( + graphics, + apiTextureCanvas +) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiTextureCanvas)) { + apiTextureCanvas = { + textureType : R3.D3.API.Texture.TEXTURE_TYPE_CANVAS + }; + } + + R3.D3.API.Texture.Canvas.call( + this, + apiTextureCanvas, + apiTextureCanvas.canvas + ); + + if (this.canvas instanceof R3.API.Canvas) { + this.canvas = new R3.Canvas( + this.graphics, + this.canvas + ); + } + + R3.D3.Texture.call( + this, + this.graphics, + this + ); + +}; + +R3.D3.Texture.Canvas.prototype = Object.create(R3.D3.Texture.prototype); +R3.D3.Texture.Canvas.prototype.constructor = R3.D3.Texture.Canvas; + +/** + * Creates an instance of our texture object + * @returns {*} + */ +R3.D3.Texture.Canvas.prototype.createInstance = function() { + + if ( + R3.Utils.UndefinedOrNull(this.canvas) || + R3.Utils.UndefinedOrNull(this.canvas.instance) + ) { + console.warn('canvas not ready at time of texture create instance'); + return; + } + + this.canvas.parentTexture = this; + + this.instance = new THREE.Texture( + this.canvas.instance + ); + + R3.D3.Texture.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Texture.Canvas.prototype.updateInstance = function(property) { + + if (property === 'canvas') { + + this.createInstance(); + + return; + } + + R3.D3.Texture.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Texture.Canvas to a R3.D3.API.Texture.Canvas + * @returns {R3.D3.API.Texture.Canvas} + */ +R3.D3.Texture.Canvas.prototype.toApiObject = function() { + + var apiTexture = R3.D3.Texture.prototype.toApiObject.call(this); + + var apiTextureCanvas = new R3.D3.API.Texture.Canvas( + apiTexture, + R3.Utils.IdOrNull(this.canvas) + ); + + return apiTextureCanvas; +}; diff --git a/src/r3-d3-texture-cube.js b/src/r3-d3-texture-cube.js new file mode 100644 index 0000000..3956edc --- /dev/null +++ b/src/r3-d3-texture-cube.js @@ -0,0 +1,140 @@ +/** + * R3.D3.Texture.Cube + * @param graphics + * @param apiTextureCube + * @constructor + */ +R3.D3.Texture.Cube = function( + graphics, + apiTextureCube +) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiTextureCube)) { + apiTextureCube = { + textureType : R3.D3.API.Texture.TEXTURE_TYPE_CUBE + }; + } + + R3.D3.API.Texture.Cube.call( + this, + apiTextureCube, + apiTextureCube.images + ); + + this.images = this.images.map( + function(image) { + if (image instanceof R3.API.Image) { + return new R3.Image(image); + } else { + return image; + } + } + ); + + R3.D3.Texture.call( + this, + this.graphics, + this + ); + +}; + +R3.D3.Texture.Cube.prototype = Object.create(R3.D3.Texture.prototype); +R3.D3.Texture.Cube.prototype.constructor = R3.D3.Texture.Cube; + +/** + * Returns all image instances, or null if one of the images are not loaded + */ +R3.D3.Texture.Cube.prototype.getImageInstances = function() { + + return this.images.reduce( + function(result, image) { + + /** + * If we have a null result return early + */ + + if (result === null) { + return result; + } + + if (R3.Utils.UndefinedOrNull(image.instance)) { + result = null; + } else { + result.push(image.instance); + } + + return result; + + }, + [] + ); +}; + +/** + * Creates an instance of our texture object + * @returns {*} + */ +R3.D3.Texture.Cube.prototype.createInstance = function() { + + var imageInstances = this.getImageInstances(); + + if (!imageInstances) { + console.warn('cube texture not ready'); + return; + } + + this.instance = new THREE.CubeTexture(imageInstances); + + R3.D3.Texture.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Texture.Cube.prototype.updateInstance = function(property) { + + if (property === 'images') { + + + var imageInstances = this.getImageInstances(); + + if (imageInstances) { + console.log('updating cube texture image instances'); + this.image = imageInstances; + } + + this.emit( + R3.Event.TEXTURE_INSTANCE_UPDATED, + { + texture : this + } + ); + + return; + } + + R3.D3.Texture.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Texture.Cube to a R3.D3.API.Texture.Cube + * @returns {R3.D3.API.Texture.Cube} + */ +R3.D3.Texture.Cube.prototype.toApiObject = function() { + + var apiTexture = R3.D3.Texture.prototype.toApiObject.call(this); + + var apiTextureCube = new R3.D3.API.Texture.Cube( + apiTexture, + this.images.map( + function(image) { + return R3.Utils.IdOrNull(image); + } + ) + ); + + return apiTextureCube; +}; diff --git a/src/r3-d3-texture-image.js b/src/r3-d3-texture-image.js new file mode 100644 index 0000000..b950064 --- /dev/null +++ b/src/r3-d3-texture-image.js @@ -0,0 +1,138 @@ +/** + * R3.D3.Texture.Image + * @param graphics + * @param apiTextureImage + * @param overrideInstance - if we pass an instance to the constructor, we want to skip the construction of this texture + * @constructor + */ +R3.D3.Texture.Image = function( + graphics, + apiTextureImage, + overrideInstance +) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (R3.Utils.UndefinedOrNull(apiTextureImage)) { + apiTextureImage = { + textureType : R3.D3.API.Texture.TEXTURE_TYPE_IMAGE + }; + } + + if (R3.Utils.UndefinedOrNull(overrideInstance)) { + overrideInstance = null; + } + this.overrideInstance = overrideInstance; + + R3.D3.API.Texture.Image.call( + this, + apiTextureImage, + apiTextureImage.image + ); + + if (this.image instanceof R3.API.Image) { + this.image = new R3.Image( + this.image + ); + } + + R3.D3.Texture.call( + this, + this.graphics, + this + ); + +}; + +R3.D3.Texture.Image.prototype = Object.create(R3.D3.Texture.prototype); +R3.D3.Texture.Image.prototype.constructor = R3.D3.Texture.Image; + +/** + * Creates an instance of our texture object + * @returns {*} + */ +R3.D3.Texture.Image.prototype.createInstance = function() { + + if ( + R3.Utils.UndefinedOrNull(this.image) || + R3.Utils.UndefinedOrNull(this.image.instance) + ) { + console.warn('image not ready at time of texture create instance'); + return; + } + + /** + * At this point - our image object exists + */ + + if (this.overrideInstance) { + + this.instance = this.overrideInstance; + this.updateFromInstance(); + + } else { + + this.instance = new THREE.Texture( + this.image.instance + ); + + } + + R3.D3.Texture.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.D3.Texture.Image.prototype.updateInstance = function(property) { + + if (property === 'image') { + + if (this.image && this.image.instance) { + this.instance.image = this.image.instance; + this.instance.needsUpdate = true; + } + + this.emit( + R3.Event.TEXTURE_INSTANCE_UPDATED, + { + texture : this + } + ); + + return; + } + + R3.D3.Texture.prototype.updateInstance.call(this, property); +}; + +/** + * Converts a R3.D3.Texture.Image to a R3.D3.API.Texture.Image + * @returns {R3.D3.API.Texture.Image} + */ +R3.D3.Texture.Image.prototype.toApiObject = function() { + + var apiTexture = R3.D3.Texture.prototype.toApiObject.call(this); + + var apiTextureImage = new R3.D3.API.Texture.Image( + apiTexture, + R3.Utils.IdOrNull(this.image) + ); + + return apiTextureImage; +}; + +/** + * Updates R3.D3.Texture.Image from instance + */ +R3.D3.Texture.Image.prototype.updateFromInstance = function() { + + this.image.instance = this.instance.image; + + if (this.image.instance) { + this.image.updateFromInstance(); + } + + R3.D3.Texture.prototype.updateFromInstance.call(this); + +}; \ No newline at end of file diff --git a/src/r3-d3-vertex.js b/src/r3-d3-vertex.js new file mode 100644 index 0000000..d336d55 --- /dev/null +++ b/src/r3-d3-vertex.js @@ -0,0 +1,39 @@ +/** + * R3.D3.Vertex + * @param apiComponent + * @constructor + */ +R3.D3.Vertex = function Vertex( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Vertex.prototype = Object.create(R3.Component.prototype); +R3.D3.Vertex.prototype.constructor = R3.D3.Vertex; + +R3.D3.Vertex.prototype.createInstance = function() { + + __CREATE_INSTANCE__; + +}; + +R3.D3.Vertex.prototype.updateInstance = function(property) { + + if (property === 'position') { + this.parent.updatePositions(); + return; + } + + if (property === 'normal') { + this.parent.updateNormals(); + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-d3-viewport-0.js b/src/r3-d3-viewport-0.js new file mode 100644 index 0000000..f8d5973 --- /dev/null +++ b/src/r3-d3-viewport-0.js @@ -0,0 +1,49 @@ +/** + * R3.D3.Viewport + * @param inherited + * @constructor + */ +R3.D3.Viewport = function( + inherited +) { + + __INHERIT_ONLY__; + + this.linkedComponents.scenes = [R3.D3.Scene]; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.D3.Viewport.prototype = Object.create(R3.Component.prototype); +R3.D3.Viewport.prototype.constructor = R3.D3.Viewport; + +/** + * R3.D3.Viewport.prototype.updateInstance + * @param property + */ +R3.D3.Viewport.prototype.updateInstance = function(property) { + + if (property === 'x') { + this.instance.x = this.x; + return; + } + + if (property === 'y') { + this.instance.y = this.y; + return; + } + + if (property === 'width') { + this.instance.z = this.z; + return; + } + + if (property === 'height') { + this.instance.w = this.w; + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-d3-viewport-fixedAspect-0.js b/src/r3-d3-viewport-fixedAspect-0.js new file mode 100644 index 0000000..f531e6a --- /dev/null +++ b/src/r3-d3-viewport-fixedAspect-0.js @@ -0,0 +1,224 @@ +/** + * R3.D3.Viewport.FixedAspect + * + * Respect the aspectRatio setting and adjust viewport x,y,width and height accordingly + * - entire viewport remains visible at all times + * - will have empty space above or below viewport depending on canvas size (if canvas ratio != viewport ratio) + * - is centered around center of canvas + * + * @param apiComponent + */ +R3.D3.Viewport.FixedAspect = function( + apiComponent, + inherited +) { + + __INHERIT_AND_INSTANTIATE__; + + R3.D3.Viewport.call( + this, + true + ) + +}; + +R3.D3.Viewport.FixedAspect.prototype = Object.create(R3.D3.Viewport.prototype); +R3.D3.Viewport.FixedAspect.prototype.constructor = R3.D3.Viewport.FixedAspect; + + +R3.D3.Viewport.FixedAspect.prototype.createInstance = function() { + + /** + * We have a dependency on our parent which could still need to call 'createInstance' + */ + + // if (typeof this.parent === 'string') { + // + // if (R3.Utils.UndefinedOrNull(this.instanceLoaded)) { + // + // this.instanceLoaded = R3.Event.Subscribe( + // R3.Event.INSTANCE_LOADED, + // function (data) { + // if (data.component.id === this.parent) { + // this.parent = data.component; + // this.createInstance(); + // this.instanceLoaded.remove(); + // } + // }.bind(this) + // ); + // + // } + // + // return; + // } + + this.calculateDimensions(); + + this.instance = this.graphics.Vector4( + this.x, + this.y, + this.width, + this.height + ); + + __CREATE_INSTANCE__; +}; + +R3.D3.Viewport.FixedAspect.prototype.updateInstance = function(property) { + + /** + * Viewports don't have an explicit size, but calling updateInstance with 'size' property will update its dimensions + */ + if ( + property === 'aspectRatio' || + property === 'size' + ) { + this.calculateDimensions(); + this.instance.x = this.x; + this.instance.y = this.y; + this.instance.z = this.width; + this.instance.w = this.height; + return; + } + + R3.D3.Viewport.prototype.updateInstance.call(this, property); + +}; + +/** + * This calculates the dimensions of the viewport based on the following example info: + * + * aspect = width + * ------ + * height + * + * width = aspect * height; + * height = width / aspect; + * + * aspect > 1 (width > height) (landscape) + * aspect < 1 (height > width) (portrait) + * + * 4 / 3 = 1.33333 (1920 x 1440) + * 16 / 9 = 1.77777 (1920 x 1080) + * + * w h w h + * 9 / 16 = 0.5625 (1080 x 1920) - required + * 3 / 4 = 0.75 (1440 x 1920) - current + * + * @returns {{left: number, right: number, top: number, bottom: number}} + */ +R3.D3.Viewport.FixedAspect.prototype.calculateDimensions = function() { + + var canvasSize = this.parent.getCanvasSize(); + + var canvasAspectRatio = canvasSize.aspectRatio; + + if (canvasAspectRatio > 1) { + + /** + * Width is greater than height (landscape) + */ + + if (this.aspectRatio < 1) { + + /** + * The required aspect ratio is portrait mode - use the full Height of the canvas + */ + this.width = this.aspectRatio * canvasSize.height; + this.height = canvasSize.height; + + } else { + + /** + * The required aspect is also more wide than high - so we have another two possibilities: + * a) The required aspect is greater than the current aspect - this means the required aspect is less high + * than the current aspect - we can use the full width + * + * b) The required aspect is less than the current aspect - this means the required aspect is higher than + * the current aspect - we need to determine a new width based on the current height + */ + + if (this.aspectRatio > canvasAspectRatio) { + /** + * a) + */ + this.width = canvasSize.width; + this.height = canvasSize.width / this.aspectRatio; + + } else { + /** + * b) + */ + this.height = canvasSize.height; + this.width = this.aspectRatio * canvasSize.height; + } + + } + + } else { + + /** + * Width is less than height (portrait) + */ + + if (this.aspectRatio > 1) { + + /** + * The required aspect is landscape in a portrait mode - but we are in landscape - use the full width and + * calculate the new height + */ + this.width = canvasSize.width; + this.height = canvasSize.width / this.aspectRatio; + + } else { + + /** + * The required aspect is also more high than wide (portrait) - we have again, two possibilities + * a) The required aspect is greater than the current aspect - this means the required aspect does not fit + * the full width of the current aspect - use the full width of the current size and determine a new height + * + * b) The required aspect is less than the current aspect - this means that the required aspect is less wide + * than the current aspect, so we can use the full height of the current size and determine a new width + */ + + if (this.aspectRatio > canvasAspectRatio) { + + /** + * a) + */ + this.width = canvasSize.width; + this.height = canvasSize.width / this.aspectRatio; + + } else { + + /** + * b) + */ + this.height = canvasSize.height; + this.width = canvasSize.height * this.aspectRatio; + } + } + } + + /** + * Clamp the values between 0 and 1 + */ + this.width = this.width / canvasSize.width; + this.height = this.height / canvasSize.height; + + /** + * Center the viewport + */ + if (this.height < 1) { + this.y = (1 - this.height) / 2; + } else { + this.y = 0; + } + + if (this.width < 1) { + this.x = (1 - this.width) / 2; + } else { + this.x = 0; + } + +}; \ No newline at end of file diff --git a/src/r3-d3-viewport-fixedAspect-vr.js b/src/r3-d3-viewport-fixedAspect-vr.js new file mode 100644 index 0000000..482e49e --- /dev/null +++ b/src/r3-d3-viewport-fixedAspect-vr.js @@ -0,0 +1,187 @@ +/** + * R3.D3.Viewport.FixedAspect.VR + * + * Respect the aspectRatio setting and adjust viewport x,y,width and height accordingly + * - entire viewport remains visible at all times + * - will have empty space above or below viewport depending on canvas size (if canvas ratio != viewport ratio) + * - is centered around center of canvas + * + * @param apiComponent + */ +R3.D3.Viewport.FixedAspect.VR = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Viewport.FixedAspect.call( + this, + apiComponent, + true + ) + +}; + +R3.D3.Viewport.FixedAspect.VR.prototype = Object.create(R3.D3.Viewport.FixedAspect.prototype); +R3.D3.Viewport.FixedAspect.VR.prototype.constructor = R3.D3.Viewport.FixedAspect.VR; + +R3.D3.Viewport.FixedAspect.VR.prototype.createInstance = function() { + + R3.D3.Viewport.FixedAspect.prototype.createInstance.call(this); +}; + +R3.D3.Viewport.FixedAspect.VR.prototype.updateInstance = function(property) { + + R3.D3.Viewport.FixedAspect.prototype.updateInstance.call(this, property); + +}; + +/** + * This calculates the dimensions of the viewport based on the following example info: + * + * aspect = width + * ------ + * height + * + * width = aspect * height; + * height = width / aspect; + * + * aspect > 1 (width > height) (landscape) + * aspect < 1 (height > width) (portrait) + * + * 4 / 3 = 1.33333 (1920 x 1440) + * 16 / 9 = 1.77777 (1920 x 1080) + * + * w h w h + * 9 / 16 = 0.5625 (1080 x 1920) - required + * 3 / 4 = 0.75 (1440 x 1920) - current + * + * @returns {{left: number, right: number, top: number, bottom: number}} + * + * At all times we have to half the width since this is only one half of the viewport + */ +R3.D3.Viewport.FixedAspect.VR.prototype.calculateDimensions = function() { + + var canvasSize = this.parent.getCanvasSize(); + + var newCanvasWidth = canvasSize.width / 2; + + var canvasAspectRatio = newCanvasWidth / canvasSize.height; + + if (canvasAspectRatio > 1) { + + /** + * Width is greater than height (landscape) + */ + + if (this.aspectRatio < 1) { + + /** + * The required aspect ratio is portrait mode - use the full Height of the canvas + */ + this.width = this.aspectRatio * canvasSize.height; + this.height = canvasSize.height; + + } else { + + /** + * The required aspect is also more wide than high - so we have another two possibilities: + * a) The required aspect is greater than the current aspect - this means the required aspect is less high + * than the current aspect - we can use the full width + * + * b) The required aspect is less than the current aspect - this means the required aspect is higher than + * the current aspect - we need to determine a new width based on the current height + */ + + if (this.aspectRatio > canvasAspectRatio) { + /** + * a) + */ + this.width = newCanvasWidth; + this.height = newCanvasWidth / this.aspectRatio; + + } else { + /** + * b) + */ + this.height = canvasSize.height; + this.width = this.aspectRatio * canvasSize.height; + } + + } + + } else { + + /** + * Width is less than height (portrait) + */ + + if (this.aspectRatio > 1) { + + /** + * The required aspect is landscape in a portrait mode - but we are in landscape - use the full width and + * calculate the new height + */ + this.width = newCanvasWidth; + this.height = newCanvasWidth / this.aspectRatio; + + } else { + + /** + * The required aspect is also more high than wide (portrait) - we have again, two possibilities + * a) The required aspect is greater than the current aspect - this means the required aspect does not fit + * the full width of the current aspect - use the full width of the current size and determine a new height + * + * b) The required aspect is less than the current aspect - this means that the required aspect is less wide + * than the current aspect, so we can use the full height of the current size and determine a new width + */ + + if (this.aspectRatio > canvasAspectRatio) { + + /** + * a) + */ + this.width = newCanvasWidth; + this.height = newCanvasWidth / this.aspectRatio; + + } else { + + /** + * b) + */ + this.height = canvasSize.height; + this.width = canvasSize.height * this.aspectRatio; + } + } + } + + /** + * Clamp the values between 0 and 1 + */ + this.width = this.width / canvasSize.width; + this.height = this.height / canvasSize.height; + + /** + * Center the viewport + */ + if (this.height < 1) { + this.y = (1 - this.height) / 2; + } else { + this.y = 0; + } + + if (this.width < 1) { + this.x = (1 - this.width) / 2; + } else { + this.x = 0; + } + + if (this.side === R3.D3.API.Viewport.FixedAspect.VR.VIEWPORT_RIGHT) { + this.x += this.width / 2; + } + + if (this.side === R3.D3.API.Viewport.FixedAspect.VR.VIEWPORT_LEFT) { + this.x -= this.width / 2; + } + +}; \ No newline at end of file diff --git a/src/r3-d3-viewport-zoomedAspect.js b/src/r3-d3-viewport-zoomedAspect.js new file mode 100644 index 0000000..f146608 --- /dev/null +++ b/src/r3-d3-viewport-zoomedAspect.js @@ -0,0 +1,45 @@ +/** + * R3.D3.Viewport.ZoomedAspect + * @param apiComponent + */ +R3.D3.Viewport.ZoomedAspect = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.D3.Viewport.call( + this, + true + ) + +}; + +R3.D3.Viewport.ZoomedAspect.prototype = Object.create(R3.D3.Viewport.prototype); +R3.D3.Viewport.ZoomedAspect.prototype.constructor = R3.D3.Viewport.ZoomedAspect; + +/** + * + * @returns {boolean} + */ +R3.D3.Viewport.ZoomedAspect.prototype.createInstance = function() { + + this.instance = this.graphics.Vector4( + this.x, + this.y, + this.width, + this.height + ); + + __CREATE_INSTANCE__; +}; + +/** + * + */ +R3.D3.Viewport.ZoomedAspect.prototype.updateInstance = function(property) { + + R3.D3.Viewport.prototype.updateInstance.call(this, property); + +}; + diff --git a/src/r3-domElement.js b/src/r3-domElement.js new file mode 100644 index 0000000..484a883 --- /dev/null +++ b/src/r3-domElement.js @@ -0,0 +1,93 @@ +/** + * R3.DomElement + * @param apiComponent + * @constructor + */ +R3.DomElement = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.fullscreen = false; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.DomElement.prototype = Object.create(R3.Component.prototype); +R3.DomElement.prototype.constructor = R3.DomElement; + +/** + * Creates an instance domElement + * @returns {*} + */ +R3.DomElement.prototype.createInstance = function() { + + this.instance = document.getElementById(this.domElementId); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates instance domElement + */ +R3.DomElement.prototype.updateInstance = function(property) { + + if (property === 'domElementId') { + this.createInstance() + } + + __UPDATE_INSTANCE__; + +}; + + +/** + * Appends domInstance to DOM instance + * @param domInstance + */ +R3.DomElement.prototype.append = function(domInstance) { + this.instance.appendChild(domInstance); +}; + +/** + * Clears DOM instance + */ +R3.DomElement.prototype.clear = function() { + this.instance.innerHTML = ''; +}; + + +R3.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; +}; + + +R3.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; +}; diff --git a/src/r3-drawRange.js b/src/r3-drawRange.js new file mode 100644 index 0000000..da54156 --- /dev/null +++ b/src/r3-drawRange.js @@ -0,0 +1,53 @@ +/** + * R3.DrawRange + * @param apiComponent + * @constructor + */ +R3.DrawRange = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.DrawRange.prototype = Object.create(R3.Component.prototype); +R3.DrawRange.prototype.constructor = R3.DrawRange; + +/** + * Creates an instance R3.DrawRange + * @returns {*} + */ +R3.DrawRange.prototype.createInstance = function() { + + this.instance = { + start : this.start, + count : this.count + }; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates R3.DrawRange instance + * @param property + */ +R3.DrawRange.prototype.updateInstance = function(property) { + + console.warn('update the geometry instead'); + + if (property === 'start') { + console.warn('todo: update start'); + return; + } + + if (property === 'count') { + console.warn('todo: update count'); + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-entity.js b/src/r3-entity.js new file mode 100644 index 0000000..1967464 --- /dev/null +++ b/src/r3-entity.js @@ -0,0 +1,56 @@ +/** + * R3.Entity + * @param apiComponent + * @constructor + */ +R3.Entity = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.linkedComponents = [R3.Component]; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.Entity.prototype = Object.create(R3.Component.prototype); +R3.Entity.prototype.constructor = R3.Entity; + +R3.Entity.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; +}; + +R3.Entity.prototype.updateInstance = function(property) { + + if (property === 'components') { + + console.log('todo: entity components change'); + + return; + } + + __UPDATE_INSTANCE__; + +}; + +/** + * Returns all components of type 'constructor' - slower than queryComponents + * @param constructor + */ +R3.Entity.prototype.findComponentsByConstructor = function(constructor) { + + return this.components.reduce( + function(result, component) { + if (component instanceof constructor) { + result.push(component); + } + return result; + }, + [] + ); + +}; diff --git a/src/r3-entityManager.js b/src/r3-entityManager.js new file mode 100644 index 0000000..4d67201 --- /dev/null +++ b/src/r3-entityManager.js @@ -0,0 +1,429 @@ +/** + * R3.EntityManager + * @param apiComponent + * @constructor + */ +R3.EntityManager = function( + apiComponent +) { + /** + * 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 = {}; + + this.defaultEntity = null; + + this.instanceDisposal = []; + + R3.Event.Subscribe( + R3.Event.REMOVE_COMPONENT, + this.removeComponent.bind(this) + ); + + R3.Event.Subscribe( + R3.Event.INSTANCE_DISPOSAL, + this.removeInstances.bind(this) + ); + + R3.Event.Subscribe( + R3.Event.REGISTER_COMPONENT, + this.registerComponent.bind(this) + ) + + // R3.Event.Subscribe( + // R3.Event.ENTITY_LOADED, + // this.entityLoaded.bind(this) + // ); + + +}; + +R3.EntityManager.prototype.registerComponent = function(component) { + + /** + * Register this component in the componentType to component register + */ + if (R3.Utils.UndefinedOrNull(this.register[component.componentType])) { + this.register[component.componentType] = {}; + } + + this.register[component.componentType][component.id] = component; + + /** + * Register this component in the id to component register + */ + if (R3.Utils.UndefinedOrNull(this.idRegister[component.id])) { + this.idRegister[component.id] = component; + } + + /** + * If this component has a parent - link it right away + */ + if (typeof component.parent === 'string') { + + if (R3.Utils.UndefinedOrNull(this.idRegister[component.parent])) { + throw new Error('A component links to a parent which has not been registered yet'); + } + + component.parent = this.idRegister[component.parent]; + + } + +}; + +/** + * Removes the component from both registries (the component type to component register, and the component ID to + * component register) + * @param data + */ +R3.EntityManager.prototype.removeComponent = function(data) { + + /** + * Sanity Check 1 + */ + if (R3.Utils.UndefinedOrNull(this.register[data.component.componentType]) || + R3.Utils.UndefinedOrNull(this.register[data.component.componentType][data.component.id]) + ) { + throw new Error('EntityManager register out of sync'); + } + + /** + * Delete the component from the componentType to Component register + */ + delete this.register[data.component.componentType][data.component.id]; + if (R3.Utils.IsEmpty(this.register[data.component.componentType])) { + delete this.register[data.component.componentType]; + } + + /** + * Sanity Check 2 + */ + if (R3.Utils.UndefinedOrNull(this.idRegister[data.component.id])){ + throw new Error('EntityManager idRegister out of sync'); + } + + /** + * Delete the component from the ID to Component register + */ + delete this.idRegister[data.component.id]; + + /** + * Now we have to be quite careful - we only have one copy left of this component - the one in data.component. + * we need a handle on all instances in this object. We need to store them to allow the 'REMOVE_COMPONENT' event + * to finish getting handled, then we need to dispose of the instance themselves. + * This gives our systems and other objects a chance to cleanly stop relying on these components at which point + * we can safely clean up our instances. + */ + + var component = data.component; + + for (var property in component) { + + if (property === 'parent') { + continue; + } + + if (component.hasOwnProperty(property)) { + if (component[property] instanceof R3.Component) { + R3.Utils.PushUnique(this.instanceDisposal, component[property].instance); + } + } + } + +}; + +R3.EntityManager.prototype.removeInstances = function(data) { + + this.instanceDisposal = this.instanceDisposal.reduce( + function(result, instance) { + if ( + R3.Utils.Defined(instance.dispose) && + typeof instance.dispose === 'function' + ) { + instance.dispose(); + } + + if (instance instanceof HTMLElement) { + instance.parentElement.removeChild(instance); + } + + return result; + }, + [] + ); + +}; + +// R3.EntityManager.prototype.entityLoaded = function(data) { +// this.defaultEntity = data.entity; +// }; + +// R3.EntityManager.prototype.registerComponent = function(data) { +// +// // var updated = false; +// +// if (R3.Utils.UndefinedOrNull(this.register[data.component.componentType])) { +// this.register[data.component.componentType] = {}; +// // R3.Event.Emit( +// // R3.Event.COMPONENT_TYPES_UPDATE, +// // { +// // componentType : data.component.componentType, +// // componentTypes : Object.keys(this.register) +// // } +// // ); +// // updated = true; +// } +// +// if (R3.Utils.UndefinedOrNull(this.register[data.component.componentType][data.component.id])) { +// this.register[data.component.componentType][data.component.id] = data.component; +// // updated = true; +// } +// +// if (R3.Utils.UndefinedOrNull(this.idRegister[data.component.id])) { +// this.idRegister[data.component.id] = data.component; +// // updated = true; +// } +// +// // if (updated) { +// // R3.Event.Emit( +// // R3.Event.REGISTER_UPDATE, +// // { +// // componentType : data.component.componentType, +// // components : this.register[data.component.componentType], +// // idRegister : this.idRegister, +// // register : this.register +// // } +// // ); +// // } +// }; + + +/** + * Returns an entity by ID or null + * @param id + * @returns {*} + */ +R3.EntityManager.prototype.findEntityById = function(id) { + + var entity = this.register[R3.Component.ENTITY][id]; + + if (entity) { + return entity; + } + + return null; +}; + +R3.EntityManager.prototype.findComponentById = function(id) { + return this.idRegister[id]; +}; + +R3.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 + ); + +}; + +R3.EntityManager.prototype.findHelperByObject = function(object) { + + if (typeof this.register[R3.Component.HELPER] === 'undefined') { + return null; + } + + return Object.keys(this.register[R3.Component.HELPER]).reduce( + function(result, helperId) { + + if (this.register[R3.Component.HELPER][helperId].object === object) { + result = this.register[R3.Component.HELPER][helperId]; + } + + return result; + }.bind(this), + null + ); + +}; + +R3.EntityManager.prototype.findSceneByObject = function(object) { + + return Object.keys(this.register[R3.Component.SCENE]).reduce( + function(result, sceneId) { + + if ( + this.register[R3.Component.SCENE][sceneId].meshes.indexOf(object) !== -1 || + this.register[R3.Component.SCENE][sceneId].lights.indexOf(object) !== -1 + ) { + result = this.register[R3.Component.SCENE][sceneId]; + } + + return result; + }.bind(this), + null + ); + +}; + + +/** + * Adds an entity to this manager + * @param entity R3.Entity + */ +R3.EntityManager.prototype.addEntity = function(entity) { + this.entities.push(entity); +}; + +/** + * Returns entity by name + * @param name + * @returns {*} + */ +R3.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 R3.D3.Entity + * @returns boolean true if successful + */ +R3.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); + + return true; +}; + +/** + * Returns all the entities with the following components + * @param components R3.Component[] + */ +// R3.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; +// }; + +R3.EntityManager.prototype.findComponentsByType = function(componentTypes) { + return R3.EntityManager.prototype.queryComponents.call(this, componentTypes); +}; + +/** + * Returns all actual components of all entities that contain this component + * More efficient + * @param componentTypes (array of component types or a single component type) + */ +R3.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 {*} + */ +R3.EntityManager.prototype.findComponentsByConstructor = 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), + [] + ); +}; diff --git a/src/r3-font.js b/src/r3-font.js new file mode 100644 index 0000000..85f5992 --- /dev/null +++ b/src/r3-font.js @@ -0,0 +1,62 @@ +/** + * R3.Font + * @param apiComponent + * @constructor + */ +R3.Font = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Font.prototype = Object.create(R3.Component.prototype); +R3.Font.prototype.constructor = R3.Font; + +/** + * Creates a light instance + * @returns {*} + */ +R3.Font.prototype.createInstance = function() { + + R3.Event.Emit( + R3.Event.LOAD_FONT, + { + font : this + }, + function(fontInstance) { + + this.instance = fontInstance; + + console.log('font instance loaded'); + + __CREATE_INSTANCE__; + + }.bind(this), + function(error) { + + console.error(error); + + this.instance = null; + + __CREATE_INSTANCE__; + + }.bind(this) + ); + +}; + +/** + * Updates the instance with the current state + */ +R3.Font.prototype.updateInstance = function(property) { + + if (property === 'path') { + this.createInstance(); + } + + __UPDATE_INSTANCE__; +}; diff --git a/src/r3-graph-0.js b/src/r3-graph-0.js new file mode 100644 index 0000000..465c8d2 --- /dev/null +++ b/src/r3-graph-0.js @@ -0,0 +1,32 @@ +/** + * R3.Graph + * @param inherited + * @constructor + */ +R3.Graph = function( + inherited +) { + + __INHERIT_ONLY__ + + this.linkedComponents.query = R3.Query; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Graph.prototype = Object.create(R3.Component.prototype); +R3.Graph.prototype.constructor = R3.Graph; + +/** + * Updates the instance with the current state + */ +R3.Graph.prototype.updateInstance = function(property) { + + if (property === 'domElement') { + console.warn('todo: update graph domElement'); + return; + } + + __UPDATE_INSTANCE__; +}; diff --git a/src/r3-graph-barchart-0.js b/src/r3-graph-barchart-0.js new file mode 100644 index 0000000..6d38a91 --- /dev/null +++ b/src/r3-graph-barchart-0.js @@ -0,0 +1,44 @@ +/** + * R3.Graph.Barchart + * @param apiComponent + * @param inherited + * @constructor + */ +R3.Graph.Barchart = function( + apiComponent, + inherited +) { + + __INHERIT_AND_INSTANTIATE__ + + this.linkedComponents.domElement = R3.DomElement; + + R3.Graph.call( + this, + true + ); + +}; + +R3.Graph.Barchart.prototype = Object.create(R3.Graph.prototype); +R3.Graph.Barchart.prototype.constructor = R3.Graph.Barchart; + +/** + * Updates the instance with the current state + */ +R3.Graph.Barchart.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Graph.Barchart.prototype.updateInstance = function(property) { + + R3.Graph.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-graph-barchart-stacked.js b/src/r3-graph-barchart-stacked.js new file mode 100644 index 0000000..989ef76 --- /dev/null +++ b/src/r3-graph-barchart-stacked.js @@ -0,0 +1,52 @@ +/** + * R3.Graph.Barchart.Stacked + * @param apiComponent + * @constructor + */ +R3.Graph.Barchart.Stacked = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.linkedComponents.domElement = R3.DomElement; + + R3.Graph.Barchart.call( + this, + apiComponent, + true + ); + +}; + +R3.Graph.Barchart.Stacked.prototype = Object.create(R3.Graph.Barchart.prototype); +R3.Graph.Barchart.Stacked.prototype.constructor = R3.Graph.Barchart.Stacked; + +/** + * Updates the instance with the current state + */ +R3.Graph.Barchart.Stacked.prototype.createInstance = function() { + + this.instance = this.graphics.BarchartStacked(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Graph.Barchart.Stacked.prototype.updateInstance = function(property) { + + if (property === 'query') { + this.chart.destroy(); + this.instance = this.graphics.BarchartStacked(this); + } + + if (property === 'size') { + this.chart.update(); + } + + R3.Graph.Barchart.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-graph-metric.js b/src/r3-graph-metric.js new file mode 100644 index 0000000..5bc1ca4 --- /dev/null +++ b/src/r3-graph-metric.js @@ -0,0 +1,61 @@ +/** + * R3.Graph.Metric + * @param apiComponent + * @constructor + */ +R3.Graph.Metric = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.linkedComponents.domElements = [R3.DomElement]; + + R3.Graph.call( + this, + true + ); + +}; + +R3.Graph.Metric.prototype = Object.create(R3.Graph.prototype); +R3.Graph.Metric.prototype.constructor = R3.Graph.Metric; + + +/** + * Updates the instance with the current state + */ +R3.Graph.Metric.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Graph.Metric.prototype.updateInstance = function(property) { + + if (property === 'query') { + + this.domElements.map( + function(domElement, index) { + + if (this.query instanceof R3.Query.Alerts.Summary) { + if (R3.Utils.UndefinedOrNull(this.query.priorities[index])) { + domElement.instance.innerHTML = 0; + } else { + domElement.instance.innerHTML = this.query.priorities[index]; + } + } + + }.bind(this) + ) + + } + + R3.Graph.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-graph-table.js b/src/r3-graph-table.js new file mode 100644 index 0000000..ff93142 --- /dev/null +++ b/src/r3-graph-table.js @@ -0,0 +1,50 @@ +/** + * R3.Graph.Table + * @param apiComponent + * @constructor + */ +R3.Graph.Table = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.linkedComponents.domElement = R3.DomElement; + + R3.Graph.call( + this, + true + ); + +}; + +R3.Graph.Table.prototype = Object.create(R3.Graph.prototype); +R3.Graph.Table.prototype.constructor = R3.Graph.Table; + +/** + * Updates the instance with the current state + */ +R3.Graph.Table.prototype.createInstance = function() { + + this.instance = this.graphics.Table(this); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Graph.Table.prototype.updateInstance = function(property) { + + if ( + property === 'columns' || + property === 'rows' || + property === 'data' + ) { + this.instance = this.graphics.Table(this); + } + + R3.Graph.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-group.js b/src/r3-group.js new file mode 100644 index 0000000..e11d82b --- /dev/null +++ b/src/r3-group.js @@ -0,0 +1,58 @@ +/** + * R3.Group + * @param apiComponent + * @constructor + */ +R3.Group = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.Group.prototype = Object.create(R3.Component.prototype); +R3.Group.prototype.constructor = R3.Group; + +/** + * Creates an instance R3.Group + * @returns {*} + */ +R3.Group.prototype.createInstance = function() { + + this.instance = { + start : this.start, + count : this.count, + materialIndex : this.materialIndex + }; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates R3.Group instance + * @param property + */ +R3.Group.prototype.updateInstance = function(property) { + + console.warn('update the geometry instead'); + + if (property === 'start') { + this.instance.start = this.start; + return; + } + + if (property === 'count') { + this.instance.count = this.count; + return; + } + + if (property === 'materialIndex') { + this.instance.materialIndex = this.materialIndex; + return; + } + + __UPDATE_INSTANCE__; +}; diff --git a/src/r3-gui.js b/src/r3-gui.js new file mode 100644 index 0000000..9e08ff9 --- /dev/null +++ b/src/r3-gui.js @@ -0,0 +1,170 @@ +/** + * R3.GUI + * + * This class uses the existing runtime but is not a component - we don't store these to API + * but they do have the capability of changing their runtime implementations + * + * @constructor + */ +R3.GUI = function(options) { + + if (R3.Utils.UndefinedOrNull(options)) { + options = {}; + } + + this.gui = null; + + R3.Event.Emit( + R3.Event.GET_RUNTIME, + this, + function(runtime) { + this.gui = runtime.gui; + }.bind(this) + ); + + if (R3.Utils.UndefinedOrNull(options.id)) { + throw new Error('You need to specify the DOM element ID'); + } + this.id = options.id; + + this.dom = document.getElementById(this.id); + + if (R3.Utils.UndefinedOrNull(options.groups)) { + options.groups = []; + } + this.groups = options.groups; + + this.createInstance(); +}; + +R3.GUI.Group = function(options) { + + if (R3.Utils.UndefinedOrNull(options)) { + options = {}; + } + + if (R3.Utils.UndefinedOrNull(options.components)) { + options.components = []; + } + this.options = options.components; + + if (R3.Utils.UndefinedOrNull(options.templates)) { + options.templates = []; + } + this.options = options.templates; +}; + +R3.GUI.Template = function(options) { + + if (R3.Utils.UndefinedOrNull(options)) { + options = {}; + } + + if (R3.Utils.UndefinedOrNull(options.component)) { + options.component = null; + } + this.component = options.component; + + if (R3.Utils.UndefinedOrNull(options.affected)) { + options.affected = []; + } + this.affected = options.affected; +}; + +/** + * Creates a helper instance + */ +R3.GUI.prototype.createInstance = function() { + + if (R3.Utils.UndefinedOrNull(this.gui)) { + throw new Error('Need a GUI runtime'); + } + + this.instance = this.gui.createInstance(); + + this.dom.appendChild(this.gui.getDomElement(this)); + + R3.Event.Emit( + R3.Event.GUI_CREATED, + this + ) + +}; + +R3.GUI.prototype.dispose = function() { + + this.clear(); + + this.dom.removeChild(this.gui.getDomElement(this)); + + R3.Event.Emit( + R3.Event.GUI_REMOVED, + this + ) + +}; + +R3.GUI.prototype.addPanel = function(component) { + return this.gui.addPanel(this, component); +}; + +R3.GUI.prototype.addNumber = function(panel, component, property) { + return this.gui.addNumber(this, panel, component, property); +}; + +R3.GUI.prototype.addString = function(panel, component, property) { + return this.gui.addString(this, panel, component, property); +}; + +R3.GUI.prototype.addButton = function(panel, component, property) { + return this.gui.addButton(this, panel, component, property); +}; + +R3.GUI.prototype.addColor = function(panel, component, property) { + return this.gui.addColor(this, panel, component, property); +}; + +R3.GUI.prototype.addCheckbox = function(panel, component, property) { + return this.gui.addCheckbox(this, panel, component, property); +}; + +R3.GUI.prototype.addSelect = function(panel, component, property) { + return this.gui.addSelect(this, panel, component, property); +}; + + +R3.GUI.prototype.addComponent = function(component) { + this.gui.addComponent(this, component); +}; + +/** + * Remove all folders from instance + */ +R3.GUI.prototype.removeComponent = function(component) { + this.gui.removeComponent(this, component); +}; + +/** + * Adds a group to instance + * @param name + * @returns {*} + */ +R3.GUI.prototype.addGroup = function(panel, name) { + return this.gui.addGroup(this, panel, name); +}; + +/** + * Remove a group + * @param name + */ +R3.GUI.prototype.removeGroup = function(name) { + this.gui.removeGroup(this, name); +}; + +R3.GUI.prototype.removeAllGroups = function() { + this.gui.removeAllGroups(this); +}; + +R3.GUI.prototype.clear = function() { + this.gui.clear(this); +}; \ No newline at end of file diff --git a/src/r3-image.js b/src/r3-image.js new file mode 100644 index 0000000..2322c07 --- /dev/null +++ b/src/r3-image.js @@ -0,0 +1,166 @@ +/** + * R3.Image + * @param apiComponent + * @constructor + */ +R3.Image = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Image.prototype = Object.create(R3.Component.prototype); +R3.Image.prototype.constructor = R3.Image; + +/** + * Creates an image instance + * @returns {*} + */ +R3.Image.prototype.createInstance = function() { + + R3.Event.Emit( + R3.Event.LOAD_IMAGE, + { + image : this + }, + function(imageInstance) { + this.instance = imageInstance; + + this.width = this.instance.width; + this.height = this.instance.height; + + __CREATE_INSTANCE__; + + }.bind(this), + function(error) { + + console.error(error); + + this.instance = null; + + __CREATE_INSTANCE__; + + }.bind(this) + ); + +}; + +/** + * Updates the instance with the current state + */ +R3.Image.prototype.updateInstance = function(property) { + + if (R3.Utils.UndefinedOrNull(property)) { + console.warn('unknown property update for Image: ' + property); + } + + if ( + property === 'fileName' || + property === 'extension' || + property === 'path' + ) { + this.createInstance(); + return; + } + + if (R3.Utils.UndefinedOrNull(this.instance)) { + console.warn('image not ready yet'); + return; + } + + if ( + property === 'width' || + property === 'height' + ) { + console.warn('width and height is read only'); + this.width = this.instance.width; + this.height = this.instance.height; + return; + } + + __UPDATE_INSTANCE__; +}; + +R3.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; + this.width = rawObject.width; + this.height = rawObject.height; +}; + +/** + * Updates R3.Image from instance + */ +R3.Image.prototype.updateFromInstance = function() { + this.fileName = this.instance.fileName || 'no filename'; + this.extension = this.instance.extension || 'no extension'; + this.path = this.instance.path || 'no path'; + this.contentType = this.instance.contentType || 'no content type'; + this.size = this.instance.size || 0; + this.width = this.instance.width || 0; + this.height = this.instance.height || 0; +}; + +R3.Image.prototype.getPixelData = function() { + + var canvas = document.createElement( 'canvas' ); + canvas.width = this.width; + canvas.height = this.height; + var context = canvas.getContext( '2d' ); + + context.drawImage(this.instance, 0, 0, canvas.width, canvas.height); + + var imageData = context.getImageData(0, 0, this.width, this.height); + + return imageData.data; + +}; + +/** + * Returns an array of Height Data for this image + * @returns {Float32Array | null} + */ +R3.Image.prototype.getHeightData = function() { + + if (R3.Utils.UndefinedOrNull(this.instance)) { + console.warn('this image is not ready to have its height data processed'); + return null; + } + + var pixels = this.getPixelData(); + + + var data = new Float32Array( this.width * this.height ); + + var height, i, j = 0; + + for (i = 0; i < pixels.length; i += 4) { + + /** + * We ignore the alpha channel for now + */ + height = (pixels[i] + pixels[i+1] + pixels[i+2]); + + /** + * Clamp values to zero or a number between 0 and 1 + */ + if (height > 3) { + height = height / 768; + } else { + height = 0; + } + + data[j++] = height; + } + + return data; +}; diff --git a/src/r3-matrix4.js b/src/r3-matrix4.js new file mode 100644 index 0000000..76d32ad --- /dev/null +++ b/src/r3-matrix4.js @@ -0,0 +1,191 @@ +/** + * R3.Matrix4 + * @param apiComponent + * @constructor + */ +R3.Matrix4 = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.componentRuntime = R3.Component.GetComponentRuntime(this.parent); + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Matrix4.prototype = Object.create(R3.Component.prototype); +R3.Matrix4.prototype.constructor = R3.Matrix4; + +/** + * R3.Matrix4.prototype.createInstance + */ +R3.Matrix4.prototype.createInstance = function() { + + switch (this.componentRuntime) { + case R3.Runtime.GRAPHICS : + this.instance = this.graphics.Matrix4( + this.rows + ); + break; + default : + case R3.Runtime.PHYSICS : + this.instance = this.physics.Matrix4( + this.rows + ); + break; + } + + __CREATE_INSTANCE__; + +}; + +/** + * Updates this instance + */ +R3.Matrix4.prototype.updateInstance = function(property) { + + if (property === 'rows') { + 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 + ); + } + + __UPDATE_INSTANCE__; + +}; + +/** + * Lookat + * @param position + * @param target + * @param up + * @returns {R3.Matrix4} + */ +R3.Matrix4.prototype.lookAt = function(position, target, up) { + + var pv = new R3.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('rows'); + + return this; +}; + +/** + * Identity + */ +R3.Matrix4.prototype.identity = function() { + + R3.API.Matrix4.prototype.identity.call(this); + +}; + +/** + * Transpose + * @returns {R3.Matrix4} + */ +R3.Matrix4.prototype.transpose = function() { + + var temp = new R3.API.Matrix4(); + + temp[0].x = this.rows[0].x; + temp[0].y = this.rows[1].x; + temp[0].z = this.rows[2].x; + temp[0].w = this.rows[3].x; + + temp[1].x = this.rows[0].y; + temp[1].y = this.rows[1].y; + temp[1].z = this.rows[2].y; + temp[1].w = this.rows[3].y; + + temp[2].x = this.rows[0].z; + temp[2].y = this.rows[1].z; + temp[2].z = this.rows[2].z; + temp[2].w = this.rows[3].z; + + temp[3].x = this.rows[0].w; + temp[3].y = this.rows[1].w; + temp[3].z = this.rows[2].w; + temp[3].w = this.rows[3].w; + + this.rows[0].x = temp[0].x; + this.rows[0].y = temp[0].y; + this.rows[0].z = temp[0].z; + this.rows[0].w = temp[0].w; + + this.rows[1].x = temp[1].x; + this.rows[1].y = temp[1].y; + this.rows[1].z = temp[1].z; + this.rows[1].w = temp[1].w; + + this.rows[2].x = temp[2].x; + this.rows[2].y = temp[2].y; + this.rows[2].z = temp[2].z; + this.rows[2].w = temp[2].w; + + this.rows[3].x = temp[3].x; + this.rows[3].y = temp[3].y; + this.rows[3].z = temp[3].z; + this.rows[3].w = temp[3].w; + + return this; +}; diff --git a/src/r3-mouse.js b/src/r3-mouse.js new file mode 100644 index 0000000..901ce6f --- /dev/null +++ b/src/r3-mouse.js @@ -0,0 +1,43 @@ +/** + * R3.Mouse + * @param apiComponent + * @constructor + */ +R3.Mouse = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.Mouse.prototype = Object.create(R3.Component.prototype); +R3.Mouse.prototype.constructor = R3.Mouse; + +/** + * createInstance + */ +R3.Mouse.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * updateInstance + * @param property + */ +R3.Mouse.prototype.updateInstance = function(property) { + + if (property === 'position') { + this.position.updateInstance('x'); + this.position.updateInstance('y'); + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-plane.js b/src/r3-plane.js new file mode 100644 index 0000000..81a0c11 --- /dev/null +++ b/src/r3-plane.js @@ -0,0 +1,50 @@ +/** + * R3.Plane + * @param apiComponent + * @constructor + */ +R3.Plane = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Plane.prototype = Object.create(R3.Component.prototype); +R3.Plane.prototype.constructor = R3.Plane; + +R3.Plane.prototype.createInstance = function() { + + this.instance = this.graphics.Plane( + this.normal, + this.constant + ); + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Plane.prototype.updateInstance = function(property) { + + if (property === 'normal') { + + this.normal.normalize(); + + this.instance.normal.x = this.normal.x; + this.instance.normal.y = this.normal.y; + this.instance.normal.z = this.normal.z; + } + + if (property === 'constant') { + this.instance.constant = this.constant; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-project-0.js b/src/r3-project-0.js new file mode 100644 index 0000000..00f9b76 --- /dev/null +++ b/src/r3-project-0.js @@ -0,0 +1,54 @@ +/** + * R3.Project + * @param inherited + * @constructor + */ +R3.Project = function( + inherited +) { + + __INHERIT_ONLY__ + + this.linkedComponents.entities = [R3.Entity]; + this.linkedComponents.controls = [R3.Controls]; + this.linkedComponents.images = [R3.Image]; + this.linkedComponents.code = [R3.CustomCode]; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.Project.prototype = Object.create(R3.Component.prototype); +R3.Project.prototype.constructor = R3.Project; + +/** + * Updates the instance with the current state + */ +R3.Project.prototype.updateInstance = function(property) { + + if (property === 'isPublic') { + console.log('todo: project isPublic update'); + return; + } + + if (property === 'entities') { + console.log('todo: project entities update'); + return; + } + + if (property === 'controls') { + console.log('todo: project controls update'); + return; + } + if (property === 'images') { + console.log('todo: project images update'); + return; + } + + if (property === 'applicationMode') { + console.log('todo: project applicationMode update'); + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-project-d2.js b/src/r3-project-d2.js new file mode 100644 index 0000000..464aefe --- /dev/null +++ b/src/r3-project-d2.js @@ -0,0 +1,48 @@ +/** + * R3.Project.D2 + * @param apiComponent + * @constructor + */ +R3.Project.D2 = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.linkedComponents.renderers = [R3.Renderer.D2]; + + R3.Project.call( + this, + true + ); +}; + +R3.Project.D2.prototype = Object.create(R3.Project.prototype); +R3.Project.D2.prototype.constructor = R3.Project.D2; + +R3.Project.D2.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Project.D2.prototype.updateInstance = function(property) { + + if (property === 'renderers') { + console.log('todo: project renderer update'); + return; + } + + if (property === 'controls') { + console.log('todo: project controls update'); + return; + } + + R3.Project.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-project-d3-0.js b/src/r3-project-d3-0.js new file mode 100644 index 0000000..dc4d862 --- /dev/null +++ b/src/r3-project-d3-0.js @@ -0,0 +1,115 @@ +/** + * R3.Project.D3 + * @param apiComponent + * @param inherited + * @constructor + */ +R3.Project.D3 = function( + apiComponent, + inherited +) { + + if (R3.EntityManager.Instance.findComponentsByConstructor(R3.Project).length >= 16) { + + R3.Event.Emit( + R3.Event.MAXIMUM_PROJECTS + ); + + throw new Error('Maximum number of open projects reached'); + } + + __INHERIT_AND_INSTANTIATE__; + + this.linkedComponents.renderers = [R3.Renderer.D3]; + this.linkedComponents.rendererTargets = [R3.D3.RenderTarget]; + this.linkedComponents.cameras = [R3.D3.Camera]; + this.linkedComponents.audios = [R3.D3.Audio]; + this.linkedComponents.mouse = R3.Mouse; + this.linkedComponents.raycaster = R3.D3.Raycaster; + this.linkedComponents.clock = R3.Clock; + this.linkedComponents.composer = R3.D3.Composer; + this.linkedComponents.effect = R3.D3.Effect; + + R3.Project.call( + this, + true + ); +}; + +R3.Project.D3.prototype = Object.create(R3.Project.prototype); +R3.Project.D3.prototype.constructor = R3.Project.D3; + +R3.Project.D3.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Project.D3.prototype.updateInstance = function(property) { + + if (property === 'renderers') { + console.log('todo: project renderers update'); + return; + } + + if (property === 'renderTargets') { + console.log('todo: project renderTargets update'); + return; + } + + if (property === 'cameras') { + console.log('todo: These controls override parent controls since they can contain 3D controls'); + /** + * These controls override parent controls since they can contain 3D controls - handle this + * properly here + */ + return; + } + + if (property === 'controls') { + console.log('todo: project controls update'); + return; + } + + if (property === 'audios') { + console.log('todo: project audios update'); + return; + } + + if (property === 'applicationMode') { + + this.controls.map( + function(control) { + if ( + control instanceof R3.Controls.D3.Orbit || + control instanceof R3.Controls.D3.FirstPerson + ) { + + var camera = control.camera; + + if (camera === this.cameras[R3.API.Project.CAMERA_INDEX_EDIT]) { + /** + * Disable the control for now if applicationMode is run + */ + if (this.applicationMode === R3.API.Project.APPLICATION_MODE_RUN) { + control.enabled = false; + } else { + control.enabled = true; + } + + control.updateInstance('enabled'); + + } + } + }.bind(this) + ); + return; + } + + R3.Project.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-project-d3-vr.js b/src/r3-project-d3-vr.js new file mode 100644 index 0000000..d826836 --- /dev/null +++ b/src/r3-project-d3-vr.js @@ -0,0 +1,37 @@ +/** + * R3.Project.D3.VR + * @param apiComponent + * @constructor + */ +R3.Project.D3.VR = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Project.D3.call( + this, + apiComponent, + true + ); +}; + +R3.Project.D3.VR.prototype = Object.create(R3.Project.D3.prototype); +R3.Project.D3.VR.prototype.constructor = R3.Project.D3.VR; + +R3.Project.D3.VR.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Project.D3.VR.prototype.updateInstance = function(property) { + + R3.Project.D3.prototype.updateInstance.call(this, property); + +}; diff --git a/src/r3-quaternion-0.js b/src/r3-quaternion-0.js new file mode 100644 index 0000000..cd81e6f --- /dev/null +++ b/src/r3-quaternion-0.js @@ -0,0 +1,128 @@ +/** + * R3.Quaternion + * @param apiComponent + * @constructor + */ +R3.Quaternion = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + Object.defineProperty( + this, + 'angle', + R3.Utils.LimitToPI('angle', this.angle) + ); + + __UPGRADE_TO_RUNTIME__; +}; + +R3.Quaternion.prototype = Object.create(R3.Component.prototype); +R3.Quaternion.prototype.constructor = R3.Quaternion; + +/** + * Creates an instance quaternion + * @returns {*} + */ +R3.Quaternion.prototype.createInstance = function() { + + var runtime = R3.Component.GetComponentRuntime(this.parent); + + switch (runtime) { + case R3.Runtime.GRAPHICS : + this.instance = new this.graphics.Quaternion( + this.x, + this.y, + this.z, + this.w + ); + break; + case R3.Runtime.PHYSICS : + this.instance = new this.physics.Quaternion( + this.x, + this.y, + this.z, + this.w + ); + break; + default: + throw new Error('unhandled component runtime: ' + runtime); + } + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance vector, calls updateInstance on the parent object + */ +R3.Quaternion.prototype.updateInstance = function(property) { + + if (property === 'x') { + this.instance.x = this.x; + return; + } + + if (property === 'y') { + this.instance.y = this.y; + return; + } + + if (property === 'z') { + this.instance.z = this.z; + return; + } + + if (property === 'w') { + this.instance.w = this.w; + return; + } + + if (property === 'axis') { + console.warn('todo: axis update'); + return; + } + + if (property === 'angle') { + console.warn('todo: angle update'); + return; + } + + __UPDATE_INSTANCE__; + +}; + + +/** + * Checks if quaternion is equal to another quaternion + * @param quaternion + * @returns {boolean} + */ +R3.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 + ); + +}; + +R3.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; + +}; + +R3.Quaternion.prototype.copy = function() { + R3.API.Quaternion.prototype.copy.call(this); +}; diff --git a/src/r3-quaternion-points.js b/src/r3-quaternion-points.js new file mode 100644 index 0000000..4be9b52 --- /dev/null +++ b/src/r3-quaternion-points.js @@ -0,0 +1,41 @@ +/** + * R3.Quaternion.Points + * @param apiComponent + * @constructor + */ +R3.Quaternion.Points = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Quaternion.Points.prototype = Object.create(R3.API.Component.prototype); +R3.Quaternion.Points.prototype.constructor = R3.Quaternion.Points; + +/** + * Creates an instance quaternion + * @returns {*} + */ +R3.Quaternion.Points.prototype.createInstance = function() { + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance vector, calls updateInstance on the parent object + */ +R3.Quaternion.Points.prototype.updateInstance = function(property) { + + if (property === 'vectors') { + console.warn('todo: vectors update'); + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-query-0.js b/src/r3-query-0.js new file mode 100644 index 0000000..64ed8b7 --- /dev/null +++ b/src/r3-query-0.js @@ -0,0 +1,68 @@ +/** + * R3.Query + * @param inherited + * @constructor + */ +R3.Query = function( + inherited +) { + + __INHERIT_ONLY__ + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Query.prototype = Object.create(R3.Component.prototype); +R3.Query.prototype.constructor = R3.Query; + +/** + * Updates the instance with the current state + */ +R3.Query.prototype.updateInstance = function(property) { + + if (property === 'path') { + console.warn('todo: update query path'); + return; + } + + if (property === 'start') { + console.warn('todo: update query start'); + return; + } + + if (property === 'end') { + console.warn('todo: update query end'); + return; + } + + if (property === 'size') { + console.warn('todo: update query size'); + return; + } + + if (property === 'text') { + console.warn('todo: update query text'); + return; + } + + if (property === 'tooltips') { + console.warn('todo: update query tooltips'); + return; + } + + __UPDATE_INSTANCE__; +}; + +R3.Query.prototype.parse = function(data) { + console.warn(data); + + if (data.hits && data.hits.hits) { + data.hits.hits.map( + function(hit) { + this.tooltips.push(hit._source); + }.bind(this) + ) + } + +}; \ No newline at end of file diff --git a/src/r3-query-alerts-0.js b/src/r3-query-alerts-0.js new file mode 100644 index 0000000..b08cab7 --- /dev/null +++ b/src/r3-query-alerts-0.js @@ -0,0 +1,35 @@ +/** + * R3.Query.Alerts + * @param inherited + * @constructor + */ +R3.Query.Alerts = function( + inherited +) { + + __INHERIT_ONLY__ + + R3.Query.call( + this, + true + ); + +}; + +R3.Query.Alerts.prototype = Object.create(R3.Query.prototype); +R3.Query.Alerts.prototype.constructor = R3.Query.Alerts; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.prototype.updateInstance = function(property) { + + R3.Query.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Alerts.prototype.parse = function(data) { + + R3.Query.prototype.parse.call(this, data); + +}; \ No newline at end of file diff --git a/src/r3-query-alerts-buckets.js b/src/r3-query-alerts-buckets.js new file mode 100644 index 0000000..ea03cd3 --- /dev/null +++ b/src/r3-query-alerts-buckets.js @@ -0,0 +1,137 @@ +/** + * R3.Query.Alerts.Buckets + * @param apiComponent + * @constructor + */ +R3.Query.Alerts.Buckets = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.Alerts.call( + this, + true + ); + +}; + +R3.Query.Alerts.Buckets.prototype = Object.create(R3.Query.Alerts.prototype); +R3.Query.Alerts.Buckets.prototype.constructor = R3.Query.Alerts.Buckets; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.Buckets.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.Buckets.prototype.updateInstance = function(property) { + + R3.Query.Alerts.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Alerts.Buckets.prototype.parse = function(data) { + + this.columns = []; + + if (this.bucketField === R3.API.Query.Alerts.Buckets.BUCKET_FIELD_ALERT_TYPE) { + this.columns.push( + { + type : 'string', + name : 'Alert Type' + } + ) + } + + if (this.bucketField === R3.API.Query.Alerts.Buckets.BUCKET_FIELD_COUNTRY) { + this.columns.push( + { + type : 'string', + name : 'Country' + } + ) + } + + if (this.bucketField === R3.API.Query.Alerts.Buckets.BUCKET_FIELD_HOSTNAME) { + this.columns.push( + { + type : 'string', + name : 'Hostname' + } + ) + } + + if (this.bucketField === R3.API.Query.Alerts.Buckets.BUCKET_FIELD_IP_V4) { + this.columns.push( + { + type : 'string', + name : 'IP Address' + } + ) + } + + if (this.bucketField === R3.API.Query.Alerts.Buckets.BUCKET_FIELD_USERNAME) { + this.columns.push( + { + type : 'string', + name : 'Username' + } + ) + } + + this.columns.push( + { + type : 'number', + name : 'Critical' + }, + { + type : 'number', + name : 'High' + }, + { + type : 'number', + name : 'Medium' + }, + { + type : 'number', + name : 'Low' + } + ); + + this.rows = data.aggregations.descriptions.buckets.reduce( + function(result, bucket) { + + var key = [bucket.key]; + var priorities = bucket.priorities.buckets.reduce( + function(result, prioBucket) { + result[prioBucket.key - 1] = prioBucket.doc_count; + return result; + }, + [ + 0, + 0, + 0, + 0 + ] + ); + + this.tooltips.push(bucket); + + result.push(key.concat(priorities)); + return result; + }.bind(this), + [] + ); + + //R3.Query.Alerts.prototype.parse.call(this, data); + +}; diff --git a/src/r3-query-alerts-firstTimeLogin-0.js b/src/r3-query-alerts-firstTimeLogin-0.js new file mode 100644 index 0000000..960f70e --- /dev/null +++ b/src/r3-query-alerts-firstTimeLogin-0.js @@ -0,0 +1,50 @@ +/** + * R3.Query.Alerts.FirstTimeLogin + * @param apiComponent + * @param inherited + * @constructor + */ +R3.Query.Alerts.FirstTimeLogin = function( + apiComponent, + inherited +) { + + __INHERIT_AND_INSTANTIATE__ + + R3.Query.Alerts.call( + this, + true + ); + +}; + +R3.Query.Alerts.FirstTimeLogin.prototype = Object.create(R3.Query.Alerts.prototype); +R3.Query.Alerts.FirstTimeLogin.prototype.constructor = R3.Query.Alerts.FirstTimeLogin; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.FirstTimeLogin.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.FirstTimeLogin.prototype.updateInstance = function(property) { + + R3.Query.Alerts.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Alerts.FirstTimeLogin.prototype.parse = function(data) { + + console.warn('not yet implemented'); + + R3.Query.Alerts.prototype.parse.call(this, data); + +}; diff --git a/src/r3-query-alerts-firstTimeLogin-applications.js b/src/r3-query-alerts-firstTimeLogin-applications.js new file mode 100644 index 0000000..fe64542 --- /dev/null +++ b/src/r3-query-alerts-firstTimeLogin-applications.js @@ -0,0 +1,79 @@ +/** + * R3.Query.Alerts.FirstTimeLogin.Applications + * @param apiComponent + * @constructor + */ +R3.Query.Alerts.FirstTimeLogin.Applications = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.Alerts.FirstTimeLogin.call( + this, + apiComponent, + true + ); + +}; + +R3.Query.Alerts.FirstTimeLogin.Applications.prototype = Object.create(R3.Query.Alerts.FirstTimeLogin.prototype); +R3.Query.Alerts.FirstTimeLogin.Applications.prototype.constructor = R3.Query.Alerts.FirstTimeLogin.Applications; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.FirstTimeLogin.Applications.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.FirstTimeLogin.Applications.prototype.updateInstance = function(property) { + + R3.Query.Alerts.FirstTimeLogin.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Alerts.FirstTimeLogin.Applications.prototype.parse = function(data) { + + this.columns = [ + { + type: 'string', + name: 'User' + }, + { + type: 'string', + name: 'Application' + }, + { + type: 'datetime', + name: 'Time' + }, + ]; + + if (data.hits.hits.length === 0) { + this.rows = [null]; + } else { + this.rows = data.hits.hits.reduce( + function (result, hit) { + var row = [ + hit._source.login.username, + hit._source.login.application, + new Date(hit._source.timestamp) + ]; + result.push(row); + return result; + }, + [] + ); + } + + R3.Query.Alerts.FirstTimeLogin.prototype.parse.call(this, data); + +}; diff --git a/src/r3-query-alerts-firstTimeLogin-devices.js b/src/r3-query-alerts-firstTimeLogin-devices.js new file mode 100644 index 0000000..5d47edc --- /dev/null +++ b/src/r3-query-alerts-firstTimeLogin-devices.js @@ -0,0 +1,86 @@ +/** + * R3.Query.Alerts.FirstTimeLogin.Devices + * @param apiComponent + * @constructor + */ +R3.Query.Alerts.FirstTimeLogin.Devices = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.Alerts.FirstTimeLogin.call( + this, + apiComponent, + true + ); + +}; + +R3.Query.Alerts.FirstTimeLogin.Devices.prototype = Object.create(R3.Query.Alerts.FirstTimeLogin.prototype); +R3.Query.Alerts.FirstTimeLogin.Devices.prototype.constructor = R3.Query.Alerts.FirstTimeLogin.Devices; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.FirstTimeLogin.Devices.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.FirstTimeLogin.Devices.prototype.updateInstance = function(property) { + + R3.Query.Alerts.FirstTimeLogin.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Alerts.FirstTimeLogin.Devices.prototype.parse = function(data) { + + this.columns = [ + { + type: 'string', + name: 'User' + }, + { + type: 'string', + name: 'Device' + }, + { + type: 'string', + name: 'Login Type' + }, + { + type: 'string', + name: 'Protocol' + }, + { + type: 'datetime', + name: 'Time' + }, + ]; + + if (data.hits && data.hits.hits) { + this.rows = data.hits.hits.reduce( + function (result, hit) { + var row = [ + hit._source.login.username, + hit._source.login.destination_hostname, + hit._source.login.login_type, + hit._source.login.login_protocol, + new Date(hit._source.timestamp) + ]; + result.push(row); + return result; + }, + [] + ); + } + + R3.Query.Alerts.FirstTimeLogin.prototype.parse.call(this, data); +}; diff --git a/src/r3-query-alerts-firstTimeLogin-vpn.js b/src/r3-query-alerts-firstTimeLogin-vpn.js new file mode 100644 index 0000000..e017931 --- /dev/null +++ b/src/r3-query-alerts-firstTimeLogin-vpn.js @@ -0,0 +1,91 @@ +/** + * R3.Query.Alerts.FirstTimeLogin.VPN + * @param apiComponent + * @constructor + */ +R3.Query.Alerts.FirstTimeLogin.VPN = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.Alerts.FirstTimeLogin.call( + this, + apiComponent, + true + ); + +}; + +R3.Query.Alerts.FirstTimeLogin.VPN.prototype = Object.create(R3.Query.Alerts.FirstTimeLogin.prototype); +R3.Query.Alerts.FirstTimeLogin.VPN.prototype.constructor = R3.Query.Alerts.FirstTimeLogin.VPN; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.FirstTimeLogin.VPN.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.FirstTimeLogin.VPN.prototype.updateInstance = function(property) { + + R3.Query.Alerts.FirstTimeLogin.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Alerts.FirstTimeLogin.VPN.prototype.parse = function(data) { + + this.columns = [ + { + type : 'string', + name : 'User' + }, + { + type : 'string', + name : 'User OS' + }, + { + type : 'string', + name : 'From' + }, + { + type : 'string', + name : 'VPN Server' + }, + { + type : 'string', + name : 'VPN Protocol' + }, + { + type : 'datetime', + name : 'Time' + } + ]; + + this.rows = data.hits.hits.reduce( + function (result, hit) { + + var row = [ + hit._source.login.username, + hit._source.login.source_os, + hit._source.login.source_geo?hit._source.login.source_geo.country + '(' + hit._source.login.source_geo.city + ')':hit._source.login.source_ip, + hit._source.login.destination_hostname + ' - ' + hit._source.login.destination_os, + hit._source.login.login_protocol, + new Date(hit._source.timestamp) + ]; + result.push(row); + return result; + }, + [] + ); + + R3.Query.Alerts.FirstTimeLogin.prototype.parse.call(this, data); + +}; diff --git a/src/r3-query-alerts-list.js b/src/r3-query-alerts-list.js new file mode 100644 index 0000000..cf1de8d --- /dev/null +++ b/src/r3-query-alerts-list.js @@ -0,0 +1,110 @@ +/** + * R3.Query.Alerts.List + * @param apiComponent + * @constructor + */ +R3.Query.Alerts.List = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.Alerts.call( + this, + true + ); + +}; + +R3.Query.Alerts.List.prototype = Object.create(R3.Query.Alerts.prototype); +R3.Query.Alerts.List.prototype.constructor = R3.Query.Alerts.List; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.List.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.List.prototype.updateInstance = function(property) { + + R3.Query.Alerts.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Alerts.List.prototype.parse = function(data) { + + this.columns = [ + { + type : 'number', + name : 'Priority' + }, + { + type : 'string', + name : 'Alert Type' + }, + { + type : 'string', + name : 'Hostname' + }, + { + type : 'string', + name : 'Device' + }, + { + type : 'string', + name : 'MAC Address' + }, + { + type : 'string', + name : 'Acknowledged' + }, + { + type : 'datetime', + name : 'Time' + } + ]; + + + + this.rows = data.hits.hits.reduce( + function(result, hit) { + + var row = []; + + row.push(hit._source.priority); + row.push(hit._source.alert_type); + + var hostname = 'unknown'; + if (hit._source.login && hit._source.login.destination_hostname) { + hostname = hit._source.login.destination_hostname; + } + row.push(hostname); + + var device = 'unknown'; + if (hit._source.device && hit._source.device.ip_v4) { + device = hit._source.device.ip_v4; + } + row.push(device); + + row.push(hit._source.mac); + + row.push({v:'ButtonName', f:hit._source.acknowledged?'Yes':'No'}); + row.push(new Date(hit._source.timestamp)); + result.push(row); + + return result; + }.bind(this), + [] + ); + + R3.Query.Alerts.prototype.parse.call(this, data); + +}; diff --git a/src/r3-query-alerts-summary.js b/src/r3-query-alerts-summary.js new file mode 100644 index 0000000..8a77586 --- /dev/null +++ b/src/r3-query-alerts-summary.js @@ -0,0 +1,55 @@ +/** + * R3.Query.Alerts.Summary + * @param apiComponent + * @constructor + */ +R3.Query.Alerts.Summary = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.Alerts.call( + this, + true + ); + +}; + +R3.Query.Alerts.Summary.prototype = Object.create(R3.Query.Alerts.prototype); +R3.Query.Alerts.Summary.prototype.constructor = R3.Query.Alerts.Summary; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.Summary.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.Summary.prototype.updateInstance = function(property) { + + R3.Query.Alerts.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Alerts.Summary.prototype.parse = function(data) { + + this.priorities = data.aggregations.priorities.buckets.reduce( + function(result, bucket) { + result.push(bucket.doc_count); + this.tooltips.push(bucket); + return result; + }.bind(this), + [] + ); + + // R3.Query.Alerts.prototype.parse.call(this, data); + +}; diff --git a/src/r3-query-alerts-timeseries.js b/src/r3-query-alerts-timeseries.js new file mode 100644 index 0000000..b2fc473 --- /dev/null +++ b/src/r3-query-alerts-timeseries.js @@ -0,0 +1,195 @@ +/** + * R3.Query.Alerts.Timeseries + * @param apiComponent + * @constructor + */ +R3.Query.Alerts.Timeseries = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.Alerts.call( + this, + true + ); + +}; + +R3.Query.Alerts.Timeseries.prototype = Object.create(R3.Query.Alerts.prototype); +R3.Query.Alerts.Timeseries.prototype.constructor = R3.Query.Alerts.Timeseries; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.Timeseries.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Alerts.Timeseries.prototype.updateInstance = function(property) { + + R3.Query.Alerts.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Alerts.Timeseries.prototype.parse = function(data) { + + this.labels = data.aggregations.mins.buckets.reduce( + function(result, bucket) { + + function formatDate(date) { + var monthNames = [ + "Jan", "Feb", "Mar", + "Apr", "May", "Jun", "Jul", + "Aug", "Sep", "Oct", + "Nov", "Dec" + ]; + + var day = date.getDate(); + var monthIndex = date.getMonth(); + var year = date.getFullYear(); + + return day + '-' + monthNames[monthIndex] + '-' + year; + } + + function formatHour(date) { + + var day = date.getDate(); + var hour = date.getHours(); + var monthIndex = date.getMonth(); + + var monthNames = [ + "Jan", "Feb", "Mar", + "Apr", "May", "Jun", "Jul", + "Aug", "Sep", "Oct", + "Nov", "Dec" + ]; + return monthIndex+1 + '/' + day + ' ' + date.toLocaleTimeString(); + return monthNames[monthIndex] + ' ' + day + '-' + hour + ':00'; + } + + function formatMinute(date) { + + var hour = date.getHours(); + var minute = date.getMinutes(); + + return date.toLocaleTimeString(); + return hour + ':' + minute; + } + + if (this.timeInterval === '1d') { + result.push(formatDate(new Date(bucket.key))); + } else if (this.timeInterval === '1h') { + result.push(formatHour(new Date(bucket.key))); + } else if (this.timeInterval === '1m') { + result.push(formatMinute(new Date(bucket.key))); + } else { + console.warn('invalid time format'); + } + + return result; + }.bind(this), + [] + ); + + this.datasets = data.aggregations.mins.buckets.reduce( + function(result, bucket) { + + var count = bucket.priorities.buckets.reduce( + function(struct, prio) { + struct[prio.key - 1] = prio.doc_count; + return struct; + }, + [ + 0, + 0, + 0, + 0 + ] + ); + + if (R3.Utils.UndefinedOrNull(count)) { + count = [0, 0, 0, 0]; + } + + count.map( + function(data, index) { + result[index].data.push(data); + } + ); + + return result; + }, + [ + { + label: 'Priority 1', + backgroundColor: '#ff4c4c', + data: [] + }, + { + label: 'Priority 2', + backgroundColor: '#ffa04c', + data: [] + }, + { + label: 'Priority 3', + backgroundColor: '#fff34c', + data: [] + + }, + { + label: 'Priority 4', + backgroundColor: '#a8ff4c', + data: [] + } + ] + ) + + // for (var label in this.labels) { + // for (var p = 0; p < 4; p++) { + // + // } + // } + // + // this.dataSets = data.aggregations.mins.buckets.reduce( + // function(result, bucket) { + // result.push( + // { + // label : + // } + // ) + // return result; + // }, + // [] + // ); + // + // this.buckets = data.aggregations.mins.buckets.reduce( + // function(result, bucket) { + // result.push( + // { + // date : new Date(bucket.key), + // count : bucket.doc_count, + // priorities : bucket.priorities.buckets.reduce( + // function(result, bucket) { + // result.push(bucket.doc_count); + // return result; + // }, + // [] + // ) + // } + // ); + // return result; + // }, + // [] + // ); + + R3.Query.Alerts.prototype.parse.call(this, data); + +}; diff --git a/src/r3-query-devices-0.js b/src/r3-query-devices-0.js new file mode 100644 index 0000000..cb3e54d --- /dev/null +++ b/src/r3-query-devices-0.js @@ -0,0 +1,82 @@ +/** + * R3.Query.Devices + * @param inherited + * @constructor + */ +R3.Query.Devices = function( + apiComponent, + inherited +) { + + __INHERIT_AND_INSTANTIATE__; + + R3.Query.call( + this, + true + ); + +}; + +R3.Query.Devices.prototype = Object.create(R3.Query.prototype); +R3.Query.Devices.prototype.constructor = R3.Query.Devices; + +R3.Query.Devices.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Devices.prototype.updateInstance = function(property) { + + R3.Query.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Devices.prototype.parse = function(data) { + + this.columns = [ + { + type: 'string', + name: 'Hostname' + }, + { + type: 'string', + name: 'IP' + }, + { + type: 'string', + name: 'MAC Address' + }, + { + type: 'datetime', + name: 'Detected' + }, + ]; + + if (data.error) { + this.rows = [ + ['error', null, null, null] + ] + } else { + this.rows = data.hits.hits.reduce( + function (result, hit) { + var row = [ + hit._source.hostname, + hit._source.ip_v4, + hit._source.mac_address, + new Date(hit._source.timestamp) + ]; + result.push(row); + return result; + }, + [] + ); + } + + R3.Query.prototype.parse.call(this, data); +}; diff --git a/src/r3-query-devices-known.js b/src/r3-query-devices-known.js new file mode 100644 index 0000000..02f78ca --- /dev/null +++ b/src/r3-query-devices-known.js @@ -0,0 +1,85 @@ +/** + * R3.Query.Devices.Known + * @param apiComponent + * @constructor + */ +R3.Query.Devices.Known = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.Devices.call( + this, + apiComponent, + true + ); + +}; + +R3.Query.Devices.Known.prototype = Object.create(R3.Query.Devices.prototype); +R3.Query.Devices.Known.prototype.constructor = R3.Query.Devices.Known; + +/** + * Updates the instance with the current state + */ +R3.Query.Devices.Known.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Devices.Known.prototype.updateInstance = function(property) { + + R3.Query.Devices.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Devices.Known.prototype.parse = function(data) { + + this.columns = [ + { + type: 'string', + name: 'Hostname' + }, + { + type: 'string', + name: 'IP' + }, + { + type: 'string', + name: 'MAC Address' + }, + { + type: 'datetime', + name: 'Detected' + }, + ]; + + if (data.error) { + this.rows = [ + ['error', null, null, null] + ] + } else { + this.rows = data.hits.hits.reduce( + function (result, hit) { + var row = [ + hit._source.hostname, + hit._source.ip_v4, + hit._source.mac_address, + new Date(hit._source.timestamp) + ]; + result.push(row); + return result; + }, + [] + ); + } + + R3.Query.Devices.prototype.parse.call(this, data); +}; diff --git a/src/r3-query-devices-sql.js b/src/r3-query-devices-sql.js new file mode 100644 index 0000000..c8112de --- /dev/null +++ b/src/r3-query-devices-sql.js @@ -0,0 +1,95 @@ +/** + * R3.Query.Devices.SQL + * @param apiComponent + * @constructor + */ +R3.Query.Devices.SQL = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.Devices.call( + this, + apiComponent, + true + ); + +}; + +R3.Query.Devices.SQL.prototype = Object.create(R3.Query.Devices.prototype); +R3.Query.Devices.SQL.prototype.constructor = R3.Query.Devices.SQL; + +/** + * Updates the instance with the current state + */ +R3.Query.Devices.SQL.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Devices.SQL.prototype.updateInstance = function(property) { + + R3.Query.Devices.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Devices.SQL.prototype.parse = function(data) { + + this.columns = [ + { + type: 'string', + name: 'IP' + }, + { + type: 'string', + name: 'Hostname' + }, + { + type: 'string', + name: 'MAC Address' + }, + { + type: 'string', + name: 'Agent ID' + }, + { + type: 'string', + name: 'Acknowledged' + }, + { + type: 'datetime', + name: 'First Seen' + } + ]; + + if (data.error) { + this.rows = [ + ['error', null, null, null] + ] + } else { + this.rows = data.devices.reduce( + function (result, device) { + var row = [ + device.ip_v4, + device.hostname, + device.mac, + device.agent_id, + {v:'ButtonName', f:device.acknowledged?'Yes':'No'}, + new Date(device.created) + ]; + result.push(row); + this.tooltips.push(device); + return result; + }.bind(this), + [] + ); + } + +}; diff --git a/src/r3-query-devices-unknown.js b/src/r3-query-devices-unknown.js new file mode 100644 index 0000000..eb792e7 --- /dev/null +++ b/src/r3-query-devices-unknown.js @@ -0,0 +1,86 @@ +/** + * R3.Query.Devices.Unknown + * @param apiComponent + * @constructor + */ +R3.Query.Devices.Unknown = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.Devices.call( + this, + apiComponent, + true + ); + +}; + +R3.Query.Devices.Unknown.prototype = Object.create(R3.Query.Devices.prototype); +R3.Query.Devices.Unknown.prototype.constructor = R3.Query.Devices.Unknown; + +/** + * Updates the instance with the current state + */ +R3.Query.Devices.Unknown.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Devices.Unknown.prototype.updateInstance = function(property) { + + R3.Query.Devices.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Devices.Unknown.prototype.parse = function(data) { + + + this.columns = [ + { + type: 'string', + name: 'Hostname' + }, + { + type: 'string', + name: 'IP' + }, + { + type: 'string', + name: 'MAC Address' + }, + { + type: 'datetime', + name: 'Detected' + }, + ]; + + if (data.error) { + this.rows = [ + ['error', null, null, null] + ] + } else { + this.rows = data.hits.hits.reduce( + function (result, hit) { + var row = [ + hit._source.hostname?hit._source.hostname:'', + hit._source.ip_v4, + hit._source.mac_address, + new Date(hit._source.timestamp) + ]; + result.push(row); + return result; + }, + [] + ); + } + + R3.Query.Devices.prototype.parse.call(this, data); +}; diff --git a/src/r3-query-logins-0.js b/src/r3-query-logins-0.js new file mode 100644 index 0000000..b8ed72e --- /dev/null +++ b/src/r3-query-logins-0.js @@ -0,0 +1,37 @@ +/** + * R3.Query.Logins + * @param apiComponent + * @param inherited + * @constructor + */ +R3.Query.Logins = function( + apiComponent, + inherited +) { + + __INHERIT_AND_INSTANTIATE__ + + R3.Query.call( + this, + true + ); + +}; + +R3.Query.Logins.prototype = Object.create(R3.Query.prototype); +R3.Query.Logins.prototype.constructor = R3.Query.Logins; + +/** + * Updates the instance with the current state + */ +R3.Query.Logins.prototype.updateInstance = function(property) { + + R3.Query.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Logins.prototype.parse = function(data) { + + R3.Query.prototype.parse.call(this, data); + +}; \ No newline at end of file diff --git a/src/r3-query-logins-applications.js b/src/r3-query-logins-applications.js new file mode 100644 index 0000000..730804e --- /dev/null +++ b/src/r3-query-logins-applications.js @@ -0,0 +1,80 @@ +/** + * R3.Query.Logins.Applications + * @param apiComponent + * @constructor + */ +R3.Query.Logins.Applications = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.Logins.call( + this, + apiComponent, + true + ); + +}; + +R3.Query.Logins.Applications.prototype = Object.create(R3.Query.Logins.prototype); +R3.Query.Logins.Applications.prototype.constructor = R3.Query.Logins.Applications; + +/** + * Updates the instance with the current state + */ +R3.Query.Logins.Applications.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Logins.Applications.prototype.updateInstance = function(property) { + + R3.Query.Logins.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Logins.Applications.prototype.parse = function(data) { + + this.columns = [ + { + type: 'string', + name: 'User' + }, + { + type: 'string', + name: 'Application' + }, + { + type: 'string', + name: 'Login Result' + }, + { + type: 'datetime', + name: 'Time' + }, + ]; + + this.rows = data.hits.hits.reduce( + function(result, hit) { + var row = [ + hit._source.username, + hit._source.application, + hit._source.success?'Login Success':'Login Failure', + new Date(hit._source.timestamp) + ]; + result.push(row); + return result; + }, + [] + ); + + R3.Query.Logins.prototype.parse.call(this, data); + +}; diff --git a/src/r3-query-logins-devices.js b/src/r3-query-logins-devices.js new file mode 100644 index 0000000..36a5a56 --- /dev/null +++ b/src/r3-query-logins-devices.js @@ -0,0 +1,90 @@ +/** + * R3.Query.Logins.Devices + * @param apiComponent + * @constructor + */ +R3.Query.Logins.Devices = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.Logins.call( + this, + apiComponent, + true + ); + +}; + +R3.Query.Logins.Devices.prototype = Object.create(R3.Query.Logins.prototype); +R3.Query.Logins.Devices.prototype.constructor = R3.Query.Logins.Devices; + +/** + * Updates the instance with the current state + */ +R3.Query.Logins.Devices.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Logins.Devices.prototype.updateInstance = function(property) { + + R3.Query.Logins.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Logins.Devices.prototype.parse = function(data) { + + this.columns = [ + { + type : 'string', + name : 'User' + }, + { + type : 'string', + name : 'Device' + }, + { + type : 'string', + name : 'Login Result' + }, + { + type : 'string', + name : 'Type' + }, + { + type : 'string', + name : 'Protocol' + }, + { + type : 'datetime', + name : 'Time' + }, + ]; + + this.rows = data.hits.hits.reduce( + function(result, hit) { + var row = [ + hit._source.username, + hit._source.destination_hostname, + hit._source.success?'Login Success':'Login Failure', + hit._source.type, + hit._source.application, + new Date(hit._source.timestamp) + ]; + result.push(row); + return result; + }, + [] + ); + + R3.Query.Logins.prototype.parse.call(this, data); + +}; diff --git a/src/r3-query-logins-vpn.js b/src/r3-query-logins-vpn.js new file mode 100644 index 0000000..ac8c843 --- /dev/null +++ b/src/r3-query-logins-vpn.js @@ -0,0 +1,80 @@ +/** + * R3.Query.Logins.VPN + * @param apiComponent + * @constructor + */ +R3.Query.Logins.VPN = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.Logins.call( + this, + apiComponent, + true + ); + +}; + +R3.Query.Logins.VPN.prototype = Object.create(R3.Query.Logins.prototype); +R3.Query.Logins.VPN.prototype.constructor = R3.Query.Logins.VPN; + +/** + * Updates the instance with the current state + */ +R3.Query.Logins.VPN.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Logins.VPN.prototype.updateInstance = function(property) { + + R3.Query.Logins.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Logins.VPN.prototype.parse = function(data) { + + + this.columns = [ + { + type : 'string', + name : 'User' + }, + { + type : 'string', + name : 'Country' + }, + { + type : 'string', + name : 'City' + }, + { + type : 'datetime', + name : 'Time' + } + ]; + + this.rows = data.hits.hits.reduce( + function(result, hit) { + var row = [ + hit._source.username, + hit._source.source_geo.country, + hit._source.source_geo.city, + new Date(hit._source.timestamp) + ]; + result.push(row); + return result; + }, + [] + ); + + R3.Query.Logins.prototype.parse.call(this, data); +}; diff --git a/src/r3-query-userDevices-0.js b/src/r3-query-userDevices-0.js new file mode 100644 index 0000000..db54e36 --- /dev/null +++ b/src/r3-query-userDevices-0.js @@ -0,0 +1,81 @@ +/** + * R3.Query.UserDevices + * @param apiComponent + * @param inherited + * @constructor + */ +R3.Query.UserDevices = function( + apiComponent, + inherited +) { + + __RUNTIME_COMPONENT__ + + R3.Query.call( + this, + true + ); + +}; + +R3.Query.UserDevices.prototype = Object.create(R3.Query.prototype); +R3.Query.UserDevices.prototype.constructor = R3.Query.UserDevices; + +/** + * Updates the instance with the current state + */ +R3.Query.UserDevices.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.UserDevices.prototype.updateInstance = function(property) { + + R3.Query.prototype.updateInstance.call(this, property); + +}; + +R3.Query.UserDevices.prototype.parse = function(data) { + + this.columns = [ + { + type: 'string', + name: 'Email' + }, + { + type: 'string', + name: 'Host' + }, + { + type: 'string', + name: 'DNS Suffix' + }, + { + type: 'datetime', + name: 'Created' + }, + ]; + + this.rows = data.userDevices.reduce( + function(result, userDevice){ + result.push( + [ + userDevice.user?userDevice.user.email:'unknown', + userDevice.device?userDevice.device.hostname:'unknown', + userDevice.device?userDevice.device.dns_suffix:'unknown', + new Date(userDevice.created) + ] + ); + return result; + }, + [] + ); + + R3.Query.prototype.parse.call(this, data); +}; \ No newline at end of file diff --git a/src/r3-query-users.js b/src/r3-query-users.js new file mode 100644 index 0000000..d27b8f5 --- /dev/null +++ b/src/r3-query-users.js @@ -0,0 +1,73 @@ +/** + * R3.Query.Users + * @param apiComponent + * @constructor + */ +R3.Query.Users = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Query.call( + this, + true + ); + +}; + +R3.Query.Users.prototype = Object.create(R3.Query.prototype); +R3.Query.Users.prototype.constructor = R3.Query.Users; + +/** + * Updates the instance with the current state + */ +R3.Query.Users.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Query.Users.prototype.updateInstance = function(property) { + + R3.Query.Devices.prototype.updateInstance.call(this, property); + +}; + +R3.Query.Users.prototype.parse = function(data) { + + this.columns = [ + { + type: 'string', + name: 'User' + }, + { + type: 'datetime', + name: 'First Seen' + }, + ]; + + if (!data.error) { + this.rows = data.users.reduce( + function (result, user) { + var row = [ + user.email, + new Date(user.created) + ]; + result.push(row); + + this.tooltips.push(user); + + return result; + }.bind(this), + [] + ); + } + + +}; diff --git a/src/r3-renderer-0.js b/src/r3-renderer-0.js new file mode 100644 index 0000000..bd58725 --- /dev/null +++ b/src/r3-renderer-0.js @@ -0,0 +1,25 @@ +/** + * R3.Renderer + * @constructor + */ +R3.Renderer = function( + inherited +) { + + __INHERIT_ONLY__ + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Renderer.prototype = Object.create(R3.Component.prototype); +R3.Renderer.prototype.constructor = R3.Renderer; + +/** + * Update Renderer Instance + */ +R3.Renderer.prototype.updateInstance = function(property) { + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-renderer-d2.js b/src/r3-renderer-d2.js new file mode 100644 index 0000000..1bb7ce6 --- /dev/null +++ b/src/r3-renderer-d2.js @@ -0,0 +1,52 @@ +/** + * R3.Renderer.D2 + * @param apiComponent + * @constructor + */ +R3.Renderer.D2 = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.linkedComponents.canvas = R3.Canvas; + + R3.Renderer.call( + this, + true + ); + +}; + +R3.Renderer.D2.prototype = Object.create(R3.Renderer.prototype); +R3.Renderer.D2.prototype.constructor = R3.Renderer.D2; + +/** + * Create R3.Renderer.D2 Instance + * @returns {*} + */ +R3.Renderer.D2.prototype.createInstance = function() { + + this.instance = new PIXI.Application( + { + view : this.canvas.instance + } + ); + + __CREATE_INSTANCE__; + +}; + +/** + * Update Renderer.D2 Instance + */ +R3.Renderer.D2.prototype.updateInstance = function(property) { + + if (property === 'canvas') { + console.warn('todo: D2 canvas update'); + return; + } + + R3.Renderer.prototype.updateInstance.call(this, property); +}; + diff --git a/src/r3-renderer-d3-0.js b/src/r3-renderer-d3-0.js new file mode 100644 index 0000000..0a10679 --- /dev/null +++ b/src/r3-renderer-d3-0.js @@ -0,0 +1,245 @@ +/** + * R3.Renderer.D3 + * @param inherited + * @constructor + */ +R3.Renderer.D3 = function( + inherited +) { + + __INHERIT_ONLY__; + + this.linkedComponents.viewports = [R3.D3.Viewport]; + this.linkedComponents.scenes = [R3.D3.Scene]; + + R3.Renderer.call( + this, + true + ); + +}; + +R3.Renderer.D3.prototype = Object.create(R3.Renderer.prototype); +R3.Renderer.D3.prototype.constructor = R3.Renderer.D3; + +/** + * Even though this class cannot be instantiated directly - it can do common tasks for its children + * @returns {*} + */ +R3.Renderer.D3.prototype.createInstance = function() { + + if (!this.instance) { + throw new Error('R3.Renderer.D3 createInstance called out of order'); + } + + this.updateInstance('autoClear'); + this.updateInstance('autoClearColor'); + this.updateInstance('autoClearDepth'); + this.updateInstance('autoClearStencil'); + this.updateInstance('gammaFactor'); + this.updateInstance('gammaInput'); + this.updateInstance('gammaOutput'); + this.updateInstance('maxMorphTargets'); + this.updateInstance('maxMorphNormals'); + this.updateInstance('physicallyCorrectLights'); + this.updateInstance('shadowMapEnabled'); + this.updateInstance('shadowMapAutoUpdate'); + this.updateInstance('shadowMapNeedsUpdate'); + this.updateInstance('shadowMapType'); + this.updateInstance('sortObjects'); + this.updateInstance('toneMapping'); + this.updateInstance('toneMappingExposure'); + this.updateInstance('toneMappingWhitePoint'); + this.updateInstance('localClippingEnabled'); + this.updateInstance('clippingPlanes'); + this.updateInstance('clearColor'); + this.updateInstance('viewports'); + this.updateInstance('opacity'); + this.updateInstance('pixelRatio'); + + __CREATE_INSTANCE__; + +}; + +/** + * Update Renderer.D3 Instance + */ +R3.Renderer.D3.prototype.updateInstance = function(property) { + + if (!property) { + throw new Error('no renderer property'); + } + + if (!this.instance) { + throw new Error('no renderer instance'); + } + + if (property === 'autoClear') { + this.instance.autoClear = this.autoClear; + return; + } + + if (property === 'autoClearColor') { + this.instance.autoClearColor = this.autoClearColor; + return; + } + + if (property === 'autoClearDepth') { + this.instance.autoClearDepth = this.autoClearDepth; + return; + } + + if (property === 'autoClearStencil') { + this.instance.autoClearStencil = this.autoClearStencil; + return; + } + + if (property === 'gammaFactor') { + this.instance.gammaFactor = this.gammaFactor; + return; + } + + if (property === 'gammaInput') { + this.instance.gammaInput = this.gammaInput; + return; + } + + if (property === 'gammaOutput') { + this.instance.gammaOutput = this.gammaOutput; + return; + } + + if (property === 'maxMorphTargets') { + this.instance.maxMorphTargets = this.maxMorphTargets; + return; + } + + if (property === 'maxMorphNormals') { + this.instance.maxMorphNormals = this.maxMorphNormals; + return; + } + + if (property === 'physicallyCorrectLights') { + this.instance.physicallyCorrectLights = this.physicallyCorrectLights; + return; + } + + if (property === 'shadowMapEnabled') { + this.instance.shadowMap.enabled = this.shadowMapEnabled; + return; + } + + if (property === 'shadowMapAutoUpdate') { + this.instance.shadowMap.autoUpdate = this.shadowMapAutoUpdate; + return; + } + + if (property === 'shadowMapNeedsUpdate') { + this.instance.shadowMap.needsUpdate = this.shadowMapNeedsUpdate; + return; + } + + if (property === 'shadowMapType') { + this.instance.shadowMap.type = this.shadowMapType; + return; + } + + if (property === 'sortObjects') { + this.instance.sortObjects = this.sortObjects; + return; + } + + if (property === 'toneMapping') { + this.instance.toneMapping = this.toneMapping; + return; + } + + if (property === 'toneMappingExposure') { + this.instance.toneMappingExposure = this.toneMappingExposure; + return; + } + + if (property === 'toneMappingWhitePoint') { + this.instance.toneMappingWhitePoint = this.toneMappingWhitePoint; + return; + } + + if (property === 'premultipliedAlpha') { + this.instance.premultipliedAlpha = this.premultipliedAlpha; + return; + } + + if (property === 'antialias') { + this.instance.antialias = this.antialias; + return; + } + + if (property === 'stencil') { + this.instance.stencil = this.stencil; + return; + } + + if (property === 'preserveDrawingBuffer') { + this.instance.preserveDrawingBuffer = this.preserveDrawingBuffer; + return; + } + + if (property === 'depth') { + this.instance.depth = this.depth; + return; + } + + if (property === 'logarithmicDepthBuffer') { + this.instance.logarithmicDepthBuffer = this.logarithmicDepthBuffer; + return; + } + + if (property === 'localClippingEnabled') { + this.instance.localClippingEnabled = this.localClippingEnabled; + return; + } + + if (property === 'clippingPlanes') { + console.warn('todo: clipping planes change'); + return; + } + + if ( + property === 'clearColor' || + property === 'opacity' + ) { + this.instance.setClearColor( + new THREE.Color( + this.clearColor.r, + this.clearColor.g, + this.clearColor.b + ), + this.opacity + ); + return; + } + + if (property === 'viewports') { + console.warn('todo: viewports change'); + } + + if (property === 'scenes') { + console.warn('todo: scenes change'); + } + + if (property === 'alpha') { + this.instance.alpha = this.alpha; + return; + } + + if (property === 'pixelRatio') { + this.instance.setPixelRatio(this.pixelRatio); + return; + } + + R3.Renderer.prototype.updateInstance.call(this, property); +}; + +R3.Renderer.D3.prototype.clear = function() { + this.instance.clear(); +}; \ No newline at end of file diff --git a/src/r3-renderer-d3-canvas-0.js b/src/r3-renderer-d3-canvas-0.js new file mode 100644 index 0000000..ec5e1be --- /dev/null +++ b/src/r3-renderer-d3-canvas-0.js @@ -0,0 +1,96 @@ +/** + * R3.Renderer.D3.Canvas + * @param apiComponent + * @param inherited + * @constructor + */ +R3.Renderer.D3.Canvas = function( + apiComponent, + inherited +) { + + __INHERIT_AND_INSTANTIATE__; + + this.linkedComponents.canvas = R3.Canvas; + + R3.Renderer.D3.call( + this, + true + ); + +}; + +R3.Renderer.D3.Canvas.prototype = Object.create(R3.Renderer.D3.prototype); +R3.Renderer.D3.Canvas.prototype.constructor = R3.Renderer.D3.Canvas; + +/** + * Create R3.Renderer.D3 Instance + * @returns {*} + */ +R3.Renderer.D3.Canvas.prototype.createInstance = function() { + + if ( + R3.Utils.UndefinedOrNull(this.canvas) || + R3.Utils.UndefinedOrNull(this.canvas.instance) + ) { + console.warn('no canvas instance or canvas not ready'); + return; + } + + this.instance = this.graphics.Renderer3D(this); + + R3.Renderer.D3.prototype.createInstance.call(this); +}; + +/** + * Update Renderer.D3 Instance + */ +R3.Renderer.D3.Canvas.prototype.updateInstance = function(property) { + + if (property === 'canvas') { + + if (this.canvas && this.canvas.instance) { + this.instance.dispose(); + this.createInstance(); + + R3.Event.Emit( + R3.Event.RENDERER_SIZE_CHANGE, + this + ) + + } else { + /** + * The canvas object was unassigned + */ + console.warn('The canvas object was unassigned - this will break something - do not save now') + } + + return; + } + + R3.Renderer.D3.prototype.updateInstance.call(this, property); +}; + +/** + * Return the size of the canvas + * @returns {{width: *, height: *}} + */ +R3.Renderer.D3.Canvas.prototype.getSize = function() { + return R3.API.Renderer.D3.Canvas.prototype.getSize.call(this); +}; + +/** + * Return the aspect ratio of the canvas + * @returns {*} + */ +R3.Renderer.D3.Canvas.prototype.getCanvasAspectRatio = function() { + return R3.API.Renderer.D3.Canvas.prototype.getCanvasAspectRatio.call(this); +}; + +/** + * Returns the size information of the canvas + * @returns {{width, aspectRatio, height}} + */ +R3.Renderer.D3.Canvas.prototype.getCanvasSize = function() { + return R3.API.Renderer.D3.Canvas.prototype.getCanvasSize.call(this); +}; \ No newline at end of file diff --git a/src/r3-renderer-d3-canvas-target.js b/src/r3-renderer-d3-canvas-target.js new file mode 100644 index 0000000..af49c8b --- /dev/null +++ b/src/r3-renderer-d3-canvas-target.js @@ -0,0 +1,96 @@ +/** + * R3.Renderer.D3.Canvas.Target + * @param apiComponent + * @constructor + */ +R3.Renderer.D3.Canvas.Target = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.linkedComponents.target = R3.D3.RenderTarget; + + R3.Renderer.D3.Canvas.call( + this, + apiComponent, + true + ); + +}; + +R3.Renderer.D3.Canvas.Target.prototype = Object.create(R3.Renderer.D3.Canvas.prototype); +R3.Renderer.D3.Canvas.Target.prototype.constructor = R3.Renderer.D3.Canvas.Target; + +/** + * Create R3.Renderer.D3 Instance + * @returns {*} + */ +R3.Renderer.D3.Canvas.Target.prototype.createInstance = function() { + + if ( + R3.Utils.UndefinedOrNull(this.target) || + R3.Utils.UndefinedOrNull(this.target.instance) + ) { + throw new Error('target not ready'); + } + + /** + * We can't call the canvas createInstance because it will call component create instance before being able + * to assign the render target + */ + if ( + R3.Utils.UndefinedOrNull(this.canvas) || + R3.Utils.UndefinedOrNull(this.canvas.instance) + ) { + console.warn('no canvas instance or canvas not ready'); + return; + } + + this.instance = this.graphics.Renderer3D(this); + + /** + * So we skip the canvas createInstance but call the rest of the parent class createInstances + */ + R3.Renderer.D3.prototype.createInstance.call(this); + +}; + +/** + * Update Renderer.D3 Instance + */ +R3.Renderer.D3.Canvas.Target.prototype.updateInstance = function(property) { + + if (property === 'target') { + + console.warn('todo also check for target being set to null or unassigned'); + + if ( + R3.Utils.Defined(this.instance) && + R3.Utils.Defined(this.target) && + R3.Utils.Defined(this.target.instance) + ) { + this.instance.setRenderTarget(this.target.instance); + + /** + * The size probably changed + */ + R3.Event.Emit( + R3.Event.RENDERER_SIZE_CHANGE, + this + ) + } + + return; + } + + R3.Renderer.D3.Canvas.prototype.updateInstance.call(this, property); +}; + +/** + * Return the size of the target instead of the canvas + * @returns {{width: *, height: *}} + */ +R3.Renderer.D3.Canvas.Target.prototype.getSize = function() { + return R3.API.Renderer.D3.Canvas.Target.prototype.getSize.call(this); +}; diff --git a/src/r3-runtime-0.js b/src/r3-runtime-0.js new file mode 100644 index 0000000..2303bf1 --- /dev/null +++ b/src/r3-runtime-0.js @@ -0,0 +1,18 @@ +/** + * R3.Runtime + * + * All Runtimes should extend this + * + * @constructor + */ +R3.Runtime = function() { + +}; + +R3.Runtime.GRAPHICS = 0x1; +R3.Runtime.PHYSICS = 0x2; +R3.Runtime.SOCKETS = 0x3; +R3.Runtime.STATISTICS = 0x4; +R3.Runtime.DEFAULT = 0x5; +R3.Runtime.GUI = 0x6; +R3.Runtime.CODER = 0x7; \ No newline at end of file diff --git a/src/r3-runtime-coder-0.js b/src/r3-runtime-coder-0.js new file mode 100644 index 0000000..440a324 --- /dev/null +++ b/src/r3-runtime-coder-0.js @@ -0,0 +1,11 @@ +/** + * R3.Runtime.Coder + * @constructor + */ +R3.Runtime.Coder = function() { + R3.Runtime.call(this); +}; + +R3.Runtime.Coder.prototype = Object.create(R3.Runtime.prototype); +R3.Runtime.Coder.prototype.constructor = R3.Runtime.Coder; + diff --git a/src/r3-runtime-coder-codemirror.js b/src/r3-runtime-coder-codemirror.js new file mode 100644 index 0000000..f2e9ea5 --- /dev/null +++ b/src/r3-runtime-coder-codemirror.js @@ -0,0 +1,35 @@ +/** + * R3.Runtime.Coder.CodeMirror + * @constructor + */ +R3.Runtime.Coder.CodeMirror = function() { + + R3.Runtime.Coder.call( + this + ); + + this.editor = null; + + this.createInstance(); +}; + +R3.Runtime.Coder.CodeMirror.prototype = Object.create(R3.Runtime.Coder.prototype); +R3.Runtime.Coder.CodeMirror.prototype.constructor = R3.Runtime.Coder.CodeMirror; + +R3.Runtime.Coder.CodeMirror.prototype.createInstance = function() { + this.instance = CodeMirror; +}; + +R3.Runtime.Coder.CodeMirror.prototype.launchEditor = function( + runtimeComponent, + property +) { + this.editor = CodeMirror.fromTextArea(myTextarea, { + lineNumbers: true + }); +}; + +R3.Runtime.Coder.CodeMirror.prototype.closeEditor = function() { + this.editor.close(); +}; + diff --git a/src/r3-runtime-graphics-0.js b/src/r3-runtime-graphics-0.js new file mode 100644 index 0000000..16908f4 --- /dev/null +++ b/src/r3-runtime-graphics-0.js @@ -0,0 +1,513 @@ +/** + * R3.Runtime.Graphics + * @constructor + */ +R3.Runtime.Graphics = function() { + + R3.Runtime.call(this); + +}; + +R3.Runtime.Graphics.prototype = Object.create(R3.Runtime.prototype); +R3.Runtime.Graphics.prototype.constructor = R3.Runtime.Graphics; + +R3.Runtime.Graphics.prototype.Vector2 = function(x,y) { + console.warn('override Vector2 in child class'); +}; + +R3.Runtime.Graphics.prototype.Vector3 = function(x,y,z) { + console.warn('override Vector3 in child class'); +}; + +R3.Runtime.Graphics.prototype.Vector4 = function(x,y,z,w) { + console.warn('override Vector4 in child class'); +}; + +R3.Runtime.Graphics.prototype.Box3 = function(x,y,z) { + console.warn('override Box3 in child class'); +}; + +R3.Runtime.Graphics.prototype.Color = function(r,g,b,a) { + console.warn('override Color in child class'); +}; + +R3.Runtime.Graphics.prototype.Matrix4 = function(rows) { + console.warn('override Matrix4 in child class'); +}; + +R3.Runtime.Graphics.prototype.Quaternion = function(x, y, z, w) { + console.warn('override Quaternion in child class'); +}; + +R3.Runtime.Graphics.prototype.Clock = function() { + console.warn('override Clock in child class'); +}; + +R3.Runtime.Graphics.prototype.EditorControls = function(canvas, camera) { + console.warn('override EditorControls in child class'); +}; + +R3.Runtime.Graphics.prototype.OrbitControls = function(canvas, camera) { + console.warn('override OrbitControls in child class'); +}; + +R3.Runtime.Graphics.prototype.FirstPersonControls = function(canvas, camera) { + console.warn('override FirstPersonControls in child class'); +}; + +R3.Runtime.Graphics.prototype.Curve = function(arcLenghDivisions) { + console.warn('override Curve in child class'); +}; + +R3.Runtime.Graphics.prototype.CurvePath = function(curves, autoClose) { + console.warn('override CurvePath in child class'); +}; + +R3.Runtime.Graphics.prototype.Path = function(points) { + console.warn('override Path in child class'); +}; + +R3.Runtime.Graphics.prototype.Shape = function(points) { + console.warn('override Shape in child class'); +}; + +R3.Runtime.Graphics.prototype.Audio = function( + path, + loop, + volume, + camera, +) { + console.warn('override Audio in child class'); +}; + +R3.Runtime.Graphics.prototype.Bone = function( + position, + rotation, + scale, + quaternion, + lookAt, + up +) { + console.warn('override Bone in child class'); +}; + +R3.Runtime.Graphics.prototype.CubeCamera = function(near, far, cubeResolution) { + console.warn('override CubeCamera in child class'); +}; + +R3.Runtime.Graphics.prototype.OrthographicCamera = function( + left, + right, + top, + bottom, + near, + far +) { + console.warn('override OrthographicCamera in child class'); +}; + +R3.Runtime.Graphics.prototype.PerspectiveCamera = function( + fov, + aspect, + near, + far +) { + console.warn('override PerspectiveCamera in child class'); +}; + +R3.Runtime.Graphics.prototype.StereoCamera = function( + fov, + aspect, + near, + far +) { + console.warn('override StereoCamera in child class'); +}; + +R3.Runtime.Graphics.prototype.RenderTarget = function( + width, + height, + wrapS, + wrapT, + magFilter, + minFilter, + format, + type, + anisotropy, + encoding, + depthBuffer, + stencilBuffer +) { + console.warn('override RenderTarget in child class'); +}; + +R3.Runtime.Graphics.prototype.Composer = function( + renderer, + renderTarget, + passes, + size +) { + console.warn('override Composer in child class'); +}; + +R3.Runtime.Graphics.prototype.Renderer3D = function( + canvas, + alpha, + premultipliedAlpha, + antialias, + stencil, + preserveDrawingBuffer, + depth, + logarithmicDepthBuffer +) { + console.warn('override Renderer3D in child class'); +}; + +R3.Runtime.Graphics.prototype.AnaglyphEffect = function( + renderer +) { + console.warn('override AnaglyphEffect in child class'); +}; + +R3.Runtime.Graphics.prototype.ParallaxEffect = function( + renderer +) { + console.warn('override ParallaxEffect in child class'); +}; + +R3.Runtime.Graphics.prototype.StereoEffect = function( + renderer +) { + console.warn('override StereoEffect in child class'); +}; + +R3.Runtime.Graphics.prototype.Face = function( + runtimeObject +) { + console.warn('override Face in child class'); +}; + +R3.Runtime.Graphics.prototype.FogExp = function( + color, + density +) { + console.warn('override R3.Runtime.Graphics.prototype.FogExp in child class'); +}; + +R3.Runtime.Graphics.prototype.Fog = function( + color, + near, + far +) { + console.warn('override R3.Runtime.Graphics.prototype.Fog in child class'); +}; + +R3.Runtime.Graphics.prototype.Raycaster = function( + position, + direction +) { + console.warn('override R3.Runtime.Graphics.prototype.Raycaster in child class'); +}; + +R3.Runtime.Graphics.prototype.Plane = function( + normal, + constant +) { + console.warn('override R3.Runtime.Graphics.prototype.Plane in child class'); +}; + +R3.Runtime.Graphics.prototype.Sphere = function( + center, + radius +) { + console.warn('override R3.Runtime.Graphics.prototype.Sphere in child class'); +}; + +R3.Runtime.Graphics.prototype.PassFXAA = function ( + width, + height +) { + console.warn('override R3.Runtime.Graphics.prototype.PassFXAA in child class'); +}; + +R3.Runtime.Graphics.prototype.PassBloom = function ( + size, + strength, + radius, + threshold +) { + console.warn('override R3.Runtime.Graphics.prototype.PassBloom in child class'); +}; + +R3.Runtime.Graphics.prototype.PassCopy = function () { + console.warn('override R3.Runtime.Graphics.prototype.PassCopy in child class'); +}; + +R3.Runtime.Graphics.prototype.PassRender = function ( + scene, + camera +) { + console.warn('override R3.Runtime.Graphics.prototype.PassRender in child class'); +}; + +R3.Runtime.Graphics.prototype.PassSSAO = function ( + scene, + camera, + size, + radius, + onlyAO, + aoClamp, + lumInfluence +) { + console.warn('override R3.Runtime.Graphics.prototype.PassSSAO in child class'); +}; + +R3.Runtime.Graphics.prototype.Geometry = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.Geometry in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBuffer = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBuffer in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferBox = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferBox in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferCircle = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferCircle in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferCone = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferCone in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferCylinder = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferCylinder in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferDodecahedron = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferDodecahedron in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferExtrude = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferExtrude in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferIcosahedron = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferIcosahedron in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferInstanced = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferInstanced in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferLathe = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferLathe in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferOctahedron = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferOctahedron in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferSphere = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferOctahedron in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferParametric = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferOctahedron in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferPlane = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferOctahedron in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferPolyhedron = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferOctahedron in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferRing = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferRing in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferShape = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferShape in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferText = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferText in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferTetrahedron = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferTetrahedron in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferTorus = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferTorus in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferTorusKnot = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferTorusKnot in child class'); +}; + +R3.Runtime.Graphics.prototype.GeometryBufferTube = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.GeometryBufferTube in child class'); +}; + +R3.Runtime.Graphics.prototype.Helper = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.Helper in child class'); +}; + +R3.Runtime.Graphics.prototype.LightAmbient = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.LightAmbient in child class'); +}; + +R3.Runtime.Graphics.prototype.LightDirectional = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.LightDirectional in child class'); +}; + +R3.Runtime.Graphics.prototype.LightHemisphere = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.LightHemisphere in child class'); +}; + +R3.Runtime.Graphics.prototype.LightPoint = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.LightPoint in child class'); +}; + +R3.Runtime.Graphics.prototype.LightRectArea = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.LightRectArea in child class'); +}; + +R3.Runtime.Graphics.prototype.LightSpot = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.LightSpot in child class'); +}; + +R3.Runtime.Graphics.prototype.MaterialBasic = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.MaterialBasic in child class'); +}; + +R3.Runtime.Graphics.prototype.MaterialPhong = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.MaterialPhong in child class'); +}; + +R3.Runtime.Graphics.prototype.MaterialPoints = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.MaterialPoints in child class'); +}; + +R3.Runtime.Graphics.prototype.MaterialShader = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.MaterialShader in child class'); +}; + +R3.Runtime.Graphics.prototype.MaterialShaderRaw = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.MaterialShaderRaw in child class'); +}; + +R3.Runtime.Graphics.prototype.MaterialStandard = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.MaterialStandard in child class'); +}; + +R3.Runtime.Graphics.prototype.Mesh = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.Mesh in child class'); +}; + +R3.Runtime.Graphics.prototype.MeshSkeleton = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.MeshSkeleton in child class'); +}; + +R3.Runtime.Graphics.prototype.Table = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.Table in child class'); +}; + +R3.Runtime.Graphics.prototype.MetricNumber = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.MetricNumber in child class'); +}; + +R3.Runtime.Graphics.prototype.BarchartStacked = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.BarchartStacked in child class'); +}; + +R3.Runtime.Graphics.prototype.updateInstance = function (runtimeObject, property) { + console.warn('override R3.Runtime.Graphics.prototype.updateInstance in child class'); +}; diff --git a/src/r3-runtime-graphics-chart.js b/src/r3-runtime-graphics-chart.js new file mode 100644 index 0000000..e9e285a --- /dev/null +++ b/src/r3-runtime-graphics-chart.js @@ -0,0 +1,77 @@ +/** + * R3.Runtime.Graphics.Chart + * @constructor + */ +R3.Runtime.Graphics.Chart = function() { + + R3.Runtime.Graphics.call( + this + ); + + this.createInstance(); +}; + +R3.Runtime.Graphics.Chart.prototype = Object.create(R3.Runtime.Graphics.prototype); +R3.Runtime.Graphics.Chart.prototype.constructor = R3.Runtime.Graphics.Chart; + +/** + * Create R3.Runtime.Graphics.Chart Instance + * @returns {*} + */ +R3.Runtime.Graphics.Chart.prototype.createInstance = function() { + this.instance = Chart; +}; + +/** + * + * @param runtimeObject + * @constructor + */ +R3.Runtime.Graphics.Chart.prototype.BarchartStacked = function(runtimeObject) { + + var domElement = document.getElementById(runtimeObject.domElement.domElementId); + // + // var divs = domElement.parentElement.getElementsByTagName('div'); + // + // for (var div of divs) { + // domElement.parentElement.removeChild(div); + // } + + var ctx = domElement.getContext('2d'); + + + + var barChartData = { + labels: runtimeObject.query.labels, + datasets: runtimeObject.query.datasets + }; + + Chart.defaults.global.defaultFontColor = '#414141ee'; + + runtimeObject.chart = new Chart(ctx, { + type: 'bar', + data: barChartData, + options: { + title: { + display: true + }, + tooltips: { + mode: 'index', + intersect: false + }, + responsive: true, + maintainAspectRatio: false, + scales: { + xAxes: [{ + stacked: true, + }], + yAxes: [{ + stacked: true + }] + } + } + }); + + return true; + +}; diff --git a/src/r3-runtime-graphics-custom.js b/src/r3-runtime-graphics-custom.js new file mode 100644 index 0000000..df4eba6 --- /dev/null +++ b/src/r3-runtime-graphics-custom.js @@ -0,0 +1,34 @@ +/** + * R3.Runtime.Graphics.Custom + * @constructor + */ +R3.Runtime.Graphics.Custom = function() { + + R3.Runtime.Graphics.call( + this + ); + + this.createInstance(); +}; + +R3.Runtime.Graphics.Custom.prototype = Object.create(R3.Runtime.Graphics.prototype); +R3.Runtime.Graphics.Custom.prototype.constructor = R3.Runtime.Graphics.Custom; + +/** + * Create R3.Runtime.Graphics.Custom Instance + * @returns {*} + */ +R3.Runtime.Graphics.Custom.prototype.createInstance = function() { + this.instance = true; +}; + +/** + * + * @param runtimeObject + * @constructor + */ +R3.Runtime.Graphics.Custom.prototype.MetricNumber = function(runtimeObject) { + + document.getElementById(runtimeObject.domElement.id).innerText = runtimeObject.parsed.count; + +}; diff --git a/src/r3-runtime-graphics-google.js b/src/r3-runtime-graphics-google.js new file mode 100644 index 0000000..564cf47 --- /dev/null +++ b/src/r3-runtime-graphics-google.js @@ -0,0 +1,234 @@ +/** + * R3.Runtime.Graphics.Google + * @constructor + */ +R3.Runtime.Graphics.Google = function() { + + R3.Runtime.Graphics.call( + this + ); + + this.createInstance(); +}; + +R3.Runtime.Graphics.Google.prototype = Object.create(R3.Runtime.Graphics.prototype); +R3.Runtime.Graphics.Google.prototype.constructor = R3.Runtime.Graphics.Google; + +/** + * Create R3.Runtime.Graphics.Google Instance + * @returns {*} + */ +R3.Runtime.Graphics.Google.prototype.createInstance = function() { + this.instance = google.charts; +}; + +R3.Runtime.Graphics.Google.Tooltip = function(domTable, table, graph) { + + var tooltip = document.createElement('div'); + tooltip.setAttribute('class', 'google-visualization-tooltip tooltip-minimized'); + + var header = document.createElement('div'); + header.setAttribute('class', 'tooltip-header'); + + var headerTitle = document.createElement('div'); + headerTitle.innerText = 'Click for more info...'; + + var button = document.createElement('button'); + button.setAttribute('class', 'btn btn-info btn-white close-button'); + button.innerText = 'X'; + + header.appendChild(headerTitle); + header.appendChild(button); + + var tooltipContent = document.createElement('pre'); + + tooltip.appendChild(header); + tooltip.appendChild(tooltipContent); + + if (graph.tooltip) { + document.body.removeChild(graph.tooltip); + } + + graph.tooltip = tooltip; + + document.body.appendChild(tooltip); + + if (graph.mouseover) { + domTable.removeEventListener('mouseover', graph.mouseover); + } + + if (graph.mouseout) { + domTable.removeEventListener('mouseout', graph.mouseout); + } + + if (graph.mousemove) { + domTable.removeEventListener('mousemove', graph.mousemove); + } + + graph.mouseover = function(tooltip) { + return function(event) { + tooltip.style.display = 'flex'; + tooltip.style.left = (event.pageX + 10) + "px"; + tooltip.style.top = (event.pageY + 10) + "px"; + }; + }(tooltip); + + graph.mouseout = function(tooltip) { + return function(event) { + tooltip.style.display = 'none'; + }; + }(tooltip); + + graph.mousemove = function(tooltip) { + return function(event) { + tooltip.style.left = (event.pageX + 10) + "px"; + tooltip.style.top = (event.pageY + 10) + "px"; + }; + }(tooltip); + + button.addEventListener('click', function(graph, tooltip, button, domTable) { + return function(event) { + domTable.addEventListener('mouseover', graph.mouseover); + domTable.addEventListener('mouseout', graph.mouseout); + domTable.addEventListener('mousemove', graph.mousemove); + tooltip.style.left = (event.pageX + 10) + "px"; + tooltip.style.top = (event.pageY + 10) + "px"; + tooltip.style.display = 'none'; + tooltip.setAttribute('class', 'google-visualization-tooltip tooltip-minimized'); + button.style.display = 'none'; + } + }(graph, tooltip, button, domTable)); + + google.visualization.events.addListener( + table, + 'ready', + function(domTable, graph) { + return function() { + domTable.addEventListener('mouseover', graph.mouseover); + domTable.addEventListener('mouseout', graph.mouseout); + domTable.addEventListener('mousemove', graph.mousemove); + }; + }(domTable, graph) + ); + + google.visualization.events.addListener( + table, + 'select', + function(domTable, graph, tooltipContent) { + return function() { + domTable.removeEventListener('mouseover', graph.mouseover); + domTable.removeEventListener('mouseout', graph.mouseout); + domTable.removeEventListener('mousemove', graph.mousemove); + tooltip.setAttribute('class', 'google-visualization-tooltip tooltip-maximized'); + button.style.display = 'block'; + + var selection = table.getSelection(); + + var row = 0; + + if (selection && selection[0]) { + row = selection[0].row + } + + tooltipContent.innerHTML = R3.Utils.SyntaxHighlight(JSON.stringify(graph.query.tooltips[row], null, 2)); + } + }(domTable, graph, tooltipContent) + ); + + return { + main : tooltip, + closeButton : button, + header : header, + title : headerTitle, + content : tooltipContent + }; +}; + +R3.Runtime.Graphics.Google.prototype.Table = function(runtimeObject) { + + google.charts.load('current', {'packages':['table']}); + google.charts.setOnLoadCallback( + + function(graph) { + + return function() { + + var dataTable = new google.visualization.DataTable(); + + // var makeTooltipActive = function(object, moveEventListener, overOutEventListener, table) { + // return function(event) { + // var selection = table.getSelection(); + // + // object.domElement.instance.removeEventListener('mousemove', moveTooltip); + // + // var closeButton = document.getElementById('button-close-tooltip'); + // closeButton.style.display = 'block'; + // var tooltip = document.getElementById('div-tooltip'); + // tooltip.setAttribute('class', 'google-visualization-tooltip tooltip-maximized'); + // var tooltipContent = document.getElementById('pre-tooltip-content'); + // tooltipContent.style.display = 'block'; + // + // + // var row = selection[0].row; + // var tooltip = document.getElementById('div-tooltip'); + // var tooltipContent = document.getElementById('pre-tooltip-content'); + // var tooltipHeader = document.getElementById('div-tooltip-header'); + // tooltipContent.innerHTML = R3.Utils.SyntaxHighlight(JSON.stringify(object.query.tooltips[row], null, 2)); + // tooltip.style.display = 'flex'; + // moveTooltip(event); + // + // } + // }; + // + // var closeButtonClick = ; + // + // var closeButton = document.getElementById('button-close-tooltip'); + // closeButton.addEventListener('click', closeButtonClick); + + graph.columns.map( + function(column) { + dataTable.addColumn(column.type, column.name); + } + ); + + dataTable.addRows(graph.rows); + + var domTable = document.getElementById(graph.domElement.domElementId); + + var table = new google.visualization.Table(domTable); + + var tooltip = R3.Runtime.Graphics.Google.Tooltip( + domTable, + table, + graph + ); + + table.draw( + dataTable, + { + showRowNumber: false, + allowHtml : true, + cssClassNames: { + tableCell: 'fixed-row-height', + hoverTableRow : 'hover-row' + }, + width: '100%', + height: '100%', + page: 'enable', + pageSize: graph.pageSize, + sortColumn: graph.columns.length - 1, + sortAscending : false, + pagingSymbols: { + prev: 'prev', + next: 'next' + }, + pagingButtonsConfiguration: 'auto' + } + ); + } + }(runtimeObject) + + ); + + return true; +}; diff --git a/src/r3-runtime-graphics-pixi.js b/src/r3-runtime-graphics-pixi.js new file mode 100644 index 0000000..8761e3b --- /dev/null +++ b/src/r3-runtime-graphics-pixi.js @@ -0,0 +1,40 @@ +/** + * R3.Runtime.Graphics.Pixi + * @constructor + */ +R3.Runtime.Graphics.Pixi = function() { + + R3.Runtime.Graphics.call( + this + ); + + this.createInstance(); +}; + +R3.Runtime.Graphics.Pixi.prototype = Object.create(R3.Runtime.Graphics.prototype); +R3.Runtime.Graphics.Pixi.prototype.constructor = R3.Runtime.Graphics.Pixi; + +/** + * Create R3.Runtime.Graphics.Pixi Instance + * @returns {*} + */ +R3.Runtime.Graphics.Pixi.prototype.createInstance = function() { + this.instance = PIXI; +}; + +R3.Runtime.Graphics.Pixi.prototype.Canvas = function(runtimeObject) { + + var instance = document.createElement('canvas'); + + instance.setAttribute('id', runtimeObject.id); + + instance.setAttribute('tabindex', runtimeObject.tabIndex); + + instance.setAttribute('width', runtimeObject.width); + + instance.setAttribute('height', runtimeObject.height); + + instance.setAttribute('style', 'width:' + runtimeObject.width + 'px;height:' + runtimeObject.height + 'px'); + + return instance; +}; \ No newline at end of file diff --git a/src/r3-runtime-graphics-three.js b/src/r3-runtime-graphics-three.js new file mode 100644 index 0000000..2b85cef --- /dev/null +++ b/src/r3-runtime-graphics-three.js @@ -0,0 +1,2131 @@ +/** + * R3.Runtime.Graphics.Three + * @constructor + */ +R3.Runtime.Graphics.Three = function() { + + R3.Runtime.Graphics.call( + this + ); + + this.createInstance(); +}; + +R3.Runtime.Graphics.Three.prototype = Object.create(R3.Runtime.Graphics.prototype); +R3.Runtime.Graphics.Three.prototype.constructor = R3.Runtime.Graphics.Three; + +/** + * Create R3.Runtime.Graphics.Three Instance + * @returns {*} + */ +R3.Runtime.Graphics.Three.prototype.createInstance = function() { + this.instance = true; +}; + +R3.Runtime.Graphics.Three.prototype.Canvas = function(runtimeObject) { + + var instance = document.createElement('canvas'); + + instance.setAttribute('id', runtimeObject.id); + + instance.setAttribute('tabindex', runtimeObject.tabIndex); + + instance.setAttribute('width', runtimeObject.width); + + instance.setAttribute('height', runtimeObject.height); + + instance.setAttribute('style', 'width:' + runtimeObject.width + 'px;height:' + runtimeObject.height + 'px'); + + if (this.autoUpdateSize) { + /** + * Update our size from the instance size + */ + runtimeObject.width = instance.width; + runtimeObject.height = instance.height; + } else { + /** + * Update our instance with our size + */ + instance.width = runtimeObject.width; + instance.height = runtimeObject.height; + } + + return instance; + +}; + +R3.Runtime.Graphics.Three.prototype.Vector2 = function(x,y) { + return new THREE.Vector2(x,y); +}; + +R3.Runtime.Graphics.Three.prototype.Vector3 = function(x,y,z) { + return new THREE.Vector3(x,y,z); +}; + +R3.Runtime.Graphics.Three.prototype.Vector4 = function(x,y,z,w) { + return new THREE.Vector4(x,y,z,w); +}; + +R3.Runtime.Graphics.Three.prototype.Color = function(r,g,b,a) { + return new THREE.Color(r,g,b); +}; + +R3.Runtime.Graphics.Three.prototype.Matrix4 = function(rows) { + + var 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 + */ + instance.set( + rows[0].x, + rows[1].x, + rows[2].x, + rows[3].x, + rows[0].y, + rows[1].y, + rows[2].y, + rows[3].y, + rows[0].z, + rows[1].z, + rows[2].z, + rows[3].z, + rows[0].w, + rows[1].w, + rows[2].w, + rows[3].w + ); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.Box3 = function(min,max) { + return new THREE.Box3(min.instance, max.instance); +}; + +R3.Runtime.Graphics.Three.prototype.Quaternion = function(x, y, z, w) { + return new THREE.Quaternion(x,y,z,w); +}; + +R3.Runtime.Graphics.Three.prototype.Clock = function() { + return new THREE.Clock(); +}; + +// R3.Runtime.Graphics.Three.prototype.EditorControls = function(canvas, camera) { +// +// if (!canvas || !canvas.instance) { +// throw new Error('no canvas instance at time of EditorControls creation'); +// } +// +// if (!camera || !camera.instance) { +// throw new Error('no camera instance at time of EditorControls creation'); +// } +// +// return new THREE.EditorControls( +// camera.instance, +// canvas.instance +// ); +// }; + +R3.Runtime.Graphics.Three.prototype.OrbitControlsInstance = function(controls) { + + controls.instance = new THREE.OrbitControls( + controls.camera.instance, + controls.canvas.instance + ); + + controls.updateInstance('enabled'); + controls.updateInstance('minPolarAngle'); + controls.updateInstance('maxPolarAngle'); + controls.updateInstance('enableDamping'); + controls.updateInstance('dampingFactor'); + controls.updateInstance('enableZoom'); + controls.updateInstance('zoomSpeed'); + controls.updateInstance('enableRotate'); + controls.updateInstance('rotateSpeed'); + controls.updateInstance('enablePan'); + controls.updateInstance('keyPanSpeed'); + controls.updateInstance('autoRotate'); + controls.updateInstance('autoRotateSpeed'); + controls.updateInstance('enableKeys'); + controls.updateInstance('target'); + + return controls.instance; + +}; + +/** + * R3.Runtime.Graphics.Three.prototype.OrbitControls + * @param runtimeObject + * @returns {boolean|*} + * @constructor + */ +R3.Runtime.Graphics.Three.prototype.OrbitControls = function(runtimeObject) { + + if (!runtimeObject.canvas) { + throw new Error('no canvas at time of OrbitControls creation'); + } + + if (!runtimeObject.camera) { + throw new Error('no camera at time of OrbitControls creation'); + } + + if (!runtimeObject.canvas.instance || + !runtimeObject.camera.instance + ) { + + /** + * This code below exists to solve the 'chicken/egg' problem when it comes to controls. + * Controls need a canvas instance to bind to - but they belong to canvasses - so we can't create their + * instances until the canvas instance is loaded, but the canvas would normally not load until their sub- + * components have loaded (i.e. the controls) - below code fixes this + * @type {{fn, remove}} + */ + this.createInstanceSubscription = R3.Event.Subscribe( + R3.Event.INSTANCE_CREATED, + function(controls) { + return function(data) { + + if (data.component === controls.canvas) { + + if (controls.camera.instance) { + + /** + * We are ready to construct this instance + */ + + this.OrbitControlsInstance(controls); + + this.createInstanceSubscription.remove(); + + } + } + + if (data.component === controls.camera) { + + if (controls.canvas.instance) { + /** + * We are ready to construct this instance + */ + + this.OrbitControlsInstance(controls); + + this.createInstanceSubscription.remove(); + } + + } + }.bind(this); + }(runtimeObject) + ); + + return true; + } + + return this.OrbitControlsInstance(runtimeObject); + +}; + +R3.Runtime.Graphics.Three.prototype.FirstPersonControlsInstance = function(controls) { + + controls.instance = new THREE.FirstPersonControls( + controls.camera.instance, + controls.canvas.instance + ); + + controls.updateInstance('enabled'); + controls.updateInstance('movementSpeed'); + controls.updateInstance('lookSpeed'); + controls.updateInstance('lookVertical'); + controls.updateInstance('autoForward'); + controls.updateInstance('activeLook'); + controls.updateInstance('heightSpeed'); + controls.updateInstance('heightCoef'); + controls.updateInstance('heightMin'); + controls.updateInstance('heightMax'); + controls.updateInstance('constrainVertical'); + controls.updateInstance('verticalMin'); + controls.updateInstance('verticalMax'); + controls.updateInstance('autoSpeedFactor'); + + return controls.instance; +}; + +/** + * R3.Runtime.Graphics.Three.prototype.FirstPersonControls + * @param runtimeObject + * @returns {boolean|*} + * @constructor + */ +R3.Runtime.Graphics.Three.prototype.FirstPersonControls = function(runtimeObject) { + + if (!runtimeObject.canvas) { + throw new Error('no canvas at time of FirstPersonControls creation'); + } + + if (!runtimeObject.camera) { + throw new Error('no camera at time of FirstPersonControls creation'); + } + + if (!runtimeObject.canvas.instance || + !runtimeObject.camera.instance + ) { + /** + * This code below exists to solve the 'chicken/egg' problem when it comes to controls. + * Controls need a canvas instance to bind to - but they belong to canvasses - so we can't create their + * instances until the canvas instance is loaded, but the canvas would normally not load until their sub- + * components have loaded (i.e. the controls) - below code fixes this + * @type {{fn, remove}} + */ + this.createInstanceSubscription = R3.Event.Subscribe( + R3.Event.INSTANCE_CREATED, + function(controls) { + return function(data) { + + if (data.component === controls.canvas) { + + if (controls.camera.instance) { + + /** + * We are ready to construct this instance + */ + + this.FirstPersonControlsInstance(controls); + + this.createInstanceSubscription.remove(); + + } + } + + if (data.component === controls.camera) { + + if (controls.canvas.instance) { + /** + * We are ready to construct this instance + */ + + this.FirstPersonControlsInstance(controls); + + this.createInstanceSubscription.remove(); + } + + } + }.bind(this); + }(runtimeObject) + ); + + return true; + } + + return this.FirstPersonControlsInstance(runtimeObject); + +}; + +R3.Runtime.Graphics.Three.prototype.Curve = function(arcLenghDivisions) { + var curve = new THREE.Curve(); + curve.arcLenghDivisions = arcLenghDivisions; + return curve; +}; + +R3.Runtime.Graphics.Three.prototype.CurvePath = function(curves, autoClose) { + + var curvePath = new THREE.CurvePath(); + + curvePath.curves = curves.reduce( + function(result, curve){ + + if (!curve.instance) { + throw new Error('curve instance not ready'); + } + + result.push(curve.instance); + return result; + }, + [] + ); + + curvePath.autoClose = autoClose; + + return curvePath; +}; + +R3.Runtime.Graphics.Three.prototype.Path = function(points) { + + return new THREE.Path( + points.map( + function(point) { + + if (!point.instance) { + throw new Error('no point instance'); + } + + return point.instance; + } + ) + ); + +}; + +R3.Runtime.Graphics.Three.prototype.Shape = function(points) { + + return new THREE.Shape( + points.map( + function(point) { + + if (!point.instance) { + throw new Error('no point instance'); + } + + return point.instance; + } + ) + ); + +}; + +/** + * Returns an Audio object - this object still has to load so don't do anything with it yet + * @param path + * @param loop + * @param volume + * @param camera + * @returns {boolean|*} + * @constructor + */ +R3.Runtime.Graphics.Three.prototype.Audio = function( + path, + loop, + volume, + camera +) { + + /** + * First off - fuck microsoft - their audio doesn't work + */ + if (document.documentMode || /Edge/.test(navigator.userAgent)) { + return true; + } + + var audio = null; + + R3.Event.Emit( + R3.Event.GET_PROJECT, + null, + function(project) { + + R3.Event.Emit( + R3.Event.GET_API_URL, + null, + function (data) { + + + /** + * Get the API URL + */ + var apiUrl = data.apiUrl; + + /** + * We need a listener and add it to the camera + * @type {THREE.AudioListener} + */ + var listener = new THREE.AudioListener(); + camera.instance.add(listener); + + /** + * We need an audio object + */ + audio = new THREE.Audio(listener); + + /** + * Now we need to load the audio file + */ + var audioLoader = new THREE.AudioLoader(); + + console.log('loading audio : ' + component.name); + + try { + audioLoader.load( + apiUrl + path + '?ts=' + Date.now(), + function (buffer) { + + console.log('loaded audio: ' + component.name); + + audio.setBuffer(buffer); + audio.setLoop(loop); + audio.setVolume(volume); + + __CREATE_INSTANCE__; + } + ); + } catch (error) { + console.warn('failed to load audio - does it exist? : ' + error.message || 'unknown reason'); + return true; + } + + } + ); + } + ); + + return audio; + +}; + +R3.Runtime.Graphics.Three.prototype.Bone = function( + position, + rotation, + scale, + quaternion, + lookAt, + up +) { + console.warn('todo: test bones'); + + var instance = new THREE.Bone(); + + instance.position = position.instance; + instance.rotation = rotation.instance; + instance.scale = scale.instance; + instance.quaternion = quaternion.instance; + instance.lookAt = lookAt.instance; + instance.up = up.instance; + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.CubeCamera = function(near, far, cubeResolution) { + + return new THREE.CubeCamera( + near, + far, + cubeResolution + ); + +}; + +R3.Runtime.Graphics.Three.prototype.OrthographicCamera = function( + left, + right, + top, + bottom, + near, + far +) { + return new THREE.OrthographicCamera( + left, + right, + top, + bottom, + near, + far + ); +}; + +R3.Runtime.Graphics.Three.prototype.PerspectiveCamera = function(runtimeObject) { + + var instance = new THREE.PerspectiveCamera( + runtimeObject.fov, + runtimeObject.aspectRatio, + runtimeObject.near, + runtimeObject.far + ); + + instance.filmGauge = runtimeObject.filmGauge; + instance.filmOffset = runtimeObject.filmOffset; + instance.focus = runtimeObject.focus; + instance.zoom = runtimeObject.zoom; + + instance.position.set( + runtimeObject.position.x, + runtimeObject.position.y, + runtimeObject.position.z + ); + + instance.lookAt(0,0,0); + + instance.updateProjectionMatrix(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.StereoCamera = function(runtimeObject) { + + var instance = R3.Runtime.Graphics.Three.prototype.PerspectiveCamera(runtimeObject); + var stereo = new THREE.StereoCamera(); + + stereo.update(instance); + + instance.userData.stereo = stereo; + + return instance; + +}; + + +R3.Runtime.Graphics.Three.prototype.RenderTarget = function( + width, + height, + wrapS, + wrapT, + magFilter, + minFilter, + format, + type, + anisotropy, + encoding, + depthBuffer, + stencilBuffer +) { + return new THREE.WebGLRenderTarget( + this.width, + this.height, + { + wrapS : wrapS, + wrapT : wrapT, + magFilter : magFilter, + minFilter : minFilter, + format : format, + type : type, + anisotropy : anisotropy, + encoding : encoding, + depthBuffer : depthBuffer, + stencilBuffer : stencilBuffer, + } + ); +}; + +R3.Runtime.Graphics.Three.prototype.Composer = function( + runtimeObject +) { + if (R3.Utils.Unloaded(runtimeObject.renderer)) { + throw new Error('no renderer instance'); + } + + var renderTargetInstance = undefined; + + if (R3.Utils.Loaded(runtimeObject.renderTarget)) { + renderTargetInstance = runtimeObject.renderTarget.instance; + } + + var composer = new THREE.EffectComposer( + runtimeObject.renderer.instance, + renderTargetInstance + ); + + runtimeObject.passes.map( + function(pass) { + + if (R3.Utils.Unloaded(pass)) { + throw new Error('Pass not loaded yet.'); + } + + composer.addPass(pass.instance); + } + ); + + return composer; +}; + +R3.Runtime.Graphics.Three.prototype.Renderer3D = function(runtimeObject){ + + var instance = new THREE.WebGLRenderer( + { + canvas : runtimeObject.canvas.instance, + alpha : runtimeObject.alpha, + premultipliedAlpha : runtimeObject.premultipliedAlpha, + antialias : runtimeObject.antialias, + stencil : runtimeObject.stencil, + preserveDrawingBuffer : runtimeObject.preserveDrawingBuffer, + depth : runtimeObject.depth, + logarithmicDepthBuffer : runtimeObject.logarithmicDepthBuffer + } + ); + + if (R3.Utils.Defined(runtimeObject.target)) { + instance.setRenderTarget(runtimeObject.target.instance); + } + + return instance; + +}; + +R3.Runtime.Graphics.Three.prototype.AnaglyphEffect = function( + renderer +) { + return new THREE.AnaglyphEffect( + renderer.instance + ); +}; + +R3.Runtime.Graphics.Three.prototype.ParallaxEffect = function( + renderer +) { + return new THREE.ParallaxBarrierEffect( + renderer.instance + ); +}; + +R3.Runtime.Graphics.Three.prototype.StereoEffect = function( + renderer, + eyeSeperation +) { + var instance = THREE.StereoEffect( + renderer.instance + ); + + instance.setEyeSeparation( + eyeSeperation + ); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.Face = function( + runtimeObject +) { + + var face = new THREE.Face3( + runtimeObject.vertexIndices[0], + runtimeObject.vertexIndices[1], + runtimeObject.vertexIndices[2] + ); + + face.normal = runtimeObject.normal.instance; + + face.color = runtimeObject.color.instance; + + if (materialIndex > -1) { + face.materialIndex = materialIndex; + } + + runtimeObject.vertices.map( + function(vertex, index) { + face.vertexColors[index] = vertex.color.instance; + } + ); + +}; + +R3.Runtime.Graphics.Three.prototype.FogExp = function(runtimeObject) { + return new THREE.FogExp2( + runtimeObject.fogColor.toHex(), + runtimeObject.density + ); +}; + +R3.Runtime.Graphics.Three.prototype.Fog = function(runtimeObject) { + return new THREE.Fog( + runtimeObject.fogColor.toHex(), + runtimeObject.near, + runtimeObject.far + ); +}; + + +R3.Runtime.Graphics.Three.prototype.Raycaster = function( + position, + direction +) { + var instance = new THREE.Raycaster(); + instance.set( + position.instance, + direction.instance + ); + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.Plane = function( + normal, + constant +) { + return new THREE.Plane( + normal.instance, + constant + ); +}; + +R3.Runtime.Graphics.Three.prototype.Sphere = function( + center, + radius +) { + return new THREE.Sphere( + center.instance, + radius + ); +}; + +R3.Runtime.Graphics.Three.prototype.PassFXAA = function (runtimeObject) { + + var instance = new THREE.ShaderPass(THREE.FXAAShader); + + instance.uniforms['resolution'].value.set( + 1 / runtimeObject.width, + 1 / runtimeObject.height + ); + + // instance.renderToScreen = this.renderToScreen; + // + // instance.enabled = this.enabled; + // + // instance.clear = this.clear; + // + // instance.needsSwap = this.needsSwap; + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.PassBloom = function (runtimeObject) { + return new THREE.UnrealBloomPass( + runtimeObject.size.instance, + runtimeObject.strength, + runtimeObject.radius, + runtimeObject.threshold + ); + +}; + +R3.Runtime.Graphics.Three.prototype.PassCopy = function () { + return new THREE.ShaderPass(THREE.CopyShader); +}; + +R3.Runtime.Graphics.Three.prototype.PassRender = function (runtimeObject) { + return new THREE.RenderPass( + runtimeObject.scene.instance, + runtimeObject.camera.instance + ); +}; + +R3.Runtime.Graphics.Three.prototype.PassSSAO = function ( + scene, + camera, + size, + radius, + onlyAO, + aoClamp, + lumInfluence +) { + var instance = new THREE.SSAOPass( + scene.instance, + camera.instance, + size.x, + size.y + ); + + instance.radius = radius; + + instance.onlyAO = onlyAO; + + instance.aoClamp = aoClamp; + + instance.lumInfluence = lumInfluence; + + return instance; + +}; + +R3.Runtime.Graphics.Three.prototype.Geometry = function ( + runtimeObject +) { + console.warn('override R3.Runtime.Graphics.prototype.Geometry in child class'); + + var instance = new THREE.Geometry(); + + runtimeObject.vertices.map( + function(vertex) { + instance.vertices.push(vertex.instance); + } + ); + + + + instance.computeBoundingBox(); + + instance.computeBoundingSphere(); + + return instance; + +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBuffer = function ( + runtimeObject +) { + var instance = new THREE.BufferGeometry(); + + /** + * Setup mesh vertices positions + * @type {Float32Array} + */ + this.updateInstance(runtimeObject, 'positions', instance); + + this.updateInstance(runtimeObject, 'vertexColors', instance); + + this.updateInstance(runtimeObject, 'uvs', instance); + + this.updateInstance(runtimeObject, 'normals', instance); + + instance.setDrawRange( + runtimeObject.drawRange.start, + runtimeObject.drawRange.count + ); + + runtimeObject.groups.map( + function(group) { + instance.addGroup( + group.start, + group.count, + group.materialIndex + ) + } + ); + + /** + * 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 = runtimeObject.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(result, group) { + instance.addGroup(result, group.count, group.index); + return result + group.count; + }, + 0 + ); + +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferBox = function ( + runtimeObject +) { + + var instance = new THREE.BoxBufferGeometry( + runtimeObject.width, + runtimeObject.height, + runtimeObject.depth, + runtimeObject.widthSegments, + runtimeObject.heightSegments, + runtimeObject.depthSegments + ); + + instance.computeVertexNormals(); + + return instance; +}; + + +R3.Runtime.Graphics.Three.prototype.GeometryBufferCircle = function ( + runtimeObject +) { + + var instance = new THREE.CircleBufferGeometry( + runtimeObject.radius, + runtimeObject.segments, + runtimeObject.thetaStart, + runtimeObject.thetaLength + ); + + instance.computeVertexNormals(); + + return instance; + +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferCone = function ( + runtimeObject +) { + var instance = new THREE.ConeBufferGeometry( + runtimeObject.radius, + runtimeObject.height, + runtimeObject.radialSegments, + runtimeObject.heightSegments, + runtimeObject.openEnded, + runtimeObject.thetaStart, + runtimeObject.thetaLength + ); + + instance.computeVertexNormals(); + + return instance; + +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferCylinder = function ( + runtimeObject +) { + var instance = new THREE.CylinderBufferGeometry( + runtimeObject.radiusTop, + runtimeObject.radiusBottom, + runtimeObject.height, + runtimeObject.radialSegments, + runtimeObject.heightSegments, + runtimeObject.openEnded, + runtimeObject.thetaStart, + runtimeObject.thetaLength + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferDodecahedron = function ( + runtimeObject +) { + var instance = new THREE.DodecahedronBufferGeometry( + runtimeObject.radius, + runtimeObject.detail + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferExtrude = function ( + runtimeObject +) { + var instance = new THREE.ExtrudeBufferGeometry( + runtimeObject.shapes.map( + function(shape) { + return shape.instance; + } + ), + { + curveSegments : runtimeObject.curveSegments, + steps : runtimeObject.steps, + amount : runtimeObject.amount, + bevelEnabled : runtimeObject.bevelEnabled, + bevelThickness : runtimeObject.bevelThickness, + bevelSize : runtimeObject.bevelSize, + bevelSegments : runtimeObject.bevelSegments + } + ); + + instance.computeVertexNormals(); + + return instance; +}; + + +R3.Runtime.Graphics.Three.prototype.GeometryBufferIcosahedron = function ( + runtimeObject +) { + + var instance = new THREE.IcosahedronBufferGeometry( + runtimeObject.radius, + runtimeObject.detail + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferInstanced = function ( + runtimeObject +) { + var instance = new THREE.InstancedBufferGeometry(); + + instance.maxInstancedCount = runtimeObject.maxInstancedCount; + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferLathe = function ( + runtimeObject +) { + var instance = new THREE.LatheBufferGeometry( + runtimeObject.points.map( + function(point) { + return point.instance; + } + ), + runtimeObject.segments, + runtimeObject.phiStart, + runtimeObject.phiLength + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferOctahedron = function ( + runtimeObject +) { + var instance = new THREE.OctahedronBufferGeometry( + runtimeObject.radius, + runtimeObject.detail + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferSphere = function ( + runtimeObject +) { + var instance = new THREE.SphereBufferGeometry( + runtimeObject.radius, + runtimeObject.widthSegments, + runtimeObject.heightSegments, + runtimeObject.phiStart, + runtimeObject.phiLength, + runtimeObject.thetaStart, + runtimeObject.thetaLength + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferParametric = function ( + runtimeObject +) { + var instance = new THREE.ParametricBufferGeometry( + new Function('u', 'v', runtimeObject.generatorFn).bind(runtimeObject), + runtimeObject.slices, + runtimeObject.stacks + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferPlane = function ( + runtimeObject +) { + var instance = new THREE.PlaneBufferGeometry( + runtimeObject.width, + runtimeObject.height, + runtimeObject.widthSegments, + runtimeObject.heightSegments + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferPolyhedron = function ( + runtimeObject +) { + var instance = new THREE.PolyhedronBufferGeometry( + runtimeObject.vertices.map( + function(vertex) { + return vertex.position.instance; + } + ), + runtimeObject.indices.map( + function(index) { + return index.instance; + } + ), + runtimeObject.radius, + runtimeObject.detail + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferRing = function ( + runtimeObject +) { + var instance = new THREE.RingBufferGeometry( + runtimeObject.innerRadius, + runtimeObject.outerRadius, + runtimeObject.thetaSegments, + runtimeObject.phiSegments, + runtimeObject.thetaStart, + runtimeObject.thetaLength + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferShape = function ( + runtimeObject +) { + var instance = new THREE.ShapeBufferGeometry( + runtimeObject.shapes.map( + function(shape) { + return shape.instance; + } + ), + runtimeObject.curveSegments + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferTetrahedron = function ( + runtimeObject +) { + var instance = new THREE.TetrahedronBufferGeometry( + runtimeObject.radius, + runtimeObject.detail + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferText = function ( + runtimeObject +) { + var instance = new THREE.TextBufferGeometry( + runtimeObject.text, + { + font : runtimeObject.font.instance, + size : runtimeObject.size, + curveSegments : runtimeObject.curveSegments, + steps : runtimeObject.steps, + amount : runtimeObject.amount, + bevelEnabled : runtimeObject.bevelEnabled, + bevelThickness : runtimeObject.bevelThickness, + bevelSize : runtimeObject.bevelSize, + bevelSegments : runtimeObject.bevelSegments + } + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferTorus = function ( + runtimeObject +) { + var instance = new THREE.TorusBufferGeometry( + runtimeObject.radius, + runtimeObject.tube, + runtimeObject.radialSegments, + runtimeObject.tubularSegments, + runtimeObject.arc + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferTorusKnot = function ( + runtimeObject +) { + var instance = new THREE.TorusKnotBufferGeometry( + runtimeObject.radius, + runtimeObject.tube, + runtimeObject.radialSegments, + runtimeObject.tubularSegments, + runtimeObject.p, + runtimeObject.q + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.GeometryBufferTube = function ( + runtimeObject +) { + var instance = new THREE.TubeBufferGeometry( + runtimeObject.path.instance, + runtimeObject.tubularSegments, + runtimeObject.radius, + runtimeObject.radialSegments, + runtimeObject.closed + ); + + instance.computeVertexNormals(); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.Helper = function ( + runtimeObject +) { + + var object = runtimeObject.parent; + + var instance = null; + + if (object instanceof R3.D3.Mesh) { + var wireframe = new THREE.WireframeGeometry(this.object.instance.geometry); + instance = new THREE.LineSegments( wireframe ); + instance.material.depthTest = false; + instance.material.opacity = 0.25; + instance.material.transparent = true; + } + + if (object instanceof R3.D3.Light.Directional) { + instance = new THREE.DirectionalLightHelper(this.object.instance); + } + + if (object instanceof R3.D3.Light.Point) { + instance = new THREE.PointLightHelper(this.object.instance); + } + + if (object instanceof R3.D3.Light.Spot) { + instance = new THREE.SpotLightHelper(this.object.instance); + } + + if (object instanceof R3.D3.Skeleton) { + instance = new THREE.SkeletonHelper(this.object.instance); + } + + return instance; +}; + + +R3.Runtime.Graphics.Three.prototype.LightAmbient = function ( + runtimeObject +) { + return new THREE.AmbientLight( + runtimeObject.color.toHex(), + runtimeObject.intensity + ); +}; + +R3.Runtime.Graphics.Three.prototype.LightDirectional = function ( + runtimeObject +) { + var instance = new THREE.DirectionalLight( + runtimeObject.color.toHex(), + runtimeObject.intensity + ); + + instance.castShadow = runtimeObject.castShadow; + + instance.position = runtimeObject.position.instance; + + /** + * Shadows work different - their instances are created internally by three.js and we need to + * assign them to our shadow runtime at creation of the light instance, and update them accordingly + * + * See comment at R3.D3.Shadow + */ + if (runtimeObject.shadow === null) { + /** + * This object was created at runtime - so initialize it properly + */ + runtimeObject.shadow = new R3.D3.Shadow.Directional(); + runtimeObject.shadow.instance = instance.shadow; + runtimeObject.shadow.updateFromInstanceAll(); + } else { + /** + * This object came from the API - so update the instance with saved settings + */ + runtimeObject.shadow.instance = instance.shadow; + runtimeObject.shadow.updateInstanceAll(); + } + + /** + * Assign our target + */ + instance.target = runtimeObject.target.instance; + + return instance; + +}; + +R3.Runtime.Graphics.Three.prototype.LightHemisphere = function ( + runtimeObject +) { + var instance = new THREE.HemisphereLight( + runtimeObject.color.toHex(), + runtimeObject.groundColor.toHex(), + runtimeObject.intensity + ); + + instance.position = runtimeObject.position.instance; + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.LightPoint = function ( + runtimeObject +) { + + var instance = new THREE.PointLight( + runtimeObject.color.toHex(), + runtimeObject.intensity, + runtimeObject.distance, + runtimeObject.decay + ); + + instance.castShadow = runtimeObject.castShadow; + instance.position = runtimeObject.position.instance; + instance.power = runtimeObject.power; + + /** + * Shadows work different - their instances are created internally by three.js and we need to + * assign them to our shadow runtime at creation of the light instance, and update them accordingly + * + * See comment at R3.D3.Shadow + */ + if (runtimeObject.shadow === null) { + /** + * This object was created at runtime - so initialize it properly + */ + runtimeObject.shadow = new R3.D3.Shadow.Directional(); + runtimeObject.shadow.instance = instance.shadow; + runtimeObject.shadow.updateFromInstanceAll(); + } else { + /** + * This object came from the API - so update the instance with saved settings + */ + runtimeObject.shadow.instance = instance.shadow; + runtimeObject.shadow.updateInstanceAll(); + } + + return instance; + +}; + +R3.Runtime.Graphics.Three.prototype.LightRectArea = function ( + runtimeObject +) { + var instance = new THREE.RectAreaLight( + runtimeObject.color.toHex(), + runtimeObject.intensity, + runtimeObject.width, + runtimeObject.height + ); + + instance.position = runtimeObject.position.instance; + + instance.lookAt(runtimeObject.lookAt.instance); + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.LightSpot = function ( + runtimeObject +) { + var instance = new THREE.SpotLight( + runtimeObject.color.toHex(), + runtimeObject.intensity, + runtimeObject.distance, + runtimeObject.angle, + runtimeObject.penumbra, + runtimeObject.decay + ); + + instance.castShadow = runtimeObject.castShadow; + instance.position = runtimeObject.position.instance; + + /** + * Shadows work different - their instances are created internally by three.js and we need to + * assign them to our shadow runtime at creation of the light instance, and update them accordingly + * + * See comment at R3.D3.Shadow + */ + if (runtimeObject.shadow === null) { + /** + * This object was created at runtime - so initialize it properly + */ + runtimeObject.shadow = new R3.D3.Shadow.Directional(); + runtimeObject.shadow.instance = instance.shadow; + runtimeObject.shadow.updateFromInstanceAll(); + } else { + /** + * This object came from the API - so update the instance with saved settings + */ + runtimeObject.shadow.instance = instance.shadow; + runtimeObject.shadow.updateInstanceAll(); + } + + instance.target = this.target.instance; + + return instance; +}; + +R3.Runtime.Graphics.Three.prototype.getMaterialParams = function( + runtimeObject +) { + return { + alphaTest : runtimeObject.alphaTest, + blendDst : runtimeObject.blendDst, + blendDstAlpha : runtimeObject.blendDstAlpha, + blendEquation : runtimeObject.blendEquation, + blendEquationAlpha : runtimeObject.blendEquationAlpha, + blending : runtimeObject.blending, + blendSrc : runtimeObject.blendSrc, + blendSrcAlpha : runtimeObject.blendSrcAlpha, + clipIntersection : runtimeObject.clipIntersection, + clippingPlanes : runtimeObject.clippingPlanes, + clipShadows : runtimeObject.clipShadows, + colorWrite : runtimeObject.colorWrite, + defines : runtimeObject.defines, + depthFunc : runtimeObject.depthFunc, + depthTest : runtimeObject.depthTest, + depthWrite : runtimeObject.depthWrite, + dithering : runtimeObject.dithering, + flatShading : runtimeObject.flatShading, + fog : runtimeObject.fog, + lights : runtimeObject.lights, + opacity : runtimeObject.opacity, + overdraw : runtimeObject.overdraw, + polygonOffset : runtimeObject.polygonOffset, + polygonOffsetFactor : runtimeObject.polygonOffsetFactor, + polygonOffsetUnits : runtimeObject.polygonOffsetUnits, + precision : runtimeObject.precision, + premultipliedAlpha : runtimeObject.premultipliedAlpha, + side : runtimeObject.side, + stencilWrite : runtimeObject.stencilWrite, + stencilFunc : runtimeObject.stencilFunc, + stencilRef : runtimeObject.stencilRef, + stencilMask : runtimeObject.stencilMask, + stencilFail : runtimeObject.stencilFail, + stencilZFail : runtimeObject.stencilZFail, + stencilZPass : runtimeObject.stencilZPass, + transparent : runtimeObject.transparent, + vertexColors : runtimeObject.vertexColors, + visible : runtimeObject.visible + } +}; + +R3.Runtime.Graphics.Three.prototype.MaterialBasic = function ( + runtimeObject +) { + + var params = this.getMaterialParams(runtimeObject); + + params.alphaMap = runtimeObject.alphaMap ? runtimeObject.alphaMap.instance : null; + params.aoMap = runtimeObject.aoMap ? runtimeObject.aoMap.instance : null; + params.aoMapIntensity = runtimeObject.aoMapIntensity; + params.color = runtimeObject.color.instance; + params.envMap = runtimeObject.envMap ? runtimeObject.envMap.instance : null; + params.lightMap = runtimeObject.lightMap ? runtimeObject.lightMap.instance : null; + params.lightMapIntensity = runtimeObject.lightMapIntensity; + params.map = runtimeObject.diffuseMap ? runtimeObject.diffuseMap.instance : null; + params.morphTargets = runtimeObject.morphTargets; + params.reflectivity = runtimeObject.reflectivity; + params.refractionRatio = runtimeObject.refractionRatio; + params.skinning = runtimeObject.skinning; + params.specularMap = runtimeObject.specularMap ? runtimeObject.specularMap.instance : null; + params.wireframe = runtimeObject.wireframe; + params.wireframeLinecap = runtimeObject.wireframeLinecap; + params.wireframeLinejoin = runtimeObject.wireframeLinejoin; + params.wireframeLinewidth = runtimeObject.wireframeLinewidth; + + return new THREE.MeshBasicMaterial(params); + +}; + +R3.Runtime.Graphics.Three.prototype.MaterialPhong = function ( + runtimeObject +) { + var params = this.getMaterialParams(runtimeObject); + + params.alphaMap = runtimeObject.alphaMap ? this.alphaMap.instance : null; + params.aoMap = runtimeObject.aoMap ? this.aoMap.instance : null; + params.aoMapIntensity = runtimeObject.aoMapIntensity; + params.bumpMap = runtimeObject.bumpMap ? this.bumpMap.instance : null; + params.bumpScale = runtimeObject.bumpScale; + params.color = runtimeObject.color.instance; + params.combine = runtimeObject.combine; + params.displacementMap = runtimeObject.displacementMap ? this.displacementMap.instance : null; + params.displacementScale = runtimeObject.displacementScale; + params.displacementBias = runtimeObject.displacementBias; + params.emissive = runtimeObject.emissive.instance; + params.emissiveMap = runtimeObject.emissiveMap ? this.emissiveMap.instance : null; + params.emissiveIntensity = runtimeObject.emissiveIntensity; + params.envMap = runtimeObject.envMap ? this.envMap.instance : null; + params.lightMap = runtimeObject.lightMap ? this.lightMap.instance : null; + params.lightMapIntensity = runtimeObject.lightMapIntensity; + params.map = runtimeObject.diffuseMap ? this.diffuseMap.instance : null; + params.morphNormals = runtimeObject.morphNormals; + params.morphTargets = runtimeObject.morphTargets; + params.normalMap = runtimeObject.normalMap ? this.normalMap.instance : null; + params.normalScale = runtimeObject.normalScale; + params.reflectivity = runtimeObject.reflectivity; + params.refractionRatio = runtimeObject.refractionRatio; + params.shininess = runtimeObject.shininess; + params.skinning = runtimeObject.skinning; + params.specular = runtimeObject.specular.instance; + params.specularMap = runtimeObject.specularMap ? this.specularMap.instance : null; + params.wireframe = runtimeObject.wireframe; + params.wireframeLinecap = runtimeObject.wireframeLinecap; + params.wireframeLinejoin = runtimeObject.wireframeLinejoin; + params.wireframeLinewidth = runtimeObject.wireframeLinewidth; + + return new THREE.MeshPhongMaterial(params); +}; + +R3.Runtime.Graphics.Three.prototype.MaterialPoints = function ( + runtimeObject +) { + + var params = this.getMaterialParams(runtimeObject); + + params.color = runtimeObject.color.instance; + params.map = runtimeObject.diffuseMap ? this.diffuseMap.instance : null; + params.morphTargets = runtimeObject.morphTargets; + params.size = runtimeObject.size; + params.sizeAttenuation = runtimeObject.sizeAttenuation; + + return new THREE.PointsMaterial(params); + +}; + +R3.Runtime.Graphics.Three.prototype.MaterialShader = function ( + runtimeObject +) { + var params = this.getMaterialParams(runtimeObject); + + params.clipping = runtimeObject.clipping; + params.defaultAttributeValues = runtimeObject.defaultAttributeValues; + params.defines = runtimeObject.defines; + params.extensions = runtimeObject.extensions; + params.fragmentShader = runtimeObject.fragmentShader.instance; + params.index0AttributeName = runtimeObject.index0AttributeName; + params.linewidth = runtimeObject.linewidth; + params.morphTargets = runtimeObject.morphTargets; + params.morphNormals = runtimeObject.morphNormals; + params.program = runtimeObject.program; + params.skinning = runtimeObject.skinning; + params.uniforms = runtimeObject.uniforms; + params.vertexShader = runtimeObject.vertexShader.instance; + params.wireframe = runtimeObject.wireframe; + params.wireframeLinewidth = runtimeObject.wireframeLinewidth; + + return new THREE.ShaderMaterial(params); +}; + +R3.Runtime.Graphics.Three.prototype.MaterialShaderRaw = function ( + runtimeObject +) { + var params = this.getMaterialParams(runtimeObject); + + params.clipping = runtimeObject.clipping; + params.defaultAttributeValues = runtimeObject.defaultAttributeValues; + params.defines = runtimeObject.defines; + params.extensions = runtimeObject.extensions; + params.fragmentShader = runtimeObject.fragmentShader.instance; + params.index0AttributeName = runtimeObject.index0AttributeName; + params.linewidth = runtimeObject.linewidth; + params.morphTargets = runtimeObject.morphTargets; + params.morphNormals = runtimeObject.morphNormals; + params.program = runtimeObject.program; + params.skinning = runtimeObject.skinning; + params.uniforms = runtimeObject.uniforms; + params.vertexShader = runtimeObject.vertexShader.instance; + params.wireframe = runtimeObject.wireframe; + params.wireframeLinewidth = runtimeObject.wireframeLinewidth; + + return new THREE.RawShaderMaterial(params); +}; + +R3.Runtime.Graphics.Three.prototype.MaterialStandard = function ( + runtimeObject +) { + var params = this.getMaterialParams(runtimeObject); + + params.alphaMap = runtimeObject.alphaMap ? this.alphaMap.instance : null; + params.aoMap = runtimeObject.aoMap ? this.aoMap.instance : null; + params.aoMapIntensity = runtimeObject.aoMapIntensity; + params.bumpMap = runtimeObject.bumpMap ? this.bumpMap.instance : null; + params.bumpScale = runtimeObject.bumpScale; + params.color = runtimeObject.color.instance; + params.displacementMap = runtimeObject.displacementMap ? this.displacementMap.instance : null; + params.displacementScale = runtimeObject.displacementScale; + params.displacementBias = runtimeObject.displacementBias; + params.emissive = runtimeObject.emissive.instance; + params.emissiveMap = runtimeObject.emissiveMap ? this.emissiveMap.instance : null; + params.emissiveIntensity = runtimeObject.emissiveIntensity; + params.envMap = runtimeObject.envMap ? this.envMap.instance : null; + params.envMapIntensity = runtimeObject.envMapIntensity; + params.lightMap = runtimeObject.lightMap ? this.lightMap.instance : null; + params.lightMapIntensity = runtimeObject.lightMapIntensity; + params.map = runtimeObject.diffuseMap ? this.diffuseMap.instance : null; + params.metalness = runtimeObject.metalness; + params.metalnessMap = runtimeObject.metalnessMap ? this.metalnessMap.instance : null; + params.morphNormals = runtimeObject.morphNormals; + params.morphTargets = runtimeObject.morphTargets; + params.normalMap = runtimeObject.normalMap ? this.normalMap.instance : null; + params.normalScale = runtimeObject.normalScale; + params.refractionRatio = runtimeObject.refractionRatio; + params.roughness = runtimeObject.roughness; + params.roughnessMap = runtimeObject.roughnessMap ? this.roughnessMap.instance : null; + params.skinning = runtimeObject.skinning; + params.wireframe = runtimeObject.wireframe; + params.wireframeLinecap = runtimeObject.wireframeLinecap; + params.wireframeLinejoin = runtimeObject.wireframeLinejoin; + params.wireframeLinewidth = runtimeObject.wireframeLinewidth; + + return new THREE.MeshStandardMaterial(params); +}; + +R3.Runtime.Graphics.Three.prototype.Mesh = function ( + runtimeObject +) { + + var geometry = null; + var materials = null; + + if (!R3.Utils.Unloaded(runtimeObject.geometry)) { + geometry = runtimeObject.geometry.instance; + } + + if (!R3.Utils.Unloaded(runtimeObject.material)) { + materials = R3.Utils.GetArrayInstances(runtimeObject.materials); + } + + var instance = new THREE.Mesh( + geometry, + materials + ); + + instance.position = runtimeObject.position.instance; + instance.rotation = runtimeObject.rotation.instance; + instance.scale = runtimeObject.scale.instance; + instance.name = runtimeObject.name; + instance.renderOrder = runtimeObject.renderOrder; + instance.visible = runtimeObject.visible; + instance.castShadow = runtimeObject.castShadow; + instance.receiveShadow = runtimeObject.receiveShadow; + instance.drawMode = runtimeObject.drawMode; + + return instance; + +}; + +R3.Runtime.Graphics.Three.prototype.MeshSkeleton = function ( + runtimeObject +) { + throw new Error('todo: implement R3.Runtime.Graphics.Three.prototype.MeshSkeleton'); +}; + +R3.Runtime.Graphics.Three.prototype.Scene = function ( + runtimeObject +) { + + var instance = new THREE.Scene(); + + instance.name = runtimeObject.name; + + if (R3.Utils.Instance(runtimeObject.fog)) { + instance.fog = runtimeObject.fog.instance; + } + + runtimeObject.meshes.map( + function(mesh) { + instance.add(mesh.instance); + } + ); + + runtimeObject.lights.map( + function(light) { + instance.add(light.instance); + } + ); + + return instance; +}; + +/** + * R3.Runtime.Graphics.Three.prototype.updateInstance + * @param runtimeObject + * @param property + * @param instance - if provided, use this as the instance object instead of using the runtimeObject instance + */ +R3.Runtime.Graphics.Three.prototype.updateInstance = function (runtimeObject, property, instance) { + + if (R3.Utils.UndefinedOrNull(instance)) { + instance = runtimeObject.instance; + } + + if (R3.Utils.UndefinedOrNull(instance)) { + throw new Error('no instance available for update'); + } + + if (runtimeObject instanceof R3.D3.Fog.Exp) { + + if (property === 'density') { + instance[property] = runtimeObject[property]; + return; + } + + } + + if (runtimeObject instanceof R3.D3.Fog.Normal) { + + if ( + property === 'near' || + property === 'far' + ) { + instance[property] = runtimeObject[property]; + return; + } + + } + + if (runtimeObject instanceof R3.D3.Fog) { + + if ( + property === 'fogColor' + ) { + runtimeObject.fogColor.instance.setRGB( + runtimeObject.fogColor.r, + runtimeObject.fogColor.g, + runtimeObject.fogColor.b + ); + instance.color = runtimeObject.fogColor.instance; + return; + } + + } + + + if (runtimeObject instanceof R3.D3.Pass.FXAA) { + + if ( + property === 'size' + ) { + + instance.uniforms['resolution'].value.set( + 1 / runtimeObject.width, + 1 / runtimeObject.height + ); + + return; + } + } + + if (runtimeObject instanceof R3.D3.Pass.Bloom) { + + if ( + property === 'size' + ) { + + instance.setSize( + runtimeObject.size.x, + runtimeObject.size.y + ); + + return; + } + + if (property === 'strength') { + instance.strength = runtimeObject.strength; + return; + } + + if (property === 'radius') { + instance.radius = runtimeObject.radius; + return; + } + + if (property === 'threshold') { + instance.threshold = runtimeObject.threshold; + return; + } + } + + if (runtimeObject instanceof R3.D3.Pass.Render.SSAO) { + + if (property === 'size') { + instance.width = runtimeObject.size.x; + instance.height = runtimeObject.size.y; + return; + } + + if (property === 'radius') { + instance.radius = runtimeObject.radius; + return; + } + + if (property === 'onlyAO') { + instance.onlyAO = runtimeObject.onlyAO; + return; + } + + if (property === 'aoClamp') { + instance.aoClamp = runtimeObject.aoClamp; + return; + } + + if (property === 'lumInfluence') { + instance.lumInfluence = runtimeObject.lumInfluence; + return; + } + + } + + if (runtimeObject instanceof R3.D3.Composer) { + + if (property === 'size') { + + instance.setSize( + runtimeObject.size.x, + runtimeObject.size.y + ); + + return; + } + + } + + if (runtimeObject instanceof R3.D3.Effect) { + + if (property === 'size') { + + instance.setSize( + runtimeObject.size.x, + runtimeObject.size.y + ); + + return; + } + + } + + + if (runtimeObject instanceof R3.D3.Effect.Stereo) { + + if (property === 'eyeSeperation') { + + instance.setEyeSeparation(runtimeObject.eyeSeperation); + + return; + } + + } + + if (runtimeObject instanceof R3.D3.Geometry.Buffer) { + + function disposeArray() { + this.array = null; + } + + if (property === 'positions') { + + var vertices = null; + + if (runtimeObject.indexed) { + + vertices = runtimeObject.vertices.reduce( + function(result, vertex) { + + result.push(vertex.position.x); + result.push(vertex.position.y); + result.push(vertex.position.z); + + return result; + }, + [] + ); + + var indices = runtimeObject.faces.reduce( + function (result, face) { + + result.push(face.vertexIndices[0]); + result.push(face.vertexIndices[1]); + result.push(face.vertexIndices[2]); + + return result; + }, + [] + ); + + instance.setIndex(indices); + + } else { + + /** + * Setup mesh vertices positions + * @type {Float32Array} + */ + vertices = runtimeObject.faces.reduce( + function (result, face) { + + result.push(runtimeObject.vertices[face.vertexIndices[0]].position.x); + result.push(runtimeObject.vertices[face.vertexIndices[0]].position.y); + result.push(runtimeObject.vertices[face.vertexIndices[0]].position.z); + result.push(runtimeObject.vertices[face.vertexIndices[1]].position.x); + result.push(runtimeObject.vertices[face.vertexIndices[1]].position.y); + result.push(runtimeObject.vertices[face.vertexIndices[1]].position.z); + result.push(runtimeObject.vertices[face.vertexIndices[2]].position.x); + result.push(runtimeObject.vertices[face.vertexIndices[2]].position.y); + result.push(runtimeObject.vertices[face.vertexIndices[2]].position.z); + + return result; + + }.bind(this), + [] + ); + } + + instance.addAttribute( 'position', new THREE.Float32BufferAttribute(vertices, 3)).onUpload(disposeArray); + + } + + if (property === 'vertexColors') { + + var colors = null; + + if (runtimeObject.indexed) { + colors = runtimeObject.vertices.reduce( + function(result, vertex){ + + result.push( + vertex.color.r, + vertex.color.g, + vertex.color.b + ); + + return result; + + }, + [] + ); + } else { + colors = runtimeObject.faces.reduce( + function (result, face) { + + result.push(runtimeObject.vertices[face.vertexIndices[0]].color.r); + result.push(runtimeObject.vertices[face.vertexIndices[0]].color.g); + result.push(runtimeObject.vertices[face.vertexIndices[0]].color.b); + result.push(runtimeObject.vertices[face.vertexIndices[1]].color.r); + result.push(runtimeObject.vertices[face.vertexIndices[1]].color.g); + result.push(runtimeObject.vertices[face.vertexIndices[1]].color.b); + result.push(runtimeObject.vertices[face.vertexIndices[2]].color.r); + result.push(runtimeObject.vertices[face.vertexIndices[2]].color.g); + result.push(runtimeObject.vertices[face.vertexIndices[2]].color.b); + + return result; + + }.bind(this), + [] + ); + } + + if (colors.length > 0) { + instance.addAttribute( 'color', new THREE.Float32BufferAttribute(colors, 3)).onUpload(disposeArray); + } + } + + if (property === 'uvs') { + + var uvs = null; + + if (runtimeObject.indexed) { + uvs = runtimeObject.vertices.reduce( + function(result, vertex) { + + result.push(vertex.uvs[0].x); + result.push(vertex.uvs[0].y); + + return result; + }, + [] + ); + } else { + uvs = runtimeObject.faces.reduce( + function(result, face) { + + result.push(runtimeObject.vertices[face.vertexIndices[0]].uvs[0].x); + result.push(runtimeObject.vertices[face.vertexIndices[0]].uvs[0].y); + result.push(runtimeObject.vertices[face.vertexIndices[1]].uvs[0].x); + result.push(runtimeObject.vertices[face.vertexIndices[1]].uvs[0].y); + result.push(runtimeObject.vertices[face.vertexIndices[2]].uvs[0].x); + result.push(runtimeObject.vertices[face.vertexIndices[2]].uvs[0].y); + + return result; + }, + [] + ); + } + + instance.addAttribute( 'uv', new THREE.Float32BufferAttribute(uvs, 2)).onUpload(disposeArray); + + } + + if (property === 'normals') { + + var normals = null; + + if (runtimeObject.indexed) { + normals = runtimeObject.vertices.reduce( + function(result, vertex) { + + result.push(vertex.normal.x); + result.push(vertex.normal.y); + result.push(vertex.normal.z); + + return result; + + }, + [] + ); + } else { + normals = runtimeObject.vertices.reduce( + function(result, face) { + + result.push(runtimeObject.vertices[face.vertexIndices[0]].normal.x); + result.push(runtimeObject.vertices[face.vertexIndices[0]].normal.y); + result.push(runtimeObject.vertices[face.vertexIndices[0]].normal.z); + result.push(runtimeObject.vertices[face.vertexIndices[1]].normal.x); + result.push(runtimeObject.vertices[face.vertexIndices[1]].normal.y); + result.push(runtimeObject.vertices[face.vertexIndices[1]].normal.z); + result.push(runtimeObject.vertices[face.vertexIndices[2]].normal.x); + result.push(runtimeObject.vertices[face.vertexIndices[2]].normal.y); + result.push(runtimeObject.vertices[face.vertexIndices[2]].normal.z); + + return result; + + }, + [] + ); + } + + instance.addAttribute( 'normal', new THREE.Float32BufferAttribute(normals, 3)).onUpload(disposeArray); + + } + + } + + +}; \ No newline at end of file diff --git a/src/r3-runtime-gui-0.js b/src/r3-runtime-gui-0.js new file mode 100644 index 0000000..6b0b795 --- /dev/null +++ b/src/r3-runtime-gui-0.js @@ -0,0 +1,12 @@ +/** + * R3.Runtime.GUI + * @constructor + */ +R3.Runtime.GUI = function() { + + R3.Runtime.call(this); + +}; + +R3.Runtime.GUI.prototype = Object.create(R3.Runtime.prototype); +R3.Runtime.GUI.prototype.constructor = R3.Runtime.GUI; diff --git a/src/r3-runtime-gui-controlKit.js b/src/r3-runtime-gui-controlKit.js new file mode 100644 index 0000000..46e4aad --- /dev/null +++ b/src/r3-runtime-gui-controlKit.js @@ -0,0 +1,275 @@ +/** + * R3.Runtime.GUI.ControlKit + * @constructor + */ +R3.Runtime.GUI.ControlKit = function() { + + R3.Runtime.GUI.call( + this + ); + + this.range = [-100, 100]; + + +}; + +R3.Runtime.GUI.ControlKit.prototype = Object.create(R3.Runtime.GUI.prototype); +R3.Runtime.GUI.ControlKit.prototype.constructor = R3.Runtime.GUI.ControlKit; + +R3.Runtime.GUI.ControlKit.prototype.createInstance = function() { + return new ControlKit({ + panelsClosable : true + }); +}; + +R3.Runtime.GUI.ControlKit.prototype.addComponent = function(gui, component) { + + if (component instanceof R3.Color) { + + } + + if (component instanceof R3.Vector2) { + + } + + //... + +}; + +R3.Runtime.GUI.ControlKit.prototype.getDomElement = function(gui) { + return gui.instance._node._element; +}; + +R3.Runtime.GUI.ControlKit.prototype.removeComponent = function(gui, component) { + +}; + +R3.Runtime.GUI.ControlKit.prototype.addPanel = function(gui, name) { + return gui.instance.addPanel({ + label : name, + width : 600, + fixed : false, + position : [0, 57], + align : 'right' + }); +}; + +R3.Runtime.GUI.ControlKit.prototype.addRamge = function(gui, panel) { + +}; + +R3.Runtime.GUI.ControlKit.prototype.componentUpdate = function(obj, component, property) { + return function(index) { + + if (obj.options && R3.Utils.Defined(index)) { + component[property] = obj.values[index]; + } else if (component[property] instanceof R3.Color) { + component[property].fromHex(obj.color); + } else { + component[property] = obj.value; + } + + /** + * The instance could have been destroyed already + */ + if (R3.Utils.UndefinedOrNull(component.instance)) { + console.warn('This GUI should be closed - the instance has alread been destroyed'); + return; + } + + + /** + * Here we update the property that changed of the component + */ + component.updateInstance(property); + + /** + * If this is a Vector or Quaternion component - the parent has to update its property which + * is this _component, because Vector numbers are a level deeper than the actual vector + */ + if ( + component instanceof R3.Vector2 || + component instanceof R3.Vector3 || + component instanceof R3.Vector4 || + component instanceof R3.Quaternion + ) { + for (var key in component.parent) { + if (component.parent.hasOwnProperty(key) && + component.parent[key] === component + ) { + component.parent.updateInstance(key); + return; + } + } + } + } +}; + +R3.Runtime.GUI.ControlKit.prototype.addColor = function(gui, panel, component, property) { + + var obj = { + color : component[property].toHex() + }; + + + var name = property.replace('Color',''); + name = name.replace('color',''); + + panel.addColor( + obj, + 'color', + { + colorMode : 'hex', + onChange : this.componentUpdate(obj, component, property), + label : name + ' color' + } + ) + +}; + +R3.Runtime.GUI.ControlKit.prototype.addSelect = function(gui, panel, component, property) { + + var values = component.guiInfo[property].options.reduce( + function(result, option) { + result.push(option.value); + return result; + }, + [] + ); + + var options = component.guiInfo[property].options.reduce( + function(result, option) { + result.push(option.name); + return result; + }, + [] + ); + + var obj = { + options : options, + values : values, + value : options[values.indexOf(component[property])] + }; + + panel.addSelect( + obj, + 'options', + { + onChange : this.componentUpdate(obj, component, property), + label : property, + target : 'value' + } + ) + +}; + + +R3.Runtime.GUI.ControlKit.prototype.addNumber = function(gui, panel, component, property) { + +// component.range = this.range; + + // var subgroup = null; + + + if (component.guiInfo && component.guiInfo[property]) { + // + // subgroup = panel.addSubGroup( + // { + // label : property + // } + // ); + + panel.addRange( + component.guiInfo[property], + 'range', + { + label : property + ' range' + } + ); + + var obj = { + value : component[property], + range : component.guiInfo[property].range + }; + + panel.addSlider( + obj, + 'value', + 'range', + { + dp: component.guiInfo[property].dp, + onChange: this.componentUpdate(obj, component, property), + onFinish: this.componentUpdate(obj, component, property) + } + ); + + } + + // var group = null; + // + // if (subgroup) { + // group = subgroup; + // } else { + // group = panel.getGroups()[panel.getGroups().length - 1]; + // } + + panel.addNumberOutput( + component, + property, + { + label : property + ' (read-only)', + dp : 4 + } + ); + +}; + +R3.Runtime.GUI.ControlKit.prototype.addString = function(gui, panel, component, property) { + panel.addStringInput( + component, + property + ); +}; + +R3.Runtime.GUI.ControlKit.prototype.addCheckbox = function(gui, panel, component, property) { + + var obj = { + value : component[property] + }; + + panel.addCheckbox( + obj, + 'value', { + onChange: this.componentUpdate(obj, component, property), + label : property + } + ); +}; + +R3.Runtime.GUI.ControlKit.prototype.addButton = function(gui, panel, component, property) { + panel.addButton( + property, + component[property].bind(component) + ); +}; + + + + +R3.Runtime.GUI.ControlKit.prototype.addGroup = function(gui, panel, name) { + return panel.addGroup({ + label : name + }); +}; + +R3.Runtime.GUI.ControlKit.prototype.removeGroup = function(gui, name) { + +}; + +R3.Runtime.GUI.ControlKit.prototype.removeAllGroups = function(gui) { + +}; + +R3.Runtime.GUI.ControlKit.prototype.clear = function(gui) { + +}; diff --git a/src/r3-runtime-gui-datgui.js b/src/r3-runtime-gui-datgui.js new file mode 100644 index 0000000..deeba2e --- /dev/null +++ b/src/r3-runtime-gui-datgui.js @@ -0,0 +1,1652 @@ +/** + * R3.Runtime.GUI.DatGUI + * @constructor + */ +R3.Runtime.GUI.DatGUI = function() { + + R3.Runtime.GUI.call( + this + ); + +}; + +R3.Runtime.GUI.DatGUI.prototype = Object.create(R3.Runtime.GUI.prototype); +R3.Runtime.GUI.DatGUI.prototype.constructor = R3.Runtime.GUI.DatGUI; + +R3.Runtime.GUI.DatGUI.prototype.createInstance = function() { + + /** + * 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(); + } + } + }; + + return new dat.GUI({autoPlace : false}); +}; + +R3.Runtime.GUI.DatGUI.prototype.getDomElement = function(instance) { + return instance.domElement; +}; + +R3.Runtime.GUI.DatGUI.prototype.addPanel = function(component) { + +}; + +R3.Runtime.GUI.DatGUI.prototype.addComponent = function(component) { + +}; + +R3.Runtime.GUI.DatGUI.prototype.removeComponent = function(component) { + +}; + +R3.Runtime.GUI.DatGUI.prototype.addGroup = function(name) { + try { + return this.instance.addFolder(name); + } catch (e) { + try { + name += ' duplicate (' + R3.Utils.RandomId() + ')'; + return this.instance.addFolder(name); + } catch (e) { + console.log(e.message); + return null; + } + } +}; + +R3.Runtime.GUI.DatGUI.prototype.removeGroup = function(name) { + try { + return this.instance.addFolder(name); + } catch (e) { + try { + name += ' duplicate (' + R3.Utils.RandomId() + ')'; + return this.instance.addFolder(name); + } catch (e) { + console.log(e.message); + return null; + } + } +}; + +R3.Runtime.GUI.DatGUI.prototype.removeAllFolders = function(name) { + try { + return this.instance.addFolder(name); + } catch (e) { + try { + name += ' duplicate (' + R3.Utils.RandomId() + ')'; + return this.instance.addFolder(name); + } catch (e) { + console.log(e.message); + return null; + } + } +}; + +R3.Runtime.GUI.DatGUI.prototype.clear = function(gui) { + gui.instance.destroy(); + gui.removeAllFolders(); +}; + +R3.Runtime.GUI.DatGUI.prototype.onChange = function(property, subProperty, affected) { + return function(value) { + affected.map(function(component){ + + component[property][subProperty] = value; + + if (component instanceof R3.D3.Mesh && property === 'rotation') { + component.useQuaternion = false; + } + + if (component instanceof R3.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); + } + + }); + } +}; + +R3.Runtime.GUI.DatGUI.prototype.controller = function(folder, object, property, subProperty, step, listen, affected, min, max) { + + if (R3.Utils.UndefinedOrNull(min)) { + min = -1000; + } + + if (R3.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' || + property === 'position' + ) { + min = -100; + max = 100; + step = 0.0001; + } + + if ( + property === 'scale' + ) { + min = -10; + max = 10; + step = 0.001; + } + + if ( + property === 'rotation' + ) { + min = -Math.PI * 2; + max = Math.PI * 2; + step = 0.0001; + } + + if ( + property === 'mapSize' + ) { + min = 16; + max = 4096; + step = 16; + } + + 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; +}; + +R3.Runtime.GUI.DatGUI.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'); + }) + } + ); + +}; + +R3.Runtime.GUI.DatGUI.prototype.buildVectorControl = function(folder, componentTemplate, property) { + + var step = 0.001; + + 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 (R3.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 ( + R3.Utils.IsVector3(object[property]) || + R3.Utils.IsVector4(object[property]) + ) { + controllers.push(this.controller(folder, object, property, 'z', step, listen, affected)); + } + +}; + +/** + * Builds a Parent Selection control + * @param folder + * @param componentTemplate + * @param property + */ +R3.Runtime.GUI.DatGUI.prototype.buildParentSelectionControl = function(folder, componentTemplate, property) { + + var constructor = componentTemplate.template.parent.__proto__.constructor; + + var options = R3.EntityManager.Instance.findComponentsByConstructor(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 = R3.EntityManager.Instance.findComponentById(value); + } + + affected.map( + function(component) { + + component[property] = newComponent; + component.updateInstance(property); + + if (property === 'parentPhysicsWorld') { + R3.Event.Emit( + R3.Event.PARENT_WORLD_CHANGE, + { + originalWorld : this.initialValue, + newWorld : newComponent, + object : component + } + ) + } + + if (property === 'parentScene') { + R3.Event.Emit( + R3.Event.PARENT_SCENE_CHANGE, + { + originalScene: this.initialValue, + newScene: newComponent, + object: component + } + ); + } + + }.bind(this) + ); + + if (property === 'parent') { + R3.Event.Emit( + R3.Event.BUILD_GUI, + null + ); + } + + this.initialValue = newComponent; + } + ); +}; + +R3.Runtime.GUI.DatGUI.prototype.buildArrayManagerControl = function( + folder, + componentTemplate, + property +) { + + var constructors = componentTemplate.template.linkedComponents[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); + component.updateInstance(property); + folder.remove(controller); + }); + } + }, + 'remove' + ).name('remove ' + property + '[' + index + '] - ' + name); + + folder.updateDisplay(); + }; + + array.map(addArrayItem); + + var idObject = {}; + + var selectionObject = R3.EntityManager.Instance.findComponentsByConstructor(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); + + R3.Event.Emit( + R3.Event.ARRAY_ITEM_ADDED, + { + component : component, + property : property, + item : activeSelection.component + } + ); + + component.updateInstance(property, activeSelection.component); + + // addArrayItem(activeSelection.component, component[property].length - 1); + //} + }); + + R3.Event.Emit( + R3.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); + +}; + +/** + * This is only for uvs right now + */ +R3.Runtime.GUI.DatGUI.prototype.buildUVManagerControl = function( + folder, + componentTemplate, + property +) { + + var object = componentTemplate.template; + + var array = object[property]; + + array.map( + function(uvs, uvSet) { + /** + * uvs should be an array of three vector2's + */ + uvs.map( + function(uv, uvIndex) { + + var onChange = function(__uvSet, __uvIndex, __property) { + return function(value) { + componentTemplate.affected.map( + function(component) { + component.uvs[__uvSet][__uvIndex][__property] = value; + component.updateInstance('uvs', __uvSet, __uvIndex); + } + ); + } + }; + + folder.add(uv, 'x').name('uvs[' + uvSet + '][' + uvIndex +'].x').onChange(onChange(uvSet, uvIndex, 'x')).listen(); + folder.add(uv, 'y').name('uvs[' + uvSet + '][' + uvIndex +'].y').onChange(onChange(uvSet, uvIndex, 'y')).listen(); + } + ) + + } + ); + + +}; + +R3.Runtime.GUI.DatGUI.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); + } + ) + } + ) + +}; + +R3.Runtime.GUI.DatGUI.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); + } + ); + } + ); + } + ); + } +}; + +R3.Runtime.GUI.DatGUI.prototype.buildSelectControl = function(folder, componentTemplate, property) { + + /** + * We need to discover the constructor for this component + */ + var constructors = null; + + if (componentTemplate.template.linkedComponents && componentTemplate.template.linkedComponents[property]) { + constructors = componentTemplate.template.linkedComponents[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 = R3.EntityManager.Instance.findComponentsByConstructor(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; + } + ); +}; + +R3.Runtime.GUI.DatGUI.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 ( + R3.Utils.IsString(object[property]) || + R3.Utils.IsBoolean(object[property]) + ) { + controllers.push(folder.add(object, property)); + } + + if (R3.Utils.IsNumber(object[property])) { + + var grain = 0.001; + + if (object.grain) { + grain = object.grain; + } + + if (property === 'componentType') { + + var readOnly = { + componentType : R3.Component.GetComponentInfo(object[property]).name + }; + + controllers.push( + folder.add( + readOnly, + 'componentType' + ) + ); + } else if (property === 'systemType') { + controllers.push( + folder.add( + object, + property, + { + 'animation' : R3.System.SYSTEM_TYPE_ANIMATION, + 'gui' : R3.System.SYSTEM_TYPE_GUI, + 'input' : R3.System.SYSTEM_TYPE_INPUT, + 'render' : R3.System.SYSTEM_TYPE_RENDER, + 'storage' : R3.System.SYSTEM_TYPE_STORAGE, + 'linking' : R3.System.SYSTEM_TYPE_LINKING, + 'physics' : R3.System.SYSTEM_TYPE_PHYSICS, + 'custom code' : R3.System.SYSTEM_TYPE_CUSTOM + } + ) + ); + } else if (property === 'controlsType') { + controllers.push( + folder.add( + object, + property, + { + 'touch' : R3.API.Controls.CONTROLS_TYPE_TOUCH, + 'mouse' : R3.API.Controls.CONTROLS_TYPE_MOUSE, + 'keyboard' : R3.API.Controls.CONTROLS_TYPE_KEYBOARD, + 'editor' : R3.API.Controls.CONTROLS_TYPE_EDITOR + } + ) + ); + } else if (property === 'stereoMode') { + controllers.push( + folder.add( + object, + property, + { + 'stereo' : R3.D3.API.Camera.Stereo.STEREO_MODE_STEREO, + 'anaglyph' : R3.D3.API.Camera.Stereo.STEREO_MODE_ANAGLYPH, + 'parallax' : R3.D3.API.Camera.Stereo.STEREO_MODE_PARALLAX + } + ) + ); + } else if (property === 'defaultMode') { + controllers.push( + folder.add( + object, + property, + { + 'run' : R3.API.Project.APPLICATION_MODE_RUN, + 'edit' : R3.API.Project.APPLICATION_MODE_EDIT + } + ) + ); + } else if (property === 'aspectRatioMode') { + controllers.push( + folder.add( + object, + property, + { + 'none' : R3.D3.API.Camera.Orthographic.ASPECT_RATIO_MODE_NONE, + 'fixed' : R3.D3.API.Camera.Orthographic.ASPECT_RATIO_MODE_FIXED, + 'based on current' : R3.D3.API.Camera.Orthographic.ASPECT_RATIO_MODE_BASED_ON_CURRENT + } + ) + ); + } else if (property === 'socketType') { + controllers.push( + folder.add( + object, + property, + { + 'none' : R3.API.Socket.TYPE_NONE, + 'cast' : R3.API.Socket.TYPE_CAST, + 'receive' : R3.API.Socket.TYPE_RECEIVE + } + ) + ); + } else if (property === 'castType') { + controllers.push( + folder.add( + object, + property, + { + 'room': R3.API.Socket.Cast.CAST_TYPE_ROOM, + 'peer': R3.API.Socket.Cast.CAST_TYPE_PEER , + 'all': R3.API.Socket.Cast.CAST_TYPE_ALL, + 'all but peer': R3.API.Socket.Cast.CAST_TYPE_ALL_BUT_PEER + } + ) + ); + } else if (property === 'receiveType') { + controllers.push( + folder.add( + object, + property, + { + 'room': R3.API.Socket.Receive.RECEIVE_TYPE_ROOM, + 'peer': R3.API.Socket.Cast.RECEIVE_TYPE_PEER + } + ) + ); + } else if (property === 'drawMode') { + controllers.push( + folder.add( + object, + property, + { + 'triangles' : R3.D3.API.Mesh.DRAW_MODE_TRIANGLES, + 'triangle strip' : R3.D3.API.Mesh.DRAW_MODE_TRIANGLE_STRIP, + 'triangle fan' : R3.D3.API.Mesh.DRAW_MODE_TRIANGLE_FAN + } + ) + ); + } else if (property === 'shadowType') { + controllers.push( + folder.add( + object, + property, + { + 'directional': R3.D3.API.Shadow.SHADOW_TYPE_DIRECTIONAL, + 'spot': R3.D3.API.Shadow.SHADOW_TYPE_SPOT + } + ) + ); + } else if (property === 'shadowMapType') { + controllers.push( + folder.add( + object, + property, + { + 'basic': R3.API.Renderer.SHADOW_MAP_TYPE_BASIC, + 'pcf': R3.API.Renderer.SHADOW_MAP_TYPE_PCF, + 'pcf soft': R3.API.Renderer.SHADOW_MAP_TYPE_PCF_SOFT + } + ) + ); + } else if (property === 'toneMapping') { + controllers.push( + folder.add( + object, + property, + { + 'linear': R3.API.Renderer.TONE_MAPPING_LINEAR, + 'reinhard': R3.API.Renderer.TONE_MAPPING_REINHARD, + 'uncharted 2': R3.API.Renderer.TONE_MAPPING_UNCHARTED_2, + 'cineon': R3.API.Renderer.TONE_MAPPING_CINEON + } + ) + ); + } else if (property === 'opacityType') { + controllers.push( + folder.add( + object, + property, + { + 'constant': R3.D3.API.Particle.OPACITY_TYPE_CONSTANT, + 'fade out': R3.D3.API.Particle.OPACITY_TYPE_FADE_OUT_LINEAR, + 'fade in': R3.D3.API.Particle.OPACITY_TYPE_FADE_IN_LINEAR, + 'fade in / out': R3.D3.API.Particle.OPACITY_TYPE_FADE_IN_OUT_LINEAR + } + ) + ); + } else if (property === 'positionOffsetType') { + controllers.push( + folder.add( + object, + property, + { + 'constant': R3.D3.API.Particle.POSITION_OFFSET_TYPE_CONSTANT, + 'random': R3.D3.API.Particle.POSITION_OFFSET_TYPE_RANDOM, + 'function': R3.D3.API.Particle.POSITION_OFFSET_TYPE_FUNCTION + } + ) + ); + } else if (property === 'directionType') { + controllers.push( + folder.add( + object, + property, + { + 'constant': R3.D3.API.Particle.DIRECTION_TYPE_CONSTANT, + 'random': R3.D3.API.Particle.DIRECTION_TYPE_RANDOM, + 'random normalized': R3.D3.API.Particle.DIRECTION_TYPE_RANDOM_NORMALIZED, + 'function': R3.D3.API.Particle.DIRECTION_TYPE_FUNCTION + } + ) + ); + } else if (property === 'speedType') { + controllers.push( + folder.add( + object, + property, + { + 'constant': R3.D3.API.Particle.SPEED_TYPE_CONSTANT, + 'linear': R3.D3.API.Particle.SPEED_TYPE_LINEAR, + 'exponential': R3.D3.API.Particle.SPEED_TYPE_EXPONENTIAL, + 'logarithmic': R3.D3.API.Particle.SPEED_TYPE_LOGARITHMIC, + '1 / log': R3.D3.API.Particle.SPEED_TYPE_ONE_OVER_LOG, + 'exp' : R3.D3.API.Particle.SPEED_TYPE_EXP, + '1 / exp' : R3.D3.API.Particle.SPEED_TYPE_ONE_OVER_EXP + } + ) + ); + } else if (property === 'scaleType') { + controllers.push( + folder.add( + object, + property, + { + 'constant': R3.D3.API.Particle.SCALE_TYPE_CONSTANT, + 'linear': R3.D3.API.Particle.SCALE_TYPE_LINEAR, + 'exponential': R3.D3.API.Particle.SCALE_TYPE_EXPONENTIAL, + 'random': R3.D3.API.Particle.SCALE_TYPE_RANDOM, + 'random (x = y)': R3.D3.API.Particle.SCALE_TYPE_RANDOM_X_EQUALS_Y, + 'function': R3.D3.API.Particle.SCALE_TYPE_FUNCTION + } + ) + ); + } else if (property === 'rotationType') { + controllers.push( + folder.add( + object, + property, + { + 'constant': R3.D3.API.Particle.ROTATION_TYPE_CONSTANT, + 'random': R3.D3.API.Particle.ROTATION_TYPE_RANDOM, + 'random - x': R3.D3.API.Particle.ROTATION_TYPE_RANDOM_X, + 'random - y': R3.D3.API.Particle.ROTATION_TYPE_RANDOM_Y, + 'random - z': R3.D3.API.Particle.ROTATION_TYPE_RANDOM_Z, + 'function': R3.D3.API.Particle.ROTATION_TYPE_FUNCTION + } + ) + ); + } else if (property === 'broadphaseType') { + controllers.push( + folder.add( + object, + property, + { + 'naive': R3.D3.Broadphase.BROADPHASE_TYPE_NAIVE, + 'grid': R3.D3.Broadphase.BROADPHASE_TYPE_GRID, + 'sap': R3.D3.Broadphase.BROADPHASE_TYPE_SAP + } + ) + ); + } else if (property === 'solverType') { + controllers.push( + folder.add( + object, + property, + { + 'gs': R3.D3.API.Solver.GS_SOLVER, + 'split': R3.D3.API.Solver.SPLIT_SOLVER + } + ) + ); + } else if (property === 'meshType') { + controllers.push( + folder.add( + object, + property, + { + 'normal' : R3.D3.API.Object.OBJECT_TYPE_MESH, + 'curve' : R3.D3.API.Object.OBJECT_TYPE_MESH_CURVE, + 'skinned' : R3.D3.API.Object.OBJECT_TYPE_MESH_SKINNED, + 'plane' : R3.D3.API.Object.OBJECT_TYPE_MESH_PLANE, + 'sphere' : R3.D3.API.Object.OBJECT_TYPE_MESH_SPHERE, + 'box' : R3.D3.API.Object.OBJECT_TYPE_MESH_BOX, + 'cylinder' : R3.D3.API.Object.OBJECT_TYPE_MESH_CYLINDER, + 'text' : R3.D3.API.Object.OBJECT_TYPE_MESH_TEXT + } + ) + ); + } else if (property === 'cameraType') { + controllers.push( + folder.add( + object, + property, + { + 'perspective' : R3.D3.API.Object.OBJECT_TYPE_CAMERA_PERSPECTIVE, + 'orthographic' : R3.D3.API.Object.OBJECT_TYPE_CAMERA_ORTHOGRAPHIC, + 'stereo' : R3.D3.API.Object.OBJECT_TYPE_CAMERA_STEREO, + 'cube' : R3.D3.API.Object.OBJECT_TYPE_CAMERA_CUBE + } + ) + ); + } else if (property === 'passType') { + controllers.push( + folder.add( + object, + property, + { + 'ssao': R3.D3.API.Pass.PASS_TYPE_SSAO, + 'bloom': R3.D3.API.Pass.PASS_TYPE_BLOOM, + 'fxaa': R3.D3.API.Pass.PASS_TYPE_FXAA, + 'render': R3.D3.API.Pass.PASS_TYPE_RENDER + } + ) + ); + } else if (property === 'rendererType') { + controllers.push( + folder.add( + object, + property, + { + '2D': R3.API.Renderer.RENDERER_TYPE_2D, + '3D': R3.API.Renderer.RENDERER_TYPE_3D + } + ) + ); + } else if (property === 'materialType') { + controllers.push( + folder.add( + object, + property, + { + 'standard': R3.D3.API.Material.MATERIAL_TYPE_STANDARD, + 'basic': R3.D3.API.Material.MATERIAL_TYPE_BASIC, + 'phong': R3.D3.API.Material.MATERIAL_TYPE_PHONG, + 'shader': R3.D3.API.Material.MATERIAL_TYPE_SHADER, + 'raw shader': R3.D3.API.Material.MATERIAL_TYPE_SHADER_RAW, + 'points': R3.D3.API.Material.MATERIAL_TYPE_POINTS + // 'toon': R3.D3.API.Material.MATERIAL_TYPE_TOON, + // 'line basic' : R3.D3.API.Material.MATERIAL_TYPE_LINE_BASIC + } + ) + ); + } else if (property === 'side') { + controllers.push( + folder.add( + object, + property, + { + 'double': R3.D3.API.Material.TYPE_DOUBLE_SIDE, + 'front': R3.D3.API.Material.TYPE_FRONT_SIDE, + 'back': R3.D3.API.Material.TYPE_BACK_SIDE + } + ) + ); + } else if (property === 'combine') { + controllers.push( + folder.add( + object, + property, + { + 'multiply': R3.D3.API.Material.COMBINE_MULTIPLY_OPERATION, + 'mix': R3.D3.API.Material.COMBINE_MIX_OPERATION, + 'add': R3.D3.API.Material.COMBINE_ADD_OPERATION + } + ) + ); + } else if (property === 'vertexColors') { + controllers.push( + folder.add( + object, + property, + { + 'none': R3.D3.API.Material.TYPE_NO_COLORS, + 'face': R3.D3.API.Material.TYPE_FACE_COLORS, + 'vertex': R3.D3.API.Material.TYPE_VERTEX_COLORS + } + ) + ); + } else if (property === 'blending') { + controllers.push( + folder.add( + object, + property, + { + 'none': R3.D3.API.Material.TYPE_NO_BLENDING, + 'normal': R3.D3.API.Material.TYPE_NORMAL_BLENDING, + 'additive': R3.D3.API.Material.TYPE_ADDITIVE_BLENDING, + 'subtractive': R3.D3.API.Material.TYPE_SUBTRACTIVE_BLENDING, + 'multiply': R3.D3.API.Material.TYPE_MULTIPLY_BLENDING, + 'custom': R3.D3.API.Material.TYPE_CUSTOM_BLENDING + } + ) + ); + } else if (property === 'blendSrc') { + controllers.push( + folder.add( + object, + property, + { + 'zero': R3.D3.API.Material.TYPE_ZERO_FACTOR, + 'one': R3.D3.API.Material.TYPE_ONE_FACTOR, + 'source color': R3.D3.API.Material.TYPE_SRC_COLOR_FACTOR, + 'one minus source color': R3.D3.API.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR, + 'source alpha': R3.D3.API.Material.TYPE_SRC_ALPHA_FACTOR, + 'one minus source alpha': R3.D3.API.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR, + 'destination alpha': R3.D3.API.Material.TYPE_DST_ALPHA_FACTOR, + 'one minus destination alpha': R3.D3.API.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR, + 'destination color': R3.D3.API.Material.TYPE_DST_COLOR_FACTOR, + 'one minus destination color': R3.D3.API.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR, + 'source alpha saturate': R3.D3.API.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR + } + ) + ); + } else if (property === 'blendDst') { + controllers.push( + folder.add( + object, + property, + { + 'zero': R3.D3.API.Material.TYPE_ZERO_FACTOR, + 'one': R3.D3.API.Material.TYPE_ONE_FACTOR, + 'source color': R3.D3.API.Material.TYPE_SRC_COLOR_FACTOR, + 'one minus source color': R3.D3.API.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR, + 'source alpha': R3.D3.API.Material.TYPE_SRC_ALPHA_FACTOR, + 'one minus source alpha': R3.D3.API.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR, + 'destination alpha': R3.D3.API.Material.TYPE_DST_ALPHA_FACTOR, + 'one minus destination alpha': R3.D3.API.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR, + 'destination color': R3.D3.API.Material.TYPE_DST_COLOR_FACTOR, + 'one minus destination color': R3.D3.API.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR, + 'source alpha saturate': R3.D3.API.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR + } + ) + ); + } else if (property === 'blendEquation') { + controllers.push( + folder.add( + object, + property, + { + 'add': R3.D3.API.Material.TYPE_ADD_EQUATION, + 'subtract': R3.D3.API.Material.TYPE_SUBTRACT_EQUATION, + 'reverse subtract': R3.D3.API.Material.TYPE_REVERSE_SUBTRACT_EQUATION, + 'min': R3.D3.API.Material.TYPE_MIN_EQUATION, + 'max': R3.D3.API.Material.TYPE_MAX_EQUATION + } + ) + ); + } else if (property === 'depthFunc') { + controllers.push( + folder.add( + object, + property, + { + 'never': R3.D3.API.Material.TYPE_NEVER_DEPTH, + 'always': R3.D3.API.Material.TYPE_ALWAYS_DEPTH, + 'less depth': R3.D3.API.Material.TYPE_LESS_DEPTH, + 'less equal depth': R3.D3.API.Material.TYPE_LESS_EQUAL_DEPTH, + 'equal depth': R3.D3.API.Material.TYPE_EQUAL_DEPTH, + 'greated equal depth': R3.D3.API.Material.TYPE_GREATER_EQUAL_DEPTH, + 'greated depth': R3.D3.API.Material.TYPE_GREATER_DEPTH, + 'not equal depth': R3.D3.API.Material.TYPE_NOT_EQUAL_DEPTH + } + ) + ); + } else if (property === 'wrapS') { + controllers.push( + folder.add( + object, + property, + { + 'repeat': R3.D3.API.Texture.TYPE_REPEAT_WRAPPING, + 'clamp': R3.D3.API.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING, + 'mirrored repeat': R3.D3.API.Texture.TYPE_MIRRORED_REPEAT_WRAPPING + } + ) + ); + } else if (property === 'wrapT') { + controllers.push( + folder.add( + object, + property, + { + 'repeat': R3.D3.API.Texture.TYPE_REPEAT_WRAPPING, + 'clamp': R3.D3.API.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING, + 'mirrored repeat': R3.D3.API.Texture.TYPE_MIRRORED_REPEAT_WRAPPING + } + ) + ); + } else if (property === 'format') { + controllers.push( + folder.add( + object, + property, + { + 'alpha': R3.D3.API.Texture.TYPE_ALPHA_FORMAT, + 'rgb': R3.D3.API.Texture.TYPE_RGB_FORMAT, + 'rgba': R3.D3.API.Texture.TYPE_RGBA_FORMAT, + 'luminance': R3.D3.API.Texture.TYPE_LUMINANCE_FORMAT, + 'luminance alpha': R3.D3.API.Texture.TYPE_LUMINANCE_ALPHA_FORMAT, + 'depth': R3.D3.API.Texture.TYPE_DEPTH_FORMAT + } + ) + ); + } else if (property === 'mapping') { + controllers.push( + folder.add( + object, + property, + { + 'uv': R3.D3.API.Texture.TYPE_UV_MAPPING, + 'cube reflection': R3.D3.API.Texture.TYPE_CUBE_REFLECTION_MAPPING, + 'cube refraction': R3.D3.API.Texture.TYPE_CUBE_REFRACTION_MAPPING, + 'equi rectangular reflection': R3.D3.API.Texture.TYPE_EQUI_RECTANGULAR_REFLECTION_MAPPING, + 'equi rectangular refraction': R3.D3.API.Texture.TYPE_EQUI_RECTANGULAR_REFRACTION_MAPPING, + 'spherical reflection': R3.D3.API.Texture.TYPE_SPHERICAL_REFLECTION_MAPPING, + 'cube uv reflection': R3.D3.API.Texture.TYPE_CUBE_UV_REFLECTION_MAPPING, + 'cube uv refraction': R3.D3.API.Texture.TYPE_CUBE_UV_REFRACTION_MAPPING + } + ) + ); + } else if (property === 'magFilter') { + controllers.push( + folder.add( + object, + property, + { + 'nearest': R3.D3.API.Texture.TYPE_NEAREST_FILTER, + 'nearest mipmap nearest': R3.D3.API.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER, + 'nearest mipmap linear': R3.D3.API.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER, + 'linear': R3.D3.API.Texture.TYPE_LINEAR_FILTER, + 'linear mipmap nearest': R3.D3.API.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER, + 'linear mipmap linear': R3.D3.API.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER + } + ) + ); + } else if (property === 'minFilter') { + controllers.push( + folder.add( + object, + property, + { + 'nearest': R3.D3.API.Texture.TYPE_NEAREST_FILTER, + 'nearest mipmap nearest': R3.D3.API.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER, + 'nearest mipmap linear': R3.D3.API.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER, + 'linear': R3.D3.API.Texture.TYPE_LINEAR_FILTER, + 'linear mipmap nearest': R3.D3.API.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER, + 'linear mipmap linear': R3.D3.API.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER + } + ) + ); + } else if (property === 'textureType') { + controllers.push( + folder.add( + object, + property, + { + 'normal': R3.D3.API.Texture.TEXTURE_TYPE_NONE, + 'image': R3.D3.API.Texture.TEXTURE_TYPE_IMAGE, + 'cube': R3.D3.API.Texture.TEXTURE_TYPE_CUBE, + 'canvas': R3.D3.API.Texture.TEXTURE_TYPE_CANVAS + } + ) + ); + } else if (property === 'storageType') { + controllers.push( + folder.add( + object, + property, + { + 'unsigned byte': R3.D3.API.Texture.TYPE_UNSIGNED_BYTE, + 'byte': R3.D3.API.Texture.TYPE_BYTE, + 'short': R3.D3.API.Texture.TYPE_SHORT, + 'unsigned short': R3.D3.API.Texture.TYPE_UNSIGNED_SHORT, + 'int': R3.D3.API.Texture.TYPE_INT, + 'unsigned int': R3.D3.API.Texture.TYPE_UNSIGNED_INT, + 'float': R3.D3.API.Texture.TYPE_FLOAT, + 'half float': R3.D3.API.Texture.TYPE_HALF_FLOAT + } + ) + ); + } else if (property === 'aspectRatio') { + controllers.push( + folder.add( + object, + property, + { + 'none': R3.API.Renderer.ASPECT_RATIO_NONE, + '4:3 (1.3333)': R3.API.Renderer.ASPECT_RATIO_4_3, + '3:2 (1.5)': R3.API.Renderer.ASPECT_RATIO_3_2, + '16:10 (1.6667)': R3.API.Renderer.ASPECT_RATIO_16_10, + '17:10 (1.7)': R3.API.Renderer.ASPECT_RATIO_17_10, + '16:9 (1.7778)': R3.API.Renderer.ASPECT_RATIO_16_9 + } + ) + ); + } else if (property === 'scaleMode') { + controllers.push( + folder.add( + object, + property, + { + 'none': R3.API.Renderer.SCALE_MODE_NONE, + 'letterbox': R3.API.Renderer.SCALE_MODE_LETTERBOX, + 'zoom-bigger': R3.API.Renderer.SCALE_MODE_ZOOM_TO_BIGGER, + 'non-uniform': R3.API.Renderer.SCALE_MODE_NON_UNIFORM + } + ) + ); + } else if (property === 'encoding') { + controllers.push( + folder.add( + object, + property, + { + 'linear': R3.D3.API.Texture.TYPE_LINEAR_ENCODING, + 'srgb': R3.D3.API.Texture.TYPE_SRGB_ENCODING, + 'gamma': R3.D3.API.Texture.TYPE_GAMMA_ENCODING, + 'rgbe': R3.D3.API.Texture.TYPE_RGBE_ENCODING, + 'log luv': R3.D3.API.Texture.TYPE_LOG_LUV_ENCODING, + 'rgbm7': R3.D3.API.Texture.TYPE_RGBM7_ENCODING, + 'rgbm16': R3.D3.API.Texture.TYPE_RGBM16_ENCODING, + 'rgbd': R3.D3.API.Texture.TYPE_RGBD_ENCODING + } + ) + ); + } else if (property === 'lightType') { + controllers.push( + folder.add( + object, + property, + { + 'ambient': R3.D3.API.Light.LIGHT_TYPE_AMBIENT, + 'directional': R3.D3.API.Light.LIGHT_TYPE_DIRECTIONAL, + 'spot': R3.D3.API.Light.LIGHT_TYPE_SPOT, + 'point': R3.D3.API.Light.LIGHT_TYPE_POINT, + 'hemisphere': R3.D3.API.Light.LIGHT_TYPE_HEMISPHERE, + 'rect area': R3.D3.API.Light.LIGHT_TYPE_RECT_AREA + } + ) + ); + } else if (property === 'eventId') { + + var options = {}; + + for (var i = 0; i < 200; i++) { + try { + options[R3.Event.GetEventName(i)] = i; + } catch (error) { + + } + } + + controllers.push( + folder.add( + object, + property, + options + ) + ); + } else if (property === 'functionType') { + controllers.push( + folder.add( + object, + property, + { + 'rotation': R3.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION, + 'translation': R3.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION, + 'scale': R3.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE + } + ) + ); + } else { + + /** + * Try to guess a scale for this property + */ + if ( + property === 'opacity' || + property === 'fadeInFactor' || + property === 'fadeOutFactor' || + property === 'metalness' || + property === 'roughness' || + property === 'aoClamp' || + property === 'lumInfluence' || + property === 'volume' + ) { + controllers.push(folder.add(object, property, 0, 1.0, 0.001)); + } else if ( + property === 'cubeResolution' + ) { + controllers.push(folder.add(object, property, 16, 4096, 16)); + } 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 === 'lightMapIntensity' || + property === 'aoMapIntensity' || + property === 'envMapIntensity' || + 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' + ) { + controllers.push(folder.add(object, property, 0, 4096, 0.001)); + } else if ( + property === 'depth' || + property === 'radius' + ) { + + if (object instanceof R3.D3.Pass.Bloom) { + controllers.push(folder.add(object, property, -10, 10, 0.001)); + } else { + controllers.push(folder.add(object, property, 0, 1000, 0.001)); + } + + } else if ( + property === 'near' || + property === 'distanceGrain' || + property === 'envMapIntensity' + ) { + controllers.push(folder.add(object, property, -10, 100, 0.001)); + } else if ( + property === 'bumpScale' || + property === 'speed' + ) { + controllers.push(folder.add(object, property, 0, 100, 0.01)); + } 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' || + property === 'bias' || + property === 'threshold' + ) { + controllers.push(folder.add(object, property, 0, 1, 0.0001)); + } else if ( + property === 'strength' || + property === 'power' + ) { + controllers.push(folder.add(object, property, 0, 25, 0.01)); + } else if ( + property === 'thetaLength' || + property === 'angle' + ) { + controllers.push(folder.add(object, property, -Math.PI * 2, Math.PI * 2, 0.01)); + } else if ( + property === 'port' || + property === 'far' + ) { + controllers.push(folder.add(object, property, 1, 65536, 1)); + } else if ( + property === 'eyeSep' + ) { + controllers.push(folder.add(object, property, -2, 2, 0.0001)); + } else if ( + property === 'arc' || + property === 'size' + ) { + controllers.push(folder.add(object, property, 0, 200, 0.001)); + } 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(); + } + + } + ); + +}; diff --git a/src/r3-runtime-physics-0.js b/src/r3-runtime-physics-0.js new file mode 100644 index 0000000..43d1440 --- /dev/null +++ b/src/r3-runtime-physics-0.js @@ -0,0 +1,77 @@ +/** + * R3.Runtime.Physics + * @constructor + */ +R3.Runtime.Physics = function() { + + R3.Runtime.call(this); + +}; + +R3.Runtime.Physics.prototype = Object.create(R3.Runtime.prototype); +R3.Runtime.Physics.prototype.constructor = R3.Runtime.Physics; + +R3.Runtime.Physics.prototype.Vector2 = function(x,y) { + console.warn('override Vector2 in child class'); +}; + +R3.Runtime.Physics.prototype.Vector3 = function(x,y,z) { + console.warn('override Vector3 in child class'); +}; + +R3.Runtime.Physics.prototype.Vector4 = function(x,y,z,w) { + console.warn('override Vector4 in child class'); +}; + +R3.Runtime.Physics.prototype.Matrix4 = function(rows) { + console.warn('override Matrix4 in child class'); +}; + +R3.Runtime.Physics.prototype.Box3 = function(rows) { + console.warn('override Box3 in child class'); +}; + +R3.Runtime.Physics.prototype.Face = function( + runtimeObject +) { + console.warn('override R3.Runtime.Physics.prototype.Face in child class'); +}; + +R3.Runtime.Physics.prototype.Quaternion = function(x,y,z,w) { + console.log('override Quaternion in child class') +}; + +R3.Runtime.Physics.prototype.Broadphase = function(broadphaseType) { + console.log('override Quaternion in child class') +}; + +R3.Runtime.Physics.prototype.ContactMaterial = function( + friction, + restitution, + contactEquationStiffness, + materials, + contactEquationRelaxation, + frictionEquationStiffness, + frictionEquationRelaxation +) { + console.log('override R3.Runtime.Physics.prototype.ContactMaterial in child class'); +}; + +R3.Runtime.Physics.prototype.Material = function( + name, + friction, + restitution +) { + console.log('override R3.Runtime.Physics.prototype.Material in child class') +}; + +R3.Runtime.Physics.prototype.Sphere = function( + center, + radius +) { + console.warn('override R3.Runtime.Physics.prototype.Sphere in child class'); +}; + +R3.Runtime.Physics.prototype.updateInstance = function(runtimeObject, property) { + console.log('override R3.Runtime.Physics.prototype.updateInstance in child class'); +}; \ No newline at end of file diff --git a/src/r3-runtime-physics-cannon.js b/src/r3-runtime-physics-cannon.js new file mode 100644 index 0000000..b6724fe --- /dev/null +++ b/src/r3-runtime-physics-cannon.js @@ -0,0 +1,163 @@ +/** + * R3.Runtime.Physics.Cannon + * @constructor + */ +R3.Runtime.Physics.Cannon = function() { + + R3.Runtime.Physics.call( + this + ); + + this.createInstance(); + +}; + +R3.Runtime.Physics.Cannon.prototype = Object.create(R3.Runtime.Physics.prototype); +R3.Runtime.Physics.Cannon.prototype.constructor = R3.Runtime.Physics.Cannon; + +R3.Runtime.Physics.Cannon.prototype.createInstance = function() { + this.instance = true; +}; + +R3.Runtime.Physics.Cannon.prototype.Vector2 = function(x,y) { + return new CANNON.Vec2(x,y,z); +}; + +R3.Runtime.Physics.Cannon.prototype.Vector3 = function(x,y,z) { + return new CANNON.Vec3(x,y,z); +}; + +R3.Runtime.Physics.Cannon.prototype.Vector4 = function(x,y,z,w) { + return new CANNON.Vec4(x,y,z,w); +}; + +R3.Runtime.Physics.Cannon.prototype.Matrix4 = function(rows) { + console.warn('TODO: implement cannon physics matrix 4'); +}; + +R3.Runtime.Physics.Cannon.prototype.Box3 = function(min,max) { + console.log('return cannon implementation of box3') +}; + +R3.Runtime.Physics.Cannon.prototype.Quaternion = function(x,y,z,w) { + console.log('return cannon implementation of quaternion') +}; + +R3.Runtime.Physics.Cannon.prototype.Broadphase = function(broadphaseType) { + + switch (broadphaseType) { + + case R3.D3.Broadphase.BROADPHASE_TYPE_NAIVE : + return new CANNON.NaiveBroadphase(); + case R3.D3.Broadphase.BROADPHASE_TYPE_GRID : + return new CANNON.GridBroadphase(); + case R3.D3.Broadphase.BROADPHASE_TYPE_SAP : + return new CANNON.SAPBroadphase(); + default : + throw new Error('Unknown broadphase type'); + } + +}; + +R3.Runtime.Physics.Cannon.prototype.ContactMaterial = function( + friction, + restitution, + contactEquationStiffness, + materials, + contactEquationRelaxation, + frictionEquationStiffness, + frictionEquationRelaxation +) { + var instance = new CANNON.ContactMaterial( + null, + null, + { + friction: friction, + restitution: restitution, + contactEquationStiffness: contactEquationStiffness, + contactEquationRelaxation: contactEquationRelaxation, + frictionEquationStiffness: frictionEquationStiffness, + frictionEquationRelaxation: frictionEquationRelaxation, + } + ); + + instance.materials = materials.map( + function(material){ + return material.instance; + } + ); + + return instance; +}; + +R3.Runtime.Physics.Cannon.prototype.Face = function( + runtimeObject +) { + console.warn('todo: R3.Runtime.Physics.Cannon.prototype.Face'); +}; + +R3.Runtime.Physics.Cannon.prototype.Material = function( + name, + friction, + restitution +) { + var instance = new CANNON.Material( + name + ); + + instance.friction = friction; + instance.restitution = restitution; + + return instance; +}; + +R3.Runtime.Physics.Cannon.prototype.Sphere = function( + center, + radius +) { + console.warn('todo: implement R3.Runtime.Physics.Cannon.prototype.Sphere'); +}; + +R3.Runtime.Physics.Cannon.prototype.updateInstance = function(runtimeObject, property) { + + var instance = runtimeObject.instance; + + if (R3.Utils.UndefinedOrNull(instance)) { + throw new Error('no instance available for update'); + } + + if (instance instanceof CANNON.ContactMaterial) { + + if ( + property === 'friction' || + property === 'restitution' || + property === 'contactEquationStiffness' || + property === 'contactEquationRelaxation' || + property === 'frictionEquationStiffness' || + property === 'frictionEquationRelaxation' + ) { + instance[property] = runtimeObject[property]; + return; + } + + if (property === 'materials') { + instance.materials = runtimeObject.materials.map( + function(material) { + return material.instance; + } + ); + return + } + } + + if (instance instanceof CANNON.Material) { + if ( + property === 'friction' || + property === 'restitution' + ) { + instance[property] = runtimeObject[property]; + return; + } + } + +}; \ No newline at end of file diff --git a/src/r3-runtime-sockets-0.js b/src/r3-runtime-sockets-0.js new file mode 100644 index 0000000..871a7e4 --- /dev/null +++ b/src/r3-runtime-sockets-0.js @@ -0,0 +1,16 @@ +/** + * R3.Runtime.Sockets + * @constructor + */ +R3.Runtime.Sockets = function() { + + R3.Runtime.call(this); + +}; + +R3.Runtime.Sockets.prototype = Object.create(R3.Runtime.prototype); +R3.Runtime.Sockets.prototype.constructor = R3.Runtime.Sockets; + +R3.Runtime.Sockets.prototype.connect = function(server) { + console.warn('Please override connect in the child class'); +}; diff --git a/src/r3-runtime-sockets-websockjet.js b/src/r3-runtime-sockets-websockjet.js new file mode 100644 index 0000000..78eb445 --- /dev/null +++ b/src/r3-runtime-sockets-websockjet.js @@ -0,0 +1,24 @@ +/** + * R3.Runtime.Sockets.Websocket + * @constructor + */ +R3.Runtime.Sockets.Websocket = function() { + + R3.Runtime.Sockets.call( + this + ); + + this.createInstance(); +}; + +R3.Runtime.Sockets.Websocket.prototype = Object.create(R3.Runtime.Sockets.prototype); +R3.Runtime.Sockets.Websocket.prototype.constructor = R3.Runtime.Sockets.Websocket; + +R3.Runtime.Sockets.Websocket.prototype.createInstance = function() { + this.instance = WebSocket; +}; + +R3.Runtime.Sockets.Websocket.prototype.connect = function(server) { + var connection = new WebSocket(server.protocol + '://' + server.ip + ':' + server.port , server.protocols); + this.connections.push(connection); +}; diff --git a/src/r3-runtime-statistics-0.js b/src/r3-runtime-statistics-0.js new file mode 100644 index 0000000..0592f29 --- /dev/null +++ b/src/r3-runtime-statistics-0.js @@ -0,0 +1,12 @@ +/** + * R3.Runtime.Statistics + * @constructor + */ +R3.Runtime.Statistics = function() { + + R3.Runtime.call(this); + +}; + +R3.Runtime.Statistics.prototype = Object.create(R3.Runtime.prototype); +R3.Runtime.Statistics.prototype.constructor = R3.Runtime.Statistics; diff --git a/src/r3-runtime-statistics-stats.js b/src/r3-runtime-statistics-stats.js new file mode 100644 index 0000000..0ac6340 --- /dev/null +++ b/src/r3-runtime-statistics-stats.js @@ -0,0 +1,21 @@ +/** + * R3.Runtime.Statistics.Stats + * @constructor + */ +R3.Runtime.Statistics.Stats = function() { + + R3.Runtime.Statistics.call( + this + ); + + this.createInstance(); + +}; + +R3.Runtime.Statistics.Stats.prototype = Object.create(R3.Runtime.Statistics.prototype); +R3.Runtime.Statistics.Stats.prototype.constructor = R3.Runtime.Statistics.Stats; + + +R3.Runtime.Statistics.Stats.prototype.createInstance = function() { + this.instance = Stats; +}; diff --git a/src/r3-scalar.js b/src/r3-scalar.js new file mode 100644 index 0000000..91426e6 --- /dev/null +++ b/src/r3-scalar.js @@ -0,0 +1,49 @@ +/** + * R3.Scalar + * @param apiComponent + * + * @property x + * @property y + * + * @constructor + */ +R3.Scalar = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Scalar.prototype = Object.create(R3.Component.prototype); +R3.Scalar.prototype.constructor = R3.Scalar; + +/** + * Creates an instance vector2 + * @returns {*} + */ +R3.Scalar.prototype.createInstance = function() { + + this.instance = { + value : this.value + }; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance vector, calls updateInstance on the parent object + */ +R3.Scalar.prototype.updateInstance = function(property) { + + if (property === 'value') { + this.instance.value = this.value; + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-server.js b/src/r3-server.js new file mode 100644 index 0000000..023a04a --- /dev/null +++ b/src/r3-server.js @@ -0,0 +1,83 @@ +/** + * R3.Server + * @param apiComponent + * @constructor + */ +R3.Server = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + this.connected = false; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.Server.prototype = Object.create(R3.Component.prototype); +R3.Server.prototype.constructor = R3.Server; + +R3.Server.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.Server.prototype.updateInstance = function(property) { + + if (property === 'protocol') { + console.log('todo: server protocol update'); + return; + } + + if (property === 'context') { + console.log('todo: server context update'); + return; + } + + if (property === 'application') { + console.log('todo: server application update'); + return; + } + + if (property === 'domain') { + console.log('todo: server domain update'); + return; + } + + if (property === 'ip') { + console.log('todo: server ip update'); + return; + } + + if (property === 'preferIp') { + console.log('todo: server preferIp update'); + return; + } + + if (property === 'port') { + console.log('todo: server port update'); + return; + } + + if (property === 'protocols') { + console.log('todo: server protocols update'); + return; + } + + __UPDATE_INSTANCE__; +}; + +R3.Server.prototype.getURL = function() { + + if (this.preferIp) { + return this.protocol + '://' + this.ip + ':' + this.port; + } else { + return this.protocol + '://' + this.context + '-' + this.application + '.' + this.domain + ':' + this.port + } + +}; diff --git a/src/r3-socket-0.js b/src/r3-socket-0.js new file mode 100644 index 0000000..bc6e151 --- /dev/null +++ b/src/r3-socket-0.js @@ -0,0 +1,71 @@ +/** + * Creates a Socket object + * @param inherited + * @property roomId + * @property peerId + * @property server + * @constructor + */ +R3.Socket = function( + inherited +) { + + if (R3.Utils.UndefinedOrNull(inherited)) { + inherited = false; + } + + if (!inherited) { + throw new Error('R3.Socket cannot be instantiated directly - use R3.Socket.Cast or R3.Socket.Receive'); + } + + this.connected = false; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Socket.prototype = Object.create(R3.Component.prototype); +R3.Socket.prototype.constructor = R3.Socket; + +/** + * This class cannot be instantiated directly - it does have common functionality though for its children classes + */ +R3.Socket.prototype.createInstance = function() { + + this.instance = new WebSocket(this.server.getURL()); + + // Connection opened + this.instance.addEventListener('open', function(event) { + this.instance.send('Hello Server!'); + }.bind(this)); + + // Listen for messages + this.instance.addEventListener('message', function(event) { + console.log('Message from server ', event.data); + }); + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.Socket.prototype.updateInstance = function(property) { + + if (property === 'roomId') { + console.log('todo: implement socket roomId update'); + return; + } + + if (property === 'peerId') { + console.log('todo: implement socket peerId update'); + return; + } + + if (property === 'server') { + console.log('todo: implement socket server update'); + return; + } + + __UPDATE_INSTANCE__; +}; diff --git a/src/r3-socket-cast.js b/src/r3-socket-cast.js new file mode 100644 index 0000000..64aa37e --- /dev/null +++ b/src/r3-socket-cast.js @@ -0,0 +1,62 @@ +/** + * R3.Socket.Cast + * @param apiComponent + * @property castType + * @property source + * @property sourceProperties + * @constructor + */ +R3.Socket.Cast = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Socket.call( + this, + true + ); +}; + +R3.Socket.Cast.prototype = Object.create(R3.Socket.prototype); +R3.Socket.Cast.prototype.constructor = R3.Socket.Cast; + +R3.Socket.Cast.prototype.createInstance = function() { + R3.Socket.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.Socket.Cast.prototype.updateInstance = function(property) { + + if (property === 'castType') { + console.log('todo: implement castType update'); + return; + } + + if (property === 'source') { + console.log('todo: implement source update'); + return; + + if (this.source !== null) { + this.sourceProperties = R3.Utils.ObjectPropertiesAsBoolean(this.source); + } else { + this.sourceProperties = {}; + } + + R3.Event.Emit( + R3.Event.CAST_SOURCE_CHANGED, + { + component:this + } + ) + } + + if (property === 'sourceProperties') { + console.log('todo: implement sourceProperties update'); + return; + } + + R3.Socket.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-socket-receive.js b/src/r3-socket-receive.js new file mode 100644 index 0000000..f2af35e --- /dev/null +++ b/src/r3-socket-receive.js @@ -0,0 +1,64 @@ +/** + * R3.Socket.Receive + * @param apiComponent + * @property receiveType + * @property destination + * @property destinationProperties + * @constructor + */ +R3.Socket.Receive = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + R3.Socket.call( + this, + true + ); + +}; + +R3.Socket.Receive.prototype = Object.create(R3.Socket.prototype); +R3.Socket.Receive.prototype.constructor = R3.Socket.Receive; + +R3.Socket.Receive.prototype.createInstance = function() { + R3.Socket.prototype.createInstance.call(this); +}; + +/** + * Updates the instance with the current state + */ +R3.Socket.Receive.prototype.updateInstance = function(property) { + + if (property === 'receiveType') { + console.log('todo: implement receiveType update'); + return; + } + + if (property === 'destination') { + + console.log('todo: implement destination update'); + return; + + if (this.destination !== null) { + this.destinationProperties = R3.Utils.ObjectPropertiesAsBoolean(this.destination); + } else { + this.destinationProperties = {}; + } + + R3.Event.Emit( + R3.Event.RECEIVE_DESTINATION_CHANGED, + { + component:this + } + ) + } + + if (property === 'destinationProperties') { + console.log('todo: implement destinationProperties update'); + return; + } + + R3.Socket.prototype.updateInstance.call(this, property); +}; diff --git a/src/r3-sphere.js b/src/r3-sphere.js new file mode 100644 index 0000000..3cf9dd1 --- /dev/null +++ b/src/r3-sphere.js @@ -0,0 +1,66 @@ +/** + * R3.Sphere + * @param apiComponent + * + * @property center + * @property radius + * + * @constructor + */ +R3.Sphere = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.Sphere.prototype = Object.create(R3.Component.prototype); +R3.Sphere.prototype.constructor = R3.Sphere; + +/** + * Creates an instance R3.Sphere + * @returns {*} + */ +R3.Sphere.prototype.createInstance = function() { + + if (this.parent.runtime === R3.Runtime.PHYSICS) { + this.instance = this.physics.Sphere( + this.center, + this.radius + ); + } + + if (this.parent.runtime === R3.Runtime.GRAPHICS) { + this.instance = this.graphics.Sphere( + this.center, + this.radius + ); + } + + __CREATE_INSTANCE__; + +}; + +/** + * Updates R3.Sphere instance + * @param property + */ +R3.Sphere.prototype.updateInstance = function(property) { + + if (property === 'center') { + this.instance.center.x = this.center.x; + this.instance.center.y = this.center.y; + this.instance.center.z = this.center.z; + return; + } + + if (property === 'radius') { + this.instance.radius = this.radius; + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-stats.js b/src/r3-stats.js new file mode 100644 index 0000000..694a7c8 --- /dev/null +++ b/src/r3-stats.js @@ -0,0 +1,60 @@ +/** + * R3.Stats + * @param apiComponent + * + * @property domElement + * + * @constructor + */ +R3.Stats = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.Stats.prototype = Object.create(R3.Component.prototype); +R3.Stats.prototype.constructor = R3.Stats; + +/** + * Creates a helper instance + */ +R3.Stats.prototype.createInstance = function() { + + this.instance = this.stats.instance(); + + this.resize(); + + this.domElement.instance.parentElement.appendChild(this.instance.dom); + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance with the current state + */ +R3.Stats.prototype.updateInstance = function(property) { + + if (property === 'domElement') { + console.warn('todo: update domElement change for stats'); + return; + } + + __UPDATE_INSTANCE__; + +}; + +R3.Stats.prototype.resize = function() { + console.log('override stats resize per implementation'); +}; + + +R3.Stats.prototype.start = function() { + this.instance.begin(); +}; + +R3.Stats.prototype.end = function() { + this.instance.end(); +}; diff --git a/src/r3-system-0.js b/src/r3-system-0.js new file mode 100644 index 0000000..5ea585c --- /dev/null +++ b/src/r3-system-0.js @@ -0,0 +1,49 @@ +/** + * System takes care of updating all the entities (based on their component data) + * @param apiSystem R3.API.System + * @constructor + */ +R3.System = function( + apiSystem +) { + this.started = false; +}; + +R3.System.SYSTEM_TYPE_NONE = 0x0; +R3.System.SYSTEM_TYPE_RENDER = 0x1; +R3.System.SYSTEM_TYPE_ANIMATION = 0x2; +R3.System.SYSTEM_TYPE_INPUT = 0x4; +R3.System.SYSTEM_TYPE_STORAGE = 0x8; +R3.System.SYSTEM_TYPE_GUI = 0xf; +R3.System.SYSTEM_TYPE_PHYSICS = 0x10; +R3.System.SYSTEM_TYPE_LINKING = 0x12; +R3.System.SYSTEM_TYPE_CUSTOM = 0x14; +R3.System.SYSTEM_TYPE_VISUALIZATION = 0x18; +R3.System.SYSTEM_TYPE_PARTICLE = 0x1f; +R3.System.SYSTEM_TYPE_AUDIO = 0x20; +R3.System.SYSTEM_TYPE_SOCKET = 0x21; +R3.System.SYSTEM_TYPE_QUERY = 0x22; +R3.System.SYSTEM_TYPE_ALL = 0xff; + +/** + * @callback + * @override + */ +R3.System.prototype.start = function() { + this.started = true; +}; + +/** + * @callback + * @override + */ +R3.System.prototype.stop = function() { + this.started = false; +}; + + +R3.System.prototype.restart = function() { + console.log('restarting system : ' + this.name); + this.stop(); + this.start(); +}; \ No newline at end of file diff --git a/src/r3-system-animation.js b/src/r3-system-animation.js new file mode 100644 index 0000000..808cfa3 --- /dev/null +++ b/src/r3-system-animation.js @@ -0,0 +1,1162 @@ +/** + * System takes care of updating all the entities (based on their component data) + * @param apiSystem R3.API.System + * @constructor + */ +R3.System.Animation = function( + apiSystem +) { + R3.System.call( + this, + apiSystem + ); + + this.animations = []; + // this.textures = []; + // this.textureIds = []; + +// 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 R3.Texture + */ + this.animateTextureInstanceSubscription = null; +}; + +R3.System.Animation.prototype = Object.create(R3.System.prototype); +R3.System.Animation.prototype.constructor = R3.System.Animation; + +R3.System.Animation.prototype.start = function() { + + R3.System.prototype.start.call(this); + + this.beforeRenderSubscription = R3.Event.Subscribe( + R3.Event.BEFORE_RENDER, + this.beforeRender.bind(this) + ); + + this.animations = R3.EntityManager.Instance.queryComponents(R3.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 = R3.Event.Subscribe( + // R3.Event.ANIMATION_MESH_ADDED, + // function(data) { + // this.attachAnimation(data.animation, data.mesh); + // }.bind(this) + // ); + // + // this.animationMeshRemovedSubscription = R3.Event.Subscribe( + // R3.Event.ANIMATION_MESH_REMOVED, + // function(data) { + // this.detachAnimation(data.mesh); + // }.bind(this) + // ); + + this.instanceCreatedSubscription = R3.Event.Subscribe( + R3.Event.INSTANCE_CREATED, + this.instanceCreated.bind(this) + ); + + this.removeComponentSubscription = R3.Event.Subscribe( + R3.Event.REMOVE_COMPONENT, + this.removeComponent.bind(this) + ); + + this.textureAnimatedSubscription = R3.Event.Subscribe( + R3.Event.TEXTURE_ANIMATED_CHANGE, + this.textureAnimatedChange.bind(this) + ); + + this.animateTextureInstanceSubscription = R3.Event.Subscribe( + R3.Event.ANIMATE_TEXTURE_INSTANCE, + this.animateTextureInstance.bind(this) + ) +}; + +R3.System.Animation.prototype.instanceCreated = function(data) { + + if ( + data.component instanceof R3.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 R3.D3.Animation) { + + R3.Utils.PushUnique(this.animations, data.component); + // + // this.animations[data.component.id] = data.component; + // data.component.meshes.map( + // function(mesh){ + // this.attachAnimation(data.component, mesh) + // }.bind(this) + // ); + } +}; + +R3.System.Animation.prototype.removeComponent = function(data) { + + if ( + data.component instanceof R3.D3.Texture && + data.component.animated + ) { + if (R3.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 R3.D3.Animation) { + + var index = this.animations.indexOf(data.component); + + if (index === -1) { + console.warn('animation index out of sync'); + } else { + this.animations.splice(index, 1); + } + } + + if (data.component instanceof R3.D3.Mesh) { + this.animations.map( + function(animation) { + + var index = animation.meshes.indexOf(data.component); + + if (index !== -1) { + animation.meshes.splice(index, 1); + animation.updateInstance('meshes'); + } + } + ) + } +}; + +R3.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 (R3.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 R3 component and linking + * system, which adds too much overhead for managing textures + * @param data + */ +R3.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); +}; + +/** + * Performs a slight change on object[property][subProperty] from instance towards object + * @param object + * @param property + * @param subProperty + * @param increment + * @returns {boolean} + */ +R3.System.Animation.prototype.slightChange = function(object, property, subProperty, increment) { + + var current = object.instance[property][subProperty]; + var target = object[property][subProperty]; + + if (Math.abs(target - current) < increment) { + object.instance[property][subProperty] = object[property][subProperty]; + return false; + } else if (current > target) { + object.instance[property][subProperty] -= increment; + } else { + object.instance[property][subProperty] += increment; + } + + return true; +}; + +R3.System.Animation.prototype.beforeRender = function(data) { + + if (this.paused) { + return; + } + + var increment = 0; + + this.animations.map( + function(animation) { + animation.meshes.map( + function(mesh) { + + if (animation.rotationSpeed) { + /** + * Apply slight rotation to mesh + */ + increment = animation.rotationSpeed * data.delta; + + this.slightChange(mesh, 'rotation', 'x', increment); + this.slightChange(mesh, 'rotation', 'y', increment); + this.slightChange(mesh, 'rotation', 'z', increment); + } + + if (animation.translationSpeed) { + /** + * Apply slight translation to mesh + */ + increment = animation.translationSpeed * data.delta; + + this.slightChange(mesh, 'position', 'x', increment); + this.slightChange(mesh, 'position', 'y', increment); + this.slightChange(mesh, 'position', 'z', increment); + } + + if (animation.scaleSpeed) { + /** + * Apply slight scale to mesh + */ + increment = animation.scaleSpeed * data.delta; + + this.slightChange(mesh, 'scale', 'x', increment); + this.slightChange(mesh, 'scale', 'y', increment); + this.slightChange(mesh, 'scale', 'z', increment); + } + }.bind(this) + ) + }.bind(this) + ); + + 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) + ) +}; + +/** + * Stop Animation System + */ +R3.System.Animation.prototype.stop = function() { + + R3.System.prototype.stop.call(this); + + this.beforeRenderSubscription.remove(); + + // this.animationMeshAddedSubscription.remove(); + // + // this.animationMeshRemovedSubscription.remove(); + // + this.animations = []; + + this.instanceCreatedSubscription.remove(); + + this.removeComponentSubscription.remove(); + + this.textureAnimatedSubscription.remove(); + + this.animateTextureInstanceSubscription.remove(); +}; + + + +/* +R3.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'); + } + +}; +*/ + +//R3.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 + } + ); +}; +*/ +// R3.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 = []; +// } +// }; +// } +// }; +// +// R3.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); +// +// // R3.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 = R3.Event.Subscribe( +// R3.Event.BEFORE_RENDER, +// function(data) { +// +// var increment = Math.abs(animation.rotationSpeed); +// +// if (!mesh.animationObject.angleIncrement) { +// increment *= -1; +// } +// +// animateRotation(data.delta * increment); +// } +// ); +// } +// }; +// +// R3.System.Animation.prototype.getQuaternionAxisX = function(mesh, animation) { +// return function() { +// return this.latest[mesh.id].quaternion.axis.x; +// }.bind(this); +// }; +// +// R3.System.Animation.prototype.setQuaternionAxisX = function(mesh, animation) { +// return function(value) { +// this.latest[mesh.id].quaternion.axis.x = value; +// }.bind(this); +// }; +// +// R3.System.Animation.prototype.getQuaternionAxisY = function(mesh, animation) { +// return function() { +// return this.latest[mesh.id].quaternion.axis.y; +// }.bind(this); +// }; +// +// R3.System.Animation.prototype.setQuaternionAxisY = function(mesh, animation) { +// return function(value) { +// this.latest[mesh.id].quaternion.axis.y = value; +// }.bind(this); +// }; +// +// R3.System.Animation.prototype.getQuaternionAxisZ = function(mesh, animation) { +// return function() { +// return this.latest[mesh.id].quaternion.axis.z; +// }.bind(this); +// }; +// +// R3.System.Animation.prototype.setQuaternionAxisZ = function(mesh, animation) { +// return function(value) { +// this.latest[mesh.id].quaternion.axis.z = value; +// }.bind(this); +// }; +// +// R3.System.Animation.prototype.getSubProperty = function(mesh, axis, property, subProperty) { +// return function() { +// return this.latest[mesh.id][property][subProperty][axis]; +// }.bind(this); +// }; + +// R3.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) +// }; + +// R3.System.Animation.prototype.getProperty = function(mesh, axis, property) { +// return function() { +// return this.latest[mesh.id][property][axis]; +// }.bind(this); +// }; +// +// R3.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) +// }; + diff --git a/src/r3-system-ar.js b/src/r3-system-ar.js new file mode 100644 index 0000000..2ed27ed --- /dev/null +++ b/src/r3-system-ar.js @@ -0,0 +1,96 @@ +/** + * R3.System.AR + * @param apiSystem R3.API.System + * @constructor + */ +R3.System.AR = function( + apiSystem +) { + R3.System.call( + this, + apiSystem + ); + + this.instanceCreatedSubscription = null; + + this.removeComponentSubscription = null; + + this.beforeRenderSubscription = null; + + this.arComponents = []; + +}; + +R3.System.AR.prototype = Object.create(R3.System.prototype); +R3.System.AR.prototype.constructor = R3.System.AR; + +/** + * Start this system (add all event listeners) + */ +R3.System.AR.prototype.start = function() { + + R3.System.prototype.start.call(this); + + this.instanceCreatedSubscription = this.subscribe( + R3.Event.INSTANCE_CREATED, + this.instanceCreated + ); + + this.removeComponentSubscription = this.subscribe( + R3.Event.REMOVE_COMPONENT, + this.removeComponent + ); + + this.beforeRenderSubscription = this.subscribe( + R3.Event.BEFORE_RENDER, + this.beforeRender + ); + +}; + +/** + * From now on we want to track everything about a component, only from the systems that are active + * @param data + */ +R3.System.AR.prototype.instanceCreated = function(data) { + if (data.component instanceof R3.D3.AR) { + R3.Utils.PushUnique(this.arComponents, data.component); + } +}; + +/** + * Removes an AR component from the System + * @param data + */ +R3.System.AR.prototype.removeComponent = function(data) { + + if (data.component instanceof R3.D3.AR) { + + var index = this.arComponents.indexOf(data.component); + + if (index === -1) { + console.warn('AR system out of sync'); + return; + } + + this.arComponents.splice(index, 1); + } +}; + +R3.System.AR.prototype.beforeRender = function(data) { + console.log('AR Render'); +}; + + +/** + * Stop this system (remove all event listeners) + */ +R3.System.AR.prototype.stop = function() { + + R3.System.prototype.stop.call(this); + + this.instanceCreatedSubscription.remove(); + this.removeComponentSubscription.remove(); + this.beforeRenderSubscription.remove(); + +}; diff --git a/src/r3-system-audio.js b/src/r3-system-audio.js new file mode 100644 index 0000000..42962d4 --- /dev/null +++ b/src/r3-system-audio.js @@ -0,0 +1,292 @@ +/** + * System takes care of updating all the entities (based on their component data) + * @param apiSystem R3.API.System + * @constructor + */ +R3.System.Audio = function( + apiSystem +) { + R3.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 = []; +}; + +R3.System.Audio.prototype = Object.create(R3.System.prototype); +R3.System.Audio.prototype.constructor = R3.System.Audio; + +/** + * Start this system (add all event listeners) + */ +R3.System.Audio.prototype.start = function() { + + R3.System.prototype.start.call(this); + + this.instanceCreatedSubscription = R3.Event.Subscribe( + R3.Event.INSTANCE_CREATED, + this.instanceCreated.bind(this) + ); + + this.removeComponentSubscription = R3.Event.Subscribe( + R3.Event.REMOVE_COMPONENT, + this.removeComponent.bind(this) + ); + + this.playAudioSubscription = R3.Event.Subscribe( + R3.Event.PLAY_AUDIO, + this.playAudio.bind(this) + ); + + this.pauseAllAudioSubscription = R3.Event.Subscribe( + R3.Event.PAUSE_ALL_AUDIO, + this.pauseAllAudio.bind(this) + ); + + this.muteAudioSubscription = R3.Event.Subscribe( + R3.Event.MUTE_AUDIO, + this.muteAudio.bind(this) + ); + + this.continueAllAudioSubscription = R3.Event.Subscribe( + R3.Event.CONTINUE_ALL_AUDIO, + this.continueAllAudio.bind(this) + ); + + this.stopAudioSubscription = R3.Event.Subscribe( + R3.Event.STOP_AUDIO, + this.stopAudio.bind(this) + ); + + this.stopAllAudioSubscription = R3.Event.Subscribe( + R3.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 + */ +R3.System.Audio.prototype.instanceCreated = function(data) { + + if (data.component instanceof R3.D3.Audio) { + + R3.Utils.PushUnique(this.audioComponents, data.component); + + data.component.instance.onEnded = function() { + this.isPlaying = false; + R3.Event.Emit( + R3.Event.AUDIO_ENDED, + { + audio : data.component + } + ); + }; + + var index = this.toPlay.indexOf(data.component.name); + + if (index !== -1) { + + R3.Event.Emit( + R3.Event.PLAY_AUDIO, + { + name : data.component.name + } + ); + + this.toPlay.splice(index, 1); + } + } +}; + +/** + * Removes a particle engine from this system + * @param data + */ +R3.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); + } +}; + +R3.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) + ) +}; + +R3.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 = []; + +}; + +R3.System.Audio.prototype.stopAllAudio = function(data) { + this.audioComponents.map( + function(audio) { + if (audio.instance.isPlaying) { + audio.instance.stop(); + } + } + ) +}; + + +R3.System.Audio.prototype.stopAudio = function(data) { + this.audioComponents.map( + function(audio) { + if (audio.name === data.name) { + if (audio.instance.isPlaying) { + audio.instance.stop(); + } + } + } + ) +}; + + +R3.System.Audio.prototype.removeComponent = function(data) { + +}; + +R3.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; + }, + [] + ); + + R3.Event.Emit(R3.Event.AUDIO_MUTED, {audioSystem:this}); + + } else { + + this.audioVolumes.map( + function(audioVolume) { + audioVolume.audio.volume = audioVolume.volume; + audioVolume.audio.updateInstance('volume'); + } + ); + + R3.Event.Emit(R3.Event.AUDIO_UNMUTED, {audioSystem:this}); + } +}; + + +/** + * Stop this system (remove all event listeners) + */ +R3.System.Audio.prototype.stop = function() { + + R3.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(); + +}; diff --git a/src/r3-system-custom-code.js b/src/r3-system-custom-code.js new file mode 100644 index 0000000..800a756 --- /dev/null +++ b/src/r3-system-custom-code.js @@ -0,0 +1,153 @@ +/** + * R3.System.CustomCode + * @constructor + */ +R3.System.CustomCode = function() { + + this.instanceCreatedSubscription = null; + this.removeComponentSubscription = null; + this.compileSuccessSubscription = null; + this.compileFailedSubscription = null; + this.eventIdUpdateSubscription = null; + + this.subscriptions = {}; + + R3.System.call( + this + ); + +}; + +R3.System.CustomCode.prototype = Object.create(R3.System.prototype); +R3.System.CustomCode.prototype.constructor = R3.System.CustomCode; + +/** + * Start the rendering system + */ +R3.System.CustomCode.prototype.start = function() { + + R3.EntityManager.Instance.queryComponents(R3.Component.CUSTOM_CODE).map( + function(component) { + this.subscriptions[component.id] = R3.Event.Subscribe( + component.eventId, + component.instance + ); + }.bind(this) + ); + + this.instanceCreatedSubscription = R3.Event.Subscribe( + R3.Event.INSTANCE_CREATED, + this.instanceCreated.bind(this) + ); + + this.removeComponentSubscription = R3.Event.Subscribe( + R3.Event.REMOVE_COMPONENT, + this.removeComponent.bind(this) + ); + + this.compileSuccessSubscription = R3.Event.Subscribe( + R3.Event.COMPILE_SUCCESS, + this.compileSuccess.bind(this) + ); + + this.compileFailedSubscription = R3.Event.Subscribe( + R3.Event.COMPILE_FAILED, + this.compileFailed.bind(this) + ); + + this.eventIdUpdateSubscription = R3.Event.Subscribe( + R3.Event.EVENT_ID_UPDATE, + this.compileSuccess.bind(this) + ); + + R3.System.prototype.start.call(this); +}; + +R3.System.CustomCode.prototype.instanceCreated = function(data) { + + if (data.component instanceof R3.CustomCode) { + + if (this.subscriptions[data.component.id]) { + console.warn('a component already existed'); + this.subscriptions[data.component.id].remove(); + } + + this.subscriptions[data.component.id] = R3.Event.Subscribe( + data.component.eventId, + data.component.instance + ); + } +}; + +R3.System.CustomCode.prototype.removeComponent = function(data) { + if (data.component instanceof R3.CustomCode) { + if (this.subscriptions[data.component.id]) { + this.subscriptions[data.component.id].remove(); + delete this.subscriptions[data.component.id]; + } + } +}; + +R3.System.CustomCode.prototype.compileSuccess = function(data) { + + if (this.subscriptions[data.component.id]) { + this.subscriptions[data.component.id].remove(); + } + + this.subscriptions[data.component.id] = R3.Event.Subscribe( + data.component.eventId, + data.component.instance + ); +}; + +R3.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 + */ +R3.System.CustomCode.prototype.stop = function() { + + 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; + } + + if (this.eventIdUpdateSubscription) { + this.eventIdUpdateSubscription.remove(); + this.eventIdUpdateSubscription = null; + } + + Object.keys(this.subscriptions).map( + function(componentId) { + if (this.subscriptions[componentId]) { + this.subscriptions[componentId].remove(); + delete this.subscriptions[componentId]; + } + }.bind(this) + ); + + R3.System.prototype.stop.call(this); + +}; + diff --git a/src/r3-system-gui.js b/src/r3-system-gui.js new file mode 100644 index 0000000..3b7e9e6 --- /dev/null +++ b/src/r3-system-gui.js @@ -0,0 +1,985 @@ +/** + * System takes care of updating all the entities (based on their component data) + * @param apiSystem R3.API.System + * @constructor + */ +/** + * R3.System.GU + * @constructor + */ +R3.System.GUI = function(options) { + + if (R3.Utils.UndefinedOrNull(options)) { + options = {}; + } + + R3.System.call(this); + + if (R3.Utils.UndefinedOrNull(options.guis)) { + options.guis = []; + } + this.guis = options.guis; + + this.guiCreatedSubscription = null; + + this.guiRemovedSubscription = null; + + this.buildGUISubscription = null; + + this.clearGUISubscription = null; + + this.beforeRenderSubscription = null; + + this.removeComponentSubscription = null; + + // this.faces = []; + // + // this.exclusiveMode = false; + // + // + // this.meshDeletedSubscription = null; + // + // this.meshSelectedSubscription = null; + // + // this.meshDeselectedSubscription = null; + // + // this.newEntitySubscription = null; + // + // this.meshSelectionObjects = {}; + // + // this.sourceChangedSubscription = null; + // + // + // + // this.windowResizeSubscription = null; + // + // this.meshFaceSelectedSubscription = null; + // + // this.meshFaceDeselectedSubscription = null; + +}; + +R3.System.GUI.prototype = Object.create(R3.System.prototype); +R3.System.GUI.prototype.constructor = R3.System.GUI; + +R3.System.GUI.prototype.start = function() { + + this.guiCreatedSubscription = R3.Event.Subscribe( + R3.Event.GUI_CREATED, + this.guiCreated.bind(this) + ); + + this.guiRemovedSubscription = R3.Event.Subscribe( + R3.Event.GUI_REMOVED, + this.guiRemoved.bind(this) + ); + + this.buildGUISubscription = R3.Event.Subscribe( + R3.Event.BUILD_GUI, + this.buildGUI.bind(this) + ); + + this.clearGUISubscription = R3.Event.Subscribe( + R3.Event.CLEAR_GUI, + this.clearGUI.bind(this) + ); + + this.beforeRenderSubscription = R3.Event.Subscribe( + R3.Event.BEFORE_RENDER, + this.beforeRender.bind(this) + ); + + this.removeComponentSubscription = R3.Event.Subscribe( + R3.Event.REMOVE_COMPONENT, + this.removeComponent.bind(this) + ); + + R3.System.prototype.start.call(this); + + + // this.windowResizeSubscription = R3.Event.Subscribe( + // R3.Event.WINDOW_RESIZE, + // this.windowResize.bind(this) + // ); + // + // this.meshFaceSelectedSubscription = R3.Event.Subscribe( + // R3.Event.MESH_FACE_SELECTED, + // this.meshFaceSelected.bind(this) + // ); + // + // this.meshFaceDeselectedSubscription = R3.Event.Subscribe( + // R3.Event.MESH_FACE_DESELECTED, + // this.meshFaceDeselected.bind(this) + // ); + // + // this.guis = R3.EntityManager.Instance.findComponentsByConstructor(R3.GUI); + // this.guis.map( + // function(gui){ + // this.initialize(gui); + // }.bind(this) + // ); + + + // this.meshDeletedSubscription = R3.Event.Subscribe( + // R3.Event.REMOVE_MESH, + // this.meshDeleted.bind(this) + // ); + // + // this.meshSelectedSubscription = R3.Event.Subscribe( + // R3.Event.MESH_SELECTED, + // this.meshSelected.bind(this) + // ); + // + // this.meshDeselectedSubscription = R3.Event.Subscribe( + // R3.Event.MESH_DESELECTED, + // this.meshDeslected.bind(this) + // ); + // + // this.componentRemovedSubscription = R3.Event.Subscribe( + // R3.Event.REMOVE_COMPONENT, + // this.removeComponent.bind(this) + // ); + // + // this.sourceChangedSubscription = R3.Event.Subscribe( + // R3.Event.CAST_SOURCE_CHANGED, + // this.castSourceChanged.bind(this) + // ); + // + // this.destinationChangedSubscription = R3.Event.Subscribe( + // R3.Event.RECEIVE_DESTINATION_CHANGED, + // this.receiveDestinationChanged.bind(this) + // ); + +}; + +// R3.System.GUI.prototype.windowResize = function(data) { +// }; + +R3.System.GUI.prototype.beforeRender = function() { + this.guis.map( + function(gui) { + if (typeof gui.instance.update === 'function') { + gui.instance.update(); + } + } + ); +}; + +R3.System.GUI.prototype.removeComponent = function(data) { + + this.guis.map( + function(gui) { + gui.instance._panels.map( + function(panel) { + if (panel._label === data.component.name) { + panel.getNode().getElement().parentElement.removeChild(panel.getNode().getElement()) + } + } + ) + } + ); + +}; + +R3.System.GUI.prototype.guiCreated = function(gui) { + R3.Utils.PushUnique(this.guis, gui); +}; + +R3.System.GUI.prototype.guiRemoved = function(gui) { + + gui.dispose(); + + var index = this.guis.indexOf(gui); + + if (index === -1) { + console.warn('gui system out of sync'); + } else { + this.guis.splice(index, 1); + } + +}; + + +// /** +// * Push the mesh to our backup components, if in exclusiveMode (menu at top is selected), +// * otherwise, just to our normal components +// * @param data +// */ +// R3.System.GUI.prototype.meshSelected = function(data) { +// +// if (this.exclusiveMode) { +// R3.Utils.PushUnique(this.backupComponents, data.mesh); +// } else { +// R3.Utils.PushUnique(this.components, data.mesh); +// } +// +// }; +// +// /** +// * Same as selected above, but removes the mesh from the components +// * @param data +// */ +// R3.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); +// } +// } +// +// }; +// +// R3.System.GUI.prototype.meshFaceSelected = function(data) { +// +// this.faces.push(data.face); +// +// this.buildGUI({ +// components : this.faces +// }) +// }; +// +// R3.System.GUI.prototype.meshFaceDeselected = function(data) { +// +// var index = this.faces.indexOf(data.face); +// +// if (index !== -1) { +// this.faces.splice(index, 1); +// +// if (this.faces.length === 0) { +// this.buildGUI({}); +// } else { +// this.buildGUI({components : this.faces}) +// } +// +// } else { +// console.warn('could not remove face'); +// } +// }; + +/** + * 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 + */ +/** + * clear GUI + */ +R3.System.GUI.prototype.clearGUI = function() { + this.guis.map( + function(gui) { + gui.clear(); + } + ); +}; + +R3.System.GUI.prototype.buildGUI = function(component) { + + this.guis.map( + function(gui) { + + /** + * First, start fresh - remove all folders + */ + gui.clear(); + + var addComponent = function(group, component, property) { + if ( + component.hasOwnProperty(property) || + typeof component[property] === 'function' + ) { + + if ( + property === 'componentType' || + property === 'register' || + property === 'linked' || + property === 'loaded' || + property === 'selected' + ) { + return; + } + + if (component.guiInfo && component.guiInfo[property] && component.guiInfo[property].options) { + gui.addSelect(group, component, property); + return; + } + + if (component[property] instanceof R3.Color) { + gui.addColor(group, component, property); + return; + } + + if (typeof component[property] === 'boolean') { + gui.addCheckbox(group, component, property); + return; + } + + if (typeof component[property] === 'number') { + gui.addNumber(group, component, property); + return; + } + + if (typeof component[property] === 'string') { + gui.addString(group, component, property); + return; + } + + if (typeof component[property] === 'function') { + gui.addButton(group, component, property); + return; + } + } + }; + + var panel = gui.addPanel(component.name); + + gui.addGroup(panel, 'Main'); + + var traverseComponent = function(component) { + + var properties = Object.keys(component); + + properties.sort(); + + properties.splice(properties.indexOf('id'), 1); + properties.splice(properties.indexOf('name'), 1); + + properties.unshift('name'); + properties.unshift('id'); + + properties.map( + function(property) { + if (component.hasOwnProperty(property)) { + + if (component.guiInfo && component.guiInfo.hasOwnProperty(property)) { + /** + * Skip properties in guiInfos - they need to go into subgroups + */ + return; + } + + addComponent(panel, component, property); + } + } + ); + + properties.map( + function(property) { + if (component.hasOwnProperty(property)) { + + if (!(component.guiInfo && component.guiInfo.hasOwnProperty(property))) { + /** + * Skip properties *NOT* in guiInfos + */ + return; + } + + var group = panel.addSubGroup( + { + label : property + } + ); + addComponent(group, component, property); + } + } + ); + }; + + traverseComponent(component); + + Object.keys(component.idToObject).map( + function(id) { + + var _component = R3.EntityManager.Instance.findComponentById(id); + + if (_component.id === component.id) { + return; + } + + if (_component instanceof R3.Color) { + return; + } + + gui.addGroup(panel, _component.name); + + traverseComponent(_component); + } + ); + + var functions = []; + + for (var fn in component) { + if ( + typeof component[fn] === 'function') { + if ( + // fn === 'clone' || + fn === 'remove' || + fn === 'save' + // fn === 'saveToRemoteAPI' + ) { + functions.push(fn); + } + } + } + + functions.sort(); + + var actions = gui.addGroup(panel, 'Actions'); + + functions.map( + function(fn) { + addComponent(actions, component, fn); + } + ) + + // var guiInfos = Object.keys(__component.guiInfo); + // + // var linkedObjects = Object.keys(__component.idToObject); + // + // + // + // + // .reduce( + // function(result, key) { + // + // var + // + // result.push(key); + // return result; + // }, + // [] + // ); + // + // var numberGroup = panel.addGroup( + // { + // label : 'Numbers' + // } + // ); + // + // var stringGroup = panel.addGroup( + // { + // label : 'Strings' + // } + // ); + // + // + // var addComponent = function(group, component) { + // return function(property) { + // if (component.hasOwnProperty(property)) { + // + // if (typeof component[property] === 'number') { + // gui.addNumber(numberGroup, component, property) + // } + // + // if (typeof component[property] === 'string') { + // gui.addString(stringGroup, component, property) + // } + // + // if (typeof component[property] === 'function') { + // gui.addButton(group, component, property) + // } + // } + // }; + // }; + // + // Object.keys(__component).map(addComponent(panel, __component)); + // + // Object.keys(__component.idToObject).map( + // function(id) { + // + // if (id === __component.id) { + // return; + // } + // + // var component = R3.EntityManager.Instance.findComponentById(id); + // + // var group = gui.addGroup(panel, component.name); + // + // Object.keys(component).map(addComponent(group, component)); + // } + // ); + + }.bind(this) + ); + + return; + + 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 R3.D3.Mesh); + } + ); + } + + /** + * Check if we have components to build a GUI for + */ + if (R3.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(); + + R3.Utils.PushUnique(result, component); + + components.map(function(component){ + R3.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) { + R3.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 parent at the top of the gui + */ + 'parent' : componentGroup.components[0].parent + }, + 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 R3.Vector2 || + result.template[property] instanceof R3.Vector3 || + result.template[property] instanceof R3.Vector4 || + result.template[property] instanceof R3.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 (R3.Utils.UndefinedOrNull(componentTemplate.template.name)) { + name = R3.GetComponentName(componentTemplate) + ' (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 R3.Vector2 || + componentTemplate.template[templateProperty] instanceof R3.Vector3 || + componentTemplate.template[templateProperty] instanceof R3.Vector4 + ) { + this.buildVectorControl(folder, componentTemplate, templateProperty); + continue; + } + + if (componentTemplate.template[templateProperty] instanceof R3.Quaternion) { + this.buildQuaternionControl(folder, componentTemplate, templateProperty); + } + + if ( + templateProperty.indexOf('parent') === 0 + ) { + + if (componentTemplate.template[templateProperty] instanceof Array) { + console.warn('read-only property :' + templateProperty); + } else { + this.buildParentSelectionControl(folder, componentTemplate, templateProperty); + } + + continue; + } + + if (componentTemplate.template[templateProperty] instanceof Array) { + + if ( + templateProperty === 'vertices' || + templateProperty === 'faces' + ) { + continue; + } + + if (templateProperty === 'uvs') { + this.buildUVManagerControl(folder, componentTemplate, templateProperty); + } + + if ( + componentTemplate.template.linkedComponents && + componentTemplate.template.linkedComponents[templateProperty] instanceof Array + ) { + this.buildArrayManagerControl(folder, componentTemplate, templateProperty); + } + + continue; + } + + if (componentTemplate.template[templateProperty] instanceof R3.Color) { + this.buildColorControl(folder, componentTemplate, templateProperty); + continue; + } + + if (typeof componentTemplate.template[templateProperty] === 'object') { + + if ( + componentTemplate.template[templateProperty] instanceof R3.Component || + ( + componentTemplate.template.linkedComponents && + componentTemplate.template.linkedComponents[templateProperty] + ) + ) { + this.buildSelectControl(folder, componentTemplate, templateProperty) + } else { + this.buildObjectControl(folder, componentTemplate, templateProperty); + } + continue; + } + + this.buildControl(folder, componentTemplate, templateProperty); + } + } + }.bind(this) + ); + }.bind(this)); + +}; + +// R3.System.GUI.prototype.meshDeleted = function(data) { +// +// data.meshes.map(function(mesh){ +// this.meshDeslected({ +// mesh : mesh +// }) +// }.bind(this)); +// +// this.buildGUI(null); +// }; +// +// R3.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); +// } +// +// }; +// +// R3.System.GUI.prototype.castSourceChanged = function(data) { +// this.buildGUI(null); +// }; +// +// R3.System.GUI.prototype.receiveDestinationChanged = function(data) { +// this.buildGUI(null); +// }; + +R3.System.GUI.prototype.stop = function() { + + this.guis.map( + function(gui) { + gui.dispose(); + } + ); + + this.guiCreatedSubscription.remove(); + + this.guiRemovedSubscription.remove(); + + this.buildGUISubscription.remove(); + + this.clearGUISubscription.remove(); + + this.beforeRenderSubscription.remove(); + + this.removeComponentSubscription.remove(); + + R3.System.prototype.stop.call(this); + +}; + diff --git a/src/r3-system-input.js b/src/r3-system-input.js new file mode 100644 index 0000000..cd0fbdf --- /dev/null +++ b/src/r3-system-input.js @@ -0,0 +1,1496 @@ +/** + * R3.System.Input + * @constructor + */ +R3.System.Input = function() { + + R3.System.call( + this + ); + + this.selectAll = false; + + this.applicationMode = R3.API.Project.APPLICATION_MODE_EDIT; + + R3.Event.Emit( + R3.Event.GET_APPLICATION_MODE, + null, + function(applicationMode) { + this.applicationMode = applicationMode; + }.bind(this) + ); + + this.grabMode = false; + + this.grabModeDirection = 'x'; + + this.controlLeft = false; + + this.sensitivityCounter = 0; + + this.playAudio = true; + + this.editorControls = []; + this.orbitControls = []; + this.firstPersonControls = []; + this.touchControls = []; + this.keyboardControls = []; + this.mouseControls = []; + + /** + * Touch Controls + * @type {null} + */ + this.touchStart = this.onTouchStart.bind(this); + this.touchMove = this.onTouchMove.bind(this); + this.touchEnd = this.onTouchEnd.bind(this); + this.touchCancel = this.onTouchCancel.bind(this); + + /** + * Keyboard Controls + * @type {null} + */ + this.keyboardKeyUp = this.onKeyboardKeyUp.bind(this); + this.keyboardKeyDown = this.onKeyboardKeyDown.bind(this); + + /** + * Mouse Controls + * @type {null} + */ + this.mouseDown = this.onMouseDown.bind(this); + this.mouseMove = this.onMouseMove.bind(this); + this.mouseWheel = this.onMouseWheel.bind(this); + this.mouseUp = this.onMouseUp.bind(this); + + this.instanceCreatedSubscription = null; + this.removeComponentSubscription = null; + this.canvasChangeSubscription = null; + this.selectionModeChangeSubscription = null; + this.beforeRenderSubscription = null; + this.applicationModeSubscription = null; + + this.selectionMode = R3.System.Input.SELECTION_MODE_DEFAULT; + +}; + +R3.System.Input.prototype = Object.create(R3.System.prototype); +R3.System.Input.prototype.constructor = R3.System.Input; + +R3.System.Input.SELECTION_MODE_MESH = 0x1; +R3.System.Input.SELECTION_MODE_FACE = 0x2; +R3.System.Input.SELECTION_MODE_DEFAULT = 0x1; + +R3.System.Input.KEY_CANCEL = 3; +R3.System.Input.KEY_HELP = 6; +R3.System.Input.KEY_BACK_SPACE = 8; +R3.System.Input.KEY_TAB = 9; +R3.System.Input.KEY_CLEAR = 12; +R3.System.Input.KEY_RETURN = 13; +R3.System.Input.KEY_ENTER = 14; +R3.System.Input.KEY_SHIFT = 16; +R3.System.Input.KEY_CONTROL = 17; +R3.System.Input.KEY_ALT = 18; +R3.System.Input.KEY_PAUSE = 19; +R3.System.Input.KEY_CAPS_LOCK = 20; +R3.System.Input.KEY_ESCAPE = 27; +R3.System.Input.KEY_SPACE = 32; +R3.System.Input.KEY_PAGE_UP = 33; +R3.System.Input.KEY_PAGE_DOWN = 34; +R3.System.Input.KEY_END = 35; +R3.System.Input.KEY_HOME = 36; +R3.System.Input.KEY_LEFT = 37; +R3.System.Input.KEY_UP = 38; +R3.System.Input.KEY_RIGHT = 39; +R3.System.Input.KEY_DOWN = 40; +R3.System.Input.KEY_PRINTSCREEN = 44; +R3.System.Input.KEY_INSERT = 45; +R3.System.Input.KEY_DELETE = 46; +R3.System.Input.KEY_0 = 48; +R3.System.Input.KEY_1 = 49; +R3.System.Input.KEY_2 = 50; +R3.System.Input.KEY_3 = 51; +R3.System.Input.KEY_4 = 52; +R3.System.Input.KEY_5 = 53; +R3.System.Input.KEY_6 = 54; +R3.System.Input.KEY_7 = 55; +R3.System.Input.KEY_8 = 56; +R3.System.Input.KEY_9 = 57; +R3.System.Input.KEY_SEMICOLON = 59; +R3.System.Input.KEY_EQUALS = 61; +R3.System.Input.KEY_A = 65; +R3.System.Input.KEY_B = 66; +R3.System.Input.KEY_C = 67; +R3.System.Input.KEY_D = 68; +R3.System.Input.KEY_E = 69; +R3.System.Input.KEY_F = 70; +R3.System.Input.KEY_G = 71; +R3.System.Input.KEY_H = 72; +R3.System.Input.KEY_I = 73; +R3.System.Input.KEY_J = 74; +R3.System.Input.KEY_K = 75; +R3.System.Input.KEY_L = 76; +R3.System.Input.KEY_M = 77; +R3.System.Input.KEY_N = 78; +R3.System.Input.KEY_O = 79; +R3.System.Input.KEY_P = 80; +R3.System.Input.KEY_Q = 81; +R3.System.Input.KEY_R = 82; +R3.System.Input.KEY_S = 83; +R3.System.Input.KEY_T = 84; +R3.System.Input.KEY_U = 85; +R3.System.Input.KEY_V = 86; +R3.System.Input.KEY_W = 87; +R3.System.Input.KEY_X = 88; +R3.System.Input.KEY_Y = 89; +R3.System.Input.KEY_Z = 90; +R3.System.Input.KEY_CONTEXT_MENU = 93; +R3.System.Input.KEY_NUMPAD0 = 96; +R3.System.Input.KEY_NUMPAD1 = 97; +R3.System.Input.KEY_NUMPAD2 = 98; +R3.System.Input.KEY_NUMPAD3 = 99; +R3.System.Input.KEY_NUMPAD4 = 100; +R3.System.Input.KEY_NUMPAD5 = 101; +R3.System.Input.KEY_NUMPAD6 = 102; +R3.System.Input.KEY_NUMPAD7 = 103; +R3.System.Input.KEY_NUMPAD8 = 104; +R3.System.Input.KEY_NUMPAD9 = 105; +R3.System.Input.KEY_MULTIPLY = 106; +R3.System.Input.KEY_ADD = 107; +R3.System.Input.KEY_SEPARATOR = 108; +R3.System.Input.KEY_SUBTRACT = 109; +R3.System.Input.KEY_DECIMAL = 110; +R3.System.Input.KEY_DIVIDE = 111; +R3.System.Input.KEY_F1 = 112; +R3.System.Input.KEY_F2 = 113; +R3.System.Input.KEY_F3 = 114; +R3.System.Input.KEY_F4 = 115; +R3.System.Input.KEY_F5 = 116; +R3.System.Input.KEY_F6 = 117; +R3.System.Input.KEY_F7 = 118; +R3.System.Input.KEY_F8 = 119; +R3.System.Input.KEY_F9 = 120; +R3.System.Input.KEY_F10 = 121; +R3.System.Input.KEY_F11 = 122; +R3.System.Input.KEY_F12 = 123; +R3.System.Input.KEY_F13 = 124; +R3.System.Input.KEY_F14 = 125; +R3.System.Input.KEY_F15 = 126; +R3.System.Input.KEY_F16 = 127; +R3.System.Input.KEY_F17 = 128; +R3.System.Input.KEY_F18 = 129; +R3.System.Input.KEY_F19 = 130; +R3.System.Input.KEY_F20 = 131; +R3.System.Input.KEY_F21 = 132; +R3.System.Input.KEY_F22 = 133; +R3.System.Input.KEY_F23 = 134; +R3.System.Input.KEY_F24 = 135; +R3.System.Input.KEY_NUM_LOCK = 144; +R3.System.Input.KEY_SCROLL_LOCK = 145; +R3.System.Input.KEY_COMMA = 188; +R3.System.Input.KEY_PERIOD = 190; +R3.System.Input.KEY_SLASH = 191; +R3.System.Input.KEY_BACK_QUOTE = 192; +R3.System.Input.KEY_OPEN_BRACKET = 219; +R3.System.Input.KEY_BACK_SLASH = 220; +R3.System.Input.KEY_CLOSE_BRACKET = 221; +R3.System.Input.KEY_QUOTE = 222; +R3.System.Input.KEY_META = 224; + +/** + * + */ +R3.System.Input.prototype.start = function() { + + R3.System.prototype.start.call(this); + + this.instanceCreatedSubscription = R3.Event.Subscribe( + R3.Event.INSTANCE_CREATED, + this.instanceCreated.bind(this) + ); + + this.removeComponentSubscription = R3.Event.Subscribe( + R3.Event.REMOVE_COMPONENT, + this.removeComponent.bind(this) + ); + + this.canvasChangeSubscription = R3.Event.Subscribe( + R3.Event.CANVAS_CHANGE, + this.canvasChange.bind(this) + ); + + this.beforeRenderSubscription = R3.Event.Subscribe( + R3.Event.BEFORE_RENDER, + this.beforeRender.bind(this) + ); + + this.selectionModeChangeSubscription = R3.Event.Subscribe( + R3.Event.SELECTION_MODE_CHANGE, + this.selectionModeChange.bind(this) + ); + + /** + * Normal Controls + */ + this.touchControls = R3.EntityManager.Instance.findComponentsByConstructor(R3.Controls.Touch); + + this.keyboardControls = R3.EntityManager.Instance.findComponentsByConstructor(R3.Controls.Keyboard); + + this.mouseControls = R3.EntityManager.Instance.findComponentsByConstructor(R3.Controls.Mouse); + + this.orbitControls = R3.EntityManager.Instance.findComponentsByConstructor(R3.Controls.D3.Orbit); + + this.firstPersonControls = R3.EntityManager.Instance.findComponentsByConstructor(R3.Controls.D3.FirstPerson); +}; + +/** + * + */ +R3.System.Input.prototype.stop = function() { + + R3.System.prototype.stop.call(this); + + this.instanceCreatedSubscription.remove(); + + this.removeComponentSubscription.remove(); + + this.canvasChangeSubscription.remove(); + + this.selectionModeChangeSubscription.remove(); + + this.beforeRenderSubscription.remove(); + + this.touchControls.map( + function(touchControl){ + this.deRegisterTouchControl(touchControl); + }.bind(this) + ); + + this.keyboardControls.map( + function(keyboardControl){ + this.deRegisterKeyboardControl(keyboardControl); + }.bind(this) + ); + + this.mouseControls.map( + function(mouseControl){ + this.deRegisterMouseControl(mouseControl); + }.bind(this) + ); + + this.orbitControls.map( + function(orbitControl) { + orbitControl.instance.dispose(); + } + ); + + this.firstPersonControls.map( + function(firstPersonControl) { + firstPersonControl.instance.dispose(); + } + ); + + this.editorControls = []; + + this.firstPersonControls = []; + + this.orbitControls = []; + + this.touchControls = []; + + this.keyboardControls = []; + + this.mouseControls = []; + +}; + +/** + * + * @param data + */ +R3.System.Input.prototype.canvasChange = function(data) { + if (data.component instanceof R3.Controls) { + console.log('todo: implement dom element change'); + } +}; + +/** + * Changes the selection mode from face to mesh etc. + * @param data + */ +R3.System.Input.prototype.selectionModeChange = function(data) { + this.selectionMode = data.selectionMode; +}; + + +R3.System.Input.prototype.beforeRender = function(project) { + + if (project.applicationMode === R3.API.Project.APPLICATION_MODE_EDIT) { + + project.controls.map( + function(control) { + if ( + control instanceof R3.Controls.D3.Orbit || + control instanceof R3.Controls.D3.FirstPerson + ) { + control.instance.update(project.clock.getDelta()); + + control.camera.updateFromInstance('position'); + control.camera.updateFromInstance('quaternion'); + control.camera.updateFromInstance('rotation'); + + if (control.camera instanceof R3.D3.Camera.Perspective.Stereo) { + control.camera.instance.userData.stereo.update(control.camera.instance); + } + } + } + ); + + } else { + /** + * We don't update anything at the moment for normal controls + */ + } + +}; + +/** + * From now on we want to track everything about a component from the systems that are active + * @param data + */ +R3.System.Input.prototype.instanceCreated = function(data) { + + if (data.component instanceof R3.Controls.Touch) { + R3.Utils.PushUnique(this.touchControls, data.component); + this.registerTouchControl(data.component); + } + + if (data.component instanceof R3.Controls.Keyboard) { + R3.Utils.PushUnique(this.keyboardControls, data.component); + this.registerKeyboardControl(data.component); + } + + if (data.component instanceof R3.Controls.Mouse) { + R3.Utils.PushUnique(this.mouseControls, data.component); + this.registerMouseControl(data.component); + } + + if (data.component instanceof R3.Controls.D3.Orbit) { + R3.Utils.PushUnique(this.orbitControls, data.component); + } + + if (data.component instanceof R3.Controls.D3.FirstPerson) { + R3.Utils.PushUnique(this.firstPersonControls, data.component); + } +}; + +/** + * Removes controls from this system + * @param data + */ +R3.System.Input.prototype.removeComponent = function(data) { + + var index; + + if (data.component instanceof R3.Controls.Touch) { + + index = this.touchControls.indexOf(data.component); + + if (index !== -1) { + + this.deRegisterTouchControl(data.component); + + this.touchControls.splice(index, 1); + + } else { + console.log('Failed to remove ' + R3.GetComponentName(data.component) + ' from R3.System.Input'); + } + } + + if (data.component instanceof R3.Controls.Keyboard) { + + index = this.keyboardControls.indexOf(data.component); + + if (index !== -1) { + + this.deRegisterKeyboardControl(data.component); + + this.keyboardControls.splice(index, 1); + + } else { + console.log('Failed to remove ' + R3.GetComponentName(data.component) + ' from R3.System.Input'); + } + } + + if (data.component instanceof R3.Controls.Mouse) { + + index = this.mouseControls.indexOf(data.component); + + if (index !== -1) { + + this.deRegisterMouseControl(data.component); + + this.mouseControls.splice(index, 1); + + } else { + console.log('Failed to remove ' + R3.GetComponentName(data.component) + ' from R3.System.Input'); + } + } + + if (data.component instanceof R3.Controls.D3.FirstPerson) { + + index = this.firstPersonControls.indexOf(data.component); + + if (index !== -1) { + + data.component.instance.dispose(); + + this.firstPersonControls.splice(index, 1); + + } else { + console.log('Failed to remove ' + R3.GetComponentName(data.component) + ' from R3.System.Input'); + } + } + + if (data.component instanceof R3.Controls.D3.Orbit) { + + index = this.orbitControls.indexOf(data.component); + + if (index !== -1) { + + data.component.instance.dispose(); + + this.orbitControls.splice(index, 1); + + } else { + console.log('Failed to remove ' + R3.GetComponentName(data.component) + ' from R3.System.Input'); + } + } + +}; + +R3.System.Input.prototype.registerTouchControl = function(touchControl) { + + if (!touchControl.canvas || !touchControl.canvas.instance) { + console.warn('no canvas at time of registration of touch controls - this part will be skipped'); + return; + } + + touchControl.canvas.instance.addEventListener( + 'touchstart', + this.touchStart, + true + ); + + touchControl.canvas.instance.addEventListener( + 'touchmove', + this.touchMove, + true + ); + touchControl.canvas.instance.addEventListener( + 'touchend', + this.touchEnd, + true + ); + touchControl.canvas.instance.addEventListener( + 'touchcancel', + this.touchCancel, + true + ); +}; + +R3.System.Input.prototype.registerKeyboardControl = function(keyboardControl) { + + if (!keyboardControl.canvas || !keyboardControl.canvas.instance) { + console.warn('no canvas at time of registration of keyboard controls - this part will be skipped'); + return; + } + + keyboardControl.canvas.instance.addEventListener( + 'keyup', + this.keyboardKeyUp, + true + ); + + keyboardControl.canvas.instance.addEventListener( + 'keydown', + this.keyboardKeyDown, + true + ); +}; + +R3.System.Input.prototype.registerMouseControl = function(mouseControl) { + + if (!mouseControl.canvas || !mouseControl.canvas.instance) { + console.warn('no canvas at time of registration of mouse controls - this part will be skipped'); + return; + } + + mouseControl.canvas.instance.addEventListener( + 'mousedown', + this.mouseDown, + false + ); + + mouseControl.canvas.instance.addEventListener( + 'mousemove', + this.mouseMove, + false + ); + + mouseControl.canvas.instance.addEventListener( + 'wheel', + this.mouseWheel, + false + ); + + mouseControl.canvas.instance.addEventListener( + 'mouseup', + this.mouseUp, + false + ); +}; + +R3.System.Input.prototype.deRegisterTouchControl = function(touchControl) { + + touchControl.canvas.instance.removeEventListener( + 'touchstart', + this.touchStart, + true + ); + + touchControl.canvas.instance.removeEventListener( + 'touchmove', + this.touchMove, + true + ); + + touchControl.canvas.instance.removeEventListener( + 'touchend', + this.touchEnd, + true + ); + + touchControl.canvas.instance.removeEventListener( + 'touchcancel', + this.touchCancel, + true + ); + +}; + +R3.System.Input.prototype.deRegisterKeyboardControl = function(keyboardControl) { + + keyboardControl.canvas.instance.removeEventListener( + 'keydown', + this.keyboardKeyDown, + true + ); + + keyboardControl.canvas.instance.removeEventListener( + 'keyup', + this.keyboardKeyUp, + true + ); + +}; + +R3.System.Input.prototype.deRegisterMouseControl = function(mouseControl) { + + mouseControl.canvas.instance.removeEventListener( + 'mousedown', + this.mouseDown, + false + ); + + mouseControl.canvas.instance.removeEventListener( + 'mousemove', + this.mouseMove, + false + ); + + mouseControl.canvas.instance.removeEventListener( + 'wheel', + this.mouseWheel, + false + ); + + mouseControl.canvas.instance.removeEventListener( + 'mouseup', + this.mouseUp, + false + ); + +}; + +R3.System.Input.GetProject = function(canvasInstance) { + + var canvasses = R3.EntityManager.Instance.findComponentsByType(R3.COMPONENT_CANVAS); + + var project = null; + + canvasses.map( + function (canvas) { + if (canvas.instance === canvasInstance) { + project = canvas.getParentProject(); + } + } + ); + + return project; +}; + +R3.System.Input.prototype.onKeyboardKeyUp = function(event) { + + R3.Event.Emit( + R3.Event.KEY_UP, + { + code : event.code || event.key, + keyCode : event.keyCode, + project : R3.System.Input.GetProject(event.target) + } + ); + +}; + +R3.System.Input.prototype.onKeyboardKeyDown = function(event) { + R3.Event.Emit( + R3.Event.KEY_DOWN, + { + code : event.code || event.key, + keyCode : event.keyCode, + project : R3.System.Input.GetProject(event.target) + } + ); + +}; + +R3.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; + + R3.Event.Emit( + R3.Event.TOUCH_START, + { + touches: this.touches, + project : R3.System.Input.GetProject(event.target) + } + ) +}; + +R3.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; + + var totalUp = 0; + var totalDown = 0; + var totalLeft = 0; + var totalRight = 0; + + 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; + + totalLeft += left; + totalRight += right; + totalUp += up; + totalDown += down; + } + } + + 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, + totalLeft : totalLeft, + totalRight : totalRight, + totalUp : totalUp, + totalDown : totalDown, + movementX : totalRight - totalLeft, + movementY : totalDown - totalUp + }; + + // if (this.sensitivityCounter >= this.touchSensitivity) { + // + // this.sensitivityCounter = 0; + + R3.Event.Emit( + R3.Event.TOUCH_MOVE, + { + touches : this.touches, + project : R3.System.Input.GetProject(event.target) + } + + ); + + // } + +}; + +R3.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; + R3.Event.Emit( + R3.Event.TOUCH_CANCEL, + { + touches: this.touches[event.changedTouches[t].identifier], + project: R3.System.Input.GetProject(event.target) + } + ); + delete this.touches[event.changedTouches[t].identifier]; + } +}; + +R3.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; + R3.Event.Emit( + R3.Event.TOUCH_END, + { + touches: this.touches[event.changedTouches[t].identifier], + project: R3.System.Input.GetProject(event.target) + } + ); + delete this.touches[event.changedTouches[t].identifier]; + } +}; + +R3.System.Input.prototype.onKeyDownEdit = function(event) { + + console.log('input system emitted keypress ' + event.code); + + R3.Event.Emit( + R3.Event.KEY_DOWN, + { + code : event.code || event.key, + keyCode : event.keyCode + } + ); + + var meshes = null; + + if (event.keyCode === R3.System.Input.KEY_DELETE) { + + meshes = R3.EntityManager.Instance.findComponentsByConstructor(R3.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) + ); + + R3.Event.Emit( + R3.Event.REMOVE_MESH, + { + meshes : deletedMeshes + } + ); + + } + + if (event.keyCode === R3.System.Input.KEY_CONTROL) { + this.controlLeft = true; + } + + if (event.keyCode === R3.System.Input.KEY_A) { + + this.selectAll = !this.selectAll; + + if (this.selectionMode === R3.System.Input.SELECTION_MODE_MESH) { + + meshes = R3.EntityManager.Instance.findComponentsByConstructor(R3.D3.Mesh); + + meshes.map(function(mesh) { + if (this.selectAll) { + this.selectMesh(mesh); + } else { + this.deselectMesh(mesh); + } + }.bind(this)); + } else { + console.warn('todo: implement face select all'); + } + + R3.Event.Emit( + R3.Event.BUILD_GUI, + null + ) + + } + + if (event.keyCode === R3.System.Input.KEY_P) { + R3.Event.Emit(R3.Event.GAME_PAUSE); + } + + if (event.keyCode === R3.System.Input.KEY_G) { + + this.grabMode = !this.grabMode; + + if (this.grabMode) { + console.log('grab mode active, translating on ' + this.grabModeDirection + ' axis'); + } else { + console.log('grab mode de-activated'); + } + + } +}; + +R3.System.Input.prototype.onKeyUpEdit = function(event) { + + R3.Event.Emit( + R3.Event.KEY_UP, + { + code : event.code || event.key, + keyCode : event.keyCode + } + ); + + if (event.code === 'ControlLeft') { + this.controlLeft = false; + } +}; + +R3.System.Input.prototype.onMouseDown = function(event) { + + R3.Event.Emit( + R3.Event.MOUSE_DOWN, + { + event : event, + project : R3.System.Input.GetProject(event.target) + } + ) +}; + +R3.System.Input.prototype.onMouseMove = function(event) { + + R3.Event.Emit( + R3.Event.MOUSE_MOVE, + { + event : event, + project : R3.System.Input.GetProject(event.target) + } + ) +}; + +R3.System.Input.prototype.onMouseWheel = function(event) { + + R3.Event.Emit( + R3.Event.MOUSE_WHEEL, + { + event : event, + project : R3.System.Input.GetProject(event.target) + } + ) +}; + +R3.System.Input.prototype.onMouseUp = function(event) { + + R3.Event.Emit( + R3.Event.MOUSE_UP, + { + event : event, + project : R3.System.Input.GetProject(event.target) + } + ) +}; + +R3.System.Input.prototype.onMouseDownEdit = function(event) { + + if (event.button === 2) { + + R3.EntityManager.Instance.findComponentsByConstructor(R3.Controls.D3).map( + + function(control) { + + if (this.controlLeft) { + return; + } + + this.mouse.x = (event.offsetX / event.target.width ) * 2 - 1; + this.mouse.y = -(event.offsetY / event.target.height) * 2 + 1; + + R3.Event.Emit( + R3.Event.GET_RENDER_CONFIGURATION, + null, + function(configuration) { + + var scenes = configuration.activeScenes; + + var camera = configuration.activeCamera; + + var intersects = scenes.reduce( + + function(result, scene) { + + this.raycaster.setFromCamera( + this.mouse, + camera + ); + + this.raycaster.getIntersectedObjects(scene.meshes).map( + function(intersect) { + result.push(intersect); + } + ); + + this.raycaster.getIntersectedObjects(scene.clones).map( + function(intersect) { + result.push(intersect); + } + ); + + return result; + }.bind(this), + [] + ); + + if (intersects.length < 1) { + return; + } + + /** + * Find the closest intersected mesh + */ + intersects.sort( + function(a, b) { + if (a.distance < b.distance) { + return -1; + } + + if (a.distance > b.distance) { + return 1; + } + + return 0; + } + ); + + var mesh = intersects[0].mesh; + var face = intersects[0].face; + + /** + * Prevent default action (like context menu or whatever) + */ + event.preventDefault(); + + /** + * Prevent other event listeners for 'mousedown' from executing their actions + */ + event.stopImmediatePropagation(); + + if (this.selectionMode === R3.System.Input.SELECTION_MODE_MESH) { + + if (mesh.selected) { + this.deselectMesh(mesh); + } else { + this.selectMesh(mesh); + } + + } else { + if (face.selected) { + this.deselectFace(mesh, face); + } else { + this.selectFace(mesh, face); + } + } + + /** + * Notify our GUI system to build a GUI + */ + R3.Event.Emit( + R3.Event.BUILD_GUI, + null + ) + }.bind(this) + ); + + }.bind(this) + ); + } +}; + +/** + * + * @param event + */ +R3.System.Input.prototype.onMouseMoveEdit = function(event) { + + R3.EntityManager.Instance.queryComponents(R3.Component.MOUSE).map( + function(mouse) { + mouse.x = event.clientX; + mouse.y = event.clientY; + } + ); + + R3.EntityManager.Instance.findComponentsByConstructor(R3.Controls.D3).map( + function(control) { + + control.camera.position.x = control.camera.instance.position.x; + control.camera.position.y = control.camera.instance.position.y; + control.camera.position.z = control.camera.instance.position.z; + + control.camera.rotation.x = control.camera.instance.rotation.x; + control.camera.rotation.y = control.camera.instance.rotation.y; + control.camera.rotation.z = control.camera.instance.rotation.z; + + control.camera.quaternion.x = control.camera.instance.quaternion.x; + control.camera.quaternion.y = control.camera.instance.quaternion.y; + control.camera.quaternion.z = control.camera.instance.quaternion.z; + control.camera.quaternion.w = control.camera.instance.quaternion.w; + } + ); + +}; + +/** + * Update the camera position etc. after mouse up + * @returns {Function} + * @param event + */ +R3.System.Input.prototype.onMouseUpEdit = function(event) { + +}; + +/** + * Update our camera position after moving the mouse wheel + * @returns {Function} + * @param event + */ +R3.System.Input.prototype.onMouseWheelEdit = function(event) { + + R3.EntityManager.Instance.findComponentsByConstructor(R3.Controls.D3).map( + function(control) { + + control.camera.position.x = control.camera.instance.position.x; + control.camera.position.y = control.camera.instance.position.y; + control.camera.position.z = control.camera.instance.position.z; + } + ); + +}; + +R3.System.Input.prototype.selectFace = function(mesh, face) { + + /** + * If mesh is already selected, do nothing + */ + if (face.selected === true) { + return; + } + + /** + * Notify our component as being 'selected' + * @type {boolean} + */ + face.selected = true; + + face.createHelper(mesh); + + R3.Event.Emit( + R3.Event.MESH_FACE_SELECTED, + { + mesh : mesh, + face : face + } + ); +}; + +R3.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(); + + this.orbitControls.map( + function(controls){ + controls.target = mesh; + controls.updateInstance('target'); + } + ); + + R3.Event.Emit( + R3.Event.MESH_SELECTED, + { + mesh : mesh + } + ); +}; + +R3.System.Input.prototype.deselectFace = function(mesh, face) { + + face.selected = false; + + face.removeHelper(mesh); + + R3.Event.Emit( + R3.Event.MESH_FACE_DESELECTED, + { + mesh : mesh, + face : face + } + ); +}; + +R3.System.Input.prototype.deselectMesh = function(mesh) { + + mesh.selected = false; + + mesh.removeHelper(); + + this.orbitControls.map( + function(controls){ + controls.target = null; + controls.updateInstance('target'); + } + ); + + R3.Event.Emit( + R3.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'); +// } +// } +// }; + +// R3.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(R3.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} +// */ +// R3.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 +// */ +// R3.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 +// */ +// R3.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(); +// } +// } +// } +// }; + diff --git a/src/r3-system-linking.js b/src/r3-system-linking.js new file mode 100644 index 0000000..95b93f2 --- /dev/null +++ b/src/r3-system-linking.js @@ -0,0 +1,983 @@ +/** + * 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 R3.API.System + * @constructor + */ +R3.System.Linking = function( + apiSystem +) { + R3.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; + this.resolveDependenciesSubscription = null; + this.replaceComponentSubscription = null; //render system does this + + /** + * Parents + */ + this.parentSceneChangeSubscription = null; + this.parentPhysicsWorldChangeSubscription = null; + + /** + * Instances + */ + this.instanceCreatedSubscription = null; + this.instanceClonedSubscription = null; + + /** + * Meshes + */ + this.removeMeshSubscription = null; + + /** + * Materials + */ + this.materialTypeChangedSubscription = null; + + /** + * Arrays + */ + this.arrayItemAddedSubscription = null; + +}; + +R3.System.Linking.prototype = Object.create(R3.System.prototype); +R3.System.Linking.prototype.constructor = R3.System.Linking; + +R3.System.Linking.prototype.start = function() { + + R3.System.prototype.start.call(this); + + /** + * Components + */ + this.componentCreatedSubscription = this.subscribe( + R3.Event.COMPONENT_CREATED, + this.componentCreated.bind(this) + ); + + this.componentUpdateSubcription = this.subscribe( + R3.Event.COMPONENT_UPDATE, + this.componentUpdate.bind(this) + ); + + this.componentClonedSubscription = this.subscribe( + R3.Event.COMPONENT_CLONED, + this.componentCloned.bind(this) + ); + + this.registerDependenciesSubscription = this.subscribe( + R3.Event.REGISTER_DEPENDENCIES, + this.registerDependenciesDirect + ); + + this.componentRemoveSubscription = this.subscribe( + R3.Event.REMOVE_COMPONENT, + this.removeComponent + ); + + this.resolveDependenciesSubscription = this.subscribe( + R3.Event.RESOLVE_DEPENDENCIES, + this.resolveDependencies + ); + + this.replaceComponentSubscription = this.subscribe( + R3.Event.REPLACE_COMPONENT, + this.replaceComponent + ); + + /** + * Parents + */ + this.parentSceneChangeSubscription = this.subscribe( + R3.Event.PARENT_SCENE_CHANGE, + this.onParentSceneChange + ); + + this.parentPhysicsWorldChangeSubscription = this.subscribe( + R3.Event.PARENT_WORLD_CHANGE, + this.onParentWorldChange + ); + + /** + * Instances + */ + this.instanceCreatedSubscription = this.subscribe( + R3.Event.INSTANCE_CREATED, + this.instanceCreated + ); + + this.instanceClonedSubscription = this.subscribe( + R3.Event.INSTANCE_CLONED, + this.instanceCloned + ); + + /** + * Meshes + */ + this.removeMeshSubscription = this.subscribe( + R3.Event.REMOVE_MESH, + this.removeMesh + ); + + /** + * Materials + */ + this.materialTypeChangedSubscription = this.subscribe( + R3.Event.MATERIAL_TYPE_CHANGED, + this.materialTypeChanged + ); + + /** + * Arrays + */ + this.arrayItemAddedSubscription = this.subscribe( + R3.Event.ARRAY_ITEM_ADDED, + this.arrayItemAdded + ); + +}; + +R3.System.Linking.prototype.link = function(component, data) { + for (var property in component.linkedComponents) { + if (component.linkedComponents.hasOwnProperty(property)) { + if (component.linkedComponents[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) { + R3.Event.Emit( + R3.Event.COMPONENT_LINKED, + link + ); + }) + + } else { + if (component[property] && + component[property] === data.component.id) { + component[property] = data.component; + + R3.Event.Emit( + R3.Event.COMPONENT_LINKED, + { + parent : component, + property : property, + child : data.component + } + ); + } + } + } + } +}; + +R3.System.Linking.prototype.resolveDependencies = function(data) { + + var component = data.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 (R3.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 + */ + R3.Utils.PushUnique(this.resolved, component); + + /** + * First check if the dependencies have already been met + */ + if ( + R3.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 || + R3.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 + */ + R3.Event.Emit( + R3.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 (R3.Utils.IsEmpty(this.dependencies)) { + + /** + * This also only notifies the Editor - We still have some more work to here + */ + R3.Event.Emit( + R3.Event.COMPONENTS_LINKED, + { + components: this.resolved.map( + function(component) { + return component; + } + ) + } + ); + + this.resolved = []; + + } + +}; + +R3.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 = R3.EntityManager.Instance.findComponentById(id); + + if (processedComponent && processedComponent.loaded) { + + /** + * Link the component + */ + this.link(component, {component: processedComponent}); + + R3.Utils.PushUnique(this.resolved, processedComponent); + + } else { + + /** + * Create a new link if none exists + */ + if (R3.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); + R3.Event.Emit( + R3.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 + */ +R3.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 : component}); + +}; + +/** + * Trigger a component update + * @param data + */ +R3.System.Linking.prototype.componentUpdate = function(data){ + + var component = R3.EntityManager.Instance.findComponentByName(data.name); + + if (R3.Utils.UndefinedOrNull(data.property)) { + console.warn('invalid data format - we expect data.property'); + return; + } + + if (R3.Utils.UndefinedOrNull(data.value)) { + console.warn('invalid data format - we expect data.value'); + return; + } + + if (R3.Utils.UndefinedOrNull(data.subProperty)) { + component[data.property] = data.value; + } else { + component[data.property][data.subProperty] = data.value; + } + + component.updateInstance(data.property); +}; + +R3.System.Linking.prototype.componentCloned = function(data) { + + this.componentCreated(data); + + if (data.component instanceof R3.D3.Mesh) { + + if (!(data.parent instanceof R3.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 + */ +R3.System.Linking.prototype.registerDependenciesDirect = function(data) { + this.registerDependencies(data.component); +}; + +R3.System.Linking.prototype.replaceComponent = function(data) { + + /** + * Link canvases + */ + if ( + data.current instanceof R3.D3.Geometry.Buffer && + data.replacement instanceof R3.D3.Geometry.Buffer + ) { + data.replacement.faces = data.current.faces.map( + function(face) { + return face; + } + ); + + data.replacement.vertices = data.current.vertices.map( + function(vertex) { + return vertex; + } + ); + + data.replacement.updateInstance('faces'); + + /** + * TODO: update both seperately when implemented properly + */ + //data.replacement.updateInstance('vertices'); + + R3.EntityManager.Instance.queryComponents(R3.Component.MESH).map( + function(mesh) { + if (mesh.geometry === data.current) { + mesh.geometry = data.replacement; + mesh.updateInstance('geometry'); + } + } + ) + } + +}; + +R3.System.Linking.prototype.removeComponent = function(data) { + + if (!data.component) { + console.error('no component to remove'); + return; + } + + var component = data.component; + + if (component.parent instanceof R3.Entity) { + component.parent.removeComponent(component); + } + + if (component instanceof R3.D3.Mesh && + component.parentScene instanceof R3.D3.Scene) { + + component.removeHelper(); + + component.parentScene.removeObject(component); + } + + if (component instanceof R3.D3.Light && + component.parentScene instanceof R3.D3.Scene) { + component.parentScene.removeObject(component); + } + + if (component instanceof R3.Entity) { + R3.EntityManager.Instance.removeEntity(component); + } + + // if (component instanceof R3.D3.Particle) { + // // component.mesh.parentScene.removeObject(component.mesh); + // } +}; + +R3.System.Linking.prototype.arrayItemAdded = function(data) { + if ( + data.component instanceof R3.D3.PhysicsWorld && + data.item instanceof R3.D3.RigidBody + ) { + data.component.addRigidBody(data.item); + } + + console.warn('todo: check if this is still necessary to add material to mesh'); + + // if (data.component instanceof R3.D3.Mesh && + // data.item instanceof R3.D3.Material + // ) { + // data.component.updateInstance('materials'); + // } +}; + +R3.System.Linking.prototype.instanceCloned = function(data) { + + // if (data.component instanceof R3.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); + // } + // } + +}; + +R3.System.Linking.prototype.instanceCreated = function(data) { + + /** + * Texture Linking + */ + if (data.component instanceof R3.D3.Texture) { + + /** + * Link Parent Textures to Canvas Objects + */ + R3.EntityManager.Instance.queryComponents(R3.Component.CANVAS).map( + function(canvas){ + if (canvas.parentTexture === data.component.id) { + canvas.parentTexture = data.component; + } + } + ); + + /** + * Find all Render Targets and see if their textures need updating + */ + R3.EntityManager.Instance.queryComponents(R3.Component.RENDER_TARGET).map( + function(renderTarget) { + if (renderTarget.texture === data.component) { + /** + * We found a render target which has this component as their texture - their instance + * has been updated + */ + if (renderTarget.texture.instance !== renderTarget.instance.texture) { + console.log('updating render target texture instance'); + renderTarget.instance.texture = renderTarget.texture.instance; + } + } + } + ) + } + + /** + * Image Linking + */ + if (data.component instanceof R3.Image) { + /** + * Find all textures which use this image + */ + R3.EntityManager.Instance.queryComponents(R3.Component.TEXTURE_IMAGE).map( + function(texture) { + if (texture.instance && texture.image === data.component) { + texture.updateInstance('image'); + } + } + ); + + R3.EntityManager.Instance.queryComponents(R3.Component.TEXTURE_CUBE).map( + function(texture) { + if (texture.instance && texture.images.indexOf(data.component) !== -1) { + texture.updateInstance('images'); + } + } + ); + + } + + /** + * Canvas Linking + */ + if (data.component instanceof R3.Canvas) { + R3.EntityManager.Instance.queryComponents(R3.Component.TEXTURE_CANVAS).map( + function(texture){ + if (data.component.parentTexture === texture.id) { + data.component.parentTexture = texture; + } + } + ) + } + + /** + * Link all scenes + */ + if (data.component instanceof R3.D3.Scene) { + /** + * Check ALL components for 'parentScenes' - this is expensive so it checks the register directly + */ + + Object.keys(R3.EntityManager.Instance.idRegister).map( + function(componentId) { + if (R3.EntityManager.Instance.idRegister[componentId].parentScene === data.component.id) { + R3.EntityManager.Instance.idRegister[componentId].parentScene = data.component; + } + } + ); + } + + if ( + data.component.parentScene && + typeof data.component.parentScene === 'string' + ) { + R3.EntityManager.Instance.queryComponents(R3.Component.SCENE).map( + function(scene) { + if (data.component.parentScene === scene.id) { + data.component.parentScene = scene; + scene.addObject(data.component); + } + } + ); + } + + + /** + * Link all meshes + */ + if (data.component instanceof R3.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(R3.EntityManager.Instance.idRegister).map( + function(componentId) { + if (R3.EntityManager.Instance.idRegister[componentId].parentMesh === data.component.id) { + R3.EntityManager.Instance.idRegister[componentId].parentMesh = data.component; + R3.EntityManager.Instance.idRegister[componentId].updateInstance('parentMesh'); + } + } + ); + + } + + } + + /** + * Maybe this component has a parent mesh + */ + if ( + data.component.parentMesh && + typeof data.component.parentMesh === 'string' + ) { + R3.EntityManager.Instance.queryComponents(R3.Component.MESH).map( + function(mesh) { + if (data.component.parentMesh === mesh.id) { + data.component.parentMesh = mesh; + data.component.updateInstance('parentMesh'); + } + } + ); + } + + if ( + data.component.parentPhysicsWorld && + typeof data.component.parentPhysicsWorld === 'string' + ) { + R3.EntityManager.Instance.queryComponents(R3.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'); + } + } + } + ); + } + + + +}; + +R3.System.Linking.prototype.materialTypeChanged = function(data) { + + var meshes = R3.EntityManager.Instance.queryComponents(R3.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 + */ +R3.System.Linking.prototype.onParentWorldChange = function(data) { + + if ( + data.object instanceof R3.D3.RigidBody + ) { + + if (data.originalWorld instanceof R3.D3.PhysicsWorld) { + data.originalWorld.removeRigidBody(data.object); + } + + if (data.newWorld instanceof R3.D3.PhysicsWorld) { + data.newWorld.addRigidBody(data.object); + } + } + +}; + +/** + * Defines what should happen when a parent scene changes + * @param data + */ +R3.System.Linking.prototype.onParentSceneChange = function(data) { + + if ( + data.object instanceof R3.D3.Mesh || + data.object instanceof R3.D3.Light + ) { + + /** + * We remove the helper (if any) from the old scene and add it to the new scene + */ + var helper = R3.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); + } + } + +}; + +/** + * 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 + */ +R3.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 = R3.EntityManager.Instance.queryComponents(R3.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(); + } + ); +}; + +R3.System.Linking.prototype.stop = function() { + R3.System.prototype.stop.call(this); + /** + * Components + */ + this.componentCreatedSubscription.remove(); + this.componentUpdateSubcription.remove(); + this.componentClonedSubscription.remove(); + this.registerDependenciesSubscription.remove(); + this.componentRemoveSubscription.remove(); + this.resolveDependenciesSubscription.remove(); + this.replaceComponentSubscription.remove(); + + /** + * Parents + */ + this.parentSceneChangeSubscription.remove(); + this.parentPhysicsWorldChangeSubscription.remove(); + + /** + * Instances + */ + this.instanceCreatedSubscription.remove(); + this.instanceClonedSubscription.remove(); + + /** + * Meshes + */ + this.removeMeshSubscription.remove(); + + /** + * Materials + */ + this.materialTypeChangedSubscription.remove(); + + /** + * Arrays + */ + this.arrayItemAddedSubscription.remove(); +}; + diff --git a/src/r3-system-particle.js b/src/r3-system-particle.js new file mode 100644 index 0000000..32cc341 --- /dev/null +++ b/src/r3-system-particle.js @@ -0,0 +1,325 @@ +/** + * System takes care of updating all the entities (based on their component data) + * @param apiSystem R3.API.System + * @constructor + */ +R3.System.Particle = function( + apiSystem +) { + R3.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; +}; + +R3.System.Particle.prototype = Object.create(R3.System.prototype); +R3.System.Particle.prototype.constructor = R3.System.Particle; + +/** + * Start this system (add all event listeners) + */ +R3.System.Particle.prototype.start = function() { + + R3.System.prototype.start.call(this); + + this.particleEngines = R3.EntityManager.Instance.queryComponents(R3.Component.PARTICLE_ENGINE); + + this.instanceCreatedSubscription = R3.Event.Subscribe( + R3.Event.INSTANCE_CREATED, + this.instanceCreated.bind(this) + ); + + this.removeComponentSubscription = R3.Event.Subscribe( + R3.Event.REMOVE_COMPONENT, + this.removeComponent.bind(this) + ); + + this.beforeRenderSubscription = R3.Event.Subscribe( + R3.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 + */ +R3.System.Particle.prototype.instanceCreated = function(data) { + + /** + * If we loaded a ParticleEngine - store a reference to it for later, also link all particles with this as parent + */ + if (data.component instanceof R3.D3.ParticleEngine) { + this.particleEngines.push(data.component); + + /** + * Link parent particle engines of already loaded particles + */ + R3.EntityManager.Instance.queryComponents(R3.Component.PARTICLE).map( + function(particle){ + if (particle.parentParticleEngine === data.component.id) { + particle.parentParticleEngine = data.component; + } + } + ) + } + + /** + * If we load a Particle, check to see if its engine loaded and link it. + */ + if (data.component instanceof R3.D3.Particle) { + R3.EntityManager.Instance.queryComponents(R3.Component.PARTICLE_ENGINE).map( + function(particleEngine) { + if (data.component.parentParticleEngine === particleEngine.id) { + data.component.parentParticleEngine = particleEngine; + } + } + ); + } +}; + +/** + * Removes a particle engine from this system + * @param data + */ +R3.System.Particle.prototype.removeComponent = function(data) { + + if (data.component instanceof R3.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 + */ +R3.System.Particle.prototype.beforeRender = function(data) { + + this.totalTime += data.delta; + + this.particleEngines.map( + function(particleEngine) { + + if ( + R3.Utils.UndefinedOrNull(particleEngine.templateParticle) || + R3.Utils.UndefinedOrNull(particleEngine.templateParticle.mesh) || + R3.Utils.UndefinedOrNull(particleEngine.templateParticle.mesh.parentScene) || + R3.Utils.UndefinedOrNull(particleEngine.templateParticle.mesh.parentScene.instance) || + !particleEngine.enabled + ) { + return; + } + + particleEngine.elapsed += data.delta; + + particleEngine.particles = particleEngine.particles.reduce( + + function(result, particle){ + + var speed = particle.userData.speed; + + if (particle.userData.speedType === R3.D3.API.Particle.SPEED_TYPE_CONSTANT) { + speed = data.delta * particle.userData.speed; + } + + if (particle.userData.speedType === R3.D3.API.Particle.SPEED_TYPE_LINEAR) { + speed = data.delta * particle.userData.speed; + particle.userData.speed += speed; + } + + if (particle.userData.speedType === R3.D3.API.Particle.SPEED_TYPE_EXPONENTIAL) { + speed = Math.pow(particle.userData.speed, 2) * data.delta; + particle.userData.speed += speed; + } + + if (particle.userData.speedType === R3.D3.API.Particle.SPEED_TYPE_LOGARITHMIC) { + speed = Math.log(particle.userData.speed) * data.delta; + particle.userData.speed += speed; + } + + if (particle.userData.speedType === R3.D3.API.Particle.SPEED_TYPE_ONE_OVER_LOG) { + speed = 1 / Math.log(particle.userData.speed) * data.delta; + particle.userData.speed += speed; + } + + if (particle.userData.speedType === R3.D3.API.Particle.SPEED_TYPE_EXP) { + speed = Math.exp(particle.userData.speed) * data.delta; + particle.userData.speed += speed; + } + + if (particle.userData.speedType === R3.D3.API.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 === R3.D3.API.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 === R3.D3.API.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; + } + + if (particleEngine.camera && particleEngine.camera.instance) { + particle.quaternion.copy(particleEngine.camera.instance.quaternion); + } + + if (particleEngine.templateParticle.opacityType === R3.D3.API.Particle.OPACITY_TYPE_FADE_IN_LINEAR) { + if (particle.userData.elapsed > particleEngine.templateParticle.fadeInAfter) { + particle.material.opacity += particleEngine.templateParticle.fadeInFactor; + } + } + + if (particleEngine.templateParticle.opacityType === R3.D3.API.Particle.OPACITY_TYPE_FADE_OUT_LINEAR) { + if (particle.userData.elapsed > particleEngine.templateParticle.fadeOutAfter) { + particle.material.opacity -= particleEngine.templateParticle.fadeOutFactor; + } + } + + if (particleEngine.templateParticle.opacityType === R3.D3.API.Particle.OPACITY_TYPE_FADE_IN_OUT_LINEAR) { + + if (particle.userData.fadeIn) { + if (particle.userData.elapsed > particleEngine.templateParticle.fadeInAfter) { + particle.material.opacity += particleEngine.templateParticle.fadeInFactor; + } + } else { + if (particle.userData.elapsed > particleEngine.templateParticle.fadeOutAfter) { + particle.material.opacity -= particleEngine.templateParticle.fadeOutFactor; + } + } + + if (particle.material.opacity >= 1) { + particle.userData.fadeIn = false; + } + } + + 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) { + R3.Event.Emit( + R3.Event.REMOVE_PARTICLE_ENGINE, + { + component : particleEngine + } + ) + } + + if (particleEngine.fired && particleEngine.particles.length === 0) { + R3.Event.Emit( + R3.Event.ENGINE_FIRED_PARTICLES_ZERO, + { + 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); + } + + particleEngine.fired = true; + } + + } 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) + */ +R3.System.Particle.prototype.stop = function() { + + R3.System.prototype.stop.call(this); + + this.instanceCreatedSubscription.remove(); + this.removeComponentSubscription.remove(); + this.beforeRenderSubscription.remove(); + +}; diff --git a/src/r3-system-physics.js b/src/r3-system-physics.js new file mode 100644 index 0000000..927659c --- /dev/null +++ b/src/r3-system-physics.js @@ -0,0 +1,151 @@ +/** + * System takes care of updating all the entities (based on their component data) + * @param apiSystem R3.API.System + * @constructor + */ +R3.System.Physics = function( + apiSystem +) { + + R3.System.call( + this, + apiSystem + ); + + this.worlds = []; + // this.rigidBodies = []; + // this.wheels = []; + // this.vehicles = []; + + // this.worldSubscription = null; + // this.rigidBodySubscription = null; + this.beforeRenderSubscription = null; + this.afterRenderSubscription = null; + + + + +}; + +R3.System.Physics.prototype = Object.create(R3.System.prototype); +R3.System.Physics.prototype.constructor = R3.System.Physics; + +R3.System.Physics.prototype.start = function() { + + R3.System.prototype.start.call(this); + + this.worlds = R3.EntityManager.Instance.queryComponents(R3.Component.PHYSICS_WORLD); + // this.rigidBodies = R3.EntityManager.Instance.queryComponents(R3.Component.RIGID_BODY); + // this.wheels = R3.EntityManager.Instance.queryComponents(R3.Component.RAYCAST_WHEEL); + // this.vehicles = R3.EntityManager.Instance.queryComponents(R3.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( + R3.Event.BEFORE_RENDER, + this.beforeRender + ); +}; + +/** + * Update script + */ +R3.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) + ); +}; + + +R3.System.Physics.prototype.stop = function() { + + R3.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(); + } + +}; + diff --git a/src/r3-system-query.js b/src/r3-system-query.js new file mode 100644 index 0000000..0bd5c29 --- /dev/null +++ b/src/r3-system-query.js @@ -0,0 +1,163 @@ +/** + * R3.System.Query + * @constructor + */ +R3.System.Query = function() { + + R3.System.call( + this + ); + + this.querySubscription = null; +}; + +R3.System.Query.prototype = Object.create(R3.System.prototype); +R3.System.Query.prototype.constructor = R3.System.Query; + +R3.System.Query.prototype.start = function() { + + this.querySubscription = R3.Event.Subscribe( + R3.Event.INSTANCE_CREATED, + this.query + ); + + this.querySubscription = R3.Event.Subscribe( + R3.Event.QUERY, + this.query + ); + + this.intervalChangeSubscription = R3.Event.Subscribe( + R3.Event.QUERY_INTERVAL_CHANGE, + this.intervalChange.bind(this) + ); + + R3.System.prototype.start.call(this); + +}; + +R3.System.Query.prototype.intervalChange = function(data) { + + var graphs = R3.EntityManager.Instance.findComponentsByConstructor(R3.Graph); + + graphs.map( + function(graph) { + graph.query.start = 'now-' + data.interval; + graph.query.timeInterval = data.timeInterval; + R3.Event.Emit( + R3.Event.QUERY, + { + component : graph.query + } + ) + } + ); + +}; + +/** + * Check for query instances - then run them + * @param component + */ +R3.System.Query.prototype.query = function(data) { + + var query = null; + + if (data.component instanceof R3.Query) { + query = data.component; + } + + if (R3.Utils.UndefinedOrNull(query)) { + return; + } + + R3.Event.Emit( + R3.Event.GET_USER, + null, + function(user) { + R3.Event.Emit( + R3.Event.GET_API_URL, + null, + function(data) { + + var queryText = query.text.slice(0); + + if (R3.Utils.Defined(query.size)) { + queryText = queryText.replace(new RegExp(R3.API.Query.QUERY_SIZE, "g"), query.size); + } + + if (R3.Utils.Defined(query.start)) { + queryText = queryText.replace(new RegExp(R3.API.Query.QUERY_START, "g"), query.start); + } + + if (R3.Utils.Defined(query.end)) { + queryText = queryText.replace(new RegExp(R3.API.Query.QUERY_END, "g"), query.end); + } + + if (R3.Utils.Defined(query.timeZone)) { + queryText = queryText.replace(new RegExp(R3.API.Query.QUERY_TIMEZONE, "g"), query.timeZone); + } + + if (R3.Utils.Defined(query.bucketField)) { + queryText = queryText.replace(new RegExp(R3.API.Query.QUERY_BUCKET_FIELD, "g"), query.bucketField); + } + + if (R3.Utils.Defined(query.loginType)) { + queryText = queryText.replace(new RegExp(R3.API.Query.QUERY_LOGIN_TYPE, "g"), query.loginType); + } + + if (R3.Utils.Defined(query.acknowledged)) { + queryText = queryText.replace(new RegExp(R3.API.Query.QUERY_ACKNOWLEDGED, "g"), query.acknowledged); + } + + if (R3.Utils.Defined(query.timeInterval)) { + queryText = queryText.replace(new RegExp(R3.API.Query.QUERY_TIME_INTERVAL, "g"), query.timeInterval); + } + + if (typeof XMLHttpRequest === 'undefined') { + console.log('Implement server side query here'); + return; + } + + var xhr = new XMLHttpRequest(); + + xhr.open( + query.httpMethod, + data.queryApiUrl + query.path + ); + + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.setRequestHeader("x-api-authorization", data.passwoid); + xhr.setRequestHeader('x-api-user-token', user.apiToken); + + xhr.onload = function (event) { + query.parse(JSON.parse(event.target.responseText)); + R3.Event.Emit( + R3.Event.QUERY_PARSED, + { + query : query + } + ) + }; + + xhr.onerror = function(error) { + console.error('An error occurred during query execution: ', error); + }; + + xhr.send(queryText); + } + ); + } + ); +}; + +R3.System.Query.prototype.stop = function() { + + this.querySubscription.remove(); + + this.intervalChangeSubscription.remove(); + + R3.System.prototype.stop.call(this); + +}; + diff --git a/src/r3-system-render.js b/src/r3-system-render.js new file mode 100644 index 0000000..9c046da --- /dev/null +++ b/src/r3-system-render.js @@ -0,0 +1,966 @@ +/** + * R3.System.Render + * @constructor + */ +R3.System.Render = function() { + + R3.System.call( + this + ); + + /** + * Hold reference to all projects + * @type {Array} + */ + this.projects = []; + + /** + * Hold reference to all statistics + * @type {Array} + */ + // this.statistics = []; + + /** + * This hook stores a reference to the current render frame - so we can break out of the render loop if needed + * @type {null} + */ + this.animationFrameHook = null; + + // this.scenes = []; + // + // this.cameras = []; + + /** + * Subscribe to some important events when this system starts + * @type {null} + */ + this.removeComponentSubscription = null; + + this.replaceComponentSubscription = null; + + this.textureUpdatedSubscription = null; + + this.windowResizeSubscription = null; + + this.instanceCreatedSubscription = null; + + this.queryParsedSubscription = null; + + this.canvasResizeSubscription = null; + +}; + +R3.System.Render.prototype = Object.create(R3.System.prototype); +R3.System.Render.prototype.constructor = R3.System.Render; + +/** + * Start the rendering system + */ +R3.System.Render.prototype.start = function() { + + this.removeComponentSubscription = R3.Event.Subscribe( + R3.Event.REMOVE_COMPONENT, + this.removeComponent.bind(this) + ); + + this.replaceComponentSubscription = R3.Event.Subscribe( + R3.Event.REPLACE_COMPONENT, + this.replaceComponent.bind(this) + ); + + this.textureUpdatedSubscription = R3.Event.Subscribe( + R3.Event.TEXTURE_INSTANCE_UPDATED, + this.textureUpdated.bind(this) + ); + + this.windowResizeSubscription = R3.Event.Subscribe( + R3.Event.WINDOW_RESIZE, + this.windowResize.bind(this) + ); + + this.instanceCreatedSubscription = R3.Event.Subscribe( + R3.Event.INSTANCE_CREATED, + this.instanceCreated.bind(this) + ); + + this.queryParsedSubscription = R3.Event.Subscribe( + R3.Event.QUERY_PARSED, + this.queryParsed.bind(this) + ); + + this.canvasResizeSubscription = R3.Event.Subscribe( + R3.Event.CANVAS_RESIZE, + this.canvasResize.bind(this) + ); + + this.graphs = R3.EntityManager.Instance.findComponentsByConstructor(R3.Graph); + + // this.cameras = R3.EntityManager.Instance.findComponentsByConstructor(R3.D3.Camera); + // + // this.scenes = R3.EntityManager.Instance.findComponentsByConstructor(R3.D3.Scene); + + // this.statistics = R3.EntityManager.Instance.queryComponents(R3.COMPONENT_STATS); + + this.projects = R3.EntityManager.Instance.findComponentsByConstructor(R3.Project); + + R3.System.prototype.start.call(this); + + this.run(); +}; + +R3.System.Render.prototype.run = function() { + + this.animationFrameHook = requestAnimationFrame( this.run.bind(this) ); + + this.render(); +}; + +R3.System.Render.prototype.instanceCreated = function(data) { + + if (data.component instanceof R3.Graph) { + this.graphs.push(data.component); + } + + if (data.component instanceof R3.Project) { + this.projects.push(data.component); + } + // + // if (data.component instanceof R3.D3.Scene) { + // this.scenes.push(data.component); + // } + // + // if (data.component instanceof R3.D3.Camera) { + // this.cameras.push(data.component); + // } + +}; + +R3.System.Render.prototype.queryParsed = function(data) { + + this.graphs.map( + function(graph) { + if (graph.query === data.query) { + + if (graph instanceof R3.Graph.Table) { + + if ( + R3.Utils.UndefinedOrNull(data.query.columns) || + R3.Utils.UndefinedOrNull(data.query.rows) + ) { + console.warn('The parsed query is not formatted to allow it to be used to populate table data'); + return; + } + + graph.columns = data.query.columns; + graph.rows = data.query.rows; + graph.updateInstance('data'); + return; + } + + graph.updateInstance('query'); + } + }.bind(this) + ); + +}; + +R3.System.Render.prototype.canvasResize = function(canvas) { + + /** + * When canvas size changes - all viewports that belong to the renderer which owns the canvas has to + * update their sizes accordingly + */ + this.projects.map( + function(project) { + project.renderers.map( + function(renderer) { + if (renderer.canvas === canvas) { + if (renderer.viewports) { + renderer.viewports.map( + function (viewport) { + viewport.updateInstance('size'); + } + ) + } + } + } + ) + } + ); +}; + +/** + * It is assumed that the canvas size represents the 'window size'. + * The R3.Event.WINDOW_RESIZE event data should contain the canvas size (width + height) in pixels + * @param data + */ +R3.System.Render.prototype.windowResize = function(data) { + + R3.Event.Emit( + R3.Event.BEFORE_WINDOW_RESIZE, + data + ); + + this.graphs.map( + function(graph) { + graph.updateInstance('size'); + }.bind(this) + ); + + /** + * Only resize elements relevant to the current projects + */ + this.projects.map( + function(project) { + project.renderers.map( + function(renderer) { + + /** + * Update renderer size + */ + renderer.instance.setSize(data.width, data.height); + + /** + * TODO: Update render target viewport (if required) + */ + if (renderer.renderTarget) { + console.log('TODO: check if we need to update render targets - imo textures should be left well alone - could be different for viewports') + } + + /** + * Update effects + */ + renderer.effect.setSize(data.width, data.height); + + /** + * Update Composer and passes + */ + renderer.composer.setSize( + data.width, + data.height + ); + + renderer.composer.passes.map( + function(pass) { + pass.setSize( + data.width, + data.height + ) + } + ); + + /** + * Update the renderer canvas size + */ + renderer.canvas.width = data.width; + renderer.canvas.height = data.height; + renderer.canvas.updateInstance('width'); + } + ) + } + ); + + R3.EntityManager.Instance.findComponentsByConstructor(R3.Canvas).map( + function(canvas) { + canvas.updateInstance('autoUpdateSize'); + } + ); + + R3.EntityManager.Instance.findComponentsByConstructor(R3.D3.Camera).map( + function(camera){ + if ( + camera instanceof R3.D3.Camera.Orthographic && + camera.aspectRatioMode !== R3.D3.API.Camera.Orthographic.ASPECT_RATIO_MODE_NONE + ) { + camera.updateInstance('aspect'); + } + + if ( + camera instanceof R3.D3.Camera.Perspective || + camera instanceof R3.D3.Camera.Stereo + ) { + camera.aspect = data.width / data.height; + camera.updateInstance('aspect'); + } + } + ); + + R3.EntityManager.Instance.queryComponents(R3.Component.COMPOSER).map( + function(composer){ + + + } + ); + + R3.Event.Emit( + R3.Event.AFTER_WINDOW_RESIZE, + data + ); + +}; + +R3.System.Render.prototype.textureUpdated = function(data) { + + R3.EntityManager.Instance.findComponentsByConstructor(R3.D3.Material).map( + function(material) { + + material.getTextures().map( + function(object) { + + if (object.texture === data.texture) { + + if (material.loaded) { + material.updateInstance(object.property); + } + + } + + } + ); + } + ); + +}; + +R3.System.Render.prototype.replaceComponent = function(data) { + + if (data.current instanceof R3.D3.Material) { + R3.EntityManager.Instance.findComponentsByConstructor(R3.D3.Mesh).map( + function(mesh) { + + var index = mesh.materials.indexOf(data.current); + + while (index !== -1) { + + mesh.materials[index] = data.replacement; + mesh.updateInstance('materials'); + + index = mesh.materials.indexOf(data.current); + } + } + ); + } + + if (data.current instanceof R3.D3.Light) { + R3.EntityManager.Instance.queryComponents(R3.Component.SCENE).map( + function(scene) { + + var index = scene.lights.indexOf(data.current); + + if (index !== -1) { + scene.lights[index] = data.replacement; + scene.updateInstance('lights'); + } + + } + ); + } + + if (data.current instanceof R3.D3.Pass) { + R3.EntityManager.Instance.queryComponents(R3.Component.COMPOSER).map( + function(composer) { + + var index = composer.passes.indexOf(data.current); + + if (index !== -1) { + + if (data.current.renderToScreen === true) { + data.replacement.renderToScreen = true; + } + + if (data.replacement.loaded) { + composer.passes[index] = data.replacement; + } else { + composer.passes.splice(index, 1); + } + + composer.updateInstance('passes'); + } + + } + ); + } + + // if ( + // data.current instanceof R3.Renderer && + // data.replacement instanceof R3.Renderer + // ) { + // data.replacement.canvas.remove(); + // data.replacement.canvas = data.current.canvas; + // data.current.canvas = null; + // + // if (this.activeRenderConfiguration.activeRenderer === data.current) { + // this.activeRenderConfiguration.activeRenderer = data.replacement; + // } + // + // if (this.activeRenderConfiguration.activeRenderer instanceof R3.Renderer.D2) { + // + // if (this.activeRenderConfiguration.activeCamera) { + // this.activeRenderConfiguration.activeCamera.remove(); + // this.activeRenderConfiguration.activeCamera = null; + // } + // + // this.activeRenderConfiguration.activeScenes.map( + // function(scene) { + // scene.remove(); + // } + // ); + // + // this.activeRenderConfiguration.activeScenes = []; + // } + // + // } +}; + +/** + * Removes a particle engine from this system + * @param data + */ +R3.System.Render.prototype.removeComponent = function(data) { + + var index; + + if (data.component instanceof R3.Project) { + + index = this.projects.indexOf(data.component); + + if (index !== -1) { + + console.log('Removing ' + R3.GetComponentName(data.component) + ' from R3.System.Render'); + + this.projects.splice(index, 1); + + } else { + console.log('Failed to remove ' + R3.GetComponentName(data.component) + ' from R3.System.Render'); + } + } + + + // if (data.component instanceof R3.RenderConfiguration) { + // + // index = this.renderConfigurations.indexOf(data.component); + // + // if (index !== -1) { + // console.log('removing renderer configuration from system'); + // + // this.renderConfigurations.splice(index, 1); + // + // } else { + // console.log('failed to find the render configuration in the system : ' + data.component.name); + // } + // + // if (this.renderConfigurations.length === 0) { + // this.activeRenderConfiguration = null; + // } + // + // if (this.renderConfigurations.length === 1) { + // this.activeRenderConfiguration = this.renderConfigurations[0]; + // } + // } + + // if (data.component instanceof R3.Renderer) { + // + // 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); + // } + // } + // + // if (data.component instanceof R3.D3.Composer) { + // + // index = this.composers.indexOf(data.component); + // + // if (index !== -1) { + // console.log('removing composer from system'); + // + // this.composers.splice(index, 1); + // + // } else { + // console.log('failed to find the composer in the system : ' + data.component.name); + // } + // } + + // if (data.component instanceof R3.Stats) { + // + // index = this.statistics.indexOf(data.component); + // + // if (index !== -1) { + // console.log('removing statistics from system'); + // + // this.statistics.splice(index, 1); + // + // } else { + // console.log('failed to find the statistics in the system : ' + data.component.name); + // } + // } + // + // if (data.component instanceof R3.D3.Camera.Cube) { + // + // index = this.cubeCameras.indexOf(data.component); + // + // if (index !== -1) { + // console.log('removing cube camera from system'); + // + // this.cubeCameras.splice(index, 1); + // + // } else { + // console.log('failed to find the cube camera in the system : ' + data.component.name); + // } + // } + + // if (data.component instanceof R3.AR) { + // + // index = this.arComponents.indexOf(data.component); + // + // if (index !== -1) { + // console.log('removing ar component from render system'); + // + // this.arComponents.splice(index, 1); + // + // } else { + // console.log('failed to find the ar component in the render system : ' + data.component.name); + // } + // } + + // if (data.component instanceof R3.D3.Mesh) { + // index = this.excludedFromEnvironment.indexOf(data.component); + // if (index !== -1) { + // console.log('removing excluded environment mesh from system'); + // this.excludedFromEnvironment.splice(index, 1); + // } + // } +}; + +/** + * Render subscription script + */ +R3.System.Render.prototype.render = function() { + + // this.statistics.map( + // function(statistics) { + // statistics.start(); + // } + // ); + + this.projects.map( + function(project) { + + R3.Event.Emit( + R3.Event.BEFORE_RENDER, + project + ); + + project.renderers.map( + + function(renderer) { + + if (!renderer.instance) { + console.warn('renderer not ready'); + return; + } + + if (renderer instanceof R3.Renderer.D2) { + renderer.instance.render(); + return; + } + + var size = renderer.getSize(); + + var scenes = renderer.scenes; + + /** + * Render all scenes which do not belong to a viewport + */ + scenes.map( + function(scene) { + if (scene.viewport === null) { + + var camera = null; + + if (project.applicationMode === R3.API.Project.APPLICATION_MODE_EDIT) { + camera = project.cameras[scene.cameraIndexEdit]; + } else { + camera = project.cameras[scene.cameraIndexRun]; + } + + if (!scene.instance) { + console.warn('scene not ready'); + return; + } + + if (!camera || !camera.instance) { + console.warn('scene not ready'); + return; + } + + renderer.instance.render( + scene.instance, + camera.instance + ) + } + } + ); + + var resetAutoClear = false; + + if (renderer.viewports.length > 1) { + + if (renderer.autoClear) { + resetAutoClear = true; + renderer.clear(); + } + + renderer.autoClear = false; + renderer.updateInstance('autoClear'); + + + } else { + + if (renderer.autoClear) { + renderer.clear(); + } + + } + + renderer.viewports.map( + + function (viewport) { + + if (!viewport.instance) { + console.warn('viewport not ready'); + return; + } + + var actualSize = { + width : viewport.width * size.width, + height : viewport.height * size.height + }; + + renderer.instance.setViewport( + viewport.x * size.width, + viewport.y * size.height, + actualSize.width, + actualSize.height + ); + + scenes.map( + + function (scene) { + + /** + * Ignore scenes which are not assigned to this viewport + */ + if (scene.viewports.indexOf(viewport) !== -1) { + return; + } + + /** + * Ignore scenes which are not ready + */ + if (!scene.instance) { + console.warn('scene not ready'); + return; + } + + + /** + * Render textures first + */ + // scene.cubeCameras.map( + // + // function(cubeCamera) { + // + // if (!cubeCamera.instance) { + // console.warn('cube camera not ready'); + // return; + // } + // + // /** + // * TODO: optimize this to add / remove meshes via Events to prevent looping through + // * TODO: all of them to inspect their excludeFromEnvironmentMapMap settings + // * @type {T | Array} + // */ + // var meshesExcluded = scene.meshes.reduce( + // function(result, mesh){ + // if (mesh.excludeFromEnvironmentMapMap) { + // result.push(mesh) + // } + // return result; + // }, + // [] + // ); + // + // meshesExcluded.map( + // function(mesh){ + // mesh.visible = false; + // mesh.updateInstance('visible'); + // } + // ); + // + // cubeCamera.instance.update( + // renderer.instance, + // scene.instance + // ); + // + // meshesExcluded.map( + // function(mesh){ + // mesh.visible = true; + // mesh.updateInstance('visible'); + // } + // ); + // + // }.bind(this) + // + // ); + + var camera = null; + + if (project.applicationMode === R3.API.Project.APPLICATION_MODE_EDIT) { + camera = project.cameras[scene.cameraIndexEdit]; + } else { + camera = project.cameras[scene.cameraIndexRun]; + } + + if (!camera || !camera.instance) { + console.warn('camera not ready'); + return; + } + + var cameraInstance = camera.instance; + + if (camera instanceof R3.D3.Camera.Perspective.Stereo) { + + if (!viewport instanceof R3.D3.Viewport.FixedAspect.VR) { + console.warn('stereo cameras should work with VR viewports'); + } else { + + if (viewport.side === R3.D3.API.Viewport.FixedAspect.VR.VIEWPORT_LEFT) { + cameraInstance = camera.instance.userData.stereo.cameraL; + } else { + cameraInstance = camera.instance.userData.stereo.cameraR; + } + + if (camera.autoAspect) { + + /** + * Avoid unneccessary aspect ratio updates if LR viewports are the same + * size + */ + if (camera.aspectRatio !== viewport.aspectRatio) { + camera.aspectRatio = viewport.aspectRatio; + camera.updateInstance('aspectRatio'); + camera.instance.userData.stereo.update(camera.instance); + } + + } + + } + + } else { + /** + * If the autoAspect of the camera is set - update the aspect ratio of the camera + * to the aspect ratio of the viewport + */ + if (camera.autoAspect) { + if (camera.aspectRatio !== viewport.aspectRatio) { + camera.aspectRatio = viewport.aspectRatio; + camera.updateInstance('aspectRatio'); + } + } + } + + // if (scene.enableEffect) { + // + // if (!scene.effect) { + // console.warn('enabling an effect when no effect is specified on the scene has no effect'); + // return; + // } + // + // if (scene.enableComposer) { + // console.warn('only an effect or composer can be active at any given time'); + // return; + // } + // + // if (!scene.effect.ready()) { + // console.warn('the effect is not ready yet: ' + scene.effect.name); + // } + // + // if (renderer.target) { + // console.warn('todo: test if rendering effect to target works'); + // + // if (!scene.effect.instance) { + // return; + // } + // + // scene.effect.instance.render( + // scene.instance, + // camera.instance, + // renderer.target.instance + // ); + // } + // + // if (!scene.effect.instance) { + // return; + // } + // + // scene.effect.instance.render( + // scene.instance, + // camera.instance + // ); + // + // console.warn('todo: check if have to return from effect render here'); + // //return; + // + // } + + if (renderer.enableComposer) { + + if (!project.composer) { + console.warn('enabling a composer when no composer is specified has no effect'); + return; + } + + if (!project.composer.ready()) { + console.warn('the composer is not ready yet: ' + project.composer.name); + } + + // renderer.instance.setSize( + // actualSize.width, + // actualSize.height + // ) + // + // project.composer.instance.setSize( + // actualSize.width, + // actualSize.height + // ) + + project.composer.size.x = actualSize.width; + project.composer.size.y = actualSize.height; + + project.composer.updateInstance('size'); + + project.composer.passes.map( + function(pass) { + if (pass instanceof R3.D3.Pass.Render) { + pass.instance.camera = cameraInstance; + } + + if (pass instanceof R3.D3.Pass.FXAA) { + pass.width = actualSize.width; + pass.height = actualSize.height; + pass.updateInstance('size'); + } + + if (pass instanceof R3.D3.Pass.Bloom) { + pass.size.x = actualSize.width; + pass.size.y = actualSize.height; + pass.updateInstance('size'); + } + } + ); + + project.composer.render(); + + return; + } + + if (renderer.target) { + + if (!renderer.target.instance) { + console.warn('render target instance not ready'); + } + + renderer.instance.render( + scene.instance, + cameraInstance, + renderer.target.instance + ) + } + + // camera.instance.updateProjectionMatrix(); + + renderer.instance.render( + scene.instance, + cameraInstance + ); + + /** + * end of scene + */ + }.bind(this) + + ); + + /** + * end of viewport + */ + }.bind(this) + ); + + /** + * Restore the autoClear for the next render loop + */ + if (resetAutoClear) { + renderer.autoClear = true; + renderer.updateInstance('autoClear'); + } + + /** + * end of renderer + */ + }.bind(this) + + ); + + R3.Event.Emit( + R3.Event.AFTER_RENDER, + project + ); + + }.bind(this) + ); + + // this.statistics.map( + // function(statistics) { + // statistics.end(); + // } + // ); +}; + +/** + * Stop the rendering system + */ +R3.System.Render.prototype.stop = function() { + + cancelAnimationFrame(this.animationFrameHook); + + this.removeComponentSubscription.remove(); + + this.replaceComponentSubscription.remove(); + + this.textureUpdatedSubscription.remove(); + + this.windowResizeSubscription.remove(); + + this.instanceCreatedSubscription.remove(); + + this.queryParsedSubscription.remove(); + + this.canvasResizeSubscription.remove(); + + this.graphs = []; + + // this.renderers = []; + // + // this.statistics = []; + + R3.System.prototype.stop.call(this); + +}; + diff --git a/src/r3-system-socket.js b/src/r3-system-socket.js new file mode 100644 index 0000000..1381cc9 --- /dev/null +++ b/src/r3-system-socket.js @@ -0,0 +1,176 @@ +/** + * System takes care of updating all the entities (based on their component data) + * @param apiSystem R3.API.System + * @constructor + */ +R3.System.Socket = function( + apiSystem +) { + R3.System.call( + this, + apiSystem + ); + + this.totalTime = 0; + + this.castComponents = []; + + this.receiveComponents = []; + + this.servers = []; + + this.instanceCreatedSubscription = null; + + this.removeComponentSubscription = null; + + this.beforeRenderSubscription = null; +}; + +R3.System.Socket.prototype = Object.create(R3.System.prototype); +R3.System.Socket.prototype.constructor = R3.System.Socket; + +/** + * Start this system (add all event listeners) + */ +R3.System.Socket.prototype.start = function() { + + R3.System.prototype.start.call(this); + + this.castComponents = R3.EntityManager.Instance.queryComponents(R3.Component.SOCKET_CAST); + this.receiveComponents = R3.EntityManager.Instance.queryComponents(R3.Component.SOCKET_RECEIVE); + this.servers = R3.EntityManager.Instance.queryComponents(R3.Component.SERVER); + + this.instanceCreatedSubscription = R3.Event.Subscribe( + R3.Event.INSTANCE_CREATED, + this.instanceCreated.bind(this) + ); + + this.removeComponentSubscription = R3.Event.Subscribe( + R3.Event.REMOVE_COMPONENT, + this.removeComponent.bind(this) + ); + + this.beforeRenderSubscription = R3.Event.Subscribe( + R3.Event.BEFORE_RENDER, + this.beforeRender.bind(this) + ); + +}; + +/** + * Connect to the socket server + * @param socketComponent + */ +R3.System.Socket.prototype.connect = function(socketComponent) { + console.log(socketComponent.name + ' is connecting to the server ' + socketComponent.serverIp); +}; + +/** + * Disconnect from the socket server + * @param socketComponent + */ +R3.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 + */ +R3.System.Socket.prototype.instanceCreated = function(data) { + + if (data.component instanceof R3.Socket.Cast) { + R3.Utils.PushUnique(this.castComponents, data.component); + } + + if (data.component instanceof R3.Socket.Receive) { + R3.Utils.PushUnique(this.receiveComponents, data.component); + } + + if (data.component instanceof R3.Server) { + R3.Utils.PushUnique(this.servers, data.component); + } +}; + +/** + * Removes a cast or receive component from this system + * @param data + */ +R3.System.Socket.prototype.removeComponent = function(data) { + + var index; + + if (data.component instanceof R3.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 R3.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 R3.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 + */ +R3.System.Socket.prototype.beforeRender = function(data) { + + this.totalTime += data.delta; + +}; + + +/** + * Stop this system (remove all event listeners) + */ +R3.System.Socket.prototype.stop = function() { + + R3.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'); + } + +}; diff --git a/src/r3-system-storage.js b/src/r3-system-storage.js new file mode 100644 index 0000000..c66d478 --- /dev/null +++ b/src/r3-system-storage.js @@ -0,0 +1,1339 @@ +/** + * R3.System.Storage + * @constructor + */ +R3.System.Storage = function() { + + R3.System.call( + this + ); + + this.loaded = []; + this.loading = []; + this.failed = []; + this.apiUserToken = 'none'; + + this.loadSubscription = null; + this.signInSubscription = null; + this.signOutSubscription = null; + this.saveSubscription = null; + this.getProjectsSubscription = null; + + this.savedSubscription = null; + this.savedErrorSubscription = null; + + // this.otherDependencies = []; + + // this.loadImageSubscription = null; + // this.blenderDataSubscription = null; + // this.imageUploadCompleteSubscription = null; + // + // this.fetchComponentTypesSubscription = null; + // this.fetchComponentsSubscription = null; +}; + +R3.System.Storage.prototype = Object.create(R3.System.prototype); +R3.System.Storage.prototype.constructor = R3.System.Storage; + +R3.System.Storage.prototype.start = function() { + + this.signInSubscription = R3.Event.Subscribe( + R3.Event.SIGN_IN, + this.signIn.bind(this) + ); + + this.signOutSubscription = R3.Event.Subscribe( + R3.Event.SIGN_OUT, + this.signOut.bind(this) + ); + + this.loadSubscription = R3.Event.Subscribe( + R3.Event.LOAD_COMPONENT, + this.load.bind(this) + ); + + this.saveSubscription = R3.Event.Subscribe( + R3.Event.SAVE_COMPONENT, + this.save.bind(this) + ); + + this.getProjectsSubscription = R3.Event.Subscribe( + R3.Event.GET_PROJECTS, + this.getProjects.bind(this) + ); + + // + // this.loadSubscription = this.subscribe( + // R3.Event.LOAD_COMPONENT, + // this.load + // ); + // + // this.deleteSubscription = this.subscribe( + // R3.Event.DELETE_COMPONENT, + // this.delete + // ); + // + // this.loadImageSubscription = this.subscribe( + // R3.Event.LOAD_IMAGE, + // this.loadImage + // ); + // + // this.loadFontSubscription = this.subscribe( + // R3.Event.LOAD_FONT, + // this.loadFont + // ); + // + // this.blenderDataSubscription = this.subscribe( + // R3.Event.BLENDER_DATA_RECEIVED, + // this.processBlenderData + // ); + // + // this.imageUploadCompleteSubscription = this.subscribe( + // R3.Event.IMAGE_UPLOAD_COMPLETE, + // this.imageUploadComplete + // ); + // + // this.fetchComponentTypesSubscription = this.subscribe( + // R3.Event.FETCH_COMPONENT_TYPES, + // this.fetchComponentTypes + // ); + // + // this.fetchComponentsSubscription = this.subscribe( + // R3.Event.FETCH_COMPONENTS, + // this.fetchComponents + // ); + + R3.System.prototype.start.call(this); + +}; + +R3.System.Storage.prototype.signIn = function(data, callback) { + + var id_token = data.user.getAuthResponse().id_token; + + var profile = data.user.getBasicProfile(); + + var apiUrl = null; + var apiAuthorization = null; + + R3.Event.Emit( + R3.Event.GET_API_URL, + null, + function(data) { + apiUrl = data.apiUrl; + apiAuthorization = data.apiAuthorization + } + ); + + /** + * Now send the token to our API + */ + var xhr = new XMLHttpRequest(); + xhr.open('POST', apiUrl + '/user/signIn'); + + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.setRequestHeader("x-api-authorization", apiAuthorization); + xhr.setRequestHeader('x-api-user-token', this.apiUserToken); + + xhr.onload = function() { + + var response = JSON.parse(xhr.responseText); + + if (xhr.status === 200) { + this.apiUserToken = response.api_user_token; + } + + callback(response); + }.bind(this); + xhr.send(JSON.stringify( + { + id : profile.getId(), + id_token : id_token, + full_name : profile.getName(), + given_name : profile.getGivenName(), + family_name : profile.getFamilyName(), + image_url : profile.getImageUrl(), + email : profile.getEmail() + } + )); +}; + +R3.System.Storage.prototype.signOut = function(data, callback) { + + var apiUrl = null; + var apiAuthorization = null; + + R3.Event.Emit( + R3.Event.GET_API_URL, + null, + function(data) { + apiUrl = data.apiUrl; + apiAuthorization = data.apiAuthorization + } + ); + + /** + * Now send the token to our API + */ + var xhr = new XMLHttpRequest(); + xhr.open('POST', apiUrl + '/user/signOut'); + + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.setRequestHeader("x-api-authorization", apiAuthorization); + xhr.setRequestHeader('x-api-user-token', this.apiUserToken); + + xhr.onload = function() { + + var response = JSON.parse(xhr.responseText); + + if (xhr.status === 200) { + this.apiUserToken = null; + } + + callback(response); + }.bind(this); + xhr.send(); +}; + + +R3.System.Storage.prototype.delete = function(data) { + + this.emit( + R3.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) { + R3.Event.Emit( + R3.Event.DELETE_COMPONENT_ERROR, + { + message: this.responseText + } + ) + } + + if (response.result === 'success') { + R3.Event.Emit( + R3.Event.COMPONENT_DELETED, + { + message: response.message || 'Successfully saved the component' + } + ) + } else { + R3.Event.Emit( + R3.Event.DELETE_COMPONENT_ERROR, + { + message: response.message || 'The server responded but failed to save the component' + } + ) + } + } + }; + + xhr.send(JSON.stringify({ + session : this.token, + includeDependencies : data.includeDependencies + })); + + }.bind(this)); + }.bind(this), + function(error) { + console.error(error.message); + throw new Error(error.message); + } + ); + + +}; + +/** + * Gets a list of projects + * @param data + * @param callback + * @param errorCallback + */ +R3.System.Storage.prototype.getProjects = function(data, callback, errorCallback) { + + if (typeof XMLHttpRequest === 'undefined') { + console.log('Implement server side save here'); + return; + } + + var apiUrl = null; + var apiAuthorization = null; + + var event = R3.Event.GET_API_URL; + + if (data.remote) { + event = R3.Event.GET_REMOTE_API_URL + } + + R3.Event.Emit( + event, + null, + function(urlData) { + apiUrl = urlData.apiUrl; + apiAuthorization = urlData.apiAuthorization; + } + ); + + var xhr = new XMLHttpRequest(); + + xhr.open( + 'GET', + apiUrl + '/project/list' + ); + + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.setRequestHeader("x-api-authorization", apiAuthorization); + xhr.setRequestHeader('x-api-user-token', this.apiUserToken); + + xhr.onload = function () { + + var response = JSON.parse(xhr.responseText); + + if (response.result === 'success') { + + callback(response); + + } else { + + errorCallback(response); + + } + + }; + + xhr.send(); + +}; + +/** + * 'Saves' data to somewhere + */ +R3.System.Storage.prototype.save = function(data, callback, errorCallback) { + + var toSave = []; + var saved = []; + var failed = []; + + if (typeof XMLHttpRequest === 'undefined') { + console.log('Implement server side save here'); + return; + } + + R3.Event.Emit( + R3.Event.SAVING, + { + component: this + } + ); + + this.savedSubscription = R3.Event.Subscribe( + R3.Event.COMPONENT_SAVED, + function(data) { + + saved.push(data.component); + + if (failed.length + saved.length === toSave.length) { + + this.savedSubscription.remove(); + + this.savedSubscription = null; + + this.savedErrorSubscription.remove(); + + this.savedErrorSubscription = null; + + R3.Event.Emit( + R3.Event.DONE_SAVING, + { + failed: failed, + saved: saved + } + ); + + if (callback) { + callback(data); + } + } + + }.bind(this) + ); + + this.savedErrorSubscription = R3.Event.Subscribe( + R3.Event.SAVE_COMPONENT_ERROR, + function(data) { + + failed.push(data.component); + + if (errorCallback) { + errorCallback(data); + } + + if (failed.length + saved.length === toSave.length) { + + this.savedSubscription.remove(); + + this.savedSubscription = null; + + this.savedErrorSubscription.remove(); + + this.savedErrorSubscription = null; + + R3.Event.Emit( + R3.Event.DONE_SAVING, + { + failed: failed, + saved: saved + } + ) + } + + }.bind(this) + ); + + var apiUrl = null; + var apiAuthorization = null; + + var event = R3.Event.GET_API_URL; + + if (data.remote) { + event = R3.Event.GET_REMOTE_API_URL + } + + R3.Event.Emit( + event, + null, + function(urlData) { + apiUrl = urlData.apiUrl; + apiAuthorization = urlData.apiAuthorization; + } + ); + + try { + + var apiObjects = Object.keys(data.component.idToObject).reduce( + + function (result, componentId) { + + var component = R3.EntityManager.Instance.findComponentById(componentId); + + var apiObject = component.toApiObject(); + + result.push(apiObject); + + return result; + + }.bind(this), + [] + ); + + } catch (error) { + + this.savedSubscription.remove(); + this.savedErrorSubscription.remove(); + + this.savedSubscription = null; + this.savedErrorSubscription = null; + + throw new Error('An error occurred during save:' + error.message); + + } + + try { + + if (data.bulk) { + + var xhr = new XMLHttpRequest(); + + xhr.open( + 'POST', + apiUrl + '/component/save' + ); + + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.setRequestHeader("x-api-authorization", apiAuthorization); + xhr.setRequestHeader('x-api-user-token', this.apiUserToken); + + xhr.onload = function () { + + var response = JSON.parse(xhr.responseText); + + if (response.result === 'success') { + + R3.Event.Emit( + R3.Event.COMPONENT_SAVED, + { + message: response.message || 'Successfully saved the component(s)', + component: apiObjects + } + ); + + } else { + + R3.Event.Emit( + R3.Event.SAVE_COMPONENT_ERROR, + { + message: response.message || 'The server responded but failed to save the component(s)', + component: apiObjects + } + ) + + } + + }; + + var data = JSON.stringify({components: apiObjects}); + + xhr.send(data); + + } else { + apiObjects.map( + function (apiObject) { + + var xhr = new XMLHttpRequest(); + + xhr.open( + 'POST', + apiUrl + '/component/save' + ); + + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.setRequestHeader("x-api-authorization", apiAuthorization); + xhr.setRequestHeader('x-api-user-token', this.apiUserToken); + + xhr.onload = function () { + + var response = JSON.parse(xhr.responseText); + + if (response.result === 'success') { + + R3.Event.Emit( + R3.Event.COMPONENT_SAVED, + { + message: response.message || 'Successfully saved the component', + component: apiObject + } + ); + + } else { + + R3.Event.Emit( + R3.Event.SAVE_COMPONENT_ERROR, + { + message: response.message || 'The server responded but failed to save the component', + component: apiObject + } + ) + + } + + }; + + var data = JSON.stringify({component: apiObject}); + + xhr.send(data); + + }.bind(this) + ); + } + + } catch (error) { + + R3.Event.Emit( + R3.Event.SAVE_COMPONENT_ERROR, + { + message: this.responseText, + component : apiObjects + } + ); + + this.savedSubscription.remove(); + this.savedErrorSubscription.remove(); + + this.savedSubscription = null; + this.savedErrorSubscription = null; + + + } + +}; + +R3.System.Storage.prototype.createRuntimeObject = function(responseText, clientErrorCallback) { + + try { + var object = JSON.parse(responseText); + } catch (errorObject) { + + if (clientErrorCallback) { + clientErrorCallback({ + message : errorObject.message || 'JSON parse error' + }) + } + + R3.Event.Emit( + R3.Event.LOAD_COMPONENT_ERROR, + {error: errorObject} + ); + + return null; + } + + if (object.result !== 'success') { + + if (clientErrorCallback) { + clientErrorCallback({ + message : object.message || 'Server load error' + }) + } + + R3.Event.Emit( + R3.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 = R3.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; +}; + +/** + * Loads a component and its dependencies if specified + * @param urlData + * @param componentData + * @param clientCallback + * @param clientErrorCallback + */ +R3.System.Storage.prototype.loadComponent = function( + urlData, + componentData, + clientCallback, + clientErrorCallback +) { + + /** + * TODO: ensure parents of this component are loaded first + */ + + /** + * 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' + */ + componentData.ids.map( + + function(id) { + + R3.Utils.PushUnique(this.loading, id); + + var component = R3.EntityManager.Instance.findComponentById(id); + + if (component) { + component.remove(); + } + + }.bind(this) + + ); + + componentData.ids.map( + + function(id) { + + var xhr = new XMLHttpRequest(); + + xhr.open( + 'GET', + urlData.apiUrl + '/component/load/' + id + ); + + xhr.setRequestHeader("Accept", "application/json"); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.setRequestHeader("x-api-authorization", urlData.apiAuthorization); + xhr.setRequestHeader('x-api-user-token', urlData.apiUserToken); + + xhr.onload = function(__system) { + + return function() { + + var runtimeComponent = __system.createRuntimeObject.bind(__system)(this.responseText); + + if (!runtimeComponent) { + __system.failed.push(id); + return; + } + + if ( + runtimeComponent.parent && + typeof runtimeComponent.parent === 'string' + ) { + R3.EntityManager.Instance.queryComponents(R3.Component.ENTITY).map( + function(entity) { + if (runtimeComponent.parent === entity.id) { + runtimeComponent.parent = entity; + } + } + ); + } + + R3.Event.Emit( + R3.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) { + R3.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 (R3.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) { + R3.Utils.PushUnique(__system.loading, dependency); + } + ); + + __system.loadComponent(apiUrl, dependencies, includeDependencies, clientCallback, clientErrorCallback); + + } + + // R3.Event.Emit( + // R3.Event.COMPONENT_DOWNLOAD_COMPLETE, + // { + // loaded: __system.loaded + // } + // ); + + R3.Event.Emit( + R3.Event.LOAD_PROGRESS, + { + loading : __system.loading.length, + loaded : __system.loaded.length + } + ); + + if (__system.loading.length === __system.loaded.length) { + + if (clientCallback) { + clientCallback({ + components : __system.loaded + }) + } + + __system.otherDependencies = []; + __system.loaded = []; + } + + + + } + + }(this); + + xhr.onerror = function(__id) { + return function(error) { + console.warn('component load failed for component ID ' + __id); + + if (clientErrorCallback) { + clientErrorCallback(error || {message:'xhr failure'}) + } + }.bind(this); + }(id); + + xhr.send(); + + }.bind(this) + + ); + + +}; + +/** + * 'Loads' data from a url + */ +R3.System.Storage.prototype.load = function(componentData, clientCallback, clientErrorCallback) { + + + if (typeof XMLHttpRequest === 'undefined') { + throw new Error('Implement server side save here'); + } + + if (R3.Utils.UndefinedOrNull(componentData.ids) || componentData.ids.length < 1) { + throw new Error('No components defined for loading'); + } + + var event = R3.Event.GET_API_URL; + + if (componentData.remote) { + event = R3.Event.GET_REMOTE_API_URL + } + + R3.Event.Emit( + event, + null, + function(urlData) { + this.loadComponent( + urlData, + componentData, + clientCallback, + clientErrorCallback + ); + }.bind(this), + console.error + ) + +}; + +R3.System.Storage.prototype.xhrLoad = function( + url, + callback, + errorCallback +) { + + if (typeof XMLHttpRequest === 'undefined') { + console.log('Implement server side load here'); + return; + } + + console.log('Loading from ' + url); + + 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 + */ +R3.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 + */ +R3.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 + */ +R3.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 = R3.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 + */ + R3.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 + */ +R3.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 = R3.Component.ConstructFromObject(rawImageObject); + R3.Event.Emit( + R3.Event.COMPONENT_CREATED, + { + component: image + } + ); + }.bind(this) + ); + + /** + * Process all textures + */ + data.textures.map(function(rawTextureObject){ + var texture = R3.Component.ConstructFromObject(rawTextureObject); + R3.Event.Emit( + R3.Event.COMPONENT_CREATED, + { + component: texture + } + ); + }.bind(this)); + + /** + * Process all materials + */ + data.materials.map(function(rawMaterialObject){ + var material = R3.Component.ConstructFromObject(rawMaterialObject); + R3.Event.Emit( + R3.Event.COMPONENT_CREATED, + { + component: material + } + ); + }.bind(this)); + + /** + * Now process all meshes + */ + data.meshes.map(function(rawMeshObject){ + var mesh = R3.Component.ConstructFromObject(rawMeshObject); + R3.Event.Emit( + R3.Event.COMPONENT_CREATED, + { + component: mesh + } + ); + }.bind(this)); + + /** + * And that should be it... + */ +}; + +R3.System.Storage.prototype.loadFont = function(data, callback, errorCallback) { + + console.log('loading font : ' + data.font.name); + + this.emit( + R3.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 (R3.Utils.IsEmpty(font.data)) { + + errorCallback({message:'font is empty'}); + + } else { + + callback(font); + + } + } + ); + + }.bind(this), + function(error) { + errorCallback(error); + } + ); + + +}; + +R3.System.Storage.prototype.loadImage = function(data, callback, errorCallback) { + + console.log('loading image : ' + data.image.name); + + this.emit( + R3.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() { + + window.URL = window.URL || window.webkitURL; + + // + // console.log(image.name + ' - response type : ' + this.response.type); + + var url; + + if (this.response.type.indexOf('application/json') !== -1) { + + var base64 = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gIPDBcYqg62uwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAaSURBVCjPY/z//z8DKYCJgUQwqmFUw9DRAABVbQMdny4VogAAAABJRU5ErkJggg=='; + + function fixBinary (bin) { + var length = bin.length; + var buf = new ArrayBuffer(length); + var arr = new Uint8Array(buf); + for (var i = 0; i < length; i++) { + arr[i] = bin.charCodeAt(i); + } + return buf; + } + + var binary = fixBinary(atob(base64)); + var blob = new Blob([binary], {type: 'image/png'}); + try { + url = window.URL.createObjectURL(blob); + } + catch (error) { + if (errorCallback) { + errorCallback({ + result: 'failure', + message: 'invalid server response trying to download image ' + data.image.name + }); + } + } + console.log('creating url : ' + url); + + + } else { + try { + url = window.URL.createObjectURL(this.response); + } catch (error) { + if (errorCallback) { + errorCallback({ + result: 'failure', + message: 'invalid server response trying to download image ' + data.image.name + }); + } + } + } + + var img = new Image(); + + img.onload = function() { + + 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); + } + ); + + +}; + +R3.System.Storage.prototype.stop = function() { + + this.signInSubscription.remove(); + this.loadSubscription.remove(); + this.signOutSubscription.remove(); + this.saveSubscription.remove(); + this.getProjectsSubscription.remove(); + + this.loaded = []; + this.failed = []; + this.loading = []; + + R3.System.prototype.stop.call(this); + + // this.loadImageSubscription.remove(); + // this.loadFontSubscription.remove(); + // this.blenderDataSubscription.remove(); + // this.imageUploadCompleteSubscription.remove(); + // this.deleteSubscription.remove(); + // this.fetchComponentTypesSubscription.remove(); + // this.fetchComponentsSubscription.remove(); +}; + diff --git a/src/r3-system-visualization.js b/src/r3-system-visualization.js new file mode 100644 index 0000000..5e03c0c --- /dev/null +++ b/src/r3-system-visualization.js @@ -0,0 +1,148 @@ +/** + * 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 R3.API.System + * @param graphics + * @param physics + * @constructor + */ +R3.System.Visualization = function( + apiSystem, + graphics, + physics +) { + + R3.System.call( + this, + apiSystem + ); + + if (R3.Utils.UndefinedOrNull(graphics)){ + R3.Event.Emit( + R3.Event.GET_GRAPHICS_RUNTIME, + null, + function(graphicsRuntime) { + graphics = graphicsRuntime; + }.bind(this), + function() { + graphics = null; + }.bind(this) + ); + } + this.graphics = graphics; + + if (R3.Utils.UndefinedOrNull(physics)){ + R3.Event.Emit( + R3.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; + +}; + +R3.System.Visualization.prototype = Object.create(R3.System.prototype); +R3.System.Visualization.prototype.constructor = R3.System.Visualization; + +R3.System.Visualization.prototype.start = function() { + + R3.System.prototype.start.call(this); + + this.visualizationSubscription = this.subscribe( + R3.Event.VISUALIZE, + this.visualize + ); + + this.stopVisualizationSubscription = this.subscribe( + R3.Event.STOP_VISUALIZE, + this.stopVisualize + ) +}; + + +R3.System.Visualization.prototype.visualize = function(data) { + + var shape = data.shape; + + var parentMesh = shape.parentMesh; + + shape.setFromMesh(); + + var apiMesh = new R3.D3.API.Mesh(); + + apiMesh.name = 'Visualization Mesh for Shape ' + shape.name; + + if (shape instanceof R3.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 R3.D3.API.Vertex( + new R3.API.Vector3(v0.x, v0.y, v0.z) + ), + new R3.D3.API.Vertex( + new R3.API.Vector3(v1.x, v1.y, v1.z) + ), + new R3.D3.API.Vertex( + new R3.API.Vector3(v2.x, v2.y, v2.z) + ) + ); + var i = apiMesh.vertices.length - 3; + apiMesh.faces.push( + new R3.D3.API.Face( + null, + null, + i, + i+1, + i+2 + ) + ); + } + } + } + } + + new R3.D3.Mesh( + this.graphics, + apiMesh + ); + +}; + +R3.System.Visualization.prototype.stopVisualize = function(data) { +}; + +R3.System.Visualization.prototype.stop = function() { + + R3.System.prototype.stop.call(this); + + if (this.visualizationSubscription) { + this.visualizationSubscription.remove(); + } + + if (this.stopVisualizationSubscription) { + this.stopVisualizationSubscription.remove(); + } + +}; + diff --git a/src/r3-user.js b/src/r3-user.js new file mode 100644 index 0000000..ca32109 --- /dev/null +++ b/src/r3-user.js @@ -0,0 +1,89 @@ +/** + * R3.User + * @param apiComponent + * + * @property googleId + * @property fullName + * @property givenName + * @property familyName + * @property imageUrl + * @property email + * @property uploadFolder + * @property idToken + * + * @constructor + */ +R3.User = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.User.prototype = Object.create(R3.Component.prototype); +R3.User.prototype.constructor = R3.User; + +R3.User.prototype.createInstance = function() { + + this.instance = true; + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.User.prototype.updateInstance = function(property) { + + if (property === 'name') { + console.log('todo: user name update'); + return; + } + + if (property === 'googleId') { + console.log('todo: user googleId update'); + return; + } + + if (property === 'fullName') { + console.log('todo: user fullName update'); + return; + } + + if (property === 'givenName') { + console.log('todo: user givenName update'); + return; + } + + if (property === 'familyName') { + console.log('todo: user familyName update'); + return; + } + + if (property === 'imageUrl') { + console.log('todo: user imageUrl update'); + return; + } + + if (property === 'email') { + console.log('todo: user email update'); + return; + } + + if (property === 'uploadFolder') { + console.log('todo: user uploadFolder update'); + return; + } + + if (property === 'idToken') { + console.log('todo: user idToken update'); + return; + } + + __UPDATE_INSTANCE__; + +}; diff --git a/src/r3-vector2.js b/src/r3-vector2.js new file mode 100644 index 0000000..88c14e7 --- /dev/null +++ b/src/r3-vector2.js @@ -0,0 +1,83 @@ +/** + * R3.Vector2 + * @param apiComponent + * + * @property x + * @property y + * + * @constructor + */ +R3.Vector2 = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Vector2.prototype = Object.create(R3.Component.prototype); +R3.Vector2.prototype.constructor = R3.Vector2; + +/** + * Creates an instance vector2 + * @returns {*} + */ +R3.Vector2.prototype.createInstance = function() { + + var runtime = R3.Component.GetComponentRuntime(this.parent); + + switch (runtime) { + case R3.Runtime.GRAPHICS : + this.instance = this.graphics.Vector2( + this.x, + this.y + ); + break; + case R3.Runtime.PHYSICS : + this.instance = this.physics.Vector2( + this.x, + this.y + ); + break; + default: + throw new Error('unhandled component runtime: ' + runtime); + } + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance vector, calls updateInstance on the parent object + */ +R3.Vector2.prototype.updateInstance = function(property) { + + if (property === 'x') { + this.instance.x = this.x; + return; + } + + if (property === 'y') { + this.instance.y = this.y; + return; + } + + __UPDATE_INSTANCE__; + +}; + +/** + * Copy + * TODO: Test + * @param v optional + * @returns {R3.Vector2} + */ +R3.Vector2.prototype.clone = function(v) { + + return new R3.Vector2( + this + ); + +}; diff --git a/src/r3-vector3.js b/src/r3-vector3.js new file mode 100644 index 0000000..61340d5 --- /dev/null +++ b/src/r3-vector3.js @@ -0,0 +1,148 @@ +/** + * R3.Vector3 + * @param apiComponent + * + * @property x + * @property y + * @property z + * + * @constructor + */ +R3.Vector3 = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Vector3.prototype = Object.create(R3.Component.prototype); +R3.Vector3.prototype.constructor = R3.Vector3; + +/** + * Creates an instance vector3 + * @returns {*} + */ +R3.Vector3.prototype.createInstance = function() { + + /** + * We have a dependency on our parent which could still need to call 'createInstance' + */ + + // if (typeof this.parent === 'string') { + // + // if (R3.Utils.UndefinedOrNull(this.instanceLoaded)) { + // + // this.instanceLoaded = R3.Event.Subscribe( + // R3.Event.INSTANCE_LOADED, + // function (data) { + // if (data.component.id === this.parent) { + // this.parent = data.component; + // this.createInstance(); + // this.instanceLoaded.remove(); + // } + // }.bind(this) + // ); + // + // } + // + // return; + // } + + var runtime = R3.Component.GetComponentRuntime(this.parent); + + switch (runtime) { + case R3.Runtime.GRAPHICS : + this.instance = this.graphics.Vector3( + this.x, + this.y, + this.z + ); + break; + case R3.Runtime.PHYSICS : + this.instance = this.physics.Vector3( + this.x, + this.y, + this.z + ); + break; + default: + throw new Error('unhandled component runtime: ' + runtime); + } + + __CREATE_INSTANCE__; +}; + +/** + * Updates the instance vector, calls updateInstance on the parent object + */ +R3.Vector3.prototype.updateInstance = function(property) { + + if (property === 'x') { + this.instance.x = this.x; + return; + } + + if (property === 'y') { + this.instance.y = this.y; + return; + } + + if (property === 'z') { + this.instance.z = this.z; + return; + } + + __UPDATE_INSTANCE__; + +}; + +/** + * Clones this vector + * @returns {R3.Vector3|R3.Vector3|R3.Vector3} + */ +R3.Vector3.prototype.clone = function() { + return new R3.Vector3(this); +}; + +/** + * Create a negative version of this vector + * @returns {R3.Vector3} + */ +R3.Vector3.prototype.negativeCopy = function() { + + var vector3 = new R3.Vector3(this); + + vector3.x *= -1; + vector3.y *= -1; + vector3.z *= -1; + + return vector3; +}; + +/** + * Applies rotation specified by axis / angle to this vector - its a wrapper for three.. + * @param axis + * @param angle + */ +R3.Vector3.prototype.applyAxisAngle = function(axis, angle) { + + console.warn('todo: do nor rely on graphics instance'); + return; + + 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; + return this; +}; \ No newline at end of file diff --git a/src/r3-vector4.js b/src/r3-vector4.js new file mode 100644 index 0000000..934d83d --- /dev/null +++ b/src/r3-vector4.js @@ -0,0 +1,84 @@ +/** + * R3.Vector4 + * @param apiComponent + * + * @property x + * @property y + * @property z + * @property w + * + * @constructor + */ +R3.Vector4 = function( + apiComponent +) { + + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; + +}; + +R3.Vector4.prototype = Object.create(R3.Component.prototype); +R3.Vector4.prototype.constructor = R3.Vector4; + +/** + * Creates an instance vector4 + * @returns {*} + */ +R3.Vector4.prototype.createInstance = function() { + + var runtime = R3.Component.GetComponentRuntime(this.parent); + + switch (runtime) { + case R3.Runtime.GRAPHICS : + this.instance = this.graphics.Vector4( + this.x, + this.y, + this.z, + this.w + ); + break; + case R3.Runtime.PHYSICS : + this.instance = this.physics.Vector4( + this.x, + this.y, + this.z, + this.w + ); + break; + default: + throw new Error('unhandled component runtime: ' + runtime); + } + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance vector, calls updateInstance on the parent object + */ +R3.Vector4.prototype.updateInstance = function(property) { + + if (property === 'x') { + this.instance.x = this.x; + return; + } + + if (property === 'y') { + this.instance.y = this.y; + return; + } + + if (property === 'z') { + this.instance.z = this.z; + return; + } + + if (property === 'w') { + this.instance.w = this.w; + return; + } + + __UPDATE_INSTANCE__; +}; diff --git a/src/r3-video.js b/src/r3-video.js new file mode 100644 index 0000000..90b7f37 --- /dev/null +++ b/src/r3-video.js @@ -0,0 +1,124 @@ +/** + * R3.Video + * @param apiComponent + * + * @property autoUpdateSize + * @property width + * @property height + * @property offset + * @property source + * + * @constructor + */ +R3.Video = function( + apiComponent +) { + __RUNTIME_COMPONENT__; + + __UPGRADE_TO_RUNTIME__; +}; + +R3.Video.prototype = Object.create(R3.Component.prototype); +R3.Video.prototype.constructor = R3.Video; + +/** + * Creates a light instance + * @returns {*} + */ +R3.Video.prototype.createInstance = function() { + + this.instance = document.createElement('video'); + + this.instance.setAttribute('id', this.id); + + this.instance.setAttribute('width', this.width); + + this.instance.setAttribute('height', this.height); + + this.instance.setAttribute('style', 'left: ' + this.offset.x + 'px;top: ' + this.offset.y + 'px'); + + this.instance.setAttribute('loop', ''); + + this.instance.setAttribute('controls', ''); + + this.instance.setAttribute('autoplay', ''); + + this.instance.setAttribute('webkit-playsinline', ''); + + if (this.autoUpdateSize) { + /** + * Update our size from the instance size + */ + this.width = this.instance.width; + this.height = this.instance.height; + } else { + /** + * Update our instance with our size + */ + this.instance.width = this.width; + this.instance.height = this.height; + } + + if (this.source) { + this.instance.setAttribute('src', this.source); + } + + __CREATE_INSTANCE__; + +}; + +/** + * Updates the instance with the current state + */ +R3.Video.prototype.updateInstance = function(property) { + + if (property === 'id') { + this.instance.setAttribute('id', this.id); + return; + } + + if (property === 'offset') { + this.instance.style.left = this.offset.x + 'px'; + this.instance.style.top = this.offset.y + 'px'; + return; + } + + if ( + property === 'autoUpdateSize' || + property === 'width' || + property === 'height' + ) { + /** + * We cannot control everything about the canvas - this is dependent on where the canvas lives and its + * dimensions can also be controlled via CSS - + * + * This means - autoUpdateSize works a little different for this component - instead of getting our size and + * applying it, it gets our canvas size and applies it, or applies our size to the canvas - of course + * the user settings override this. + */ + if (this.autoUpdateSize) { + + /** + * Update from our canvas size + */ + this.width = this.instance.width; + this.height = this.instance.height; + + } else { + + /** + * Command our canvas to take a size - this is not guaranteed however - CSS wins + */ + this.instance.width = this.width; + this.instance.height = this.height; + } + return; + } + + if (property === 'source') { + this.instance.src = this.source; + return; + } + + __UPDATE_INSTANCE__; +}; diff --git a/src/r3-z.js b/src/r3-z.js new file mode 100644 index 0000000..3c359cb --- /dev/null +++ b/src/r3-z.js @@ -0,0 +1,10 @@ + +R3.EntityManager.Instance = new R3.EntityManager(); + +if (typeof window !== 'undefined') { + window.R3 = R3; +} + +if (typeof module !== 'undefined') { + module.exports = R3; +} \ No newline at end of file diff --git a/test/test.gameLib.js b/test/test.gameLib.js new file mode 100644 index 0000000..ac70a36 --- /dev/null +++ b/test/test.gameLib.js @@ -0,0 +1,178 @@ +var chai = require('chai'), + sinon = require("sinon"), + sinonChai = require("sinon-chai"), + config = require('../config.js'), + assert = chai.assert, + R3 = require('../build/r3'), + CANNON = require('cannon'), + THREE = require('three'); + +chai.use(sinonChai); + +describe('R3 object creation', function(){ + + this.timeout(0); + + before(function(){ + + }); + + after(function(){ + + }); + + beforeEach(function(done, err) { + this.xhr = sinon.useFakeXMLHttpRequest(); + + this.requests = []; + this.xhr.onCreate = function(xhr) { + this.requests.push(xhr); + }.bind(this); + done(); + }); + + afterEach(function(done, err){ + this.xhr.restore(); + done(); + }); + + it('Should create a Bone object', function (done) { + + var bone = new R3.D3.Bone( + null, + 1, + 'test bone 1', + [2, 3, 4] + ); + + assert(bone.position instanceof R3.D3.Vector3); + assert(bone.rotation instanceof R3.D3.Vector3); + assert(bone.scale instanceof R3.D3.Vector3); + assert(bone.up instanceof R3.D3.Vector3); + assert(bone.quaternion instanceof R3.D3.Vector4); + assert(bone.parentBoneId == null); + assert.deepEqual(bone.childBoneIds, [2,3,4]); + + done(); + }); + + it('Should create a BoneWeight object', function (done) { + + var boneWeight = new R3.D3.BoneWeight( + 1, + 0.5 + ); + + assert(boneWeight.boneIndex == 1); + assert(boneWeight.weight == 0.5); + + done(); + }); + + it('Should create a Broadphase object', function (done) { + + var engine = new R3.D3.Engine( + R3.D3.Engine.ENGINE_TYPE_CANNON, + CANNON + ); + + assert(engine.engineType == R3.D3.Engine.ENGINE_TYPE_CANNON); + assert(engine.instance instanceof Object); + + var broadphase = new R3.D3.Broadphase( + null, + 'broad-phase', + R3.D3.Broadphase.BROADPHASE_TYPE_NAIVE, + engine, + true + ); + + assert(broadphase.id == null); + assert(broadphase.instance instanceof CANNON.NaiveBroadphase); + assert(broadphase.engine instanceof R3.D3.Engine); + assert(broadphase.name == 'broad-phase'); + assert(broadphase.broadphaseType == R3.D3.Broadphase.BROADPHASE_TYPE_NAIVE); + + done(); + }); + + it('Should create a Color object', function (done) { + + var color = new R3.D3.Color( + 0.1, + 0.2, + 0.3, + 0.4 + ); + + assert(color.r == 0.1); + assert(color.g == 0.2); + assert(color.b == 0.3); + assert(color.a == 0.4); + + done(); + }); + + it('Should create a Color object', function (done) { + + var color = new R3.D3.Color( + 0.1, + 0.2, + 0.3, + 0.4 + ); + + assert(color.r == 0.1); + assert(color.g == 0.2); + assert(color.b == 0.3); + assert(color.a == 0.4); + + done(); + }); + + + it('Should create an Engine object', function (done) { + + var engine = new R3.D3.Engine( + R3.D3.Engine.ENGINE_TYPE_CANNON, + CANNON + ); + + assert(engine.engineType == R3.D3.Engine.ENGINE_TYPE_CANNON); + assert(engine.instance instanceof Object); + + done(); + }); + + it('Should create a FlyControls object', function (done) { + console.log("Cannot test FlyControls server side"); + done(); + }); + + it('Should load the scene via API', function(done) { + + var scene = new R3.D3.Scene( + null, + '/gamewheel/root/root/test', + 'test' + ); + + var graphics = new R3.D3.Graphics( + R3.D3.Graphics.GRAPHICS_TYPE_THREE, + THREE + ); + + R3.D3.Scene.LoadSceneFromApi( + scene, + function(stuff){ + done(); + }, + graphics, + '/uploads/gamewheel/root/root/test', + null, + 'http://api.gamewheel.local' + ); + + }); + +}); \ No newline at end of file diff --git a/todo/r3-d3-polyVertex.js b/todo/r3-d3-polyVertex.js new file mode 100644 index 0000000..7cd2410 --- /dev/null +++ b/todo/r3-d3-polyVertex.js @@ -0,0 +1,36 @@ +/** + * Contains a Poly vertex data structure + * @param localIndex + * @param mvertIndex + * @param uv R3.API.Vector2 + * @param materialIndex + * @param edgeIndex + * @constructor + */ +R3.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 {R3.D3.PolyVertex} + */ +R3.D3.PolyVertex.prototype.clone = function() { + return new R3.D3.PolyVertex( + this.localIndex, + this.mvertIndex, + this.uv.copy(), + this.materialIndex, + this.edgeIndex + ) +}; \ No newline at end of file diff --git a/todo/r3-d3-triangleEdge.js b/todo/r3-d3-triangleEdge.js new file mode 100644 index 0000000..7d6257a --- /dev/null +++ b/todo/r3-d3-triangleEdge.js @@ -0,0 +1,13 @@ +/** + * TriangleEdge + * @param triangle + * @param edge + * @constructor + */ +R3.D3.TriangleEdge = function( + triangle, + edge +) { + this.triangle = triangle; + this.edge = edge; +}; \ No newline at end of file diff --git a/todo/soc-a.js b/todo/soc-a.js new file mode 100644 index 0000000..27bd71f --- /dev/null +++ b/todo/soc-a.js @@ -0,0 +1,8 @@ +console.log('Loading SOC Library compiled on : __DATE__'); + +/** + * SOC + * @constructor + */ +function SOC () { +} diff --git a/todo/soc-graph-barchart-stacked.js b/todo/soc-graph-barchart-stacked.js new file mode 100644 index 0000000..e69de29 diff --git a/todo/soc-graph-barchart.js b/todo/soc-graph-barchart.js new file mode 100644 index 0000000..e69de29 diff --git a/todo/soc-graph-counter.js b/todo/soc-graph-counter.js new file mode 100644 index 0000000..12f064b --- /dev/null +++ b/todo/soc-graph-counter.js @@ -0,0 +1,33 @@ + + +SOC.Query.WorldMapDashboard = function() { + google.charts.load('current', { + 'packages':['geochart'], + // Note: you will need to get a mapsApiKey for your project. + // See: https://developers.google.com/chart/interactive/docs/basic_load_libs#load-settings + 'mapsApiKey': 'AIzaSyBvsr1U4CzWk9_t4prYNCuRWwe8HFLY8IM' + }); + google.charts.setOnLoadCallback(drawRegionsMap); + + function drawRegionsMap() { + var data = google.visualization.arrayToDataTable([ + ['Country', 'Popularity'], + ['Germany', 200], + ['United States', 300], + ['Brazil', 400], + ['Canada', 500], + ['France', 600], + ['RU', 700] + ]); + + var options = {}; + + var chart = new google.visualization.GeoChart(document.getElementById('div-access')); + + chart.draw(data, options); + + document.getElementById('div-access').getElementsByTagName('div')[0].style.position = 'absolute'; + } + + +}; diff --git a/todo/soc-graph-table.js b/todo/soc-graph-table.js new file mode 100644 index 0000000..12f064b --- /dev/null +++ b/todo/soc-graph-table.js @@ -0,0 +1,33 @@ + + +SOC.Query.WorldMapDashboard = function() { + google.charts.load('current', { + 'packages':['geochart'], + // Note: you will need to get a mapsApiKey for your project. + // See: https://developers.google.com/chart/interactive/docs/basic_load_libs#load-settings + 'mapsApiKey': 'AIzaSyBvsr1U4CzWk9_t4prYNCuRWwe8HFLY8IM' + }); + google.charts.setOnLoadCallback(drawRegionsMap); + + function drawRegionsMap() { + var data = google.visualization.arrayToDataTable([ + ['Country', 'Popularity'], + ['Germany', 200], + ['United States', 300], + ['Brazil', 400], + ['Canada', 500], + ['France', 600], + ['RU', 700] + ]); + + var options = {}; + + var chart = new google.visualization.GeoChart(document.getElementById('div-access')); + + chart.draw(data, options); + + document.getElementById('div-access').getElementsByTagName('div')[0].style.position = 'absolute'; + } + + +}; diff --git a/todo/soc-graph-world.js b/todo/soc-graph-world.js new file mode 100644 index 0000000..12f064b --- /dev/null +++ b/todo/soc-graph-world.js @@ -0,0 +1,33 @@ + + +SOC.Query.WorldMapDashboard = function() { + google.charts.load('current', { + 'packages':['geochart'], + // Note: you will need to get a mapsApiKey for your project. + // See: https://developers.google.com/chart/interactive/docs/basic_load_libs#load-settings + 'mapsApiKey': 'AIzaSyBvsr1U4CzWk9_t4prYNCuRWwe8HFLY8IM' + }); + google.charts.setOnLoadCallback(drawRegionsMap); + + function drawRegionsMap() { + var data = google.visualization.arrayToDataTable([ + ['Country', 'Popularity'], + ['Germany', 200], + ['United States', 300], + ['Brazil', 400], + ['Canada', 500], + ['France', 600], + ['RU', 700] + ]); + + var options = {}; + + var chart = new google.visualization.GeoChart(document.getElementById('div-access')); + + chart.draw(data, options); + + document.getElementById('div-access').getElementsByTagName('div')[0].style.position = 'absolute'; + } + + +}; diff --git a/todo/soc-graph.js b/todo/soc-graph.js new file mode 100644 index 0000000..5adf3a0 --- /dev/null +++ b/todo/soc-graph.js @@ -0,0 +1,2 @@ +function SOC.Graph() { +} diff --git a/todo/soc-query-alert-dashboard.js b/todo/soc-query-alert-dashboard.js new file mode 100644 index 0000000..bff2796 --- /dev/null +++ b/todo/soc-query-alert-dashboard.js @@ -0,0 +1,66 @@ +/** + * @param options + * @constructor + */ +SOC.Query.AlertDashboard = function( + options +) { + + if (!options) { + options = {}; + } + + if (!options.path) { + options.path = '/alerts/_search'; + } + + if (!options.query) { + options.query = { + "version": false, + "size": 0, + "sort": [ + { + "timestamp": { + "order": "desc", + "unmapped_type": "boolean" + } + } + ], + "_source": { + "includes": ["*"] + }, + "aggs": { + "priorities": { + "histogram": { + "field": "priority", + "interval": "1", + "min_doc_count": 0 + } + } + }, + "query": { + "bool": { + "must": [ + { + "range": { + "timestamp": { + "format": "strict_date_optional_time", + "gte": "%QUERY_START", + "lt": "%QUERY_END" + } + } + } + ] + } + } + }; + } + + SOC.Query.call( + this, + options + ); +}; + +SOC.Query.AlertDashboard.prototype = Object.create(SOC.Query.prototype); +SOC.Query.AlertDashboard.prototype.constructor = SOC.Query; diff --git a/todo/soc-query-alert-list.js b/todo/soc-query-alert-list.js new file mode 100644 index 0000000..714cebe --- /dev/null +++ b/todo/soc-query-alert-list.js @@ -0,0 +1,79 @@ + + + +/** + * @param options + * @constructor + */ +SOC.Query.AlertList = function( + options +) { + + if (!options) { + options = {}; + } + + if (!options.path) { + options.path = '/alerts/_search'; + } + + if (!options.query) { + options.query = { + "version": false, + "size": 200, + "sort": [ + { + "priority": { + "order": "asc", + "unmapped_type": "boolean" + }, + "alert_type.keyword": { + "order": "asc", + "unmapped_type": "boolean" + } + } + ], + "_source": { + "includes": ["*"] + }, + "query": { + "bool": { + "must": [ + { + "range": { + "timestamp": { + "format": "strict_date_optional_time", + "gte": "", + "lt": "" + } + } + } + ] + } + } + } + } + + SOC.Query.call( + this, + options + ); +}; + +SOC.Query.AlertList.prototype = Object.create(SOC.Query.prototype); +SOC.Query.AlertList.prototype.constructor = SOC.Query; + +SOC.Query.AlertList.prototype.draw = function(divId, data) { + + google.charts.load( + 'current', + { + 'packages': ['table'] + } + ); + + google.charts.setOnLoadCallback( + this.drawTable(divId, data) + ); + +}; diff --git a/todo/soc-query.js b/todo/soc-query.js new file mode 100644 index 0000000..ad517c0 --- /dev/null +++ b/todo/soc-query.js @@ -0,0 +1,92 @@ +SOC.Query = function (options) { + + if (options && options.path) { + this.path = options.path; + } else { + this.path = null; + } + + if (options && options.queryStart) { + this.queryStart = options.queryStart; + } else { + this.queryStart = 'now-7d'; + } + + if (options && options.queryEnd) { + this.queryEnd = options.queryEnd; + } else { + this.queryEnd = 'now+4h'; + } + + if (options && options.query) { + this.query = options.query; + } else { + this.query = null; + } + + if (options && options.onData) { + this.onData = options.onData; + } else { + this.onData = function() { + throw new Error( + "You should specify a onData function in the constructor to your query, ex. SOC.Query.SomeQuery({onData : myCallbackFunction})" + ) + }; + } + + this.run(); + +}; + +SOC.Query.prototype = Object.create(SOC.prototype); +SOC.Query.prototype.constructor = SOC; + +SOC.Query.prototype.run = function() { + + if (this.path === null) { + throw new Error('query path must be set'); + } + + if (this.query === null) { + throw new Error('query must be set'); + } + + var xhr = new XMLHttpRequest(); + + xhr.open( + 'POST', + this.apiUrl + this.path, + true + ); + + xhr.onload = function(event){ + console.log('loaded'); + this.onData(JSON.parse(event.target.responseText)); + }.bind(this); + + xhr.onerror = function(event) { + throw new Error('An error occured during query execution'); + }; + + xhr.setRequestHeader( + 'Content-Type', + 'application/json' + ); + + var queryText = JSON.stringify(this.query); + + queryText = queryText.replace('%QUERY_START', this.queryStart); + queryText = queryText.replace('%QUERY_END', this.queryEnd); + + xhr.send( + queryText + ); +}; + +SOC.Query.prototype.drawTable = function(divId, data) { + + return function() { + + + } +};