dev #84
|
@ -3,6 +3,7 @@ import { TresCanvas } from '@tresjs/core'
|
||||||
import { OrbitControls } from '@tresjs/cientos'
|
import { OrbitControls } from '@tresjs/cientos'
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
import { useGLTF } from '@tresjs/cientos'
|
import { useGLTF } from '@tresjs/cientos'
|
||||||
|
import { degToRad, radToDeg } from 'three/src/math/MathUtils.js';
|
||||||
|
|
||||||
const fence_section = use_fence_section()
|
const fence_section = use_fence_section()
|
||||||
const section_count = use_section_count()
|
const section_count = use_section_count()
|
||||||
|
@ -11,11 +12,12 @@ const max_size = use_max_size()
|
||||||
|
|
||||||
const controlsState = reactive({
|
const controlsState = reactive({
|
||||||
distance: section_count.value,
|
distance: section_count.value,
|
||||||
minDistance: 7,
|
minDistance: 10,
|
||||||
maxDistance: 20,
|
maxDistance: 10,
|
||||||
position: { x: 0, y: 0, z: 0 },
|
position: { x: 0, y: 0, z: 0 },
|
||||||
enablePan: false,
|
// enablePan: false,
|
||||||
maxPolarAngle: (Math.PI / 2) - 0.2,
|
minPolarAngle: degToRad(30),
|
||||||
|
maxPolarAngle: degToRad(80),
|
||||||
})
|
})
|
||||||
const cameraStat = reactive({
|
const cameraStat = reactive({
|
||||||
position: [-4, 2, 8],
|
position: [-4, 2, 8],
|
||||||
|
@ -26,18 +28,19 @@ const cameraStat = reactive({
|
||||||
const pointLight = ref()
|
const pointLight = ref()
|
||||||
const loadAll = async () => {
|
const loadAll = async () => {
|
||||||
const { scene: light } = await useGLTF('/models_light/zabor_so_svetom.glb')
|
const { scene: light } = await useGLTF('/models_light/zabor_so_svetom.glb')
|
||||||
pointLight.value = light.children[2]
|
pointLight.value = light.children[2].clone()
|
||||||
pointLight.value.color = '#f0dea9'
|
pointLight.value.intensity = pointLight.value.intensity * 0.05
|
||||||
pointLight.value.intensity = pointLight.value.intensity * 0.1
|
|
||||||
pointLight.value.shadow.camera.near = 50
|
|
||||||
pointLight.value.shadow.bias = -0.002
|
pointLight.value.shadow.bias = -0.002
|
||||||
const j = 4
|
const j = 4
|
||||||
pointLight.value.shadow.mapSize.x = 512 * j
|
pointLight.value.shadow.mapSize.x = 512 * j
|
||||||
pointLight.value.shadow.mapSize.y = 512 * j
|
pointLight.value.shadow.mapSize.y = 512 * j
|
||||||
|
|
||||||
const k = 3
|
const k = 1
|
||||||
|
// 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
|
||||||
pointLight.value.position.x = pointLight.value.position.x * k
|
pointLight.value.position.x = pointLight.value.position.x * k
|
||||||
pointLight.value.position.y = pointLight.value.position.y * k
|
pointLight.value.position.y = pointLight.value.position.z * k
|
||||||
pointLight.value.position.z = pointLight.value.position.z * k
|
pointLight.value.position.z = pointLight.value.position.z * k
|
||||||
}
|
}
|
||||||
const camera = ref("camera")
|
const camera = ref("camera")
|
||||||
|
@ -50,7 +53,7 @@ watch([section_count, extra_section], () => {
|
||||||
let v = (section_count.value + ~~(!!extra_section.value)) * 2
|
let v = (section_count.value + ~~(!!extra_section.value)) * 2
|
||||||
if (v < controlsState.minDistance) v = controlsState.minDistance;
|
if (v < controlsState.minDistance) v = controlsState.minDistance;
|
||||||
if (v > controlsState.maxDistance) v = controlsState.maxDistance;
|
if (v > controlsState.maxDistance) v = controlsState.maxDistance;
|
||||||
(camera.value as any).position.normalize().multiplyScalar(v)
|
// (camera.value as any).position.normalize().multiplyScalar(v)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
@ -62,22 +65,25 @@ watch([section_count, extra_section], () => {
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<Loader />
|
<Loader />
|
||||||
<TresCanvas>
|
<TresCanvas clear-color="#ccc">
|
||||||
<TresPerspectiveCamera v-bind="cameraStat" ref="camera" />
|
<TresPerspectiveCamera v-bind="cameraStat" ref="camera" />
|
||||||
<OrbitControls v-bind="controlsState" make-default />
|
<OrbitControls v-bind="controlsState" make-default />
|
||||||
<TresGroup :position-x="Math.min(section_count, max_size) * fence_section * -1" :position-y="-3">
|
<TresGroup>
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<ModelParametric />
|
<ModelParametric />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</TresGroup>
|
</TresGroup>
|
||||||
<TresMesh receive-shadow :position-y="-3.65" name="ground">
|
<TresMesh receive-shadow name="ground">
|
||||||
<TresCircleGeometry :args="[50, 32]" :rotate-x="-Math.PI * 0.5" />
|
<TresCircleGeometry :args="[50, 32]" :rotate-x="-Math.PI * 0.5" />
|
||||||
<TresShadowMaterial :opacity="0.2" />
|
<TresShadowMaterial :opacity="0.2" />
|
||||||
</TresMesh>
|
</TresMesh>
|
||||||
|
|
||||||
<template v-if="pointLight">
|
<template v-if="pointLight">
|
||||||
<TresPointLight v-bind="pointLight" cast-shadow />
|
<TresPointLight v-bind="pointLight.clone()" cast-shadow />
|
||||||
|
<TresPointLight v-bind="pointLight.clone()" :position-x="pointLight.position.x * -1"
|
||||||
|
:position-z="pointLight.position.z * -1" cast-shadow />
|
||||||
</template>
|
</template>
|
||||||
|
<TresAmbientLight intensity="10" />
|
||||||
</TresCanvas>
|
</TresCanvas>
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { BufferGeometry, Matrix4, Vector2, Vector3 } from 'three';
|
import { BufferGeometry, Matrix4, Vector2, Vector3 } from 'three';
|
||||||
|
|
||||||
const props = defineProps(['index', 'models'])
|
const props = defineProps(['index', 'models', 'last_element'])
|
||||||
|
|
||||||
const lamelle_height = use_lamelle_height()
|
const lamelle_height = use_lamelle_height()
|
||||||
const lamelles_count = use_lamelles_count()
|
const lamelles_count = use_lamelles_count()
|
||||||
|
@ -18,16 +18,11 @@ const pillar_size = 104 * 0.001
|
||||||
const pillar_one_pos = ref(fence_section.value * -0.5 - 0.015)
|
const pillar_one_pos = ref(fence_section.value * -0.5 - 0.015)
|
||||||
const pillar_two_pos = ref(fence_section.value * 0.5 + pillar_size + bSize - 0.01)
|
const pillar_two_pos = ref(fence_section.value * 0.5 + pillar_size + bSize - 0.01)
|
||||||
|
|
||||||
const scale_koef = 2.5
|
const scale_koef = 1
|
||||||
const show_pillar_one = ref(props.index == 1)
|
const show_pillar_one = ref(props.index == 1)
|
||||||
const show_pillar_two = ref(true)
|
const show_pillar_two = ref(true)
|
||||||
|
|
||||||
const last_element = ref(Math.min((section_count.value + ~~(!!extra_section.value)), max_size.value))
|
const getExtraValue = () => (extra_section.value && props.last_element) ? extra_section.value * 0.001 : false
|
||||||
watch([section_count, fence_section, extra_section], () => {
|
|
||||||
last_element.value = Math.min(section_count.value + ~~(!!extra_section.value), max_size.value)
|
|
||||||
})
|
|
||||||
|
|
||||||
const getExtraValue = () => (extra_section.value && props.index == last_element.value) ? extra_section.value * 0.001 : false
|
|
||||||
const extra = ref(getExtraValue())
|
const extra = ref(getExtraValue())
|
||||||
if (extra.value) {
|
if (extra.value) {
|
||||||
pillar_one_pos.value = (extra.value as number) * -0.5 - 0.015
|
pillar_one_pos.value = (extra.value as number) * -0.5 - 0.015
|
||||||
|
@ -71,14 +66,14 @@ watch([instanced_lamelle, fence_section, extra_section, lamelles_count, extra],
|
||||||
if (i >= lamelles_count.value) {
|
if (i >= lamelles_count.value) {
|
||||||
instanced_lamelle.value.setMatrixAt(i, new Matrix4().makeTranslation(new Vector3(0, 20, 20)));
|
instanced_lamelle.value.setMatrixAt(i, new Matrix4().makeTranslation(new Vector3(0, 20, 20)));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
instanced_lamelle.value.instanceMatrix.needsUpdate = true
|
instanced_lamelle.value.instanceMatrix.needsUpdate = true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
watch([section_count, fence_section, extra_section], () => {
|
watch([section_count, fence_section, extra_section], () => {
|
||||||
extra.value = getExtraValue()
|
extra.value = getExtraValue()
|
||||||
if (extra_section.value && props.index == last_element.value) {
|
if (extra_section.value && props.last_element) {
|
||||||
pillar_one_pos.value = (extra.value as number) * -0.5 - 0.015
|
pillar_one_pos.value = (extra.value as number) * -0.5 - 0.015
|
||||||
pillar_two_pos.value = (extra.value as number) * 0.5 + pillar_size + bSize - 0.01
|
pillar_two_pos.value = (extra.value as number) * 0.5 + pillar_size + bSize - 0.01
|
||||||
// translate_to_section.value = make_translate_to_section(extra_section.value * 0.001)
|
// translate_to_section.value = make_translate_to_section(extra_section.value * 0.001)
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Box3, Vector3 } from 'three';
|
||||||
|
import { degToRad } from 'three/src/math/MathUtils.js';
|
||||||
|
|
||||||
|
const props = defineProps(['number', 'count', 'models'])
|
||||||
|
const rotate = () => {
|
||||||
|
switch (props.number) {
|
||||||
|
case 1:
|
||||||
|
return degToRad(0)
|
||||||
|
case 2:
|
||||||
|
return degToRad(90)
|
||||||
|
case 3:
|
||||||
|
return degToRad(270)
|
||||||
|
case 4:
|
||||||
|
return degToRad(180)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const { seekByName } = useSeek()
|
||||||
|
const { scene } = useTresContext()
|
||||||
|
|
||||||
|
const section_count = use_section_count()
|
||||||
|
const extra_section = use_extra_section()
|
||||||
|
|
||||||
|
const total = ref((section_count.value + ~~(!!extra_section.value)))
|
||||||
|
const position = ref(new Vector3())
|
||||||
|
const count_pos = () => {
|
||||||
|
total.value = (section_count.value + ~~(!!extra_section.value))
|
||||||
|
|
||||||
|
const line = seekByName(scene.value, `line_${props.number}`)
|
||||||
|
const line_size = new Vector3()
|
||||||
|
const line_pos = new Vector3()
|
||||||
|
if (line && line.children.length) {
|
||||||
|
line.updateMatrixWorld()
|
||||||
|
new Box3().expandByObject(line).getSize(line_size)
|
||||||
|
line.getWorldPosition(line_pos)
|
||||||
|
console.log(`line_${props.number}`, line, line_size, line_pos)
|
||||||
|
}
|
||||||
|
const line1 = seekByName(scene.value, `line_1`);
|
||||||
|
const line1_size = new Vector3()
|
||||||
|
const line1_pos = new Vector3()
|
||||||
|
if (line1) {
|
||||||
|
new Box3().expandByObject(line1).getSize(line1_size)
|
||||||
|
line1.getWorldPosition(line1_pos)
|
||||||
|
console.log('first', line1, line1_size, line1_pos)
|
||||||
|
}
|
||||||
|
switch (props.number) {
|
||||||
|
case 1: break;
|
||||||
|
case 2:
|
||||||
|
// position.value.x = line_size.y
|
||||||
|
position.value.z = line1_size.z * -1
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
position.value.z = line1_size.x * -1
|
||||||
|
position.value.x = line1_size.x
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
position.value.z = line1_size.x * -1
|
||||||
|
position.value.x = line1_size.x
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
count_pos()
|
||||||
|
})
|
||||||
|
watch(() => [props.count, section_count.value, extra_section.value], count_pos)
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<TresGroup :name="`line_${props.number}`" :rotate-y="rotate()" :position-x="position.x" :position-y="position.y"
|
||||||
|
:position-z="position.z">
|
||||||
|
<template v-for="i in props.count">
|
||||||
|
<template v-if="(i + (props.number - 1) * props.count) <= total"
|
||||||
|
:key="(i + (props.number - 1) * props.count)">
|
||||||
|
<ModelFence :index="i" :models="props.models"
|
||||||
|
:last_element="(i + (props.number - 1) * props.count) == total" />
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</TresGroup>
|
||||||
|
</template>
|
|
@ -12,6 +12,7 @@ import { GainMapLoader, } from '@monogrid/gainmap-js'
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
import { useGLTF, } from '@tresjs/cientos'
|
import { useGLTF, } from '@tresjs/cientos'
|
||||||
import { getColorHexFromRal, type ralTypes } from '../ral';
|
import { getColorHexFromRal, type ralTypes } from '../ral';
|
||||||
|
import { degToRad, radToDeg } from 'three/src/math/MathUtils.js';
|
||||||
|
|
||||||
const pillar_color = use_pillar_color()
|
const pillar_color = use_pillar_color()
|
||||||
const lamelle_color = use_lamelle_color()
|
const lamelle_color = use_lamelle_color()
|
||||||
|
@ -91,12 +92,39 @@ watch(pillar_color, () => {
|
||||||
set_material(element, getColorHexFromRal(pillar_color.value))
|
set_material(element, getColorHexFromRal(pillar_color.value))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
watch([section_count, extra_section], () => {
|
|
||||||
|
const total = ref((section_count.value + ~~(!!extra_section.value)))
|
||||||
|
const size = ref(Math.ceil(total.value / 4))
|
||||||
|
const count = ref((total.value >= 4) ? size.value : total.value)
|
||||||
|
|
||||||
|
watch(() => [section_count.value, extra_section.value], () => {
|
||||||
|
console.log('parametric line clear')
|
||||||
|
total.value = (section_count.value + ~~(!!extra_section.value))
|
||||||
|
size.value = Math.ceil(total.value / 4);
|
||||||
|
count.value = (total.value >= 4) ? size.value : total.value;
|
||||||
|
|
||||||
|
const lines_count = (total.value >= 4) ? 4 : 1
|
||||||
const base = seek(scene.value, 'name', 'base')
|
const base = seek(scene.value, 'name', 'base')
|
||||||
const n = (section_count.value as number) + ~~(!!extra_section.value)
|
if (base?.children && base.children.length !== lines_count) {
|
||||||
if (base?.children && n < base?.children.length) {
|
base.children = [...base?.children.slice(0, lines_count)]
|
||||||
base.children = [...base?.children.slice(0, n)]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const lines = seekAll(scene.value, 'name', 'line')
|
||||||
|
lines.forEach(line => {
|
||||||
|
let n = size.value
|
||||||
|
if (lines_count == 1) {
|
||||||
|
n = total.value
|
||||||
|
}
|
||||||
|
if (line.name.endsWith('_4')) {
|
||||||
|
n = total.value - size.value * 3
|
||||||
|
if (n < 0) {
|
||||||
|
n = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (line?.children && n < line?.children.length) {
|
||||||
|
line.children = [...line?.children.slice(0, n)]
|
||||||
|
}
|
||||||
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(lamelle_count, () => {
|
watch(lamelle_count, () => {
|
||||||
|
@ -104,30 +132,12 @@ watch(lamelle_count, () => {
|
||||||
(el: Ref) => { set_material(el.value, getColorHexFromRal(pillar_color.value), lamelle_count.value) });
|
(el: Ref) => { set_material(el.value, getColorHexFromRal(pillar_color.value), lamelle_count.value) });
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
const loader = new GainMapLoader(renderer.value)
|
|
||||||
const result = await loader.loadAsync([
|
|
||||||
'hdrmaps/hdr.webp',
|
|
||||||
'hdrmaps/hdr-gainmap.webp',
|
|
||||||
'hdrmaps/hdr.json',
|
|
||||||
])
|
|
||||||
if (renderer.value && camera.value) {
|
|
||||||
renderer.value.render(scene.value, camera.value)
|
|
||||||
}
|
|
||||||
scene.value.environment = result.renderTarget.texture
|
|
||||||
scene.value.background = result.renderTarget.texture
|
|
||||||
scene.value.background.mapping = EquirectangularReflectionMapping
|
|
||||||
scene.value.backgroundRotation = new Euler(0, 10, 0)
|
|
||||||
scene.value.backgroundIntensity = 1.5
|
|
||||||
scene.value.backgroundBlurriness = 0.06
|
|
||||||
result.renderTarget.texture.dispose();
|
|
||||||
})
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<TresGroup name="base">
|
<TresGroup name="base">
|
||||||
<template v-for="i in Math.min((section_count + ~~(!!extra_section)), max_size)">
|
<template v-for="line in (total >= 4) ? 4 : 1" :key="`${line}_${count}`">
|
||||||
<ModelFence :index="i" :models="{ top, fence, fence_top, fence_bottom, fence_inner, fastening, lamelle }" />
|
<ModelLine :models="{ top, fence, fence_top, fence_bottom, fence_inner, fastening, lamelle }" :number="line"
|
||||||
|
:count="count" />
|
||||||
</template>
|
</template>
|
||||||
</TresGroup>
|
</TresGroup>
|
||||||
</template>
|
</template>
|
|
@ -1,5 +1,5 @@
|
||||||
import { Color, DoubleSide, MeshBasicMaterial, MeshStandardMaterial, RepeatWrapping, TextureLoader, Vector2 } from "three"
|
import { Color, DoubleSide, MeshBasicMaterial, MeshStandardMaterial, RepeatWrapping, TextureLoader, Vector2 } from "three"
|
||||||
import { useLoader } from '@tresjs/core'
|
import { useLoader, type TresLoader } from '@tresjs/core'
|
||||||
|
|
||||||
const set_metaril_func = (scene: any, material: any) => {
|
const set_metaril_func = (scene: any, material: any) => {
|
||||||
scene.children.forEach((el: any) => {
|
scene.children.forEach((el: any) => {
|
||||||
|
@ -31,7 +31,7 @@ export const set_material = (scene: any, color: any, count: number | undefined =
|
||||||
color: new Color(c || '#9c9c00'),
|
color: new Color(c || '#9c9c00'),
|
||||||
alphaMap: count ? texture : null,
|
alphaMap: count ? texture : null,
|
||||||
transparent: true,
|
transparent: true,
|
||||||
opacity: 0.75,
|
opacity: 1,
|
||||||
// roughness: 0.5,
|
// roughness: 0.5,
|
||||||
// metalness: 0,
|
// metalness: 0,
|
||||||
side: DoubleSide,
|
side: DoubleSide,
|
||||||
|
|
Loading…
Reference in New Issue