adds furniture and music

This commit is contained in:
pb-coding 2023-09-26 13:27:40 +02:00
parent 57be5cd514
commit ab1bad8842
28 changed files with 801 additions and 26 deletions

View file

@ -9,7 +9,7 @@
/> />
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title> <title>Play Skyjo!</title>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

Binary file not shown.

View file

@ -0,0 +1,155 @@
{
"asset": {
"generator": "Khronos glTF Blender I/O v1.6.16",
"version": "2.0"
},
"scene": 0,
"scenes": [
{
"name": "Scene",
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0,
"name": "GreenChair_01"
}
],
"materials": [
{
"doubleSided": true,
"name": "GreenChair_01",
"normalTexture": {
"index": 0
},
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 1
},
"metallicRoughnessTexture": {
"index": 2
}
}
}
],
"meshes": [
{
"name": "classic-chair.003",
"primitives": [
{
"attributes": {
"POSITION": 0,
"NORMAL": 1,
"TEXCOORD_0": 2
},
"indices": 3,
"material": 0
}
]
}
],
"textures": [
{
"sampler": 0,
"source": 0
},
{
"sampler": 0,
"source": 1
},
{
"sampler": 0,
"source": 2
}
],
"images": [
{
"mimeType": "image/jpeg",
"name": "GreenChair_01_nor_gl",
"uri": "textures/GreenChair_01_nor_gl_1k.jpg"
},
{
"mimeType": "image/jpeg",
"name": "GreenChair_01_diff",
"uri": "textures/GreenChair_01_diff_1k.jpg"
},
{
"mimeType": "image/jpeg",
"name": "GreenChair_01_metallic-GreenChair_01_roughness",
"uri": "textures/GreenChair_01_arm_1k.jpg"
}
],
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 2934,
"max": [
0.3360123336315155,
1.0579816102981567,
0.2863401472568512
],
"min": [
-0.3370821177959442,
-0.0005302081117406487,
-0.37804722785949707
],
"type": "VEC3"
},
{
"bufferView": 1,
"componentType": 5126,
"count": 2934,
"type": "VEC3"
},
{
"bufferView": 2,
"componentType": 5126,
"count": 2934,
"type": "VEC2"
},
{
"bufferView": 3,
"componentType": 5123,
"count": 12639,
"type": "SCALAR"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 35208,
"byteOffset": 0
},
{
"buffer": 0,
"byteLength": 35208,
"byteOffset": 35208
},
{
"buffer": 0,
"byteLength": 23472,
"byteOffset": 70416
},
{
"buffer": 0,
"byteLength": 25278,
"byteOffset": 93888
}
],
"samplers": [
{
"magFilter": 9729,
"minFilter": 9987
}
],
"buffers": [
{
"byteLength": 119168,
"uri": "GreenChair_01.bin"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

View file

@ -0,0 +1,268 @@
{
"asset": {
"generator": "Khronos glTF Blender I/O v3.3.32",
"version": "2.0"
},
"scene": 0,
"scenes": [
{
"name": "blend_export.001",
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0,
"name": "modern_arm_chair_01"
}
],
"materials": [
{
"doubleSided": true,
"name": "modern_arm_chair_01_legs",
"normalTexture": {
"index": 0
},
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 1
},
"metallicRoughnessTexture": {
"index": 2
}
}
},
{
"doubleSided": true,
"name": "modern_arm_chair_01_pillow",
"normalTexture": {
"index": 3
},
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 4
},
"metallicRoughnessTexture": {
"index": 5
}
}
}
],
"meshes": [
{
"name": "Cube.007",
"primitives": [
{
"attributes": {
"POSITION": 0,
"NORMAL": 1,
"TEXCOORD_0": 2
},
"indices": 3,
"material": 0
},
{
"attributes": {
"POSITION": 4,
"NORMAL": 5,
"TEXCOORD_0": 6
},
"indices": 7,
"material": 1
}
]
}
],
"textures": [
{
"sampler": 0,
"source": 0
},
{
"sampler": 0,
"source": 1
},
{
"sampler": 0,
"source": 2
},
{
"sampler": 0,
"source": 3
},
{
"sampler": 0,
"source": 4
},
{
"sampler": 0,
"source": 5
}
],
"images": [
{
"mimeType": "image/jpeg",
"name": "modern_arm_chair_01_legs_nor_gl",
"uri": "textures/modern_arm_chair_01_legs_nor_gl_1k.jpg"
},
{
"mimeType": "image/jpeg",
"name": "modern_arm_chair_01_legs_diff",
"uri": "textures/modern_arm_chair_01_legs_diff_1k.jpg"
},
{
"mimeType": "image/jpeg",
"name": "modern_arm_chair_01_legs_metal-modern_arm_chair_01_legs_rough",
"uri": "textures/modern_arm_chair_01_legs_arm_1k.jpg"
},
{
"mimeType": "image/jpeg",
"name": "modern_arm_chair_01_pillow_nor_gl",
"uri": "textures/modern_arm_chair_01_pillow_nor_gl_1k.jpg"
},
{
"mimeType": "image/jpeg",
"name": "modern_arm_chair_01_pillow_diff",
"uri": "textures/modern_arm_chair_01_pillow_diff_1k.jpg"
},
{
"mimeType": "image/jpeg",
"name": "modern_arm_chair_01_pillow_metal-modern_arm_chair_01_pillow_rough",
"uri": "textures/modern_arm_chair_01_pillow_arm_1k.jpg"
}
],
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 3884,
"max": [
0.4135356843471527,
0.8698092699050903,
0.41110995411872864
],
"min": [
-0.4068087339401245,
0.0003815953677985817,
-0.56038498878479
],
"type": "VEC3"
},
{
"bufferView": 1,
"componentType": 5126,
"count": 3884,
"type": "VEC3"
},
{
"bufferView": 2,
"componentType": 5126,
"count": 3884,
"type": "VEC2"
},
{
"bufferView": 3,
"componentType": 5123,
"count": 16824,
"type": "SCALAR"
},
{
"bufferView": 4,
"componentType": 5126,
"count": 1967,
"max": [
0.3583531975746155,
1.0232336521148682,
0.38417327404022217
],
"min": [
-0.3549351990222931,
0.34748637676239014,
-0.5754517316818237
],
"type": "VEC3"
},
{
"bufferView": 5,
"componentType": 5126,
"count": 1967,
"type": "VEC3"
},
{
"bufferView": 6,
"componentType": 5126,
"count": 1967,
"type": "VEC2"
},
{
"bufferView": 7,
"componentType": 5123,
"count": 9924,
"type": "SCALAR"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 46608,
"byteOffset": 0,
"target": 34962
},
{
"buffer": 0,
"byteLength": 46608,
"byteOffset": 46608,
"target": 34962
},
{
"buffer": 0,
"byteLength": 31072,
"byteOffset": 93216,
"target": 34962
},
{
"buffer": 0,
"byteLength": 33648,
"byteOffset": 124288,
"target": 34963
},
{
"buffer": 0,
"byteLength": 23604,
"byteOffset": 157936,
"target": 34962
},
{
"buffer": 0,
"byteLength": 23604,
"byteOffset": 181540,
"target": 34962
},
{
"buffer": 0,
"byteLength": 15736,
"byteOffset": 205144,
"target": 34962
},
{
"buffer": 0,
"byteLength": 19848,
"byteOffset": 220880,
"target": 34963
}
],
"samplers": [
{
"magFilter": 9729,
"minFilter": 9987
}
],
"buffers": [
{
"byteLength": 240728,
"uri": "modern_arm_chair_01.bin"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 KiB

Binary file not shown.

View file

@ -0,0 +1,238 @@
{
"asset": {
"generator": "Khronos glTF Blender I/O v1.6.16",
"version": "2.0"
},
"scene": 0,
"scenes": [
{
"name": "Scene",
"nodes": [
0,
1
]
}
],
"nodes": [
{
"mesh": 0,
"name": "sofa_02_Base",
"translation": [
0.00026735191931948066,
0.00020578503608703613,
0.03126468509435654
]
},
{
"mesh": 1,
"name": "sofa_02_Seat",
"translation": [
0.00026735191931948066,
0.00020578503608703613,
0.03126468509435654
]
}
],
"materials": [
{
"doubleSided": true,
"name": "sofa_02",
"normalTexture": {
"index": 0
},
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 1
},
"metallicRoughnessTexture": {
"index": 2
}
}
}
],
"meshes": [
{
"name": "Plane.001",
"primitives": [
{
"attributes": {
"POSITION": 0,
"NORMAL": 1,
"TEXCOORD_0": 2
},
"indices": 3,
"material": 0
}
]
},
{
"name": "Mesh.007",
"primitives": [
{
"attributes": {
"POSITION": 4,
"NORMAL": 5,
"TEXCOORD_0": 6
},
"indices": 7,
"material": 0
}
]
}
],
"textures": [
{
"sampler": 0,
"source": 0
},
{
"sampler": 0,
"source": 1
},
{
"sampler": 0,
"source": 2
}
],
"images": [
{
"mimeType": "image/jpeg",
"name": "sofa_02_nor_gl",
"uri": "textures/sofa_02_nor_gl_1k.jpg"
},
{
"mimeType": "image/jpeg",
"name": "sofa_02_diff",
"uri": "textures/sofa_02_diff_1k.jpg"
},
{
"mimeType": "image/jpeg",
"name": "sofa_02_metallic-sofa_02_roughness",
"uri": "textures/sofa_02_arm_1k.jpg"
}
],
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 1616,
"max": [
0.9035836458206177,
0.7094888687133789,
0.3020688593387604
],
"min": [
-0.9035837054252625,
-5.960464477539063e-8,
-0.5089631676673889
],
"type": "VEC3"
},
{
"bufferView": 1,
"componentType": 5126,
"count": 1616,
"type": "VEC3"
},
{
"bufferView": 2,
"componentType": 5126,
"count": 1616,
"type": "VEC2"
},
{
"bufferView": 3,
"componentType": 5123,
"count": 7032,
"type": "SCALAR"
},
{
"bufferView": 4,
"componentType": 5126,
"count": 212,
"max": [
0.7098315358161926,
0.41038596630096436,
0.3087882101535797
],
"min": [
-0.7062357068061829,
0.24655179679393768,
-0.2188045084476471
],
"type": "VEC3"
},
{
"bufferView": 5,
"componentType": 5126,
"count": 212,
"type": "VEC3"
},
{
"bufferView": 6,
"componentType": 5126,
"count": 212,
"type": "VEC2"
},
{
"bufferView": 7,
"componentType": 5123,
"count": 1152,
"type": "SCALAR"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 19392,
"byteOffset": 0
},
{
"buffer": 0,
"byteLength": 19392,
"byteOffset": 19392
},
{
"buffer": 0,
"byteLength": 12928,
"byteOffset": 38784
},
{
"buffer": 0,
"byteLength": 14064,
"byteOffset": 51712
},
{
"buffer": 0,
"byteLength": 2544,
"byteOffset": 65776
},
{
"buffer": 0,
"byteLength": 2544,
"byteOffset": 68320
},
{
"buffer": 0,
"byteLength": 1696,
"byteOffset": 70864
},
{
"buffer": 0,
"byteLength": 2304,
"byteOffset": 72560
}
],
"samplers": [
{
"magFilter": 9729,
"minFilter": 9987
}
],
"buffers": [
{
"byteLength": 74864,
"uri": "sofa_02.bin"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

BIN
public/textures/carpet.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 MiB

View file

@ -1,8 +1,10 @@
import { FC } from "react"; import { FC } from "react";
import { Object3D, Mesh, Vector3 } from "three"; import { Vector3 } from "three";
import { Canvas } from "@react-three/fiber"; import { Canvas } from "@react-three/fiber";
import { useGLTF } from "@react-three/drei"; import { OrbitControls, Environment } from "@react-three/drei";
import Music from "../components/Music";
import Model from "../components/Model";
import PlayArea from "../components/PlayArea"; import PlayArea from "../components/PlayArea";
import { Game } from "../types/gameTypes"; import { Game } from "../types/gameTypes";
import { createFloor } from "../objects/floor"; import { createFloor } from "../objects/floor";
@ -12,13 +14,30 @@ type GameCanvasProps = {
gameData: Game | null; gameData: Game | null;
}; };
const ENVIRONMENT = import.meta.env.VITE_ENVIRONMENT || "";
const GameCanvas: FC<GameCanvasProps> = ({ gameData }) => { const GameCanvas: FC<GameCanvasProps> = ({ gameData }) => {
const tableModel = useGLTF("/models/table.glb");
const heightProportion = 1.4; const heightProportion = 1.4;
const aspectRatio = const aspectRatio =
window.innerWidth / (window.innerHeight / heightProportion); window.innerWidth / (window.innerHeight / heightProportion);
const floorObject = createFloor(new Vector3(0, 0, 0)); const floorObject = createFloor(
new Vector3(0, 0, 0),
{ x: 1, y: 0.001, z: 1 },
"/textures/floor.jpg",
200
);
const carpetObject = createFloor(
new Vector3(0, 1, 0),
{ x: 1, y: 0.001, z: 2 },
"/textures/red-carpet.jpg",
60,
true,
4,
4
);
const isLocalEnv = ENVIRONMENT === "local";
if (!gameData) return null; if (!gameData) return null;
@ -38,32 +57,53 @@ const GameCanvas: FC<GameCanvasProps> = ({ gameData }) => {
aspect: aspectRatio, aspect: aspectRatio,
}} }}
> >
<ambientLight color={0xa3a3a3} intensity={0.1} /> <Environment preset="apartment" />
<Music />
{/*<ambientLight color={0xa3a3a3} intensity={0.1} />
<directionalLight <directionalLight
color={0xffffff} color={0xffffff}
position={[0, 50, 20]} position={[0, 40, 20]}
castShadow castShadow
shadow-mapSize={[1024, 1024]} shadow-mapSize={[1024, 1024]}
/> />*/}
<mesh> <mesh>
<boxGeometry args={[2, 2, 2]} /> <boxGeometry args={[2, 2, 2]} />
<meshStandardMaterial color={0x00ff00} /> <meshStandardMaterial color={0x00ff00} />
</mesh> </mesh>
<primitive <Model
object={tableModel.scene} name="table"
path="/models/table.glb"
position={[0, 1.8, 2]} position={[0, 1.8, 2]}
scale={[2, 2, 2]} scale={[2, 2, 2]}
traverse={(node: Object3D) => {
if (node instanceof Mesh) {
// node.castShadow = true;
node.receiveShadow = true;
}
}}
/> />
<Model
name="armchair"
path="/models/arm-chair/modern_arm_chair_01_1k.gltf"
position={[0, 0, 16]}
rotation={[0, 3.15, 0]}
scale={[20, 20, 20]}
/>
<Model
name="green-chair"
path="/models/GreenChair_01_1k.gltf/GreenChair_01_1k.gltf"
position={[0, 0, -18]}
rotation={[0, 0, 0]}
scale={[25, 25, 25]}
/>
<Model
name="sofa"
path="/models/sofa/sofa_02_1k.gltf"
position={[-25, 0, 2]}
rotation={[0, 1.55, 0]}
scale={[25, 25, 25]}
/>
<gridHelper args={[100, 100]} /> <gridHelper args={[100, 100]} />
<axesHelper args={[5]} /> <axesHelper args={[5]} />
{isLocalEnv && <OrbitControls />}
<PlayArea gameData={gameData} /> <PlayArea gameData={gameData} />
<primitive object={floorObject} /> <primitive object={floorObject} />
<primitive object={carpetObject} />
</Canvas> </Canvas>
</div> </div>
); );

