개요
삼각형 내부에 새로운 정점을 삽입하여 1개의 삼각형을 3개로 분할한다.

Input
| 타입 | 매개변수 | 설명 |
|---|---|---|
| int | TriangleID | 분할할 삼각형의 ID |
| FVector3d | BaryCoordinates | 새 정점의 무게중심 좌표 (w1, w2, w3) |
분할할 삼각형의 ID와 무게중심 좌표를 입력받는다.
Output
| 타입 | 매개변수 | 설명 |
|---|---|---|
| FPokeTriangleInfo& | PokeResult | 분할 결과 정보를 저장할 출력 구조체 |
삼각형을 분할, FPokeTriangleInfo를 반환한다.
알고리즘
유효성 검사
if ( !IsTriangle( TriangleID ) )
{
return EMeshResult::Failed_NotATriangle;
}삼각형 ID가 유효한지 확인한다.
정점 정보 수집
FIndex3i tv = GetTriangle( TriangleID ); // 정점 [A, B, C]
FIndex3i te = GetTriEdges( TriangleID ); // 엣지 [eAB, eBC, eCA]
// 무게중심 좌표로 새 정점의 속성 보간
FVertexInfo vinfo;
GetTriBaryPoint( TriangleID, BaryCoordinates[ 0 ], BaryCoordinates[ 1 ], BaryCoordinates[ 2 ], vinfo );
int center = AppendVertex( vinfo );FDynamicMesh3::GetTriBaryPoint()를 통해 정점 정보를 수집힌다.
새 엣지 생성
중심점(P)에서 각 꼭짓점으로 3개 엣지 생성:
// A-P, B-P, C-P 엣지 생성 (삼각형 연결은 아직 안 함)
int eaC = AddEdgeInternal( tv[ 0 ], center, -1, -1 ); // A-P
int ebC = AddEdgeInternal( tv[ 1 ], center, -1, -1 ); // B-P
int ecC = AddEdgeInternal( tv[ 2 ], center, -1, -1 ); // C-P
// 정점 참조 카운트 증가
VertexRefCounts.Increment( tv[ 0 ] ); // A
VertexRefCounts.Increment( tv[ 1 ] ); // B
VertexRefCounts.Increment( tv[ 2 ] ); // C
VertexRefCounts.Increment( center, 3 ); // P는 3개 삼각형에 사용삼각형 재구성
원본 삼각형 재활용 (첫 번째 조각)
// ABC → ABP로 변경
SetTriangleInternal( TriangleID, tv[ 0 ], tv[ 1 ], center );
SetTriangleEdgesInternal( TriangleID, te[ 0 ], ebC, eaC );
// 정점: [A, B, P]
// 엣지: [eAB(원본), eBP(새), ePA(새)]새 삼각형 2개 추가
// 두 번째 조각: BCP
int t1 = AddTriangleInternal( tv[ 1 ], tv[ 2 ], center, te[ 1 ], ecC, ebC );
// 정점: [B, C, P]
// 엣지: [eBC(원본), eCP(새), ePB(새)]
// 세 번째 조각: CAP
int t2 = AddTriangleInternal( tv[ 2 ], tv[ 0 ], center, te[ 2 ], eaC, ecC );
// 정점: [C, A, P]
// 엣지: [eCA(원본), eAP(새), ePC(새)]엣지-삼각형 관계 업데이트
원본 엣지 수정
// eBC는 이제 OriginalTri 대신 t1에 속함
ReplaceEdgeTriangle( te[ 1 ], TriangleID, t1 );
// eCA는 이제 OriginalTri 대신 t2에 속함
ReplaceEdgeTriangle( te[ 2 ], TriangleID, t2 );새 엣지에 삼각형 연결
// eAP: OriginalTri(ABP)와 t2(CAP)에 공유
SetEdgeTrianglesInternal( eaC, TriangleID, t2 );
// eBP: OriginalTri(ABP)와 t1(BCP)에 공유
SetEdgeTrianglesInternal( ebC, TriangleID, t1 );
// eCP: t1(BCP)와 t2(CAP)에 공유
SetEdgeTrianglesInternal( ecC, t1, t2 );삼각형 그룹 복사
if ( HasTriangleGroups() )
{
int g = TriangleGroups.GetValue()[ TriangleID ];
TriangleGroups->InsertAt( g, t1 );
TriangleGroups->InsertAt( g, t2 );
}원본 삼각형의 그룹 ID를 새 삼각형들에도 적용한다.
결과 정보 저장
PokeResult.OriginalTriangle = TriangleID;
PokeResult.TriVertices = tv; // [A, B, C]
PokeResult.NewVertex = center; // P
PokeResult.NewTriangles = FIndex2i( t1, t2 ); // [BCP, CAP]
PokeResult.NewEdges = FIndex3i( eaC, ebC, ecC ); // [AP, BP, CP]
PokeResult.BaryCoords = BaryCoordinates;어트리뷰트 업데이트 & 완료
// UV, 노멀 등 오버레이 어트리뷰트 업데이트
if ( HasAttributes() )
{
Attributes()->OnPokeTriangle( PokeResult );
}
// 메시 변경 스탬프 업데이트
UpdateChangeStamps( true, true );
return EMeshResult::Ok;