001a16cf32
feat: add new logic EC_World.
167 lines
5.4 KiB
C#
167 lines
5.4 KiB
C#
using CSNetwork.GPDataType;
|
|
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace BrewMonster.Scripts
|
|
{
|
|
public class CHalfSpace
|
|
{
|
|
public static float DistThresh; //空间一顶点到halfspace平面的距离阈值,作为判断是在半空间内部、外部,or 边界上
|
|
//该阈值属于整个类而不是某一个对象,因此定义为静态成员
|
|
//根据三个顶点构造平面及半空间区域
|
|
//Attributes
|
|
public const float HS_DEFAULT_DISTTHRESH = 0.000001f; //距离差的阈值,作为判断是在半空间内部or边界上
|
|
|
|
protected A3DVECTOR3 m_vNormal;
|
|
protected float m_d;
|
|
|
|
public void Set(A3DVECTOR3 v1, A3DVECTOR3 v2)
|
|
{
|
|
m_vNormal = A3DVECTOR3.CrossProduct(v2 - v1, new A3DVECTOR3(0.0f, 0.0f, 1.0f));
|
|
m_vNormal.Normalize();
|
|
m_d = A3DVECTOR3.DotProduct(v1, m_vNormal);
|
|
}
|
|
public void Set(A3DVECTOR3 v1, A3DVECTOR3 v2, A3DVECTOR3 v3)
|
|
{
|
|
m_vNormal = A3DVECTOR3.CrossProduct(v2 - v1, v3 - v1);
|
|
m_vNormal.Normalize();
|
|
m_d = A3DVECTOR3.DotProduct(v1, m_vNormal);
|
|
}
|
|
|
|
//直接设置法向
|
|
public void SetNormal(A3DVECTOR3 n) { m_vNormal = n; m_vNormal.Normalize(); }
|
|
|
|
public float GetDist() { return m_d; }
|
|
|
|
//直接设置距离d
|
|
public void SetD(float d) { m_d = d; }
|
|
|
|
public CHalfSpace(A3DVECTOR3 v1, A3DVECTOR3 v2, A3DVECTOR3 v3)
|
|
{
|
|
Set(v1, v2, v3);
|
|
|
|
}
|
|
//根据两个顶点构造平行于Z轴的平面及半空间区域
|
|
public CHalfSpace(A3DVECTOR3 v1, A3DVECTOR3 v2)
|
|
{
|
|
Set(v1, v2);
|
|
}
|
|
public CHalfSpace()
|
|
{
|
|
|
|
}
|
|
|
|
public CHalfSpace(CHalfSpace hs)
|
|
{
|
|
m_vNormal = hs.m_vNormal;
|
|
m_d = hs.m_d;
|
|
}
|
|
|
|
// 对决定Halfspace的平面进行变换!变换矩阵为mtxTrans
|
|
public virtual void Transform(A3DMATRIX4 mtxTrans)
|
|
{
|
|
//从mtxTrans分解出Scale,Rotate,Translate分量
|
|
A3DVECTOR3 vTranslate = mtxTrans.GetRow(3);
|
|
float fScale = mtxTrans.GetCol(0).Magnitude();
|
|
|
|
// 与mtxTrans一样,仍定义为右乘矩阵
|
|
A3DMATRIX3 mtx3Rotate = new A3DMATRIX3();
|
|
mtx3Rotate.m = new float[3 * 3];
|
|
for (int i = 0; i < 3; i++)
|
|
for (int j = 0; j < 3; j++)
|
|
mtx3Rotate.m[(i * 3) + j] = mtxTrans.m[(i * 4) + j] / fScale;
|
|
|
|
//对于平面方程N.X=D的变换(s,R,t)如下:
|
|
|
|
// N'=NR
|
|
SetNormal(m_vNormal * mtx3Rotate);
|
|
|
|
//D'=s*D+N'.t
|
|
SetD(fScale * m_d + A3DVECTOR3.DotProduct(m_vNormal, vTranslate));
|
|
}
|
|
|
|
public void Translate(float Delta) { m_d += Delta; } //沿法线方向作一个平移
|
|
public void Inverse() { m_d = -m_d; m_vNormal = -m_vNormal; } //翻转半空间的正反方向
|
|
|
|
//点v到半空间定义平面的距离,此距离带符号!
|
|
public float DistV2Plane(A3DVECTOR3 v)
|
|
{
|
|
float d = A3DVECTOR3.DotProduct(v, m_vNormal);
|
|
return (d - m_d);
|
|
}
|
|
|
|
//与线段求交
|
|
public int IntersectLineSeg(A3DVECTOR3 v1, A3DVECTOR3 v2, A3DVECTOR3 vIntersection)
|
|
{
|
|
vIntersection = new A3DVECTOR3(0.0f, 0.0f, 0.0f);
|
|
//先处理在平面上的情况
|
|
bool v1InPlane = OnPlane(v1);
|
|
bool v2InPlane = OnPlane(v2);
|
|
if (v1InPlane && v2InPlane) return 3;
|
|
if (v1InPlane) return 1;
|
|
if (v2InPlane) return 2;
|
|
|
|
if (Outside(v1) ^ Outside(v2))
|
|
{
|
|
//两顶点分别在两侧,计算交点
|
|
A3DVECTOR3 vd = v2 - v1;
|
|
float t = m_d - A3DVECTOR3.DotProduct(m_vNormal, v1);
|
|
t /= A3DVECTOR3.DotProduct(m_vNormal, vd);
|
|
//assert(t < 1.0f && t > 0.0f);
|
|
vIntersection = v1 + t * vd;
|
|
|
|
return 4;
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// 判断一个三维点是否处于半空间内部,或者说处于平面的一侧
|
|
// 注意halfspace的OutSide,Inside定义方式
|
|
// /\
|
|
// /||\
|
|
// ||
|
|
// || normal (Outside)
|
|
//------------------------------------------Plane
|
|
// (Inside)
|
|
//
|
|
public bool Inside(A3DVECTOR3 v)
|
|
{
|
|
float d = A3DVECTOR3.DotProduct(v, m_vNormal);
|
|
bool bInside = (m_d - d > DistThresh);
|
|
return (bInside);
|
|
}
|
|
public bool Outside(A3DVECTOR3 v)
|
|
{
|
|
float d = A3DVECTOR3.DotProduct(v, m_vNormal);
|
|
bool bOutside = (d - m_d > DistThresh);
|
|
return (bOutside);
|
|
}
|
|
public bool OnPlane(A3DVECTOR3 v)
|
|
{
|
|
float d = A3DVECTOR3.DotProduct(v, m_vNormal);
|
|
bool bOnPlane = (Math.Abs(m_d - d) <= DistThresh);
|
|
return bOnPlane;
|
|
}
|
|
|
|
//set && get operations
|
|
public static void SetDistThresh(float DThresh = HS_DEFAULT_DISTTHRESH) //并设定一个缺省值
|
|
{
|
|
DistThresh = DThresh;
|
|
}
|
|
|
|
public A3DVECTOR3 GetNormal() { return m_vNormal; }
|
|
|
|
//点法式
|
|
public void SetNV(A3DVECTOR3 n, A3DVECTOR3 v)
|
|
{
|
|
m_vNormal = n;
|
|
m_vNormal.Normalize();
|
|
m_d = A3DVECTOR3.DotProduct(m_vNormal, v);
|
|
}
|
|
|
|
}
|
|
}
|