30
src/components/Model.tsx Normal file
View file

@ -0,0 +1,30 @@
import { FC } from "react";
import { useGLTF } from "@react-three/drei";
type ModelProps = {
name: string;
path: string;
position: [number, number, number];
rotation?: [number, number, number];
scale: [number, number, number];
};
const Model: FC<ModelProps> = ({
path,
position,
rotation = [0, 0, 0],
scale,
}) => {
const model = useGLTF(path);
return (
<primitive
object={model.scene}
position={position}
rotation={rotation}
scale={scale}
/>
);
};
export default Model;

31
src/components/Music.tsx Normal file
View file

@ -0,0 +1,31 @@
import { FC, useEffect } from "react";
import { AudioLoader, Audio, AudioListener } from "three";
import { useThree } from "@react-three/fiber";
const Music: FC = () => {
const { camera } = useThree(); // Access the camera using useThree hook
useEffect(() => {
const listener = new AudioListener();
camera.add(listener); // Add the listener to the camera
const sound = new Audio(listener);
const audioLoader = new AudioLoader();
audioLoader.load("/music/Local_Forecast.mp3", function (buffer) {
sound.setBuffer(buffer);
sound.setLoop(true);
sound.setVolume(0.5);
sound.play();
});
// Cleanup listener on component unmount
return () => {
sound.stop();
camera.remove(listener);
};
}, [camera]);
return <></>;
};
export default Music;

