refactor: move world concepts into engine
This commit is contained in:
parent
eeedcb8e48
commit
2d15c7ab8d
52 changed files with 3298 additions and 1558 deletions
|
|
@ -1,17 +1,19 @@
|
|||
import type { Vec3 } from "../../engine/math/Vec3"
|
||||
import { Mesh } from "../../engine/scene/Mesh"
|
||||
import type { Material } from "../../engine/render/Material"
|
||||
import type { Prefab } from "../../engine/scene/Prefab"
|
||||
|
||||
const TAU = Math.PI * 2
|
||||
|
||||
/** Flower bloom color, indexing a region of the `flower` texture atlas. */
|
||||
export type FlowerColor = "white" | "red" | "yellow"
|
||||
/** Concrete atlas style referenced directly by flower instances. */
|
||||
export type FlowerStyle = { bloomUv: [number, number] }
|
||||
|
||||
/** A single small flower: a thin crossed-quad stem plus a shallow fan of petals.
|
||||
* Tiny, so it is drawn double-sided (no backface cull) and carries no collider.
|
||||
* `size` is roughly its height; `seed` jitters the petals. */
|
||||
export type Flower = {
|
||||
position: Vec3
|
||||
color: FlowerColor
|
||||
style: FlowerStyle
|
||||
size: number
|
||||
seed: number
|
||||
}
|
||||
|
|
@ -23,16 +25,21 @@ export type Flower = {
|
|||
* or draw call. `build` appends into one shared flower mesh.
|
||||
*/
|
||||
export namespace Flower {
|
||||
/** uv center of each bloom color's atlas region (tile units). */
|
||||
const BLOOM_UV: Record<FlowerColor, [number, number]> = {
|
||||
white: [0.75, 0.25],
|
||||
red: [0.25, 0.75],
|
||||
yellow: [0.75, 0.75],
|
||||
}
|
||||
export const white: FlowerStyle = { bloomUv: [0.75, 0.25] }
|
||||
export const red: FlowerStyle = { bloomUv: [0.25, 0.75] }
|
||||
export const yellow: FlowerStyle = { bloomUv: [0.75, 0.75] }
|
||||
|
||||
/** uv center of the green stem region. */
|
||||
const STEM_U = 0.25
|
||||
const STEM_V = 0.25
|
||||
|
||||
export function create(material: Material): Prefab<Flower> {
|
||||
return {
|
||||
position: (flower) => flower.position,
|
||||
bakeNear: (flower, batch) => build(flower, batch.mesh(material)),
|
||||
}
|
||||
}
|
||||
|
||||
export function build(flower: Flower, mesh: Mesh): void {
|
||||
const rand = rng(flower.seed)
|
||||
const p = flower.position
|
||||
|
|
@ -43,14 +50,21 @@ export namespace Flower {
|
|||
stem(mesh, p.x, p.y, p.z, bloomY, w, 0)
|
||||
stem(mesh, p.x, p.y, p.z, bloomY, 0, w)
|
||||
// Bloom: a shallow fan of petals, center raised a touch so it domes.
|
||||
const [bu, bv] = BLOOM_UV[flower.color]
|
||||
const [bu, bv] = flower.style.bloomUv
|
||||
const rad = flower.size * 0.38
|
||||
const center = Mesh.push(mesh, p.x, bloomY + rad * 0.3, p.z, bu, bv)
|
||||
const ring = center + 1
|
||||
const petals = 5
|
||||
for (let i = 0; i <= petals; i++) {
|
||||
const angle = (i / petals) * TAU + rand() * 0.4
|
||||
Mesh.push(mesh, p.x + Math.cos(angle) * rad, bloomY, p.z + Math.sin(angle) * rad, bu, bv)
|
||||
Mesh.push(
|
||||
mesh,
|
||||
p.x + Math.cos(angle) * rad,
|
||||
bloomY,
|
||||
p.z + Math.sin(angle) * rad,
|
||||
bu,
|
||||
bv,
|
||||
)
|
||||
}
|
||||
for (let i = 0; i < petals; i++) {
|
||||
mesh.indices.push(center, ring + i, ring + i + 1)
|
||||
|
|
@ -58,7 +72,15 @@ export namespace Flower {
|
|||
}
|
||||
|
||||
/** A thin vertical quad from the ground to `y1`, width along (dx, dz). */
|
||||
function stem(mesh: Mesh, x: number, y0: number, z: number, y1: number, dx: number, dz: number): void {
|
||||
function stem(
|
||||
mesh: Mesh,
|
||||
x: number,
|
||||
y0: number,
|
||||
z: number,
|
||||
y1: number,
|
||||
dx: number,
|
||||
dz: number,
|
||||
): void {
|
||||
const a = Mesh.push(mesh, x - dx, y0, z - dz, STEM_U, STEM_V)
|
||||
const b = Mesh.push(mesh, x + dx, y0, z + dz, STEM_U, STEM_V)
|
||||
const c = Mesh.push(mesh, x + dx, y1, z + dz, STEM_U, STEM_V)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue