import * as THREE from 'three' import {CSG} from 'three-csg-ts' import gsap from 'gsap' //@ts-ignore import {mergeGeometries} from 'three/addons/utils/BufferGeometryUtils.js' import Clx3DGraphics from "@/modules/amr/ptr/clx/Clx3DGraphics"; import Viewport from "@/core/engine/Viewport"; import PtrObject from "@/modules/amr/ptr/PtrObject"; export default class Clx3dObject extends PtrObject { override rotationSpeed = (Math.PI / 10) override showForkSpeed: number = 0.15 override upForkSpeed: number = 0.15 constructor(item: ItemJson, viewport: Viewport, option?: RendererCudOption) { super(item, viewport) if (!Clx3DGraphics.clxPedestalGeometry) { Clx3DGraphics.clxPedestalGeometry = Clx3DGraphics.createClxPedestal() } const clxPedestalGeometry = Clx3DGraphics.clxPedestalGeometry const clxPedestalMaterial = new THREE.MeshPhongMaterial({color: 0xffdddbca}) const clxPedestalMesh = new THREE.Mesh(clxPedestalGeometry, clxPedestalMaterial) if (!Clx3DGraphics.clxPillarGeometry) { Clx3DGraphics.clxPillarGeometry = Clx3DGraphics.createClxPillar() } const clxPillarGeometry = Clx3DGraphics.clxPillarGeometry const clxPillarMaterial = new THREE.MeshPhongMaterial({color: 0xff6c6956}) const clxPillarMesh = new THREE.Mesh(clxPillarGeometry, clxPillarMaterial) if (!Clx3DGraphics.clxForkGeometry) { Clx3DGraphics.clxForkGeometry = Clx3DGraphics.createClxFork() } const clxForkGeometry = Clx3DGraphics.clxForkGeometry const clxForkMaterial = new THREE.MeshPhongMaterial({color: 0xff444444}) const clxForkMesh = new THREE.Mesh(clxForkGeometry, clxForkMaterial) clxForkMesh.name = 'clxFork' if (!Clx3DGraphics.clxGemelGeometryL) { Clx3DGraphics.clxGemelGeometryL = Clx3DGraphics.createClxGemel(true) } const clxGemelGeometryL = Clx3DGraphics.clxGemelGeometryL if (!Clx3DGraphics.clxGemelGeometryR) { Clx3DGraphics.clxGemelGeometryR = Clx3DGraphics.createClxGemel(false) } const clxGemelGeometryR = Clx3DGraphics.clxGemelGeometryR const clxGemelMaterial = new THREE.MeshPhongMaterial({color: 0xff555555}) const clxGemelMeshL1 = new THREE.Mesh(clxGemelGeometryL, clxGemelMaterial) clxGemelMeshL1.name = 'clxGemelMeshL1' const clxGemelMeshL2 = new THREE.Mesh(clxGemelGeometryL, clxGemelMaterial) clxGemelMeshL2.name = 'clxGemelMeshL2' const clxGemelMeshR1 = new THREE.Mesh(clxGemelGeometryR, clxGemelMaterial) clxGemelMeshR1.name = 'clxGemelMeshR1' const clxGemelMeshR2 = new THREE.Mesh(clxGemelGeometryR, clxGemelMaterial) clxGemelMeshR2.name = 'clxGemelMeshR2' if (!Clx3DGraphics.clxForkBasePlateGeometry) { Clx3DGraphics.clxForkBasePlateGeometry = Clx3DGraphics.createClxForkBasePlate() } const clxForkBasePlateGeometry = Clx3DGraphics.clxForkBasePlateGeometry const clxForkBasePlateMesh = new THREE.Mesh(clxForkBasePlateGeometry, clxGemelMaterial) clxForkBasePlateMesh.name = 'clxForkBasePlateMesh' const d = 0 this.add(clxPedestalMesh) this.add(clxPillarMesh) this.add(clxForkMesh) const ac = Math.asin(d / (2 * 0.8)) clxGemelMeshL1.position.z = 0.5 - d / 4 clxGemelMeshL1.position.y = 0.72 clxGemelMeshL1.rotation.x = -ac clxGemelMeshL2.position.z = 0.5 - d / 4 * 3 clxGemelMeshL2.position.y = 0.72 clxGemelMeshL2.rotation.x = -ac clxGemelMeshR1.position.z = 0.5 - d / 4 clxGemelMeshR1.position.y = 0.72 clxGemelMeshR1.rotation.x = ac clxGemelMeshR2.position.z = 0.5 - d / 4 * 3 clxGemelMeshR2.position.y = 0.72 clxGemelMeshR2.rotation.x = ac this.add(clxGemelMeshL1) this.add(clxGemelMeshL2) this.add(clxGemelMeshR1) this.add(clxGemelMeshR2) this.add(clxForkBasePlateMesh) } override animationShowFork(z: number): Promise { const clxFork = this.getObjectByName('clxFork') const clxGemelMeshL1 = this.getObjectByName('clxGemelMeshL1') const clxGemelMeshL2 = this.getObjectByName('clxGemelMeshL2') const clxGemelMeshR1 = this.getObjectByName('clxGemelMeshR1') const clxGemelMeshR2 = this.getObjectByName('clxGemelMeshR2') const clxForkBasePlateMesh = this.getObjectByName('clxForkBasePlateMesh') const fy = clxFork.position.y const time = Math.abs((clxFork.position.z - z) / this.upForkSpeed) const ac = Math.asin(z / (2 * 0.8)) // clxGemelMeshL1.position.z = 0.5 - z/4 // clxGemelMeshL1.position.y = fy + 0.72 // clxGemelMeshL1.rotation.x = -ac gsap.to(clxGemelMeshL1.position, { z: 0.5 - z / 4, y: fy + 0.72, duration: time, repeat: 0, ease: 'power1.inOut' }) gsap.to(clxGemelMeshL1.rotation, { x: -ac, duration: time, repeat: 0, ease: 'power1.inOut' }) // clxGemelMeshL2.position.z = 0.5 - z/4 * 3 // clxGemelMeshL2.position.y = fy + 0.72 // clxGemelMeshL2.rotation.x = -ac gsap.to(clxGemelMeshL2.position, { z: 0.5 - z / 4 * 3, y: fy + 0.72, duration: time, repeat: 0, ease: 'power1.inOut' }) gsap.to(clxGemelMeshL2.rotation, { x: -ac, duration: time, repeat: 0, ease: 'power1.inOut' }) // clxGemelMeshR1.position.z = 0.5 - z/4 // clxGemelMeshR1.position.y = fy + 0.72 // clxGemelMeshR1.rotation.x = ac gsap.to(clxGemelMeshR1.position, { z: 0.5 - z / 4, y: fy + 0.72, duration: time, repeat: 0, ease: 'power1.inOut' }) gsap.to(clxGemelMeshR1.rotation, { x: ac, duration: time, repeat: 0, ease: 'power1.inOut' }) // clxGemelMeshR2.position.z = 0.5 - z/4 * 3 // clxGemelMeshR2.position.y = fy + 0.72 // clxGemelMeshR2.rotation.x = ac gsap.to(clxGemelMeshR2.position, { z: 0.5 - z / 4 * 3, y: fy + 0.72, duration: time, repeat: 0, ease: 'power1.inOut' }) gsap.to(clxGemelMeshR2.rotation, { x: ac, duration: time, repeat: 0, ease: 'power1.inOut' }) gsap.to(clxForkBasePlateMesh.position, { y: fy, duration: time, repeat: 0, ease: 'power1.inOut' }) return new Promise(resolve => { this.actionAnimation = gsap.to(clxFork.position, { z: -z, duration: time, repeat: 0, ease: 'power1.inOut', onComplete: ()=>{ setTimeout(() => { resolve() }, 1000) }, }) }) } override animationHideFork(): Promise { return this.animationShowFork(0) } override animationUpFork(y: number): Promise { const clxFork = this.getObjectByName('clxFork') const clxGemelMeshL1 = this.getObjectByName('clxGemelMeshL1') const clxGemelMeshL2 = this.getObjectByName('clxGemelMeshL2') const clxGemelMeshR1 = this.getObjectByName('clxGemelMeshR1') const clxGemelMeshR2 = this.getObjectByName('clxGemelMeshR2') const clxForkBasePlateMesh = this.getObjectByName('clxForkBasePlateMesh') const time = Math.abs((clxFork.position.y - y) / this.upForkSpeed) gsap.to(clxGemelMeshL1.position, { y: y + 0.72, duration: time, repeat: 0, ease: 'sine.inOut' }) gsap.to(clxGemelMeshL2.position, { y: y + 0.72, duration: time, repeat: 0, ease: 'sine.inOut' }) gsap.to(clxGemelMeshR1.position, { y: y + 0.72, duration: time, repeat: 0, ease: 'sine.inOut' }) gsap.to(clxGemelMeshR2.position, { y: y + 0.72, duration: time, repeat: 0, ease: 'sine.inOut' }) gsap.to(clxForkBasePlateMesh.position, { y: y, duration: time, repeat: 0, ease: 'sine.inOut' }) return new Promise(resolve => { const bh = 0.22 const children = clxFork.children this.actionAnimation = gsap.to(clxFork.position, { y: y, duration: time, repeat: 0, ease: 'sine.inOut', onComplete: ()=>{ setTimeout(() => { resolve() }, 1000) }, onUpdate: function() { const a = this.targets()[0] if (a.y < bh) { if (a.z > -1) { for (let i = 0; i < children.length; i++) { const child = children[i] child.position.y = bh - a.y } } else if (a.y < 0 ) { for (let i = 0; i < children.length; i++) { const child = children[i] child.position.y = 0 - a.y } } } } }) }) } override animationDownFork(): Promise { return this.animationUpFork(0) } override getArmObject(): THREE.Object3D | undefined { const clxFork = this.getObjectByName('clxFork') return clxFork } }