diff --git a/src/client/object/camera.ts b/src/client/object/camera.ts index edb6e3d..eac557e 100644 --- a/src/client/object/camera.ts +++ b/src/client/object/camera.ts @@ -62,7 +62,7 @@ export class ThirdPersonCamera { mousemove: (e: MouseEvent) => this.dragEvent(e.clientX, e.clientY), wheel: (e: WheelEvent) => { e.deltaY < 0 ? (this.distance /= 1.2) : (this.distance *= 1.2); - this.distance = clamp(this.distance, 4, 20); + this.distance = clamp(this.distance, 3, 20); this.calculateCameraOffset(); }, // mobile @@ -88,22 +88,19 @@ export class ThirdPersonCamera { if (this.previousPinchLength) { const delta = pinchLength / this.previousPinchLength; delta > 0 ? (this.distance *= delta) : (this.distance /= delta); - this.distance = clamp(this.distance, 4, 20); + this.distance = clamp(this.distance, 3, 20); this.calculateCameraOffset(); } this.previousPinchLength = pinchLength; - } else { + } else if (this.panning) { this.dragEvent(ev.touches[0].clientX, ev.touches[0].clientY); } }, touchend: (ev: TouchEvent) => { this.pinching = false; + this.panning = false; this.previousPinchLength = 0; - - if (!ev.touches?.length) { - this.panning = false; - } }, }; diff --git a/src/client/object/world/quadtree/quadtree-node.ts b/src/client/object/world/quadtree/quadtree-node.ts index b7a23ad..a5655a0 100644 --- a/src/client/object/world/quadtree/quadtree-node.ts +++ b/src/client/object/world/quadtree/quadtree-node.ts @@ -21,21 +21,22 @@ export enum LODSide { LEFT, } -export function mirrorSide(x: number): number { - return (x + 2) % 4; +export function mirrorSide(side: number): number { + return (side + 2) % 4; } -export function isAdjacent(s: number, q: number): boolean { - return (4 + q - s) % 4 <= 1; +export function isAdjacent(side: number, quadrant: number): boolean { + return (4 + quadrant - side) % 4 <= 1; } -export function reflectSide(s: number, q: number): number { - return s % 2 ? (q % 2 ? q - 1 : q + 1) : 3 - q; +export function reflectSide(side: number, quadrant: number): number { + return side % 2 ? (quadrant % 2 ? quadrant - 1 : quadrant + 1) : 3 - quadrant; } export class QuadtreeNode { - public _children: QuadtreeNode[] = []; - public _neighbors: QuadtreeNode[] = []; + private _children: QuadtreeNode[] = []; + private _neighbors: QuadtreeNode[] = []; + private _detailDifferences: number[] = []; private _leaf = true; private _mesh?: Mesh; @@ -103,7 +104,12 @@ export class QuadtreeNode { public setNeighbor(side: LODSide, neighbor: QuadtreeNode) { this._neighbors[side] = neighbor; - neighbor._neighbors[mirrorSide(side)] = this; + if (neighbor) { + const mirrored = mirrorSide(side); + neighbor._neighbors[mirrored] = this; + neighbor._updateNeighborDetailDifferences(mirrored); + } + this._updateNeighborDetailDifferences(side); } public findNeighbor(side: LODSide) { @@ -128,6 +134,31 @@ export class QuadtreeNode { } } + private _equalOrHigherNeighbor(side: LODSide): QuadtreeNode { + for (let node: QuadtreeNode = this; !!node; node = node.parent) { + if (node?._neighbors[side]) { + return node._neighbors[side]; + } + } + return null; + } + + private _updateNeighborDetailDifferences(side: LODSide) { + for (let i = 0; i < 4; i++) { + const neighbor = this._equalOrHigherNeighbor(i); + if (neighbor) { + this._detailDifferences[i] = Math.min(this.level - neighbor.level, 4); + } + } + + if (!this._leaf) { + for (let i = 0; i < 4; i++) { + if (isAdjacent(side, i)) + this._children[i]._updateNeighborDetailDifferences(side); + } + } + } + private _createGeometry(): BufferGeometry { const apparentSize = this.root.size / Math.pow(2, this.level); const vertCount = @@ -144,36 +175,50 @@ export class QuadtreeNode { const vertDivj = y / (vertCount - 1); const vertDivi = x / (vertCount - 1); - const absX = this.position.x + (y / (vertCount - 1)) * apparentSize; - const absY = this.position.y + (x / (vertCount - 1)) * apparentSize; + const absX = this.position.x + vertDivj * apparentSize; + const absY = this.position.y + vertDivi * apparentSize; const normal = this.root.getNormal(absX, absY); + const height = this.root.getHeight(absX, absY); // Calculate relative resolution const pj = vertDivj * (this.root.size / divisionLevel); const pi = vertDivi * (this.root.size / divisionLevel); - vertices.push(pj, this.root.getHeight(absX, absY), pi); + vertices.push(pj, height, pi); normals.push(normal.x, normal.y, normal.z); uvs.push(absX / (this.root.size - 1), absY / (this.root.size - 1)); + + // Create quad + if (x !== vertCount - 1 && y !== vertCount - 1) { + const topLeft = x * vertCount + y; + const topRight = topLeft + 1; + const bottomLeft = (x + 1) * vertCount + y; + const bottomRight = bottomLeft + 1; + indices.push( + topLeft, + bottomLeft, + topRight, + topRight, + bottomLeft, + bottomRight, + ); + } } } - for (let x = 0; x < vertCount - 1; x++) { - for (let y = 0; y < vertCount - 1; y++) { - const topLeft = x * vertCount + y; - const topRight = topLeft + 1; - const bottomLeft = (x + 1) * vertCount + y; - const bottomRight = bottomLeft + 1; - indices.push( - topLeft, - bottomLeft, - topRight, - topRight, - bottomLeft, - bottomRight, - ); - } - } + // for (let test = 1; test < vertCount; test += 2) { + // // bottom + // vertices[test * 3 + 1] = vertices[test * 3 + 1] + 2; + // // top + // const testi = vertCount * vertCount * 3 - vertCount * 3 + test * 3; + // vertices[testi + 1] = vertices[testi + 1] + 2; + // // right + // const testi2 = vertCount * 3 * test; + // vertices[testi2 + 1] = vertices[testi2 + 1] + 2; + // // left + // const testi3 = vertCount * 3 * test + (vertCount - 1) * 3; + // vertices[testi3 + 1] = vertices[testi3 + 1] + 2; + // } geometry.setIndex(indices); geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));