@adatechnology/game-terrain-three 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +20 -2
- package/dist/index.d.ts +50 -0
- package/dist/index.global.js +682 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +652 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/renderer.ts","../src/surface-material.ts","../src/chunk-geometry.ts","../src/layers.ts","../src/rebar.ts","../src/test-module.ts","../src/locale.ts"],"sourcesContent":["import type * as THREE_NS from 'three'\nimport { markKitOrigin } from '@adatechnology/game-contracts'\nimport type { Terrain, TerrainChunk } from '@adatechnology/game-terrain'\nimport { buildChunkGeometry, buildPristineGeometry } from './chunk-geometry'\nimport { createDebrisLayer, createMarkLayer } from './layers'\nimport { buildRebarGeometry } from './rebar'\nimport { createSurfaceMaterial } from './surface-material'\n\ntype ThreeLib = typeof THREE_NS\n\nexport interface TerrainRendererOptions {\n readonly terrain: Terrain\n /** Beyond this distance in metres a dug chunk draws half its vertices (default 30), twice this a quarter. */\n readonly lodDistance?: number\n /** Marks farther than this in metres are not drawn (default 45). */\n readonly markDistance?: number\n /** Metres the untouched ground goes on beyond the terrain, so that it has no edge in sight (default 300). */\n readonly skirt?: number\n}\n\nexport interface TerrainRenderer {\n readonly group: THREE_NS.Group\n /** Call every frame with the camera's position. Redraws at most the terrain's budget of chunks. */\n sync(camera: { readonly x: number; readonly y: number; readonly z: number }): void\n /** What is on the screen, for a bench. */\n stats(): { readonly chunkMeshes: number; readonly pristineChunks: number; readonly marksDrawn: number; readonly debrisDrawn: number }\n dispose(): void\n}\n\nconst DEFAULT_LOD_DISTANCE = 30\nconst DEFAULT_MARK_DISTANCE = 45\nconst DEFAULT_SKIRT = 300\nconst LOD_CHECK_METRES = 4\nconst REBAR_COLOUR = 0x4a3528\n\ninterface DrawnChunk {\n mesh: THREE_NS.Mesh\n rebar: THREE_NS.Mesh | null\n step: number\n}\n\n/** The ground of a `Terrain`: chunks nobody touched share one flat geometry, a dug one gets a mesh of its own that gets simpler far away. */\nexport function createTerrainRenderer(THREE: ThreeLib, options: TerrainRendererOptions): TerrainRenderer {\n const { terrain } = options\n const lodDistance = options.lodDistance ?? DEFAULT_LOD_DISTANCE\n const skirt = options.skirt ?? DEFAULT_SKIRT\n const group = markKitOrigin(new THREE.Group(), { owner: 'game-terrain-three', kind: 'ground' })\n group.name = 'floor'\n const surface = createSurfaceMaterial(THREE)\n const rebarMaterial = new THREE.MeshStandardMaterial({ color: REBAR_COLOUR, roughness: 0.75, metalness: 0.35 })\n const pristineMesh = new THREE.Mesh(new THREE.BufferGeometry(), surface)\n pristineMesh.receiveShadow = true\n pristineMesh.name = 'terrain-pristine'\n pristineMesh.frustumCulled = false\n group.add(pristineMesh)\n const drawn = new Map<number, DrawnChunk>()\n const marks = createMarkLayer(THREE, terrain, options.markDistance ?? DEFAULT_MARK_DISTANCE)\n const debris = createDebrisLayer(THREE, terrain)\n group.add(marks.mesh, debris.mesh)\n let pristineStale = true\n let pristineCount = 0\n let lodX = Infinity\n let lodZ = Infinity\n let firstSync = true\n\n const distanceTo = (chunk: TerrainChunk, camera: { x: number; z: number }): number => {\n const half = (chunk.cells * terrain.cellSize) / 2\n const centreX = terrain.bounds[0] + chunk.column * terrain.cellSize + half\n const centreZ = terrain.bounds[1] + chunk.row * terrain.cellSize + half\n return Math.hypot(centreX - camera.x, centreZ - camera.z)\n }\n const stepFor = (distance: number): number => (distance > lodDistance * 2 ? 4 : distance > lodDistance ? 2 : 1)\n\n function drop(index: number): void {\n const entry = drawn.get(index)\n if (!entry) return\n group.remove(entry.mesh)\n entry.mesh.geometry.dispose()\n if (entry.rebar) {\n group.remove(entry.rebar)\n entry.rebar.geometry.dispose()\n }\n drawn.delete(index)\n }\n\n function draw(chunk: TerrainChunk, camera: { x: number; z: number }): void {\n drop(chunk.index)\n const step = stepFor(distanceTo(chunk, camera))\n const mesh = new THREE.Mesh(buildChunkGeometry(THREE, terrain, chunk, step), surface)\n mesh.receiveShadow = true\n group.add(mesh)\n const bars = buildRebarGeometry(THREE, terrain, chunk)\n let rebar: THREE_NS.Mesh | null = null\n if (bars) {\n rebar = new THREE.Mesh(bars, rebarMaterial)\n rebar.castShadow = true\n group.add(rebar)\n }\n drawn.set(chunk.index, { mesh, rebar, step })\n }\n\n function rebuildPristine(): void {\n const chunks: TerrainChunk[] = []\n for (let index = 0; index < terrain.chunksX * terrain.chunksZ; index++) {\n const chunk = terrain.chunk(index)\n if (chunk.pristine) chunks.push(chunk)\n }\n pristineMesh.geometry.dispose()\n pristineMesh.geometry = buildPristineGeometry(THREE, terrain, chunks, skirt)\n pristineCount = chunks.length\n pristineStale = false\n }\n\n return {\n group,\n sync(camera) {\n // the first picture and a floor just laid have every chunk dirty: pristine ones need no work of their own, the rest are drawn at once so that the floor never has holes\n const limit = firstSync ? Infinity : undefined\n firstSync = false\n for (const chunk of terrain.drainDirtyChunks(limit)) {\n if (chunk.pristine) {\n if (drawn.has(chunk.index)) drop(chunk.index)\n pristineStale = true\n } else {\n if (!drawn.has(chunk.index)) pristineStale = true\n draw(chunk, camera)\n }\n }\n if (pristineStale) rebuildPristine()\n if (Math.hypot(camera.x - lodX, camera.z - lodZ) > LOD_CHECK_METRES) {\n lodX = camera.x\n lodZ = camera.z\n for (const [index, entry] of drawn) {\n const chunk = terrain.chunk(index)\n if (stepFor(distanceTo(chunk, camera)) !== entry.step) draw(chunk, camera)\n }\n }\n marks.sync(camera)\n debris.sync()\n },\n stats: () => ({ chunkMeshes: drawn.size, pristineChunks: pristineCount, marksDrawn: marks.mesh.count, debrisDrawn: debris.mesh.count }),\n dispose() {\n for (const index of [...drawn.keys()]) drop(index)\n pristineMesh.geometry.dispose()\n surface.dispose()\n rebarMaterial.dispose()\n marks.dispose()\n debris.dispose()\n group.removeFromParent()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport { TERRAIN_PATTERNS } from '@adatechnology/game-terrain'\n\ntype ThreeLib = typeof THREE_NS\n\n/** Index of a pattern in the shader's branches. */\nexport const patternIndex = (pattern: string | undefined): number => Math.max(0, TERRAIN_PATTERNS.indexOf((pattern ?? 'plain') as (typeof TERRAIN_PATTERNS)[number]))\n\nconst SURFACE_GLSL = /* glsl */ `\nfloat tsHash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); }\nfloat tsNoise(vec2 p) {\n vec2 i = floor(p); vec2 f = fract(p); f = f * f * (3.0 - 2.0 * f);\n return mix(mix(tsHash(i), tsHash(i + vec2(1.0, 0.0)), f.x), mix(tsHash(i + vec2(0.0, 1.0)), tsHash(i + vec2(1.0, 1.0)), f.x), f.y);\n}\nfloat tsFbm(vec2 p) { return tsNoise(p) * 0.55 + tsNoise(p * 2.3 + 7.1) * 0.3 + tsNoise(p * 5.1 + 3.3) * 0.15; }\nfloat tsLine(float value, float period, float width) { float d = abs(fract(value / period + 0.5) - 0.5) * period; return 1.0 - smoothstep(width * 0.6, width, d); }\nvec3 terrainSurface(vec3 base, vec2 xz, float kind) {\n float k = floor(kind + 0.5);\n if (k < 0.5) return base * (0.86 + 0.28 * tsFbm(xz * 9.0));\n if (k < 1.5) {\n float blades = tsNoise(xz * vec2(70.0, 55.0)) * 0.6 + tsNoise(xz * 22.0) * 0.4;\n float patches = tsFbm(xz * 1.3);\n return base * (0.55 + 0.8 * blades) * mix(vec3(1.25, 1.05, 0.7), vec3(0.8, 1.1, 0.85), patches);\n }\n if (k < 2.5) return base * (0.6 + 0.75 * tsFbm(xz * 6.0)) * (0.82 + 0.36 * tsNoise(xz * 48.0));\n if (k < 3.5) return base * (0.88 + 0.12 * sin(xz.x * 22.0 + tsFbm(xz * 2.0) * 9.0)) * (0.92 + 0.16 * tsNoise(xz * 90.0));\n if (k < 4.5) { float grain = tsNoise(xz * 120.0); return base * (0.55 + 1.1 * grain * grain) * (0.85 + 0.3 * tsFbm(xz * 0.8)); }\n if (k < 5.5) {\n float joint = max(tsLine(xz.x, 3.0, 0.012), tsLine(xz.y, 3.0, 0.012));\n return base * (0.82 + 0.3 * tsFbm(xz * 3.5)) * (0.94 + 0.12 * tsNoise(xz * 130.0)) * (1.0 - 0.6 * joint);\n }\n if (k < 6.5) {\n vec2 cell = floor(xz / 0.6);\n float grout = max(tsLine(xz.x, 0.6, 0.006), tsLine(xz.y, 0.6, 0.006));\n return mix(base * (0.93 + 0.14 * tsHash(cell)) * (0.97 + 0.06 * tsFbm(xz * 7.0)), vec3(0.14, 0.13, 0.12), grout);\n }\n if (k < 7.5) {\n float row = floor(xz.y / 0.14);\n float along = xz.x + tsHash(vec2(row, 3.0)) * 2.4;\n float seam = max(tsLine(xz.y, 0.14, 0.004), tsLine(along, 2.4, 0.004));\n float grain = tsNoise(vec2(along * 3.0, xz.y * 70.0)) * 0.6 + tsNoise(vec2(along * 11.0, xz.y * 180.0)) * 0.4;\n return base * (0.72 + 0.56 * tsHash(vec2(row, floor(along / 2.4)))) * (0.75 + 0.5 * grain) * (1.0 - 0.75 * seam);\n }\n vec2 cell = floor(xz / 0.22);\n float seams = max(tsLine(xz.x, 0.22, 0.012), tsLine(xz.y, 0.22, 0.012));\n return base * (0.7 + 0.6 * tsHash(cell)) * (0.85 + 0.3 * tsFbm(xz * 16.0)) * (1.0 - 0.55 * seams);\n}\n`\n\n/** The ground's material: the colour of what is exposed comes per vertex, flat so that the edge between two materials stays sharp, its pattern (blades of grass, grout, planks) is drawn per pixel from the world position so that it never tiles or stretches. */\nexport function createSurfaceMaterial(THREE: ThreeLib): THREE_NS.MeshStandardMaterial {\n const material = new THREE.MeshStandardMaterial({ roughness: 0.95, metalness: 0 })\n material.onBeforeCompile = (shader) => {\n shader.vertexShader = shader.vertexShader\n .replace('#include <common>', '#include <common>\\nattribute float aPattern;\\nattribute vec3 aBase;\\nattribute vec2 aShade;\\nflat varying float vPattern;\\nflat varying vec3 vBase;\\nvarying vec2 vShade;\\nvarying vec2 vGroundXZ;')\n .replace('#include <begin_vertex>', '#include <begin_vertex>\\nvPattern = aPattern;\\nvBase = aBase;\\nvShade = aShade;\\nvGroundXZ = position.xz;')\n shader.fragmentShader = shader.fragmentShader\n .replace('#include <common>', `#include <common>\\nflat varying float vPattern;\\nflat varying vec3 vBase;\\nvarying vec2 vShade;\\nvarying vec2 vGroundXZ;\\n${SURFACE_GLSL}`)\n .replace('#include <color_fragment>', '#include <color_fragment>\\ndiffuseColor.rgb = mix(terrainSurface(vBase, vGroundXZ, vPattern), vec3(0.012, 0.011, 0.01), vShade.y) * vShade.x;')\n }\n material.customProgramCacheKey = () => 'game-terrain-surface'\n return material\n}\n","import type * as THREE_NS from 'three'\nimport type { Terrain, TerrainChunk } from '@adatechnology/game-terrain'\nimport { patternIndex } from './surface-material'\n\ntype ThreeLib = typeof THREE_NS\n\n/** Metres over which the raw colour of a dug layer darkens: the bottom of a hole gets little light. */\nconst DEPTH_SHADE = 1.6\nconst MIN_DEPTH_LIGHT = 0.55\nconst LOOSE_VISIBLE = 0.004\n/** A skin thinner than this (turf, asphalt) is not what comes out of a hole: what is under it is. */\nconst THIN_SKIN = 0.1\nconst SKIRT_QUADS = 4\nconst BROKEN_DEPTH = 0.004\nconst BROKEN_TONE = 0.62\n\n/** What a vertex shows: the colour and pattern of what is exposed or heaped on it, sharp at the edge between materials, and its light and burn, which blend. */\nfunction vertexLook(terrain: Terrain, column: number, row: number, base: [number, number, number], shade: [number, number]): number {\n const index = row * terrain.stride + column\n let material = terrain.vertexMaterial(column, row)\n if (terrain.loose[index]! > LOOSE_VISIBLE) {\n const profile = terrain.profileList[terrain.profileIndex[index]!]!\n const first = profile.strata[0]!\n material = terrain.material(first.thickness < THIN_SKIN && profile.strata[1] ? profile.strata[1].material : first.material)\n }\n // dug concrete shows its broken aggregate, not the troweled surface with its joints\n const broken = material.pattern === 'concrete' && terrain.dug[index]! > BROKEN_DEPTH\n const tone = broken ? BROKEN_TONE : 1\n base[0] = material.color[0] * tone\n base[1] = material.color[1] * tone\n base[2] = material.color[2] * tone\n shade[0] = Math.max(MIN_DEPTH_LIGHT, 1 - terrain.dug[index]! / DEPTH_SHADE)\n shade[1] = terrain.scorch[index]!\n return patternIndex(broken ? 'soil' : material.pattern)\n}\n\n/** The chunk as a grid with one vertex every `step` cells; the normals come from the height field, so that neighbouring chunks meet without a seam. */\nexport function buildChunkGeometry(THREE: ThreeLib, terrain: Terrain, chunk: TerrainChunk, step: number): THREE_NS.BufferGeometry {\n const [x0, z0] = terrain.bounds\n const { cellSize, columns, rows } = terrain\n const lastColumn = Math.min(columns, chunk.column + chunk.cells)\n const lastRow = Math.min(rows, chunk.row + chunk.cells)\n const across = Math.ceil((lastColumn - chunk.column) / step) + 1\n const down = Math.ceil((lastRow - chunk.row) / step) + 1\n const positions = new Float32Array(across * down * 3)\n const normals = new Float32Array(across * down * 3)\n const bases = new Float32Array(across * down * 3)\n const shades = new Float32Array(across * down * 2)\n const patterns = new Float32Array(across * down)\n const base: [number, number, number] = [0, 0, 0]\n const shade: [number, number] = [1, 0]\n let at = 0\n for (let j = 0; j < down; j++) {\n const row = Math.min(lastRow, chunk.row + j * step)\n for (let i = 0; i < across; i++) {\n const column = Math.min(lastColumn, chunk.column + i * step)\n const height = terrain.vertexHeight(column, row)\n positions[at * 3] = x0 + column * cellSize\n positions[at * 3 + 1] = height\n positions[at * 3 + 2] = z0 + row * cellSize\n const left = terrain.vertexHeight(Math.max(0, column - 1), row)\n const right = terrain.vertexHeight(Math.min(columns, column + 1), row)\n const back = terrain.vertexHeight(column, Math.max(0, row - 1))\n const front = terrain.vertexHeight(column, Math.min(rows, row + 1))\n const nx = left - right\n const ny = 2 * cellSize\n const nz = back - front\n const length = Math.hypot(nx, ny, nz)\n normals[at * 3] = nx / length\n normals[at * 3 + 1] = ny / length\n normals[at * 3 + 2] = nz / length\n patterns[at] = vertexLook(terrain, column, row, base, shade)\n bases.set(base, at * 3)\n shades.set(shade, at * 2)\n at++\n }\n }\n const indices = new Uint32Array((across - 1) * (down - 1) * 6)\n let cursor = 0\n for (let j = 0; j < down - 1; j++) {\n for (let i = 0; i < across - 1; i++) {\n const a = j * across + i\n const b = a + 1\n const c = a + across\n const d = c + 1\n indices[cursor++] = a\n indices[cursor++] = c\n indices[cursor++] = b\n // both triangles end on `b`: a flat attribute takes the last vertex, so the whole quad has one material and the edge between two is a straight line\n indices[cursor++] = c\n indices[cursor++] = d\n indices[cursor++] = b\n }\n }\n const geometry = new THREE.BufferGeometry()\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n geometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3))\n geometry.setAttribute('aBase', new THREE.BufferAttribute(bases, 3))\n geometry.setAttribute('aShade', new THREE.BufferAttribute(shades, 2))\n geometry.setAttribute('aPattern', new THREE.BufferAttribute(patterns, 1))\n geometry.setIndex(new THREE.BufferAttribute(indices, 1))\n return geometry\n}\n\n/**\n * Every chunk nothing touched, as one flat quad each in one geometry: the whole floor of an arena is a single draw call until someone digs it. Around them, out to `skirt` metres, the\n * ground goes on as the same surface: what is thrown past the edge lands on something, not on the sky.\n */\nexport function buildPristineGeometry(THREE: ThreeLib, terrain: Terrain, chunks: readonly TerrainChunk[], skirt: number): THREE_NS.BufferGeometry {\n const [x0, z0] = terrain.bounds\n const { cellSize, columns, rows } = terrain\n const [, , x1, z1] = terrain.bounds\n const quads = chunks.length + SKIRT_QUADS\n const positions = new Float32Array(quads * 12)\n const normals = new Float32Array(quads * 12)\n const bases = new Float32Array(quads * 12)\n const shades = new Float32Array(quads * 8)\n const patterns = new Float32Array(quads * 4)\n const indices = new Uint32Array(quads * 6)\n const base: [number, number, number] = [0, 0, 0]\n const shade: [number, number] = [1, 0]\n chunks.forEach((chunk, n) => {\n const lastColumn = Math.min(columns, chunk.column + chunk.cells)\n const lastRow = Math.min(rows, chunk.row + chunk.cells)\n const corners = [[chunk.column, chunk.row], [lastColumn, chunk.row], [chunk.column, lastRow], [lastColumn, lastRow]] as const\n const pattern = vertexLook(terrain, chunk.column, chunk.row, base, shade)\n corners.forEach(([column, row], corner) => {\n const at = n * 4 + corner\n positions[at * 3] = x0 + column * cellSize\n positions[at * 3 + 1] = terrain.vertexHeight(column, row)\n positions[at * 3 + 2] = z0 + row * cellSize\n normals[at * 3 + 1] = 1\n bases.set(base, at * 3)\n shades.set(shade, at * 2)\n patterns[at] = pattern\n })\n const first = n * 4\n indices.set([first, first + 2, first + 1, first + 2, first + 3, first + 1], n * 6)\n })\n const surface = terrain.material(terrain.profileList.find((profile) => profile.id === terrain.layout().surface)?.strata[0]?.material ?? terrain.profileList[terrain.profileIndex[0]!]!.strata[0]!.material)\n const rects = [\n [x0 - skirt, z0 - skirt, x1 + skirt, z0],\n [x0 - skirt, z1, x1 + skirt, z1 + skirt],\n [x0 - skirt, z0, x0, z1],\n [x1, z0, x1 + skirt, z1],\n ] as const\n rects.forEach(([ax, az, bx, bz], r) => {\n const n = chunks.length + r\n const corners = [[ax, az], [bx, az], [ax, bz], [bx, bz]] as const\n corners.forEach(([x, z], corner) => {\n const at = n * 4 + corner\n positions[at * 3] = x\n positions[at * 3 + 2] = z\n normals[at * 3 + 1] = 1\n bases.set(surface.color, at * 3)\n shades[at * 2] = 1\n patterns[at] = patternIndex(surface.pattern)\n })\n const first = n * 4\n indices.set([first, first + 2, first + 1, first + 2, first + 3, first + 1], n * 6)\n })\n const geometry = new THREE.BufferGeometry()\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n geometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3))\n geometry.setAttribute('aBase', new THREE.BufferAttribute(bases, 3))\n geometry.setAttribute('aShade', new THREE.BufferAttribute(shades, 2))\n geometry.setAttribute('aPattern', new THREE.BufferAttribute(patterns, 1))\n geometry.setIndex(new THREE.BufferAttribute(indices, 1))\n return geometry\n}\n","import type * as THREE_NS from 'three'\nimport type { Terrain, TerrainDebrisKind } from '@adatechnology/game-terrain'\n\ntype ThreeLib = typeof THREE_NS\n\nconst MARK_LIFT = 0.006\nconst MARK_REACH = 1.5\nconst MARK_TEXTURE_SIZE = 64\nconst MARK_DARKEN = 0.85\n/** How a piece of each kind is stretched: a shard is a flake, a splinter a long sliver. */\nconst PIECE_SHAPE: Record<TerrainDebrisKind, readonly [number, number, number]> = { clods: [1, 0.85, 1], chips: [1, 0.6, 0.8], shards: [1.3, 0.2, 1], splinters: [0.3, 0.25, 2.4], dust: [1, 0.8, 1] }\n\n/** A pock as an alpha disc: dark in the middle, a broken lighter ring where the surface chipped. */\nfunction createMarkTexture(THREE: ThreeLib): THREE_NS.DataTexture {\n const size = MARK_TEXTURE_SIZE\n const data = new Uint8Array(size * size * 4)\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n const u = (x + 0.5) / size - 0.5\n const v = (y + 0.5) / size - 0.5\n const angle = Math.atan2(v, u)\n const lobes = 0.86 + 0.09 * Math.sin(angle * 5) + 0.05 * Math.sin(angle * 13 + 1)\n const q = Math.hypot(u, v) / (0.5 * lobes)\n const shade = q < 0.55 ? 0.42 + q * 0.5 : 0.7 + (q - 0.55) * 0.8\n const at = (y * size + x) * 4\n data[at] = data[at + 1] = data[at + 2] = Math.round(Math.min(1, shade) * 255)\n data[at + 3] = q < 0.8 ? 255 : q < 1 ? Math.round((1 - (q - 0.8) / 0.2) * 255) : 0\n }\n }\n const texture = new THREE.DataTexture(data, size, size, THREE.RGBAFormat)\n texture.magFilter = THREE.LinearFilter\n texture.minFilter = THREE.LinearFilter\n texture.needsUpdate = true\n return texture\n}\n\nexport function createMarkLayer(THREE: ThreeLib, terrain: Terrain, drawDistance: number): { mesh: THREE_NS.InstancedMesh; sync(camera: { x: number; z: number }): void; dispose(): void } {\n const geometry = new THREE.PlaneGeometry(1, 1)\n geometry.rotateX(-Math.PI / 2)\n const texture = createMarkTexture(THREE)\n const material = new THREE.MeshStandardMaterial({ map: texture, transparent: true, depthWrite: false, roughness: 1, polygonOffset: true, polygonOffsetFactor: -2, polygonOffsetUnits: -2 })\n const mesh = new THREE.InstancedMesh(geometry, material, terrain.budget.maxMarks)\n mesh.name = 'terrain-marks'\n mesh.count = 0\n mesh.frustumCulled = false\n mesh.receiveShadow = true\n mesh.renderOrder = 1\n const matrix = new THREE.Matrix4()\n const rotation = new THREE.Matrix4()\n const scale = new THREE.Matrix4()\n const colour = new THREE.Color()\n let seen = ''\n let cameraX = Infinity\n let cameraZ = Infinity\n return {\n mesh,\n sync(camera) {\n const marks = terrain.marks()\n let blows = 0\n for (const mark of marks) blows += mark.count\n const stamp = `${terrain.marksVersion}:${blows}`\n if (stamp === seen && Math.hypot(camera.x - cameraX, camera.z - cameraZ) < 5) return\n seen = stamp\n cameraX = camera.x\n cameraZ = camera.z\n let count = 0\n for (const mark of marks) {\n if (Math.hypot(mark.x - camera.x, mark.z - camera.z) > drawDistance) continue\n const size = mark.radius * 2 * MARK_REACH\n rotation.makeRotationY(mark.id * 2.399)\n scale.makeScale(size, 1, size)\n matrix.multiplyMatrices(rotation, scale)\n matrix.setPosition(mark.x, terrain.heightAt(mark.x, mark.z) + MARK_LIFT, mark.z)\n mesh.setMatrixAt(count, matrix)\n const [r, g, b] = terrain.material(mark.material).color\n colour.setRGB(r * MARK_DARKEN + 0.04, g * MARK_DARKEN + 0.04, b * MARK_DARKEN + 0.04)\n mesh.setColorAt(count, colour)\n count++\n }\n mesh.count = count\n mesh.instanceMatrix.needsUpdate = true\n if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n texture.dispose()\n mesh.removeFromParent()\n },\n }\n}\n\nexport function createDebrisLayer(THREE: ThreeLib, terrain: Terrain): { mesh: THREE_NS.InstancedMesh; sync(): void; dispose(): void } {\n const geometry = new THREE.IcosahedronGeometry(1, 0)\n const material = new THREE.MeshStandardMaterial({ roughness: 0.95, flatShading: true })\n const mesh = new THREE.InstancedMesh(geometry, material, terrain.budget.maxDebris)\n mesh.name = 'terrain-debris'\n mesh.count = 0\n mesh.castShadow = true\n mesh.frustumCulled = false\n const matrix = new THREE.Matrix4()\n const position = new THREE.Vector3()\n const scale = new THREE.Vector3()\n const quaternion = new THREE.Quaternion()\n const euler = new THREE.Euler()\n const colour = new THREE.Color()\n return {\n mesh,\n sync() {\n const pieces = terrain.debris()\n let count = 0\n for (const piece of pieces) {\n const [x, y, z] = piece.position\n // the turn follows the distance travelled, so that a piece at rest stays as it landed\n const travelled = x * 1.7 + z * 1.3 + y\n euler.set(piece.spin[0] * travelled * 0.2 + piece.id, piece.spin[1] * travelled * 0.2, piece.spin[2] * travelled * 0.2)\n const shape = PIECE_SHAPE[piece.kind]\n scale.set(shape[0] * piece.radius, shape[1] * piece.radius, shape[2] * piece.radius)\n matrix.compose(position.set(x, y, z), quaternion.setFromEuler(euler), scale)\n mesh.setMatrixAt(count, matrix)\n const [r, g, b] = terrain.material(piece.material).color\n const tone = 0.85 + ((piece.id * 37) % 30) / 100\n mesh.setColorAt(count, colour.setRGB(r * tone, g * tone, b * tone))\n count++\n }\n mesh.count = count\n mesh.instanceMatrix.needsUpdate = true\n if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true\n },\n dispose() {\n geometry.dispose()\n material.dispose()\n mesh.removeFromParent()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { Terrain, TerrainChunk } from '@adatechnology/game-terrain'\n\ntype ThreeLib = typeof THREE_NS\n\nconst BAR_RADIUS = 0.006\nconst EXPOSED_MARGIN = 0.002\n/** Metres a bar hangs just before it gives way. */\nconst MAX_SAG = 0.07\n\n/** The bars of a reinforced layer where the digging passed their cover: a mesh of the chunk, or null when none is showing. */\nexport function buildRebarGeometry(THREE: ThreeLib, terrain: Terrain, chunk: TerrainChunk): THREE_NS.BufferGeometry | null {\n const [x0, z0] = terrain.bounds\n const { cellSize, columns, rows, stride } = terrain\n const lastColumn = Math.min(columns, chunk.column + chunk.cells)\n const lastRow = Math.min(rows, chunk.row + chunk.cells)\n const boxes: number[] = []\n const coverOf = (index: number): { depth: number; spacing: number } | null => {\n let top = 0\n for (const stratum of terrain.profileList[terrain.profileIndex[index]!]!.strata) {\n if (stratum.reinforcement) return { depth: top + stratum.reinforcement.cover, spacing: stratum.reinforcement.spacing }\n top += stratum.thickness\n }\n return null\n }\n // past the bottom of its strata the slab has opened: the bars are gone there and stay bent around the hole\n const showing = (index: number, depth: number): boolean => {\n const profile = terrain.profileList[terrain.profileIndex[index]!]!\n const limit = profile.strata.reduce((sum, stratum) => sum + stratum.thickness, 0)\n return terrain.dug[index]! > depth + EXPOSED_MARGIN && terrain.dug[index]! <= limit + EXPOSED_MARGIN\n }\n const onBar = (coordinate: number, spacing: number): boolean => Math.floor(coordinate / spacing) !== Math.floor((coordinate + cellSize) / spacing)\n const addBox = (ax: number, az: number, bx: number, bz: number, y: number): void => {\n boxes.push(Math.min(ax, bx) - BAR_RADIUS, y - BAR_RADIUS, Math.min(az, bz) - BAR_RADIUS, Math.max(ax, bx) + BAR_RADIUS, y + BAR_RADIUS, Math.max(az, bz) + BAR_RADIUS)\n }\n for (let row = chunk.row; row <= lastRow; row++) {\n for (let column = chunk.column; column <= lastColumn; column++) {\n const index = row * stride + column\n const cover = coverOf(index)\n if (!cover || !showing(index, cover.depth)) continue\n const x = x0 + column * cellSize\n const z = z0 + row * cellSize\n const y = -cover.depth - BAR_RADIUS - Math.min(1, terrain.barBend[index]!) * MAX_SAG\n if (onBar(z, cover.spacing) && column < lastColumn && showing(index + 1, cover.depth)) addBox(x, z, x + cellSize, z, y)\n if (onBar(x, cover.spacing) && row < lastRow && showing(index + stride, cover.depth)) addBox(x, z, x, z + cellSize, y)\n }\n }\n if (boxes.length === 0) return null\n const count = boxes.length / 6\n const positions = new Float32Array(count * 24 * 3)\n const normals = new Float32Array(count * 24 * 3)\n const indices = new Uint32Array(count * 36)\n const FACES: readonly (readonly [readonly number[], readonly [number, number, number]])[] = [\n [[0, 4, 2, 0, 4, 5, 3, 4, 5, 3, 4, 2], [0, 1, 0]],\n [[0, 1, 5, 0, 1, 2, 3, 1, 2, 3, 1, 5], [0, -1, 0]],\n [[0, 1, 5, 3, 1, 5, 3, 4, 5, 0, 4, 5], [0, 0, 1]],\n [[3, 1, 2, 0, 1, 2, 0, 4, 2, 3, 4, 2], [0, 0, -1]],\n [[3, 1, 5, 3, 1, 2, 3, 4, 2, 3, 4, 5], [1, 0, 0]],\n [[0, 1, 2, 0, 1, 5, 0, 4, 5, 0, 4, 2], [-1, 0, 0]],\n ]\n let vertex = 0\n let cursor = 0\n for (let n = 0; n < count; n++) {\n const box = boxes.slice(n * 6, n * 6 + 6)\n for (const [corners, normal] of FACES) {\n const first = vertex\n for (let c = 0; c < 4; c++) {\n positions[vertex * 3] = box[corners[c * 3]!]!\n positions[vertex * 3 + 1] = box[corners[c * 3 + 1]!]!\n positions[vertex * 3 + 2] = box[corners[c * 3 + 2]!]!\n normals.set(normal, vertex * 3)\n vertex++\n }\n indices.set([first, first + 1, first + 2, first, first + 2, first + 3], cursor)\n cursor += 6\n }\n }\n const geometry = new THREE.BufferGeometry()\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n geometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3))\n geometry.setIndex(new THREE.BufferAttribute(indices, 1))\n return geometry\n}\n","import type * as THREE_NS from 'three'\nimport { markKitOrigin } from '@adatechnology/game-contracts'\nimport type { DestructibleSpec, GroundLayout, ModuleArea, ModuleHost, TestableItem, TestableModule } from '@adatechnology/game-contracts'\nimport { locale as localeTable } from './locale'\n\ntype ThreeLib = typeof THREE_NS\n\n/** The strips of the area, side by side, one of each ground. */\nexport const TERRAIN_STRIPS = ['dirt', 'lawn', 'sand', 'road', 'concrete_slab', 'suspended_slab', 'wood_floor', 'tile_floor', 'stone_paving'] as const\nconst STRIP_WIDTH = 3\nconst STRIP_Z0 = 4\nconst STRIP_Z1 = 13\nconst stripRect = (index: number): readonly [number, number, number, number] => {\n const x0 = (index - TERRAIN_STRIPS.length / 2) * STRIP_WIDTH\n return [x0, STRIP_Z0, x0 + STRIP_WIDTH, STRIP_Z1]\n}\nexport const TERRAIN_AREA_GROUND: GroundLayout = {\n surface: 'concrete_slab',\n zones: TERRAIN_STRIPS.map((surface, index) => ({ rect: stripRect(index), surface })),\n}\n\nconst WEIGHT_SIDE = 0.32\nconst WEIGHT_HEIGHT = 4\nconst LABEL_Y = 0.02\nconst LABEL_WIDTH = 2.6\nconst LABEL_HEIGHT = 0.5\n\nfunction weightSpec(): DestructibleSpec {\n return { name: 'Weight', parts: [{ id: 'block', material: 'concrete', shape: { kind: 'box', size: [WEIGHT_SIDE, WEIGHT_SIDE, WEIGHT_SIDE] }, position: [0, WEIGHT_SIDE / 2, 0] }], joints: [] }\n}\n\nfunction buildWeight(THREE: ThreeLib): THREE_NS.Object3D {\n const mesh = new THREE.Mesh(new THREE.BoxGeometry(WEIGHT_SIDE, WEIGHT_SIDE, WEIGHT_SIDE), new THREE.MeshStandardMaterial({ color: 0xb4b4ae, roughness: 0.9 }))\n mesh.name = 'block'\n mesh.position.y = WEIGHT_SIDE / 2\n mesh.castShadow = true\n const root = markKitOrigin(new THREE.Group(), { owner: 'game-terrain-three', kind: 'item' })\n root.add(mesh)\n return root\n}\n\nfunction buildLabel(THREE: ThreeLib, text: string, x: number): THREE_NS.Object3D | null {\n if (typeof document === 'undefined') return null\n const canvas = document.createElement('canvas')\n canvas.width = 512\n canvas.height = 96\n const context = canvas.getContext('2d')\n if (!context) return null\n context.fillStyle = 'rgba(0,0,0,0.55)'\n context.fillRect(0, 0, 512, 96)\n context.fillStyle = '#fff'\n context.font = 'bold 54px sans-serif'\n context.textAlign = 'center'\n context.textBaseline = 'middle'\n context.fillText(text, 256, 50)\n const mesh = new THREE.Mesh(new THREE.PlaneGeometry(LABEL_WIDTH, LABEL_HEIGHT), new THREE.MeshBasicMaterial({ map: new THREE.CanvasTexture(canvas), transparent: true }))\n // read from the start of the area, looking along +z\n markKitOrigin(mesh, { owner: 'game-terrain-three', kind: 'room' })\n mesh.rotation.set(-Math.PI / 2, 0, Math.PI)\n mesh.position.set(x, LABEL_Y, STRIP_Z0 - LABEL_HEIGHT)\n return mesh\n}\n\n/**\n * The ground bench: a strip of each surface side by side to shoot, blow up, burn and drop weights on. Opening the area lays the strips (`ground`) and drops a concrete block\n * on each from four metres.\n */\nexport function createTerrainTestModule(options: { readonly locale?: string } = {}): TestableModule {\n let labels: THREE_NS.Object3D[] = []\n const text = localeTable(options.locale ?? 'en')\n return {\n id: 'terrain',\n name: text.name,\n group: text.group,\n ground: TERRAIN_AREA_GROUND,\n items(): TestableItem[] {\n return [{ id: 'terrain_weight', name: text.weight, build: (THREE) => buildWeight(THREE as ThreeLib), spec: weightSpec, movable: true }]\n },\n area(): ModuleArea {\n for (const label of labels) label.visible = true\n return {\n placements: TERRAIN_STRIPS.map((_, index) => {\n const [x0] = stripRect(index)\n return { item: 'terrain_weight', position: [x0 + STRIP_WIDTH / 2, WEIGHT_HEIGHT, STRIP_Z1 - 1.2] }\n }),\n view: { eye: [0, 1.7, 1.5], target: [0, 0, 8] },\n }\n },\n attach(host: ModuleHost): () => void {\n const THREE = host.THREE as ThreeLib\n const scene = host.scene as THREE_NS.Scene\n labels = TERRAIN_STRIPS.flatMap((surface, index) => {\n const [x0] = stripRect(index)\n const label = buildLabel(THREE, text.surfaces[surface], x0 + STRIP_WIDTH / 2)\n if (!label) return []\n label.visible = false\n scene.add(label)\n return [label]\n })\n const stop = host.onClear?.(() => {\n for (const label of labels) label.visible = false\n })\n return () => {\n stop?.()\n for (const label of labels) label.removeFromParent()\n labels = []\n }\n },\n }\n}\n","import type { TERRAIN_STRIPS } from './test-module'\n\ninterface TerrainText {\n readonly name: string\n readonly group: string\n readonly weight: string\n readonly surfaces: Record<(typeof TERRAIN_STRIPS)[number], string>\n}\n\nconst LOCALES: Record<string, TerrainText> = {\n en: {\n name: 'Terrain',\n group: 'Terrain',\n weight: 'Concrete block (60 kg)',\n surfaces: { dirt: 'Dirt', lawn: 'Lawn', sand: 'Sand', road: 'Asphalt', concrete_slab: 'Concrete slab', suspended_slab: 'Slab over a void', wood_floor: 'Wood floor', tile_floor: 'Tile', stone_paving: 'Stone paving' },\n },\n 'pt-BR': {\n name: 'Terreno',\n group: 'Terreno',\n weight: 'Bloco de concreto (60 kg)',\n surfaces: { dirt: 'Terra', lawn: 'Grama', sand: 'Areia', road: 'Asfalto', concrete_slab: 'Laje de concreto', suspended_slab: 'Laje sobre vão', wood_floor: 'Assoalho', tile_floor: 'Cerâmica', stone_paving: 'Pedra' },\n },\n}\n\nexport const locale = (id: string): TerrainText => LOCALES[id] ?? LOCALES.en!\n"],"mappings":"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","names":["markKitOrigin","markKitOrigin"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adatechnology/game-terrain-three",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "three.js renderer for @adatechnology/game-terrain: chunked ground with a material pattern per surface, simplified far away, the marks as instanced decals, rebar where a slab is dug past its cover, and the clods.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"game",
|
|
8
|
+
"terrain",
|
|
9
|
+
"heightmap",
|
|
10
|
+
"destruction",
|
|
11
|
+
"three",
|
|
12
|
+
"threejs"
|
|
13
|
+
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/Andersonfrfilho/adatechnology-game-kit.git",
|
|
17
|
+
"directory": "packages/game-terrain-three"
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "dist/index.js",
|
|
24
|
+
"module": "dist/index.js",
|
|
25
|
+
"types": "dist/index.d.ts",
|
|
26
|
+
"unpkg": "dist/index.global.js",
|
|
27
|
+
"jsdelivr": "dist/index.global.js",
|
|
28
|
+
"sideEffects": false,
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./global": "./dist/index.global.js"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist"
|
|
38
|
+
],
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@adatechnology/game-terrain": "0.1.0",
|
|
41
|
+
"@adatechnology/game-contracts": "0.18.0"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"three": "^0.160.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^22.10.7",
|
|
48
|
+
"@types/three": "^0.160.0",
|
|
49
|
+
"three": "^0.160.1",
|
|
50
|
+
"tsup": "^8.5.1",
|
|
51
|
+
"typescript": "^5.7.3",
|
|
52
|
+
"vitest": "^3.2.4"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsup",
|
|
56
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
57
|
+
"test": "vitest run"
|
|
58
|
+
}
|
|
6
59
|
}
|