Fix collision detection
This commit is contained in:
parent
006ab3c4e6
commit
5b4e67cbf0
2 changed files with 169 additions and 49 deletions
|
|
@ -36,6 +36,6 @@ export class Circle implements IShape {
|
|||
}
|
||||
|
||||
public clone(): Circle {
|
||||
return new Circle(this.center, this.radius);
|
||||
return new Circle(vec2.clone(this.center), this.radius);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { BoundingBox } from '../bounding-box';
|
|||
import { clamp01 } from '../../helper/clamp';
|
||||
import { mix } from '../../helper/mix';
|
||||
import { IShape } from '../i-shape';
|
||||
import { rotate90Deg } from '../../helper/rotate-90-deg';
|
||||
|
||||
export class TunnelShape implements IShape {
|
||||
public readonly isInverted = true;
|
||||
|
|
@ -39,8 +40,49 @@ export class TunnelShape implements IShape {
|
|||
return new BoundingBox(this, xMin, xMax, yMin, yMax);
|
||||
}
|
||||
|
||||
public normal(from: vec2): vec2 {
|
||||
throw new Error('Unimplemented');
|
||||
public normal(target: vec2): vec2 {
|
||||
const targetFromDelta = vec2.subtract(vec2.create(), target, this.from);
|
||||
|
||||
const h = clamp01(
|
||||
vec2.dot(targetFromDelta, this.toFromDelta) /
|
||||
vec2.dot(this.toFromDelta, this.toFromDelta)
|
||||
);
|
||||
|
||||
let diff = vec2.create();
|
||||
|
||||
if (h == 1) {
|
||||
vec2.subtract(diff, target, this.to);
|
||||
} else if (h == 0) {
|
||||
vec2.subtract(diff, target, this.from);
|
||||
} else {
|
||||
const side = Math.sign(
|
||||
this.toFromDelta.x * targetFromDelta.y -
|
||||
this.toFromDelta.y * targetFromDelta.x
|
||||
);
|
||||
|
||||
const normal = rotate90Deg(this.toFromDelta);
|
||||
vec2.normalize(normal, normal);
|
||||
|
||||
const translatedFrom = vec2.add(
|
||||
vec2.create(),
|
||||
this.from,
|
||||
vec2.scale(vec2.create(), normal, side * this.fromRadius)
|
||||
);
|
||||
|
||||
const translatedTo = vec2.add(
|
||||
vec2.create(),
|
||||
this.to,
|
||||
vec2.scale(vec2.create(), normal, side * this.toRadius)
|
||||
);
|
||||
|
||||
diff = rotate90Deg(
|
||||
vec2.subtract(vec2.create(), translatedTo, translatedFrom)
|
||||
);
|
||||
|
||||
vec2.scale(diff, diff, side);
|
||||
}
|
||||
|
||||
return vec2.normalize(diff, diff);
|
||||
}
|
||||
|
||||
public distance(target: vec2): number {
|
||||
|
|
@ -60,6 +102,11 @@ export class TunnelShape implements IShape {
|
|||
}
|
||||
|
||||
public clone(): TunnelShape {
|
||||
return new TunnelShape(this.from, this.to, this.fromRadius, this.toRadius);
|
||||
return new TunnelShape(
|
||||
vec2.clone(this.from),
|
||||
vec2.clone(this.to),
|
||||
this.fromRadius,
|
||||
this.toRadius
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue