Skip to content

Commit

Permalink
feat - implement new hotspot system and postprocess basics
Browse files Browse the repository at this point in the history
  • Loading branch information
sdubourg committed Jul 26, 2023
1 parent c34055f commit 500ad08
Show file tree
Hide file tree
Showing 12 changed files with 279 additions and 43 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
"@react-spring/web": "^9.7.3",
"@react-three/drei": "9.68.3",
"@react-three/fiber": "8.13.0",
"@react-three/postprocessing": "^2.15.0",
"@types/three": "0.149.0",
"@xstate/react": "^3.2.2",
"leva": "^0.9.35",
"postprocessing": "^6.32.2",
"prettier": "^3.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
53 changes: 53 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 27 additions & 6 deletions src/components/gl/House/Appartment_v1.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ Command: npx [email protected] appartment_v1.gltf -t -K -T
Files: appartment_v1.gltf [18.62MB] > appartment_v1-transformed.glb [1.69MB] (91%)
*/

import * as THREE from 'three';
import React, { forwardRef, useRef } from 'react';
import { useGLTF } from '@react-three/drei';
import { forwardRef } from 'react';
import * as THREE from 'three';
import { type GLTF } from 'three-stdlib';
import { barMachine } from '../../../machines/bar.machine';
import { toiletMachine } from '../../../machines/toilet.machine';
import { AppartmentHotspot } from './HotSpots/AppartmentHotspot';

