diff --git a/packages/recast-navigation-core/src/debug-drawer-utils.ts b/packages/recast-navigation-core/src/debug-drawer-utils.ts new file mode 100644 index 00000000..a9298c74 --- /dev/null +++ b/packages/recast-navigation-core/src/debug-drawer-utils.ts @@ -0,0 +1,289 @@ +import { NavMesh } from './nav-mesh'; +import { NavMeshQuery } from './nav-mesh-query'; +import { Raw, RawModule } from './raw'; +import { + RecastCompactHeightfield, + RecastContourSet, + RecastHeightfield, + RecastHeightfieldLayer, + RecastHeightfieldLayerSet, + RecastPolyMesh, + RecastPolyMeshDetail, +} from './recast'; + +export type DebugDrawerPrimitiveType = 'lines' | 'tris' | 'quads' | 'points'; + +export type DebugDrawerPrimitive = { + type: DebugDrawerPrimitiveType; + vertices: [x: number, y: number, z: number, r: number, g: number, b: number, a: number][]; +}; + +/** + * Represents a helper class to visualize navigation cur and related data in PlayCanvas. + */ +export class DebugDrawerUtils { + private debugDrawImpl: RawModule.DebugDrawImpl; + + private currentPrimitiveType: number = 0; + private currentVertices: DebugDrawerPrimitive['vertices'] = []; + + private primitives: DebugDrawerPrimitive[] = []; + + constructor() { + this.debugDrawImpl = new Raw.Module.DebugDrawImpl(); + + // Bind the debug draw implementation handlers + this.debugDrawImpl.handleBegin = (primitive: number, _size: number) => { + this.currentPrimitiveType = primitive; + this.currentVertices = []; + }; + + this.debugDrawImpl.handleDepthMask = (_state: number) => { + // unused for now... + }; + + this.debugDrawImpl.handleTexture = (_state: number) => { + // unused for now... + }; + + this.debugDrawImpl.handleVertexWithColor = ( + x: number, + y: number, + z: number, + color: number + ) => { + this.vertex(x, y, z, color); + }; + + this.debugDrawImpl.handleVertexWithColorAndUV = ( + x: number, + y: number, + z: number, + color: number, + _u: number, + _v: number + ) => { + this.vertex(x, y, z, color); + }; + + const primitiveMap: Record = { + [Raw.Module.DU_DRAW_LINES]: 'lines', + [Raw.Module.DU_DRAW_TRIS]: 'tris', + [Raw.Module.DU_DRAW_QUADS]: 'quads', + [Raw.Module.DU_DRAW_POINTS]: 'points', + }; + + this.debugDrawImpl.handleEnd = () => { + const type = primitiveMap[this.currentPrimitiveType]; + + this.primitives.push({ + type, + vertices: this.currentVertices, + }); + }; + } + + private flush(): DebugDrawerPrimitive[] { + const cur = this.primitives; + this.primitives = []; + return cur; + } + + drawHeightfieldSolid(hf: RecastHeightfield): DebugDrawerPrimitive[] { + Raw.RecastDebugDraw.debugDrawHeightfieldSolid(this.debugDrawImpl, hf.raw); + return this.flush(); + } + + drawHeightfieldWalkable(hf: RecastHeightfield): DebugDrawerPrimitive[] { + Raw.RecastDebugDraw.debugDrawHeightfieldWalkable( + this.debugDrawImpl, + hf.raw + ); + return this.flush(); + } + + drawCompactHeightfieldSolid( + chf: RecastCompactHeightfield + ): DebugDrawerPrimitive[] { + Raw.RecastDebugDraw.debugDrawCompactHeightfieldSolid( + this.debugDrawImpl, + chf.raw + ); + return this.flush(); + } + + drawCompactHeightfieldRegions( + chf: RecastCompactHeightfield + ): DebugDrawerPrimitive[] { + Raw.RecastDebugDraw.debugDrawCompactHeightfieldRegions( + this.debugDrawImpl, + chf.raw + ); + return this.flush(); + } + + drawCompactHeightfieldDistance( + chf: RecastCompactHeightfield + ): DebugDrawerPrimitive[] { + Raw.RecastDebugDraw.debugDrawCompactHeightfieldDistance( + this.debugDrawImpl, + chf.raw + ); + return this.flush(); + } + + drawHeightfieldLayer( + layer: RecastHeightfieldLayer, + idx: number + ): DebugDrawerPrimitive[] { + Raw.RecastDebugDraw.debugDrawHeightfieldLayer( + this.debugDrawImpl, + layer.raw, + idx + ); + return this.flush(); + } + + drawHeightfieldLayers( + lset: RecastHeightfieldLayerSet + ): DebugDrawerPrimitive[] { + Raw.RecastDebugDraw.debugDrawHeightfieldLayers( + this.debugDrawImpl, + lset.raw + ); + return this.flush(); + } + + drawRegionConnections( + cset: RecastContourSet, + alpha: number = 1 + ): DebugDrawerPrimitive[] { + Raw.RecastDebugDraw.debugDrawRegionConnections( + this.debugDrawImpl, + cset.raw, + alpha + ); + return this.flush(); + } + + drawRawContours( + cset: RecastContourSet, + alpha: number = 1 + ): DebugDrawerPrimitive[] { + Raw.RecastDebugDraw.debugDrawRawContours( + this.debugDrawImpl, + cset.raw, + alpha + ); + return this.flush(); + } + + drawContours( + cset: RecastContourSet, + alpha: number = 1 + ): DebugDrawerPrimitive[] { + Raw.RecastDebugDraw.debugDrawContours(this.debugDrawImpl, cset.raw, alpha); + return this.flush(); + } + + drawPolyMesh(mesh: RecastPolyMesh): DebugDrawerPrimitive[] { + Raw.RecastDebugDraw.debugDrawPolyMesh(this.debugDrawImpl, mesh.raw); + return this.flush(); + } + + drawPolyMeshDetail(dmesh: RecastPolyMeshDetail): DebugDrawerPrimitive[] { + Raw.RecastDebugDraw.debugDrawPolyMeshDetail(this.debugDrawImpl, dmesh.raw); + return this.flush(); + } + + drawNavMesh(mesh: NavMesh, flags: number = 0): DebugDrawerPrimitive[] { + Raw.DetourDebugDraw.debugDrawNavMesh( + this.debugDrawImpl, + mesh.raw.getNavMesh(), + flags + ); + return this.flush(); + } + + drawNavMeshWithClosedList( + mesh: NavMesh, + query: NavMeshQuery, + flags: number = 0 + ): DebugDrawerPrimitive[] { + Raw.DetourDebugDraw.debugDrawNavMeshWithClosedList( + this.debugDrawImpl, + mesh.raw.m_navMesh, + query.raw.m_navQuery, + flags + ); + return this.flush(); + } + + drawNavMeshNodes(query: NavMeshQuery): DebugDrawerPrimitive[] { + Raw.DetourDebugDraw.debugDrawNavMeshNodes( + this.debugDrawImpl, + query.raw.m_navQuery + ); + return this.flush(); + } + + drawNavMeshBVTree(mesh: NavMesh): DebugDrawerPrimitive[] { + Raw.DetourDebugDraw.debugDrawNavMeshBVTree( + this.debugDrawImpl, + mesh.raw.m_navMesh + ); + return this.flush(); + } + + drawNavMeshPortals(mesh: NavMesh): DebugDrawerPrimitive[] { + Raw.DetourDebugDraw.debugDrawNavMeshPortals( + this.debugDrawImpl, + mesh.raw.m_navMesh + ); + return this.flush(); + } + + drawNavMeshPolysWithFlags( + mesh: NavMesh, + flags: number, + col: number + ): DebugDrawerPrimitive[] { + Raw.DetourDebugDraw.debugDrawNavMeshPolysWithFlags( + this.debugDrawImpl, + mesh.raw.m_navMesh, + flags, + col + ); + return this.flush(); + } + + drawNavMeshPoly( + mesh: NavMesh, + ref: number, + col: number + ): DebugDrawerPrimitive[] { + Raw.DetourDebugDraw.debugDrawNavMeshPoly( + this.debugDrawImpl, + mesh.raw.m_navMesh, + ref, + col + ); + return this.flush(); + } + + /** + * Disposes of the debug drawer and releases resources. + */ + dispose(): void { + Raw.Module.destroy(this.debugDrawImpl); + } + + private vertex(x: number, y: number, z: number, color: number) { + const r = ((color >> 16) & 0xff) / 255; + const g = ((color >> 8) & 0xff) / 255; + const b = (color & 0xff) / 255; + const a = ((color >> 24) & 0xff) / 255; + + this.currentVertices.push([x, y, z, r, g, b, a]); + } +} diff --git a/packages/recast-navigation-core/src/index.ts b/packages/recast-navigation-core/src/index.ts index aec6a0b5..9b3b3fce 100644 --- a/packages/recast-navigation-core/src/index.ts +++ b/packages/recast-navigation-core/src/index.ts @@ -1,5 +1,6 @@ export * from './arrays'; export * from './crowd'; +export * from './debug-drawer-utils'; export * from './detour'; export * from './nav-mesh'; export * from './nav-mesh-query'; diff --git a/packages/recast-navigation-playcanvas/src/debug/debug-drawer.ts b/packages/recast-navigation-playcanvas/src/debug/debug-drawer.ts index 60d7dfa8..19345d8f 100644 --- a/packages/recast-navigation-playcanvas/src/debug/debug-drawer.ts +++ b/packages/recast-navigation-playcanvas/src/debug/debug-drawer.ts @@ -1,7 +1,8 @@ import { + DebugDrawerPrimitive, + DebugDrawerUtils, NavMesh, NavMeshQuery, - Raw, RecastCompactHeightfield, RecastContourSet, RecastHeightfield, @@ -30,19 +31,6 @@ import { VertexFormat, } from 'playcanvas'; -/** - * Represents a vertex with position and color data. - */ -type VertexData = { - x: number; - y: number; - z: number; - r: number; - g: number; - b: number; - a: number; -}; - /** * Parameters for creating DebugDrawer. */ @@ -61,14 +49,14 @@ export class DebugDrawer extends Entity { pointMaterial: StandardMaterial; lineMaterial: StandardMaterial; + private debugDrawerUtils: DebugDrawerUtils; private graphicsDevice: GraphicsDevice; - private debugDrawImpl: any; // Replace 'any' with the actual type if available - private currentVertices: VertexData[] = []; - private currentPrimitive: number = 0; constructor(graphicsDevice: GraphicsDevice, params?: DebugDrawerParams) { super(); + this.debugDrawerUtils = new DebugDrawerUtils(); + this.graphicsDevice = graphicsDevice; if (params?.triMaterial) { @@ -100,137 +88,91 @@ export class DebugDrawer extends Entity { this.lineMaterial.emissive = new Color(1, 1, 1); this.lineMaterial.update(); } + } - this.debugDrawImpl = new Raw.Module.DebugDrawImpl(); - - // Bind the debug draw implementation handlers - this.debugDrawImpl.handleBegin = (primitive: number, _size: number) => { - this.currentPrimitive = primitive; - this.currentVertices = []; - }; - - this.debugDrawImpl.handleDepthMask = (_state: number) => { - // Implement if necessary - }; - - this.debugDrawImpl.handleTexture = (_state: number) => { - // Implement if necessary - }; - - this.debugDrawImpl.handleVertexWithColor = ( - x: number, - y: number, - z: number, - color: number - ) => { - this.vertex(x, y, z, color); - }; - - this.debugDrawImpl.handleVertexWithColorAndUV = ( - x: number, - y: number, - z: number, - color: number, - _u: number, - _v: number - ) => { - this.vertex(x, y, z, color); - }; - - this.debugDrawImpl.handleEnd = () => { - if (this.currentPrimitive === Raw.Module.DU_DRAW_LINES) { - this.endLines(); - } else if (this.currentPrimitive === Raw.Module.DU_DRAW_TRIS) { - this.endTris(); - } else if (this.currentPrimitive === Raw.Module.DU_DRAW_QUADS) { - this.endQuads(); - } else if (this.currentPrimitive === Raw.Module.DU_DRAW_POINTS) { - this.endPoints(); + drawPrimitives(primitives: DebugDrawerPrimitive[]): void { + for (const primitive of primitives) { + switch (primitive.type) { + case 'points': + this.drawPoints(primitive); + break; + case 'lines': + this.drawLines(primitive); + break; + case 'tris': + this.drawTris(primitive); + break; + case 'quads': + this.drawQuads(primitive); + break; } - }; + } } drawHeightfieldSolid(hf: RecastHeightfield): void { - Raw.RecastDebugDraw.debugDrawHeightfieldSolid(this.debugDrawImpl, hf.raw); + const primitives = this.debugDrawerUtils.drawHeightfieldSolid(hf); + this.drawPrimitives(primitives); } drawHeightfieldWalkable(hf: RecastHeightfield): void { - Raw.RecastDebugDraw.debugDrawHeightfieldWalkable( - this.debugDrawImpl, - hf.raw - ); + const primitives = this.debugDrawerUtils.drawHeightfieldWalkable(hf); + this.drawPrimitives(primitives); } drawCompactHeightfieldSolid(chf: RecastCompactHeightfield): void { - Raw.RecastDebugDraw.debugDrawCompactHeightfieldSolid( - this.debugDrawImpl, - chf.raw - ); + const primitives = this.debugDrawerUtils.drawCompactHeightfieldSolid(chf); + this.drawPrimitives(primitives); } drawCompactHeightfieldRegions(chf: RecastCompactHeightfield): void { - Raw.RecastDebugDraw.debugDrawCompactHeightfieldRegions( - this.debugDrawImpl, - chf.raw - ); + const primitives = this.debugDrawerUtils.drawCompactHeightfieldRegions(chf); + this.drawPrimitives(primitives); } drawCompactHeightfieldDistance(chf: RecastCompactHeightfield): void { - Raw.RecastDebugDraw.debugDrawCompactHeightfieldDistance( - this.debugDrawImpl, - chf.raw - ); + const primitives = + this.debugDrawerUtils.drawCompactHeightfieldDistance(chf); + this.drawPrimitives(primitives); } drawHeightfieldLayer(layer: RecastHeightfieldLayer, idx: number): void { - Raw.RecastDebugDraw.debugDrawHeightfieldLayer( - this.debugDrawImpl, - layer.raw, - idx - ); + const primitives = this.debugDrawerUtils.drawHeightfieldLayer(layer, idx); + this.drawPrimitives(primitives); } drawHeightfieldLayers(lset: RecastHeightfieldLayerSet): void { - Raw.RecastDebugDraw.debugDrawHeightfieldLayers( - this.debugDrawImpl, - lset.raw - ); + const primitives = this.debugDrawerUtils.drawHeightfieldLayers(lset); + this.drawPrimitives(primitives); } drawRegionConnections(cset: RecastContourSet, alpha: number = 1): void { - Raw.RecastDebugDraw.debugDrawRegionConnections( - this.debugDrawImpl, - cset.raw, - alpha - ); + const primitives = this.debugDrawerUtils.drawRegionConnections(cset, alpha); + this.drawPrimitives(primitives); } drawRawContours(cset: RecastContourSet, alpha: number = 1): void { - Raw.RecastDebugDraw.debugDrawRawContours( - this.debugDrawImpl, - cset.raw, - alpha - ); + const primitives = this.debugDrawerUtils.drawRawContours(cset, alpha); + this.drawPrimitives(primitives); } drawContours(cset: RecastContourSet, alpha: number = 1): void { - Raw.RecastDebugDraw.debugDrawContours(this.debugDrawImpl, cset.raw, alpha); + const primitives = this.debugDrawerUtils.drawContours(cset, alpha); + this.drawPrimitives(primitives); } drawPolyMesh(mesh: RecastPolyMesh): void { - Raw.RecastDebugDraw.debugDrawPolyMesh(this.debugDrawImpl, mesh.raw); + const primitives = this.debugDrawerUtils.drawPolyMesh(mesh); + this.drawPrimitives(primitives); } drawPolyMeshDetail(dmesh: RecastPolyMeshDetail): void { - Raw.RecastDebugDraw.debugDrawPolyMeshDetail(this.debugDrawImpl, dmesh.raw); + const primitives = this.debugDrawerUtils.drawPolyMeshDetail(dmesh); + this.drawPrimitives(primitives); } drawNavMesh(mesh: NavMesh, flags: number = 0): void { - Raw.DetourDebugDraw.debugDrawNavMesh( - this.debugDrawImpl, - mesh.raw.getNavMesh(), - flags - ); + const primitives = this.debugDrawerUtils.drawNavMesh(mesh, flags); + this.drawPrimitives(primitives); } drawNavMeshWithClosedList( @@ -238,51 +180,41 @@ export class DebugDrawer extends Entity { query: NavMeshQuery, flags: number = 0 ): void { - Raw.DetourDebugDraw.debugDrawNavMeshWithClosedList( - this.debugDrawImpl, - mesh.raw.m_navMesh, - query.raw.m_navQuery, + const primitives = this.debugDrawerUtils.drawNavMeshWithClosedList( + mesh, + query, flags ); + this.drawPrimitives(primitives); } drawNavMeshNodes(query: NavMeshQuery): void { - Raw.DetourDebugDraw.debugDrawNavMeshNodes( - this.debugDrawImpl, - query.raw.m_navQuery - ); + const primitives = this.debugDrawerUtils.drawNavMeshNodes(query); + this.drawPrimitives(primitives); } drawNavMeshBVTree(mesh: NavMesh): void { - Raw.DetourDebugDraw.debugDrawNavMeshBVTree( - this.debugDrawImpl, - mesh.raw.m_navMesh - ); + const primitives = this.debugDrawerUtils.drawNavMeshBVTree(mesh); + this.drawPrimitives(primitives); } drawNavMeshPortals(mesh: NavMesh): void { - Raw.DetourDebugDraw.debugDrawNavMeshPortals( - this.debugDrawImpl, - mesh.raw.m_navMesh - ); + const primitives = this.debugDrawerUtils.drawNavMeshPortals(mesh); + this.drawPrimitives(primitives); } drawNavMeshPolysWithFlags(mesh: NavMesh, flags: number, col: number): void { - Raw.DetourDebugDraw.debugDrawNavMeshPolysWithFlags( - this.debugDrawImpl, - mesh.raw.m_navMesh, + const primitives = this.debugDrawerUtils.drawNavMeshPolysWithFlags( + mesh, flags, col ); + this.drawPrimitives(primitives); } drawNavMeshPoly(mesh: NavMesh, ref: number, col: number): void { - Raw.DetourDebugDraw.debugDrawNavMeshPoly( - this.debugDrawImpl, - mesh.raw.m_navMesh, - ref, - col - ); + const primitives = this.debugDrawerUtils.drawNavMeshPoly(mesh, ref, col); + this.drawPrimitives(primitives); } // Implement other drawing methods similarly... @@ -305,30 +237,20 @@ export class DebugDrawer extends Entity { * Disposes of the debug drawer and releases resources. */ dispose(): void { + this.debugDrawerUtils.dispose(); this.reset(); - Raw.Module.destroy(this.debugDrawImpl); - // Dispose materials if necessary - } - - private vertex(x: number, y: number, z: number, color: number) { - const r = ((color >> 16) & 0xff) / 255; - const g = ((color >> 8) & 0xff) / 255; - const b = (color & 0xff) / 255; - const a = ((color >> 24) & 0xff) / 255; - - this.currentVertices.push({ x, y, z, r, g, b, a }); } - private endPoints(): void { + private drawPoints(primitive: DebugDrawerPrimitive): void { const graphicsDevice = this.graphicsDevice; const positions: number[] = []; const colors: number[] = []; - for (let i = 0; i < this.currentVertices.length; i++) { - const vertex = this.currentVertices[i]; - positions.push(vertex.x, vertex.y, vertex.z); - colors.push(vertex.r, vertex.g, vertex.b, vertex.a); + for (let i = 0; i < primitive.vertices.length; i++) { + const [x, y, z, r, g, b, a] = primitive.vertices[i]; + positions.push(x, y, z); + colors.push(r, g, b, a); } const mesh = createPointMesh(graphicsDevice, positions, colors); @@ -340,16 +262,16 @@ export class DebugDrawer extends Entity { this.addChild(entity); } - private endLines(): void { + private drawLines(primitive: DebugDrawerPrimitive): void { const graphicsDevice = this.graphicsDevice; const positions: number[] = []; const colors: number[] = []; - for (let i = 0; i < this.currentVertices.length; i++) { - const vertex = this.currentVertices[i]; - positions.push(vertex.x, vertex.y, vertex.z); - colors.push(vertex.r, vertex.g, vertex.b, vertex.a); + for (let i = 0; i < primitive.vertices.length; i++) { + const [x, y, z, r, g, b, a] = primitive.vertices[i]; + positions.push(x, y, z); + colors.push(r, g, b, a); } const mesh = createLineMesh(graphicsDevice, positions, colors); @@ -361,16 +283,16 @@ export class DebugDrawer extends Entity { this.addChild(entity); } - private endTris(): void { + private drawTris(primitive: DebugDrawerPrimitive): void { const graphicsDevice = this.graphicsDevice; const positions: number[] = []; const colors: number[] = []; - for (let i = 0; i < this.currentVertices.length; i++) { - const vertex = this.currentVertices[i]; - positions.push(vertex.x, vertex.y, vertex.z); - colors.push(vertex.r, vertex.g, vertex.b, vertex.a); + for (let i = 0; i < primitive.vertices.length; i++) { + const [x, y, z, r, g, b, a] = primitive.vertices[i]; + positions.push(x, y, z); + colors.push(r, g, b, a); } const mesh = createTriangleMesh(graphicsDevice, positions, colors); @@ -382,52 +304,26 @@ export class DebugDrawer extends Entity { this.addChild(entity); } - private endQuads(): void { + private drawQuads(primitive: DebugDrawerPrimitive): void { // Quads are converted to triangles const graphicsDevice = this.graphicsDevice; const positions: number[] = []; const colors: number[] = []; - for (let i = 0; i < this.currentVertices.length; i += 4) { - const v0 = this.currentVertices[i]; - const v1 = this.currentVertices[i + 1]; - const v2 = this.currentVertices[i + 2]; - const v3 = this.currentVertices[i + 3]; + for (let i = 0; i < primitive.vertices.length; i += 4) { + const [x0, y0, z0, r0, g0, b0, a0] = primitive.vertices[i]; + const [x1, y1, z1, r1, g1, b1, a1] = primitive.vertices[i + 1]; + const [x2, y2, z2, r2, g2, b2, a2] = primitive.vertices[i + 2]; + const [x3, y3, z3, r3, g3, b3, a3] = primitive.vertices[i + 3]; // First triangle (v0, v1, v2) - positions.push(v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, v2.x, v2.y, v2.z); - colors.push( - v0.r, - v0.g, - v0.b, - v0.a, - v1.r, - v1.g, - v1.b, - v1.a, - v2.r, - v2.g, - v2.b, - v2.a - ); + positions.push(x0, y0, z0, x1, y1, z1, x2, y2, z2); + colors.push(r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2); // Second triangle (v0, v2, v3) - positions.push(v0.x, v0.y, v0.z, v2.x, v2.y, v2.z, v3.x, v3.y, v3.z); - colors.push( - v0.r, - v0.g, - v0.b, - v0.a, - v2.r, - v2.g, - v2.b, - v2.a, - v3.r, - v3.g, - v3.b, - v3.a - ); + positions.push(x0, y0, z0, x2, y2, z2, x3, y3, z3); + colors.push(r0, g0, b0, a0, r2, g2, b2, a2, r3, g3, b3, a3); } const mesh = createTriangleMesh(graphicsDevice, positions, colors); diff --git a/packages/recast-navigation-three/src/debug/debug-drawer.ts b/packages/recast-navigation-three/src/debug/debug-drawer.ts index 1ab35245..7672132a 100644 --- a/packages/recast-navigation-three/src/debug/debug-drawer.ts +++ b/packages/recast-navigation-three/src/debug/debug-drawer.ts @@ -1,7 +1,8 @@ import { + DebugDrawerPrimitive, + DebugDrawerUtils, NavMesh, NavMeshQuery, - Raw, RecastCompactHeightfield, RecastContourSet, RecastHeightfield, @@ -17,16 +18,6 @@ import { LineSegmentsGeometry, } from 'three/addons'; -type VertexData = [ - x: number, - y: number, - z: number, - r: number, - g: number, - b: number, - a: number, -]; - const _color = new THREE.Color(); export type DebugDrawerParams = { @@ -43,10 +34,7 @@ export class DebugDrawer extends THREE.Group { lineMaterial: LineMaterial; - private debugDrawImpl: InstanceType; - - private currentVertices: VertexData[] = []; - private currentPrimitive = 0; + private debugDrawerUtils: DebugDrawerUtils; constructor({ triMaterial, @@ -55,6 +43,8 @@ export class DebugDrawer extends THREE.Group { }: DebugDrawerParams = {}) { super(); + this.debugDrawerUtils = new DebugDrawerUtils(); + this.triMaterial = triMaterial ?? new THREE.MeshBasicMaterial({ @@ -76,136 +66,91 @@ export class DebugDrawer extends THREE.Group { polygonOffsetFactor: -4, polygonOffsetUnits: -10, }); + } - this.debugDrawImpl = new Raw.Module.DebugDrawImpl(); - - this.debugDrawImpl.handleBegin = (primitive: number, _size: number) => { - this.currentPrimitive = primitive; - this.currentVertices = []; - }; - - this.debugDrawImpl.handleDepthMask = (_state: number) => { - // all methods must be implemented for JSImplentation - }; - - this.debugDrawImpl.handleTexture = (_state: number) => { - // all methods must be implemented for JSImplentation - }; - - this.debugDrawImpl.handleVertexWithColor = ( - x: number, - y: number, - z: number, - color: number - ) => { - this.vertex(x, y, z, color); - }; - - this.debugDrawImpl.handleVertexWithColorAndUV = ( - x: number, - y: number, - z: number, - color: number, - _u: number, - _v: number - ) => { - this.vertex(x, y, z, color); - }; - - this.debugDrawImpl.handleEnd = () => { - if (this.currentPrimitive === Raw.Module.DU_DRAW_LINES) { - this.endLines(); - } else if (this.currentPrimitive === Raw.Module.DU_DRAW_TRIS) { - this.endTris(); - } else if (this.currentPrimitive === Raw.Module.DU_DRAW_QUADS) { - this.endQuads(); - } else if (this.currentPrimitive === Raw.Module.DU_DRAW_POINTS) { - this.endPoints(); + drawPrimitives(primitives: DebugDrawerPrimitive[]): void { + for (const primitive of primitives) { + switch (primitive.type) { + case 'points': + this.drawPoints(primitive); + break; + case 'lines': + this.drawLines(primitive); + break; + case 'tris': + this.drawTris(primitive); + break; + case 'quads': + this.drawQuads(primitive); + break; } - }; + } } drawHeightfieldSolid(hf: RecastHeightfield): void { - Raw.RecastDebugDraw.debugDrawHeightfieldSolid(this.debugDrawImpl, hf.raw); + const primitives = this.debugDrawerUtils.drawHeightfieldSolid(hf); + this.drawPrimitives(primitives); } drawHeightfieldWalkable(hf: RecastHeightfield): void { - Raw.RecastDebugDraw.debugDrawHeightfieldWalkable( - this.debugDrawImpl, - hf.raw - ); + const primitives = this.debugDrawerUtils.drawHeightfieldWalkable(hf); + this.drawPrimitives(primitives); } drawCompactHeightfieldSolid(chf: RecastCompactHeightfield): void { - Raw.RecastDebugDraw.debugDrawCompactHeightfieldSolid( - this.debugDrawImpl, - chf.raw - ); + const primitives = this.debugDrawerUtils.drawCompactHeightfieldSolid(chf); + this.drawPrimitives(primitives); } drawCompactHeightfieldRegions(chf: RecastCompactHeightfield): void { - Raw.RecastDebugDraw.debugDrawCompactHeightfieldRegions( - this.debugDrawImpl, - chf.raw - ); + const primitives = this.debugDrawerUtils.drawCompactHeightfieldRegions(chf); + this.drawPrimitives(primitives); } drawCompactHeightfieldDistance(chf: RecastCompactHeightfield): void { - Raw.RecastDebugDraw.debugDrawCompactHeightfieldDistance( - this.debugDrawImpl, - chf.raw - ); + const primitives = + this.debugDrawerUtils.drawCompactHeightfieldDistance(chf); + this.drawPrimitives(primitives); } drawHeightfieldLayer(layer: RecastHeightfieldLayer, idx: number): void { - Raw.RecastDebugDraw.debugDrawHeightfieldLayer( - this.debugDrawImpl, - layer.raw, - idx - ); + const primitives = this.debugDrawerUtils.drawHeightfieldLayer(layer, idx); + this.drawPrimitives(primitives); } drawHeightfieldLayers(lset: RecastHeightfieldLayerSet): void { - Raw.RecastDebugDraw.debugDrawHeightfieldLayers( - this.debugDrawImpl, - lset.raw - ); + const primitives = this.debugDrawerUtils.drawHeightfieldLayers(lset); + this.drawPrimitives(primitives); } drawRegionConnections(cset: RecastContourSet, alpha: number = 1): void { - Raw.RecastDebugDraw.debugDrawRegionConnections( - this.debugDrawImpl, - cset.raw, - alpha - ); + const primitives = this.debugDrawerUtils.drawRegionConnections(cset, alpha); + this.drawPrimitives(primitives); } drawRawContours(cset: RecastContourSet, alpha: number = 1): void { - Raw.RecastDebugDraw.debugDrawRawContours( - this.debugDrawImpl, - cset.raw, - alpha - ); + const primitives = this.debugDrawerUtils.drawRawContours(cset, alpha); + this.drawPrimitives(primitives); } drawContours(cset: RecastContourSet, alpha: number = 1): void { - Raw.RecastDebugDraw.debugDrawContours(this.debugDrawImpl, cset.raw, alpha); + const primitives = this.debugDrawerUtils.drawContours(cset, alpha); + this.drawPrimitives(primitives); } drawPolyMesh(mesh: RecastPolyMesh): void { - Raw.RecastDebugDraw.debugDrawPolyMesh(this.debugDrawImpl, mesh.raw); + const primitives = this.debugDrawerUtils.drawPolyMesh(mesh); + this.drawPrimitives(primitives); } drawPolyMeshDetail(dmesh: RecastPolyMeshDetail): void { - Raw.RecastDebugDraw.debugDrawPolyMeshDetail(this.debugDrawImpl, dmesh.raw); + const primitives = this.debugDrawerUtils.drawPolyMeshDetail(dmesh); + this.drawPrimitives(primitives); } drawNavMesh(mesh: NavMesh, flags: number = 0): void { - Raw.DetourDebugDraw.debugDrawNavMesh( - this.debugDrawImpl, - mesh.raw.getNavMesh(), - flags - ); + const primitives = this.debugDrawerUtils.drawNavMesh(mesh, flags); + this.drawPrimitives(primitives); } drawNavMeshWithClosedList( @@ -213,51 +158,41 @@ export class DebugDrawer extends THREE.Group { query: NavMeshQuery, flags: number = 0 ): void { - Raw.DetourDebugDraw.debugDrawNavMeshWithClosedList( - this.debugDrawImpl, - mesh.raw.m_navMesh, - query.raw.m_navQuery, + const primitives = this.debugDrawerUtils.drawNavMeshWithClosedList( + mesh, + query, flags ); + this.drawPrimitives(primitives); } drawNavMeshNodes(query: NavMeshQuery): void { - Raw.DetourDebugDraw.debugDrawNavMeshNodes( - this.debugDrawImpl, - query.raw.m_navQuery - ); + const primitives = this.debugDrawerUtils.drawNavMeshNodes(query); + this.drawPrimitives(primitives); } drawNavMeshBVTree(mesh: NavMesh): void { - Raw.DetourDebugDraw.debugDrawNavMeshBVTree( - this.debugDrawImpl, - mesh.raw.m_navMesh - ); + const primitives = this.debugDrawerUtils.drawNavMeshBVTree(mesh); + this.drawPrimitives(primitives); } drawNavMeshPortals(mesh: NavMesh): void { - Raw.DetourDebugDraw.debugDrawNavMeshPortals( - this.debugDrawImpl, - mesh.raw.m_navMesh - ); + const primitives = this.debugDrawerUtils.drawNavMeshPortals(mesh); + this.drawPrimitives(primitives); } drawNavMeshPolysWithFlags(mesh: NavMesh, flags: number, col: number): void { - Raw.DetourDebugDraw.debugDrawNavMeshPolysWithFlags( - this.debugDrawImpl, - mesh.raw.m_navMesh, + const primitives = this.debugDrawerUtils.drawNavMeshPolysWithFlags( + mesh, flags, col ); + this.drawPrimitives(primitives); } drawNavMeshPoly(mesh: NavMesh, ref: number, col: number): void { - Raw.DetourDebugDraw.debugDrawNavMeshPoly( - this.debugDrawImpl, - mesh.raw.m_navMesh, - ref, - col - ); + const primitives = this.debugDrawerUtils.drawNavMeshPoly(mesh, ref, col); + this.drawPrimitives(primitives); } // todo: @@ -277,10 +212,10 @@ export class DebugDrawer extends THREE.Group { } dispose(): void { + this.debugDrawerUtils.dispose(); + this.reset(); - Raw.Module.destroy(this.debugDrawImpl); - this.pointGeometry.dispose(); this.triMaterial.dispose(); @@ -288,30 +223,24 @@ export class DebugDrawer extends THREE.Group { this.lineMaterial.dispose(); } - private vertex(x: number, y: number, z: number, color: number) { - const r = ((color >> 16) & 0xff) / 255; - const g = ((color >> 8) & 0xff) / 255; - const b = (color & 0xff) / 255; - const a = ((color >> 24) & 0xff) / 255; - - this.currentVertices.push([x, y, z, r, g, b, a]); - } - - private endPoints(): void { + private drawPoints(primitive: DebugDrawerPrimitive): void { const geometry = this.pointGeometry; const instancedMesh = new THREE.InstancedMesh( geometry, this.pointMaterial, - this.currentVertices.length + primitive.vertices.length / 3 ); - for (let i = 0; i < this.currentVertices.length; i++) { - const [x, y, z, r, g, b] = this.currentVertices[i]; + for (let point = 0; point < primitive.vertices.length / 7; point++) { + const [x, y, z, r, g, b] = primitive.vertices[point]; - instancedMesh.setMatrixAt(i, new THREE.Matrix4().setPosition(x, y, z)); + instancedMesh.setMatrixAt( + point, + new THREE.Matrix4().setPosition(x, y, z) + ); - instancedMesh.setColorAt(i, _color.setRGB(r, g, b)); + instancedMesh.setColorAt(point, _color.setRGB(r, g, b)); } instancedMesh.instanceMatrix.needsUpdate = true; @@ -319,15 +248,15 @@ export class DebugDrawer extends THREE.Group { this.add(instancedMesh); } - private endLines(): void { + private drawLines(primitive: DebugDrawerPrimitive): void { const lineSegmentsGeometry = new LineSegmentsGeometry(); const positions: number[] = []; const colors: number[] = []; - for (let i = 0; i < this.currentVertices.length; i += 2) { - const [x1, y1, z1, r1, g1, b1] = this.currentVertices[i]; - const [x2, y2, z2, r2, g2, b2] = this.currentVertices[i + 1]; + for (let i = 0; i < primitive.vertices.length; i += 2) { + const [x1, y1, z1, r1, g1, b1] = primitive.vertices[i]; + const [x2, y2, z2, r2, g2, b2] = primitive.vertices[i + 1]; positions.push(x1, y1, z1); positions.push(x2, y2, z2); @@ -347,13 +276,14 @@ export class DebugDrawer extends THREE.Group { this.add(lineSegments); } - private endTris(): void { + private drawTris(primitive: DebugDrawerPrimitive): void { const geometry = new THREE.BufferGeometry(); - const positions = new Float32Array(this.currentVertices.length * 3); - const colors = new Float32Array(this.currentVertices.length * 3); + const positions = new Float32Array(primitive.vertices.length * 3); + const colors = new Float32Array(primitive.vertices.length * 3); + + for (let i = 0; i < primitive.vertices.length; i++) { + const [x, y, z, r, g, b] = primitive.vertices[i]; - for (let i = 0; i < this.currentVertices.length; i++) { - const [x, y, z, r, g, b] = this.currentVertices[i]; positions[i * 3 + 0] = x; positions[i * 3 + 1] = y; positions[i * 3 + 2] = z; @@ -372,19 +302,18 @@ export class DebugDrawer extends THREE.Group { this.add(mesh); } - private endQuads(): void { + private drawQuads(primitive: DebugDrawerPrimitive): void { const positions: number[] = []; const colors: number[] = []; - for (let i = 0; i < this.currentVertices.length; i += 4) { + for (let i = 0; i < primitive.vertices.length; i += 4) { const vertices = [ - this.currentVertices[i], - this.currentVertices[i + 1], - this.currentVertices[i + 2], - - this.currentVertices[i], - this.currentVertices[i + 2], - this.currentVertices[i + 3], + primitive.vertices[i], + primitive.vertices[i + 1], + primitive.vertices[i + 2], + primitive.vertices[i], + primitive.vertices[i + 2], + primitive.vertices[i + 3], ]; for (const [x, y, z, r, g, b] of vertices) {