EM_Task/UnrealEd/Private/Fbx/AdjacentInfo.cpp

143 lines
3.4 KiB
C++
Raw Permalink Normal View History

2026-02-13 16:18:33 +08:00
#include "AdjacentInfo.h"
// 索引相同的顶点是同一个点
bool operator==(const FAdjacentVertex& left, const FAdjacentVertex& right)
{
return left.Index() == right.Index();
}
// 只要边连接的两个顶点相同(顺序可以相反)就是同一个边
bool operator==(const FAdjacentEdge& left, const FAdjacentEdge& right)
{
return (left.V1() == right.V1() && left.V2() == right.V2()) || (left.V1() == right.V2() && left.V2() == right.V1());
}
void FAdjacentVertex::CalculateType()
{
// 是边界点
if (inBorder)
{
if (angle > 1.5f * PI)
{
type = 2.0f;
}
else if (angle < 0.5f * PI)
{
type = 3.0f;
}
else
{
type = 1.0f;
}
}
else
{
type = 0.0f;
}
}
void FAdjacentVertex::CalculateSoftNormalByAdjVertice()
{
if (!inBorder)
return;
uint32 innerAdjVerticeCount = 0;
for (FAdjacentVertex* v: adjVertice)
if (!v->inBorder)
++innerAdjVerticeCount;
softNormal = FVector::ZeroVector;
// 如果相邻顶点有内部顶点,使用内部顶点方向
if (innerAdjVerticeCount)
{
for (FAdjacentVertex* v: adjVertice)
{
if (!v->inBorder)
{
FVector dir = pos - v->pos;
dir.Normalize();
softNormal += dir;
}
}
}
else
{
for (FAdjacentVertex* v: adjVertice)
{
FVector dir = pos - v->pos;
dir.Normalize();
softNormal += dir;
}
}
softNormal.Normalize();
}
void FAdjacentVertex::ProjectSoftNormalOnNormalPlane()
{
normal.Normalize();
if (inBorder)
{
softNormal.Normalize();
softNormal -= FVector::DotProduct(normal, softNormal) * normal;
softNormal.Normalize();
}
}
FAdjacentEdge::FAdjacentEdge(FAdjacentVertex& v1, FAdjacentVertex& v2): v1(v1), v2(v2), count(1)
{
length = (v1.Pos() - v2.Pos()).Size();
}
void FAdjacentEdge::SetInBorder()
{
v1.InBorder() = true;
v2.InBorder() = true;
}
void FAdjacentEdge::AddVertexToEdge()
{
v1.AdjVertice().Add(&v2);
v2.AdjVertice().Add(&v1);
}
FAdjacentPolygon::FAdjacentPolygon(const TArray<FAdjacentVertex*>& Vertices, const TArray<FAdjacentEdge*>& Edges, int32 N)
: v(Vertices), e(Edges), n(N)
{
// 计算面法线
FVector dirAB = V(1).Pos() - V(0).Pos();
FVector dirBC = V(2).Pos() - V(1).Pos();
normal = FVector::CrossProduct(dirAB, dirBC);
normal.Normalize();
}
void FAdjacentPolygon::CalculateVertexNormal()
{
// 对于三角形的每个顶点,计算该顶点角度和方向
for (int i = 0; i < n; ++i)
{
// 顶点
FAdjacentVertex& A = V(i);
FAdjacentVertex& B = V((i - 1 + n) % n);
FAdjacentVertex& C = V((i + 1) % n);
FVector dirBA = A.Pos() - B.Pos();
FVector dirCA = A.Pos() - C.Pos();
dirBA.Normalize();
dirCA.Normalize();
float cosA = FVector::DotProduct(dirBA, dirCA);
// 顶点A的角度
float angle = FMath::Acos(cosA);
FVector vNormal = normal * angle;
A.Normal() += vNormal;
if (A.InBorder()) // 边界顶点 计算边界延伸方向
{
// angle为权重
A.SoftNormal() += (dirBA + dirCA).GetUnsafeNormal() * angle;
}
A.Angle() += angle;
}
}