diff --git a/packages/frontend-2/components/tour/Segmentation.vue b/packages/frontend-2/components/tour/Segmentation.vue
index e1b226b35..70fbb4f47 100644
--- a/packages/frontend-2/components/tour/Segmentation.vue
+++ b/packages/frontend-2/components/tour/Segmentation.vue
@@ -64,7 +64,7 @@
diff --git a/packages/frontend-2/lib/tour/slideshowItems.ts b/packages/frontend-2/lib/tour/slideshowItems.ts
index b677686ae..3d8523427 100644
--- a/packages/frontend-2/lib/tour/slideshowItems.ts
+++ b/packages/frontend-2/lib/tour/slideshowItems.ts
@@ -11,7 +11,7 @@ export type SlideshowItem = {
export const items = [
{
- camPos: [-31.86138, 15.93344, -41.14196, -22.0765, 15.93344, -35.10095, 0, 1],
+ camPos: [-31.86138, 41.14196, 15.93344, -22.0765, 35.10095, 15.93344, 0, 1],
style: {} as Partial,
viewed: false,
showControls: true,
@@ -24,7 +24,7 @@ export const items = [
}
},
{
- camPos: [-3.3795, 23.25852, -40.78977, -20.65056, 21.78906, -40.72203, 0, 1],
+ camPos: [-3.3795, 40.78977, 23.25852, -20.65056, 40.72203, 21.78906, 0, 1],
style: {} as Partial,
viewed: false,
showControls: true,
@@ -36,7 +36,7 @@ export const items = [
}
},
{
- camPos: [-39.91711, 42.83686, -46.26069, -18.44162, 34.91624, -29.75982, 0, 1],
+ camPos: [-39.91711, 46.26069, 42.83686, -18.44162, 29.75982, 34.91624, 0, 1],
style: {} as Partial,
viewed: false,
showControls: false,
diff --git a/packages/viewer-sandbox/src/main.ts b/packages/viewer-sandbox/src/main.ts
index 91e764351..fff2800f6 100644
--- a/packages/viewer-sandbox/src/main.ts
+++ b/packages/viewer-sandbox/src/main.ts
@@ -105,7 +105,7 @@ const getStream = () => {
// prettier-ignore
// 'https://speckle.xyz/streams/da9e320dad/commits/5388ef24b8?c=%5B-7.66134,10.82932,6.41935,-0.07739,-13.88552,1.8697,0,1%5D'
// Revit sample house (good for bim-like stuff with many display meshes)
- // 'https://speckle.xyz/streams/da9e320dad/commits/5388ef24b8'
+ 'https://speckle.xyz/streams/da9e320dad/commits/5388ef24b8'
// 'https://latest.speckle.dev/streams/c1faab5c62/commits/ab1a1ab2b6'
// 'https://speckle.xyz/streams/da9e320dad/commits/5388ef24b8'
// 'https://latest.speckle.dev/streams/58b5648c4d/commits/60371ecb2d'
@@ -387,7 +387,7 @@ const getStream = () => {
// Sum fucking pipes
// 'https://app.speckle.systems/projects/122448a81e/models/f21aff1f4a'
// Thin plane
- 'https://app.speckle.systems/projects/20f72acc58/models/2cf8a736f8'
+ // 'https://app.speckle.systems/projects/20f72acc58/models/2cf8a736f8'
)
}
diff --git a/packages/viewer/src/modules/extensions/CameraController.ts b/packages/viewer/src/modules/extensions/CameraController.ts
index dfb0bda0a..4e09e96cc 100644
--- a/packages/viewer/src/modules/extensions/CameraController.ts
+++ b/packages/viewer/src/modules/extensions/CameraController.ts
@@ -22,8 +22,8 @@ import { FlyControls, FlyControlsOptions } from './controls/FlyControls'
import { SpeckleControls } from './controls/SpeckleControls'
import { GeometryType } from '../batching/Batch'
-const UP: Vector3 = new Vector3(0, 1, 0)
-const quatBuff = new Quaternion()
+// const UP: Vector3 = new Vector3(0, 1, 0)
+// const quatBuff = new Quaternion()
export enum NearPlaneCalculation {
EMPIRIC,
@@ -405,8 +405,7 @@ export class CameraController extends Extension implements SpeckleCamera {
const renderer = this.viewer.getRenderer()
if (!renderer.renderingCamera) return
- const camera = renderer.renderingCamera as PerspectiveCamera
- const minDist = this.getClosestGeometryDistance(camera)
+ const minDist = this.getClosestGeometryDistance()
if (minDist === Number.POSITIVE_INFINITY) {
this.updateNearCameraPlaneEmpiric(targetVolume, offsetScale)
return
@@ -456,12 +455,9 @@ export class CameraController extends Extension implements SpeckleCamera {
renderer.renderingCamera.updateProjectionMatrix()
}
- protected getClosestGeometryDistance(camera: PerspectiveCamera): number {
- const cameraPosition = camera.position
+ protected getClosestGeometryDistance(): number {
+ const cameraPosition = this._renderingCamera.position
const cameraTarget = this.getTarget()
- cameraTarget.applyQuaternion(
- quatBuff.setFromUnitVectors(UP, this._activeControls.up)
- )
const cameraDir = new Vector3().subVectors(cameraTarget, cameraPosition).normalize()
const batches = this.viewer
@@ -583,13 +579,9 @@ export class CameraController extends Extension implements SpeckleCamera {
}
protected setViewSpeckle(view: SpeckleView, transition = true) {
- /** SpeckleViews assume Z up, so we pre-transform to Z forward */
- const quat = new Quaternion()
- .setFromUnitVectors(new Vector3(0, 1, 0), new Vector3(0, 0, 1))
- .invert()
this._activeControls.fromPositionAndTarget(
- new Vector3(view.origin.x, view.origin.y, view.origin.z).applyQuaternion(quat),
- new Vector3(view.target.x, view.target.y, view.target.z).applyQuaternion(quat)
+ new Vector3(view.origin.x, view.origin.y, view.origin.z),
+ new Vector3(view.target.x, view.target.y, view.target.z)
)
if (!transition) this._activeControls.jumpToGoal()
@@ -608,19 +600,23 @@ export class CameraController extends Extension implements SpeckleCamera {
this.viewer.World.worldBox.getBoundingSphere(targetSphere)
const distance = this.fitToRadius(targetSphere.radius)
- const canonicalPosition = new Vector3()
- .copy(this.viewer.World.worldBox.getCenter(new Vector3()))
- .applyQuaternion(
- new Quaternion()
- .setFromUnitVectors(new Vector3(0, 1, 0), new Vector3(0, 0, 1))
- .invert()
- )
- const canonicalTarget = new Vector3().copy(canonicalPosition)
+ const canonicalPosition = new Vector3().copy(
+ this.viewer.World.worldBox.getCenter(new Vector3())
+ )
+ const canonicalTarget = new Vector3().copy(canonicalPosition)
+ const controlerBasis = new Quaternion().setFromUnitVectors(
+ new Vector3(0, 1, 0),
+ this._activeControls.up
+ )
switch (side) {
case 'front':
this._activeControls.fromPositionAndTarget(
- canonicalPosition.add(new Vector3(0, 0, 1).multiplyScalar(distance)),
+ canonicalPosition.add(
+ new Vector3(0, 0, 1)
+ .applyQuaternion(controlerBasis)
+ .multiplyScalar(distance)
+ ),
canonicalTarget
)
if (this._renderingCamera === this.orthographicCamera) this.disableRotations()
@@ -628,7 +624,11 @@ export class CameraController extends Extension implements SpeckleCamera {
case 'back':
this._activeControls.fromPositionAndTarget(
- canonicalPosition.add(new Vector3(0, 0, -1).multiplyScalar(distance)),
+ canonicalPosition.add(
+ new Vector3(0, 0, -1)
+ .applyQuaternion(controlerBasis)
+ .multiplyScalar(distance)
+ ),
canonicalTarget
)
if (this._renderingCamera === this.orthographicCamera) this.disableRotations()
@@ -637,7 +637,11 @@ export class CameraController extends Extension implements SpeckleCamera {
case 'up':
case 'top':
this._activeControls.fromPositionAndTarget(
- canonicalPosition.add(new Vector3(0, 1, 0).multiplyScalar(distance)),
+ canonicalPosition.add(
+ new Vector3(0, 1, 0)
+ .applyQuaternion(controlerBasis)
+ .multiplyScalar(distance)
+ ),
canonicalTarget
)
if (this._renderingCamera === this.orthographicCamera) this.disableRotations()
@@ -646,7 +650,11 @@ export class CameraController extends Extension implements SpeckleCamera {
case 'down':
case 'bottom':
this._activeControls.fromPositionAndTarget(
- canonicalPosition.add(new Vector3(0, -1, 0).multiplyScalar(distance)),
+ canonicalPosition.add(
+ new Vector3(0, -1, 0)
+ .applyQuaternion(controlerBasis)
+ .multiplyScalar(distance)
+ ),
canonicalTarget
)
if (this._renderingCamera === this.orthographicCamera) this.disableRotations()
@@ -654,7 +662,11 @@ export class CameraController extends Extension implements SpeckleCamera {
case 'right':
this._activeControls.fromPositionAndTarget(
- canonicalPosition.add(new Vector3(1, 0, 0).multiplyScalar(distance)),
+ canonicalPosition.add(
+ new Vector3(1, 0, 0)
+ .applyQuaternion(controlerBasis)
+ .multiplyScalar(distance)
+ ),
canonicalTarget
)
if (this._renderingCamera === this.orthographicCamera) this.disableRotations()
@@ -662,7 +674,11 @@ export class CameraController extends Extension implements SpeckleCamera {
case 'left':
this._activeControls.fromPositionAndTarget(
- canonicalPosition.add(new Vector3(-1, 0, 0).multiplyScalar(distance)),
+ canonicalPosition.add(
+ new Vector3(-1, 0, 0)
+ .applyQuaternion(controlerBasis)
+ .multiplyScalar(distance)
+ ),
canonicalTarget
)
if (this._renderingCamera === this.orthographicCamera) this.disableRotations()
diff --git a/packages/viewer/src/modules/extensions/controls/SmoothOrbitControls.ts b/packages/viewer/src/modules/extensions/controls/SmoothOrbitControls.ts
index b9c6ac7f3..923135e0a 100644
--- a/packages/viewer/src/modules/extensions/controls/SmoothOrbitControls.ts
+++ b/packages/viewer/src/modules/extensions/controls/SmoothOrbitControls.ts
@@ -237,10 +237,13 @@ export class SmoothOrbitControls extends SpeckleControls {
const v0 = new Vector3().copy(position)
const v1 = new Vector3().copy(target)
- v0.sub(v1)
+ /** Three.js Spherical assumes (0, 1, 0) as up... */
+ v0.sub(v1).applyMatrix4(this._basisTransformInv)
const spherical = new Spherical()
spherical.setFromCartesianCoords(v0.x, v0.y, v0.z)
this.setOrbit(spherical.theta, spherical.phi, spherical.radius)
+ /** Three.js Spherical assumes (0, 1, 0) as up... */
+ v1.applyMatrix4(this._basisTransformInv)
this.setTarget(v1.x, v1.y, v1.z)
}
@@ -263,21 +266,17 @@ export class SmoothOrbitControls extends SpeckleControls {
}
/**
- * Gets the current goal position. Needs to be in a basis with (0,1,0) as up
+ * Gets the current goal position
*/
public getPosition(): Vector3 {
- return this.positionFromSpherical(this.goalSpherical, this.origin).applyMatrix4(
- this._basisTransformInv
- )
+ return this.positionFromSpherical(this.goalSpherical, this.goalOrigin)
}
/**
* Gets the point in model coordinates the model should orbit/pivot around.
- * Needs to be in a basis with (0,1,0) as up
- * We keep goalOrigin untransformed, so there is no need to transform back from the controller's defined basis
*/
public getTarget(): Vector3 {
- return this.goalOrigin.clone()
+ return this.goalOrigin.clone().applyMatrix4(this._basisTransform)
}
public isStationary(): boolean {
@@ -304,6 +303,19 @@ export class SmoothOrbitControls extends SpeckleControls {
this.setFieldOfView(Math.exp(this.goalLogFov))
}
+ /** Computes min/max radius values based on the current world size */
+ protected computeMinMaxRadius() {
+ if (this.world) {
+ const maxDistance = this.world.getRelativeOffset(10)
+ const minDistance = this.world.getRelativeOffset(0.01)
+ if (!isNaN(maxDistance) && !isNaN(minDistance))
+ Object.assign(this._options, {
+ maximumRadius: maxDistance,
+ minimumRadius: minDistance
+ })
+ }
+ }
+
/**
* Set the absolute orbital goal of the camera. The change will be
* applied over a number of frames depending on configured acceleration and
@@ -326,6 +338,10 @@ export class SmoothOrbitControls extends SpeckleControls {
maximumRadius
} = this._options
+ if (isNaN(minimumRadius) || isNaN(maximumRadius)) {
+ this.computeMinMaxRadius()
+ }
+
const { theta, phi, radius } = this.goalSpherical
const nextTheta = clamp(goalTheta, minimumAzimuthalAngle, maximumAzimuthalAngle)
@@ -512,15 +528,7 @@ export class SmoothOrbitControls extends SpeckleControls {
return false
}
- if (this.world) {
- const maxDistance = this.world.getRelativeOffset(10)
- const minDistance = this.world.getRelativeOffset(0.01)
- this.applyOptions({
- maximumRadius: maxDistance,
- minimumRadius: minDistance
- })
- // radiusNormalisationRange = this.world.worldBox.getSize(new Vector3()).length()
- }
+ this.computeMinMaxRadius()
const { maximumPolarAngle } = this._options
@@ -644,6 +652,7 @@ export class SmoothOrbitControls extends SpeckleControls {
return height / (Math.tan(MathUtils.DEG2RAD * Math.exp(this.logFov) * 0.5) * 2)
}*/
+ /** Three.js Spherical assumes (0, 1, 0) as up... */
protected positionFromSpherical(spherical: Spherical, origin?: Vector3) {
const position: Vector3 = new Vector3()
position.setFromSpherical(spherical)
@@ -655,6 +664,7 @@ export class SmoothOrbitControls extends SpeckleControls {
return position
}
+ /** Three.js Spherical assumes (0, 1, 0) as up... */
protected quaternionFromSpherical(spherical: Spherical) {
const quaternion: Quaternion = new Quaternion()
quaternion.setFromEuler(
@@ -823,7 +833,8 @@ export class SmoothOrbitControls extends SpeckleControls {
this.panPerPixel
dxy.multiplyScalar(metersPerPixel)
- const target = this.getTarget()
+ /** This panProjection assumes (0, 1, 0) as up... */
+ const target = this.getTarget().applyMatrix4(this._basisTransformInv)
target.add(dxy.applyMatrix3(this.panProjection))
this.setTarget(target.x, target.y, target.z)
}
diff --git a/packages/viewer/src/modules/extensions/controls/SpeckleControls.ts b/packages/viewer/src/modules/extensions/controls/SpeckleControls.ts
index d5d94407d..21d7cce86 100644
--- a/packages/viewer/src/modules/extensions/controls/SpeckleControls.ts
+++ b/packages/viewer/src/modules/extensions/controls/SpeckleControls.ts
@@ -23,10 +23,7 @@ export abstract class SpeckleControls extends EventEmitter {
abstract fitToSphere(sphere: Sphere): void
abstract dispose(): void
- /** The input position and target vectors will always be in basis where (0,1,0) is up */
abstract fromPositionAndTarget(position: Vector3, target: Vector3): void
- /** Always in basis where (0,1,0) is up */
abstract getTarget(): Vector3
- /** Always in basis where (0,1,0) is up */
abstract getPosition(): Vector3
}