UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

173 lines (168 loc) 6.17 kB
import { b2_maxFloat, b2MakeArray } from "../common/b2_settings.js"; import { b2Vec2 } from "../common/b2_math.js"; import { b2StackQueue } from "./b2_stack_queue.js"; export class b2VoronoiDiagram { constructor(t) { this.m_generatorCapacity = 0; this.m_generatorCount = 0; this.m_countX = 0; this.m_countY = 0; this.m_diagram = []; this.m_generatorBuffer = b2MakeArray(t, (t => new b2VoronoiDiagram_Generator)); this.m_generatorCapacity = t; } AddGenerator(t, s, o) { const i = this.m_generatorBuffer[this.m_generatorCount++]; i.center.Copy(t); i.tag = s; i.necessary = o; } Generate(t, s) { const o = 1 / t; const i = new b2Vec2(+b2_maxFloat, +b2_maxFloat); const n = new b2Vec2(-b2_maxFloat, -b2_maxFloat); let a = 0; for (let t = 0; t < this.m_generatorCount; t++) { const s = this.m_generatorBuffer[t]; if (s.necessary) { b2Vec2.MinV(i, s.center, i); b2Vec2.MaxV(n, s.center, n); ++a; } } if (a === 0) { this.m_countX = 0; this.m_countY = 0; return; } i.x -= s; i.y -= s; n.x += s; n.y += s; this.m_countX = 1 + Math.floor(o * (n.x - i.x)); this.m_countY = 1 + Math.floor(o * (n.y - i.y)); this.m_diagram = []; const h = new b2StackQueue(4 * this.m_countX * this.m_countY); for (let t = 0; t < this.m_generatorCount; t++) { const s = this.m_generatorBuffer[t]; s.center.SelfSub(i).SelfMul(o); const n = Math.floor(s.center.x); const a = Math.floor(s.center.y); if (n >= 0 && a >= 0 && n < this.m_countX && a < this.m_countY) { h.Push(new b2VoronoiDiagram_Task(n, a, n + a * this.m_countX, s)); } } while (!h.Empty()) { const t = h.Front(); const s = t.m_x; const o = t.m_y; const i = t.m_i; const n = t.m_generator; h.Pop(); if (!this.m_diagram[i]) { this.m_diagram[i] = n; if (s > 0) { h.Push(new b2VoronoiDiagram_Task(s - 1, o, i - 1, n)); } if (o > 0) { h.Push(new b2VoronoiDiagram_Task(s, o - 1, i - this.m_countX, n)); } if (s < this.m_countX - 1) { h.Push(new b2VoronoiDiagram_Task(s + 1, o, i + 1, n)); } if (o < this.m_countY - 1) { h.Push(new b2VoronoiDiagram_Task(s, o + 1, i + this.m_countX, n)); } } } for (let t = 0; t < this.m_countY; t++) { for (let s = 0; s < this.m_countX - 1; s++) { const o = s + t * this.m_countX; const i = this.m_diagram[o]; const n = this.m_diagram[o + 1]; if (i !== n) { h.Push(new b2VoronoiDiagram_Task(s, t, o, n)); h.Push(new b2VoronoiDiagram_Task(s + 1, t, o + 1, i)); } } } for (let t = 0; t < this.m_countY - 1; t++) { for (let s = 0; s < this.m_countX; s++) { const o = s + t * this.m_countX; const i = this.m_diagram[o]; const n = this.m_diagram[o + this.m_countX]; if (i !== n) { h.Push(new b2VoronoiDiagram_Task(s, t, o, n)); h.Push(new b2VoronoiDiagram_Task(s, t + 1, o + this.m_countX, i)); } } } while (!h.Empty()) { const t = h.Front(); const s = t.m_x; const o = t.m_y; const i = t.m_i; const n = t.m_generator; h.Pop(); const a = this.m_diagram[i]; const r = n; if (a !== r) { const t = a.center.x - s; const n = a.center.y - o; const e = r.center.x - s; const c = r.center.y - o; const b = t * t + n * n; const m = e * e + c * c; if (b > m) { this.m_diagram[i] = r; if (s > 0) { h.Push(new b2VoronoiDiagram_Task(s - 1, o, i - 1, r)); } if (o > 0) { h.Push(new b2VoronoiDiagram_Task(s, o - 1, i - this.m_countX, r)); } if (s < this.m_countX - 1) { h.Push(new b2VoronoiDiagram_Task(s + 1, o, i + 1, r)); } if (o < this.m_countY - 1) { h.Push(new b2VoronoiDiagram_Task(s, o + 1, i + this.m_countX, r)); } } } } } GetNodes(t) { for (let s = 0; s < this.m_countY - 1; s++) { for (let o = 0; o < this.m_countX - 1; o++) { const i = o + s * this.m_countX; const n = this.m_diagram[i]; const a = this.m_diagram[i + 1]; const h = this.m_diagram[i + this.m_countX]; const r = this.m_diagram[i + 1 + this.m_countX]; if (a !== h) { if (n !== a && n !== h && (n.necessary || a.necessary || h.necessary)) { t(n.tag, a.tag, h.tag); } if (r !== a && r !== h && (n.necessary || a.necessary || h.necessary)) { t(a.tag, r.tag, h.tag); } } } } } } export class b2VoronoiDiagram_Generator { constructor() { this.center = new b2Vec2; this.tag = 0; this.necessary = false; } } export class b2VoronoiDiagram_Task { constructor(t, s, o, i) { this.m_x = t; this.m_y = s; this.m_i = o; this.m_generator = i; } }