/** * Mesh Superset - The apiMesh properties get moved into the Mesh object itself, and then the instance is created * @param graphics R3.GraphicsRuntime * @param apiMeshPlane * @constructor */ R3.D3.Mesh.Plane = function ( graphics, apiMeshPlane ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); if (R3.Utils.UndefinedOrNull(apiMeshPlane)) { apiMeshPlane = { meshType : R3.D3.API.Mesh.MESH_TYPE_PLANE }; } R3.D3.API.Mesh.Plane.call( this, apiMeshPlane, apiMeshPlane.width, apiMeshPlane.height, apiMeshPlane.widthSegments, apiMeshPlane.heightSegments, apiMeshPlane.heightMapScale, apiMeshPlane.isHeightMap, apiMeshPlane.isDotMap, apiMeshPlane.dotMapScale, apiMeshPlane.dotMapOffset, apiMeshPlane.dotMapWeight, apiMeshPlane.dotObject ); this.dotMapScale = new R3.Vector3( this.graphics, this.dotMapScale, this ); this.dotMapOffset = new R3.Vector3( this.graphics, this.dotMapOffset, this ); this.dotMapWeight = new R3.Vector3( this.graphics, this.dotMapWeight, this ); this.dots = []; R3.D3.Mesh.call( this, graphics, apiMeshPlane ); }; R3.D3.Mesh.Plane.prototype = Object.create(R3.D3.Mesh.prototype); R3.D3.Mesh.Plane.prototype.constructor = R3.D3.Mesh.Plane; R3.D3.Mesh.Plane.prototype.createInstance = function() { var geometry = null; /** * If this geometry is not coming from the database, apply the vertex data from the instance to our runtime object */ if (this.vertices.length === 0) { geometry = new THREE.PlaneGeometry( this.width, this.height, this.widthSegments, this.heightSegments ); this.updateVerticesFromGeometryInstance(geometry); /** * If this is a heightmap - first generate the z-coordinates */ if (this.isHeightMap) { this.generateHeightMapFromBumpMap(); } } /** * Now construct the mesh instance */ R3.D3.Mesh.prototype.createInstance.call(this); if (this.isDotMap && this.dotObject) { this.generateDotMap(); } }; /** * */ R3.D3.Mesh.Plane.prototype.updateInstance = function(property) { var geometry = null; if ( property === 'width' || property === 'height' || property === 'widthSegments' || property === 'heightSegments' || property === 'isHeightMap' || property === 'heightMapScale' ) { geometry = new THREE.PlaneGeometry( this.width, this.height, this.widthSegments, this.heightSegments ); this.updateVerticesFromGeometryInstance(geometry); if (this.isHeightMap) { this.generateHeightMapFromBumpMap(); } geometry = this.createInstanceGeometry(); this.instance.geometry = geometry; } if ( property === 'isDotMap' || property === 'dotMapScale' || property === 'dotMapOffset' || property === 'dotMapWeight' || property === 'dotObject' ) { this.dots.map( function(dot){ this.parentScene.instance.remove(dot); dot.geometry.dispose(); dot.material.dispose(); }.bind(this) ); if (this.isDotMap) { this.generateDotMap(); } } R3.D3.Mesh.prototype.updateInstance.call(this, property); }; /** * Converts a R3.D3.Mesh.Plane to a R3.D3.API.Mesh.Plane * @returns {R3.D3.API.Mesh.Plane} */ R3.D3.Mesh.Plane.prototype.toApiObject = function() { var apiMesh = R3.D3.Mesh.prototype.toApiObject.call(this); var apiMeshPlane = new R3.D3.API.Mesh.Plane( apiMesh, this.width, this.height, this.widthSegments, this.heightSegments, this.heightMapScale, this.isHeightMap, this.isDotMap, this.dotMapScale.toApiObject(), this.dotMapOffset.toApiObject(), this.dotMapWeight.toApiObject(), R3.Utils.IdOrNull(this.dotObject) ); return apiMeshPlane; }; R3.D3.Mesh.Plane.prototype.generateDotMap = function() { this.dots = []; var data = this.getHeightData(); var width = Math.sqrt(data.length); var height = width; for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++ ) { var z = data[(y * width) + x]; if (z < 0.1) { continue; } var geometry; var material; if (this.dotObject) { geometry = this.dotObject.instance.geometry.clone(); material = this.dotObject.materials[0].instance; } else { geometry = new THREE.BoxBufferGeometry(0.5, 0.5, 0.5); material = this.materials[0].instance; } var dot = new THREE.Mesh(geometry, material); dot.name = 'dot ' + this.dots.length; dot.position.x = x * this.dotMapWeight.x + this.dotMapOffset.x; dot.position.y = height - (y * this.dotMapWeight.y + this.dotMapOffset.y); dot.position.z = z * this.dotMapWeight.z + this.dotMapOffset.z; dot.scale.x = z * this.dotMapScale.x + 0.00001; dot.scale.y = z * this.dotMapScale.y + 0.00001; dot.scale.z = z * this.dotMapScale.z + 0.00001; this.parentScene.instance.add(dot); this.dots.push(dot); } } }; /** * * @returns {THREE.PlaneGeometry} */ R3.D3.Mesh.Plane.prototype.generateHeightMapFromBumpMap = function() { var data = this.getHeightData(); this.vertices.map( function(vertex, index) { vertex.position.z = data[index]; } ); // var geometry = this.createInstanceGeometry(); // // this.instance.geometry = geometry; // // var vertices = this.instance.geometry.attributes.position.array; // // for ( var i = 0; i < vertices.length; i += 3 ) { // vertices[i+2] = data[i]; // } // // this.instance.geometry.attributes.position.needsUpdate = true; //this.updateVerticesFromGeometryInstance(this.instance.geometry); // this.updateInstance(); }; R3.D3.Mesh.Plane.prototype.createPhysicsObjects = function() { R3.Event.Emit( R3.Event.GET_PHYSICS_RUNTIME, null, function(physics){ /** * Create the plane shape * @type {R3.D3.API.Shape} */ var apiShapePlane = new R3.D3.API.Shape( null, 'Shape Plane (' + this.name + ')' ); apiShapePlane.parentMesh = this; var shapePlane = new R3.D3.Shape.Plane( physics, apiShapePlane ); var apiRigidBody = new R3.D3.API.RigidBody( null, 'Rigid Body (' + this.name + ')', 0, null, new R3.API.Vector3( this.position.x, this.position.y, this.position.z ), new R3.API.Quaternion( this.quaternion.x, this.quaternion.y, this.quaternion.z, this.quaternion.w, new R3.API.Vector3( this.quaternion.axis.x, this.quaternion.axis.y, this.quaternion.axis.z ), this.quaternion.angle ) ); apiRigidBody.shapes.push(shapePlane); apiRigidBody.parentMesh = this; /** * Construct the rigid body * @type {R3.D3.RigidBody} */ var rigidBody = new R3.D3.RigidBody( physics, apiRigidBody ); if (this.parentEntity instanceof R3.Entity) { this.parentEntity.addComponent(shapePlane); this.parentEntity.addComponent(rigidBody); } }.bind(this), function(error){ console.log(error.message); throw new Error(error.message); } ); };