91 lines
3.1 KiB
Vue
91 lines
3.1 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 groundMaterial = ref({
|
|
color: "#555",
|
|
roughness: 0.7,
|
|
metalness: 0,
|
|
side: FrontSide,
|
|
precision: 'lowp',
|
|
})
|
|
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 shadows>
|
|
<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> |