Model centering can be off on Unified mode (#193)

Fixes #182
This commit is contained in:
Pierre Jacquier
2023-05-30 06:52:53 -04:00
committed by GitHub
parent 29cc1435c2
commit 85151ffe8f
4 changed files with 35 additions and 16 deletions

View File

@ -1,17 +1,17 @@
import { useThree } from '@react-three/fiber'
import type { MutableRefObject, PropsWithChildren } from 'react'
import { Suspense, useEffect, useRef } from 'react'
import { BufferGeometry } from 'three'
import { Sphere } from 'three'
import { Vector3 } from 'three'
import { calculateFovFactor } from './Camera'
type BaseModelProps = {
cameraRef: MutableRefObject<any>
geometry: BufferGeometry
boundingSphere: Sphere | null | undefined
}
export function BaseModel({
geometry,
boundingSphere,
cameraRef,
children,
}: PropsWithChildren<BaseModelProps>) {
@ -21,14 +21,9 @@ export function BaseModel({
// Camera view, adapted from KittyCAD/website
useEffect(() => {
if (geometry && cameraRef.current) {
geometry.computeBoundingSphere()
// TODO: understand the implications of this,
// it's been disabled as it was causing before and after to be misaligned
// geometry.center()
if (boundingSphere && cameraRef.current) {
// move the camera away so the object fits in the view
const { radius } = geometry.boundingSphere || { radius: 1 }
const { radius } = boundingSphere || { radius: 1 }
if (!camera.position.length()) {
const arbitraryNonZeroStartPosition = new Vector3(0.5, 0.5, 1)
camera.position.copy(arbitraryNonZeroStartPosition)
@ -42,7 +37,7 @@ export function BaseModel({
camera.zoom = fovFactor / camera.position.length()
camera.updateProjectionMatrix()
}
}, [geometry, camera, cameraRef, canvasHeight])
}, [boundingSphere, camera, cameraRef, canvasHeight])
return (
<Suspense fallback={null}>

View File

@ -26,6 +26,7 @@ function loadGeometry(file: string, checkUV = false): BufferGeometry {
new BufferAttribute(new Float32Array([]), 1)
)
}
geometry.computeBoundingSphere() // will be used for auto-centering
return geometry
}

View File

@ -1,6 +1,14 @@
import type { MutableRefObject } from 'react'
import { useTheme } from '@primer/react'
import { BufferGeometry } from 'three'
import {
Box3,
BufferGeometry,
Group,
Mesh,
MeshBasicMaterial,
Sphere,
Vector3,
} from 'three'
import { Geometry, Base, Subtraction, Intersection } from '@react-three/csg'
import { BaseModel } from './BaseModel'
@ -13,6 +21,20 @@ type UnifiedModelProps = {
showDeletions: boolean
}
function getCommonSphere(
beforeGeometry: BufferGeometry,
afterGeometry: BufferGeometry
) {
const group = new Group()
const dummyMaterial = new MeshBasicMaterial()
group.add(new Mesh(beforeGeometry, dummyMaterial))
group.add(new Mesh(afterGeometry, dummyMaterial))
const boundingBox = new Box3().setFromObject(group)
const center = new Vector3()
boundingBox.getCenter(center)
return boundingBox.getBoundingSphere(new Sphere(center))
}
export function UnifiedModel({
beforeGeometry,
afterGeometry,
@ -27,9 +49,10 @@ export function UnifiedModel({
const deletionsColor = theme?.colors.danger.muted
return (
// TODO: here we give beforeGeometry for auto camera centering,
// for the lack of something better. Need to check the implications
<BaseModel geometry={beforeGeometry} cameraRef={cameraRef}>
<BaseModel
boundingSphere={getCommonSphere(beforeGeometry, afterGeometry)}
cameraRef={cameraRef}
>
{/* Unchanged */}
<mesh>
<meshPhongMaterial

View File

@ -25,7 +25,7 @@ export function WireframeModel({ geometry, cameraRef, colors }: Props) {
)
return (
<BaseModel geometry={geometry} cameraRef={cameraRef}>
<BaseModel boundingSphere={geometry.boundingSphere} cameraRef={cameraRef}>
<group ref={groupRef}>
<mesh
castShadow={true}