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.
- package/README.md +51 -0
- package/index.html +13 -0
- package/package.json +82 -0
- package/src/gaesup/animation/actions.ts +123 -0
- package/src/gaesup/camera/cameraCollisionDetecter.tsx +53 -0
- package/src/gaesup/camera/control/map.ts +10 -0
- package/src/gaesup/camera/control/normal copy.ts +19 -0
- package/src/gaesup/camera/control/normal.ts +15 -0
- package/src/gaesup/camera/control/orbit.ts +31 -0
- package/src/gaesup/camera/index.tsx +102 -0
- package/src/gaesup/camera/type.ts +17 -0
- package/src/gaesup/component/Airplane.tsx +46 -0
- package/src/gaesup/component/Character.tsx +48 -0
- package/src/gaesup/component/Vehicle.tsx +40 -0
- package/src/gaesup/component/gltf/AirplaneGltf.tsx +31 -0
- package/src/gaesup/component/gltf/CharacterGltf.tsx +81 -0
- package/src/gaesup/component/gltf/VehicleGltf.tsx +31 -0
- package/src/gaesup/component/gltf/WheelJoint.tsx +39 -0
- package/src/gaesup/component/gltf/type.ts +6 -0
- package/src/gaesup/component/ref/airplane.tsx +83 -0
- package/src/gaesup/component/ref/character.tsx +132 -0
- package/src/gaesup/component/ref/vehicle.tsx +145 -0
- package/src/gaesup/controller/index.tsx +103 -0
- package/src/gaesup/controller/type.ts +139 -0
- package/src/gaesup/gaesupProps/index.tsx +66 -0
- package/src/gaesup/initial/callback/index.ts +73 -0
- package/src/gaesup/initial/callback/type.ts +45 -0
- package/src/gaesup/initial/controller/index.ts +143 -0
- package/src/gaesup/initial/controller/initDebug.ts +102 -0
- package/src/gaesup/initial/gaesupWorld/collider/airplane.ts +26 -0
- package/src/gaesup/initial/gaesupWorld/collider/character.ts +32 -0
- package/src/gaesup/initial/gaesupWorld/collider/gltf.ts +91 -0
- package/src/gaesup/initial/gaesupWorld/collider/index.ts +26 -0
- package/src/gaesup/initial/gaesupWorld/collider/vehicle.ts +43 -0
- package/src/gaesup/initial/gaesupWorld/index.ts +82 -0
- package/src/gaesup/initial/gaesupWorld/type.ts +37 -0
- package/src/gaesup/physics/airplane/currentSetting.ts +20 -0
- package/src/gaesup/physics/airplane/damping.ts +8 -0
- package/src/gaesup/physics/airplane/direction.ts +70 -0
- package/src/gaesup/physics/airplane/gravity.ts +11 -0
- package/src/gaesup/physics/airplane/impulse.ts +22 -0
- package/src/gaesup/physics/airplane/index.tsx +16 -0
- package/src/gaesup/physics/airplane/turn.ts +12 -0
- package/src/gaesup/physics/airplane copy/currentSetting.ts +20 -0
- package/src/gaesup/physics/airplane copy/direction.ts +52 -0
- package/src/gaesup/physics/airplane copy/gravity.ts +6 -0
- package/src/gaesup/physics/airplane copy/impulse.ts +28 -0
- package/src/gaesup/physics/airplane copy/index.tsx +14 -0
- package/src/gaesup/physics/airplane copy/turn.ts +9 -0
- package/src/gaesup/physics/character/accelaration.ts +14 -0
- package/src/gaesup/physics/character/currentSetting.ts +20 -0
- package/src/gaesup/physics/character/damping.ts +6 -0
- package/src/gaesup/physics/character/direction.ts +104 -0
- package/src/gaesup/physics/character/impulse.ts +24 -0
- package/src/gaesup/physics/character/index.tsx +20 -0
- package/src/gaesup/physics/character/jump.ts +21 -0
- package/src/gaesup/physics/character/stabilizing.ts +6 -0
- package/src/gaesup/physics/character/turn.ts +17 -0
- package/src/gaesup/physics/check/ground.ts +19 -0
- package/src/gaesup/physics/check/index.ts +12 -0
- package/src/gaesup/physics/check/moving.ts +21 -0
- package/src/gaesup/physics/check/rotate.ts +13 -0
- package/src/gaesup/physics/check/slope.ts +50 -0
- package/src/gaesup/physics/index.ts +50 -0
- package/src/gaesup/physics/type.ts +35 -0
- package/src/gaesup/physics/vehicle/currentSetting.ts +20 -0
- package/src/gaesup/physics/vehicle/damping.ts +8 -0
- package/src/gaesup/physics/vehicle/direction.ts +27 -0
- package/src/gaesup/physics/vehicle/impulse.ts +22 -0
- package/src/gaesup/physics/vehicle/index.tsx +14 -0
- package/src/gaesup/physics/vehicle/turn.ts +11 -0
- package/src/gaesup/stores/active/index.ts +19 -0
- package/src/gaesup/stores/active/type.ts +16 -0
- package/src/gaesup/stores/airplane/index.ts +6 -0
- package/src/gaesup/stores/airplane/type.ts +4 -0
- package/src/gaesup/stores/animation/index.ts +18 -0
- package/src/gaesup/stores/animation/type.ts +9 -0
- package/src/gaesup/stores/collider/index.ts +55 -0
- package/src/gaesup/stores/context/controller/index.ts +36 -0
- package/src/gaesup/stores/context/controller/reducer.ts +18 -0
- package/src/gaesup/stores/context/controller/type.ts +38 -0
- package/src/gaesup/stores/context/gaesupworld/index.ts +11 -0
- package/src/gaesup/stores/context/gaesupworld/reducer.ts +21 -0
- package/src/gaesup/stores/context/gaesupworld/type.ts +66 -0
- package/src/gaesup/stores/control/index.ts +33 -0
- package/src/gaesup/stores/control/type.ts +11 -0
- package/src/gaesup/stores/joystick/index.ts +72 -0
- package/src/gaesup/stores/joystick/type.ts +23 -0
- package/src/gaesup/stores/minimap/index.ts +5 -0
- package/src/gaesup/stores/minimap/type.ts +22 -0
- package/src/gaesup/stores/point/type.ts +6 -0
- package/src/gaesup/stores/states/index.tsx +10 -0
- package/src/gaesup/stores/states/type.ts +10 -0
- package/src/gaesup/stores/url/index.ts +6 -0
- package/src/gaesup/stores/url/type.ts +6 -0
- package/src/gaesup/styles.css.ts +26 -0
- package/src/gaesup/tools/gameboy/GameBoyButton.tsx +38 -0
- package/src/gaesup/tools/gameboy/index.tsx +36 -0
- package/src/gaesup/tools/gameboy/style.css.ts +78 -0
- package/src/gaesup/tools/gamepad/GamePadButton.tsx +31 -0
- package/src/gaesup/tools/gamepad/index.tsx +55 -0
- package/src/gaesup/tools/gamepad/style.css.ts +16 -0
- package/src/gaesup/tools/index.tsx +61 -0
- package/src/gaesup/tools/joystick/index.tsx +145 -0
- package/src/gaesup/tools/joystick/style.css.ts +40 -0
- package/src/gaesup/tools/jumpPoint/index.tsx +27 -0
- package/src/gaesup/tools/jumpPoint/style.css.ts +33 -0
- package/src/gaesup/tools/keyBoardToolTip/constant.ts +144 -0
- package/src/gaesup/tools/keyBoardToolTip/index.tsx +85 -0
- package/src/gaesup/tools/keyBoardToolTip/style.css.ts +49 -0
- package/src/gaesup/tools/minimap/index.tsx +47 -0
- package/src/gaesup/tools/minimap/style.css.ts +144 -0
- package/src/gaesup/tools/style.css.ts +34 -0
- package/src/gaesup/utils/constant.ts +1 -0
- package/src/gaesup/utils/ray.ts +23 -0
- package/src/gaesup/utils/ref.ts +17 -0
- package/src/gaesup/utils/vector.ts +40 -0
- package/src/gaesup/world/index.tsx +17 -0
- package/src/gaesup/world/type.ts +10 -0
- package/src/styles/constants/boxshadow.css.ts +499 -0
- package/src/styles/constants/constant.css.ts +81 -0
- package/src/styles/constants/direction.css.ts +168 -0
- package/src/styles/constants/flex.css.ts +68 -0
- package/src/styles/constants/gradient.css.ts +10 -0
- package/src/styles/constants/grid.css.ts +37 -0
- package/src/styles/constants/palette.css.ts +324 -0
- package/src/styles/constants/translate.css.ts +129 -0
- package/src/styles/global.css.ts +91 -0
- package/src/styles/recipe/base.css.ts +31 -0
- package/src/styles/recipe/button.css.ts +109 -0
- package/src/styles/recipe/index.css.ts +134 -0
- package/src/styles/recipe/input.css.ts +33 -0
- package/src/styles/sprinkles/color.css.ts +62 -0
- package/src/styles/sprinkles/direction.css.ts +26 -0
- package/src/styles/sprinkles/display.css.ts +25 -0
- package/src/styles/sprinkles/fontSize.css.ts +25 -0
- package/src/styles/sprinkles/grid.css.ts +25 -0
- package/src/styles/sprinkles/index.css.ts +22 -0
- package/src/styles/sprinkles/margin.css.ts +30 -0
- package/src/styles/sprinkles/padding.css.ts +30 -0
- package/src/styles/sprinkles/position.css.ts +14 -0
- package/src/styles/sprinkles/size.css.ts +23 -0
- package/src/styles/theme.css.ts +98 -0
- package/tsconfig.json +27 -0
- package/tsconfig.node.json +10 -0
- 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
|
+
[](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
|
+
}
|