📄 mm3d.pas
字号:
Result[2,0] := W.X;
Result[2,1] := W.Y;
Result[2,2] := W.Z;
end;
{-----------------------------------------------------------------------------}
function MM3DCreateCameraMatrix(const Origin, Front, Top: TMM3DVector): TMM3DMatrix4D;
var
QM, M : TMM3DMatrix4D;
begin
M := MM3DMatrixFromTranslation(MM3DVectorInvert(Origin));
QM := MM3DMatrixInvert(MM3DMatrixFromCameraOrientation(Front,Top));
M := MM3DMatrixMul(M,QM);
Result := M;
end;
{-----------------------------------------------------------------------------}
function MM3DVectorInvert(const V: TMM3DVector): TMM3DVector;
begin
with Result do
begin
x := -V.x;
y := -V.y;
z := -V.z;
end;
end;
{-----------------------------------------------------------------------------}
function MM3DMatrixInvert(const M: TMM3DMatrix4D): TMM3DMatrix4D;
var
D : TMM3DValue;
i, j: Integer;
begin
D := MM3DMatrixDeterminant(M);
for i := 0 to 3 do
for j := 0 to 3 do
Result[j,i] := MM3DMatrixCofactor(M, i, j)/D;
end;
{-----------------------------------------------------------------------------}
function MM3DMatrixDeterminant(const M: TMM3DMatrix4D): TMM3DValue;
begin
Result := M[0,0] * MM3DMatrixCofactor (M, 0, 0) +
M[0,1] * MM3DMatrixCofactor (M, 0, 1) +
M[0,2] * MM3DMatrixCofactor (M, 0, 2) +
M[0,3] * MM3DMatrixCofactor (M, 0, 3);
end;
{-----------------------------------------------------------------------------}
function MM3DMatrixCofactor(const M: TMM3DMatrix4D; i, j: Integer): TMM3DValue;
var
i0, i1, i2, j0, j1, j2: Integer;
Det: TMM3DValue;
begin
case i of
0: begin i0 := 1; i1 := 2; i2 := 3; end;
1: begin i0 := 0; i1 := 2; i2 := 3; end;
2: begin i0 := 0; i1 := 1; i2 := 3; end;
3: begin i0 := 0; i1 := 1; i2 := 2; end;
else
i0 := 0; i1 := 0; i2 := 0;
end;
case j of
0: begin j0 := 1; j1 := 2; j2 := 3; end;
1: begin j0 := 0; j1 := 2; j2 := 3; end;
2: begin j0 := 0; j1 := 1; j2 := 3; end;
3: begin j0 := 0; j1 := 1; j2 := 2; end;
else
j0 := 0; j1 := 0; j2 := 0;
end;
Det := M[i0,j0] * (M[i1,j1] * M[i2,j2] - M[i1,j2] * M[i2,j1]) -
M[i0,j1] * (M[i1,j0] * M[i2,j2] - M[i1,j2] * M[i2,j0]) +
M[i0,j2] * (M[i1,j0] * M[i2,j1] - M[i1,j1] * M[i2,j0]);
if Odd(i + j) then
Result := -Det
else
Result := Det;
end;
{-----------------------------------------------------------------------------}
function MM3DVectorDegToRad(const R: TMM3DVector): TMM3DVector;
begin
with Result do
begin
X := R.X/180*Pi;
Y := R.Y/180*Pi;
Z := R.Z/180*Pi;
end;
end;
{-----------------------------------------------------------------------------}
function MM3DVectorRadToDeg(const R: TMM3DVector): TMM3DVector;
begin
with Result do
begin
X := R.X/Pi*180;
Y := R.Y/Pi*180;
Z := R.Z/Pi*180;
end;
end;
{-----------------------------------------------------------------------------}
function MM3DDegToRad(D: TMM3DValue): TMM3DValue;
begin
Result := D/180*Pi;
end;
{-----------------------------------------------------------------------------}
function MM3DRadToDeg(R: TMM3DValue): TMM3DValue;
begin
Result := R/Pi*180;
end;
{-----------------------------------------------------------------------------}
function MM3DMatrixFromCameraOrientation(const Front, Top: TMM3DVector): TMM3DMatrix4D;
var
Axis: TMM3DVector;
A : TMM3DValue;
F, T: TMM3DVector;
M : TMM3DMatrix4D;
function Transf(const V: TMM3DVector; const M: TMM3DMatrix4D): TMM3DVector;
begin
Result := MM3DVector3D(MM3DVectorTransform(V,M));
end;
begin
F := MM3DVectorNormalize(Front);
T := MM3DVectorNormalize(Top);
// Put Y to its place
Axis := MM3DVectorCrossProduct(YUnit,T);
A := ArcCos(MM3DVectorDotProduct(YUnit,T));
if Round(A/Pi*180) > 178 then
begin
Axis := ZUnit;
end;
Result := MM3DMatrixFromRotation(Axis,A);
M := MM3DMatrixInvert(Result);
T := Transf(T,M);
F := MM3DVectorNormalize(Transf(F,M));
// Put Z to its place
Axis := MM3DVectorCrossProduct(ZUnit,F);
A := ArcCos(MM3DVectorDotProduct(ZUnit,F));
if Round(A/Pi*180) > 178 then
begin
Axis := YUnit;
end;
Result := MM3DMatrixMul(MM3DMatrixFromRotation(Axis,A),Result);
end;
{-----------------------------------------------------------------------------}
function MM3DVectorEqual(const V1, V2: TMM3DVector): Boolean;
begin
Result := GlobalCmpMem(V1,V2,SizeOf(V1));
end;
{== TMMVector3D =========================================================}
procedure TMMVector3D.SetComp(Index: Integer; Value: TMM3DValue);
begin
case Index of
0: if FVector.x <> Value then FVector.x := Value else Exit;
1: if FVector.y <> Value then FVector.y := Value else Exit;
2: if FVector.z <> Value then FVector.z := Value else Exit;
end;
Changed;
end;
{-- TMMVector3D ---------------------------------------------------------}
function TMMVector3D.GetComp(Index: Integer): TMM3DValue;
begin
Result := 0;
case Index of
0: Result := FVector.x;
1: Result := FVector.y;
2: Result := FVector.z;
end;
end;
{-- TMMVector3D ---------------------------------------------------------}
procedure TMMVector3D.SetAsVector(const Value: TMM3DVector);
begin
if not MM3DVectorEqual(FVector,Value) then
begin
FVector := Value;
Changed;
end;
end;
{-- TMMVector3D ---------------------------------------------------------}
procedure TMMVector3D.Assign(Source: TPersistent);
begin
if Source is TMMVector3D then
AsVector := (Source as TMMVector3D).AsVector
else
inherited Assign(Source);
end;
{== TMMMatrix3D ==============================================================}
procedure TMMMatrix3D.SetMatrix(const Value: TMM3DMatrix4D);
begin
FMatrix := Value;
Changed;
end;
{-- TMMMatrix3D --------------------------------------------------------------}
procedure TMMMatrix3D.WriteMatrix(Writer: TWriter);
var
i, j: Integer;
begin
Writer.WriteListBegin;
for i := 0 to 3 do
for j := 0 to 3 do
Writer.WriteFloat(FMatrix[i,j]);
Writer.WriteListEnd;
end;
{-- TMMMatrix3D --------------------------------------------------------------}
procedure TMMMatrix3D.ReadMatrix(Reader: TReader);
var
i, j: Integer;
begin
Reader.ReadListBegin;
for i := 0 to 3 do
for j := 0 to 3 do
FMatrix[i,j] := Reader.ReadFloat;
Reader.ReadListEnd;
end;
{-- TMMMatrix3D --------------------------------------------------------------}
function TMMMatrix3D.GetCell(Row, Col: Integer): TMM3DValue;
begin
Result := FMatrix[Row,Col];
end;
{-- TMMMatrix3D --------------------------------------------------------------}
procedure TMMMatrix3D.SetCell(Row, Col: Integer; Value: TMM3DValue);
begin
FMatrix[Row,Col] := Value;
Changed;
end;
{-- TMMMatrix3D --------------------------------------------------------------}
procedure TMMMatrix3D.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineProperty('Data',ReadMatrix,WriteMatrix,True);
end;
{-- TMMMatrix3D --------------------------------------------------------------}
function TMMMatrix3D.VectorTransform(const V: TMM3DVector): TMM3DVector4D;
begin
Result := MM3DVectorTransform(V,FMatrix);
end;
{-- TMMMatrix3D --------------------------------------------------------------}
function TMMMatrix3D.InverseVectorTransform(const V: TMM3DVector): TMM3DVector4D;
var
M: TMM3DMatrix4D;
begin
M := MM3DMatrixInvert(FMatrix);
Result := MM3DVectorTransform(V,M);
end;
{-- TMMMatrix3D --------------------------------------------------------------}
procedure TMMMatrix3D.Assign(Source: TPersistent);
begin
if Source is TMMMatrix3D then
AsMatrix := (Source as TMMMatrix3D).AsMatrix
else
inherited Assign(Source);
end;
initialization
White := MM3DCreateColorRGB(1,1,1);
Red := MM3DCreateColorRGB(0.5,0,0);
Green := MM3DCreateColorRGB(0,0.5,0);
Blue := MM3DCreateColorRGB(0,0,0.5);
LightRed := MM3DCreateColorRGB(1,0,0);
LightGreen := MM3DCreateColorRGB(0,1,0);
LightBlue := MM3DCreateColorRGB(0,0,1);
Yellow := MM3DCreateColorRGB(1,1,0);
Black := MM3DCreateColorRGB(0,0,0);
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -