294 lines
6.7 KiB
C++
294 lines
6.7 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
#pragma once
|
|
|
|
#include "Core/Types.h"
|
|
#include "Math/MathConst.h"
|
|
#include "Math/Point.h"
|
|
|
|
namespace UE::CADKernel
|
|
{
|
|
/**
|
|
* Should be unified with the math utilities implemented by the Geometry team.
|
|
*/
|
|
class CADKERNEL_API FMatrixH
|
|
{
|
|
private:
|
|
double Matrix[16];
|
|
|
|
public:
|
|
|
|
static const FMatrixH Identity;
|
|
|
|
FMatrixH()
|
|
{
|
|
SetIdentity();
|
|
}
|
|
|
|
FMatrixH(const double* const InMatrix16)
|
|
{
|
|
for (int32 Index = 0; Index < 16; Index++)
|
|
{
|
|
Matrix[Index] = InMatrix16[Index];
|
|
}
|
|
}
|
|
|
|
FMatrixH(const double InMatrix44[][4])
|
|
{
|
|
for (int32 Row = 0; Row < 4; Row++)
|
|
{
|
|
for (int32 Column = 0; Column < 4; Column++)
|
|
{
|
|
Matrix[4 * Row + Column] = InMatrix44[Row][Column];
|
|
}
|
|
}
|
|
}
|
|
|
|
FMatrixH(const FVector& Origin, const FVector& Ox, const FVector& Oy, const FVector& Oz)
|
|
{
|
|
BuildChangeOfCoordinateSystemMatrix(Ox, Oy, Oz, Origin);
|
|
}
|
|
|
|
friend FArchive& operator<<(FArchive& Ar, FMatrixH& InMatrix)
|
|
{
|
|
Ar.Serialize(InMatrix.Matrix, 16 * sizeof(double));
|
|
return Ar;
|
|
}
|
|
|
|
void SetIdentity()
|
|
{
|
|
for (int32 Row = 0; Row < 4; Row++)
|
|
{
|
|
for (int32 Column = 0; Column < 4; Column++)
|
|
{
|
|
Get(Row, Column) = Row == Column ? 1. : 0.;
|
|
}
|
|
}
|
|
}
|
|
|
|
void FromAxisOrigin(const FVector& Axis, const FVector& Origin);
|
|
|
|
/**
|
|
* @param Xaxis the vector X of the old coordinate system in the new coordinate system
|
|
* @param Yaxis the vector Y of the old coordinate system in the new coordinate system
|
|
* @param Zaxis the vector Z of the old coordinate system in the new coordinate system
|
|
* @param Origin Origin of the old coordinate system in the new coordinate system
|
|
* @return the transform matrix
|
|
*/
|
|
void BuildChangeOfCoordinateSystemMatrix(const FVector& Xaxis, const FVector& Yaxis, const FVector& Zaxis, const FVector& Origin);
|
|
|
|
FVector Multiply(const FVector& InPoint) const
|
|
{
|
|
return FVector(
|
|
InPoint.X * Get(0, 0) + InPoint.Y * Get(0, 1) + InPoint.Z * Get(0, 2) + Get(0, 3),
|
|
InPoint.X * Get(1, 0) + InPoint.Y * Get(1, 1) + InPoint.Z * Get(1, 2) + Get(1, 3),
|
|
InPoint.X * Get(2, 0) + InPoint.Y * Get(2, 1) + InPoint.Z * Get(2, 2) + Get(2, 3)
|
|
);
|
|
}
|
|
|
|
FVector Multiply(const FVector2d& Point2D) const
|
|
{
|
|
return Multiply(FVector(Point2D, 0.));
|
|
}
|
|
|
|
FVector2d Multiply2D(const FVector2d& Point2D) const
|
|
{
|
|
const FVector Point = Multiply(FVector(Point2D, 0.));
|
|
return FVector2d(Point.X, Point.Y);
|
|
}
|
|
|
|
FVector MultiplyVector(const FVector& InVector) const
|
|
{
|
|
return FVector(
|
|
InVector.X * Get(0, 0) + InVector.Y * Get(0, 1) + InVector.Z * Get(0, 2),
|
|
InVector.X * Get(1, 0) + InVector.Y * Get(1, 1) + InVector.Z * Get(1, 2),
|
|
InVector.X * Get(2, 0) + InVector.Y * Get(2, 1) + InVector.Z * Get(2, 2)
|
|
);
|
|
}
|
|
|
|
FVector MultiplyVector(const FVector2d& Point2D) const
|
|
{
|
|
return MultiplyVector(FVector(Point2D, 0.));
|
|
}
|
|
|
|
FVector2d MultiplyVector2D(const FVector2d& Point2D) const
|
|
{
|
|
const FVector Point = MultiplyVector(FVector(Point2D, 0.));
|
|
return FVector2d(Point.X, Point.Y);
|
|
}
|
|
|
|
FVector3f MultiplyVector(const FVector3f& InVector) const
|
|
{
|
|
return FVector3f(
|
|
(float)(InVector.X * Get(0, 0) + InVector.Y * Get(0, 1) + InVector.Z * Get(0, 2)),
|
|
(float)(InVector.X * Get(1, 0) + InVector.Y * Get(1, 1) + InVector.Z * Get(1, 2)),
|
|
(float)(InVector.X * Get(2, 0) + InVector.Y * Get(2, 1) + InVector.Z * Get(2, 2))
|
|
);
|
|
}
|
|
|
|
static FMatrixH MakeRotationMatrix(double InAngle, const FVector InAxe);
|
|
|
|
static FMatrixH MakeTranslationMatrix(const FVector& InPoint);
|
|
|
|
static FMatrixH MakeScaleMatrix(FVector& Scale);
|
|
static FMatrixH MakeScaleMatrix(double ScaleX, double ScaleY, double ScaleZ);
|
|
|
|
/**
|
|
* Apply the rotation centered in origin to PointToRotate
|
|
*/
|
|
FVector PointRotation(const FVector& PointToRotate, const FVector& Origin) const
|
|
{
|
|
FVector Result = Origin;
|
|
for (int32 Index = 0; Index < 3; Index++)
|
|
{
|
|
for (int32 Jndex = 0; Jndex < 3; Jndex++)
|
|
{
|
|
Result[Index] += Get(Index, Jndex) * (PointToRotate[Jndex] - Origin[Jndex]);
|
|
}
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
FVector2d PointRotation(const FVector2d& PointToRotate, const FVector2d& Origin) const
|
|
{
|
|
FVector2d Result = Origin;
|
|
for (int32 Index = 0; Index < 2; Index++)
|
|
{
|
|
for (int32 Jndex = 0; Jndex < 2; Jndex++)
|
|
{
|
|
Result[Index] += Get(Index, Jndex) * (PointToRotate[Jndex] - Origin[Jndex]);
|
|
}
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
void Inverse();
|
|
|
|
FMatrixH GetInverse() const
|
|
{
|
|
FMatrixH NewMatrix = *this;
|
|
NewMatrix.Inverse();
|
|
return NewMatrix;
|
|
}
|
|
|
|
void Transpose()
|
|
{
|
|
FMatrixH Tmp = *this;
|
|
for (int32 Index = 0; Index < 4; Index++)
|
|
{
|
|
for (int32 Jndex = 0; Jndex < 4; Jndex++)
|
|
{
|
|
Get(Index, Jndex) = Tmp.Get(Jndex, Index);
|
|
}
|
|
}
|
|
}
|
|
|
|
double& Get(int32 Row, int32 Column)
|
|
{
|
|
return Matrix[Row * 4 + Column];
|
|
}
|
|
|
|
double Get(int32 Row, int32 Column) const
|
|
{
|
|
return Matrix[Row * 4 + Column];
|
|
}
|
|
|
|
double& operator()(int32 Row, int32 Column)
|
|
{
|
|
return Matrix[Row * 4 + Column];
|
|
}
|
|
|
|
double operator()(int32 Row, int32 Column) const
|
|
{
|
|
return Matrix[Row * 4 + Column];
|
|
}
|
|
|
|
double& operator[](int32 Index)
|
|
{
|
|
return Matrix[Index];
|
|
}
|
|
|
|
FMatrixH operator*(const FMatrixH& InMatrix) const
|
|
{
|
|
FMatrixH Result;
|
|
|
|
for (int32 Index = 0; Index < 4; Index++)
|
|
{
|
|
for (int32 Jndex = 0; Jndex < 4; Jndex++)
|
|
{
|
|
Result.Get(Index, Jndex) = 0;
|
|
for (int32 Kndex = 0; Kndex < 4; Kndex++)
|
|
{
|
|
Result.Get(Index, Jndex) = Result.Get(Index, Jndex) + (Get(Index, Kndex) * InMatrix.Get(Kndex, Jndex));
|
|
}
|
|
}
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
void operator*=(const FMatrixH& InMatrix)
|
|
{
|
|
FMatrixH Result = *this * InMatrix;
|
|
Move(*this, Result);
|
|
}
|
|
|
|
FVector operator*(const FVector& Point) const
|
|
{
|
|
return Multiply(Point);
|
|
}
|
|
|
|
FMatrixH operator+(const FMatrixH& InMatrix) const
|
|
{
|
|
FMatrixH Result;
|
|
for (int32 i = 0; i < 16; i++)
|
|
{
|
|
Result.Matrix[i] = Matrix[i] + InMatrix.Matrix[i];
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
void GetMatrixDouble(double* OutMatrix) const
|
|
{
|
|
memcpy(OutMatrix, Matrix, 16 * sizeof(double));
|
|
}
|
|
|
|
FVector Column(int32 Index) const
|
|
{
|
|
return FVector(Get(0, Index), Get(1, Index), Get(2, Index));
|
|
}
|
|
|
|
FVector Row(int32 Index) const
|
|
{
|
|
return FVector(Get(Index, 0), Get(Index, 1), Get(Index, 2));
|
|
}
|
|
|
|
void Print(EVerboseLevel level) const;
|
|
|
|
bool IsId() const
|
|
{
|
|
for (int32 Row = 0; Row < 4; Row++)
|
|
{
|
|
for (int32 Column = 0; Column < 4; Column++)
|
|
{
|
|
if (Row == Column)
|
|
{
|
|
if (!FMath::IsNearlyEqual(Get(Row, Column), 1.)) return false;
|
|
}
|
|
else
|
|
{
|
|
if (!FMath::IsNearlyZero(Get(Row, Column))) return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
CADKERNEL_API void InverseMatrixN(double* Matrix, int32 n);
|
|
|
|
CADKERNEL_API void MatrixProduct(int32 ARowNum, int32 AColumnNum, int32 ResultRank, const double* InMatrixA, const double* InMatrixB, double* OutMatrix);
|
|
|
|
CADKERNEL_API void TransposeMatrix(int32 RowNum, int32 ColumnNum, const double* InMatrix, double* OutMatrix);
|
|
|
|
} // namespace UE::CADKernel
|
|
|