From 8dc115543026dda15e8e2058149770f8856d3990 Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Thu, 2 Apr 2026 20:27:45 +0200 Subject: [PATCH] auto-git: [add] src/viewport-three/viewport-entity-markers.ts --- fixtures/assets/tiny-triangle-draco.glb | Bin 0 -> 916 bytes src/viewport-three/viewport-entity-markers.ts | 60 ++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 fixtures/assets/tiny-triangle-draco.glb create mode 100644 src/viewport-three/viewport-entity-markers.ts diff --git a/fixtures/assets/tiny-triangle-draco.glb b/fixtures/assets/tiny-triangle-draco.glb new file mode 100644 index 0000000000000000000000000000000000000000..d8e4f152286f99f5caedf5a49d7795c908dd7e26 GIT binary patch literal 916 zcmah|U2obj6m?+Iw3ljo*gNv$ltl@YZOTi<=+M|GnSk~MRmg-(u$0)$b|@8!wEc(u zjr~S;9n!MTE>RNS+;e=-xweyZ(yI|dzSRkF@%b>0hC9l%21COgO+bKRMk*T81fee{ ziV3}xDr;;`y})Zxmu^65E(Ic*o=*#xvN#5lwI*UtVY{M8Ze(u{4fO5g^re~l4G8B^cI`?|n*o-dc6t~lHr zv>aj@`k1;k5G|Lb&ng^%NX&|cuiHm%#Y6C~*^C)boTZ1nV43yU<6Dy}Xk1iDl)s*< z3otBAc|4MNvJ%)C+t@kN(3PoFJr?)V+kMBpbg<`RsSvfPiL<)VCn*godH@&3(t1$XON7j?T@()`YT7d`iIH%?47yj^K07)&Ds~qcOm<^R_=E=c7(Hs?{6^Fw m&zwCD$P+wRm~u$He);_Si~6JW*Wf7v$^Oi~f4;t)osb_(tsR2^ literal 0 HcmV?d00001 diff --git a/src/viewport-three/viewport-entity-markers.ts b/src/viewport-three/viewport-entity-markers.ts new file mode 100644 index 00000000..eb70fd53 --- /dev/null +++ b/src/viewport-three/viewport-entity-markers.ts @@ -0,0 +1,60 @@ +import { BoxGeometry, CylinderGeometry, Mesh, MeshStandardMaterial, TorusGeometry } from "three"; + +const SOUND_EMITTER_CABINET_SIZE = { + x: 0.38, + y: 0.5, + z: 0.18 +}; + +const SOUND_EMITTER_FRONT_OFFSET = 0.1; +const SOUND_EMITTER_TWEEETER_RADIUS = 0.045; +const SOUND_EMITTER_TWEETER_Y = 0.15; +const SOUND_EMITTER_WOOFER_RADIUS = 0.11; +const SOUND_EMITTER_WOOFER_Y = -0.08; + +function createSpeakerMaterial(color: number, selected: boolean, emissiveIntensity: number, roughness: number, metalness: number) { + return new MeshStandardMaterial({ + color, + emissive: color, + emissiveIntensity: selected ? emissiveIntensity : emissiveIntensity * 0.35, + roughness, + metalness + }); +} + +export function createSoundEmitterMarkerMeshes(markerColor: number, selected: boolean): Mesh[] { + const cabinet = new Mesh( + new BoxGeometry(SOUND_EMITTER_CABINET_SIZE.x, SOUND_EMITTER_CABINET_SIZE.y, SOUND_EMITTER_CABINET_SIZE.z), + createSpeakerMaterial(0x23272e, selected, 0.08, 0.88, 0.02) + ); + + const tweeterRing = new Mesh( + new TorusGeometry(SOUND_EMITTER_TWEEETER_RADIUS, 0.012, 8, 18), + createSpeakerMaterial(markerColor, selected, 0.22, 0.4, 0.04) + ); + tweeterRing.rotation.x = Math.PI * 0.5; + tweeterRing.position.set(0, SOUND_EMITTER_TWEETER_Y, SOUND_EMITTER_FRONT_OFFSET); + + const tweeterCone = new Mesh( + new CylinderGeometry(SOUND_EMITTER_TWEEETER_RADIUS * 0.58, SOUND_EMITTER_TWEEETER_RADIUS * 0.58, 0.028, 18), + createSpeakerMaterial(0x14171c, selected, 0.08, 0.68, 0.01) + ); + tweeterCone.rotation.x = Math.PI * 0.5; + tweeterCone.position.set(0, SOUND_EMITTER_TWEETER_Y, SOUND_EMITTER_FRONT_OFFSET + 0.006); + + const wooferRing = new Mesh( + new TorusGeometry(SOUND_EMITTER_WOOFER_RADIUS, 0.016, 8, 20), + createSpeakerMaterial(markerColor, selected, 0.22, 0.42, 0.04) + ); + wooferRing.rotation.x = Math.PI * 0.5; + wooferRing.position.set(0, SOUND_EMITTER_WOOFER_Y, SOUND_EMITTER_FRONT_OFFSET); + + const wooferCone = new Mesh( + new CylinderGeometry(SOUND_EMITTER_WOOFER_RADIUS * 0.6, SOUND_EMITTER_WOOFER_RADIUS * 0.6, 0.032, 20), + createSpeakerMaterial(0x14171c, selected, 0.08, 0.72, 0.01) + ); + wooferCone.rotation.x = Math.PI * 0.5; + wooferCone.position.set(0, SOUND_EMITTER_WOOFER_Y, SOUND_EMITTER_FRONT_OFFSET + 0.007); + + return [cabinet, tweeterRing, tweeterCone, wooferRing, wooferCone]; +}