using System;
// using JNGame.Collision2D;
using JNGame.Math;
// using Debug = JNGame.Logging.Debug;
namespace JNGame.PathFinding
{
///
/// 导航三角形在二叉空间分割树中的引用
/// 一个导航三角形可能会被树分割为多个三角形引用
///
public class TriangleRef
{
///
/// 当前三角形引用关联的导航三角形索引
///
public int index;
///
/// 三角形顶点A
///
public LVector2 vertexA;
///
/// 三角形顶点B
///
public LVector2 vertexB;
///
/// 三角形顶点C
///
public LVector2 vertexC;
///
/// 是否是分割的三角形
///
public bool IsSplit { get; private set; } = false;
///
/// 三角形的边框
///
public SplitLine[] borders;
///
/// 根据下标获取三角形的顶点,合法下标0/1/2
///
///
///
///
public LVector2 this[int index]
{
get
{
return index switch
{
0 => vertexA,
1 => vertexB,
2 => vertexC,
_ => throw new IndexOutOfRangeException("vector idx invalid" + index),
};
}
}
///
/// 根据原始导航三角形创建引用
/// 由此构造的三角形引用认为是未切割过的三角形
///
/// 原始的导航三角形
public TriangleRef(NavTriangle srcTriangle)
: this(srcTriangle.vertexA.ToLVector2XZ(), srcTriangle.vertexB.ToLVector2XZ(), srcTriangle.vertexC.ToLVector2XZ(), srcTriangle.index)
{ }
///
/// 根据分割的三个顶点和原始导航三角形创建引用
/// 由此构造的三角形引用认为是切割过的三角形
///
/// 三角形顶点A
/// 三角形顶点B
/// 三角形顶点C
/// 原始的导航三角形
public TriangleRef(in LVector2 vertexA, in LVector2 vertexB, in LVector2 vertexC, TriangleRef srcTriangle)
: this(vertexA, vertexB, vertexC, srcTriangle.index)
{
IsSplit = true;
}
///
/// 私有构造
///
/// 三角形顶点A
/// 三角形顶点B
/// 三角形顶点C
/// 引用的导航三角形索引
private TriangleRef(in LVector2 vertexA, in LVector2 vertexB, in LVector2 vertexC, int idx)
{
this.vertexA = vertexA;
this.vertexB = vertexB;
this.vertexC = vertexC;
index = idx;
borders = new SplitLine[]
{
new SplitLine(vertexA, vertexB),
new SplitLine(vertexB, vertexC),
new SplitLine(vertexC, vertexA)
};
//check valid
CheckValid();
}
///
/// 三角形三点不可重合
///
private void CheckValid()
{
for (int i = 0; i < 3; i++)
{
if (borders[i].Direction == LVector2.Zero)
{
// Debug.Assert(false);
}
}
}
///
/// 判断点是否在此三角形内
///
///
///
public bool Contain(in LVector2 pos)
{
// ABC三个顶点绕序为顺时针,三个叉积都需要为负,则点在三角形内
var isRightA = LVector2.Cross(vertexB - vertexA, pos - vertexA) > 0;
if (isRightA) return false;
var isRightB = LVector2.Cross(vertexC - vertexB, pos - vertexB) > 0;
if (isRightB) return false;
var isRightC = LVector2.Cross(vertexA - vertexC, pos - vertexC) > 0;
if (isRightC) return false;
return true;
}
}
}