diff --git a/components/model/bench-table.vue b/components/model/bench-table.vue
index 7b09302..75e1c06 100644
--- a/components/model/bench-table.vue
+++ b/components/model/bench-table.vue
@@ -2,37 +2,28 @@
//@ts-ignore
import { useGLTF } from '@tresjs/cientos'
import { useTresContext } from '@tresjs/core'
-import { Vector3 } from 'three'
-import { ref, onMounted } from 'vue'
+import { degToRad } from 'three/src/math/MathUtils.js'
const { camera, controls } = useTresContext()
-const { scene: obj } = await useGLTF('/models/bench2_export-v1.glb')
-const scale = ref(1) // Масштаб объекта
-
-onMounted(() => {
- if (obj && camera.value && controls.value) {
- const distance = 10
- const cameraOffset = { x: 1, y: 0.75, z: -1.25 } // Смещение камеры
-
- // Вычисляем масштаб и позицию камеры
- const { scale: objectScale } = calculateScaleToFit(
- obj,
- camera.value as any,
- controls.value as any,
- distance,
- cameraOffset
- )
-
- scale.value = objectScale
+const { scene } = await useGLTF('/models/table.glb')
+const object = calculateScaleToFit(
+ scene,
+ camera,
+ controls,
+ 3,
+ {
+ x: Math.sin(degToRad(-30)), // Смещение по оси X
+ y: 1, // Нет смещения по оси Y
+ z: -Math.cos(degToRad(0)) // Смещение по оси Z
}
-})
+)
-
-
+
+
-
\ No newline at end of file
+
diff --git a/components/model/bench.vue b/components/model/bench.vue
index b82fa0c..6a600fa 100644
--- a/components/model/bench.vue
+++ b/components/model/bench.vue
@@ -2,37 +2,28 @@
//@ts-ignore
import { useGLTF } from '@tresjs/cientos'
import { useTresContext } from '@tresjs/core'
-import { Vector3 } from 'three'
-import { ref, onMounted } from 'vue'
+import { degToRad } from 'three/src/math/MathUtils.js'
const { camera, controls } = useTresContext()
-const { scene: obj } = await useGLTF('/models/bench_export-v1.glb')
-const scale = ref(1) // Масштаб объекта
-
-onMounted(() => {
- if (obj && camera.value && controls.value) {
- const distance = 10
- const cameraOffset = { x: -1, y: 0.75, z: -1.25 } // Смещение камеры
-
- // Вычисляем масштаб и позицию камеры
- const { scale: objectScale } = calculateScaleToFit(
- obj,
- camera.value as any,
- controls.value as any,
- distance,
- cameraOffset
- )
-
- scale.value = objectScale
+const { scene } = await useGLTF('/models/bench.glb')
+const object = calculateScaleToFit(
+ scene,
+ camera,
+ controls,
+ 2,
+ {
+ x: Math.sin(degToRad(30)), // Смещение по оси X
+ y: 1, // Нет смещения по оси Y
+ z: -Math.cos(degToRad(0)) // Смещение по оси Z
}
-})
+)
-
-
+
+
-
\ No newline at end of file
+
diff --git a/components/model/env.vue b/components/model/env.vue
index c4bd86b..5b727a1 100644
--- a/components/model/env.vue
+++ b/components/model/env.vue
@@ -1,11 +1,12 @@
-
\ No newline at end of file
+
diff --git a/components/model/scene.vue b/components/model/scene.vue
index 8e2b29c..63044df 100644
--- a/components/model/scene.vue
+++ b/components/model/scene.vue
@@ -14,15 +14,26 @@ const props = defineProps({
}
})
+const camera = ref()
+const controls = ref()
+
const controlsState = reactive({
- // minDistance: 2,
- // maxDistance: 10,
- enablePan: false,
- enableZoom: false,
- maxPolarAngle: Math.PI / 2 - 0.2
+ minDistance: 2,
+ maxDistance: 20,
+ enablePan: false
+ // enableZoom: false,
+ // maxPolarAngle: Math.PI / 2 - 0.2
})
const toggleModal = () => {}
+
+const changeDistance = (v = 1) => {
+ if (camera.value && controls.value) {
+ const distance = camera.value.position.distanceTo(new Vector3(0, 0, 0))
+ const r = distance + v
+ camera.value.position.normalize().multiplyScalar(r)
+ }
+}
@@ -32,14 +43,45 @@ const toggleModal = () => {}
Загрузка 3D модели
-
-
-
+
+
+
+
diff --git a/public/models/bench.glb b/public/models/bench.glb
new file mode 100644
index 0000000..0423146
Binary files /dev/null and b/public/models/bench.glb differ
diff --git a/public/models/bench_export-v1.glb b/public/models/bench_export-v1.glb
deleted file mode 100644
index 9101377..0000000
Binary files a/public/models/bench_export-v1.glb and /dev/null differ
diff --git a/public/models/bench2_export-v1.glb b/public/models/table.glb
similarity index 67%
rename from public/models/bench2_export-v1.glb
rename to public/models/table.glb
index 49d874c..1d18444 100644
Binary files a/public/models/bench2_export-v1.glb and b/public/models/table.glb differ
diff --git a/utils/calculateScaleToFit.ts b/utils/calculateScaleToFit.ts
index 09069fa..744938e 100644
--- a/utils/calculateScaleToFit.ts
+++ b/utils/calculateScaleToFit.ts
@@ -1,38 +1,54 @@
-import { Box3, PerspectiveCamera, Vector3 } from 'three'
-import { degToRad } from 'three/src/math/MathUtils.js';
+import { Box3, PerspectiveCamera, Vector3, Mesh, Camera } from 'three'
+import { degToRad } from 'three/src/math/MathUtils.js'
-/**
- * Вычисляет масштаб объекта и позицию камеры, чтобы объект полностью помещался в видимой области.
- * @param object - Объект Three.js (например, загруженная модель).
- * @param camera - Экземпляр камеры.
- * @param controls - Экземпляр OrbitControls.
- * @param distance - Расстояние от камеры до объекта.
- * @param cameraOffset - Коэффициенты смещения камеры (x, y, z).
- */
-export default function (
+export default function calculateScaleToFit(
object: any,
- camera: PerspectiveCamera,
+ camera: ComputedRef,
controls: any,
distance: number,
cameraOffset: { x: number; y: number; z: number }
) {
+ // Создаем новый BoundingBox
+ const bbox = new Box3()
+
// Обновляем мировую матрицу объекта
object.updateWorldMatrix(true, true)
- const fov = camera.fov // Угол обзора камеры
- const aspect = camera.aspect // Соотношение сторон
+ // Перебираем все дочерние элементы объекта
+ object.traverse((child: any) => {
+ if (child.isMesh) {
+ // Добавляем геометрию каждого меша в bounding box
+ const geometry = child.geometry
+ if (geometry) {
+ geometry.computeBoundingBox() // Убедимся, что bounding box геометрии вычислен
+ const meshBBox = geometry.boundingBox.clone()
+ if (meshBBox) {
+ // Применяем мировую матрицу к bounding box
+ meshBBox.applyMatrix4(child.matrixWorld)
+ bbox.union(meshBBox) // Объединяем с общим bounding box
+ }
+ }
+ }
+ })
- const bbox = new Box3().setFromObject(object) // Вычисляем bounding box
+ // Вычисляем центр и размер bounding box
const center = new Vector3()
- bbox.getCenter(center) // Центр объекта
+ bbox.getCenter(center)
const size = new Vector3()
- bbox.getSize(size) // Размеры объекта
+ bbox.getSize(size)
- // Рассчитываем масштаб, чтобы объект полностью помещался в видимой области
- const vFOV = degToRad(fov) // Угол обзора в радианах
- const visibleHeight = 2 * Math.tan(vFOV / 2) * distance // Видимая высота
- const visibleWidth = visibleHeight * aspect // Видимая ширина
+ // Центрируем объект
+ object.position.sub(center)
+ object.updateWorldMatrix(true, true)
+
+ // Рассчитываем масштаб
+ const fov = (camera.value as PerspectiveCamera).fov
+ const aspect = (camera.value as PerspectiveCamera).aspect
+
+ const vFOV = degToRad(fov)
+ const visibleHeight = 2 * Math.tan(vFOV / 2) * distance
+ const visibleWidth = visibleHeight * aspect
const scaleX = visibleWidth / size.x
const scaleY = visibleHeight / size.y
@@ -40,18 +56,20 @@ export default function (
const scale = Math.min(scaleX, scaleY, scaleZ)
- // Позиционируем камеру с учетом смещения
- camera.position.set(
- center.x + distance * cameraOffset.x,
- center.y + distance * cameraOffset.y,
- center.z + distance * cameraOffset.z
- )
+ // Масштабируем объект
+ object.scale.setScalar(scale)
+ object.updateWorldMatrix(true, true)
- // Устанавливаем цель для OrbitControls
- if (controls) {
- controls.target.set(center.x, center.y, center.z)
- controls.update() // Обновляем контроллы
+ if (camera.value) {
+ const [x, y, z] = Object.values(cameraOffset).map(el => el * distance);
+ camera.value.position.set(x, y, z);
}
- return { scale, center }
+ // Настройка OrbitControls
+ if (controls.value) {
+ controls.value.target.set(...Object.values(center.multiplyScalar(1)))
+ controls.value.update()
+ }
+
+ return object
}
\ No newline at end of file