UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SmoothProject.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4#include "Chaos/Defines.h"
6
7namespace Chaos {
8
9 template <class T>
11 const TConstArrayView<FVec3>& Points,
12 const TArray<TVec3<int32>>& Tris,
14 const FVec3& Pos,
15 const int32 TriIdx,
16 FVec3& Weights,
18 T* B,
19 T* C,
20 TVec3<T>& C0,
21 TVec3<T>& C1,
22 TVec3<T>& C2,
23 TVec3<T>& W0,
24 TVec3<T>& W1,
25 TVec3<T>& W2)
26 {
27 // Construct orthogonal tangents from point normal
28 for (int32 i = 0; i < 3; i++)
29 {
30 const int32 PtIdx = Tris[TriIdx][i];
32 TangentBases[i][0] = PointNormal.GetOrthogonalVector().GetSafeNormal();
33 TangentBases[i][1] = FVec3::CrossProduct(TangentBases[i][0], PointNormal);
34 }
35 // Solve
36 for (int32 i = 0; i < 3; i++)
37 {
38 for (int j = 0; j < 3; j++)
39 {
40 const int32 PtIdx = Tris[TriIdx][j];
41 const FVec3& Pt = Points[PtIdx];
42 const FVec3& TangentBase0 = TangentBases[i][0];
43 const FVec3& TangentBase1 = TangentBases[i][1];
44 FReal B0j = FVec3::DotProduct(TangentBase0, Pt);
45 FReal B1j = FVec3::DotProduct(TangentBase1, Pt);
46 RowMaj3x3Set(B, 0, j, static_cast<T>(B0j));
47 RowMaj3x3Set(B, 1, j, static_cast<T>(B1j));
48 RowMaj3x3Set(B, 2, j, static_cast<T>(1.0));
49 }
50 RowMaj3x3Inverse(B, B); // Sets B
51 FVec3 PV(
52 FVec3::DotProduct(TangentBases[i][0], Pos),
53 FVec3::DotProduct(TangentBases[i][1], Pos),
54 static_cast<T>(1.0));
56 }
57
58 RowMaj3x3Get(C, 0, 0) -= static_cast<T>(1.0);
59 RowMaj3x3Get(C, 1, 1) -= static_cast<T>(1.0);
60 RowMaj3x3Get(C, 2, 2) -= static_cast<T>(1.0);
61
62 RowMaj3x3GetRow(C, 0, C0);
63 RowMaj3x3GetRow(C, 1, C1);
64 RowMaj3x3GetRow(C, 2, C2);
65
66 W0 = FVec3::CrossProduct(C0, C1);
67 W1 = FVec3::CrossProduct(C0, C2);
68 W2 = FVec3::CrossProduct(C1, C2);
69
70 if (W0[0] >= 0.0 && W0[1] >= 0.0 && W0[2] >= 0.0)
71 {
72 Weights = W0;
73 }
74 else if (W1[0] >= 0.0 && W1[1] >= 0.0 && W1[2] >= 0.0)
75 {
76 Weights = W1;
77 }
78 else if (W2[0] >= 0.0 && W2[1] >= 0.0 && W2[2] >= 0.0)
79 {
80 Weights = W2;
81 }
82 else
83 {
84 // We're outside of the cone implied by the normals,
85 // so the projection doesn't exist.
86 return false;
87 }
88
89 FReal WeightsSum = Weights[0] + Weights[1] + Weights[2];
90 if (fabs(WeightsSum) < 1.0e-6)
91 {
92 // The point is at the vertex of the normal cone, so the
93 // projection isn't unique. Any face location will do.
94 static const T OneThird = static_cast<T>(1.0 / 3);
95 Weights = FVec3(OneThird, OneThird, OneThird);
96 return true;
97 }
98 Weights /= WeightsSum;
99 return true;
100 }
101
102 template <class T>
104 const TConstArrayView<FVec3>& Points,
105 const TArray<TVec3<int32>>& Tris,
107 const FVec3& Pos,
108 const int32 TriIdx,
109 FVec3& Weights)
110 {
113 for (int32 i = 0; i < 3; i++)
114 {
115 TangentBases[i].SetNum(2);
116 }
117 T B[9];
118 T C[9];
119 TVec3<T> C0;
120 TVec3<T> C1;
121 TVec3<T> C2;
122 TVec3<T> W0;
123 TVec3<T> W1;
124 TVec3<T> W2;
125
126 return SmoothProject(Points, Tris, PointNormals, Pos, TriIdx, Weights,
127 TangentBases, &B[0], &C[0], C0, C1, C2, W0, W1, W2);
128 }
129
130 template <class T>
132 const TConstArrayView<FVec3>& Points,
133 const TArray<TVec3<int32>>& Tris,
135 const FVec3& Pos,
136 const TArray<int32>& TriIdx,
137 TArray<FVec3>& Weights,
138 const bool UseFirstFound = false)
139 {
142 for (int32 i = 0; i < 3; i++)
143 {
144 TangentBases[i].SetNum(2);
145 }
146 T B[9];
147 T C[9];
148 TVec3<T> C0;
149 TVec3<T> C1;
150 TVec3<T> C2;
151 TVec3<T> W0;
152 TVec3<T> W1;
153 TVec3<T> W2;
154
157 Weights.SetNum(TriIdx.Num());
158 for (int i = 0; i < TriIdx.Num(); i++)
159 {
160 RetVal[i] = SmoothProject(Points, Tris, PointNormals, Pos, TriIdx[i], Weights[i],
161 TangentBases, &B[0], &C[0], C0, C1, C2, W0, W1, W2);
162 if (UseFirstFound && RetVal[i])
163 {
164 return RetVal;
165 }
166 }
167 return RetVal;
168 }
169
170} // namespace Chaos
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define W1
#define W2
Definition Vector.h:1000
Definition Array.h:670
void SetNumZeroed(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2340
void SetNum(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2308
Definition SkeletalMeshComponent.h:307
TV RowMaj3x3Multiply(const T *A, const TV &x)
Definition Poisson.h:159
void RowMaj3x3Inverse(const T Det, const T A0, const T A1, const T A2, const T A3, const T A4, const T A5, const T A6, const T A7, const T A8, T *Inv)
Definition Poisson.h:109
FRealDouble FReal
Definition Real.h:22
void RowMaj3x3SetCol(T *A, const int32 j, const T *Values)
Definition Poisson.h:66
TVector< FReal, 3 > FVec3
Definition Core.h:17
const T & RowMaj3x3Get(const T *A, const int32 i, const int32 j)
Definition Poisson.h:25
bool SmoothProject(const TConstArrayView< FVec3 > &Points, const TArray< TVec3< int32 > > &Tris, const TArray< FVec3 > &PointNormals, const FVec3 &Pos, const int32 TriIdx, FVec3 &Weights, TArray< TArray< FVec3 > > &TangentBases, T *B, T *C, TVec3< T > &C0, TVec3< T > &C1, TVec3< T > &C2, TVec3< T > &W0, TVec3< T > &W1, TVec3< T > &W2)
Definition SmoothProject.h:10
void RowMaj3x3Set(T *A, const int32 i, const int32 j, const T Value)
Definition Poisson.h:19
void RowMaj3x3GetRow(T *A, const int32 i, TV &Row)
Definition Poisson.h:55