This repository has been archived on 2022-05-21. You can view files and clone it, but cannot push or open issues or pull requests.
shapes-juke/sjplayer/src/sjplayer/TriangleElement.d

84 lines
2.2 KiB
D

/// License: MIT
module sjplayer.TriangleElement;
import std.algorithm,
std.math,
std.typecons;
import gl4d;
import sjplayer.AbstractShapeElement,
sjplayer.ElementInterface,
sjplayer.ShapeElementDrawer,
sjplayer.ShapeElementProgram,
sjplayer.ShapeElementScheduledController,
sjplayer.util.linalg;
///
class TriangleElement : AbstractShapeElement {
public:
override DamageCalculationResult CalculateDamage(vec2 p1, vec2 p2) const {
if (!alive) return DamageCalculationResult(0, 0);
const m = matrix.inverse;
const a = (m * vec3(p1, 1)).xy;
const b = (m * vec3(p2, 1)).xy;
enum A = vec2( 0, sqrt(3f)*2f/3f);
enum B = vec2(-1, -sqrt(3f) /3f);
enum C = vec2( 1, -sqrt(3f) /3f);
bool CheckInside(vec2 pt) {
return
cross2(B-A, pt-A) >= 0 && cross2(pt-A, C-A) >= 0 && cross2(C-B, pt-B) >= 0;
}
if (CheckInside(a) || CheckInside(b)) {
return DamageCalculationResult(damage, 0);
}
enum edges = [
tuple(A, B),
tuple(A, C),
tuple(B, C),
];
float[3] distances;
static foreach (i, edge; edges) {
distances[i] = CalculateDistance2LineSegment(edge[0], edge[1], a, b);
}
const min_distance = distances[].minElement;
if (min_distance == 0) {
return DamageCalculationResult(damage, 0);
}
return DamageCalculationResult(0, 1-(min_distance-1).clamp(0f, 1f));
}
}
///
alias TriangleElementDrawer = ShapeElementDrawer!(
TriangleElementProgram,
[vec2(-1, 1.2), vec2(-1, -1), vec2(1, -1), vec2(1, 1.2)]);
///
alias TriangleElementProgram = ShapeElementProgram!(q{
vec2 A = vec2( 0, sqrt(3)*2/3);
vec2 B = vec2(-1, -sqrt(3) /3);
vec2 C = vec2( 1, -sqrt(3) /3);
vec2 AB = B - A;
vec2 AC = C - A;
vec2 BC = C - B;
float cross_AB = AB.x * (uv_.y - A.y) - AB.y * (uv_.x - A.x);
float cross_AC = (uv_.x - A.x) * AC.y - (uv_.y - A.y) * AC.x;
float cross_BC = BC.x * (uv_.y - B.y) - BC.y * (uv_.x - B.x);
return step(0, cross_AB) * step(0, cross_AC) * step(0, cross_BC);
});
///
alias TriangleElementScheduledControllerFactory =
ShapeElementScheduledControllerFactory!(
TriangleElement,
TriangleElementDrawer);