[add] Added TriangleElement.
This commit is contained in:
parent
3d992ee73b
commit
928be56f10
@ -38,7 +38,8 @@ class Context {
|
|||||||
|
|
||||||
import sjplayer.BackgroundScheduledController,
|
import sjplayer.BackgroundScheduledController,
|
||||||
sjplayer.CircleElement,
|
sjplayer.CircleElement,
|
||||||
sjplayer.SquareElement;
|
sjplayer.SquareElement,
|
||||||
|
sjplayer.TriangleElement;
|
||||||
auto factories = tuple(
|
auto factories = tuple(
|
||||||
tuple(
|
tuple(
|
||||||
"actor",
|
"actor",
|
||||||
@ -61,6 +62,10 @@ class Context {
|
|||||||
"square",
|
"square",
|
||||||
SquareElementScheduledControllerFactory(programs, varstore),
|
SquareElementScheduledControllerFactory(programs, varstore),
|
||||||
),
|
),
|
||||||
|
tuple(
|
||||||
|
"triangle",
|
||||||
|
TriangleElementScheduledControllerFactory(programs, varstore),
|
||||||
|
),
|
||||||
tuple(
|
tuple(
|
||||||
"variable",
|
"variable",
|
||||||
VarStoreScheduledControllerFactory(varstore),
|
VarStoreScheduledControllerFactory(varstore),
|
||||||
|
@ -8,7 +8,8 @@ import sjplayer.Actor,
|
|||||||
sjplayer.Background,
|
sjplayer.Background,
|
||||||
sjplayer.CircleElement,
|
sjplayer.CircleElement,
|
||||||
sjplayer.PostEffect,
|
sjplayer.PostEffect,
|
||||||
sjplayer.SquareElement;
|
sjplayer.SquareElement,
|
||||||
|
sjplayer.TriangleElement;
|
||||||
|
|
||||||
///
|
///
|
||||||
class ProgramSet {
|
class ProgramSet {
|
||||||
@ -20,6 +21,7 @@ class ProgramSet {
|
|||||||
CircleElementProgram,
|
CircleElementProgram,
|
||||||
PostEffectProgram,
|
PostEffectProgram,
|
||||||
SquareElementProgram,
|
SquareElementProgram,
|
||||||
|
TriangleElementProgram,
|
||||||
);
|
);
|
||||||
|
|
||||||
///
|
///
|
||||||
|
83
sjplayer/src/sjplayer/TriangleElement.d
Normal file
83
sjplayer/src/sjplayer/TriangleElement.d
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/// 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);
|
@ -33,10 +33,6 @@ unittest {
|
|||||||
|
|
||||||
///
|
///
|
||||||
float CalculateDistance2LineSegment(vec2 a1, vec2 b1, vec2 a2, vec2 b2) {
|
float CalculateDistance2LineSegment(vec2 a1, vec2 b1, vec2 a2, vec2 b2) {
|
||||||
float cross2(vec2 v1, vec2 v2) {
|
|
||||||
return v1.x * v2.y - v1.y * v2.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a1 == b1) return CalculateDistanceOriginAndLineSegment(a2 - a1, b2 - a1);
|
if (a1 == b1) return CalculateDistanceOriginAndLineSegment(a2 - a1, b2 - a1);
|
||||||
if (a2 == b2) return CalculateDistanceOriginAndLineSegment(a1 - a2, b1 - a2);
|
if (a2 == b2) return CalculateDistanceOriginAndLineSegment(a1 - a2, b1 - a2);
|
||||||
|
|
||||||
@ -77,3 +73,8 @@ unittest {
|
|||||||
assert(CalculateDistance2LineSegment(
|
assert(CalculateDistance2LineSegment(
|
||||||
vec2(-1, 0), vec2(1, 0), vec2(2, 1), vec2(2, -1)).approxEqual(1f));
|
vec2(-1, 0), vec2(1, 0), vec2(2, 1), vec2(2, -1)).approxEqual(1f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
float cross2(vec2 v1, vec2 v2) {
|
||||||
|
return v1.x * v2.y - v1.y * v2.x;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user