gaesup-world 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/README.md +51 -0
  2. package/index.html +13 -0
  3. package/package.json +82 -0
  4. package/src/gaesup/animation/actions.ts +123 -0
  5. package/src/gaesup/camera/cameraCollisionDetecter.tsx +53 -0
  6. package/src/gaesup/camera/control/map.ts +10 -0
  7. package/src/gaesup/camera/control/normal copy.ts +19 -0
  8. package/src/gaesup/camera/control/normal.ts +15 -0
  9. package/src/gaesup/camera/control/orbit.ts +31 -0
  10. package/src/gaesup/camera/index.tsx +102 -0
  11. package/src/gaesup/camera/type.ts +17 -0
  12. package/src/gaesup/component/Airplane.tsx +46 -0
  13. package/src/gaesup/component/Character.tsx +48 -0
  14. package/src/gaesup/component/Vehicle.tsx +40 -0
  15. package/src/gaesup/component/gltf/AirplaneGltf.tsx +31 -0
  16. package/src/gaesup/component/gltf/CharacterGltf.tsx +81 -0
  17. package/src/gaesup/component/gltf/VehicleGltf.tsx +31 -0
  18. package/src/gaesup/component/gltf/WheelJoint.tsx +39 -0
  19. package/src/gaesup/component/gltf/type.ts +6 -0
  20. package/src/gaesup/component/ref/airplane.tsx +83 -0
  21. package/src/gaesup/component/ref/character.tsx +132 -0
  22. package/src/gaesup/component/ref/vehicle.tsx +145 -0
  23. package/src/gaesup/controller/index.tsx +103 -0
  24. package/src/gaesup/controller/type.ts +139 -0
  25. package/src/gaesup/gaesupProps/index.tsx +66 -0
  26. package/src/gaesup/initial/callback/index.ts +73 -0
  27. package/src/gaesup/initial/callback/type.ts +45 -0
  28. package/src/gaesup/initial/controller/index.ts +143 -0
  29. package/src/gaesup/initial/controller/initDebug.ts +102 -0
  30. package/src/gaesup/initial/gaesupWorld/collider/airplane.ts +26 -0
  31. package/src/gaesup/initial/gaesupWorld/collider/character.ts +32 -0
  32. package/src/gaesup/initial/gaesupWorld/collider/gltf.ts +91 -0
  33. package/src/gaesup/initial/gaesupWorld/collider/index.ts +26 -0
  34. package/src/gaesup/initial/gaesupWorld/collider/vehicle.ts +43 -0
  35. package/src/gaesup/initial/gaesupWorld/index.ts +82 -0
  36. package/src/gaesup/initial/gaesupWorld/type.ts +37 -0
  37. package/src/gaesup/physics/airplane/currentSetting.ts +20 -0
  38. package/src/gaesup/physics/airplane/damping.ts +8 -0
  39. package/src/gaesup/physics/airplane/direction.ts +70 -0
  40. package/src/gaesup/physics/airplane/gravity.ts +11 -0
  41. package/src/gaesup/physics/airplane/impulse.ts +22 -0
  42. package/src/gaesup/physics/airplane/index.tsx +16 -0
  43. package/src/gaesup/physics/airplane/turn.ts +12 -0
  44. package/src/gaesup/physics/airplane copy/currentSetting.ts +20 -0
  45. package/src/gaesup/physics/airplane copy/direction.ts +52 -0
  46. package/src/gaesup/physics/airplane copy/gravity.ts +6 -0
  47. package/src/gaesup/physics/airplane copy/impulse.ts +28 -0
  48. package/src/gaesup/physics/airplane copy/index.tsx +14 -0
  49. package/src/gaesup/physics/airplane copy/turn.ts +9 -0
  50. package/src/gaesup/physics/character/accelaration.ts +14 -0
  51. package/src/gaesup/physics/character/currentSetting.ts +20 -0
  52. package/src/gaesup/physics/character/damping.ts +6 -0
  53. package/src/gaesup/physics/character/direction.ts +104 -0
  54. package/src/gaesup/physics/character/impulse.ts +24 -0
  55. package/src/gaesup/physics/character/index.tsx +20 -0
  56. package/src/gaesup/physics/character/jump.ts +21 -0
  57. package/src/gaesup/physics/character/stabilizing.ts +6 -0
  58. package/src/gaesup/physics/character/turn.ts +17 -0
  59. package/src/gaesup/physics/check/ground.ts +19 -0
  60. package/src/gaesup/physics/check/index.ts +12 -0
  61. package/src/gaesup/physics/check/moving.ts +21 -0
  62. package/src/gaesup/physics/check/rotate.ts +13 -0
  63. package/src/gaesup/physics/check/slope.ts +50 -0
  64. package/src/gaesup/physics/index.ts +50 -0
  65. package/src/gaesup/physics/type.ts +35 -0
  66. package/src/gaesup/physics/vehicle/currentSetting.ts +20 -0
  67. package/src/gaesup/physics/vehicle/damping.ts +8 -0
  68. package/src/gaesup/physics/vehicle/direction.ts +27 -0
  69. package/src/gaesup/physics/vehicle/impulse.ts +22 -0
  70. package/src/gaesup/physics/vehicle/index.tsx +14 -0
  71. package/src/gaesup/physics/vehicle/turn.ts +11 -0
  72. package/src/gaesup/stores/active/index.ts +19 -0
  73. package/src/gaesup/stores/active/type.ts +16 -0
  74. package/src/gaesup/stores/airplane/index.ts +6 -0
  75. package/src/gaesup/stores/airplane/type.ts +4 -0
  76. package/src/gaesup/stores/animation/index.ts +18 -0
  77. package/src/gaesup/stores/animation/type.ts +9 -0
  78. package/src/gaesup/stores/collider/index.ts +55 -0
  79. package/src/gaesup/stores/context/controller/index.ts +36 -0
  80. package/src/gaesup/stores/context/controller/reducer.ts +18 -0
  81. package/src/gaesup/stores/context/controller/type.ts +38 -0
  82. package/src/gaesup/stores/context/gaesupworld/index.ts +11 -0
  83. package/src/gaesup/stores/context/gaesupworld/reducer.ts +21 -0
  84. package/src/gaesup/stores/context/gaesupworld/type.ts +66 -0
  85. package/src/gaesup/stores/control/index.ts +33 -0
  86. package/src/gaesup/stores/control/type.ts +11 -0
  87. package/src/gaesup/stores/joystick/index.ts +72 -0
  88. package/src/gaesup/stores/joystick/type.ts +23 -0
  89. package/src/gaesup/stores/minimap/index.ts +5 -0
  90. package/src/gaesup/stores/minimap/type.ts +22 -0
  91. package/src/gaesup/stores/point/type.ts +6 -0
  92. package/src/gaesup/stores/states/index.tsx +10 -0
  93. package/src/gaesup/stores/states/type.ts +10 -0
  94. package/src/gaesup/stores/url/index.ts +6 -0
  95. package/src/gaesup/stores/url/type.ts +6 -0
  96. package/src/gaesup/styles.css.ts +26 -0
  97. package/src/gaesup/tools/gameboy/GameBoyButton.tsx +38 -0
  98. package/src/gaesup/tools/gameboy/index.tsx +36 -0
  99. package/src/gaesup/tools/gameboy/style.css.ts +78 -0
  100. package/src/gaesup/tools/gamepad/GamePadButton.tsx +31 -0
  101. package/src/gaesup/tools/gamepad/index.tsx +55 -0
  102. package/src/gaesup/tools/gamepad/style.css.ts +16 -0
  103. package/src/gaesup/tools/index.tsx +61 -0
  104. package/src/gaesup/tools/joystick/index.tsx +145 -0
  105. package/src/gaesup/tools/joystick/style.css.ts +40 -0
  106. package/src/gaesup/tools/jumpPoint/index.tsx +27 -0
  107. package/src/gaesup/tools/jumpPoint/style.css.ts +33 -0
  108. package/src/gaesup/tools/keyBoardToolTip/constant.ts +144 -0
  109. package/src/gaesup/tools/keyBoardToolTip/index.tsx +85 -0
  110. package/src/gaesup/tools/keyBoardToolTip/style.css.ts +49 -0
  111. package/src/gaesup/tools/minimap/index.tsx +47 -0
  112. package/src/gaesup/tools/minimap/style.css.ts +144 -0
  113. package/src/gaesup/tools/style.css.ts +34 -0
  114. package/src/gaesup/utils/constant.ts +1 -0
  115. package/src/gaesup/utils/ray.ts +23 -0
  116. package/src/gaesup/utils/ref.ts +17 -0
  117. package/src/gaesup/utils/vector.ts +40 -0
  118. package/src/gaesup/world/index.tsx +17 -0
  119. package/src/gaesup/world/type.ts +10 -0
  120. package/src/styles/constants/boxshadow.css.ts +499 -0
  121. package/src/styles/constants/constant.css.ts +81 -0
  122. package/src/styles/constants/direction.css.ts +168 -0
  123. package/src/styles/constants/flex.css.ts +68 -0
  124. package/src/styles/constants/gradient.css.ts +10 -0
  125. package/src/styles/constants/grid.css.ts +37 -0
  126. package/src/styles/constants/palette.css.ts +324 -0
  127. package/src/styles/constants/translate.css.ts +129 -0
  128. package/src/styles/global.css.ts +91 -0
  129. package/src/styles/recipe/base.css.ts +31 -0
  130. package/src/styles/recipe/button.css.ts +109 -0
  131. package/src/styles/recipe/index.css.ts +134 -0
  132. package/src/styles/recipe/input.css.ts +33 -0
  133. package/src/styles/sprinkles/color.css.ts +62 -0
  134. package/src/styles/sprinkles/direction.css.ts +26 -0
  135. package/src/styles/sprinkles/display.css.ts +25 -0
  136. package/src/styles/sprinkles/fontSize.css.ts +25 -0
  137. package/src/styles/sprinkles/grid.css.ts +25 -0
  138. package/src/styles/sprinkles/index.css.ts +22 -0
  139. package/src/styles/sprinkles/margin.css.ts +30 -0
  140. package/src/styles/sprinkles/padding.css.ts +30 -0
  141. package/src/styles/sprinkles/position.css.ts +14 -0
  142. package/src/styles/sprinkles/size.css.ts +23 -0
  143. package/src/styles/theme.css.ts +98 -0
  144. package/tsconfig.json +27 -0
  145. package/tsconfig.node.json +10 -0
  146. package/vite.config.ts +9 -0
