bx-2376-new_type #86

Merged
ksenia_mikhailova merged 13 commits from bx-2376-new_type into dev 2025-03-20 10:57:21 +03:00
5 changed files with 195 additions and 147 deletions
Showing only changes of commit fea664c209 - Show all commits

View File

@ -27,21 +27,18 @@ const cameraStat = reactive({
</div> </div>
</template> </template>
<Loader /> <Loader />
<TresCanvas clear-color="#e2e8f0"> <Scene :canvasProps="{ clearColor: '#e2e8f0' }">
<TresPerspectiveCamera v-bind="cameraStat" ref="camera" /> <TresPerspectiveCamera v-bind="cameraStat" ref="camera" />
<OrbitControls v-bind="controlsState" make-default /> <OrbitControls v-bind="controlsState" make-default />
<Suspense> <Suspense>
<ModelSmoothCamera /> <ModelSmoothCamera />
</Suspense> </Suspense>
<Suspense>
<ModelEnv />
</Suspense>
<TresGroup> <TresGroup>
<Suspense> <Suspense>
<ModelParametric /> <ModelParametric />
</Suspense> </Suspense>
</TresGroup> </TresGroup>
</TresCanvas> </Scene>
</ClientOnly> </ClientOnly>
</div> </div>
</template> </template>

View File

@ -17,22 +17,6 @@ const explosion_state = use_explosion_state()
const toggleExpState = () => { const toggleExpState = () => {
explosion_state.value = !explosion_state.value explosion_state.value = !explosion_state.value
} }
const back_light = ref()
const secondary_light = ref()
const loadAll = async () => {
const { scene: back } = await useGLTF('/models_light/back_exp.glb')
const { scene: secondary } = await useGLTF('/models_light/secondary_exp.glb')
const k = 0.03
back_light.value = back.children[0]
back_light.value.intensity = back_light.value.intensity * k
back_light.value.shadow.bias = -0.02
secondary_light.value = secondary.children[0]
secondary_light.value.intensity = secondary_light.value.intensity * k
secondary_light.value.shadow.bias = -0.01
}
const changeDistance = (v = 1) => { const changeDistance = (v = 1) => {
if (camera.value && controls.value) { if (camera.value && controls.value) {
@ -41,9 +25,6 @@ const changeDistance = (v = 1) => {
camera.value.position.normalize().multiplyScalar(r) camera.value.position.normalize().multiplyScalar(r)
} }
} }
onMounted(() => {
loadAll()
})
</script> </script>
<template> <template>
<div class="h-96 relative"> <div class="h-96 relative">
@ -53,14 +34,11 @@ onMounted(() => {
Загрузка 3D модели Загрузка 3D модели
</div> </div>
</template> </template>
<TresCanvas height="600"> <Scene :canvasProps="{ height: '600' }">
<TresPerspectiveCamera :position="[-7, 2, 4]" ref="camera" /> <TresPerspectiveCamera :position="[-7, 2, 4]" ref="camera" />
<OrbitControls v-bind="controlsState" ref="controls" make-default /> <OrbitControls v-bind="controlsState" ref="controls" make-default />
<ModelEnv />
<Suspense>
<ModelDiagram /> <ModelDiagram />
</Suspense> </Scene>
</TresCanvas>
</ClientOnly> </ClientOnly>
<div class="canvas-icons"> <div class="canvas-icons">
<a href="#" @click.prevent="toggleExpState"> <a href="#" @click.prevent="toggleExpState">

View File

@ -22,59 +22,76 @@ const { seek, seekAll } = useSeek()
const globalFenceType = useGlobalFenceType() const globalFenceType = useGlobalFenceType()
const topper_models = { const top = ref(null)
const pillar_top = ref()
const pillar_center = ref(null)
const pillar_bottom = ref(null)
const pillar_inner = ref(null)
const pillar_brace = ref(null)
const fastening_top = ref(null)
const fastening_side = ref(null)
const fixing = ref(null)
const lamelle = ref(null)
const total = ref(0)
const size = ref(0)
const count = ref(0)
const min_for_square = 12;
const loadAll = async () => {
const topper_models = {
baseToppers: {} as { [key: toppersIds]: Object3D }, baseToppers: {} as { [key: toppersIds]: Object3D },
aristoToppers: {} as { [key: toppersIds]: Object3D }, aristoToppers: {} as { [key: toppersIds]: Object3D },
} }
for (const key of Object.keys(allToppers)) { for (const key of Object.keys(allToppers)) {
let toppers = allToppers[key] let toppers = allToppers[key]
for await (const element of toppers) { for await (const element of toppers) {
const { scene } = await useGLTF(getModel(element.id, key)) const { scene } = await useGLTF(getModel(element.id, key))
topper_models[key][element.id] = scene topper_models[key][element.id] = scene
} }
} }
const { scene: model_pillar_center } = await useGLTF('/models_one/pillar/center.glb') const { scene: model_pillar_center } = await useGLTF('/models_one/pillar/center.glb')
const { scene: model_pillar_bottom } = await useGLTF('/models_one/pillar/bottom.glb') const { scene: model_pillar_bottom } = await useGLTF('/models_one/pillar/bottom.glb')
const { scene: model_pillar_inner } = await useGLTF('/models_one/pillar/inner.glb') const { scene: model_pillar_inner } = await useGLTF('/models_one/pillar/inner.glb')
const { scene: model_pillar_brace } = await useGLTF('/models_one/pillar/brace.glb') const { scene: model_pillar_brace } = await useGLTF('/models_one/pillar/brace.glb')
const { scene: model_fastening_top } = await useGLTF('/models_one/fastening/top.glb'); const { scene: model_fastening_top } = await useGLTF('/models_one/fastening/top.glb');
const { scene: model_fastening_side } = await useGLTF('/models_one/fastening/side.glb'); const { scene: model_fastening_side } = await useGLTF('/models_one/fastening/side.glb');
const { scene: model_fixing } = await useGLTF('/models_one/fixing.glb'); const { scene: model_fixing } = await useGLTF('/models_one/fixing.glb');
const { scene: top_model } = await useGLTF('/models_one/top_100.glb', { draco: true }) const { scene: top_model } = await useGLTF('/models_one/top_100.glb', { draco: true })
// const { scene: lamelle_model } = await useGLTF('/models_one/lamel_100.glb', { draco: true }); // const { scene: lamelle_model } = await useGLTF('/models_one/lamel_100.glb', { draco: true });
const { scene: lamelle_model_standart } = await useGLTF('/models_one/lamel_100.glb', { draco: true }); const { scene: lamelle_model_standart } = await useGLTF('/models_one/lamel_100.glb', { draco: true });
const { scene: lamelle_model_aristo } = await useGLTF('/models_one/lamel_100_aristo.glb', { draco: true }); const { scene: lamelle_model_aristo } = await useGLTF('/models_one/lamel_100_aristo.glb', { draco: true });
const top = ref(top_model) top.value = top_model
const pillar_top = ref() pillar_center.value = model_pillar_center
const pillar_center = ref(model_pillar_center) pillar_bottom.value = model_pillar_bottom
const pillar_bottom = ref(model_pillar_bottom) pillar_inner.value = model_pillar_inner
const pillar_inner = ref(model_pillar_inner) pillar_brace.value = model_pillar_brace
const pillar_brace = ref(model_pillar_brace) fastening_top.value = model_fastening_top
const fastening_top = ref(model_fastening_top) fastening_side.value = model_fastening_side
const fastening_side = ref(model_fastening_side) fixing.value = model_fixing
const fixing = ref(model_fixing) lamelle.value = lamelle_model_standart
const lamelle = ref(lamelle_model_standart)
const setPillarTopper = () => { const setPillarTopper = () => {
let key = 'baseToppers' let key = 'baseToppers'
if (globalFenceType.value?.type == 'aristo') { if (globalFenceType.value?.type == 'aristo') {
key = 'aristoToppers' key = 'aristoToppers'
} }
pillar_top.value = topper_models[key][pillar_topper.value] pillar_top.value = topper_models[key][pillar_topper.value]
} }
setPillarTopper() setPillarTopper()
watch(pillar_topper, setPillarTopper) watch(pillar_topper, setPillarTopper)
const total = ref((section_count.value + ~~(!!extra_section.value))) total.value = (section_count.value + ~~(!!extra_section.value))
const size = ref(Math.ceil(total.value / 4)) size.value = Math.ceil(total.value / 4)
const count = ref((total.value >= 4) ? size.value : total.value) count.value = (total.value >= 4) ? size.value : total.value
watch(() => [section_count.value, extra_section.value], () => { watch(() => [section_count.value, extra_section.value], () => {
total.value = (section_count.value + ~~(!!extra_section.value)) total.value = (section_count.value + ~~(!!extra_section.value))
size.value = Math.ceil(total.value / 4); size.value = Math.ceil(total.value / 4);
count.value = (total.value >= 4) ? size.value : total.value; count.value = (total.value >= 4) ? size.value : total.value;
@ -102,8 +119,8 @@ watch(() => [section_count.value, extra_section.value], () => {
inner.children = [...inner?.children.slice(0, n)] inner.children = [...inner?.children.slice(0, n)]
} }
}); });
}) })
const setTarget = (smooth = false) => { const setTarget = (smooth = false) => {
let f = fence_section.value * lamelles_count.value * lamelle_height.value * 0.75; let f = fence_section.value * lamelles_count.value * lamelle_height.value * 0.75;
const max = 2.25 const max = 2.25
if (f < max) f = max if (f < max) f = max
@ -116,22 +133,21 @@ const setTarget = (smooth = false) => {
(controls.value as any).update() (controls.value as any).update()
goto_cam.value = new Vector3(f, f, f) goto_cam.value = new Vector3(f, f, f)
} }
} }
watch([lamelles_count, fence_section, lamelle_height], () => { watch([lamelles_count, fence_section, lamelle_height], () => {
setTarget() setTarget()
open_calc.value = [] open_calc.value = []
}) })
watch(open_calc, () => { watch(open_calc, () => {
if (Object.keys(open_calc.value).length == 0) { if (Object.keys(open_calc.value).length == 0) {
setTarget(true) setTarget(true)
} }
}) })
const min_for_square = 12;
setTarget() setTarget()
const setLamelleType = () => { const setLamelleType = () => {
if (globalFenceType.value?.type == 'standart') { if (globalFenceType.value?.type == 'standart') {
lamelle.value = lamelle_model_standart lamelle.value = lamelle_model_standart
lamelle_height.value = 0.115 lamelle_height.value = 0.115
@ -144,9 +160,11 @@ const setLamelleType = () => {
pillar_topper.value = 0 pillar_topper.value = 0
setPillarTopper() setPillarTopper()
} }
}
setLamelleType()
watch(() => globalFenceType.value?.id, setLamelleType)
} }
setLamelleType() onMounted(async () => { await loadAll() })
watch(() => globalFenceType.value?.id, setLamelleType)
</script> </script>
<template> <template>
<TresGroup name="base"> <TresGroup name="base">

55
components/scene.vue Normal file
View File

@ -0,0 +1,55 @@
<script setup>
const props = defineProps({
canvasProps: {
type: Object,
default: () => ({}),
},
cameraProps: {
type: Object,
default: () => ({}),
}
});
const container = ref(null);
const isIntersecting = ref(true);
let observer;
// Вычисляем renderMode на основе видимости
const renderMode = computed(() => (isIntersecting.value ? 'always' : 'never'));
const startObserver = () => {
observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
isIntersecting.value = entry.isIntersecting;
});
},
{ threshold: 0.1 } // Настройте порог видимости по вашему усмотрению
);
if (container.value) {
observer.observe(container.value);
}
}
onMounted(async () => {
await nextTick(); // Ждём завершения рендеринга
startObserver(); // Запускаем IntersectionObserver
});
onBeforeUnmount(() => {
if (observer) {
observer.disconnect();
}
});
</script>
<template>
<div ref="container" class="h-full">
<Suspense>
<TresCanvas v-bind="canvasProps" :render-mode="renderMode" :key="renderMode">
<ModelEnv />
<Suspense>
<slot />
</Suspense>
</TresCanvas>
</Suspense>
</div>
</template>

View File

@ -29,7 +29,7 @@ export default defineNuxtConfig({
runtimeConfig: { runtimeConfig: {
public: { public: {
// apiBase: process.env.mode == 'DEVELOPMENT' ? "http://localhost:8000" : "https://mns.kustarshina.ru/kp", // apiBase: process.env.mode == 'DEVELOPMENT' ? "http://localhost:8000" : "https://mns.kustarshina.ru/kp",
apiBase: process.env.mode == 'DEVELOPMENT' ? "http://mns.dev.kustarshina.ru/kp" : "https://mns.kustarshina.ru/kp", apiBase: process.env.mode == 'DEVELOPMENT' ? "http://mns.dev.kustarshina.ru" : "https://mns.kustarshina.ru/kp",
// apiBase: 'http://localhost:8000', // apiBase: 'http://localhost:8000',
imgBase: 'https://mns.kustarshina.ru', imgBase: 'https://mns.kustarshina.ru',
baseUrl: '', baseUrl: '',