@pmndrs/viverse 0.1.6 → 0.1.9
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 +1 -1
- package/dist/physics/index.d.ts +5 -4
- package/dist/physics/index.js +29 -20
- package/dist/simple-character.js +3 -3
- package/package.json +2 -2
package/README.md
CHANGED
package/dist/physics/index.d.ts
CHANGED
|
@@ -24,9 +24,9 @@ export type BvhCharacterPhysicsOptions = {
|
|
|
24
24
|
*/
|
|
25
25
|
linearDamping?: number;
|
|
26
26
|
/**
|
|
27
|
-
* @default 0.
|
|
27
|
+
* @default 0.5;
|
|
28
28
|
*/
|
|
29
|
-
|
|
29
|
+
maxGroundSlope?: number;
|
|
30
30
|
} | boolean;
|
|
31
31
|
/**
|
|
32
32
|
* assumes the target object origin is at its bottom
|
|
@@ -37,7 +37,8 @@ export declare class BvhCharacterPhysics {
|
|
|
37
37
|
private destroyed;
|
|
38
38
|
private readonly stateVelocity;
|
|
39
39
|
readonly inputVelocity: Vector3;
|
|
40
|
-
|
|
40
|
+
private notGroundedSeconds;
|
|
41
|
+
get isGrounded(): boolean;
|
|
41
42
|
constructor(character: Object3D, world: BvhPhysicsWorld);
|
|
42
43
|
applyVelocity(velocity: Vector3): void;
|
|
43
44
|
/**
|
|
@@ -45,6 +46,6 @@ export declare class BvhCharacterPhysics {
|
|
|
45
46
|
*/
|
|
46
47
|
update(fullDelta: number, options?: BvhCharacterPhysicsOptions): void;
|
|
47
48
|
destroy(): void;
|
|
48
|
-
shapecastCapsule(position: Vector3, options: Exclude<BvhCharacterPhysicsOptions, boolean>):
|
|
49
|
+
shapecastCapsule(position: Vector3, maxGroundSlope: number, options: Exclude<BvhCharacterPhysicsOptions, boolean>): boolean;
|
|
49
50
|
}
|
|
50
51
|
export * from './world.js';
|
package/dist/physics/index.js
CHANGED
|
@@ -7,8 +7,8 @@ const triPoint = new Vector3();
|
|
|
7
7
|
const capsulePoint = new Vector3();
|
|
8
8
|
const collisionFreePosition = new Vector3();
|
|
9
9
|
const position = new Vector3();
|
|
10
|
-
const collisionDelta = new Vector3();
|
|
11
10
|
const invertedParentMatrix = new Matrix4();
|
|
11
|
+
const YAxis = new Vector3(0, 1, 0);
|
|
12
12
|
/**
|
|
13
13
|
* assumes the target object origin is at its bottom
|
|
14
14
|
*/
|
|
@@ -18,7 +18,10 @@ export class BvhCharacterPhysics {
|
|
|
18
18
|
destroyed = false;
|
|
19
19
|
stateVelocity = new Vector3();
|
|
20
20
|
inputVelocity = new Vector3();
|
|
21
|
-
|
|
21
|
+
notGroundedSeconds = 0;
|
|
22
|
+
get isGrounded() {
|
|
23
|
+
return this.notGroundedSeconds < 0.2;
|
|
24
|
+
}
|
|
22
25
|
constructor(character, world) {
|
|
23
26
|
this.character = character;
|
|
24
27
|
this.world = world;
|
|
@@ -57,13 +60,17 @@ export class BvhCharacterPhysics {
|
|
|
57
60
|
invertedParentMatrix.identity();
|
|
58
61
|
}
|
|
59
62
|
//compute new position based on the state velocity, the input velocity, and the delta
|
|
60
|
-
const yMovement = this.stateVelocity.y * partialDelta;
|
|
61
|
-
position.addScaledVector(this.stateVelocity, partialDelta);
|
|
62
63
|
position.addScaledVector(this.inputVelocity, partialDelta);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this.
|
|
64
|
+
position.addScaledVector(this.stateVelocity, partialDelta);
|
|
65
|
+
const isGrounded = this.shapecastCapsule(collisionFreePosition.copy(position), options.maxGroundSlope ?? 1, options) &&
|
|
66
|
+
this.stateVelocity.y < 0;
|
|
67
|
+
this.notGroundedSeconds += partialDelta;
|
|
68
|
+
if (isGrounded) {
|
|
69
|
+
this.notGroundedSeconds = 0;
|
|
70
|
+
}
|
|
71
|
+
if (!isGrounded || this.inputVelocity.lengthSq() > 0) {
|
|
72
|
+
this.character.position.copy(collisionFreePosition).applyMatrix4(invertedParentMatrix);
|
|
73
|
+
}
|
|
67
74
|
//compute new velocity
|
|
68
75
|
// apply gravity
|
|
69
76
|
this.stateVelocity.y += (options.gravity ?? -20) * partialDelta;
|
|
@@ -71,21 +78,15 @@ export class BvhCharacterPhysics {
|
|
|
71
78
|
const dampingFactor = 1.0 / (1.0 + partialDelta * (options.linearDamping ?? 0.1));
|
|
72
79
|
this.stateVelocity.multiplyScalar(dampingFactor);
|
|
73
80
|
// apply collision to velocity
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (this.isGrounded) {
|
|
77
|
-
this.stateVelocity.set(0, (options.gravity ?? -20) * partialDelta, 0);
|
|
78
|
-
}
|
|
79
|
-
else if (collisionDelta.length() > 1e-5) {
|
|
80
|
-
collisionDelta.normalize();
|
|
81
|
-
this.stateVelocity.addScaledVector(collisionDelta, -collisionDelta.dot(this.stateVelocity));
|
|
81
|
+
if (isGrounded) {
|
|
82
|
+
this.stateVelocity.set(0, (options.gravity ?? -20) * 0.01, 0);
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
destroy() {
|
|
86
87
|
this.destroyed = true;
|
|
87
88
|
}
|
|
88
|
-
shapecastCapsule(position, options) {
|
|
89
|
+
shapecastCapsule(position, maxGroundSlope, options) {
|
|
89
90
|
const radius = options.capsuleRadius ?? 0.4;
|
|
90
91
|
const height = options.capsuleHeight ?? 1.7;
|
|
91
92
|
segment.start.copy(position);
|
|
@@ -97,6 +98,7 @@ export class BvhCharacterPhysics {
|
|
|
97
98
|
aabbox.expandByPoint(segment.end);
|
|
98
99
|
aabbox.min.addScalar(-radius);
|
|
99
100
|
aabbox.max.addScalar(radius);
|
|
101
|
+
let grounded = false;
|
|
100
102
|
for (const bvh of this.world.getBodies()) {
|
|
101
103
|
bvh.shapecast({
|
|
102
104
|
intersectsBounds: (bounds) => bounds.intersectsBox(aabbox),
|
|
@@ -104,9 +106,11 @@ export class BvhCharacterPhysics {
|
|
|
104
106
|
// Use your existing triangle vs segment closestPointToSegment
|
|
105
107
|
const distance = tri.closestPointToSegment(segment, triPoint, capsulePoint);
|
|
106
108
|
if (distance === 0) {
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
const isCloserToSegmentStart = capsulePoint.distanceTo(segment.start) < capsulePoint.distanceTo(segment.end);
|
|
110
|
+
if (isCloserToSegmentStart) {
|
|
111
|
+
grounded = true;
|
|
112
|
+
}
|
|
113
|
+
const scaledDirection = capsulePoint.sub(isCloserToSegmentStart ? segment.start : segment.end);
|
|
110
114
|
scaledDirection.y += radius;
|
|
111
115
|
segment.start.add(scaledDirection);
|
|
112
116
|
segment.end.add(scaledDirection);
|
|
@@ -114,6 +118,10 @@ export class BvhCharacterPhysics {
|
|
|
114
118
|
else if (distance < radius) {
|
|
115
119
|
const depthInsideCapsule = radius - distance;
|
|
116
120
|
const direction = capsulePoint.sub(triPoint).divideScalar(distance);
|
|
121
|
+
const slope = Math.tan(Math.acos(direction.dot(YAxis)));
|
|
122
|
+
if (direction.y > 0 && slope <= maxGroundSlope) {
|
|
123
|
+
grounded = true;
|
|
124
|
+
}
|
|
117
125
|
segment.start.addScaledVector(direction, depthInsideCapsule);
|
|
118
126
|
segment.end.addScaledVector(direction, depthInsideCapsule);
|
|
119
127
|
}
|
|
@@ -122,6 +130,7 @@ export class BvhCharacterPhysics {
|
|
|
122
130
|
}
|
|
123
131
|
position.copy(segment.start);
|
|
124
132
|
position.y -= radius;
|
|
133
|
+
return grounded;
|
|
125
134
|
}
|
|
126
135
|
}
|
|
127
136
|
export * from './world.js';
|
package/dist/simple-character.js
CHANGED
|
@@ -152,7 +152,7 @@ async function* SimpleCharacterTimeline(camera, character) {
|
|
|
152
152
|
actions.jumpForward.paused = true;
|
|
153
153
|
actions.jumpForward.fadeIn(character.options.animation?.crossFadeDuration ?? DefaultCrossFadeDuration);
|
|
154
154
|
},
|
|
155
|
-
update: () => void character.physics.inputVelocity.multiplyScalar(
|
|
155
|
+
update: () => void character.physics.inputVelocity.multiplyScalar(0.3),
|
|
156
156
|
until: timePassed((typeof character.options.movement?.jump === 'object'
|
|
157
157
|
? character.options.movement?.jump.delay
|
|
158
158
|
: undefined) ?? DefaultJumDelay, 'seconds'),
|
|
@@ -197,7 +197,7 @@ async function* SimpleCharacterTimeline(camera, character) {
|
|
|
197
197
|
}),
|
|
198
198
|
transitionTo: {
|
|
199
199
|
jumpDown: {
|
|
200
|
-
when: (_, clock) => clock.actionTime > 0.
|
|
200
|
+
when: (_, clock) => clock.actionTime > 0.3 && character.physics.isGrounded,
|
|
201
201
|
},
|
|
202
202
|
finally: 'jumpLoop',
|
|
203
203
|
},
|
|
@@ -226,7 +226,7 @@ async function* SimpleCharacterTimeline(camera, character) {
|
|
|
226
226
|
actions.jumpDown.fadeIn(character.options.animation?.crossFadeDuration ?? DefaultCrossFadeDuration);
|
|
227
227
|
},
|
|
228
228
|
cleanup: () => actions.jumpDown.fadeOut(character.options.animation?.crossFadeDuration ?? DefaultCrossFadeDuration),
|
|
229
|
-
until: timePassed(
|
|
229
|
+
until: timePassed(150, 'milliseconds'),
|
|
230
230
|
}),
|
|
231
231
|
transitionTo: { finally: 'moving' },
|
|
232
232
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pmndrs/viverse",
|
|
3
|
-
"description": "Toolkit for building Three.js Apps for
|
|
3
|
+
"description": "Toolkit for building Three.js Apps for VIVERSE and beyond.",
|
|
4
4
|
"author": "Bela Bohlender",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"homepage": "https://github.com/pmndrs/viverse",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"three": "*"
|
|
23
23
|
},
|
|
24
|
-
"version": "0.1.
|
|
24
|
+
"version": "0.1.9",
|
|
25
25
|
"type": "module",
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@pixiv/three-vrm": "^3.4.2",
|