depth.test.js
3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// depth.test.js — 透视缩放 + zIndex 纵深 + 遮挡判定(render-pixi §8 验收 7)。
//
// 对照原型 pixi-stage.js / character-actor.js:
// - setActorWorldPos 后角色按 worldY 做透视缩放(近大远小)+ zIndex=round(worldY)。
// - 遮挡片 zIndex=baseY;人物 worldY < baseY 被遮、> baseY 盖住。
import { describe, it, expect } from 'vitest'
import { perspectiveScale, depthZIndex } from '../src/geom.js'
import { isOccluded } from '../src/occluder.js'
import { createPixiRenderer } from '../src/index.js'
import { makeStubPixi, StubApplication } from './stub-pixi.js'
const depth = { nearY: 1000, farY: 200, nearScale: 1.5, farScale: 0.5 }
describe('geom 纵深纯函数', () => {
it('perspectiveScale:近(下/大)→nearScale、远(上/小)→farScale、区间外夹紧', () => {
expect(perspectiveScale(1000, depth)).toBeCloseTo(1.5)
expect(perspectiveScale(200, depth)).toBeCloseTo(0.5)
expect(perspectiveScale(600, depth)).toBeCloseTo(1.0) // 中点
expect(perspectiveScale(2000, depth)).toBeCloseTo(1.5) // 夹紧 near
expect(perspectiveScale(-100, depth)).toBeCloseTo(0.5) // 夹紧 far
})
it('perspectiveScale 单调:worldY 越大缩放越大(近大远小)', () => {
expect(perspectiveScale(400, depth)).toBeLessThan(perspectiveScale(800, depth))
})
it('depthZIndex = round(worldY)', () => {
expect(depthZIndex(456.4)).toBe(456)
expect(depthZIndex(456.6)).toBe(457)
})
})
describe('遮挡判定', () => {
it('人物脚下 worldY < baseY → 被遮;> baseY → 盖住;== 不被遮', () => {
expect(isOccluded(300, 500)).toBe(true)
expect(isOccluded(700, 500)).toBe(false)
expect(isOccluded(500, 500)).toBe(false)
})
})
const rig = {
id: 'humanoid_v1',
canvas: { width: 1080, height: 1080 },
bones: [{ name: 'root', parent: null, pos: { x: 0, y: 0 }, rotation: 0 }],
slots: [{ name: 'torso', bone: 'root', zOrder: 10 }],
}
describe('setActorWorldPos 集成', () => {
function setup() {
const PIXI = makeStubPixi()
const r = createPixiRenderer(new StubApplication(), { PIXI, rig })
return { r, PIXI }
}
it('setActorWorldPos 写根容器位置 + zIndex=round(worldY)', () => {
const { r } = setup()
r.addActor('a', { rigId: 'humanoid_v1', parts: { torso: { url: 't.png' } } }, { x: 0, y: 0, facing: 'left', scale: 1 })
r.setActorWorldPos('a', 250, 740.3)
const actor = r._actors.get('a')
expect(actor.root.position.x).toBe(250)
expect(actor.root.position.y).toBe(740.3)
expect(actor.root.zIndex).toBe(740)
})
it('loadScene 设 depth 后,角色按 worldY 透视缩放(baseScale=1)', async () => {
const { r } = setup()
r.addActor('a', { rigId: 'humanoid_v1', parts: { torso: { url: 't.png' } } }, { x: 0, y: 0, facing: 'left', scale: 1 })
await r.loadScene({ world: { w: 2000, h: 1200 }, depth })
r.setActorWorldPos('a', 0, 1000) // 近
const near = Math.abs(r._actors.get('a').root.scale.x)
r.setActorWorldPos('a', 0, 200) // 远
const far = Math.abs(r._actors.get('a').root.scale.x)
expect(near).toBeCloseTo(1.5)
expect(far).toBeCloseTo(0.5)
expect(near).toBeGreaterThan(far)
})
})