add unoptimized pathfinding

This commit is contained in:
2024-12-25 00:32:33 +09:00
parent 47aade7b3f
commit 05360208b0
8 changed files with 353 additions and 37 deletions
+64 -5
View File
@@ -1,21 +1,41 @@
import SAT from 'sat'
import { Vector2 } from 'three'
import Entity from './entity.js'
export default class SATX {
static collideObject(collider1, collider2) {
static clamp(vectorOrObject, maxX = Infinity, maxY = Infinity, radius = 0) {
let modified = null
if (vectorOrObject instanceof Vector2) {
modified = vectorOrObject.clone()
}
else if (vectorOrObject instanceof SAT.Vector) {
modified = new SAT.Vector(vectorOrObject.x, vectorOrObject.y)
}
else {
modified = { x: vectorOrObject.x, y: vectorOrObject.y }
}
modified.x = Math.min(Math.max(radius, vectorOrObject.x), (maxX ?? Infinity) - radius)
modified.y = Math.min(Math.max(radius, vectorOrObject.y), (maxY ?? Infinity) - radius)
return modified
}
static collideObject(collider1, collider2, result = null) {
if (collider1 instanceof SAT.Circle && collider2 instanceof SAT.Circle) {
return SAT.testCircleCircle(collider1, collider2)
return SAT.testCircleCircle(collider1, collider2, result)
}
if (collider1 instanceof SAT.Circle && collider2 instanceof SAT.Polygon) {
return SAT.testCirclePolygon(collider1, collider2)
return SAT.testCirclePolygon(collider1, collider2, result)
}
if (collider1 instanceof SAT.Polygon && collider2 instanceof SAT.Circle) {
return SAT.testPolygonCircle(collider1, collider2)
return SAT.testPolygonCircle(collider1, collider2, result)
}
if (collider1 instanceof SAT.Polygon && collider2 instanceof SAT.Polygon) {
return SAT.testPolygonPolygon(collider1, collider2)
return SAT.testPolygonPolygon(collider1, collider2, result)
}
return false
@@ -24,4 +44,43 @@ export default class SATX {
static collideObjects(collider1, colliders) {
return colliders.some((c) => this.collideObject(collider1, c))
}
static enclosingRegularPolygonRadius(numberOfVertices) {
return 1 / Math.cos(Math.PI / numberOfVertices)
}
static entityTunnel(from, to, radius) {
const length = to.clone().sub(from)
const halfWidth = length.clone().normalize().multiplyScalar(radius).rotateAround(new Vector2(), Math.PI / 2)
const width = halfWidth.clone().multiplyScalar(2)
const origin = from.clone().sub(halfWidth)
const satPoints = [
new SAT.Vector(...origin.toArray()),
new SAT.Vector(...from.clone().sub(halfWidth).add(length).sub(origin).toArray()),
new SAT.Vector(...from.clone().sub(halfWidth).add(length.clone().add(width)).sub(origin).toArray()),
new SAT.Vector(...from.clone().sub(halfWidth).add(width).sub(origin).toArray()),
]
return new SAT.Polygon(satPoints[0], [new SAT.Vector(), ...satPoints.slice(1)])
}
static fixCollisions(entityPosition, colliders, radius = 0) {
const position = entityPosition.clone()
let collider = Entity.collider(position.x, position.y, radius)
colliders.forEach((c) => {
let result = new SAT.Response()
if (this.collideObject(collider, c, result)) {
position.sub(new Vector2(result.overlapV.x, result.overlapV.y))
collider = Entity.collider(position.x, position.y, radius)
}
})
return position
}
static polygonToThreeVector2(polygon) {
const position = new Vector2(polygon.pos.x, polygon.pos.y)
return polygon.points.map((p) => new Vector2(p.x, p.y).add(position))
}
}