three-base 2.0.87 → 2.0.89

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/FPScontrol.ts DELETED
@@ -1,209 +0,0 @@
1
- /*
2
- * @Author: xiaosihan
3
- * @Date: 2022-05-04 23:01:36
4
- * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2022-06-06 13:32:08
6
- */
7
-
8
- import { Camera, Clock, EventDispatcher, Object3D, Vector3 } from "three";
9
- import { Capsule } from "three/examples/jsm/math/Capsule";
10
- import { Octree } from "three/examples/jsm/math/Octree";
11
- import { clamp, degToRad } from "three/src/math/MathUtils";
12
-
13
-
14
- /**
15
- * 第一人称控制器
16
- *
17
- * @export
18
- * @class FPScontrol
19
- * @extends {EventDispatcher}
20
- */
21
- export default class FPScontrol extends EventDispatcher {
22
-
23
- canvas!: HTMLCanvasElement
24
-
25
- constructor(camera: Camera, canvas: HTMLCanvasElement) {
26
- super();
27
-
28
- // 相机对象
29
- this.camera = camera;
30
-
31
- this.camera.rotation.order = 'YXZ';
32
-
33
- this.canvas = canvas;
34
-
35
- this.init(canvas);
36
- }
37
-
38
- // 是否启用
39
- enable = false;
40
-
41
- GRAVITY = 30; // 重力
42
- STEPS_PER_FRAME = 5; // 每帧碰撞计算的次数
43
- speed = 1; // 速度
44
- camera!: Camera;
45
-
46
- // 世界八叉树对象
47
- worldOctree = new Octree();
48
-
49
- // 用户自己的碰撞体积
50
- playerCollider = new Capsule(new Vector3(0, 0.35, 0), new Vector3(0, 1, 0), 0.35);
51
-
52
- // 时钟对象
53
- clock = new Clock();
54
-
55
- playerVelocity = new Vector3();
56
- playerDirection = new Vector3();
57
-
58
- playerOnFloor = false;
59
- mouseTime = 0;
60
- isMousedown = false;
61
- keyStates: { [key: string]: boolean } = {};
62
-
63
-
64
- init(canvas: HTMLCanvasElement) {
65
- this.playerCollider.end.set(0, 1, 0);
66
- document.addEventListener('keydown', this.keydown);
67
- document.addEventListener('keyup', this.keyup);
68
- canvas.addEventListener('pointerdown', this.mousedown);
69
- document.addEventListener('pointerup', this.mouseup);
70
- document.body.addEventListener('pointermove', this.mousemove);
71
- this.enable = true;
72
- }
73
-
74
-
75
- keydown = (event: KeyboardEvent) => {
76
- this.keyStates[event.code] = true;
77
- }
78
-
79
- keyup = (event: KeyboardEvent) => {
80
- this.keyStates[event.code] = false;
81
- }
82
-
83
- mousedown = () => {
84
- this.isMousedown = true;
85
- this.mouseTime = performance.now();
86
- }
87
-
88
- mouseup = () => {
89
- this.isMousedown = false;
90
- }
91
-
92
- mousemove = (event: MouseEvent) => {
93
- if (this.enable && this.isMousedown) {
94
- this.camera.rotation.y -= event.movementX / 500;
95
- this.camera.rotation.x -= event.movementY / 500;
96
-
97
- }
98
- }
99
-
100
- // 设置 八叉树 节点
101
- fromGraphNode(object3d: Object3D) {
102
- this.worldOctree.fromGraphNode(object3d);
103
- }
104
-
105
- // 获取前进的向量
106
- getForwardVector = () => {
107
- this.camera.getWorldDirection(this.playerDirection);
108
- this.playerDirection.y = 0;
109
- this.playerDirection.normalize();
110
- return this.playerDirection;
111
- }
112
-
113
- // 获取 后退的向量
114
- getSideVector = () => {
115
- this.camera.getWorldDirection(this.playerDirection);
116
- this.playerDirection.y = 0;
117
- this.playerDirection.normalize();
118
- this.playerDirection.cross(this.camera.up);
119
- return this.playerDirection;
120
- }
121
-
122
- // 玩家移动控制器
123
- controls = (deltaTime: number) => {
124
- const speedDelta = deltaTime * (this.playerOnFloor ? 25 : 8) * this.speed;
125
- if (this.keyStates['KeyW']) {
126
- this.playerVelocity.add(this.getForwardVector().multiplyScalar(speedDelta));
127
- }
128
- if (this.keyStates['KeyS']) {
129
- this.playerVelocity.add(this.getForwardVector().multiplyScalar(-speedDelta));
130
- }
131
- if (this.keyStates['KeyA']) {
132
- this.playerVelocity.add(this.getSideVector().multiplyScalar(-speedDelta));
133
- }
134
- if (this.keyStates['KeyD']) {
135
- this.playerVelocity.add(this.getSideVector().multiplyScalar(speedDelta));
136
- }
137
-
138
- if (this.playerOnFloor) {
139
- if (this.keyStates['Space']) {
140
- this.playerVelocity.y = 15;
141
- }
142
- }
143
-
144
- }
145
-
146
- // 更新玩家的位置
147
- updatePlayer = (deltaTime: number) => {
148
- let damping = Math.exp(-4 * deltaTime) - 1;
149
- if (!this.playerOnFloor) {
150
- this.playerVelocity.y -= this.GRAVITY * deltaTime;
151
- damping *= 0.1;
152
- }
153
- this.playerVelocity.addScaledVector(this.playerVelocity, damping);
154
- const deltaPosition = this.playerVelocity.clone().multiplyScalar(deltaTime);
155
- this.playerCollider.translate(deltaPosition);
156
- this.playerCollisions();
157
- this.camera.position.copy(this.playerCollider.end);
158
- this.camera.position.y += 1;
159
- this.camera.rotation.x = clamp(this.camera.rotation.x, degToRad(-20), degToRad(20));
160
- }
161
-
162
- // 玩家的碰撞检测
163
- playerCollisions() {
164
- const result = this.worldOctree.capsuleIntersect(this.playerCollider);
165
- this.playerOnFloor = false;
166
- if (result) {
167
- this.playerOnFloor = result.normal.y > 0;
168
- if (!this.playerOnFloor) {
169
- this.playerVelocity.addScaledVector(result.normal, -result.normal.dot(this.playerVelocity));
170
-
171
- }
172
- this.playerCollider.translate(result.normal.multiplyScalar(result.depth));
173
- }
174
- }
175
- // 更新控制器的位置
176
- teleportPlayerIfOob = () => {
177
- if (this.camera.position.y <= -10) {
178
- this.playerCollider.start.set(0, 0.35, 0);
179
- this.playerCollider.end.set(0, 1, 10);
180
- this.playerCollider.radius = 0.35;
181
- this.camera.position.copy(this.playerCollider.end);
182
- // this.camera.position.set(0, 3, 0);
183
- }
184
- }
185
-
186
- // 更新
187
- update() {
188
- if (this.enable) {
189
- const deltaTime = Math.min(0.05, this.clock.getDelta()) / this.STEPS_PER_FRAME;
190
- for (let i = 0; i < this.STEPS_PER_FRAME; i++) {
191
- this.controls(deltaTime);
192
- this.updatePlayer(deltaTime);
193
- this.teleportPlayerIfOob();
194
- }
195
- }
196
- }
197
-
198
- // 销毁事件
199
- disposer() {
200
- this.enable = false;
201
- document.removeEventListener('keydown', this.keydown);
202
- document.removeEventListener('keyup', this.keyup);
203
- this.canvas.removeEventListener('pointerdown', this.mousedown);
204
- document.removeEventListener('pointerup', this.mouseup);
205
- document.body.removeEventListener('pointermove', this.mousemove);
206
- }
207
-
208
-
209
- }
package/Fire/Fire.ts DELETED
@@ -1,99 +0,0 @@
1
- /*
2
- * @Author: xiaosihan
3
- * @Date: 2024-06-17 02:15:58
4
- * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2024-06-18 20:34:38
6
- */
7
-
8
- import { BufferGeometry, Camera, Clock, Color, Group, Material, NormalBufferAttributes, Object3DEventMap, PerspectiveCamera, Points, Scene, Vector2, WebGLRenderer } from "three";
9
- import FireGromtry from "./FireGromtry";
10
- import FireMaterial from "./FireMaterial";
11
- import { degToRad } from "three/src/math/MathUtils";
12
-
13
- // 粒子火焰效果
14
- export default class Fire extends Points {
15
-
16
- constructor() {
17
- super();
18
- }
19
-
20
- geometry = new FireGromtry(0, 0, 0);
21
-
22
- material = new FireMaterial();
23
-
24
- // 火焰的颜色
25
- fireColor = "#ff2200";
26
- // 火焰的整体缩放值
27
- fireScale = 1;
28
- // 火焰的燃烧半径
29
- fireRadius = 0.5;
30
- // 火焰的高度
31
- fireHeight = 3;
32
- // 火焰的粒子数量
33
- particleCount = 500;
34
- // 是否是透视相机
35
- isPerspectiveCamera = true;
36
- //渲染器的尺寸
37
- size = new Vector2();
38
-
39
- // 缓存的参数
40
- cacheProps = {
41
- fireColor: "#ff2200",
42
- fireScale: 0,
43
- fireRadius: 0.5,
44
- fireHeight: 3,
45
- particleCount: 500,
46
- width: 0,
47
- height: 0,
48
- isPerspectiveCamera: true
49
- }
50
-
51
- // 当前渲染的帧数
52
- updataFrame = 0;
53
-
54
- // 时钟对象
55
- clock = new Clock();
56
-
57
- onBeforeRender(renderer: WebGLRenderer, scene: Scene, camera: Camera, geometry: BufferGeometry<NormalBufferAttributes>, material: Material, group: Group<Object3DEventMap>): void {
58
-
59
- const delta = this.clock.getDelta();
60
- renderer.getSize(this.size);
61
-
62
- if (
63
- this.cacheProps.fireColor !== this.fireColor ||
64
- this.cacheProps.fireScale !== this.fireScale ||
65
- this.cacheProps.fireRadius !== this.fireRadius ||
66
- this.cacheProps.fireHeight !== this.fireHeight ||
67
- this.cacheProps.particleCount !== this.particleCount ||
68
- this.cacheProps.isPerspectiveCamera !== this.isPerspectiveCamera ||
69
- this.cacheProps.width !== this.size.x ||
70
- this.cacheProps.height !== this.size.y
71
- ) {
72
- this.cacheProps.fireColor = this.fireColor;
73
- this.cacheProps.fireScale = this.fireScale;
74
- this.cacheProps.fireRadius = this.fireRadius;
75
- this.cacheProps.fireHeight = this.fireHeight;
76
- this.cacheProps.particleCount = this.particleCount;
77
- this.cacheProps.isPerspectiveCamera = this.isPerspectiveCamera;
78
- this.cacheProps.width = this.size.x;
79
- this.cacheProps.height = this.size.y;
80
-
81
- this.geometry = new FireGromtry(this.fireRadius * this.fireScale, this.fireHeight * this.fireScale, this.particleCount);
82
-
83
- this.material.uniforms.color.value = new Color(this.fireColor);
84
- this.material.uniforms.size.value = this.fireScale * 0.4;
85
- if ((camera as PerspectiveCamera).isPerspectiveCamera) {
86
- this.material.uniforms.heightOfNearPlane.value = Math.abs(this.size.y / (2 * Math.tan(degToRad((camera as PerspectiveCamera).fov * 0.5))));
87
- } else {
88
- this.material.uniforms.heightOfNearPlane.value = 0;
89
- }
90
-
91
- }
92
-
93
- this.isPerspectiveCamera = (camera as PerspectiveCamera).isPerspectiveCamera;
94
-
95
- this.material.uniforms.time.value = (this.material.uniforms.time.value + delta) % 1;
96
-
97
- }
98
-
99
- }
@@ -1,54 +0,0 @@
1
- /*
2
- * @Author: xiaosihan
3
- * @Date: 2024-06-17 02:15:58
4
- * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2024-06-18 18:12:37
6
- */
7
-
8
- export const SPRITE_ROW_LENGTH = 4; // 粒子图片中图片数量
9
- export const ONE_SPRITE_ROW_LENGTH = 1 / SPRITE_ROW_LENGTH; // 每一行的宽度
10
- import { BufferAttribute, BufferGeometry } from "three";
11
-
12
- // 粒子火焰顶点对象
13
- export default class FireGromtry extends BufferGeometry {
14
-
15
- radius = 0.5;
16
- height = 3;
17
- particleCount = 200;
18
-
19
- constructor(radius: number = 0.5, height: number = 3, particleCount: number = 200) {
20
- super();
21
-
22
- const halfHeight = height * 0.5;
23
- const position = new Float32Array(particleCount * 3);
24
- const random = new Float32Array(particleCount);
25
- const sprite = new Float32Array(particleCount);
26
-
27
- for (let i = 0; i < particleCount; i++) {
28
-
29
- const r = Math.sqrt(Math.random()) * radius;
30
- const angle = Math.random() * 2 * Math.PI;
31
- position[i * 3 + 0] = Math.cos(angle) * r;
32
- position[i * 3 + 1] = (radius - r) / radius * halfHeight + halfHeight;
33
- position[i * 3 + 2] = Math.sin(angle) * r;
34
- sprite[i] = ONE_SPRITE_ROW_LENGTH * ((Math.random() * 4) | 0);
35
- random[i] = Math.random();
36
-
37
- if (i === 0) {
38
-
39
- // to avoid going out of Frustum
40
- position[i * 3 + 0] = 0;
41
- position[i * 3 + 1] = 0;
42
- position[i * 3 + 2] = 0;
43
-
44
- }
45
-
46
- }
47
-
48
- this.setAttribute('position', new BufferAttribute(position, 3));
49
- this.setAttribute('random', new BufferAttribute(random, 1));
50
- this.setAttribute('sprite', new BufferAttribute(sprite, 1));
51
- }
52
-
53
-
54
- }
@@ -1,92 +0,0 @@
1
- /*
2
- * @Author: xiaosihan
3
- * @Date: 2024-06-17 02:37:46
4
- * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2024-06-18 20:23:31
6
- */
7
-
8
- import { AdditiveBlending, Color, ShaderChunk, ShaderMaterial } from "three";
9
- import threeLoader from "../threeLoader";
10
- import { ONE_SPRITE_ROW_LENGTH } from "./FireGromtry";
11
-
12
- // 火焰粒子材质
13
- export default class FireMaterial extends ShaderMaterial {
14
-
15
- constructor() {
16
- super();
17
- }
18
-
19
- // 材质参数
20
- uniforms = {
21
- color: { value: new Color() },
22
- size: { value: 0.0 },
23
- map: { value: threeLoader.getTexture("data:image/png;base64,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") },
24
- time: { value: 0.0 },
25
- heightOfNearPlane: { value: 0.0 }
26
- };
27
-
28
- // 顶点着色器
29
- vertexShader = `
30
- ${ShaderChunk.common}
31
- ${ShaderChunk.logdepthbuf_pars_vertex}
32
- attribute float random;
33
- attribute float sprite;
34
- uniform float time;
35
- uniform float size;
36
- uniform float heightOfNearPlane;
37
-
38
- varying float vSprite;
39
- varying float vOpacity;
40
-
41
- float quadraticIn( float t ) {
42
- float tt = t * t;
43
- return tt * tt;
44
- }
45
-
46
- void main() {
47
- float progress = fract( time + ( 2.0 * random - 1.0 ) );
48
- float progressNeg = 1.0 - progress;
49
- float ease = quadraticIn( progress );
50
- float influence = sin( PI * ease );
51
-
52
- vec3 newPosition = position * vec3( 1.0, ease, 1.0 );
53
- gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
54
- gl_PointSize = ( heightOfNearPlane * size ) / gl_Position.w;
55
-
56
- vOpacity = min( influence * 4.0, 1.0 ) * progressNeg;
57
- vSprite = sprite;
58
- ${ShaderChunk.logdepthbuf_vertex}
59
- }
60
- `;
61
-
62
- //片元着色器
63
- fragmentShader = `
64
- ${ShaderChunk.logdepthbuf_pars_fragment}
65
- uniform vec3 color;
66
- uniform sampler2D map;
67
-
68
- varying float vSprite;
69
- varying float vOpacity;
70
-
71
- void main() {
72
- vec2 texCoord = vec2(
73
- gl_PointCoord.x * ${ONE_SPRITE_ROW_LENGTH} + vSprite,
74
- gl_PointCoord.y
75
- );
76
- // gl_FragColor = vec4( texture2D( map, texCoord ).xyz * color * vOpacity, 1.0 );
77
- vec4 textureColor = texture2D( map, texCoord );
78
- float colorMax = max(max(textureColor.x, textureColor.y),textureColor.z);
79
- vec4 newTextureColor = vec4( textureColor.xyz * (100.0) , colorMax);
80
- gl_FragColor = newTextureColor * vec4(color,1.0) * vOpacity;
81
- ${ShaderChunk.logdepthbuf_fragment}
82
- }
83
- `
84
-
85
- blending = AdditiveBlending
86
- depthTest = true
87
- depthWrite = false;
88
- transparent = true
89
- fog = true
90
-
91
-
92
- }