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 { Rect } from "#/engine/Rect.ts";
|
||||
import $ from "#/engine/Scene.ts";
|
||||
import {
|
||||
createVector,
|
||||
getDotProduct,
|
||||
invScale,
|
||||
scale,
|
||||
type Vector,
|
||||
} from "#/engine/Vector.ts";
|
||||
import { createVector, invScale, type Vector, ZERO } from "#/engine/Vector.ts";
|
||||
|
||||
export enum Shape {
|
||||
Circle,
|
||||
@@ -418,6 +412,7 @@ function createCollision(): Collision {
|
||||
};
|
||||
}
|
||||
|
||||
const relVelocity = createVector();
|
||||
export function moveAndCollide(
|
||||
id: string,
|
||||
velocity: Vector,
|
||||
@@ -425,6 +420,7 @@ export function moveAndCollide(
|
||||
): Array<Collision> {
|
||||
const colliders = $<Collider>("collider")!;
|
||||
const positions = $<Vector>("position")!;
|
||||
const velocities = $<Vector>("velocity");
|
||||
const selfColl = colliders.get(id)!.value;
|
||||
const selfPos = positions.get(id)!.value;
|
||||
|
||||
@@ -438,13 +434,22 @@ export function moveAndCollide(
|
||||
|
||||
const otherColl = collider.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 tHit = sweptAABB(
|
||||
collision,
|
||||
selfColl,
|
||||
selfPos,
|
||||
velocity,
|
||||
relVelocity,
|
||||
otherColl,
|
||||
otherPos,
|
||||
delta,
|
||||
@@ -462,7 +467,7 @@ export function moveAndCollide(
|
||||
collision,
|
||||
selfColl,
|
||||
selfPos,
|
||||
velocity,
|
||||
relVelocity,
|
||||
otherColl,
|
||||
otherPos,
|
||||
delta,
|
||||
@@ -474,7 +479,7 @@ export function moveAndCollide(
|
||||
collision,
|
||||
selfColl,
|
||||
selfPos,
|
||||
velocity,
|
||||
relVelocity,
|
||||
otherColl,
|
||||
otherPos,
|
||||
delta,
|
||||
@@ -486,7 +491,7 @@ export function moveAndCollide(
|
||||
collision,
|
||||
selfColl,
|
||||
selfPos,
|
||||
velocity,
|
||||
relVelocity,
|
||||
otherColl,
|
||||
otherPos,
|
||||
delta,
|
||||
@@ -510,6 +515,7 @@ export function moveAndSlide(
|
||||
): void {
|
||||
let timeLeft = 1;
|
||||
const position = $<Vector>("position").get(id)!.value;
|
||||
const velocities = $<Vector>("velocity");
|
||||
|
||||
let i = 0;
|
||||
while (i++ < 4 && timeLeft > 0) {
|
||||
@@ -530,19 +536,18 @@ export function moveAndSlide(
|
||||
}
|
||||
|
||||
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;
|
||||
position.x += velocity.x * 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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user