Add tostão furado model and stage lights

This commit is contained in:
2023-09-19 16:17:50 +01:00
parent 62cbca8083
commit c4feadb4af
10 changed files with 400 additions and 23 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,17 @@
import { useGLTF, useTexture } from "@react-three/drei";
import { CoinProps } from "@/types/coin";
export function TostaoFurado(coin: CoinProps) {
// @ts-expect-error property `nodes` actually exists
const { nodes } = useGLTF("/models/tostao-furado.gltf");
const texture = useTexture("/api/merge-textures/" + coin.id);
return (
<>
<primitive object={nodes.TostaoFurado.geometry} />
<meshStandardMaterial metalness={1} roughness={0.5} map={texture} />
</>
);
}
useGLTF.preload("/models/tostao-furado.gltf");
+12 -3
View File
@@ -2,9 +2,10 @@ import * as THREE from "three";
import { useLoader } from "@react-three/fiber";
import { CoinProps } from "@/types/coin";
import { useEffect, useMemo } from "react";
import { EuroCents20 } from "./custom-geometries/euro-cents-20";
import { BahamasCents15 } from "./custom-geometries/bahamas-cents-15";
import { BahamasCents10 } from "./custom-geometries/bahamas-cents-10";
import { EuroCents20 } from "./custom/euro-cents-20";
import { BahamasCents15 } from "./custom/bahamas-cents-15";
import { BahamasCents10 } from "./custom/bahamas-cents-10";
import { TostaoFurado } from "./custom/tostao-furado";
const SafeEdgeMaterial = ({ edge }: Pick<CoinProps, "edge">) => {
const edgeTexture: THREE.Texture = useLoader(
@@ -94,6 +95,14 @@ export const CoinInstance = (coin: CoinProps) => {
return <EuroCents20 {...coin} />;
}
if (
coin.value?.numeric_value === 25 &&
coin.value?.currency?.name === "Peseta" &&
coin.min_year >= 1990
) {
return <TostaoFurado {...coin} />;
}
if (
coin.value?.currency?.name === "Dollar" &&
coin.issuer?.code === "bahamas"
+6 -1
View File
@@ -38,7 +38,12 @@ export const CoinInstances = (coinProps: CoinProps) => {
}, [at, count, size, thickness]);
return (
<instancedMesh ref={ref} args={[undefined, undefined, count]}>
<instancedMesh
castShadow
receiveShadow
ref={ref}
args={[undefined, undefined, count]}
>
<CoinInstance {...coinProps} />
</instancedMesh>
);
+19 -19
View File
@@ -1,4 +1,4 @@
import { Canvas, PointLightProps } from "@react-three/fiber";
import { Canvas, SpotLightProps } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
import { useRef } from "react";
import { CoinInstances } from "./coin-instances";
@@ -6,6 +6,7 @@ import { CoinProps } from "@/types/coin";
import { PlaneProps, Physics, usePlane } from "@react-three/cannon";
import { Mesh } from "three";
import styles from "./index.module.css";
import { StageLightModel } from "./stage-light-model";
type Props = {
coins: CoinProps[];
@@ -13,33 +14,28 @@ type Props = {
const Plane = (props: PlaneProps) => {
const [ref] = usePlane(() => ({ ...props }), useRef<Mesh>(null));
return (
<mesh ref={ref}>
<circleGeometry args={[64]} />
<meshBasicMaterial color={"black"} />
<mesh receiveShadow ref={ref}>
<circleGeometry args={[128]} />
<meshStandardMaterial color={"#222"} metalness={0} roughness={1} />
</mesh>
);
};
const Lightbulb = (props: PointLightProps) => (
const StageLight = (props: SpotLightProps) => (
<>
<pointLight {...props} />
<mesh position={props.position}>
<sphereGeometry args={[0.25]} />
<meshBasicMaterial color="white" />
</mesh>
<spotLight {...props} castShadow penumbra={1} />
<StageLightModel position={props.position} />
</>
);
export const Pile = ({ coins }: Props) => (
<Canvas camera={{ position: [0, 16, 16] }} className={styles.canvas}>
<ambientLight />
<Lightbulb position={[0, 16, 0]} />
<Lightbulb position={[16, 0, 16]} />
<Lightbulb position={[16, 0, -16]} />
<Lightbulb position={[-16, 0, 16]} />
<Lightbulb position={[-16, 0, -16]} />
<Canvas shadows camera={{ position: [0, 16, 16] }} className={styles.canvas}>
<StageLight position={[32, 16, 32]} />
<StageLight position={[32, 16, -32]} />
<StageLight position={[-32, 16, 32]} />
<StageLight position={[-32, 16, -32]} />
<Physics gravity={[0, -20, 0]}>
<Plane rotation={[-Math.PI / 2, 0, 0]} position={[0, -2, 0]} />
{coins.map((coinProps) => (
@@ -47,6 +43,10 @@ export const Pile = ({ coins }: Props) => (
))}
</Physics>
<OrbitControls maxPolarAngle={Math.PI / 2} enablePan={false} />
<OrbitControls
maxPolarAngle={Math.PI / 2}
enablePan={false}
minDistance={4}
/>
</Canvas>
);
+36
View File
@@ -0,0 +1,36 @@
import { GroupProps } from "@react-three/fiber";
import { useGLTF } from "@react-three/drei";
import { useLayoutEffect, useRef } from "react";
import { Group } from "three";
export function StageLightModel(props: GroupProps) {
// @ts-expect-error properties `nodes` and `materials` actually exist
const { nodes, materials } = useGLTF("/models/stage-light.gltf");
const ref = useRef<Group>(null!);
useLayoutEffect(() => {
ref.current.lookAt(0, 0, 0);
ref.current.rotateY(-Math.PI / 2);
}, []);
return (
<group ref={ref} {...props} dispose={null}>
<mesh
position={[-2, 0, 0]}
castShadow
receiveShadow
geometry={nodes.Cube001.geometry}
material={materials.Base}
/>
<mesh
position={[-2, 0, 0]}
castShadow
receiveShadow
geometry={nodes.Cube001_1.geometry}
material={materials.Light}
/>
</group>
);
}
useGLTF.preload("/models/stage-light.gltf");