100 lines
2.5 KiB
TypeScript
100 lines
2.5 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import * as THREE from 'three'
|
|
import {
|
|
getWalkableSurfaceHits,
|
|
projectRoutePositionToSurface,
|
|
resolveDominantRouteSurfaceY
|
|
} from '@/components/map/routeSurfaceProjection'
|
|
|
|
const createDeck = (
|
|
y: number,
|
|
width = 40,
|
|
depth = 40,
|
|
x = 0,
|
|
z = 0
|
|
) => {
|
|
const deck = new THREE.Mesh(
|
|
new THREE.BoxGeometry(width, 0.2, depth),
|
|
new THREE.MeshBasicMaterial()
|
|
)
|
|
deck.position.set(x, y - 0.1, z)
|
|
return deck
|
|
}
|
|
|
|
const boundsOf = (object: THREE.Object3D) => {
|
|
object.updateWorldMatrix(true, true)
|
|
return new THREE.Box3().setFromObject(object)
|
|
}
|
|
|
|
describe('route surface projection', () => {
|
|
it('将5楼遗留的非零路线Y投射到真实楼面', () => {
|
|
const floor = new THREE.Group()
|
|
floor.add(createDeck(26.964))
|
|
const fixture = new THREE.Mesh(
|
|
new THREE.BoxGeometry(2, 2, 2),
|
|
new THREE.MeshBasicMaterial()
|
|
)
|
|
fixture.position.set(0, 28, 0)
|
|
floor.add(fixture)
|
|
|
|
const bounds = boundsOf(floor)
|
|
const hits = getWalkableSurfaceHits(floor, bounds, [0, 0.33, 0])
|
|
const projected = projectRoutePositionToSurface(
|
|
floor,
|
|
bounds,
|
|
[0, 0.33, 0],
|
|
26.964,
|
|
0.24
|
|
)
|
|
|
|
expect(hits[0]).toBeCloseTo(26.964, 3)
|
|
expect(projected?.y).toBeCloseTo(27.204, 3)
|
|
})
|
|
|
|
it('以多数路线点命中的楼面为当前楼层高度', () => {
|
|
const floor = new THREE.Group()
|
|
floor.add(createDeck(26.964, 20, 20))
|
|
floor.add(createDeck(29.5, 4, 4, 20, 0))
|
|
const bounds = boundsOf(floor)
|
|
|
|
const surfaceY = resolveDominantRouteSurfaceY(floor, bounds, [
|
|
[-5, 0.197, 0],
|
|
[0, 0.33, 0],
|
|
[5, 0.254, 0],
|
|
[20, 0.33, 0]
|
|
])
|
|
|
|
expect(surfaceY).toBeCloseTo(26.964, 3)
|
|
})
|
|
|
|
it('不把当前楼层已隐藏的模型表面作为路线高度', () => {
|
|
const floor = new THREE.Group()
|
|
const hiddenDeck = createDeck(2)
|
|
hiddenDeck.visible = false
|
|
floor.add(hiddenDeck)
|
|
floor.add(createDeck(10))
|
|
const bounds = boundsOf(floor)
|
|
|
|
const surfaceY = resolveDominantRouteSurfaceY(floor, bounds, [[0, 0, 0]])
|
|
|
|
expect(surfaceY).toBeCloseTo(10, 3)
|
|
})
|
|
|
|
it('返回包含楼层布局位移的世界高度,避免重复叠加偏移', () => {
|
|
const floor = new THREE.Group()
|
|
floor.add(createDeck(5))
|
|
floor.position.y = 68
|
|
const bounds = boundsOf(floor)
|
|
|
|
const projected = projectRoutePositionToSurface(
|
|
floor,
|
|
bounds,
|
|
[0, 5.074, 0],
|
|
undefined,
|
|
0.24
|
|
)
|
|
|
|
expect(projected?.y).toBeCloseTo(73.24, 3)
|
|
})
|
|
})
|