type GLTFResult = GLTF & {
nodes: {
Expand Down Expand Up @@ -97,6 +100,7 @@ export const AppartmentModel = forwardRef<
const { nodes, materials } = useGLTF(
'assets/appartment_v1-transformed.glb',
) as GLTFResult;

return (
<group {...props} dispose={null}>
<mesh ref={ref}>
Expand Down Expand Up @@ -204,13 +208,16 @@ export const AppartmentModel = forwardRef<
rotation={[Math.PI / 2, 0, 0]}
scale={4.673}
/>
<mesh

<AppartmentHotspot
geometry={nodes.bar001.geometry}
material={materials.bar}
materials={materials.bar}
position={[8.725, 1.23, 7.158]}
rotation={[-Math.PI / 2, 0, -0.191]}
scale={-5.408}
hotSpotMachine={barMachine}
/>

<mesh
geometry={nodes.graffitti_party.geometry}
material={materials.graffitti_party}
Expand Down Expand Up @@ -319,12 +326,23 @@ export const AppartmentModel = forwardRef<
position={[51.326, -0.712, 1.437]}
scale={11.879}
/>
<mesh

<AppartmentHotspot
geometry={nodes.cheloupee.geometry}
materials={materials.cheloupee}
position={[50.937, 3.299, -2.056]}
rotation={[Math.PI / 2, 0, 0]}
scale={4.715}
hotSpotMachine={toiletMachine}
/>

<AppartmentHotspot
geometry={nodes.cheloupee.geometry}
material={materials.cheloupee}
materials={materials.cheloupee}
position={[54.937, 3.299, -2.056]}
rotation={[Math.PI / 2, 0, 0]}
scale={4.715}
hotSpotMachine={toiletMachine}
/>
<mesh
geometry={nodes.sink.geometry}
Expand Down Expand Up @@ -359,14 +377,17 @@ export const AppartmentModel = forwardRef<
materials.render_map_brick,
8,
]}
// @ts-ignore
instanceMatrix={nodes.render_map_brick.instanceMatrix}
/>
<instancedMesh
args={[nodes.window002.geometry, materials.window, 7]}
// @ts-ignore
instanceMatrix={nodes.window002.instanceMatrix}
/>
<instancedMesh
args={[nodes.Cube001.geometry, nodes.Cube001.material, 8]}
// @ts-ignore
instanceMatrix={nodes.Cube001.instanceMatrix}
/>
</mesh>
Expand Down
78 changes: 78 additions & 0 deletions src/components/gl/House/HotSpots/AppartmentHotspot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { a, useSpring } from '@react-spring/three';
import type { MeshProps } from '@react-three/fiber';
import { useInterpret } from '@xstate/react';
import { useState } from 'react';
import { shallow } from 'zustand/shallow';
import { useStoreDragging } from '../../../../stores/storeDragging';
import type { AppartmentHotSpot } from './types';

export const AppartmentHotspot = ({
geometry,
materials,
hotSpotMachine,
...props
}: AppartmentHotSpot & MeshProps) => {
const [isHovered, setIsHovered] = useState(false);
const service = useInterpret(hotSpotMachine);

// TODO : use below solution when availble ===> registers hotspot machine in game machine
// const gameMachine = useGameMachineProvider();

// useEffect(() => {
// gameMachine.send({ type: 'HOTSPOT_CREATED', service });
// return () => {
// gameMachine.send({ type: 'HOTSPOT_DESTROYED', service });
// };
// }, []);

const { setIsDragging, isDragging, setDraggingId, draggingActorRef } =
useStoreDragging(
(state) => ({
isDragging: state.isDragging,
setDraggingId: state.setDraggingId,
setIsDragging: state.setIsDragging,
draggingActorRef: state.draggingActorRef,
}),
shallow,
);

// setup easings
const { glow, scale } = useSpring({
glow: isHovered ? 2 : 1,
scale: isHovered ? [1, 1.05, 1.05] : [1, 1, 1],
});

const handleOnClick = () => {
if (isDragging) {
setIsDragging(false);
setDraggingId(null);

draggingActorRef &&
service.send({ type: 'onAddPerson', person: draggingActorRef });
}
};

return (
// @ts-ignore
<a.group scale={scale} onClick={handleOnClick}>
<mesh
onPointerEnter={() => setIsHovered(true)}
onPointerLeave={() => setIsHovered(false)}
geometry={geometry}
material={materials}
{...props}
>
{/* @ts-ignore */}
<a.meshLambertMaterial
map={materials.map} // TODO: render some button in a different RenderTexture, to control light pulsing diffrent rythm
alphaTest={0.1}
transparent
toneMapped={false}
emissive={0xffffff}
emissiveMap={materials.map}
emissiveIntensity={glow}
/>
</mesh>
</a.group>
);
};
10 changes: 10 additions & 0 deletions src/components/gl/House/HotSpots/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { BufferGeometry, MeshStandardMaterial } from 'three';
import type {} from 'xstate';
import type { toiletMachine } from '../../../../machines/toilet.machine';
import type { barMachine } from '../../../../machines/bar.machine';

export type AppartmentHotSpot = {
geometry: BufferGeometry;
materials: MeshStandardMaterial;
hotSpotMachine: typeof barMachine | typeof toiletMachine;
};
47 changes: 27 additions & 20 deletions src/components/gl/Person/Person.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { a, useSpring } from '@react-spring/three';
import { Html, useTexture } from '@react-three/drei';
import { Box, Html, useTexture } from '@react-three/drei';

Check warning on line 2 in src/components/gl/Person/Person.tsx

View workflow job for this annotation

GitHub Actions / main - Build and deploy

'Box' is defined but never used

Check failure on line 2 in src/components/gl/Person/Person.tsx

View workflow job for this annotation

GitHub Actions / main - Build and deploy

'Box' is declared but its value is never read.
import { useFrame } from '@react-three/fiber';
import { useSelector } from '@xstate/react';
import { useControls } from 'leva';
Expand Down Expand Up @@ -86,7 +86,7 @@ export const Person = ({
useEffect(() => {
if (ref.current && refGroup.current && !isExists.current) {
ref.current.geometry.translate(0, PERSON_HEIGHT * 0.5, 0);
refGroup.current.position.copy(pos || new Vector3(0, 0, 30));
refGroup.current.position.copy(pos || new Vector3(-31, 0, 9));
isExists.current = true;
actor.send('triggerStart');
}
Expand All @@ -101,21 +101,28 @@ export const Person = ({
refFloor.current && raycaster.intersectObject(refFloor.current);

// drag
if (intersects && intersects.length > 0 && isBeingDragged) {
const [intersect] = intersects;
if (isDragging) {
const newGroupPos = new Vector3(
intersect.point.x,
0,
intersect.point.z,
);
refGroup.current.position.lerp(newGroupPos, 0.1);
ref.current.position.y = MathUtils.lerp(
ref.current.position.y,
PERSON_HEIGHT * 0.15,
0.2,
);
}
// if (intersects && intersects.length > 0 && isBeingDragged) {
// const [intersect] = intersects;
// if (isDragging) {
// const newGroupPos = new Vector3(
// intersect.point.x,
// 0,
// intersect.point.z,
// );
// refGroup.current.position.lerp(newGroupPos, 0.1);
// ref.current.position.y = MathUtils.lerp(
// ref.current.position.y,
// PERSON_HEIGHT * 0.15,
// 0.2,
// );
// }
// }

if (isDragging) {
refGroup.current.position.lerp(
new Vector3(camera.position.x, refGroup.current.position.y, 8),
0.75,
);
}

// wobble
Expand Down Expand Up @@ -152,13 +159,13 @@ export const Person = ({
return (
<>
<group ref={refGroup}>
<mesh ref={ref} uuid={serviceId} onClick={handleOnClick}>
<mesh ref={ref} uuid={serviceId} onPointerDown={handleOnClick}>
<planeBufferGeometry args={[3, PERSON_HEIGHT]} />
<meshBasicMaterial map={tex} transparent alphaTest={0.1} />
</mesh>
<Statbar position-y={6} value={thirst} />
<Statbar position-y={8} value={pee} />
<Statbar position-y={10} value={hype} />
<Statbar position-y={6.25} value={pee} />
<Statbar position-y={6.5} value={hype} />

<a.mesh
ref={refShadow}
Expand Down
2 changes: 1 addition & 1 deletion src/components/gl/Person/Statbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const fragmentShader = `
}
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
}
`;

Expand Down
4 changes: 2 additions & 2 deletions src/components/gl/Scene/Scene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ export const Scene = () => {
return (
<Canvas
camera={{ fov: 65 }}
gl={{ alpha: true }}
gl={{ alpha: true, antialias: true }}
style={{ width: '100vw', height: '100vh' }}
>
<ambientLight />
<ambientLight intensity={1.5} />

<World />
</Canvas>
Expand Down
Loading

0 comments on commit 500ad08

Please sign in to comment.