mns-mini-zabor/components/calcModels.vue

84 lines
3.0 KiB
Vue

<script setup lang="ts">
import { FrontSide, RepeatWrapping } from 'three';
import { TresCanvas, useTexture } from '@tresjs/core'
import { OrbitControls, useGLTF } from '@tresjs/cientos'
const fence_section = use_fence_section()
const section_count = use_section_count()
const extra_section = use_extra_section()
const max_size = use_max_size()
const controlsState = reactive({
distance: section_count.value,
minDistance: 7,
maxDistance: 20,
position: { x: 0, y: 0, z: 0 },
enablePan: false,
maxPolarAngle: (Math.PI / 2) - 0.2,
})
const cameraStat = reactive({
position: [-4, 2, 8],
aspect: 1920 / 600,
fov: 40,
})
const pointLight = ref()
const pointLight2 = ref()
const loadAll = async () => {
const { scene: light } = await useGLTF('/models_light/zabor_so_svetom.glb')
pointLight.value = light.children[2]
pointLight.value.color = '#f0dea9'
pointLight.value.intensity = pointLight.value.intensity * 0.1
pointLight.value.shadow.camera.near = 50
pointLight.value.shadow.bias = -0.002
const j = 4
pointLight.value.shadow.mapSize.x = 512 * j
pointLight.value.shadow.mapSize.y = 512 * j
const k = 5
pointLight.value.position.x = pointLight.value.position.x * k
pointLight.value.position.y = pointLight.value.position.y * k
pointLight.value.position.z = pointLight.value.position.z * k
}
const camera = ref("camera")
onMounted(() => {
cameraStat.aspect = window.innerWidth / (window.innerHeight * 0.5)
loadAll()
})
watch([section_count, extra_section], () => {
let v = (section_count.value + ~~(!!extra_section.value)) * 2
if (v < controlsState.minDistance) v = controlsState.minDistance;
if (v > controlsState.maxDistance) v = controlsState.maxDistance;
(camera.value as any).position.normalize().multiplyScalar(v)
})
</script>
<template>
<div class="container min-w-full siteblock_calc-canvas">
<ClientOnly fallback-tag="div">
<template #fallback>
<div class="fallback">
Загрузка 3D модели
</div>
</template>
<Loader />
<TresCanvas preset="realistic">
<TresPerspectiveCamera v-bind="cameraStat" ref="camera" />
<OrbitControls v-bind="controlsState" make-default />
<TresGroup :position-x="Math.min(section_count, max_size) * fence_section * -1" :position-y="-3">
<Suspense>
<ModelParametric />
</Suspense>
</TresGroup>
<TresMesh receive-shadow :position-y="-3.65" name="ground">
<TresCircleGeometry :args="[50, 32]" :rotate-x="-Math.PI * 0.5" />
<TresShadowMaterial :opacity="0.2" />
</TresMesh>
<template v-if="pointLight">
<TresPointLight v-bind="pointLight" cast-shadow />
</template>
</TresCanvas>
</ClientOnly>
</div>
</template>