(**********************************************************************

    :Program.  	 R3Test.mod
    :Contents.	 Testmodule for MathLibR2
    :Author.   	 Nicolas Benezan [bne]
    :Address.    Postwiesenstr. 2, D7000 Stuttgart 60
    :Phone.      711/333679
    :Copyright.  Public Domain
    :Language. 	 Modula-2
    :Translator. M2Amiga AMSoft
    :Imports.	 MathLibR2, IntuiStruct [bne]
    :ModHistory. V1.0 [bne] 16.07.88 (Demo Amok#4)
    
**********************************************************************)

MODULE R3Test;

FROM MathLibR3	IMPORT Vector3,Matrix3,Add3,Trans3,Mmul3,Scalar,Invert3;
FROM IntuiStruct IMPORT StructScreen,StructWindow;
FROM Graphics	IMPORT RastPortPtr,Draw,Move,SetDrMd,SetAPen,ViewModes,
		ViewModeSet,jam1,WaitTOF,RectFill;
FROM Exec	IMPORT WaitPort;
FROM Intuition	IMPORT ScreenPtr,WindowPtr,ScreenFlags,ScreenFlagSet,
		WindowFlags,WindowFlagSet,IDCMPFlags,IDCMPFlagSet,
                customScreen,stdScreenHeight,NewScreen,NewWindow,
                OpenScreen,OpenWindow,CloseScreen,CloseWindow;
FROM Arts	IMPORT Assert;
FROM SYSTEM	IMPORT ADR;
FROM MathTrans	IMPORT Sin,Cos;

CONST	Ox=160;
	Oy=122;
        gamma=0.03;
	beta=0.05;
        alpha=-0.1;
        grow=1.003;

VAR	Screen:ScreenPtr;
	Window:WindowPtr;
        MyScreen:NewScreen;
        MyWindow:NewWindow;
        RastPort:RastPortPtr;
        Point:ARRAY [1..8] OF Vector3;
        RotX,RotY,RotZ,Matrix:Matrix3;
        Vector:Vector3;
        n,m:INTEGER;

PROCEDURE Round(X:Scalar):INTEGER;
BEGIN
  RETURN INTEGER(X+0.5);
END Round;

PROCEDURE DeleteCube;
VAR	n:INTEGER;
BEGIN
  SetAPen(RastPort,0);
  RectFill(RastPort,2,10,317,242);
END DeleteCube;

PROCEDURE DrawCube;
VAR	n,x,y:INTEGER;

  PROCEDURE Perspective(V:Vector3); (* Zentralprojektion *)
  VAR	Scale:Scalar;
  BEGIN
    Scale:=400.0/(V.z+400.0);
    x:=Round(V.x*Scale)+Ox;
    y:=Round(V.y*Scale)+Oy;
  END Perspective;

BEGIN
  SetAPen(RastPort,1);
  Perspective(Point[4]);
  Move(RastPort,x,y);
  FOR n:=1 TO 4 DO
    Perspective(Point[n]);
    Draw(RastPort,x,y);
  END;
  Perspective(Point[8]);
  Move(RastPort,x,y);
  FOR n:=5 TO 8 DO
    Perspective(Point[n]);
    Draw(RastPort,x,y);
  END;
  FOR n:=1 TO 4 DO
    Perspective(Point[n]);
    Move(RastPort,x,y);
    Perspective(Point[n+4]);
    Draw(RastPort,x,y);
  END;
END DrawCube;

BEGIN
  StructScreen(MyScreen,1,0,1,ViewModeSet{},customScreen,ADR("R³ Test"));
  Screen:=OpenScreen(MyScreen);
  Assert(Screen#NIL,ADR("Screen klemmt"));
  StructWindow(MyWindow,0,12,320,244,-1,-1,IDCMPFlagSet{closeWindow},
  	WindowFlagSet{windowClose,simpleRefresh,noCareRefresh,backDrop},
        NIL,Screen,customScreen);
  Window:=OpenWindow(MyWindow);
  Assert(Window#NIL,ADR("Window klemmt"));
  RastPort:=Window^.rPort;
  SetDrMd(RastPort,jam1);
  Point[1].x:=-50.0;	(* Würfel *)
  Point[1].y:=-50.0;
  Point[1].z:=-50.0;
  Point[2].x:=-50.0;
  Point[2].y:=50.0;
  Point[2].z:=-50.0;
  Point[3].x:=50.0;
  Point[3].y:=50.0;
  Point[3].z:=-50.0;
  Point[4].x:=50.0;
  Point[4].y:=-50.0;
  Point[4].z:=-50.0;
  FOR n:=5 TO 8 DO
    Point[n]:=Point[n-4];
    Point[n].z:=50.0;
  END;
  (*		/ 1   0    0 \
     RotX:=     | 0  cos  sin|
     		\ 0  -sin cos/	*)
  RotX[1,1]:=1.0;
  RotX[1,2]:=0.0;
  RotX[1,3]:=0.0;
  RotX[2,1]:=0.0;
  RotX[2,2]:=Cos(alpha);
  RotX[2,3]:=-Sin(alpha);
  RotX[3,1]:=0.0;
  RotX[3,2]:=Sin(alpha);
  RotX[3,3]:=Cos(alpha);
  (*		/cos  sin 0\
     RotZ:=     |-sin cos 0|
     		\ 0   0   1/	*)
  RotZ[1,1]:=Cos(beta)*grow;
  RotZ[1,2]:=Sin(beta)*grow;
  RotZ[1,3]:=0.0;
  RotZ[2,1]:=-Sin(beta)*grow;
  RotZ[2,2]:=Cos(beta)*grow;
  RotZ[2,3]:=0.0;
  RotZ[3,1]:=0.0;
  RotZ[3,2]:=0.0;
  RotZ[3,3]:=1.0;
  (*		/cos  0 -sin\
     RotY:=     | 0   1   0 |
     		\sin  0  cos/	*)
  RotY[1,1]:=Cos(gamma);
  RotY[1,2]:=0.0;
  RotY[1,3]:=-Sin(gamma);
  RotY[2,1]:=0.0;
  RotY[2,2]:=1.0;
  RotY[2,3]:=0.0;
  RotY[3,1]:=Sin(gamma);
  RotY[3,2]:=0.0;
  RotY[3,3]:=Cos(gamma);
  Mmul3(RotY,RotZ,Matrix);
  Mmul3(Matrix,RotX,Matrix);
  DrawCube;
  FOR n:=1 TO 200 DO
    FOR m:=1 TO 8 DO
      Trans3(Matrix,Point[m],Point[m]);
    END;
    DeleteCube;
    DrawCube;
    WaitTOF;
  END;
  IF Invert3(Matrix) THEN END;
  Mmul3(Matrix,Matrix,Matrix);
  FOR n:=1 TO 100 DO
    FOR m:=1 TO 8 DO
      Trans3(Matrix,Point[m],Point[m]);
    END;
    DeleteCube;
    DrawCube;
    WaitTOF;
  END;
  WaitPort(Window^.userPort);
  CloseWindow(Window);
  CloseScreen(Screen);
END R3Test.