View file

@ -5,20 +5,33 @@ import {
SRGBColorSpace, SRGBColorSpace,
Vector3, Vector3,
Mesh, Mesh,
RepeatWrapping,
} from "three"; } from "three";
export const createFloor = (
position: Vector3,
sizeObject: { x: number; y: number; z: number },
texturePath: string,
floorSize: number,
repeating: boolean = false,
repeatX: number = 1,
repeatY: number = 1
) => {
const textureLoader = new TextureLoader(); const textureLoader = new TextureLoader();
const floorSize = 200;
const floorGeometry = new BoxGeometry( const floorGeometry = new BoxGeometry(
floorSize * 1, floorSize * sizeObject.x,
floorSize * 0.001, floorSize * sizeObject.y,
floorSize * 1 floorSize * sizeObject.z
); );
const floorTexture = textureLoader.load("/textures/floor.jpg"); const floorTexture = textureLoader.load(texturePath);
floorTexture.colorSpace = SRGBColorSpace; floorTexture.colorSpace = SRGBColorSpace;
if (repeating) {
floorTexture.wrapS = RepeatWrapping;
floorTexture.wrapT = RepeatWrapping;
floorTexture.repeat.set(repeatX, repeatY);
}
export const createFloor = (position: Vector3) => {
const floorMaterial = [ const floorMaterial = [
new MeshBasicMaterial(), new MeshBasicMaterial(),
new MeshBasicMaterial(), new MeshBasicMaterial(),