refactor: move world concepts into engine
This commit is contained in:
parent
eeedcb8e48
commit
2d15c7ab8d
52 changed files with 3298 additions and 1558 deletions
62
engine/world/CollisionWorld.ts
Normal file
62
engine/world/CollisionWorld.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import type { Vec3 } from "../math/Vec3"
|
||||
import { Collider, type Collider as ColliderShape } from "./Collider"
|
||||
import type { Terrain } from "./Terrain"
|
||||
|
||||
export type CollisionWorld = {
|
||||
terrain: Terrain
|
||||
staticColliders: ColliderShape[]
|
||||
dynamicColliders: ColliderShape[]
|
||||
}
|
||||
|
||||
export namespace CollisionWorld {
|
||||
export function create(
|
||||
terrain: Terrain,
|
||||
staticColliders: ColliderShape[],
|
||||
): CollisionWorld {
|
||||
return { terrain, staticColliders, dynamicColliders: [] }
|
||||
}
|
||||
|
||||
export function pushOut(
|
||||
world: CollisionWorld,
|
||||
position: Vec3,
|
||||
radius: number,
|
||||
): void {
|
||||
pushFrom(world.staticColliders, position, radius)
|
||||
pushFrom(world.dynamicColliders, position, radius)
|
||||
}
|
||||
|
||||
export function groundHeight(world: CollisionWorld, position: Vec3): number {
|
||||
let ground = world.terrain.heightAt(position.x, position.z)
|
||||
ground = standingHeight(world.staticColliders, position, ground)
|
||||
return standingHeight(world.dynamicColliders, position, ground)
|
||||
}
|
||||
|
||||
function pushFrom(
|
||||
colliders: ColliderShape[],
|
||||
position: Vec3,
|
||||
radius: number,
|
||||
): void {
|
||||
for (const collider of colliders) {
|
||||
if (position.y < collider.top - 0.01) {
|
||||
Collider.pushOut(collider, position, radius)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function standingHeight(
|
||||
colliders: ColliderShape[],
|
||||
position: Vec3,
|
||||
initial: number,
|
||||
): number {
|
||||
let ground = initial
|
||||
for (const collider of colliders) {
|
||||
if (
|
||||
collider.standable &&
|
||||
Collider.contains(collider, position.x, position.z)
|
||||
) {
|
||||
ground = Math.max(ground, collider.top)
|
||||
}
|
||||
}
|
||||
return ground
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue