Press n or j to go to the next uncovered block, b, p or k for the previous block.
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 79 80 | 20x 20x 47x 47x 47x 130x 109x 1x 7x | import { CodeMapBuilding } from "./codeMapBuilding" import { Vector3, Ray, Box3 } from "three" import { Scaling } from "../../../codeCharta.model" export class CodeMapGeometricDescription { private _buildings: CodeMapBuilding[] // todo tk: depending on how many buildings, refactor this to { [node.path]: node } might give `this.getBuildingByPath` a performance boost private mapSize: number private scales: Vector3 constructor(mapSize: number) { this._buildings = new Array<CodeMapBuilding>() this.mapSize = mapSize this.scales = new Vector3(1, 1, 1) } add(building: CodeMapBuilding) { this._buildings.push(building) } get buildings() { return this._buildings } setScales(scales: Scaling) { this.scales = new Vector3(scales.x, scales.y, scales.z) } getBuildingByPath(path: string) { return this.buildings.find(x => x.node.path === path) } intersect(ray: Ray) { let intersectedBuilding: CodeMapBuilding let leastIntersectedDistance = Number.POSITIVE_INFINITY const boxTranslation = this.scales .clone() .multiplyScalar(this.mapSize) .multiply(new Vector3(-1, 0, -1)) for (const building of this._buildings) { const box: Box3 = building.boundingBox.clone() box.min.multiply(this.scales) box.max.multiply(this.scales) box.translate(boxTranslation) Iif (this.rayIntersectsAxisAlignedBoundingBox(ray, box)) { const intersectionPoint: Vector3 = ray.intersectBox(box, new Vector3()) Iif (intersectionPoint) { const intersectionDistance = intersectionPoint.distanceTo(ray.origin) Iif (intersectionDistance < leastIntersectedDistance) { leastIntersectedDistance = intersectionDistance intersectedBuilding = building } } } } return intersectedBuilding } private rayIntersectsAxisAlignedBoundingBox(ray: Ray, box: Box3) { const tx1 = (box.min.x - ray.origin.x) * (1 / ray.direction.x) const tx2 = (box.max.x - ray.origin.x) * (1 / ray.direction.x) let tmin = Math.min(tx1, tx2) let tmax = Math.max(tx1, tx2) const ty1 = (box.min.y - ray.origin.y) * (1 / ray.direction.y) const ty2 = (box.max.y - ray.origin.y) * (1 / ray.direction.y) tmin = Math.max(tmin, Math.min(ty1, ty2)) tmax = Math.min(tmax, Math.max(ty1, ty2)) return tmax >= tmin } } |