MM3D.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:30k
- {========================================================================}
- {= (c) 1995-98 SwiftSoft Ronald Dittrich =}
- {========================================================================}
- {= All Rights Reserved =}
- {========================================================================}
- {= D 01099 Dresden = Fax.: +49 (0)351-8037944 =}
- {= Loewenstr.7a = info@swiftsoft.de =}
- {========================================================================}
- {= Actual versions on http://www.swiftsoft.de/mmtools.html =}
- {========================================================================}
- {= This code is for reference purposes only and may not be copied or =}
- {= distributed in any format electronic or otherwise except one copy =}
- {= for backup purposes. =}
- {= =}
- {= No Delphi Component Kit or Component individually or in a collection=}
- {= subclassed or otherwise from the code in this unit, or associated =}
- {= .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed =}
- {= without express permission from SwiftSoft. =}
- {= =}
- {= For more licence informations please refer to the associated =}
- {= HelpFile. =}
- {========================================================================}
- {= $Date: 31.07.98 - 23:35:59 $ =}
- {========================================================================}
- unit MM3D;
- {$I COMPILER.INC}
- {.$DEFINE _DEBUG}
- interface
- uses
- Classes,
- SysUtils,
- Windows,
- Graphics,
- MMObj;
- type
- FLOAT3D = Extended;
- {$IFDEF CBUILDER3} {$EXTERNALSYM LONG} {$ENDIF}
- LONG = LongInt;
- {$IFDEF CBUILDER3} {$EXTERNALSYM PVOID} {$ENDIF}
- PVOID = Pointer;
- PMM3DColor = ^TMM3DColor;
- TMM3DColor = DWORD;
- PMM3DValue = ^TMM3DValue;
- TMM3DValue = FLOAT3D;
- PMM3DVector = ^TMM3DVector;
- TMM3DVector = record
- case Byte of
- 0: (x, y, z: TMM3DValue);
- 1: (dvX, dvY, dvZ: TMM3DValue);
- 2: (Values: array [0..2] of TMM3DValue);
- end;
- PMM3DVector4D = ^TMM3DVector4D;
- TMM3DVector4D = record
- x, y, z, w : TMM3DValue;
- end;
- PMM3DQuaternion = ^TMM3DQuaternion;
- TMM3DQuaternion = record
- s : TMM3DValue;
- v : TMM3DVector;
- end;
- PMM3DMatrix4D = ^TMM3DMatrix4D;
- TMM3DMatrix4D = array[0..3,0..3] of TMM3DValue;
- TMM3DProjectionType = (ptPerspective,ptOrthographic);
- type
- {-- TMM3DMatrix --------------------------------------------------------------}
- TMMMatrix3D = class(TMMObject)
- private
- FMatrix : TMM3DMatrix4D;
- procedure SetMatrix(const Value: TMM3DMatrix4D);
- procedure WriteMatrix(Writer: TWriter);
- procedure ReadMatrix(Reader: TReader);
- function GetCell(Row, Col: Integer): TMM3DValue;
- procedure SetCell(Row, Col: Integer; Value: TMM3DValue);
- protected
- procedure DefineProperties(Filer: TFiler); override;
- public
- function VectorTransform(const V: TMM3DVector): TMM3DVector4D;
- function InverseVectorTransform(const V: TMM3DVector): TMM3DVector4D;
- procedure Assign(Source: TPersistent); override;
- {$IFDEF CBUILDER3} {$EXTERNALSYM TMMMatrix3D.AsMatrix} {$ENDIF}
- property AsMatrix : TMM3DMatrix4D read FMatrix write SetMatrix;
- property Cell[Row,Col: Integer] : TMM3DValue read GetCell write SetCell; default;
- end;
- {-- TMM3DVector --------------------------------------------------------------}
- TMMVector3D = class(TMMObject)
- private
- FVector : TMM3DVector;
- procedure SetComp(Index: Integer; Value: TMM3DValue);
- function GetComp(Index: Integer): TMM3DValue;
- procedure SetAsVector(const Value: TMM3DVector);
- public
- procedure Assign(Source: TPersistent); override;
- property AsVector : TMM3DVector read FVector write SetAsVector;
- published
- property X: TMM3DValue index 0 read GetComp write SetComp;
- property Y: TMM3DValue index 1 read GetComp write SetComp;
- property Z: TMM3DValue index 2 read GetComp write SetComp;
- end;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DCreateColorRGB} {$ENDIF}
- function MM3DCreateColorRGB(red, green, blue: TMM3DValue): TMM3DColor;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DCreateColorRGBA} {$ENDIF}
- function MM3DCreateColorRGBA(red, green, blue, alpha: TMM3DValue): TMM3DColor;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DColorGetRed} {$ENDIF}
- function MM3DColorGetRed(color: TMM3DColor): TMM3DValue;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DColorGetGreen} {$ENDIF}
- function MM3DColorGetGreen(color: TMM3DColor): TMM3DValue;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DColorGetBlue} {$ENDIF}
- function MM3DColorGetBlue(color: TMM3DColor): TMM3DValue;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DColorGetAlpha} {$ENDIF}
- function MM3DColorGetAlpha(color: TMM3DColor): TMM3DValue;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DBuildRGBColor} {$ENDIF}
- function MM3DBuildRGBColor(color: TMM3DColor): TColor;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorAdd} {$ENDIF}
- function MM3DVectorAdd(const s1, s2: TMM3DVector): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorSubtract} {$ENDIF}
- function MM3DVectorSubtract(const s1, s2: TMM3DVector): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorReflect} {$ENDIF}
- function MM3DVectorReflect(const ray, normal: TMM3DVector): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorCrossProduct} {$ENDIF}
- function MM3DVectorCrossProduct(const s1, s2: TMM3DVector): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorDotProduct} {$ENDIF}
- function MM3DVectorDotProduct(const s1, s2: TMM3DVector): TMM3DValue;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorNormalize} {$ENDIF}
- function MM3DVectorNormalize(const v: TMM3DVector): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorNormalise} {$ENDIF}
- function MM3DVectorNormalise(const v: TMM3DVector): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorModulus} {$ENDIF}
- function MM3DVectorModulus(const v: TMM3DVector): TMM3DValue;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorRotate} {$ENDIF}
- function MM3DVectorRotate(const v, axis: TMM3DVector; theta: TMM3DValue): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorScale} {$ENDIF}
- function MM3DVectorScale(const s: TMM3DVector; factor: TMM3DValue): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorRandom} {$ENDIF}
- function MM3DVectorRandom: TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DQuaternionFromRotation} {$ENDIF}
- function MM3DQuaternionFromRotation(const v: TMM3DVector; theta: TMM3DValue): TMM3DQuaternion;
- //function MM3DQuaternionMultiply(const a, b: TMM3DQuaternion): TMM3DQuaternion;
- //function MM3DQuaternionSlerp(const a, b: TMM3DQuaternion; alpha: TMM3DValue): TMM3DQuaternion;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DMatrixFromQuaternion} {$ENDIF}
- function MM3DMatrixFromQuaternion(const q: TMM3DQuaternion): TMM3DMatrix4D;
- { NOTE: Not all functions listed below work properly }
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVector} {$ENDIF}
- function MM3DVector(x, y, z: TMM3DValue): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorRotateQ} {$ENDIF}
- function MM3DVectorRotateQ(const v: TMM3DVector; const q: TMM3DQuaternion): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorTransform} {$ENDIF}
- function MM3DVectorTransform(const v: TMM3DVector; const Mat: TMM3DMatrix4D): TMM3DVector4D;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVector3D} {$ENDIF}
- function MM3DVector3D(const v: TMM3DVector4D): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DCreateViewportMatrix} {$ENDIF}
- function MM3DCreateViewportMatrix(Front: TMM3DValue; Proj: TMM3DProjectionType): TMM3DMatrix4D;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DMatrixMul} {$ENDIF}
- function MM3DMatrixMul(const M1, M2: TMM3DMatrix4D): TMM3DMatrix4D;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DMatrixFromTranslation} {$ENDIF}
- function MM3DMatrixFromTranslation(const T: TMM3DVector): TMM3DMatrix4D;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DMatrixFromScaling} {$ENDIF}
- function MM3DMatrixFromScaling(const T: TMM3DVector): TMM3DMatrix4D;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DMatrixFromRotation} {$ENDIF}
- function MM3DMatrixFromRotation(const Axis: TMM3DVector; Angle: TMM3DValue): TMM3DMatrix4D;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DMatrixFromRotationTo} {$ENDIF}
- function MM3DMatrixFromRotationTo(const Dest: TMM3DVector): TMM3DMatrix4D;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DCreateCameraMatrix} {$ENDIF}
- function MM3DCreateCameraMatrix(const Origin, Front, Top: TMM3DVector): TMM3DMatrix4D;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorInvert} {$ENDIF}
- function MM3DVectorInvert(const V: TMM3DVector): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DMatrixInvert} {$ENDIF}
- function MM3DMatrixInvert(const M: TMM3DMatrix4D): TMM3DMatrix4D;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DMatrixDeterminant} {$ENDIF}
- function MM3DMatrixDeterminant(const M: TMM3DMatrix4D): TMM3DValue;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DMatrixCofactor} {$ENDIF}
- function MM3DMatrixCofactor(const M: TMM3DMatrix4D; i, j: Integer): TMM3DValue;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorDegToRad} {$ENDIF}
- function MM3DVectorDegToRad(const R: TMM3DVector): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorRadToDeg} {$ENDIF}
- function MM3DVectorRadToDeg(const R: TMM3DVector): TMM3DVector;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DDegToRad} {$ENDIF}
- function MM3DDegToRad(D: TMM3DValue): TMM3DValue;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DRadToDeg} {$ENDIF}
- function MM3DRadToDeg(R: TMM3DValue): TMM3DValue;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DMatrixFromCameraOrientation} {$ENDIF}
- function MM3DMatrixFromCameraOrientation(const Front, Top: TMM3DVector): TMM3DMatrix4D;
- {$IFDEF CBUILDER3} {$EXTERNALSYM MM3DVectorEqual} {$ENDIF}
- function MM3DVectorEqual(const V1, V2: TMM3DVector): Boolean;
- type
- {-- EMM3DError ---------------------------------------------------------------}
- EMM3DError = class(Exception)
- end;
- const
- XUnit : TMM3DVector = (x:1;y:0;z:0);
- YUnit : TMM3DVector = (x:0;y:1;z:0);
- ZUnit : TMM3DVector = (x:0;y:0;z:1);
- ZeroVector : TMM3DVector = (x:0;y:0;z:0);
- Identity : TMM3DMatrix4D = (
- (1, 0, 0, 0),
- (0, 1, 0, 0),
- (0, 0, 1, 0),
- (0, 0, 0, 1)
- );
- var
- White : TMM3DColor;
- Red : TMM3DColor;
- Blue : TMM3DColor;
- Green : TMM3DColor;
- LightRed : TMM3DColor;
- LightBlue : TMM3DColor;
- LightGreen : TMM3DColor;
- Yellow : TMM3DColor;
- Black : TMM3DColor;
- implementation
- uses
- MMMath,
- MMUtils
- {$IFDEF _DEBUG}
- ,MMDebug
- {$ENDIF}
- ;
- {-----------------------------------------------------------------------------}
- function MM3DCreateColorRGB(red, green, blue: TMM3DValue): TMM3DColor;
- begin
- Result := $ff000000 or (Trunc(red * 255) shl 16) or (Trunc(green * 255) shl 8) or Trunc(blue * 255);
- end;
- {-----------------------------------------------------------------------------}
- function MM3DCreateColorRGBA(red, green, blue, alpha: TMM3DValue): TMM3DColor;
- begin
- Result := (Trunc(alpha * 255) shl 24) or (Trunc(red * 255) shl 16) or (Trunc(green * 255) shl 8) or Trunc(blue * 255);
- end;
- {-----------------------------------------------------------------------------}
- function MM3DColorGetRed(color: TMM3DColor): TMM3DValue;
- begin
- Result := ((color shr 16) and $ff)/255;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DColorGetGreen(color: TMM3DColor): TMM3DValue;
- begin
- Result := ((color shr 8) and $ff)/255;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DColorGetBlue(color: TMM3DColor): TMM3DValue;
- begin
- Result := (color and $ff)/255;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DColorGetAlpha(color: TMM3DColor): TMM3DValue;
- begin
- Result := (color shr 24)/255;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DBuildRGBColor(color: TMM3DColor): TColor;
- type
- TBytes = record
- case Byte of
- 0: (C: TMM3DColor);
- 1: (B, G, R, A: Byte);
- end;
- begin
- with TBytes(color) do
- Result := RGB(R,G,B);
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVectorAdd(const s1, s2: TMM3DVector): TMM3DVector;
- begin
- with Result do
- begin
- x := s1.x + s2.x;
- y := s1.y + s2.y;
- z := s1.z + s2.z;
- end;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVectorSubtract(const s1, s2: TMM3DVector): TMM3DVector;
- begin
- with Result do
- begin
- x := s1.x - s2.x;
- y := s1.y - s2.y;
- z := s1.z - s2.z;
- end;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVectorReflect(const ray, normal: TMM3DVector): TMM3DVector;
- begin
- Result := MM3DVectorRotate(ray,normal,Pi);
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVectorCrossProduct(const s1, s2: TMM3DVector): TMM3DVector;
- begin
- with Result do
- begin
- X := (s1.Y*s2.Z)-(s1.Z*s2.Y);
- Y := (s1.Z*s2.X)-(s1.X*s2.Z);
- Z := (s1.X*s2.Y)-(s1.Y*s2.X);
- end;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVectorDotProduct(const s1, s2: TMM3DVector): TMM3DValue;
- begin
- Result := (s1.X * s2.X) + (s1.Y * s2.Y) + (s1.Z * s2.Z);
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVectorNormalize(const v: TMM3DVector): TMM3DVector;
- var
- M: TMM3DValue;
- begin
- M := MM3DVectorModulus(v);
- if M = 0 then
- { TODO: Should be resource id }
- raise EMM3DError.Create('Zero-length vector passed to normalize');
- with Result do
- begin
- X := v.X/M;
- Y := v.Y/M;
- Z := v.Z/M;
- end;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVectorNormalise(const v: TMM3DVector): TMM3DVector;
- begin
- Result := MM3DVectorNormalize(v);
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVectorModulus(const v: TMM3DVector): TMM3DValue;
- begin
- Result := Sqrt(Sqr(v.x)+Sqr(v.y)+Sqr(v.z));
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVectorRotate(const v, axis: TMM3DVector; theta: TMM3DValue): TMM3DVector;
- var
- M: TMM3DMatrix4D;
- begin
- M := MM3DMatrixFromRotation(axis,theta);
- Result := MM3DVector3D(MM3DVectorTransform(v,M));
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVectorScale(const s: TMM3DVector; factor: TMM3DValue): TMM3DVector;
- begin
- with Result do
- begin
- X := s.X*factor;
- Y := s.Y*factor;
- Z := s.Z*factor;
- end;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVectorRandom: TMM3DVector;
- begin
- with Result do
- begin
- X := Random(MaxInt)-(MaxInt div 2);
- Y := Random(MaxInt)-(MaxInt div 2);
- Z := Random(MaxInt)-(MaxInt div 2);
- end;
- Result := MM3DVectorNormalize(Result);
- end;
- {-----------------------------------------------------------------------------}
- function MM3DQuaternionFromRotation(const v: TMM3DVector; theta: TMM3DValue): TMM3DQuaternion;
- var
- ht: TMM3DValue;
- ch, sh: TMM3DValue;
- ax: TMM3DVector;
- begin
- ax := MM3DVectorNormalize(v);
- ht := theta/2;
- ch := cos(ht);
- sh := sin(ht);
- Result.v.x := ax.x*sh;
- Result.v.y := ax.y*sh;
- Result.v.z := ax.z*sh;
- Result.s := ch;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DMatrixFromQuaternion(const q: TMM3DQuaternion): TMM3DMatrix4D;
- var
- xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz: TMM3DValue;
- begin
- xs := 2*q.v.x;
- ys := 2*q.v.y;
- zs := 2*q.v.z;
- wx := q.s*xs;
- wy := q.s*ys;
- wz := q.s*zs;
- xx := q.v.x*xs;
- xy := q.v.x*ys;
- xz := q.v.x*zs;
- yy := q.v.y*ys;
- yz := q.v.y*zs;
- zz := q.v.z*zs;
- Result := Identity;
- Result[0,0] := 1 - (yy + zz);
- Result[0,1] := xy - wz;
- Result[0,2] := xz + wy;
- Result[1,0] := xy + wz;
- Result[1,1] := 1 - (xx + zz);
- Result[1,2] := yz - wx;
- Result[2,0] := xz - wy;
- Result[2,1] := yz + wx;
- Result[2,2] := 1 - (xx + yy);
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVector(x, y, z: TMM3DValue): TMM3DVector;
- begin
- Result.x := x;
- Result.y := y;
- Result.z := z;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVectorRotateQ(const v: TMM3DVector; const q: TMM3DQuaternion): TMM3DVector;
- begin
- Result := MM3DVector3D(MM3DVectorTransform(v,MM3DMatrixFromQuaternion(q)));
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVectorTransform(const v: TMM3DVector; const Mat: TMM3DMatrix4D): TMM3DVector4D;
- begin
- with v do
- begin
- Result.x := x * mat[0,0] + y * mat[0,1] + z * mat[0,2] + 1 * mat[0,3];
- Result.y := x * mat[1,0] + y * mat[1,1] + z * mat[1,2] + 1 * mat[1,3];
- Result.z := x * mat[2,0] + y * mat[2,1] + z * mat[2,2] + 1 * mat[2,3];
- Result.w := x * mat[3,0] + y * mat[3,1] + z * mat[3,2] + 1 * mat[3,3];
- end;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DCreateViewportMatrix(Front: TMM3DValue; Proj: TMM3DProjectionType): TMM3DMatrix4D;
- begin
- FillChar(Result,SizeOf(Result),0);
- if Proj = ptPerspective then
- begin
- Result[0,0] := Front;
- Result[1,1] := Front;
- Result[2,2] := 1;
- Result[3,2] := 1;
- end
- else
- begin
- Result[0,0] := 1;
- Result[1,1] := 1;
- Result[2,3] := Front;
- Result[3,3] := 1;
- end;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DVector3D(const v: TMM3DVector4D): TMM3DVector;
- begin
- with v do
- begin
- Result.X := X/W;
- Result.Y := Y/W;
- Result.Z := Z/W;
- end;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DMatrixMul(const M1, M2: TMM3DMatrix4D): TMM3DMatrix4D;
- var
- i, j: Integer;
- begin
- for i := 0 to 3 do
- for j := 0 to 3 do
- Result[j,i] := M1[0,i] * M2[j,0] + M1[1,i] * M2[j,1] + M1[2,i] * M2[j,2] + M1[3,i] * M2[j,3];
- end;
- {-----------------------------------------------------------------------------}
- function MM3DMatrixFromTranslation(const T: TMM3DVector): TMM3DMatrix4D;
- begin
- FillChar(Result,SizeOf(Result),0);
- Result[0,3] := T.x;
- Result[1,3] := T.y;
- Result[2,3] := T.z;
- Result[0,0] := 1;
- Result[1,1] := 1;
- Result[2,2] := 1;
- Result[3,3] := 1;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DMatrixFromScaling(const T: TMM3DVector): TMM3DMatrix4D;
- begin
- FillChar(Result,SizeOf(Result),0);
- Result[0,0] := T.x;
- Result[1,1] := T.y;
- Result[2,2] := T.z;
- Result[3,3] := 1;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DMatrixFromRotation(const Axis: TMM3DVector; Angle: TMM3DValue): TMM3DMatrix4D;
- var
- Q: TMM3DQuaternion;
- begin
- if Angle = 0 then
- Result := Identity
- else
- begin
- Q := MM3DQuaternionFromRotation(Axis,Angle);
- Result := MM3DMatrixFromQuaternion(Q);
- end;
- end;
- {-----------------------------------------------------------------------------}
- function MM3DMatrixFromRotationTo(const Dest: TMM3DVector): TMM3DMatrix4D;
- type
- PVect = ^TVect;
- TVect = array[0..2] of TMM3DValue;
- var
- N, T, W, U, V: TMM3DVector;
- function GetMinorAxis(const V: TMM3DVector): Integer;
- begin
- Result := 0;
- if V.X > V.Y then
- Result := 1;
- if V.Z < PVect(@V)[Result] then
- Result := 2;
- end;
- begin
- N := MM3DVectorNormalize(Dest);
- T := N;
- W := N;
- PVect(@T)[GetMinorAxis(W)] := 1.0;
- U := MM3DVectorNormalize(MM3DVectorCrossProduct(T,W));
- V := MM3DVectorCrossProduct(W,U);
- Result := Identity;
- Result[0,0] := U.X;
- Result[0,1] := U.Y;
- Result[0,2] := U.Z;
- Result[1,0] := V.X;
- Result[1,1] := V.Y;
- Result[1,2] := V.Z;
- 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.