UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

118 lines (83 loc) 3.19 kB
import { UintArrayForCount } from "../../../../core/collection/array/typed/uint_array_for_count.js"; import { geometry_compute_vertex_normals_indexed } from "./geometry_compute_vertex_normals_indexed.js"; /** * * @param {Sampler2D} samplerHeight * @param {Vector2} position * @param {Vector2} size * @param {Vector2} scale * @param {Vector2} totalSize * @param {number} resolution * @returns {{indices, vertices: Float32Array, normals: Float32Array, uvs: Float32Array}} */ export function build_height_field_geometry(samplerHeight, position, size, scale, totalSize, resolution) { const width = size.x; const height = size.y; const gridX1 = width * resolution; const gridY1 = height * resolution; const gridX2 = gridX1 - 1; const gridY2 = gridY1 - 1; let offset = 0, offset2 = 0; const vertexCount = gridX1 * gridY1; const vertices = new Float32Array(vertexCount * 3); const normals = new Float32Array(vertexCount * 3); const uvs = new Float32Array(vertexCount * 2); let y, x; const vMultiplier = (size.y / totalSize.y) / gridY2; const uMultiplier = (size.x / totalSize.x) / gridX2; const vConst = position.y / totalSize.y; const uConst = position.x / totalSize.x; const totalScaledSizeX = totalSize.x * scale.x; const totalScaledSizeY = totalSize.y * scale.y; //fill vertices let px, py, pz; for (y = 0; y < gridY1; y++) { const v = y * vMultiplier + vConst; pz = v * totalScaledSizeY; for (x = 0; x < gridX1; x++) { const u = x * uMultiplier + uConst; //get height sample const val = samplerHeight.sampleChannelBicubicUV(u, v, 0); px = u * totalScaledSizeX; py = val; vertices[offset] = px; vertices[offset + 1] = py; vertices[offset + 2] = pz; uvs[offset2] = u; uvs[offset2 + 1] = v; offset += 3; offset2 += 2; } } offset = 0; const IndexArray = UintArrayForCount(vertices.length / 3); /** * @type {Uint8Array|Uint16Array|Uint32Array} */ const indices = new IndexArray(gridX2 * gridY2 * 6); //add faces //TODO TraingleStip mode is more efficient in terms of memory usage and probably GPU-time for (y = 0; y < gridY2; y++) { for (x = 0; x < gridX2; x++) { const a = x + gridX1 * y; const b = x + gridX1 * (y + 1); const c = (x + 1) + gridX1 * (y + 1); const d = (x + 1) + gridX1 * y; indices[offset] = a; indices[offset + 1] = b; indices[offset + 2] = d; indices[offset + 3] = b; indices[offset + 4] = c; indices[offset + 5] = d; offset += 6; } } geometry_compute_vertex_normals_indexed(vertices, normals, indices); //CleanupGeometry(geometry); return { indices: indices, vertices: vertices, normals: normals, uvs: uvs }; }