mirror of
https://github.com/yeicor-3d/yet-another-cad-viewer.git
synced 2025-12-19 22:24:17 +01:00
add support for orthographic camera!
This commit is contained in:
@@ -63,10 +63,8 @@ let modelViewerInfo: Ref<typeof ModelViewerInfo | null> = ref(null);
|
|||||||
|
|
||||||
<!--suppress CssUnusedSymbol -->
|
<!--suppress CssUnusedSymbol -->
|
||||||
<style>
|
<style>
|
||||||
html, body, #main {
|
html, body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ function createGizmo(expectedParent: HTMLElement, scene: ModelScene): HTMLElemen
|
|||||||
//console.log("New camera position", newLookFrom)
|
//console.log("New camera position", newLookFrom)
|
||||||
scene.getCamera().position.copy(newLookFrom);
|
scene.getCamera().position.copy(newLookFrom);
|
||||||
scene.getCamera().lookAt(lookAt);
|
scene.getCamera().lookAt(lookAt);
|
||||||
|
if ((scene as any).__perspectiveCamera) { // HACK: Make the hacky ortho also work
|
||||||
|
(scene as any).__perspectiveCamera.position.copy(newLookFrom);
|
||||||
|
(scene as any).__perspectiveCamera.lookAt(lookAt);
|
||||||
|
}
|
||||||
scene.queueRender();
|
scene.queueRender();
|
||||||
}
|
}
|
||||||
return gizmo;
|
return gizmo;
|
||||||
|
|||||||
@@ -1,21 +1,53 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {VBtn, VIcon} from "vuetify/lib/components";
|
import {VBtn, VIcon} from "vuetify/lib/components";
|
||||||
|
import {ref} from "vue";
|
||||||
import OrientationGizmo from "./OrientationGizmo.vue";
|
import OrientationGizmo from "./OrientationGizmo.vue";
|
||||||
|
import type {ModelScene} from "@google/model-viewer/lib/three-components/ModelScene";
|
||||||
|
import {OrthographicCamera} from "three";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelViewerInfo: Object
|
modelViewerInfo: Object
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function syncOrthoCamera(force: boolean) {
|
||||||
|
if (!props.modelViewerInfo) return;
|
||||||
|
let scene: ModelScene = props.modelViewerInfo.scene
|
||||||
|
let perspectiveCam = (scene as any).__perspectiveCamera;
|
||||||
|
if (force || perspectiveCam && scene.camera != perspectiveCam) {
|
||||||
|
// Get zoom level from perspective camera
|
||||||
|
let dist = scene.getTarget().distanceToSquared(perspectiveCam.position);
|
||||||
|
let w = scene.aspect * dist ** 1.1 / 4000;
|
||||||
|
let h = dist ** 1.1 / 4000;
|
||||||
|
(scene as any).camera = new OrthographicCamera(-w, w, h, -h, perspectiveCam.near, perspectiveCam.far);
|
||||||
|
scene.camera.position.copy(perspectiveCam.position);
|
||||||
|
scene.camera.lookAt(scene.getTarget().clone().add(scene.target.position));
|
||||||
|
requestAnimationFrame(() => syncOrthoCamera(false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let toggleProjectionText = ref('PERSP'); // Default to perspective camera
|
||||||
function toggleProjection() {
|
function toggleProjection() {
|
||||||
if (!props.modelViewerInfo) return;
|
if (!props.modelViewerInfo) return;
|
||||||
console.log('Toggling projection', props.modelViewerInfo);
|
let scene: ModelScene = props.modelViewerInfo.scene
|
||||||
|
let prevCam = scene.camera;
|
||||||
|
let wasPerspectiveCamera = prevCam.isPerspectiveCamera;
|
||||||
|
if (wasPerspectiveCamera) {
|
||||||
|
(scene as any).__perspectiveCamera = prevCam; // Save the default perspective camera
|
||||||
|
// This hack also needs to sync the camera position and target
|
||||||
|
requestAnimationFrame(() => syncOrthoCamera(true));
|
||||||
|
} else {
|
||||||
|
// Restore the default perspective camera
|
||||||
|
scene.camera = (scene as any).__perspectiveCamera;
|
||||||
|
}
|
||||||
|
toggleProjectionText.value = wasPerspectiveCamera ? 'ORTHO' : 'PERSP';
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<orientation-gizmo v-if="props.modelViewerInfo" :scene="props.modelViewerInfo.scene"/>
|
<orientation-gizmo v-if="props.modelViewerInfo" :scene="props.modelViewerInfo.scene"/>
|
||||||
<v-btn icon="mdi-projector" @click="toggleProjection"><span class="icon-detail">PERSP</span>
|
<v-btn icon="mdi-projector" @click="toggleProjection"><span class="icon-detail">{{ toggleProjectionText }}</span>
|
||||||
<v-icon icon="mdi-projector"></v-icon>
|
<v-icon icon="mdi-projector"></v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user