fix CCD (but introduce another issue >.<)
This commit is contained in:
+25
-20
@@ -2,13 +2,7 @@ import type { Circle } from "#/engine/Circle.ts";
|
|||||||
import type { Polygon } from "#/engine/Polygon.ts";
|
import type { Polygon } from "#/engine/Polygon.ts";
|
||||||
import type { Rect } from "#/engine/Rect.ts";
|
import type { Rect } from "#/engine/Rect.ts";
|
||||||
import $ from "#/engine/Scene.ts";
|
import $ from "#/engine/Scene.ts";
|
||||||
import {
|
import { createVector, invScale, type Vector, ZERO } from "#/engine/Vector.ts";
|
||||||
createVector,
|
|
||||||
getDotProduct,
|
|
||||||
invScale,
|
|
||||||
scale,
|
|
||||||
type Vector,
|
|
||||||
} from "#/engine/Vector.ts";
|
|
||||||
|
|
||||||
export enum Shape {
|
export enum Shape {
|
||||||
Circle,
|
Circle,
|
||||||
@@ -418,6 +412,7 @@ function createCollision(): Collision {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const relVelocity = createVector();
|
||||||
export function moveAndCollide(
|
export function moveAndCollide(
|
||||||
id: string,
|
id: string,
|
||||||
velocity: Vector,
|
velocity: Vector,
|
||||||
@@ -425,6 +420,7 @@ export function moveAndCollide(
|
|||||||
): Array<Collision> {
|
): Array<Collision> {
|
||||||
const colliders = $<Collider>("collider")!;
|
const colliders = $<Collider>("collider")!;
|
||||||
const positions = $<Vector>("position")!;
|
const positions = $<Vector>("position")!;
|
||||||
|
const velocities = $<Vector>("velocity");
|
||||||
const selfColl = colliders.get(id)!.value;
|
const selfColl = colliders.get(id)!.value;
|
||||||
const selfPos = positions.get(id)!.value;
|
const selfPos = positions.get(id)!.value;
|
||||||
|
|
||||||
@@ -438,13 +434,22 @@ export function moveAndCollide(
|
|||||||
|
|
||||||
const otherColl = collider.value;
|
const otherColl = collider.value;
|
||||||
const otherPos = positions.get(cid)!.value;
|
const otherPos = positions.get(cid)!.value;
|
||||||
|
const otherVel = velocities?.get(cid)?.value ?? ZERO;
|
||||||
|
|
||||||
|
relVelocity.x = velocity.x - otherVel.x;
|
||||||
|
relVelocity.y = velocity.y - otherVel.y;
|
||||||
|
|
||||||
|
// no relative motion
|
||||||
|
if (relVelocity.x === 0 && relVelocity.y === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const collision = next(selfColl.buffer);
|
const collision = next(selfColl.buffer);
|
||||||
const tHit = sweptAABB(
|
const tHit = sweptAABB(
|
||||||
collision,
|
collision,
|
||||||
selfColl,
|
selfColl,
|
||||||
selfPos,
|
selfPos,
|
||||||
velocity,
|
relVelocity,
|
||||||
otherColl,
|
otherColl,
|
||||||
otherPos,
|
otherPos,
|
||||||
delta,
|
delta,
|
||||||
@@ -462,7 +467,7 @@ export function moveAndCollide(
|
|||||||
collision,
|
collision,
|
||||||
selfColl,
|
selfColl,
|
||||||
selfPos,
|
selfPos,
|
||||||
velocity,
|
relVelocity,
|
||||||
otherColl,
|
otherColl,
|
||||||
otherPos,
|
otherPos,
|
||||||
delta,
|
delta,
|
||||||
@@ -474,7 +479,7 @@ export function moveAndCollide(
|
|||||||
collision,
|
collision,
|
||||||
selfColl,
|
selfColl,
|
||||||
selfPos,
|
selfPos,
|
||||||
velocity,
|
relVelocity,
|
||||||
otherColl,
|
otherColl,
|
||||||
otherPos,
|
otherPos,
|
||||||
delta,
|
delta,
|
||||||
@@ -486,7 +491,7 @@ export function moveAndCollide(
|
|||||||
collision,
|
collision,
|
||||||
selfColl,
|
selfColl,
|
||||||
selfPos,
|
selfPos,
|
||||||
velocity,
|
relVelocity,
|
||||||
otherColl,
|
otherColl,
|
||||||
otherPos,
|
otherPos,
|
||||||
delta,
|
delta,
|
||||||
@@ -510,6 +515,7 @@ export function moveAndSlide(
|
|||||||
): void {
|
): void {
|
||||||
let timeLeft = 1;
|
let timeLeft = 1;
|
||||||
const position = $<Vector>("position").get(id)!.value;
|
const position = $<Vector>("position").get(id)!.value;
|
||||||
|
const velocities = $<Vector>("velocity");
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i++ < 4 && timeLeft > 0) {
|
while (i++ < 4 && timeLeft > 0) {
|
||||||
@@ -530,19 +536,18 @@ export function moveAndSlide(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const time = closest.time;
|
const time = closest.time;
|
||||||
// if the collider overlap already
|
|
||||||
if (time === 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const dot = getDotProduct(velocity, closest.normal);
|
|
||||||
velocity.x -= closest.normal.x * dot;
|
|
||||||
velocity.y -= closest.normal.y * dot;
|
|
||||||
|
|
||||||
const scalar = Math.max(0, time - EPSILON) * deltaLeft;
|
const scalar = Math.max(0, time - EPSILON) * deltaLeft;
|
||||||
position.x += velocity.x * scalar;
|
position.x += velocity.x * scalar;
|
||||||
position.y += velocity.y * scalar;
|
position.y += velocity.y * scalar;
|
||||||
|
|
||||||
|
// a stationary entity might not have a velocity compnent
|
||||||
|
const otherVel = velocities.get(closest.cid)?.value ?? ZERO;
|
||||||
|
const rvx = velocity.x - otherVel.x;
|
||||||
|
const rvy = velocity.y - otherVel.y;
|
||||||
|
const dot = rvx * closest.normal.x + rvy * closest.normal.y;
|
||||||
|
velocity.x -= closest.normal.x * dot;
|
||||||
|
velocity.y -= closest.normal.y * dot;
|
||||||
|
|
||||||
timeLeft *= 1 - time;
|
timeLeft *= 1 - time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ const process = defineEntity<{
|
|||||||
stuff: 1,
|
stuff: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
process((id, _delta) => {
|
process((id, delta) => {
|
||||||
const position = $<Vector>("position").get(id)!.value;
|
const position = $<Vector>("position").get(id)!.value;
|
||||||
const velocity = $<Vector>("velocity").get(id)!.value;
|
const velocity = $<Vector>("velocity").get(id)!.value;
|
||||||
const collider = $<Collider>("collider").get(id)!.value;
|
const collider = $<Collider>("collider").get(id)!.value;
|
||||||
@@ -80,8 +80,8 @@ process((id, _delta) => {
|
|||||||
const sprite = $<Sprite>("sprite").get(id)!;
|
const sprite = $<Sprite>("sprite").get(id)!;
|
||||||
const animation = $<SpriteAnimation>("animation").get(id)!;
|
const animation = $<SpriteAnimation>("animation").get(id)!;
|
||||||
|
|
||||||
velocity.x = stuff.value * 0.5;
|
velocity.x = stuff.value * 0.05;
|
||||||
position.x += velocity.x;
|
position.x += velocity.x * delta;
|
||||||
|
|
||||||
if (position.x + collider.offset.x > viewport.canvas.width - 16) {
|
if (position.x + collider.offset.x > viewport.canvas.width - 16) {
|
||||||
stuff.value = -1;
|
stuff.value = -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user