Spaces:
Running
Running
File size: 4,031 Bytes
6ce4ca6 3165745 6ce4ca6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
<script lang="ts">
import { useCursor } from '@threlte/extras'
import { T } from "@threlte/core";
import { HTML, type IntersectionEvent } from "@threlte/extras";
import { GLTF, useGltf } from "@threlte/extras";
import Model from "./GPUModel.svelte";
import { Shape, Path, ExtrudeGeometry, BoxGeometry } from "three";
import { onMount } from "svelte";
import type { VideoInstance } from "$lib/elements/video/VideoManager.svelte";
import { videoManager } from "$lib/elements/video/VideoManager.svelte";
// Props interface
interface Props {
// Transform props
position?: [number, number, number];
rotation?: [number, number, number];
scale?: [number, number, number];
rotating?: boolean;
}
// Props with defaults
let { position = [0, 0, 0], rotation = [0, 0, 0], scale = [1, 1, 1], rotating = false }: Props = $props();
// Create the TV frame geometry (outer rounded rectangle)
function createTVFrame(
tvWidth: number,
tvHeight: number,
tvDepth: number,
tvFrameThickness: number,
tvCornerRadius: number
) {
const shape = new Shape();
const x = -tvWidth / 2;
const y = -tvHeight / 2;
const w = tvWidth;
const h = tvHeight;
const radius = tvCornerRadius;
shape.moveTo(x, y + radius);
shape.lineTo(x, y + h - radius);
shape.quadraticCurveTo(x, y + h, x + radius, y + h);
shape.lineTo(x + w - radius, y + h);
shape.quadraticCurveTo(x + w, y + h, x + w, y + h - radius);
shape.lineTo(x + w, y + radius);
shape.quadraticCurveTo(x + w, y, x + w - radius, y);
shape.lineTo(x + radius, y);
shape.quadraticCurveTo(x, y, x, y + radius);
// Create hole for screen (inner rectangle)
const hole = new Path();
const hx = x + tvFrameThickness;
const hy = y + tvFrameThickness;
const hwidth = w - tvFrameThickness * 2;
const hheight = h - tvFrameThickness * 2;
const hradius = tvCornerRadius * 0.5;
hole.moveTo(hx, hy + hradius);
hole.lineTo(hx, hy + hheight - hradius);
hole.quadraticCurveTo(hx, hy + hheight, hx + hradius, hy + hheight);
hole.lineTo(hx + hwidth - hradius, hy + hheight);
hole.quadraticCurveTo(hx + hwidth, hy + hheight, hx + hwidth, hy + hheight - hradius);
hole.lineTo(hx + hwidth, hy + hradius);
hole.quadraticCurveTo(hx + hwidth, hy, hx + hwidth - hradius, hy);
hole.lineTo(hx + hradius, hy);
hole.quadraticCurveTo(hx, hy, hx, hy + hradius);
shape.holes.push(hole);
return new ExtrudeGeometry(shape, {
depth: tvDepth,
bevelEnabled: true,
bevelThickness: 0.02,
bevelSize: 0.02,
bevelSegments: 8
});
}
// Create the screen (video display area)
function createScreen(tvWidth: number, tvHeight: number, tvFrameThickness: number) {
const w = tvWidth - tvFrameThickness * 2;
const h = tvHeight - tvFrameThickness * 2;
// Create a very thin box for the screen area (only visible from front)
return new BoxGeometry(w, h, 0.02);
}
const frameGeometry = createTVFrame(1, 1, 1, 0.2, 0.15);
const screenGeometry = createScreen(1, 1, 0.2);
const gltf = useGltf("/gpu/scene.gltf");
let fan_rotation = $state(0);
let rotationPerSeconds = $state(1); // 1 rotation per second by default
onMount(() => {
const interval = setInterval(() => {
// Calculate angle increment per frame for desired rotations per second
if (rotating) {
const angleIncrement = (Math.PI * 2 * rotationPerSeconds) / 60;
fan_rotation = fan_rotation + angleIncrement;
}
}, 1000/60); // Run at ~60fps
return () => {
clearInterval(interval);
};
});
</script>
<T.Group
{position}
{rotation}
{scale}
>
<!-- TV Frame -->
<!-- <T.Mesh geometry={frameGeometry}>
<T.MeshStandardMaterial
color={"#374151"}
metalness={0.05}
roughness={0.4}
envMapIntensity={0.3}
/>
</T.Mesh> -->
<T.Group
scale={[1, 1, 1]}
>
<Model fan_rotation={fan_rotation} />
</T.Group>
<!-- <GLTF castShadow receiveShadow gltf={$gltf} position={{ y: 1 }} scale={3} /> -->
<!-- <T.Group scale={[1,1,1]}>
{#if $gltf}
<T is={$gltf.nodes['Sketchfab_model']} />
{/if}
</T.Group> -->
</T.Group>
|