package/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # Gaesup World
2
+
3
+ Web 3D Character Controller and World Platform Library
4
+
5
+ [![npm (tag)](https://img.shields.io/npm/v/leva?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/leva)
6
+
7
+ @react-three/fiber
8
+ @react-three/drei
9
+ three @types/three
10
+ @react-three/rapier
11
+
12
+ Gaesup World는 @react/three-fiber, @react/three-drei, rapier 를 사용하여 웹 3D 환경에서 캐릭터, 비행기, 자동자 등의 컨트롤 도구를 제공하는 라이브러리입니다.
13
+
14
+ 이 컨트롤러는 캐릭터의 움직임, 애니메이션, 상호작용을 쉽게 관리할 수 있도록 설계되었습니다. 가상의 세계에서 캐릭터를 움직이거나 탈것을 쉽게 활용할 수 있고, 미니맵이나 조이스틱 등의 유틸 등도 설계되어 있습니다
15
+
16
+ ## 특징
17
+
18
+ - React Three Fiber를 기반으로 하는 3D 캐릭터 컨트롤
19
+ - 간단한 API를 통한 캐릭터 움직임 및 애니메이션 제어
20
+ - 확장 가능한 구조로 다양한 커스터마이징 지원
21
+ - 가벼운 라이브러리로 빠른 로딩 및 성능 최적화
22
+
23
+ ## 설치 방법
24
+
25
+ ```bash
26
+ npm install @react-three/fiber @react-three/drei three @types/three @react-three/rapier gaesup-world
27
+ ```
28
+
29
+ 또는
30
+
31
+ ```bash
32
+ yarn add @react-three/fiber @react-three/drei three @types/three @react-three/rapier gaesup-world
33
+ ```
34
+
35
+ ## 문서
36
+
37
+ 더 자세한 사용 방법 및 API 문서는 [여기](#)를 참조하세요.
38
+
39
+ ## 기여 방법
40
+
41
+ 이 프로젝트에 기여하고 싶으시다면, 다음 단계를 따라주세요:
42
+
43
+ 1. 프로젝트를 Fork합니다.
44
+ 2. 새로운 Feature 브랜치를 생성합니다 (`git checkout -b feature/AmazingFeature`).
45
+ 3. 변경사항을 Commit합니다 (`git commit -m 'Add some AmazingFeature'`).
46
+ 4. 브랜치에 Push합니다 (`git push origin feature/AmazingFeature`).
47
+ 5. Pull Request를 생성합니다.
48
+
49
+ ## 라이센스
50
+
51
+ 이 프로젝트는 [MIT 라이센스](LICENSE) 하에 배포됩니다.
package/index.html ADDED
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/gaesupworld.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>gaesup world | example with react</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/examples/select/main.tsx"></script>
12
+ </body>
13
+ </html>
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "gaesup-world",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "homepage": "https://jigglypop.github.io/gaesup-world/",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "prepare": "rm -rf dist && tsc",
9
+ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
10
+ "preview": "vite preview",
11
+ "predeploy": "npm run build",
12
+ "deploy": "gh-pages -d dist"
13
+ },
14
+ "dependencies": {
15
+ "@dimforge/rapier3d": "^0.11.2",
16
+ "@emotion/react": "^11.11.1",
17
+ "@mdx-js/loader": "^3.0.0",
18
+ "@mdx-js/react": "^3.0.0",
19
+ "@next/mdx": "^14.0.1",
20
+ "@react-icons/all-files": "^4.1.0",
21
+ "@react-three/drei": "9.88.11",
22
+ "@react-three/fiber": "8.15.9",
23
+ "@react-three/postprocessing": "^2.15.10",
24
+ "@react-three/rapier": "^1.1.2",
25
+ "@types/three": "^0.158.1",
26
+ "@types/uuid": "^9.0.6",
27
+ "@uiw/react-md-editor": "3.25.2",
28
+ "@vanilla-extract/babel-plugin": "^1.2.0",
29
+ "@vanilla-extract/css": "^1.13.0",
30
+ "@vanilla-extract/css-utils": "^0.1.3",
31
+ "@vanilla-extract/dynamic": "^2.0.3",
32
+ "@vanilla-extract/next-plugin": "^2.3.1",
33
+ "@vanilla-extract/recipes": "^0.5.0",
34
+ "@vanilla-extract/sprinkles": "^1.6.1",
35
+ "@zeit/next-bundle-analyzer": "0.1.2",
36
+ "css-loader": "^6.8.1",
37
+ "gh-pages": "^6.1.0",
38
+ "lamina": "^1.1.23",
39
+ "leva": "0.9.35",
40
+ "lodash": "4.17.21",
41
+ "next-compose": "0.0.2",
42
+ "next-remove-imports": "1.0.12",
43
+ "node-fetch": "3.3.2",
44
+ "prettier": "^3.1.0",
45
+ "r3f-perf": "7.1.2",
46
+ "react": "^18.2.0",
47
+ "react-device-detect": "^2.2.3",
48
+ "react-dom": "^18.2.0",
49
+ "react-use-refs": "^1.0.1",
50
+ "three": "^0.158.0"
51
+ },
52
+ "devDependencies": {
53
+ "@types/react": "^18.2.37",
54
+ "@types/react-dom": "^18.2.15",
55
+ "@typescript-eslint/eslint-plugin": "^6.10.0",
56
+ "@typescript-eslint/parser": "^6.10.0",
57
+ "@vanilla-extract/vite-plugin": "^3.9.2",
58
+ "@vitejs/plugin-react-swc": "^3.5.0",
59
+ "eslint": "^8.53.0",
60
+ "eslint-plugin-react-hooks": "^4.6.0",
61
+ "eslint-plugin-react-refresh": "^0.4.4",
62
+ "path": "^0.12.7",
63
+ "typescript": "^5.2.2",
64
+ "vite": "^5.0.0"
65
+ },
66
+ "description": "Web 3D Character Controller and World Platform Library",
67
+ "main": "index.js",
68
+ "repository": {
69
+ "type": "git",
70
+ "url": "git+https://github.com/jigglypop/gaesup-world.git"
71
+ },
72
+ "keywords": [
73
+ "three.js",
74
+ "@react-three/fiber",
75
+ "@react-three/drei"
76
+ ],
77
+ "author": "jigglypop",
78
+ "license": "MIT",
79
+ "bugs": {
80
+ "url": "https://github.com/jigglypop/gaesup-world/issues"
81
+ }
82
+ }
@@ -0,0 +1,123 @@
1
+ import { useAnimations, useKeyboardControls } from "@react-three/drei";
2
+ import { useFrame } from "@react-three/fiber";
3
+ import { RefObject, useContext, useEffect } from "react";
4
+ import { animationTagType, groundRayType } from "../controller/type";
5
+ import {
6
+ GaesupWorldContext,
7
+ GaesupWorldDispatchContext,
8
+ } from "../stores/context/gaesupworld";
9
+
10
+ export type playActionsType = {
11
+ outerGroupRef: RefObject<THREE.Group>;
12
+ groundRay: groundRayType;
13
+ isRider?: boolean;
14
+ };
15
+
16
+ export default function playActions({
17
+ outerGroupRef,
18
+ groundRay,
19
+ isRider,
20
+ }: playActionsType) {
21
+ const { characterGltf, animations: characterAnimations } =
22
+ useContext(GaesupWorldContext);
23
+ const dispatch = useContext(GaesupWorldDispatchContext);
24
+ const { animations } = characterGltf;
25
+ const control = useKeyboardControls()[1]();
26
+ const { actions } = useAnimations(animations, outerGroupRef);
27
+
28
+ useEffect(() => {
29
+ characterAnimations.keyControl = control;
30
+ dispatch({
31
+ type: "update",
32
+ payload: {
33
+ animations: {
34
+ ...characterAnimations,
35
+ },
36
+ },
37
+ });
38
+ }, [control]);
39
+
40
+ const playAnimation = (tag: keyof animationTagType) => {
41
+ characterAnimations.current = tag;
42
+ dispatch({
43
+ type: "update",
44
+ payload: {
45
+ animations: {
46
+ ...characterAnimations,
47
+ },
48
+ },
49
+ });
50
+ };
51
+
52
+ const setAnimationName = (actions: {
53
+ [x: string]: THREE.AnimationAction | null;
54
+ }) => {
55
+ characterAnimations.animationNames = Object.assign(
56
+ characterAnimations.animationNames,
57
+ Object.keys(actions).reduce((acc, cur) => {
58
+ return {
59
+ ...acc,
60
+ [cur]: cur,
61
+ };
62
+ }, {})
63
+ );
64
+ dispatch({
65
+ type: "update",
66
+ payload: {
67
+ animations: {
68
+ ...characterAnimations,
69
+ },
70
+ },
71
+ });
72
+ };
73
+
74
+ const resetAni = () => playAnimation("idle");
75
+ const playIdle = () => playAnimation("idle");
76
+ const playWalk = () => playAnimation("walk");
77
+ const playRun = () => playAnimation("run");
78
+ const playJump = () => playAnimation("jump");
79
+ const playFall = () => playAnimation("fall");
80
+ const playRide = () => playAnimation("ride");
81
+
82
+ useEffect(() => {
83
+ return () => {
84
+ resetAni();
85
+ };
86
+ }, []);
87
+
88
+ useEffect(() => {
89
+ // Play animation
90
+ const action = actions[characterAnimations.current]
91
+ ?.reset()
92
+ .fadeIn(0.2)
93
+ .play();
94
+ setAnimationName(actions);
95
+ return () => {
96
+ action?.fadeOut(0.2);
97
+ };
98
+ }, [characterAnimations.current]);
99
+
100
+ const { states, activeState } = useContext(GaesupWorldContext);
101
+ const { isNotMoving, isMoving, isJumping, isRunning, isAnimationOuter } =
102
+ states;
103
+ useFrame(() => {
104
+ if (isRider) {
105
+ playRide();
106
+ } else {
107
+ if (!isAnimationOuter) {
108
+ if (isJumping) {
109
+ playJump();
110
+ } else if (isNotMoving) {
111
+ playIdle();
112
+ } else if (isRunning) {
113
+ playRun();
114
+ } else if (isMoving) {
115
+ playWalk();
116
+ }
117
+ if (groundRay.hit === null && activeState.velocity.y < 0) {
118
+ playFall();
119
+ }
120
+ }
121
+ }
122
+ });
123
+ }
@@ -0,0 +1,53 @@
1
+ import { propType } from "../controller/type";
2
+
3
+ export default function cameraCollisionDetector(prop: propType) {
4
+ // const { cameraRay, constant, options } = prop;
5
+ // const { camera } = useThree();
6
+ const checkCollision = (delta: number) => {
7
+ // cameraRay.origin.copy(cameraRay.pivot.position);
8
+ // camera.getWorldPosition(cameraRay.position);
9
+ // cameraRay.dir.subVectors(cameraRay.position, cameraRay.pivot.position);
10
+ // cameraRay.intersects = cameraRay.rayCast!.intersectObjects(
11
+ // Object.values(cameraRay.intersectObjectMap)
12
+ // );
13
+ // if (
14
+ // cameraRay.intersects.length &&
15
+ // cameraRay.intersects[0].distance <= -constant.cameraInitDistance
16
+ // ) {
17
+ // if (options.cameraCollisionType === "transparent") {
18
+ // cameraRay.intersetesAndTransParented = [...cameraRay.intersects];
19
+ // cameraRay.intersetesAndTransParented.map((intersect) => {
20
+ // const mesh = intersect.object as THREE.Mesh;
21
+ // const material = mesh.material as THREE.MeshStandardMaterial;
22
+ // material.opacity = 0.2;
23
+ // material.transparent = true;
24
+ // });
25
+ // } else if (options.cameraCollisionType === "closeUp") {
26
+ // constant.cameraMinDistance =
27
+ // -cameraRay.intersects[0].distance * constant.cameraCollisionOff < -0.7
28
+ // ? -cameraRay.intersects[0].distance * constant.cameraCollisionOff
29
+ // : -0.7;
30
+ // }
31
+ // } else {
32
+ // if (options.cameraCollisionType === "transparent") {
33
+ // cameraRay.intersetesAndTransParented.map((intersect) => {
34
+ // const mesh = intersect.object as THREE.Mesh;
35
+ // const material = mesh.material as THREE.MeshStandardMaterial;
36
+ // material.opacity = 1;
37
+ // material.transparent = false;
38
+ // });
39
+ // cameraRay.intersetesAndTransParented = [];
40
+ // }
41
+ // constant.cameraMinDistance = constant.cameraInitDistance;
42
+ // }
43
+ // cameraRay.lerpingPoint.set(
44
+ // cameraRay.followCamera.position.x,
45
+ // constant.cameraMinDistance * Math.sin(-cameraRay.followCamera.rotation.x),
46
+ // constant.cameraMinDistance * Math.cos(-cameraRay.followCamera.rotation.x)
47
+ // );
48
+ //
49
+ // cameraRay.followCamera.position.lerp(cameraRay.lerpingPoint, delta * 4);
50
+ };
51
+
52
+ return { checkCollision };
53
+ }
@@ -0,0 +1,10 @@
1
+ import { cameraPropType } from "../../physics/type";
2
+
3
+ export default function mapControl(prop: cameraPropType) {
4
+ const {
5
+ state,
6
+ worldContext: { activeState },
7
+ } = prop;
8
+ const position = activeState.position.clone();
9
+ state.camera.position.set(-10, 10, -10).add(position);
10
+ }
@@ -0,0 +1,19 @@
1
+ import { cameraPropType } from "../../physics/type";
2
+
3
+ export default function normal(prop: cameraPropType) {
4
+ const {
5
+ state,
6
+ cameraRay,
7
+ constant,
8
+ checkCollision,
9
+ delta,
10
+ worldContext: { activeState },
11
+ } = prop;
12
+ cameraRay.pivot.position.lerp(
13
+ activeState.position,
14
+ 1 - Math.exp(-constant.cameraCamFollow * delta)
15
+ );
16
+ state.camera.position.set(0, 0, 0);
17
+ state.camera.lookAt(cameraRay.pivot.position);
18
+ checkCollision(delta);
19
+ }
@@ -0,0 +1,15 @@
1
+ import { cameraPropType } from "../../physics/type";
2
+ import { V3 } from "../../utils/vector";
3
+
4
+ export default function normal(prop: cameraPropType) {
5
+ const {
6
+ state,
7
+ controllerContext: { perspectiveCamera },
8
+ worldContext: { activeState },
9
+ } = prop;
10
+ const cameraPosition = activeState.position
11
+ .clone()
12
+ .add(V3(perspectiveCamera.XZDistance, perspectiveCamera.YDistance, 0));
13
+ state.camera.position.lerp(cameraPosition, 1);
14
+ state.camera.lookAt(activeState.position);
15
+ }
@@ -0,0 +1,31 @@
1
+ import { quat } from "@react-three/rapier";
2
+ import { cameraPropType } from "../../physics/type";
3
+ import { V3 } from "../../utils/vector";
4
+
5
+ export default function orbit(prop: cameraPropType) {
6
+ const {
7
+ state,
8
+ controllerContext: { perspectiveCamera },
9
+ worldContext: { activeState },
10
+ } = prop;
11
+ const cameraPosition = activeState.position.clone().add(
12
+ V3(Math.sin(activeState.euler.y), 0, Math.cos(activeState.euler.y))
13
+ .normalize()
14
+ .clone()
15
+ .multiplyScalar(perspectiveCamera.XZDistance)
16
+ .multiplyScalar(perspectiveCamera.isFront ? -1 : 1)
17
+ .add(V3(0, perspectiveCamera.YDistance, 0))
18
+ );
19
+
20
+ state.camera.position.lerp(cameraPosition, 0.2);
21
+ state.camera.quaternion.copy(
22
+ activeState.quat
23
+ .clone()
24
+ .multiply(
25
+ perspectiveCamera.isFront
26
+ ? quat().setFromAxisAngle(V3(0, 1, 0), Math.PI)
27
+ : quat()
28
+ )
29
+ );
30
+ state.camera.lookAt(activeState.position);
31
+ }
@@ -0,0 +1,102 @@
1
+ import {
2
+ MapControls,
3
+ OrbitControls,
4
+ OrthographicCamera,
5
+ PerspectiveCamera,
6
+ } from "@react-three/drei";
7
+ import { useFrame, useThree } from "@react-three/fiber";
8
+ import { useContext } from "react";
9
+ import * as THREE from "three";
10
+ import { propType, refsType } from "../controller/type";
11
+ import { cameraPropType } from "../physics/type";
12
+ import { GaesupControllerContext } from "../stores/context/controller";
13
+ import { GaesupWorldContext } from "../stores/context/gaesupworld";
14
+ import cameraCollisionDetector from "./cameraCollisionDetecter";
15
+ import mapControl from "./control/map";
16
+ import normal from "./control/normal copy";
17
+ import orbit from "./control/orbit";
18
+
19
+ export default function Camera({
20
+ refs,
21
+ prop,
22
+ control,
23
+ }: {
24
+ refs: refsType;
25
+ prop: propType;
26
+ control: {
27
+ [key: string]: boolean;
28
+ };
29
+ }) {
30
+ const worldContext = useContext(GaesupWorldContext);
31
+ const controllerContext = useContext(GaesupControllerContext);
32
+ const { cameraMode, perspectiveCamera, orthographicCamera } =
33
+ controllerContext;
34
+ const { rigidBodyRef, outerGroupRef } = refs;
35
+ const { cameraRay } = prop;
36
+ const { checkCollision } = cameraCollisionDetector(prop);
37
+ const { scene, camera } = useThree();
38
+ const { activeState } = worldContext;
39
+
40
+ const intersectObjectMap: { [uuid: string]: THREE.Object3D } = {};
41
+ const cameraProp: cameraPropType = {
42
+ ...prop,
43
+ checkCollision,
44
+ control,
45
+ controllerContext,
46
+ worldContext,
47
+ };
48
+
49
+ const getMeshs = (object: THREE.Object3D) => {
50
+ if (object.userData && object.userData.intangible) return;
51
+ if (
52
+ object instanceof THREE.Mesh &&
53
+ object.geometry.type !== "InstancedBufferGeometry"
54
+ ) {
55
+ intersectObjectMap[object.uuid] = object;
56
+ }
57
+ object.children.forEach((child) => {
58
+ getMeshs(child);
59
+ });
60
+ };
61
+
62
+ useFrame((state, delta) => {
63
+ if (
64
+ !rigidBodyRef ||
65
+ !rigidBodyRef.current ||
66
+ !outerGroupRef ||
67
+ !outerGroupRef.current
68
+ )
69
+ return null;
70
+ cameraProp.state = state;
71
+ cameraProp.delta = delta;
72
+
73
+ if (cameraMode.cameraType === "perspective") {
74
+ scene.children.forEach((child) => getMeshs(child));
75
+ cameraRay.intersectObjectMap = intersectObjectMap;
76
+ if (cameraMode.controlType === "orbit") {
77
+ orbit(cameraProp);
78
+ } else if (cameraMode.controlType === "normal") {
79
+ normal(cameraProp);
80
+ }
81
+ } else if (cameraMode.cameraType === "orthographic") {
82
+ mapControl(cameraProp);
83
+ }
84
+ });
85
+
86
+ return (
87
+ <>
88
+ {cameraMode.cameraType === "perspective" && (
89
+ <>
90
+ <OrbitControls target={activeState.position} />
91
+ <PerspectiveCamera makeDefault {...perspectiveCamera} />
92
+ </>
93
+ )}
94
+ {cameraMode.cameraType === "orthographic" && (
95
+ <>
96
+ <MapControls target={activeState.position} />
97
+ <OrthographicCamera makeDefault {...orthographicCamera} />
98
+ </>
99
+ )}
100
+ </>
101
+ );
102
+ }
@@ -0,0 +1,17 @@
1
+ export type cameraRayType = {
2
+ origin: THREE.Vector3;
3
+ hit: THREE.Raycaster;
4
+ rayCast: THREE.Raycaster | null;
5
+ lerpingPoint: THREE.Vector3;
6
+ length: number;
7
+ dir: THREE.Vector3;
8
+ position: THREE.Vector3;
9
+ followCamera: THREE.Object3D;
10
+ pivot: THREE.Object3D;
11
+ intersetesAndTransParented: THREE.Intersection<
12
+ THREE.Object3D<THREE.Object3DEventMap>
13
+ >[];
14
+ intersects: THREE.Intersection<THREE.Object3D<THREE.Object3DEventMap>>[];
15
+ intersectObjects: THREE.Object3D[];
16
+ intersectObjectMap: { [uuid: string]: THREE.Object3D };
17
+ };
@@ -0,0 +1,46 @@
1
+ "use client";
2
+
3
+ import { propType, refsType } from "../controller/type";
4
+ import calculation from "../physics";
5
+ import { AirplaneInnerGroupRef } from "./gltf/AirplaneGltf";
6
+ import {
7
+ AirplaneCollider,
8
+ AirplaneGroup,
9
+ AirplaneRigidBody,
10
+ } from "./ref/airplane";
11
+
12
+ export function Airplane({
13
+ controllerProps,
14
+ refs,
15
+ }: {
16
+ controllerProps: propType;
17
+ refs: refsType;
18
+ }) {
19
+ const { rigidBodyRef, outerGroupRef, capsuleColliderRef, innerGroupRef } =
20
+ refs;
21
+ calculation(controllerProps);
22
+
23
+ return (
24
+ <>
25
+ <AirplaneGroup ref={outerGroupRef}>
26
+ <AirplaneRigidBody
27
+ ref={rigidBodyRef}
28
+ groundRay={controllerProps.groundRay}
29
+ >
30
+ <AirplaneCollider prop={controllerProps} ref={capsuleColliderRef} />
31
+ {/* <CharacterGltf
32
+ gltf={characterGltf}
33
+ prop={prop}
34
+ url={props.url}
35
+ character={props.character}
36
+ groundRay={prop.groundRay}
37
+ refs={refs}
38
+ callbacks={callbacks}
39
+ isRider={true}
40
+ /> */}
41
+ <AirplaneInnerGroupRef ref={innerGroupRef} />
42
+ </AirplaneRigidBody>
43
+ </AirplaneGroup>
44
+ </>
45
+ );
46
+ }
@@ -0,0 +1,48 @@
1
+ "use client";
2
+
3
+ import calculation from "../physics";
4
+
5
+ import { propType, refsType } from "../controller/type";
6
+ import CharacterGltf from "./gltf/CharacterGltf";
7
+ import {
8
+ CharacterCapsuleCollider,
9
+ CharacterGroup,
10
+ CharacterRigidBody,
11
+ CharacterSlopeRay,
12
+ } from "./ref/character";
13
+
14
+ export function Character({
15
+ controllerProps,
16
+ refs,
17
+ }: {
18
+ controllerProps: propType;
19
+ refs: refsType;
20
+ }) {
21
+ const { capsuleColliderRef, rigidBodyRef, outerGroupRef, slopeRayOriginRef } =
22
+ refs;
23
+ calculation(controllerProps);
24
+
25
+ return (
26
+ <CharacterRigidBody ref={rigidBodyRef} controllerProps={controllerProps}>
27
+ <CharacterCapsuleCollider
28
+ prop={controllerProps}
29
+ ref={capsuleColliderRef}
30
+ />
31
+ <CharacterGroup ref={outerGroupRef}>
32
+ <CharacterSlopeRay
33
+ slopeRay={controllerProps.slopeRay}
34
+ groundRay={controllerProps.groundRay}
35
+ ref={slopeRayOriginRef}
36
+ />
37
+ {controllerProps.children}
38
+ <CharacterGltf
39
+ prop={controllerProps}
40
+ groupProps={controllerProps.groupProps}
41
+ groundRay={controllerProps.groundRay}
42
+ refs={refs}
43
+ callbacks={controllerProps.callbacks}
44
+ />
45
+ </CharacterGroup>
46
+ </CharacterRigidBody>
47
+ );
48
+ }
@@ -0,0 +1,40 @@
1
+ "use client";
2
+
3
+ import { propType, refsType } from "../controller/type";
4
+ import calculation from "../physics";
5
+ import CharacterGltf from "./gltf/CharacterGltf";
6
+ import VehicleGltf from "./gltf/VehicleGltf";
7
+ import { Wheels } from "./gltf/WheelJoint";
8
+ import { VehicleCollider, VehicleGroup, VehicleRigidBody } from "./ref/vehicle";
9
+
10
+ export function Vehicle({
11
+ controllerProps,
12
+ refs,
13
+ }: {
14
+ controllerProps: propType;
15
+ refs: refsType;
16
+ }) {
17
+ const { rigidBodyRef, outerGroupRef } = refs;
18
+ calculation(controllerProps);
19
+
20
+ return (
21
+ <VehicleGroup ref={outerGroupRef}>
22
+ <VehicleRigidBody
23
+ ref={rigidBodyRef}
24
+ groundRay={controllerProps.groundRay}
25
+ >
26
+ <VehicleCollider />
27
+ <CharacterGltf
28
+ prop={controllerProps}
29
+ groupProps={controllerProps.groupProps}
30
+ groundRay={controllerProps.groundRay}
31
+ refs={refs}
32
+ callbacks={controllerProps.callbacks}
33
+ isRider={true}
34
+ />
35
+ <VehicleGltf />
36
+ </VehicleRigidBody>
37
+ <Wheels prop={controllerProps} />
38
+ </VehicleGroup>
39
+ );
40
+ }