(id)
| 375 | |
| 376 | /** Unit cube (or cross) centered at origin with baked face shading. */ |
| 377 | export function buildBlockGeometry(id) { |
| 378 | const def = BLOCKS[id]; |
| 379 | const buf = new GeoBuf(); |
| 380 | if (def.shape === 'cross') { |
| 381 | const rect = uvRect(def.tex.py); |
| 382 | const a = -0.35, b = 0.35; |
| 383 | for (const [[x0, z0], [x1, z1]] of [[[a, a], [b, b]], [[a, b], [b, a]]]) { |
| 384 | for (const flip of [false, true]) { |
| 385 | const corners = [ |
| 386 | { x: x0, z: z0, u: 0, vy: 0 }, |
| 387 | { x: x1, z: z1, u: 1, vy: 0 }, |
| 388 | { x: x1, z: z1, u: 1, vy: 1 }, |
| 389 | { x: x0, z: z0, u: 0, vy: 1 }, |
| 390 | ]; |
| 391 | const list = flip ? [...corners].reverse() : corners; |
| 392 | buf.quad(list.map((c) => ({ |
| 393 | x: c.x, y: c.vy - 0.5, z: c.z, |
| 394 | u: rect.u0 + (rect.u1 - rect.u0) * c.u, |
| 395 | v: rect.v0 + (rect.v1 - rect.v0) * c.vy, |
| 396 | r: 1, g: 0, |
| 397 | }))); |
| 398 | } |
| 399 | } |
| 400 | } else { |
| 401 | for (const face of FACES) { |
| 402 | const tile = def.tex[face.key]; |
| 403 | const rect = uvRect(tile === 'water_still' ? 'water_still' : tile); |
| 404 | const shade = FACE_SHADE[face.key]; |
| 405 | buf.quad(face.corners.map((c) => ({ |
| 406 | x: c.pos[0] - 0.5, y: c.pos[1] - 0.5, z: c.pos[2] - 0.5, |
| 407 | u: rect.u0 + (rect.u1 - rect.u0) * c.u, |
| 408 | v: rect.v0 + (rect.v1 - rect.v0) * c.v, |
| 409 | r: shade, g: 0, |
| 410 | }))); |
| 411 | } |
| 412 | } |
| 413 | const g = buf.build(); |
| 414 | g.computeBoundingSphere(); |
| 415 | return g; |
| 416 | } |
no test coverage detected