mirror of
https://github.com/DefectingCat/DefectingCat.github.io
synced 2025-07-15 08:41:37 +00:00
feat(3d): add bocchi and react model
This commit is contained in:
112
components/models/home/bocchi.tsx
Normal file
112
components/models/home/bocchi.tsx
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import { useGLTF, Float } from '@react-three/drei';
|
||||||
|
import { useLoader } from '@react-three/fiber';
|
||||||
|
import { JSX, useMemo } from 'react';
|
||||||
|
import { useMediaQuery } from 'react-responsive';
|
||||||
|
import * as THREE from 'three';
|
||||||
|
import { DRACOLoader, GLTF, GLTFLoader } from 'three-stdlib';
|
||||||
|
|
||||||
|
type GLTFResult = GLTF & {
|
||||||
|
nodes: {
|
||||||
|
Object_4: THREE.Mesh;
|
||||||
|
Object_6: THREE.Mesh;
|
||||||
|
Object_8: THREE.Mesh;
|
||||||
|
Object_10: THREE.Mesh;
|
||||||
|
Object_12: THREE.Mesh;
|
||||||
|
Object_14: THREE.Mesh;
|
||||||
|
Object_16: THREE.Mesh;
|
||||||
|
};
|
||||||
|
materials: {
|
||||||
|
main: THREE.MeshStandardMaterial;
|
||||||
|
material: THREE.MeshStandardMaterial;
|
||||||
|
yellow: THREE.MeshStandardMaterial;
|
||||||
|
blue: THREE.MeshStandardMaterial;
|
||||||
|
glass: THREE.MeshPhysicalMaterial;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const BocchiRubbishBin = (props: JSX.IntrinsicElements['group']) => {
|
||||||
|
const { nodes, materials } = useLoader(
|
||||||
|
GLTFLoader,
|
||||||
|
'/models/bocchi_the_rock-processed.glb',
|
||||||
|
(loader) => {
|
||||||
|
const dracoLoader = new DRACOLoader();
|
||||||
|
dracoLoader.setDecoderPath('/libs/draco/');
|
||||||
|
loader.setDRACOLoader(dracoLoader);
|
||||||
|
},
|
||||||
|
) as unknown as GLTFResult;
|
||||||
|
|
||||||
|
const isMobile = useMediaQuery({ query: '(max-width: 768px)' });
|
||||||
|
const position = useMemo(() => {
|
||||||
|
if (isMobile) {
|
||||||
|
return [5, 3, 0] as const;
|
||||||
|
}
|
||||||
|
return [-12, 7, 0] as const;
|
||||||
|
}, [isMobile]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Float floatIntensity={1.6}>
|
||||||
|
<group
|
||||||
|
{...props}
|
||||||
|
dispose={null}
|
||||||
|
position={position}
|
||||||
|
rotation={[Math.PI / 10, Math.PI / 10, 0]}
|
||||||
|
>
|
||||||
|
<mesh
|
||||||
|
castShadow
|
||||||
|
receiveShadow
|
||||||
|
geometry={nodes.Object_4.geometry}
|
||||||
|
material={materials.main}
|
||||||
|
/>
|
||||||
|
<mesh
|
||||||
|
castShadow
|
||||||
|
receiveShadow
|
||||||
|
geometry={nodes.Object_6.geometry}
|
||||||
|
material={materials.material}
|
||||||
|
position={[0, 0.375, -0.099]}
|
||||||
|
rotation={[0.21, 0, 0]}
|
||||||
|
/>
|
||||||
|
<mesh
|
||||||
|
castShadow
|
||||||
|
receiveShadow
|
||||||
|
geometry={nodes.Object_8.geometry}
|
||||||
|
material={materials.yellow}
|
||||||
|
/>
|
||||||
|
<mesh
|
||||||
|
castShadow
|
||||||
|
receiveShadow
|
||||||
|
geometry={nodes.Object_10.geometry}
|
||||||
|
material={materials.blue}
|
||||||
|
/>
|
||||||
|
<mesh
|
||||||
|
castShadow
|
||||||
|
receiveShadow
|
||||||
|
geometry={nodes.Object_12.geometry}
|
||||||
|
material={materials.main}
|
||||||
|
position={[0, 0.758, 0]}
|
||||||
|
/>
|
||||||
|
<mesh
|
||||||
|
castShadow
|
||||||
|
receiveShadow
|
||||||
|
geometry={nodes.Object_14.geometry}
|
||||||
|
material={materials.glass}
|
||||||
|
position={[0.856, 0.277, 1.046]}
|
||||||
|
rotation={[-0.033, 0.088, 1.429]}
|
||||||
|
scale={[-0.175, 0.175, 0.175]}
|
||||||
|
/>
|
||||||
|
<mesh
|
||||||
|
castShadow
|
||||||
|
receiveShadow
|
||||||
|
geometry={nodes.Object_16.geometry}
|
||||||
|
material={materials.glass}
|
||||||
|
position={[-0.852, 0.277, 1.046]}
|
||||||
|
rotation={[-0.032, -0.024, -1.413]}
|
||||||
|
scale={0.175}
|
||||||
|
/>
|
||||||
|
</group>
|
||||||
|
</Float>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
useGLTF.preload('/models/bocchi_the_rock-processed.glb');
|
||||||
|
|
||||||
|
export default BocchiRubbishBin;
|
@ -10,6 +10,8 @@ const ComputerModel = lazy(
|
|||||||
() => import('components/models/home/computer-model'),
|
() => import('components/models/home/computer-model'),
|
||||||
);
|
);
|
||||||
const Target = lazy(() => import('components/models/home/target'));
|
const Target = lazy(() => import('components/models/home/target'));
|
||||||
|
const ReactLogo = lazy(() => import('components/models/home/react-logo'));
|
||||||
|
const Bocchi = lazy(() => import('components/models/home/bocchi'));
|
||||||
|
|
||||||
const ComputerDesk = () => {
|
const ComputerDesk = () => {
|
||||||
const isMobile = useMediaQuery({ query: '(max-width: 768px)' });
|
const isMobile = useMediaQuery({ query: '(max-width: 768px)' });
|
||||||
@ -32,7 +34,9 @@ const ComputerDesk = () => {
|
|||||||
rotation={[0, -Math.PI, 0]}
|
rotation={[0, -Math.PI, 0]}
|
||||||
/>
|
/>
|
||||||
<Target />
|
<Target />
|
||||||
|
<ReactLogo />
|
||||||
<PerspectiveCamera makeDefault position={[0, 0, 30]} />
|
<PerspectiveCamera makeDefault position={[0, 0, 30]} />
|
||||||
|
<Bocchi />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
{/* <Leva /> */}
|
{/* <Leva /> */}
|
||||||
|
57
components/models/home/react-logo.tsx
Normal file
57
components/models/home/react-logo.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { useGLTF, Float } from '@react-three/drei';
|
||||||
|
import { useLoader } from '@react-three/fiber';
|
||||||
|
import { JSX, useMemo } from 'react';
|
||||||
|
import { useMediaQuery } from 'react-responsive';
|
||||||
|
import * as THREE from 'three';
|
||||||
|
import { DRACOLoader, GLTF, GLTFLoader } from 'three-stdlib';
|
||||||
|
|
||||||
|
type GLTFResult = GLTF & {
|
||||||
|
nodes: {
|
||||||
|
['React-Logo_Material002_0']: THREE.Mesh;
|
||||||
|
};
|
||||||
|
materials: {
|
||||||
|
['Material.002']: THREE.MeshStandardMaterial;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function ReactLogo(props: JSX.IntrinsicElements['group']) {
|
||||||
|
const { nodes, materials } = useLoader(
|
||||||
|
GLTFLoader,
|
||||||
|
'/models/react_logo-processed.glb',
|
||||||
|
(loader) => {
|
||||||
|
const dracoLoader = new DRACOLoader();
|
||||||
|
dracoLoader.setDecoderPath('/libs/draco/');
|
||||||
|
loader.setDRACOLoader(dracoLoader);
|
||||||
|
},
|
||||||
|
) as unknown as GLTFResult;
|
||||||
|
|
||||||
|
const isMobile = useMediaQuery({ query: '(max-width: 768px)' });
|
||||||
|
const position = useMemo(() => {
|
||||||
|
if (isMobile) {
|
||||||
|
return [5, 3, 0] as const;
|
||||||
|
}
|
||||||
|
return [10, 3, 0] as const;
|
||||||
|
}, [isMobile]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Float floatIntensity={1.6}>
|
||||||
|
<group {...props} dispose={null}>
|
||||||
|
<group scale={0.3} position={position}>
|
||||||
|
<mesh
|
||||||
|
castShadow
|
||||||
|
receiveShadow
|
||||||
|
geometry={nodes['React-Logo_Material002_0'].geometry}
|
||||||
|
material={materials['Material.002']}
|
||||||
|
position={[0, 7.935, 18.102]}
|
||||||
|
rotation={[0, 0, -Math.PI / 2]}
|
||||||
|
scale={[0.39, 0.39, 0.5]}
|
||||||
|
/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
</Float>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
useGLTF.preload('/models/react_logo.glb');
|
||||||
|
|
||||||
|
export default ReactLogo;
|
BIN
public/models/bocchi_rubbish_bin-processed.glb
Normal file
BIN
public/models/bocchi_rubbish_bin-processed.glb
Normal file
Binary file not shown.
BIN
public/models/bocchi_the_rock-processed.glb
Normal file
BIN
public/models/bocchi_the_rock-processed.glb
Normal file
Binary file not shown.
BIN
public/models/react_logo-processed.glb
Normal file
BIN
public/models/react_logo-processed.glb
Normal file
Binary file not shown.
Reference in New Issue
Block a user