/** * @param sizeX Number * @param sizeY Number * @param matrix matrix 2D Array with height data (Column Major) * @param elementSize Number * @param heightScale Number * @constructor */ R3.D3.Heightmap = function Heightmap( sizeX, sizeY, matrix, elementSize, heightScale ) { if (typeof sizeX == 'undefined') { sizeX = 0; } this.sizeX = sizeX; if (typeof sizeY == 'undefined') { sizeY = 0; } this.sizeY = sizeY; if (typeof matrix == 'undefined') { matrix = []; } this.matrix = matrix; if (typeof elementSize == 'undefined') { elementSize = 10; } this.elementSize = elementSize; if (typeof heightScale == 'undefined') { heightScale = 15; } this.elementSize = heightScale; }; R3.D3.Heightmap.prototype.toApiHeightMap = function() { //TODO - create API heightmap someday return { sizeX: this.sizeX, sizeY: this.sizeY, matrix: this.matrix, elementSize: this.elementSize, heightScale: this.heightScale } }; /** * Creates a graphics instance mesh from the graphics, physics and physics shape * @param graphics R3.D3.Graphics * @param shape R3.D3.Shape * @param engine R3.D3.Engine * @returns {THREE.Mesh|this.meshes} */ R3.D3.Heightmap.GenerateInstanceMesh = function( graphics, shape, engine ) { graphics.isNotThreeThrow(); engine.isNotCannonThrow(); var geometry = new graphics.instance.Geometry(); var v0 = new engine.instance.Vec3(); var v1 = new engine.instance.Vec3(); var v2 = new engine.instance.Vec3(); for (var xi = 0; xi < shape.instance.data.length - 1; xi++) { for (var yi = 0; yi < shape.instance.data[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); geometry.vertices.push( new graphics.instance.Vector3(v0.x, v0.y, v0.z), new graphics.instance.Vector3(v1.x, v1.y, v1.z), new graphics.instance.Vector3(v2.x, v2.y, v2.z) ); var i = geometry.vertices.length - 3; geometry.faces.push(new graphics.instance.Face3(i, i+1, i+2)); } } } geometry.computeBoundingSphere(); geometry.computeFaceNormals(); return new graphics.instance.Mesh( geometry, new graphics.instance.MeshNormalMaterial( { wireframe: false, shading : graphics.instance.SmoothShading } ) ); }; /** * Needs an RGBA * @param imagePath string * @param heightScale * @param callback * @constructor */ R3.D3.Heightmap.GenerateHeightmapDataFromImage = function ( imagePath, heightScale, callback ) { var img = new Image(); img.onload = function () { var canvas = document.createElement('canvas'); canvas.width = img.width; canvas.height = img.height; var context = canvas.getContext('2d'); context.drawImage(img, 0, 0); var imgd = context.getImageData(0, 0, img.width, img.height); var pixels = imgd.data; var heightList = []; for (var i = 0, n = pixels.length; i < n; i += (4)) { heightList.push(pixels[i]); } var matrix = []; var sizeX = img.width, sizeY = img.height; for (var x = 0; x < sizeX; x++) { matrix.push([]); for (var j = 0; j < sizeY; j++) { var height = (heightList[(sizeX - x) + j * sizeY] / 255) * heightScale; matrix[x].push(height); } } // todo: delete canvas here callback( new R3.D3.Heightmap( sizeX, sizeY, matrix, 10, heightScale ) ); }; img.src = imagePath; };