From 14b0863d64e1da148e74f28095843acf9f86dcc6 Mon Sep 17 00:00:00 2001 From: kovacsv Date: Sun, 18 Sep 2022 13:01:51 +0200 Subject: [PATCH] Add orthographic mode to the viewer class. --- source/engine/main.js | 4 +- source/engine/viewer/viewer.js | 97 +++++++++++++++++++++++++++++++--- 2 files changed, 93 insertions(+), 8 deletions(-) diff --git a/source/engine/main.js b/source/engine/main.js index 1c89e3a..0ab8c13 100644 --- a/source/engine/main.js +++ b/source/engine/main.js @@ -68,7 +68,7 @@ import { Camera, CameraIsEqual3D } from './viewer/camera.js'; import { GetIntegerFromStyle, GetDomElementExternalWidth, GetDomElementExternalHeight, GetDomElementInnerDimensions, GetDomElementClientCoordinates, CreateDomElement, AddDomElement, AddDiv, ClearDomElement, InsertDomElementBefore, InsertDomElementAfter, ShowDomElement, IsDomElementVisible, SetDomElementWidth, SetDomElementHeight, GetDomElementOuterWidth, GetDomElementOuterHeight, SetDomElementOuterWidth, SetDomElementOuterHeight, CreateDiv } from './viewer/domutils.js'; import { EmbeddedViewer, Init3DViewerElement, Init3DViewerElements } from './viewer/embeddedviewer.js'; import { MouseInteraction, TouchInteraction, ClickDetector, Navigation, NavigationType } from './viewer/navigation.js'; -import { UpVector, ShadingModel, Viewer, GetDefaultCamera, TraverseThreeObject, GetShadingTypeOfObject } from './viewer/viewer.js'; +import { CameraValidator, UpVector, ShadingModel, Viewer, GetDefaultCamera, TraverseThreeObject, GetShadingTypeOfObject, CameraMode } from './viewer/viewer.js'; import { ViewerGeometry, ViewerExtraGeometry, SetThreeMeshPolygonOffset } from './viewer/viewergeometry.js'; export { @@ -316,12 +316,14 @@ export { ClickDetector, Navigation, NavigationType, + CameraValidator, UpVector, ShadingModel, Viewer, GetDefaultCamera, TraverseThreeObject, GetShadingTypeOfObject, + CameraMode, ViewerGeometry, ViewerExtraGeometry, SetThreeMeshPolygonOffset diff --git a/source/engine/viewer/viewer.js b/source/engine/viewer/viewer.js index 25f5182..fa5523a 100644 --- a/source/engine/viewer/viewer.js +++ b/source/engine/viewer/viewer.js @@ -1,5 +1,5 @@ import { Coord3D, CoordDistance3D, SubCoord3D } from '../geometry/coord3d.js'; -import { Direction } from '../geometry/geometry.js'; +import { DegRad, Direction, IsEqual } from '../geometry/geometry.js'; import { ColorComponentToFloat } from '../model/color.js'; import { ShadingType } from '../threejs/threeutils.js'; import { Camera } from './camera.js'; @@ -9,6 +9,12 @@ import { ViewerExtraGeometry, ViewerGeometry } from './viewergeometry.js'; import * as THREE from 'three'; +export const CameraMode = +{ + Perspective : 1, + Orthographic : 2 +}; + export function GetDefaultCamera (direction) { let fieldOfView = 45.0; @@ -69,6 +75,39 @@ export function GetShadingTypeOfObject (mainObject) return shadingType; } +export class CameraValidator +{ + constructor () + { + this.eyeCenterDistance = 0.0; + this.forceUpdate = true; + } + + ForceUpdate () + { + this.forceUpdate = true; + } + + ValidatePerspective () + { + if (this.forceUpdate) { + this.forceUpdate = false; + return false; + } + return true; + } + + ValidateOrthographic (eyeCenterDistance) + { + if (this.forceUpdate || !IsEqual (this.eyeCenterDistance, eyeCenterDistance)) { + this.eyeCenterDistance = eyeCenterDistance; + this.forceUpdate = false; + return false; + } + return true; + } +} + export class UpVector { constructor () @@ -209,6 +248,8 @@ export class Viewer this.geometry = null; this.extraGeometry = null; this.camera = null; + this.cameraMode = null; + this.cameraValidator = null; this.shading = null; this.navigation = null; this.upVector = null; @@ -299,8 +340,27 @@ export class Viewer SetCamera (camera) { this.navigation.SetCamera (camera); - this.camera.fov = camera.fov; - this.camera.updateProjectionMatrix (); + this.cameraValidator.ForceUpdate (); + this.Render (); + } + + SetCameraMode (cameraMode) + { + if (this.cameraMode === cameraMode) { + return; + } + + this.scene.remove (this.camera); + if (cameraMode === CameraMode.Perspective) { + this.camera = new THREE.PerspectiveCamera (45.0, 1.0, 0.1, 1000.0); + } else if (cameraMode === CameraMode.Orthographic) { + this.camera = new THREE.OrthographicCamera (-1.0, 1.0, 1.0, -1.0, 0.1, 1000.0); + } + this.scene.add (this.camera); + + this.cameraMode = cameraMode; + this.cameraValidator.ForceUpdate (); + this.Render (); } @@ -315,9 +375,8 @@ export class Viewer if (window.devicePixelRatio) { this.renderer.setPixelRatio (window.devicePixelRatio); } - this.camera.aspect = width / height; - this.camera.updateProjectionMatrix (); this.renderer.setSize (width, height); + this.cameraValidator.ForceUpdate (); this.Render (); } @@ -351,7 +410,8 @@ export class Viewer this.camera.near = 100.0; this.camera.far = 1000000.0; } - this.camera.updateProjectionMatrix (); + + this.cameraValidator.ForceUpdate (); this.Render (); } @@ -391,10 +451,31 @@ export class Viewer Render () { let navigationCamera = this.navigation.GetCamera (); + this.camera.position.set (navigationCamera.eye.x, navigationCamera.eye.y, navigationCamera.eye.z); this.camera.up.set (navigationCamera.up.x, navigationCamera.up.y, navigationCamera.up.z); this.camera.lookAt (new THREE.Vector3 (navigationCamera.center.x, navigationCamera.center.y, navigationCamera.center.z)); + if (this.cameraMode === CameraMode.Perspective) { + if (!this.cameraValidator.ValidatePerspective ()) { + this.camera.aspect = this.canvas.width / this.canvas.height; + this.camera.fov = navigationCamera.fov; + this.camera.updateProjectionMatrix (); + } + } else if (this.cameraMode === CameraMode.Orthographic) { + let eyeCenterDistance = CoordDistance3D (navigationCamera.eye, navigationCamera.center); + if (!this.cameraValidator.ValidateOrthographic (eyeCenterDistance)) { + let aspect = this.canvas.width / this.canvas.height; + let eyeCenterDistance = CoordDistance3D (navigationCamera.eye, navigationCamera.center); + let frustumHalfHeight = eyeCenterDistance * Math.tan (0.5 * navigationCamera.fov * DegRad); + this.camera.left = -frustumHalfHeight * aspect; + this.camera.right = frustumHalfHeight * aspect; + this.camera.top = frustumHalfHeight; + this.camera.bottom = -frustumHalfHeight; + this.camera.updateProjectionMatrix (); + } + } + this.shading.UpdateByCamera (navigationCamera); this.renderer.render (this.scene, this.camera); } @@ -519,7 +600,9 @@ export class Viewer InitNavigation () { let camera = GetDefaultCamera (Direction.Z); - this.camera = new THREE.PerspectiveCamera (camera.fov, this.canvas.width / this.canvas.height, 0.1, 1000.0); + this.camera = new THREE.PerspectiveCamera (45.0, 1.0, 0.1, 1000.0); + this.cameraMode = CameraMode.Perspective; + this.cameraValidator = new CameraValidator (); this.scene.add (this.camera); let canvasElem = this.renderer.domElement;