diff --git a/mario_kart.tsx b/mario_kart.tsx new file mode 100644 index 0000000..1685f80 --- /dev/null +++ b/mario_kart.tsx @@ -0,0 +1,46 @@ +/* +Auto-generated by: https://github.com/pmndrs/gltfjsx +Command: npx gltfjsx@6.2.16 c:\Users\mouli\Downloads\mario_kart.glb -o c:\Users\mouli\Desktop\mario_kart.tsx --types +Author: TheShibeLord (https://sketchfab.com/TheShibeLord) +License: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/) +Source: https://sketchfab.com/3d-models/mario-kart-66cc131575344ab69238ec5872f24927 +Title: Mario Kart +*/ + +import * as THREE from 'three' +import React, { useRef } from 'react' +import { useGLTF } from '@react-three/drei' +import { GLTF } from 'three-stdlib' + +type GLTFResult = GLTF & { + nodes: { + mt_mario: THREE.Mesh + mt_kart_Mario_S: THREE.Mesh + mt_Kart_Mario_Tire_S: THREE.Mesh + } + materials: { + mt_mario: THREE.MeshStandardMaterial + mt_kart_Mario_S: THREE.MeshStandardMaterial + mt_Kart_Mario_Tire_S: THREE.MeshStandardMaterial + } + animations: GLTFAction[] +} + +type ContextType = Record> + +export function Model(props: JSX.IntrinsicElements['group']) { + const { nodes, materials } = useGLTF('/mario_kart.glb') as GLTFResult + return ( + + + + + + + + + + ) +} + +useGLTF.preload('/mario_kart.glb') diff --git a/package-lock.json b/package-lock.json index 2463e9f..6fa0e9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@react-three/drei": "^9.93.0", "@react-three/fiber": "^8.15.13", "@react-three/postprocessing": "^2.15.11", + "@react-three/rapier": "^1.2.1", "gsap": "^3.12.4", "leva": "^0.9.35", "react": "^18.2.0", @@ -35,6 +36,40 @@ "node": ">=6.9.0" } }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-10.5.0.tgz", + "integrity": "sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw==", + "dependencies": { + "@chevrotain/gast": "10.5.0", + "@chevrotain/types": "10.5.0", + "lodash": "4.17.21" + } + }, + "node_modules/@chevrotain/gast": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-10.5.0.tgz", + "integrity": "sha512-pXdMJ9XeDAbgOWKuD1Fldz4ieCs6+nLNmyVhe2gZVqoO7v8HXuHYs5OV2EzUtbuai37TlOAQHrTDvxMnvMJz3A==", + "dependencies": { + "@chevrotain/types": "10.5.0", + "lodash": "4.17.21" + } + }, + "node_modules/@chevrotain/types": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-10.5.0.tgz", + "integrity": "sha512-f1MAia0x/pAVPWH/T73BJVyO2XU5tI4/iE7cnxb7tqdNTNhQI3Uq3XkqcoteTmD4t1aM0LbHCJOhgIDn07kl2A==" + }, + "node_modules/@chevrotain/utils": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-10.5.0.tgz", + "integrity": "sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ==" + }, + "node_modules/@dimforge/rapier3d-compat": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.11.2.tgz", + "integrity": "sha512-vdWmlkpS3G8nGAzLuK7GYTpNdrkn/0NKCe0l1Jqxc7ZZOB3N0q9uG/Ap9l9bothWuAvxscIt0U97GVLr0lXWLg==" + }, "node_modules/@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", @@ -1019,6 +1054,42 @@ "three": ">=0.144.0" } }, + "node_modules/@react-three/rapier": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@react-three/rapier/-/rapier-1.2.1.tgz", + "integrity": "sha512-h22uqwvMBVVmwfe37fs0tF3u+gNDJv/LzS4lRYnZ4IaHZPlprAjvccef6R7pFlW2EU/o26HhzTMoE5/Btkdcew==", + "dependencies": { + "@dimforge/rapier3d-compat": "0.11.2", + "three-stdlib": "2.23.9", + "use-asset": "1.0.4" + }, + "peerDependencies": { + "@react-three/fiber": ">=8.9.0", + "react": ">=18.0.0", + "three": ">=0.139.0" + } + }, + "node_modules/@react-three/rapier/node_modules/three-stdlib": { + "version": "2.23.9", + "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.23.9.tgz", + "integrity": "sha512-fYBClVGQptD7UZcoRZGNlR3sKcUW37hVPoEW1v68E4XuiwD0Ml/VqDUJ0yEMVE2DlooDvqgqv/rIcHC/B4N5pg==", + "dependencies": { + "@types/draco3d": "^1.4.0", + "@types/offscreencanvas": "^2019.6.4", + "@types/webxr": "^0.5.2", + "chevrotain": "^10.1.2", + "draco3d": "^1.4.1", + "fflate": "^0.6.9", + "ktx-parse": "^0.4.5", + "mmd-parser": "^1.0.4", + "opentype.js": "^1.3.3", + "potpack": "^1.0.1", + "zstddec": "^0.0.2" + }, + "peerDependencies": { + "three": ">=0.128.0" + } + }, "node_modules/@stitches/react": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@stitches/react/-/react-1.2.8.tgz", @@ -1470,6 +1541,19 @@ "three": ">=0.126.1" } }, + "node_modules/chevrotain": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-10.5.0.tgz", + "integrity": "sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==", + "dependencies": { + "@chevrotain/cst-dts-gen": "10.5.0", + "@chevrotain/gast": "10.5.0", + "@chevrotain/types": "10.5.0", + "@chevrotain/utils": "10.5.0", + "lodash": "4.17.21", + "regexp-to-ast": "0.5.0" + } + }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -1741,6 +1825,11 @@ "node": ">=0.10.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, "node_modules/fflate": { "version": "0.6.10", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", @@ -2024,6 +2113,11 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "node_modules/ktx-parse": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.4.5.tgz", + "integrity": "sha512-MK3FOody4TXbFf8Yqv7EBbySw7aPvEcPX++Ipt6Sox+/YMFvR5xaTyhfNSk1AEmMy+RYIw81ctN4IMxCB8OAlg==" + }, "node_modules/leva": { "version": "0.9.35", "resolved": "https://registry.npmjs.org/leva/-/leva-0.9.35.tgz", @@ -2046,6 +2140,11 @@ "react-dom": ">=16.8.0" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lodash.clamp": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/lodash.clamp/-/lodash.clamp-4.0.3.tgz", @@ -2172,6 +2271,11 @@ "node": ">=0.10.0" } }, + "node_modules/mmd-parser": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mmd-parser/-/mmd-parser-1.0.4.tgz", + "integrity": "sha512-Qi0VCU46t2IwfGv5KF0+D/t9cizcDug7qnNoy9Ggk7aucp0tssV8IwTMkBlDbm+VqAf3cdQHTCARKSsuS2MYFg==" + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -2243,6 +2347,21 @@ "node": ">= 0.8" } }, + "node_modules/opentype.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz", + "integrity": "sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw==", + "dependencies": { + "string.prototype.codepointat": "^0.2.1", + "tiny-inflate": "^1.0.3" + }, + "bin": { + "ot": "bin/ot" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -2485,6 +2604,11 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, + "node_modules/regexp-to-ast": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz", + "integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==" + }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -2706,6 +2830,11 @@ "node": ">= 0.8" } }, + "node_modules/string.prototype.codepointat": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", + "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==" + }, "node_modules/suspend-react": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz", @@ -2743,6 +2872,11 @@ "three": ">=0.128.0" } }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -2803,6 +2937,17 @@ "node": ">= 0.8" } }, + "node_modules/use-asset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/use-asset/-/use-asset-1.0.4.tgz", + "integrity": "sha512-7/hqDrWa0iMnCoET9W1T07EmD4Eg/Wmoj/X8TGBc++ECRK4m5yTsjP4O6s0yagbxfqIOuUkIxe2/sA+VR2GxZA==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "react": ">=17.0" + } + }, "node_modules/utility-types": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", @@ -2923,6 +3068,11 @@ "node": ">= 8" } }, + "node_modules/zstddec": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/zstddec/-/zstddec-0.0.2.tgz", + "integrity": "sha512-DCo0oxvcvOTGP/f5FA6tz2Z6wF+FIcEApSTu0zV5sQgn9hoT5lZ9YRAKUraxt9oP7l4e8TnNdi8IZTCX6WCkwA==" + }, "node_modules/zustand": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", diff --git a/package.json b/package.json index d2fb45b..607d87b 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@react-three/drei": "^9.93.0", "@react-three/fiber": "^8.15.13", "@react-three/postprocessing": "^2.15.11", + "@react-three/rapier": "^1.2.1", "gsap": "^3.12.4", "leva": "^0.9.35", "react": "^18.2.0", diff --git a/public/models/Mariokart.jsx b/public/models/Mariokart.jsx new file mode 100644 index 0000000..e565191 --- /dev/null +++ b/public/models/Mariokart.jsx @@ -0,0 +1,21 @@ +/* +Auto-generated by: https://github.com/pmndrs/gltfjsx +Command: npx gltfjsx@6.2.16 .\mariokart.glb --transform --shadows +Files: .\mariokart.glb [101.9KB] > C:\Users\mouli\dev\r3f-vite-starter\public\models\mariokart-transformed.glb [26.36KB] (74%) +*/ + +import React, { useRef } from 'react' +import { useGLTF } from '@react-three/drei' + +export function ario(props) { + const { nodes, materials } = useGLTF('/mariokart-transformed.glb') + return ( + + + + + + ) +} + +useGLTF.preload('/mariokart-transformed.glb') diff --git a/public/models/front_wheel.glb b/public/models/front_wheel.glb new file mode 100644 index 0000000..55271b8 Binary files /dev/null and b/public/models/front_wheel.glb differ diff --git a/public/models/mario_kart-transformed.glb b/public/models/mario_kart-transformed.glb new file mode 100644 index 0000000..f9721ad Binary files /dev/null and b/public/models/mario_kart-transformed.glb differ diff --git a/public/models/mario_kart.glb b/public/models/mario_kart.glb new file mode 100644 index 0000000..1653d96 Binary files /dev/null and b/public/models/mario_kart.glb differ diff --git a/public/models/mariokart-transformed.glb b/public/models/mariokart-transformed.glb new file mode 100644 index 0000000..a1e15a9 Binary files /dev/null and b/public/models/mariokart-transformed.glb differ diff --git a/public/models/mariokart.glb b/public/models/mariokart.glb new file mode 100644 index 0000000..15ee576 Binary files /dev/null and b/public/models/mariokart.glb differ diff --git a/public/models/mariokarttest-transformed.glb b/public/models/mariokarttest-transformed.glb new file mode 100644 index 0000000..a1e15a9 Binary files /dev/null and b/public/models/mariokarttest-transformed.glb differ diff --git a/public/models/mariokarttest.glb b/public/models/mariokarttest.glb new file mode 100644 index 0000000..15ee576 Binary files /dev/null and b/public/models/mariokarttest.glb differ diff --git a/public/models/mariokarttest.tsx b/public/models/mariokarttest.tsx new file mode 100644 index 0000000..54eaeb8 --- /dev/null +++ b/public/models/mariokarttest.tsx @@ -0,0 +1,42 @@ +/* +Auto-generated by: https://github.com/pmndrs/gltfjsx +Command: npx gltfjsx@6.2.16 c:\Users\mouli\dev\r3f-vite-starter\public\models\mariokarttest.glb -o c:\Users\mouli\dev\r3f-vite-starter\public\models\mariokarttest.tsx --types +*/ + +import * as THREE from 'three' +import React, { useRef } from 'react' +import { useGLTF } from '@react-three/drei' +import { GLTF } from 'three-stdlib' + +type GLTFResult = GLTF & { + nodes: { + mt_kart_Mario_S: THREE.Mesh + mt_Kart_Mario_Tire_S001: THREE.Mesh + mt_Kart_Mario_Tire_S002: THREE.Mesh + mt_Kart_Mario_Tire_S003: THREE.Mesh + mt_mario: THREE.Mesh + } + materials: { + mt_kart_Mario_S: THREE.MeshStandardMaterial + mt_Kart_Mario_Tire_S: THREE.MeshStandardMaterial + mt_mario: THREE.MeshStandardMaterial + } + animations: GLTFAction[] +} + +type ContextType = Record> + +export function Model(props: JSX.IntrinsicElements['group']) { + const { nodes, materials } = useGLTF('/mariokarttest.glb') as GLTFResult + return ( + + + + + + + + ) +} + +useGLTF.preload('/mariokarttest.glb') diff --git a/public/models/racing_kart-transformed.glb b/public/models/racing_kart-transformed.glb new file mode 100644 index 0000000..c26d66b Binary files /dev/null and b/public/models/racing_kart-transformed.glb differ diff --git a/public/models/racing_kart.glb b/public/models/racing_kart.glb new file mode 100644 index 0000000..9ac78c6 Binary files /dev/null and b/public/models/racing_kart.glb differ diff --git a/public/models/racing_kart_test-transformed.glb b/public/models/racing_kart_test-transformed.glb new file mode 100644 index 0000000..dc39ccf Binary files /dev/null and b/public/models/racing_kart_test-transformed.glb differ diff --git a/public/models/racing_kart_test.glb b/public/models/racing_kart_test.glb new file mode 100644 index 0000000..6c969f4 Binary files /dev/null and b/public/models/racing_kart_test.glb differ diff --git a/public/models/rear_wheels.glb b/public/models/rear_wheels.glb new file mode 100644 index 0000000..79cf991 Binary files /dev/null and b/public/models/rear_wheels.glb differ diff --git a/public/models/spafrancorchamps-REALISTIC.glb b/public/models/spafrancorchamps-REALISTIC.glb new file mode 100644 index 0000000..b70e756 Binary files /dev/null and b/public/models/spafrancorchamps-REALISTIC.glb differ diff --git a/public/models/spafrancorchamps-transformed.glb b/public/models/spafrancorchamps-transformed.glb new file mode 100644 index 0000000..06b3351 Binary files /dev/null and b/public/models/spafrancorchamps-transformed.glb differ diff --git a/public/models/spafrancorchamps.glb b/public/models/spafrancorchamps.glb new file mode 100644 index 0000000..89e0fe4 Binary files /dev/null and b/public/models/spafrancorchamps.glb differ diff --git a/public/models/tour_paris_promenade-transformed.glb b/public/models/tour_paris_promenade-transformed.glb new file mode 100644 index 0000000..5c320bb Binary files /dev/null and b/public/models/tour_paris_promenade-transformed.glb differ diff --git a/public/models/tour_paris_promenade.glb b/public/models/tour_paris_promenade.glb new file mode 100644 index 0000000..cce2c0b Binary files /dev/null and b/public/models/tour_paris_promenade.glb differ diff --git a/public/vite.svg b/public/models/vite.svg similarity index 100% rename from public/vite.svg rename to public/models/vite.svg diff --git a/src/App.jsx b/src/App.jsx index bf6275c..d94e99a 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,11 +1,51 @@ import { Canvas } from "@react-three/fiber"; import { Experience } from "./components/Experience"; +import { Suspense, useMemo } from "react"; +import { Physics } from "@react-three/rapier"; +import { + KeyboardControls, + Loader, + OrbitControls, + Preload, + Stats, +} from "@react-three/drei"; +export const Controls = { + up: "up", + down: "down", + left: "left", + right: "right", + boost: "boost", + shoot: "shoot", + slow: "slow", + reset: "reset", +}; function App() { + + + const map = useMemo( + () => [ + { name: Controls.up, keys: ["KeyW", "ArrowUp"] }, + { name: Controls.down, keys: ["KeyS", "ArrowDown"] }, + { name: Controls.left, keys: ["KeyA", "ArrowLeft"] }, + { name: Controls.right, keys: ["KeyD", "ArrowRight"] }, + { name: Controls.jump, keys: ["Space"] }, + { name: Controls.slow, keys: ["Shift"] }, + { name: Controls.shoot, keys: ["KeyE", "Click"] }, + { name: Controls.reset, keys: ["KeyR"] }, + ], + [] + ); + return ( - - - + + + + + + + + ); } diff --git a/src/components/Experience.jsx b/src/components/Experience.jsx index a829491..de8093b 100644 --- a/src/components/Experience.jsx +++ b/src/components/Experience.jsx @@ -1,13 +1,46 @@ -import { OrbitControls } from "@react-three/drei"; +import { + Environment, + OrbitControls, + PerspectiveCamera, + Lightformer +} from "@react-three/drei"; +import { Ground } from "./Ground"; +import { RigidBody } from "@react-three/rapier"; +import { PlayerController } from "./PlayerController"; +import { Track } from "./models/Spafrancorchamps-REALISTIC"; +import { Paris } from "./models/Tour_paris_promenade"; +import { EffectComposer, N8AO, Bloom, DepthOfField, TiltShift2, HueSaturation} from '@react-three/postprocessing' export const Experience = () => { return ( <> - - - - - + + + + + + + {/* */} + {/* */} + + + {/* */} + + + {/* */} + + ); }; diff --git a/src/components/Ground.jsx b/src/components/Ground.jsx new file mode 100644 index 0000000..4389fd8 --- /dev/null +++ b/src/components/Ground.jsx @@ -0,0 +1,12 @@ +import { RigidBody } from "@react-three/rapier"; + +export const Ground = (props) => { + return ( + + + + + + + ); +}; diff --git a/src/components/Particles1.jsx b/src/components/Particles1.jsx new file mode 100644 index 0000000..8c82078 --- /dev/null +++ b/src/components/Particles1.jsx @@ -0,0 +1,2 @@ +export const Particles1 = () => { +} \ No newline at end of file diff --git a/src/components/PlayerController.jsx b/src/components/PlayerController.jsx new file mode 100644 index 0000000..a679fdf --- /dev/null +++ b/src/components/PlayerController.jsx @@ -0,0 +1,329 @@ +import { Controls } from "../App"; +import { RigidBody, useRapier } from "@react-three/rapier"; +import { + useKeyboardControls, + PerspectiveCamera, + ContactShadows, +} from "@react-three/drei"; +import { useFrame, useThree } from "@react-three/fiber"; +import { useRef, useState, useEffect, useCallback } from "react"; +import * as THREE from "three"; +import { Model } from "./models/Racing_kart"; +import { FrontRightWheel } from "./models/Front_Right_Wheel"; +import { FrontLeftWheel } from "./models/Front_Left_Wheel"; +import { RearWheels } from "./models/Rear_wheels"; +import gsap from "gsap"; +import { Mario } from "./models/Mario_kart"; + +export const PlayerController = () => { + const upPressed = useKeyboardControls((state) => state[Controls.up]); + const downPressed = useKeyboardControls((state) => state[Controls.down]); + const leftPressed = useKeyboardControls((state) => state[Controls.left]); + const rightPressed = useKeyboardControls((state) => state[Controls.right]); + const jumpPressed = useKeyboardControls((state) => state[Controls.jump]); + const [isOnGround, setIsOnGround] = useState(false); + const body = useRef(); + const kart = useRef(); + const cam = useRef(); + const initialSpeed = 0; + const maxSpeed = 30; + const boostSpeed = 50; + const acceleration = 0.1; + const decceleration = 0.2; + const damping = 0.001; + const MaxSteeringSpeed = 0.01; + const [currentSteeringSpeed, setCurrentSteeringSpeed] = useState(0); + const [currentSpeed, setCurrentSpeed] = useState(initialSpeed); + const camMaxOffset = 0.5; + let steeringAngle = 0; + const isOnFloor = useRef(false); + const jumpForce = useRef(0); + const jumpIsHeld = useRef(false); + const driftDirection = useRef(0); + const driftLeft = useRef(false); + const driftRight = useRef(false); + const driftForce = useRef(0); + const mario = useRef(); + const accumulatedDriftPower = useRef(0); + const blueTurboThreshold = 10; + const orangeTurboThreshold = 30; + const purpleTurboThreshold = 60; + const [turboColor, setTurboColor] = useState(0xffffff); + const boostDuration = useRef(0); + const isBoosting = useRef(false); + let targetXPosition = 0; + let targetZPosition = 8; + const [steeringAngleWheels, setSteeringAngleWheels] = useState(0); + + const [scale, setScale] = useState(0); + + useFrame(({ pointer, clock }) => { + const time = clock.getElapsedTime(); + if (!body.current && !mario.current) return; + + // HANDLING AND STEERING + const kartRotation = + kart.current.rotation.y - driftDirection.current * driftForce.current; + const forwardDirection = new THREE.Vector3( + -Math.sin(kartRotation), + 0, + -Math.cos(kartRotation) + ); + + if (leftPressed && currentSpeed > 0) { + steeringAngle = currentSteeringSpeed; + targetXPosition = -camMaxOffset; + } else if (rightPressed && currentSpeed > 0) { + steeringAngle = -currentSteeringSpeed; + targetXPosition = camMaxOffset; + } else { + steeringAngle = 0; + targetXPosition = 0; + 1; + } + + // mouse steering + steeringAngle = currentSteeringSpeed * -pointer.x; + targetXPosition = -camMaxOffset * -pointer.x; + + // ACCELERATING + + if (upPressed && currentSpeed < maxSpeed) { + // Accelerate the kart within the maximum speed limit + setCurrentSpeed(Math.min(currentSpeed + acceleration, maxSpeed)); + } else if (upPressed && currentSpeed > maxSpeed && boostDuration.current > 0){ + setCurrentSpeed(Math.max(currentSpeed - decceleration, maxSpeed)); + } + + if (upPressed) { + if (currentSteeringSpeed < MaxSteeringSpeed) { + setCurrentSteeringSpeed( + Math.min(currentSteeringSpeed + 0.0001, MaxSteeringSpeed) + ); + } + } + // REVERSING + if (downPressed && currentSpeed < -maxSpeed) { + setCurrentSpeed(Math.max(currentSpeed - acceleration, -maxSpeed)); + } + // DECELERATING + else if (!upPressed && !downPressed) { + if (currentSteeringSpeed > 0) { + setCurrentSteeringSpeed(Math.max(currentSteeringSpeed - 0.00005, 0)); + } else if (currentSteeringSpeed < 0) { + setCurrentSteeringSpeed(Math.min(currentSteeringSpeed + 0.00005, 0)); + } + setCurrentSpeed(Math.max(currentSpeed - decceleration, 0)); + } + + + // Update the kart's rotation based on the steering angle + kart.current.rotation.y += steeringAngle; + + // Apply damping to simulate slowdown when no keys are pressed + body.current.applyImpulse( + { + x: -body.current.linvel().x * (1 - damping), + y: 0, + z: -body.current.linvel().z * (1 - damping), + }, + true + ); + const bodyPosition = body.current.translation(); + kart.current.position.set( + bodyPosition.x, + bodyPosition.y - 1, + bodyPosition.z + ); + + // JUMPING + if (jumpPressed && isOnFloor.current && !jumpIsHeld.current) { + jumpForce.current += 11; + isOnFloor.current = false; + jumpIsHeld.current = true; + } + + if (!isOnFloor.current && jumpForce.current > 0) { + jumpForce.current -= 1; + } + if (!jumpPressed) { + jumpIsHeld.current = false; + driftDirection.current = 0; + driftForce.current = 0; + driftLeft.current = false; + driftRight.current = false; + } + // DRIFTING + if ( + jumpIsHeld.current && + currentSteeringSpeed > 0 && + pointer.x < -0.24 && + !driftRight.current + ) { + driftLeft.current = true; + } + if ( + jumpIsHeld.current && + currentSteeringSpeed > 0 && + pointer.x > 0.24 && + !driftLeft.current + ) { + driftRight.current = true; + } + + if (!jumpIsHeld.current && !driftLeft.current && !driftRight.current) { + mario.current.rotation.y = THREE.MathUtils.lerp( + mario.current.rotation.y, + 0, + 0.001 + ); + setTurboColor(0xffffff); + accumulatedDriftPower.current = 0; + + } + + if (driftLeft.current) { + driftDirection.current = 1; + driftForce.current = 0.4; + mario.current.rotation.y = THREE.MathUtils.lerp( + mario.current.rotation.y, + (steeringAngle * 50 + 0.5), + 0.1 + ); + accumulatedDriftPower.current += 0.1 * (steeringAngle + 1); + } + if (driftRight.current) { + driftDirection.current = -1; + driftForce.current = 0.4; + mario.current.rotation.y = THREE.MathUtils.lerp( + mario.current.rotation.y, + -(-steeringAngle * 50 + 0.5), + 0.1 + ); + accumulatedDriftPower.current += 0.1 * (-steeringAngle + 1); + } + if (!driftLeft.current && !driftRight.current) { + mario.current.rotation.y = THREE.MathUtils.lerp( + mario.current.rotation.y, + steeringAngle * 30, + 0.1 + ); + setScale(0); + } + if (accumulatedDriftPower.current > blueTurboThreshold) { + setTurboColor(0x00ffff); + boostDuration.current = 50; + } + if (accumulatedDriftPower.current > orangeTurboThreshold) { + setTurboColor(0xffcf00); + boostDuration.current = 100; + } + if (accumulatedDriftPower.current > purpleTurboThreshold) { + setTurboColor(0xff00ff); + boostDuration.current = 250; + } + + if(driftLeft.current || driftRight.current){ + const oscillation = Math.sin(time * 1000) * 0.1; + + const vibration = oscillation + 0.9; + setScale(vibration); + } + // RELEASING DRIFT + + if (boostDuration.current > 1 && !jumpIsHeld.current) { + setCurrentSpeed(boostSpeed); + boostDuration.current -= 1; + targetZPosition = 10; + } else if (boostDuration.current <= 1) { + targetZPosition = 8; + } + + + // CAMERA WORK + + cam.current.updateMatrixWorld(); + + cam.current.position.x = THREE.MathUtils.lerp( + cam.current.position.x, + targetXPosition, + 0.01 + ); + + cam.current.position.z = THREE.MathUtils.lerp( + cam.current.position.z, + targetZPosition, + 0.01 + ); + cam.current.updateMatrixWorld(); + + body.current.applyImpulse( + { + x: forwardDirection.x * currentSpeed, + y: 0 + jumpForce.current, + z: forwardDirection.z * currentSpeed, + }, + true + ); + + // Update the kart's rotation based on the steering angle + setSteeringAngleWheels(steeringAngle * 25); + console.log(scale) + }); + + return ( + + { + isOnFloor.current = true; + }} + > + + + + + + + + + + + + + + + + + + + + + + {/* */} + + + + ); +}; diff --git a/src/components/models/Front_Left_Wheel.jsx b/src/components/models/Front_Left_Wheel.jsx new file mode 100644 index 0000000..0edb0a2 --- /dev/null +++ b/src/components/models/Front_Left_Wheel.jsx @@ -0,0 +1,73 @@ +import React, { useEffect, useRef } from "react"; +import { useGLTF } from "@react-three/drei"; +import gsap from "gsap"; + +export function FrontLeftWheel({ + currentSpeed, + left, + right, + ...props +}) { + const { nodes, materials } = useGLTF("./models/front_wheel.glb"); + const wheel = useRef(); + + + useEffect(() => { + if (!wheel.current) return; + if(left){ + gsap.to(wheel.current.rotation, { + duration: 0.5, + y: Math.PI + Math.PI / 8, + ease: "power2.inOut", + }); + gsap.to(wheel.current.position, { + duration: 0.5, + z: 0.075, + ease: "power2.inOut", + }); + } else if(right){ + gsap.to(wheel.current.rotation, { + duration: 0.5, + y: Math.PI - Math.PI / 8, + ease: "power2.inOut", + }); + gsap.to(wheel.current.position, { + duration: 0.5, + z: -0.075, + ease: "power2.inOut", + }); + } else if(!left && !right){ + gsap.to(wheel.current.rotation, { + duration: 0.2, + y: Math.PI, + ease: "power2.inOut", + }); + gsap.to(wheel.current.position, { + duration: 0.2, + z: 0, + ease: "power2.inOut", + }); + } + + }, [left, right]); + return ( + + + + + + + + ); +} + +useGLTF.preload("./models/front_wheel.glb"); \ No newline at end of file diff --git a/src/components/models/Front_Right_Wheel.jsx b/src/components/models/Front_Right_Wheel.jsx new file mode 100644 index 0000000..4cceb2c --- /dev/null +++ b/src/components/models/Front_Right_Wheel.jsx @@ -0,0 +1,74 @@ +import React, { useEffect, useRef } from "react"; +import { useGLTF } from "@react-three/drei"; +import gsap from "gsap"; + +export function FrontRightWheel({ + currentSpeed, + left, + right, + ...props +}) { + const { nodes, materials } = useGLTF("./models/front_wheel.glb"); + const wheel = useRef(); + + + useEffect(() => { + if (!wheel.current) return; + if(left){ + gsap.to(wheel.current.rotation, { + duration: 0.5, + y: Math.PI / 8, + ease: "power2.inOut", + }); + gsap.to(wheel.current.position, { + duration: 0.5, + z: -0.075, + ease: "power2.inOut", + }); + + } else if(right){ + gsap.to(wheel.current.rotation, { + duration: 0.5, + y: - Math.PI / 8, + ease: "power2.inOut", + }); + gsap.to(wheel.current.position, { + duration: 0.5, + z: 0.075, + ease: "power2.inOut", + }); + } else if(!left && !right) { + gsap.to(wheel.current.rotation, { + duration: 0.2, + y: 0, + ease: "power2.inOut", + }); + gsap.to(wheel.current.position, { + duration: 0.2, + z: 0, + ease: "power2.inOut", + }); + } + + }, [left, right]); + return ( + + + + + + + + ); +} + +useGLTF.preload("./models/front_wheel.glb"); \ No newline at end of file diff --git a/src/components/models/Front_wheel.jsx b/src/components/models/Front_wheel.jsx new file mode 100644 index 0000000..5dc9282 --- /dev/null +++ b/src/components/models/Front_wheel.jsx @@ -0,0 +1,44 @@ +/* +Auto-generated by: https://github.com/pmndrs/gltfjsx +Command: npx gltfjsx@6.2.16 .\front_wheel.glb +*/ + +import React, { useEffect, useRef } from "react"; +import { useGLTF } from "@react-three/drei"; +import gsap from "gsap"; + +export function FrontWheel({ + isLeftWheel, + currentSpeed, + left, + right, + ...props +}) { + const { nodes, materials } = useGLTF("./models/front_wheel.glb"); + const wheel = useRef(); + const rotation = isLeftWheel ? [0, Math.PI, 0] : [0, 0, 0]; + + useEffect(() => { + + }, [currentSpeed, left, right]); + return ( + + + + + + + + ); +} + +useGLTF.preload("./models/front_wheel.glb"); diff --git a/src/components/models/Mario_kart.jsx b/src/components/models/Mario_kart.jsx new file mode 100644 index 0000000..b3667fa --- /dev/null +++ b/src/components/models/Mario_kart.jsx @@ -0,0 +1,39 @@ +/* +Auto-generated by: https://github.com/pmndrs/gltfjsx +Command: npx gltfjsx@6.2.16 .\mariokarttest.glb --shadows +*/ + +import React, { useRef } from 'react' +import { useGLTF } from '@react-three/drei' +import { useFrame } from '@react-three/fiber' + +export function Mario({currentSpeed, steeringAngleWheels, ...props}) { + const { nodes, materials } = useGLTF('./models/mariokarttest.glb') + + const frontLeftWheel = useRef() + const frontRightWheel = useRef() + const rearWheels = useRef() + const frontWheels = useRef() + + useFrame(() => { + const rotation = currentSpeed / 100 + frontLeftWheel.current.rotation.x += rotation + frontRightWheel.current.rotation.x += rotation + rearWheels.current.rotation.x += rotation + frontWheels.current.rotation.y = steeringAngleWheels + + }) + return ( + + + + + + + + + + ) +} + +useGLTF.preload('./models/mariokarttest.glb') diff --git a/src/components/models/Racing_kart.jsx b/src/components/models/Racing_kart.jsx new file mode 100644 index 0000000..42566fa --- /dev/null +++ b/src/components/models/Racing_kart.jsx @@ -0,0 +1,111 @@ +/* +Auto-generated by: https://github.com/pmndrs/gltfjsx +Command: npx gltfjsx@6.2.16 .\racing_kart.glb --transform +Files: .\racing_kart.glb [1.83MB] > C:\Users\mouli\dev\r3f-vite-starter\public\models\racing_kart-transformed.glb [150.05KB] (92%) +Author: scailman (https://sketchfab.com/scailman) +License: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/) +Source: https://sketchfab.com/3d-models/racing-kart-f48f8e66bba6492eadc000d2585b6a32 +Title: Racing Kart +*/ + +import React, { useEffect, useRef } from "react"; +import { useGLTF } from "@react-three/drei"; +import gsap from "gsap"; + +export function Model({ steeringAngle, speed, left, right, ...props }) { + const { nodes, materials } = useGLTF("./models/racing_kart-transformed.glb"); + + + return ( + + + + + + + + + + + + {/* + */} + + + + + + ); +} + +useGLTF.preload("./models/racing_kart-transformed.glb"); diff --git a/src/components/models/Rear_wheels.jsx b/src/components/models/Rear_wheels.jsx new file mode 100644 index 0000000..5fb6d82 --- /dev/null +++ b/src/components/models/Rear_wheels.jsx @@ -0,0 +1,33 @@ +/* +Auto-generated by: https://github.com/pmndrs/gltfjsx +Command: npx gltfjsx@6.2.16 .\rear_wheels.glb +*/ + +import React, { useRef } from 'react' +import { useGLTF } from '@react-three/drei' + +export function RearWheels(props) { + const { nodes, materials } = useGLTF('./models/rear_wheels.glb') + return ( + + + + + + + + + + + + + + + + + + + ) +} + +useGLTF.preload('./models/rear_wheels.glb') diff --git a/src/components/models/Spafrancorchamps-REALISTIC.jsx b/src/components/models/Spafrancorchamps-REALISTIC.jsx new file mode 100644 index 0000000..e254e96 --- /dev/null +++ b/src/components/models/Spafrancorchamps-REALISTIC.jsx @@ -0,0 +1,21 @@ +/* +Auto-generated by: https://github.com/pmndrs/gltfjsx +Command: npx gltfjsx@6.2.16 .\spafrancorchamps-REALISTIC.glb +*/ + +import React, { useRef } from 'react' +import { useGLTF } from '@react-three/drei' +import { RigidBody } from '@react-three/rapier' + +export function Track(props) { + const { nodes, materials } = useGLTF('./models/spafrancorchamps-REALISTIC.glb') + return ( + + + + + + ) +} + +useGLTF.preload('./models/spafrancorchamps-REALISTIC.glb') diff --git a/src/components/models/Tour_paris_promenade.jsx b/src/components/models/Tour_paris_promenade.jsx new file mode 100644 index 0000000..172a542 --- /dev/null +++ b/src/components/models/Tour_paris_promenade.jsx @@ -0,0 +1,38 @@ +/* +Auto-generated by: https://github.com/pmndrs/gltfjsx +Command: npx gltfjsx@6.2.16 .\tour_paris_promenade.glb --transform --shadows +Files: .\tour_paris_promenade.glb [51.35MB] > C:\Users\mouli\dev\r3f-vite-starter\public\models\tour_paris_promenade-transformed.glb [2.24MB] (96%) +Author: amogusstrikesback2 (https://sketchfab.com/amogusstrikesback2) +License: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/) +Source: https://sketchfab.com/3d-models/tour-paris-promenade-9d9b5dcfd6504ea0b582d36687e10fab +Title: tour paris promenade +*/ + +import React, { useRef } from 'react' +import { useGLTF } from '@react-three/drei' +import { RigidBody } from '@react-three/rapier' + +export function Paris(props) { + const { nodes, materials } = useGLTF('./models/tour_paris_promenade-transformed.glb') + materials.M_Cmn_ShadowCollision.opacity = 0 + materials.M_Cmn_ShadowCollision.transparent = true + return ( + + + + + + + + + + + + + + + + ) +} + +useGLTF.preload('./models/tour_paris_promenade-transformed.glb') diff --git a/vite.config.js b/vite.config.js index 861b04b..2ba14c3 100644 --- a/vite.config.js +++ b/vite.config.js @@ -4,4 +4,7 @@ import react from '@vitejs/plugin-react-swc' // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], + optimizeDeps: { + exclude: ['js-big-decimal'] + } })