UNPKG

@inweb/viewer-visualize

Version:

JavaScript library for rendering CAD and BIM files in a browser using VisualizeJS

185 lines (142 loc) 5.74 kB
/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a // license agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// /* eslint-disable no-unused-vars */ import { Viewer } from "../Viewer"; import { Point2d } from "./Common/Geometry"; import { ViewParams } from "./Common/OdaGeAction"; import { OdBaseDragger } from "./Common/OdBaseDragger"; export class OrbitAroundBuildingDragger extends OdBaseDragger { protected maxPolarAngle: number; protected minPolarAngle: number; protected m_viewCenter: any; protected m_startPoint: Point2d; protected startCameraParams: ViewParams; protected m_delta: number; constructor(viewer: Viewer) { super(viewer); this.autoSelect = true; this.press = false; this.maxPolarAngle = Math.PI / 2; this.minPolarAngle = 0; // radians } override start(x: number, y: number): void { this.press = true; this.m_viewCenter = this.getCenter(); this.m_startPoint = { x, y }; const view = this.getViewer().activeView; this.startCameraParams = this.getViewParams(); const corners = view.vportRect; this.m_delta = Math.max(corners[1] - corners[0], corners[2] - corners[3]); this.beginInteractivity(); } setDefaultViewParams(): void { this.setViewParams(this.startCameraParams); } override drag(x: number, y: number): void { if (this.press) { let dX = x - this.m_startPoint.x; let dY = y - this.m_startPoint.y; dX *= Math.PI / this.m_delta; dY *= Math.PI / this.m_delta; this.setDefaultViewParams(); const { Vector3d, Matrix3d } = this.m_module; const target = Vector3d.createFromArray(this.startCameraParams.target); const offset = Vector3d.createFromArray(this.startCameraParams.position).sub(target); const dir = offset.normalize(); const zMatrix = new Matrix3d(); zMatrix.setToIdentity(); const xMatrix = new Matrix3d(); xMatrix.setToIdentity(); // ---- restore start rotation ---- const yAxis = Vector3d.createFromArray([dir.x, dir.y, dir.z]); const zAxis = Vector3d.createFromArray(this.startCameraParams.upVector); const xAxis = yAxis.crossProduct(zAxis); // ----------- zAxis rotation restore ----------- let xyDir = Vector3d.createFromArray([yAxis.x, yAxis.y, 0]); if (xyDir.length() <= 0.00001) { xyDir.set(-xAxis.y, xAxis.x, 0); } else { xyDir = xyDir.normalize(); } const xyAngle = Math.sign(xyDir.dotProduct(Vector3d.createFromArray([-1, 0, 0]))) * xyDir.angleTo(Vector3d.createFromArray([0, 1, 0])); dX -= xyAngle; // ----------- zAxis rotation restore ----------- // ----------- xAxis rotation restore ----------- let yzDir = Vector3d.createFromArray([dir.x, dir.y, 0]); let yzAngle = 0; if (yzDir.length() <= 0.00001) { yzAngle = (-dir.z * Math.PI) / 2; } else { yzDir = yzDir.normalize(); yzAngle = -yzDir.angleTo(dir); } dY -= yzAngle; // ----------- xAxis rotation restore ----------- // ---- restore start rotation ---- zMatrix.setToRotation(-dX, [0, 0, 1], [0, 0, 0]); const xAngle = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, dY)); xMatrix.setToRotation(xAngle, [1, 0, 0], [0, 0, 0]); const endMatrix = zMatrix.postMultBy(xMatrix); let pos = Vector3d.createFromArray([0, 1, 0]).transformBy(endMatrix); const up = Vector3d.createFromArray([0, 0, 1]).transformBy(endMatrix); pos.setLength(offset.length()); pos = target.add(pos); const current = this.getViewParams(); current.position = pos.toArray(); current.upVector = up.toArray(); this.setViewParams(current); } } override end(): void { this.press = false; this.endInteractivity(); } getCenter(): any { const viewer = this.getViewer(); let ext = viewer.getActiveExtents(); const pSet = viewer.getSelected(); if (!pSet.isNull() && pSet.numItems() !== 0) { const itr = pSet.getIterator(); const entId = itr.getEntity(); if (entId.getType() === 1) { const obj = entId.openObject(); ext.delete(); ext = obj.getExtents(); obj.delete(); } else if (entId.getType() === 2) { const obj = entId.openObjectAsInsert(); const extTuple = obj.getExtents(); ext.delete(); ext = extTuple.ext; extTuple.delete(); obj.delete(); } itr.delete(); } const center = ext.center(); ext.delete(); return center; } }