Skip to content

Commit

Permalink
Update view center when bounds changes
Browse files Browse the repository at this point in the history
Fixes #13
  • Loading branch information
mbrown1413 committed Mar 20, 2024
1 parent 14840c3 commit cc2b26e
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 22 deletions.
12 changes: 9 additions & 3 deletions ui/components/GridDisplay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<script setup lang="ts">
import {ref, Ref, computed} from "vue"
import {Puzzle, Piece, Voxel} from "~lib"
import {Puzzle, Piece, Voxel, Bounds} from "~lib"
import {useGridDrawComposible} from "./GridDisplay_draw.ts"
import {useGridMouseComposible} from "./GridDisplay_mouse.ts"
Expand Down Expand Up @@ -57,17 +57,23 @@ const viewpointOptions = computed(() =>
const pieces = computed(() => props.pieces)
const bounds = computed(() => {
let bounds: Bounds
if(props.boundsSizing === "voxels") {
const allVoxels = []
for(const piece of pieces.value) {
allVoxels.push(...piece.voxels)
}
return props.puzzle.grid.getVoxelBounds(...allVoxels)
bounds = props.puzzle.grid.getVoxelBounds(...allVoxels)
} else {
return props.puzzle.grid.getBoundsMax(
bounds = props.puzzle.grid.getBoundsMax(
...pieces.value.map(piece => piece.bounds)
)
}
if(bounds.some(b => b === 0)) {
bounds = props.puzzle.grid.getDefaultPieceBounds()
}
return bounds
})
const {
Expand Down
62 changes: 44 additions & 18 deletions ui/components/GridDisplay_draw.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {ref, Ref, ComputedRef, onMounted, onUnmounted, computed, watchEffect} from "vue"
import {ref, Ref, ComputedRef, onMounted, onUnmounted, computed, watchEffect, watch} from "vue"

import * as THREE from "three"
import {Vector3} from "three"
Expand Down Expand Up @@ -40,6 +40,13 @@ export function useGridDrawComposible(
buildScene()
multiRenderer.requestRender()
})

setCameraPosition()
setCameraTarget()

watch(() => [...bounds.value], () => {
setCameraTarget()
})
})

onUnmounted(() => {
Expand Down Expand Up @@ -70,7 +77,7 @@ export function useGridDrawComposible(
camera.updateProjectionMatrix()

// Calculate camera near/far to fit entire scene
const boundingBox = new THREE.Box3().setFromObject(scene) // Calculated _after_ AxisHelper added
const boundingBox = new THREE.Box3().setFromObject(scene)
const boundingSphere = boundingBox.getBoundingSphere(new THREE.Sphere())
const sphereDistance = boundingSphere.distanceToPoint(camera.position)
camera.near = Math.max(sphereDistance * .9, 0.1)
Expand All @@ -97,23 +104,24 @@ export function useGridDrawComposible(
})
}

function initializeCamera() {
const boundingBox = new THREE.Box3().setFromObject(scene) // Calculated _before_ AxisHeper added
const boundingSphere = boundingBox.getBoundingSphere(new THREE.Sphere())
function setCameraPosition() {
const boundingBox = getGridBoundingBox(grid, bounds.value)
const center = boundingBox.getCenter(new Vector3())

// Position camera according to the initial viewpoint.
const boundingSphere = boundingBox.getBoundingSphere(new THREE.Sphere())
const fovRadians = fov * (Math.PI/180)
const cameraPosition = viewpoint.value.forwardVector.clone().normalize()
cameraPosition.multiplyScalar(
-1 * (boundingSphere.radius * 1.2) / Math.tan(fovRadians / 2)
)
cameraPosition.add(center)
camera.position.set(cameraPosition.x, cameraPosition.y, cameraPosition.z)
}

function setCameraTarget() {
const boundingBox = getGridBoundingBox(grid, bounds.value)
const center = boundingBox.getCenter(new Vector3())

// Center view on the center of the grid.
// Only do this once on initialization though, since the user can
// right-click drag to change the OrbitControls target location.
if(controls) {
controls.target = center
camera.lookAt(center)
Expand Down Expand Up @@ -300,7 +308,6 @@ export function useGridDrawComposible(
}

/* Call rebuild() when the objects in the scene need to be updated. */
let isInitialRebuild = true
function buildScene() {
objectCache.newScene()
objectCache.resetStats()
Expand Down Expand Up @@ -353,13 +360,7 @@ export function useGridDrawComposible(
}
}

if(isInitialRebuild) {
initializeCamera()
}

// Add axes helper after bounding box is computed so it doesn't affect the
// center.
const axesHelper = objectCache.getOrSet("axisHelper", () => {
const axesHelper = objectCache.getOrSet("axesHelper", () => {
const obj = new THREE.AxesHelper()
obj.position.set(-1, -1, -1)
return obj
Expand All @@ -368,12 +369,37 @@ export function useGridDrawComposible(

resourceTracker.markUsed(scene)
resourceTracker.releaseUnused()
isInitialRebuild = false
}

return {
scene,
camera,
hitTestObjects,
}
}

function getGridBoundingBox(grid: Grid, bounds: Bounds): THREE.Box3 {
const points = getAllGridVertices(grid, bounds)
const min = new Vector3(points[0].x, points[0].y, points[0].z)
const max = new Vector3(points[0].x, points[0].y, points[0].z)
for(const point of points) {
min.x = Math.min(min.x, point.x)
min.y = Math.min(min.y, point.y)
min.z = Math.min(min.z, point.z)
max.x = Math.max(max.x, point.x)
max.y = Math.max(max.y, point.y)
max.z = Math.max(max.z, point.z)
}
return new THREE.Box3(min, max)
}

function getAllGridVertices(grid: Grid, bounds: Bounds): Vector3[] {
const points = []
for(const voxel of grid.getVoxels(bounds)) {
const voxelInfo = grid.getVoxelInfo(voxel)
for(const polygon of Object.values(voxelInfo.sidePolygons)) {
points.push(...polygon)
}
}
return points
}
2 changes: 1 addition & 1 deletion ui/components/ProblemPiecesEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function updateGoal(pieceId: string | null) {
:puzzle="puzzle"
:pieces="[item.piece]"
displayOnly
boundsSizing="pieceBounds"
boundsSizing="voxels"
:size="200"
/>
</template>
Expand Down

0 comments on commit cc2b26e

Please sign in to comment.