diff --git a/src/game-lib-a-component-a.js b/src/game-lib-a-component-a.js index 336dfcd..97863f2 100644 --- a/src/game-lib-a-component-a.js +++ b/src/game-lib-a-component-a.js @@ -116,6 +116,9 @@ GameLib.Component.COMPONENT_STATS = 0x1d; GameLib.Component.COMPONENT_GUI = 0x1e; GameLib.Component.COMPONENT_IMAGE = 0x1f; GameLib.Component.COMPONENT_ENTITY = 0x20; +GameLib.Component.COMPONENT_MESH_SPHERE = 0x21; +GameLib.Component.COMPONENT_MESH_PLANE = 0x22; +GameLib.Component.COMPONENT_MESH_CURVE = 0x23; /** * Returns string name for component number @@ -157,6 +160,9 @@ GameLib.Component.GetComponentName = function(number) { case 0x1e : return 'GameLib.GUI'; case 0x1f : return 'GameLib.D3.Image'; case 0x20 : return 'GameLib.Entity'; + case 0x21 : return 'GameLib.D3.Mesh.Sphere'; + case 0x22 : return 'GameLib.D3.Mesh.Plane'; + case 0x23 : return 'GameLib.D3.Mesh.Curve'; break; } }; diff --git a/src/game-lib-d3-api-mesh.js b/src/game-lib-d3-api-mesh.js index 1642ab8..5cc4aa0 100644 --- a/src/game-lib-d3-api-mesh.js +++ b/src/game-lib-d3-api-mesh.js @@ -54,7 +54,7 @@ GameLib.D3.API.Mesh = function( this.id = id; if (GameLib.Utils.UndefinedOrNull(meshType)) { - meshType = GameLib.D3.Mesh.TYPE_NORMAL; + meshType = GameLib.D3.Mesh.MESH_TYPE_NORMAL; } this.meshType = meshType; diff --git a/src/game-lib-d3-helper.js b/src/game-lib-d3-helper.js index 57611ef..1ed0696 100644 --- a/src/game-lib-d3-helper.js +++ b/src/game-lib-d3-helper.js @@ -41,7 +41,7 @@ GameLib.D3.Helper = function( if ( object instanceof GameLib.D3.Mesh && - object.meshType !== GameLib.D3.Mesh.TYPE_CURVE + object.meshType !== GameLib.D3.Mesh.MESH_TYPE_CURVE ) { helperType = GameLib.D3.Helper.HELPER_TYPE_EDGES; } diff --git a/src/game-lib-d3-input-editor.js b/src/game-lib-d3-input-editor.js index a91c373..a716165 100644 --- a/src/game-lib-d3-input-editor.js +++ b/src/game-lib-d3-input-editor.js @@ -148,13 +148,13 @@ GameLib.D3.Input.Editor.prototype.onKeyDown = function(entity, entityManager) { if (mesh.selected) { this.removeHelper(mesh, entity); entity.removeComponent(mesh); - console.log('entity.buildIdToObject()'); + entity.buildIdToObject(); gui.removeObject(mesh); var scene = mesh.parentScene; scene.removeObject(mesh); - console.log('scene.buildIdToObject()'); + scene.buildIdToObject(); } }.bind(this) ); @@ -281,7 +281,7 @@ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity, entityManager) return function(event) { - if (event.button === 0 || event.button === 2) { + if (event.button === 2) { if (this.controlLeft) { return; diff --git a/src/game-lib-d3-material.js b/src/game-lib-d3-material.js index a7290f8..aeef8c2 100644 --- a/src/game-lib-d3-material.js +++ b/src/game-lib-d3-material.js @@ -700,237 +700,232 @@ GameLib.D3.Material.prototype.updateMeshBasicMaterialInstance = function() { */ GameLib.D3.Material.prototype.createInstance = function(update) { - if (!this.loaded) { - console.log('Attempted to create an instance but the runtime object is not fully loaded : ' + this.name); - return null; - } - - if (update) { - - var typeChange = false; - - if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_STANDARD) { - if (!(this.instance instanceof THREE.MeshStandardMaterial)) { - this.instance = this.createStandardMaterialInstance(); - typeChange = true; - } else { - this.updateStandardMaterialInstance(); - } - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_POINTS) { - if (!(this.instance instanceof THREE.PointsMaterial)) { - this.instance = this.createPointsMaterialInstance(); - typeChange = true; - } else { - this.updatePointsMaterialInstance(); - } - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_PHONG) { - if (!(this.instance instanceof THREE.MeshPhongMaterial)) { - this.instance = this.createPhongMaterialInstance(); - typeChange = true; - } else { - this.updatePhongMaterialInstance(); - } - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_BASIC) { - if (!(this.instance instanceof THREE.MeshBasicMaterial)) { - this.instance = this.createMeshBasicMaterialInstance(); - typeChange = true; - } else { - this.updateMeshBasicMaterialInstance(); - } - } else { - console.warn('not yet implemented (material type = ' + this.materialType + ')'); - } - - this.updateTextures(); - - if (typeChange) { - this.publish( - GameLib.Event.MATERIAL_TYPE_CHANGED, - { - material: this - } - ); - } - - this.instance.needsUpdate = true; - - - - } else { - - var instance = null; - - if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_STANDARD) { - - instance = this.createStandardMaterialInstance(); - - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_POINTS) { - - instance = this.createPointsMaterialInstance(); - - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_PHONG) { - - instance = this.createPhongMaterialInstance(); - - } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_BASIC) { - - instance = this.createMeshBasicMaterialInstance(); - - } else { - console.warn("material type is not implemented yet: " + this.materialType); - } - - instance.needsUpdate = true; - - this.subscribe( - GameLib.Event.TEXTURE_LOADED, - function (data) { - - var modified = false; - - /** - * We also need to check if the image of the texture is assigned - - * if not we should disable the map - */ - if (this.alphaMap === data.texture) { - - if (data.texture.image) { - this.instance.alphaMap = data.texture.instance; - } else { - this.instance.alphaMap = null; - } - - modified = true; - } - if (this.aoMap === data.texture) { - - if (data.texture.image) { - this.instance.aoMap = data.texture.instance; - } else { - this.instance.aoMap = null; - } - modified = true; - } - if (this.bumpMap === data.texture) { - - if (data.texture.image) { - this.instance.bumpMap = data.texture.instance; - } else { - this.instance.bumpMap = null; - } - modified = true; - } - if (this.diffuseMap === data.texture) { - - if (data.texture.image) { - this.instance.map = data.texture.instance; - } else { - this.instance.map = null; - } - modified = true; - } - if (this.displacementMap === data.texture) { - - if (data.texture.image) { - this.instance.displacementMap = data.texture.instance; - } else { - this.instance.displacementMap = null; - } - modified = true; - } - if (this.emissiveMap === data.texture) { - - if (data.texture.image) { - this.instance.emissiveMap = data.texture.instance; - } else { - this.instance.emissiveMap = null; - } - modified = true; - } - if (this.environmentMap === data.texture) { - - if (data.texture.image) { - this.instance.envMap = data.texture.instance; - } else { - this.instance.envMap = null; - } - modified = true; - } - if (this.lightMap === data.texture) { - - if (data.texture.image) { - this.instance.lightMap = data.texture.instance; - } else { - this.instance.lightMap = null; - } - modified = true; - } - if (this.metalnessMap === data.texture) { - - if (data.texture.image) { - this.instance.metalnessMap = data.texture.instance; - } else { - this.instance.metalnessMap = null; - } - modified = true; - } - if (this.normalMap === data.texture) { - - if (data.texture.image) { - this.instance.normalMap = data.texture.instance; - } else { - this.instance.normalMap = null; - } - modified = true; - } - if (this.roughnessMap === data.texture) { - - if (data.texture.image) { - this.instance.roughnessMap = data.texture.instance; - } else { - this.instance.roughnessMap = null; - } - modified = true; - } - if (this.specularMap === data.texture) { - - if (data.texture.image) { - this.instance.specularMap = data.texture.instance; - } else { - this.instance.specularMap = null; - } - modified = true; - } - - if (modified) { - - this.publish( - GameLib.Event.MATERIAL_LOADED, - { - material: this - } - ); - - this.instance.needsUpdate = true; - } - - } - ); - - this.instance = instance; - - this.updateTextures(); - - return instance; + if (!this.loaded) { + console.log('Attempted to create an instance but the runtime object is not fully loaded : ' + this.name); + return null; } -}; + var instance = null; + + if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_STANDARD) { + + instance = this.createStandardMaterialInstance(); + + } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_POINTS) { + + instance = this.createPointsMaterialInstance(); + + } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_PHONG) { + + instance = this.createPhongMaterialInstance(); + + } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_BASIC) { + + instance = this.createMeshBasicMaterialInstance(); + + } else { + console.warn("material type is not implemented yet: " + this.materialType); + } + + instance.needsUpdate = true; + + this.subscribe( + GameLib.Event.TEXTURE_LOADED, + function (data) { + + var modified = false; + + /** + * We also need to check if the image of the texture is assigned - + * if not we should disable the map + */ + if (this.alphaMap === data.texture) { + + if (data.texture.image) { + this.instance.alphaMap = data.texture.instance; + } else { + this.instance.alphaMap = null; + } + + modified = true; + } + if (this.aoMap === data.texture) { + + if (data.texture.image) { + this.instance.aoMap = data.texture.instance; + } else { + this.instance.aoMap = null; + } + modified = true; + } + if (this.bumpMap === data.texture) { + + if (data.texture.image) { + this.instance.bumpMap = data.texture.instance; + } else { + this.instance.bumpMap = null; + } + modified = true; + } + if (this.diffuseMap === data.texture) { + + if (data.texture.image) { + this.instance.map = data.texture.instance; + } else { + this.instance.map = null; + } + modified = true; + } + if (this.displacementMap === data.texture) { + + if (data.texture.image) { + this.instance.displacementMap = data.texture.instance; + } else { + this.instance.displacementMap = null; + } + modified = true; + } + if (this.emissiveMap === data.texture) { + + if (data.texture.image) { + this.instance.emissiveMap = data.texture.instance; + } else { + this.instance.emissiveMap = null; + } + modified = true; + } + if (this.environmentMap === data.texture) { + + if (data.texture.image) { + this.instance.envMap = data.texture.instance; + } else { + this.instance.envMap = null; + } + modified = true; + } + if (this.lightMap === data.texture) { + + if (data.texture.image) { + this.instance.lightMap = data.texture.instance; + } else { + this.instance.lightMap = null; + } + modified = true; + } + if (this.metalnessMap === data.texture) { + + if (data.texture.image) { + this.instance.metalnessMap = data.texture.instance; + } else { + this.instance.metalnessMap = null; + } + modified = true; + } + if (this.normalMap === data.texture) { + + if (data.texture.image) { + this.instance.normalMap = data.texture.instance; + } else { + this.instance.normalMap = null; + } + modified = true; + } + if (this.roughnessMap === data.texture) { + + if (data.texture.image) { + this.instance.roughnessMap = data.texture.instance; + } else { + this.instance.roughnessMap = null; + } + modified = true; + } + if (this.specularMap === data.texture) { + + if (data.texture.image) { + this.instance.specularMap = data.texture.instance; + } else { + this.instance.specularMap = null; + } + modified = true; + } + + if (modified) { + + this.publish( + GameLib.Event.MATERIAL_LOADED, + { + material: this + } + ); + + this.instance.needsUpdate = true; + } + } + ); + + this.instance = instance; + + this.updateTextures(); + + return instance; +} /** * Updates the instance with the current state */ GameLib.D3.Material.prototype.updateInstance = function() { - this.createInstance(true); + + if (!this.instance) { + console.warn('Attempt to update a non-existent instance'); + return; + } + + var typeChange = false; + + if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_STANDARD) { + if (!(this.instance instanceof THREE.MeshStandardMaterial)) { + this.instance = this.createStandardMaterialInstance(); + typeChange = true; + } else { + this.updateStandardMaterialInstance(); + } + } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_POINTS) { + if (!(this.instance instanceof THREE.PointsMaterial)) { + this.instance = this.createPointsMaterialInstance(); + typeChange = true; + } else { + this.updatePointsMaterialInstance(); + } + } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_PHONG) { + if (!(this.instance instanceof THREE.MeshPhongMaterial)) { + this.instance = this.createPhongMaterialInstance(); + typeChange = true; + } else { + this.updatePhongMaterialInstance(); + } + } else if (this.materialType === GameLib.D3.Material.MATERIAL_TYPE_BASIC) { + if (!(this.instance instanceof THREE.MeshBasicMaterial)) { + this.instance = this.createMeshBasicMaterialInstance(); + typeChange = true; + } else { + this.updateMeshBasicMaterialInstance(); + } + } else { + console.warn('not yet implemented (material type = ' + this.materialType + ')'); + } + + this.updateTextures(); + + if (typeChange) { + this.publish( + GameLib.Event.MATERIAL_TYPE_CHANGED, + { + material: this + } + ); + } + + this.instance.needsUpdate = true; }; /** diff --git a/src/game-lib-d3-mesh-0.js b/src/game-lib-d3-mesh-0.js index 6a04ffe..9424c5a 100644 --- a/src/game-lib-d3-mesh-0.js +++ b/src/game-lib-d3-mesh-0.js @@ -122,9 +122,19 @@ GameLib.D3.Mesh = function ( this ); + var componentType = GameLib.Component.COMPONENT_MESH; + + if (this.meshType === GameLib.D3.Mesh.MESH_TYPE_PLANE) { + componentType = GameLib.Component.COMPONENT_MESH_PLANE + } + + if (this.meshType === GameLib.D3.Mesh.MESH_TYPE_SPHERE) { + componentType = GameLib.Component.COMPONENT_MESH_SPHERE + } + GameLib.Component.call( this, - GameLib.Component.COMPONENT_MESH, + componentType, { 'parentMesh' : GameLib.D3.Mesh, 'parentScene' : GameLib.D3.Scene, @@ -141,41 +151,74 @@ GameLib.D3.Mesh.prototype.constructor = GameLib.D3.Mesh; * Mesh Type * @type {number} */ -GameLib.D3.Mesh.TYPE_NORMAL = 0x0; -GameLib.D3.Mesh.TYPE_SKINNED = 0x1; -GameLib.D3.Mesh.TYPE_CURVE = 0x2; +GameLib.D3.Mesh.MESH_TYPE_NORMAL = 0x0; +GameLib.D3.Mesh.MESH_TYPE_SKINNED = 0x1; +GameLib.D3.Mesh.MESH_TYPE_CURVE = 0x2; +GameLib.D3.Mesh.MESH_TYPE_SPHERE = 0x3; +GameLib.D3.Mesh.MESH_TYPE_PLANE = 0x4; + /** - * Mesh Shape (predefined or custom) - * @type {number} + * Apply geometry data to our game-lib object from the geometry instance (revere of applyVertexData) + * @param geometryInstance */ -GameLib.D3.Mesh.SHAPE_CUSTOM = 0x1; -GameLib.D3.Mesh.SHAPE_SPHERE = 0x2; - -/** - * Creates custom geometry - * @returns {THREE.Geometry} - */ -GameLib.D3.Mesh.prototype.customGeometry = function(){ - - var geometry = new THREE.Geometry(); - +GameLib.D3.Mesh.prototype.updateVerticesFromGeometryInstance = function(geometryInstance) { /** * Setup vertices */ - for (var v = 0; v < this.vertices.length; v++) { - geometry.vertices.push( - new this.graphics.instance.Vector3( - this.vertices[v].position.x, - this.vertices[v].position.y, - this.vertices[v].position.z + + this.vertices = []; + + geometryInstance.vertices.map(function(vertex){ + this.vertices.push( + new GameLib.D3.Vertex( + this.graphics, + new GameLib.D3.API.Vertex( + new GameLib.Vector3( + this.graphics, + new GameLib.API.Vector3( + vertex.x, + vertex.y, + vertex.z + ) + ) + ) ) ) + }.bind(this)); + +}; + +/** + * Apply vertex data to geometry instance + * @param geometry + */ +GameLib.D3.Mesh.prototype.applyVertexDataToInstance = function(geometry) { + + if (this.vertices.length > 0) { + geometry.vertices = []; + this.vertices.map( + function(vertex) { + geometry.vertices.push( + new THREE.Vector3( + vertex.position.x, + vertex.position.y, + vertex.position.z + ) + ) + }.bind(this) + ); + geometry.verticesNeedUpdate = true; } - /** - * Setup faces - */ +}; + +/** + * Applies face data information to the geometry + * @param geometry + */ +GameLib.D3.Mesh.prototype.applyFaceDataToGeometry = function(geometry) { + for (var f = 0; f < this.faces.length; f++) { var face = new this.graphics.instance.Face3( @@ -239,12 +282,16 @@ GameLib.D3.Mesh.prototype.customGeometry = function(){ geometry.faces.push(face); } +}; + +/** + * Apply UV data to geometry instance + * @param geometry + */ +GameLib.D3.Mesh.prototype.applyUVDataToGeometry = function(geometry) { geometry.faceVertexUvs = []; - /** - * Setup face UVs - */ for (var fm = 0; fm < this.faceVertexUvs.length; fm++) { var faceMaterialVertexUvs = this.faceVertexUvs[fm]; @@ -269,137 +316,51 @@ GameLib.D3.Mesh.prototype.customGeometry = function(){ ); } } +}; - return geometry; +GameLib.D3.Mesh.prototype.applyBones = function(geometry) { + + /** + * Setup Bone Indexes + */ + this.skinIndices.map( + function(skinIndex) { + geometry.skinIndices.push( + new THREE.Vector4( + skinIndex.x, + skinIndex.y, + skinIndex.z, + skinIndex.w + ) + ); + } + ); + + /** + * Setup Bone Weights + */ + this.skinWeights.map( + function(skinWeight) { + geometry.skinWeights.push( + new THREE.Vector4( + skinWeight.x, + skinWeight.y, + skinWeight.z, + skinWeight.w + ) + ); + } + ); }; -/** - * Creates a mesh instance or updates it - */ -GameLib.D3.Mesh.prototype.createInstance = function(update) { +GameLib.D3.Mesh.prototype.createInstanceDefaults = function(instance) { - if (!this.loaded) { - console.log('Attempted to create an instance but the runtime object is not fully loaded : ' + this.name); - return null; - } + instance.name = this.name; - if (update) { - - if (this.parentMesh && this.parentMesh.loaded) { - - this.instance.parent = this.parentMesh.instance; - - this.instance.position.x = this.localPosition.x; - this.instance.position.y = this.localPosition.y; - this.instance.position.z = this.localPosition.z; - - this.instance.rotation.x = this.localRotation.x; - this.instance.rotation.y = this.localRotation.y; - this.instance.rotation.z = this.localRotation.z; - - this.instance.scale.x = this.localScale.x; - this.instance.scale.y = this.localScale.y; - this.instance.scale.z = this.localScale.z; - - } else { - 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.position.x = this.position.x + this.localPosition.x; - this.instance.position.y = this.position.y + this.localPosition.y; - this.instance.position.z = this.position.z + this.localPosition.z; - - this.instance.scale.x = this.scale.x * this.localScale.x; - this.instance.scale.y = this.scale.y * this.localScale.y; - this.instance.scale.z = this.scale.z * this.localScale.z; - - this.instance.up.x = this.up.x; - this.instance.up.y = this.up.y; - this.instance.up.z = this.up.z; - - this.instance.rotateX(this.localRotation.x); - this.instance.rotateY(this.localRotation.y); - this.instance.rotateZ(this.localRotation.z); - } - - this.instance.name = this.name; - - if (this.materials.length === 1 && this.materials[0].instance) { - this.instance.material = this.materials[0].instance; - } - - this.instance.renderOrder = this.renderOrder; - - this.instance.geometry.computeBoundingBox(); - - this.width = this.instance.geometry.boundingBox.max.x - this.instance.geometry.boundingBox.min.x; - this.height = this.instance.geometry.boundingBox.max.y - this.instance.geometry.boundingBox.min.y; - this.depth = this.instance.geometry.boundingBox.max.z - this.instance.geometry.boundingBox.min.z; - - } else { - - var instance = null; - var geometry = null; - - if (this instanceof GameLib.D3.Mesh.Sphere) { - geometry = this.sphereGeometry(); - } else { - geometry = this.customGeometry(); - } - - geometry.computeFaceNormals(); - geometry.computeVertexNormals(); - - if (this.meshType === GameLib.D3.Mesh.TYPE_NORMAL) { - instance = new THREE.Mesh(geometry); - } else if (this.meshType === GameLib.D3.Mesh.TYPE_CURVE) { - instance = new THREE.Points(geometry); - } else if (this.meshType === GameLib.D3.Mesh.TYPE_SKINNED) { - - /** - * Setup bones (indexes) - */ - for (var si = 0; si < this.skinIndices.length; si++) { - geometry.skinIndices.push( - new THREE.Vector4( - this.skinIndices[si].x, - this.skinIndices[si].y, - this.skinIndices[si].z, - this.skinIndices[si].w - ) - ); - } - - /** - * Setup bones (weights) - */ - for (var sw = 0; sw < this.skinWeights.length; sw++) { - geometry.skinWeights.push( - new THREE.Vector4( - this.skinWeights[sw].x, - this.skinWeights[sw].y, - this.skinWeights[sw].z, - this.skinWeights[sw].w - ) - ); - } - - instance = new THREE.SkinnedMesh(geometry); - - instance.add(this.skeleton.rootBoneInstance); - - instance.bind(this.skeleton.instance); - } else { - console.log('cannot handle meshes of type ' + this.meshType + ' yet.'); - } - - instance.name = this.name; - - if (this.parentMesh && this.parentMesh.loaded) { + if (this.parentMesh && this.parentMesh.loaded) { + if (this.parentMesh.loaded) { instance.parent = this.parentMesh.instance; instance.position.x = this.localPosition.x; @@ -413,80 +374,186 @@ GameLib.D3.Mesh.prototype.createInstance = function(update) { instance.scale.x = this.localScale.x; instance.scale.y = this.localScale.y; instance.scale.z = this.localScale.z; - } else { - instance.quaternion.x = this.quaternion.x; - instance.quaternion.y = this.quaternion.y; - instance.quaternion.z = this.quaternion.z; - instance.quaternion.w = this.quaternion.w; - - instance.position.x = this.position.x + this.localPosition.x; - instance.position.y = this.position.y + this.localPosition.y; - instance.position.z = this.position.z + this.localPosition.z; - - instance.scale.x = this.scale.x * this.localScale.x; - instance.scale.y = this.scale.y * this.localScale.y; - instance.scale.z = this.scale.z * this.localScale.z; - - instance.up.x = this.up.x; - instance.up.y = this.up.y; - instance.up.z = this.up.z; - - instance.rotateX(this.localRotation.x); - instance.rotateY(this.localRotation.y); - instance.rotateZ(this.localRotation.z); + console.warn('parent mesh not loaded at time of creating instance - provide callback here') } - if (this.materials.length === 1 && this.materials[0].instance) { - instance.material = this.materials[0].instance; - } + } else { - instance.renderOrder = this.renderOrder; + instance.quaternion.x = this.quaternion.x; + instance.quaternion.y = this.quaternion.y; + instance.quaternion.z = this.quaternion.z; + instance.quaternion.w = this.quaternion.w; - instance.geometry.computeBoundingBox(); + instance.position.x = this.position.x + this.localPosition.x; + instance.position.y = this.position.y + this.localPosition.y; + instance.position.z = this.position.z + this.localPosition.z; - this.width = instance.geometry.boundingBox.max.x - instance.geometry.boundingBox.min.x; - this.height = instance.geometry.boundingBox.max.y - instance.geometry.boundingBox.min.y; - this.depth = instance.geometry.boundingBox.max.z - instance.geometry.boundingBox.min.z; + instance.scale.x = this.scale.x * this.localScale.x; + instance.scale.y = this.scale.y * this.localScale.y; + instance.scale.z = this.scale.z * this.localScale.z; - this.subscribe( - GameLib.Event.MATERIAL_LOADED, - function(data) { + instance.up.x = this.up.x; + instance.up.y = this.up.y; + instance.up.z = this.up.z; - if (this.instance.material === data.material.instance) { - return; - } - - if (this.materials[0] === data.material) { - - if (this.instance.material !== data.material.instance) { - this.instance.material = data.material.instance; - } - - this.instance.geometry.uvsNeedUpdate = true; - } - } - ); - - this.subscribe( - GameLib.Event.MATERIAL_TYPE_CHANGED, - function(data) { - if (this.materials[0].id === data.material.id) { - this.instance.material = data.material.instance; - this.instance.geometry.uvsNeedUpdate = true; - } - } - ); - - return instance; + instance.rotateX(this.localRotation.x); + instance.rotateY(this.localRotation.y); + instance.rotateZ(this.localRotation.z); } + + if (this.materials.length === 1 && this.materials[0].instance) { + instance.material = this.materials[0].instance; + } + + instance.renderOrder = this.renderOrder; + + this.subscribe( + GameLib.Event.MATERIAL_LOADED, + function (data) { + + if (this.instance.material === data.material.instance) { + this.instance.geometry.uvsNeedUpdate = true; + return; + } + + if (this.materials[0] === data.material) { + + if (this.instance.material !== data.material.instance) { + this.instance.material = data.material.instance; + } + + this.instance.geometry.uvsNeedUpdate = true; + } + } + ); + + this.subscribe( + GameLib.Event.MATERIAL_TYPE_CHANGED, + function (data) { + if (this.materials[0].id === data.material.id) { + this.instance.material = data.material.instance; + this.instance.geometry.uvsNeedUpdate = true; + } + } + ); +}; + +/** + * Creates a mesh instance or updates it + */ +GameLib.D3.Mesh.prototype.createInstance = function() { + + if (!this.loaded) { + console.log('Attempted to create an instance but the runtime object is not fully loaded : ' + this.name); + return null; + } + + var geometry = new THREE.Geometry(); + + /** + * Setup vertices + */ + this.applyVertexDataToInstance(geometry); + + /** + * Setup faces + */ + this.applyFaceDataToGeometry(geometry); + + /** + * Setup face UVs + */ + this.applyUVDataToGeometry(geometry); + + /** + * Apply skin indices + */ + this.applyBones(geometry); + + /** + * Re-compute normals + */ + geometry.computeFaceNormals(); + geometry.computeVertexNormals(); + + var instance = null; + + if (this.skeleton) { + instance = new THREE.SkinnedMesh(geometry); + instance.add(this.skeleton.rootBoneInstance); + instance.bind(this.skeleton.instance); + } else { + instance = new THREE.Mesh(geometry); + } + + this.createInstanceDefaults(instance); + + return instance; }; /** * Updates the mesh instance */ GameLib.D3.Mesh.prototype.updateInstance = function() { - this.createInstance(true); + + if (this.parentMesh && this.parentMesh.loaded) { + + if (this.instance.parent !== this.parentMesh.instance) { + this.instance.parent = this.parentMesh.instance; + } + + this.instance.position.x = this.localPosition.x; + this.instance.position.y = this.localPosition.y; + this.instance.position.z = this.localPosition.z; + + this.instance.rotation.x = this.localRotation.x; + this.instance.rotation.y = this.localRotation.y; + this.instance.rotation.z = this.localRotation.z; + + this.instance.scale.x = this.localScale.x; + this.instance.scale.y = this.localScale.y; + this.instance.scale.z = this.localScale.z; + + } else { + + 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.position.x = this.position.x + this.localPosition.x; + this.instance.position.y = this.position.y + this.localPosition.y; + this.instance.position.z = this.position.z + this.localPosition.z; + + this.instance.scale.x = this.scale.x * this.localScale.x; + this.instance.scale.y = this.scale.y * this.localScale.y; + this.instance.scale.z = this.scale.z * this.localScale.z; + + this.instance.up.x = this.up.x; + this.instance.up.y = this.up.y; + this.instance.up.z = this.up.z; + + this.instance.rotateX(this.localRotation.x); + this.instance.rotateY(this.localRotation.y); + this.instance.rotateZ(this.localRotation.z); + } + + this.instance.name = this.name; + + if (this.materials.length === 1 && this.materials[0].instance) { + this.instance.material = this.materials[0].instance; + } + + this.instance.renderOrder = this.renderOrder; + // + // this.instance.geometry.computeBoundingBox(); + // + // if (this.meshType === GameLib.D3.Mesh.MESH_TYPE_NORMAL) { + // this.width = this.instance.geometry.boundingBox.max.x - this.instance.geometry.boundingBox.min.x; + // this.height = this.instance.geometry.boundingBox.max.y - this.instance.geometry.boundingBox.min.y; + // this.depth = this.instance.geometry.boundingBox.max.z - this.instance.geometry.boundingBox.min.z; + // } }; /** diff --git a/src/game-lib-d3-mesh-curve.js b/src/game-lib-d3-mesh-curve.js new file mode 100644 index 0000000..cb48592 --- /dev/null +++ b/src/game-lib-d3-mesh-curve.js @@ -0,0 +1,39 @@ +/** + * Mesh Superset - The apiMesh properties get moved into the Mesh object itself, and then the instance is created + * @param graphics GameLib.D3.Graphics + * @param apiMesh GameLib.D3.API.Mesh + * @constructor + */ +GameLib.D3.Mesh.Curve = function ( + graphics, + apiMesh +) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + GameLib.D3.Mesh.call( + this, + this.graphics, + apiMesh + ); +}; + +GameLib.D3.Mesh.Curve.prototype = Object.create(GameLib.D3.Mesh.prototype); +GameLib.D3.Mesh.Curve.prototype.constructor = GameLib.D3.Mesh.Curve; + + +GameLib.D3.Mesh.Curve.prototype.createInstance = function() { + + var geometry = new THREE.Geometry(); + + /** + * Setup vertices + */ + this.applyVertexDataToInstance(geometry); + + var instance = new THREE.Points(geometry); + + this.createInstanceDefaults(instance); + + return instance; +}; \ No newline at end of file diff --git a/src/game-lib-d3-mesh-plane.js b/src/game-lib-d3-mesh-plane.js new file mode 100644 index 0000000..ec7daf8 --- /dev/null +++ b/src/game-lib-d3-mesh-plane.js @@ -0,0 +1,205 @@ +/** + * Mesh Superset - The apiMesh properties get moved into the Mesh object itself, and then the instance is created + * @param graphics GameLib.D3.Graphics + * @param apiMesh GameLib.D3.API.Mesh + * @param width + * @param height + * @param widthSegments + * @param heightSegments + * @constructor + */ +GameLib.D3.Mesh.Plane = function ( + graphics, + apiMesh, + width, + height, + widthSegments, + heightSegments +) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (GameLib.Utils.UndefinedOrNull(width)) { + width = 1; + } + this.width = width; + + if (GameLib.Utils.UndefinedOrNull(height)) { + height = 1; + } + this.height = height; + + if (GameLib.Utils.UndefinedOrNull(widthSegments)) { + widthSegments = 1; + } + this.widthSegments = widthSegments; + + if (GameLib.Utils.UndefinedOrNull(heightSegments)) { + heightSegments = 1 + } + this.heightSegments = heightSegments; + + GameLib.D3.Mesh.call( + this, + this.graphics, + apiMesh + ); +}; + +GameLib.D3.Mesh.Plane.prototype = Object.create(GameLib.D3.Mesh.prototype); +GameLib.D3.Mesh.Plane.prototype.constructor = GameLib.D3.Mesh.Plane; + + +GameLib.D3.Mesh.Plane.prototype.createInstance = function(update) { + + var geometry = new THREE.PlaneGeometry( + this.width, + this.height, + this.widthSegments, + this.heightSegments + ); + + /** + * If this geometry is coming from the database, apply the vertex data + */ + if (this.vertices.length > 0) { + this.applyVertexDataToInstance(geometry); + } else { + this.updateVerticesFromGeometryInstance(geometry); + } + + this.applyBones(geometry); + + var instance = null; + + if (this.skeleton) { + instance = new THREE.SkinnedMesh(geometry) + } else { + instance = new THREE.Mesh(geometry); + } + + instance.userData.width = this.width; + instance.userData.height = this.height; + instance.userData.widthSegments = this.widthSegments; + instance.userData.heightSegments = this.heightSegments; + + this.createInstanceDefaults(instance); + + return instance; +}; + +GameLib.D3.Mesh.Plane.prototype.updateInstance = function() { + + if ( + this.instance.userData.width !== this.width || + this.instance.userData.height !== this.height || + this.instance.userData.widthSegments !== this.widthSegments || + this.instance.userData.heightSegments !== this.heightSegments + ) { + var geometry = new THREE.PlaneGeometry( + this.width, + this.height, + this.widthSegments, + this.heightSegments + ); + + this.instance.geometry = geometry; + + this.updateVerticesFromGeometryInstance(geometry); + } + + GameLib.D3.Mesh.prototype.updateInstance.call(this); +}; + +/** + * Converts a GameLib.D3.Mesh to a GameLib.D3.API.Mesh + * @returns {GameLib.D3.API.Mesh} + */ +GameLib.D3.Mesh.Plane.prototype.toApiObject = function() { + + var apiMesh = GameLib.D3.Mesh.prototype.toApiObject.call(this); + + apiMesh.width = this.width; + apiMesh.height = this.height; + apiMesh.widthSegments = this.widthSegments; + apiMesh.heightSegments = this.heightSegments; + + return apiMesh; +}; + +/** + * TODO fix all this weird loading shit + * Converts a standard object mesh to a GameLib.D3.Mesh + * @param graphics GameLib.D3.Graphics + * @param objectMesh {Object} + * @constructor + */ +GameLib.D3.Mesh.Plane.FromObject = function(graphics, objectMesh) { + + var apiMesh = GameLib.D3.API.Mesh.FromObject(objectMesh); + + return new GameLib.D3.Mesh.Plane( + graphics, + apiMesh, + objectMesh.width, + objectMesh.height, + objectMesh.widthSegments, + objectMesh.heightSegments + ); + +}; + +GameLib.D3.Mesh.Plane.prototype.getHeightData = function(img,scale) { + + if (GameLib.Utils.UndefinedOrNull(scale)) { + scale = 1; + } + + if (GameLib.Utils.UndefinedOrNull(img)) { + img = this.instance.material.bumpMap.image; + } + + var canvas = document.createElement( 'canvas' ); + canvas.width = img.width; + canvas.height = img.height; + var context = canvas.getContext( '2d' ); + + var size = img.width * img.height; + var data = new Float32Array( size ); + + context.drawImage(img,0,0); + + for ( var i = 0; i < size; i ++ ) { + data[i] = 0 + } + + var imgd = context.getImageData(0, 0, img.width, img.height); + var pix = imgd.data; + + var j=0; + for (var i = 0; i 0) { + geometry = new THREE.Geometry(); + this.applyVertexDataToInstance(geometry); + } else { + geometry = new THREE.SphereGeometry( + this.radius, + this.widthSegments, + this.heightSegments + ); + this.updateVerticesFromGeometryInstance(geometry); + } + + this.applyBones(geometry); + + var instance = null; + + if (this.skeleton) { + instance = new THREE.SkinnedMesh(geometry) + } else { + instance = new THREE.Mesh(geometry); + } + + instance.userData.radius = this.radius; + instance.userData.widthSegments = this.widthSegments; + instance.userData.heightSegments = this.heightSegments; + + this.createInstanceDefaults(instance); + + return instance; +}; + +GameLib.D3.Mesh.Sphere.prototype.updateInstance = function() { + + if ( + this.instance.userData.widthSegments !== this.widthSegments || + this.instance.userData.heightSegments !== this.heightSegments || + this.instance.userData.radius !== this.radius + ) { + var geometry = new THREE.SphereGeometry( + this.radius, + this.widthSegments, + this.heightSegments + ); + + this.instance.geometry = geometry; + + this.updateVerticesFromGeometryInstance(geometry); + } + + GameLib.D3.Mesh.prototype.updateInstance.call(this); -GameLib.D3.Mesh.Sphere.prototype.sphereGeometry = function() { - return new THREE.SphereGeometry( - this.radius, - this.widthSegments, - this.heightSegments - ); }; /** diff --git a/src/game-lib-entity.js b/src/game-lib-entity.js index 073710b..23887f1 100644 --- a/src/game-lib-entity.js +++ b/src/game-lib-entity.js @@ -67,12 +67,17 @@ GameLib.Entity.prototype.addComponent = function(component) { */ component.buildIdToObject(); + /** + * Also add the child components of this component as components of this entity + */ for (var property in component.idToObject) { - if (component.idToObject.hasOwnProperty(property)) { - if (component.idToObject[property] instanceof GameLib.Component) { - this.components.push(component.idToObject[property]); - component.idToObject[property].parentEntity = this; - } + if (component.idToObject.hasOwnProperty(property) && + component.idToObject[property] !== component && + component.idToObject[property] instanceof GameLib.Component && + this.components.indexOf(component.idToObject[property] === -1) + ) { + this.components.push(component.idToObject[property]); + component.idToObject[property].parentEntity = this; } } diff --git a/src/game-lib-gui.js b/src/game-lib-gui.js index fd3fa2c..1feb735 100644 --- a/src/game-lib-gui.js +++ b/src/game-lib-gui.js @@ -302,9 +302,11 @@ GameLib.GUI.prototype.buildControl = function(folder, object, property, entityMa object, property, { - 'normal' : GameLib.D3.Mesh.TYPE_NORMAL, - 'curve' : GameLib.D3.Mesh.TYPE_CURVE, - 'skinned' : GameLib.D3.Mesh.TYPE_SKINNED + 'normal' : GameLib.D3.Mesh.MESH_TYPE_NORMAL, + 'curve' : GameLib.D3.Mesh.MESH_TYPE_CURVE, + 'skinned' : GameLib.D3.Mesh.MESH_TYPE_SKINNED, + 'plane' : GameLib.D3.Mesh.MESH_TYPE_PLANE, + 'sphere' : GameLib.D3.Mesh.MESH_TYPE_SPHERE } ).name(property).listen() ); @@ -616,12 +618,17 @@ GameLib.GUI.prototype.buildControl = function(folder, object, property, entityMa ) { handles.push(folder.add(object, property, 0, 5).step(0.001).name(property).listen()); } else if ( + property === 'widthSegments' || + property === 'heightSegments' + ) { + handles.push(folder.add(object, property, 1, 1000).step(1).name(property).listen()); + } else if ( property === 'angle' || - // property == 'width' || - // property == 'height' || + property === 'width' || + property === 'height' || property === 'depth' ) { - handles.push(folder.add(object, property, -Math.PI, Math.PI).step(0.0001).name(property).listen()); + handles.push(folder.add(object, property, -1000, 1000).step(1).name(property).listen()); } else if ( property === 'near' || property === 'distanceGrain' || @@ -791,13 +798,19 @@ GameLib.GUI.prototype.buildControl = function(folder, object, property, entityMa GameLib.GUI.prototype.buildVectorControl = function(folder, object, property, dimension) { + var step = 0.1; + + if (property === 'localRotation') { + step = 0.001; + } + if (dimension === 4) { folder.add( object[property], 'w', -100, 100 - ).name(property + '.w').listen().step(0.1).onChange( + ).name(property + '.w').listen().step(step).onChange( function() { object.updateInstance(); } @@ -809,7 +822,7 @@ GameLib.GUI.prototype.buildVectorControl = function(folder, object, property, di 'x', -100, 100 - ).name(property + '.x').listen().step(0.1).onChange( + ).name(property + '.x').listen().step(step).onChange( function() { object.updateInstance(); } @@ -820,7 +833,7 @@ GameLib.GUI.prototype.buildVectorControl = function(folder, object, property, di 'y', -100, 100 - ).name(property + '.y').listen().step(0.1).onChange( + ).name(property + '.y').listen().step(step).onChange( function() { object.updateInstance(); } @@ -835,7 +848,7 @@ GameLib.GUI.prototype.buildVectorControl = function(folder, object, property, di 'z', -100, 100 - ).name(property + '.z').listen().step(0.1).onChange( + ).name(property + '.z').listen().step(step).onChange( function() { object.updateInstance(); }