1. with GL; 
  2. with GLOBE_3D.Math; 
  3.  
  4. package body Actors is 
  5.  
  6.    use GLOBE_3D, GLOBE_3D.Math, GLOBE_3D.REF, Game_Control, GL; 
  7.  
  8.    procedure Limited_Translation (actor          : in out GLOBE_3D.Camera; 
  9.                                   gc             :        Game_Control.Command_set; 
  10.                                   gx, gy         :        GLOBE_3D.Real; 
  11.                                   unitary_change :        GLOBE_3D.Real; 
  12.                                   deceleration   :        GLOBE_3D.Real; 
  13.                                   time_step      :        GLOBE_3D.Real) is 
  14.  
  15.       pragma Unreferenced (gx); 
  16.  
  17.       unitary_movement, eye_movement : Real; 
  18.       step : Vector_3D; 
  19.  
  20.    begin 
  21.       unitary_movement := (case gc (run_mode) is 
  22.                            when True  => 300.0, 
  23.                            when False => 100.0); 
  24.       unitary_movement := unitary_movement * unitary_change; 
  25.       eye_movement := unitary_movement * 2.0; 
  26.  
  27.       actor.Speed (2) := actor.Speed (2) + (case gc (go_forward) is 
  28.                                             when True  => -eye_movement, 
  29.                                             when False => +eye_movement); 
  30.  
  31.       actor.Speed (1) := actor.Speed (1) + (if    gc (slide_vertical_graduated) then +gy * 2.0 * unitary_movement 
  32.                                             elsif gc (slide_down)               then -eye_movement 
  33.                                             elsif gc (slide_up)                 then +eye_movement 
  34.                                             else 0.0); 
  35.       actor.Speed (0) := actor.Speed (0) + (if    gc (slide_vertical_graduated) then +gy * 2.0 * unitary_movement 
  36.                                             elsif gc (slide_down)               then -eye_movement 
  37.                                             elsif gc (slide_up)                 then +eye_movement 
  38.                                             else 0.0); 
  39.  
  40.       step := time_step * (Transpose (actor.World_Rotation) * actor.Speed); 
  41.       --  (speed (0),    -- lateral sliding 
  42.       --    speed (1),    -- vertical sliding 
  43.       --    speed (2));  -- forward/backwards 
  44.       --   -- ^ vector in the local referential 
  45.  
  46.       Limiting (step); 
  47.  
  48.       actor.Clipper.Eye_Position := actor.Clipper.Eye_Position + step; 
  49.  
  50.       actor.Speed := deceleration * actor.Speed; 
  51.  
  52.    end Limited_Translation; 
  53.  
  54.    procedure No_Limitation (step : in out GLOBE_3D.Vector_3D) is 
  55.    null; 
  56.  
  57.    procedure Translation_inst is new Limited_Translation (No_Limitation); 
  58.  
  59.    procedure Translation (actor          : in out GLOBE_3D.Camera; 
  60.                           gc             :        Game_Control.Command_set; 
  61.                           gx, gy         :        GLOBE_3D.Real; 
  62.                           unitary_change :        GLOBE_3D.Real; 
  63.                           deceleration   :        GLOBE_3D.Real; 
  64.                           time_step      :        GLOBE_3D.Real) renames Translation_inst; 
  65.  
  66.    procedure Rotation (actor          : in out GLOBE_3D.Camera; 
  67.                        gc             :        Game_Control.Command_set; 
  68.                        gx, gy         :        GLOBE_3D.Real; 
  69.                        unitary_change :        GLOBE_3D.Real; 
  70.                        deceleration   :        GLOBE_3D.Real; 
  71.                        time_step      :        GLOBE_3D.Real) is 
  72.  
  73.       incremental_rotation : Vector_3D := (0.0, 0.0, 0.0); 
  74.  
  75.    begin 
  76.       Abstract_rotation (gc, gx, gy, 
  77.                          unitary_change, deceleration, incremental_rotation, time_step, 
  78.                          actor.rotation_Speed); 
  79.       actor.rotation := actor.rotation + incremental_rotation; 
  80.       if actor.compose_rotations then 
  81.          actor.World_Rotation := 
  82.            XYZ_rotation (incremental_rotation) * actor.World_Rotation; 
  83.          Re_Orthonormalize (actor.World_Rotation); 
  84.       else 
  85.          declare 
  86.             r : Vector_3D renames actor.rotation; 
  87.             -- We need to turn around the axes in this order : Y, X, Z 
  88.          begin 
  89.             actor.World_Rotation := 
  90.               XYZ_rotation (0.0,  0.0, r (2)) *  -- 3) turn around the nose 
  91.               XYZ_rotation (r (0),  0.0,  0.0) *  -- 2) lift or lower the head 
  92.               XYZ_rotation (0.0, r (1),  0.0);    -- 1) pivotate around the feet 
  93.          end; 
  94.       end if; 
  95.    end Rotation; 
  96.  
  97.    procedure Abstract_rotation (gc             :        Game_Control.Command_set; 
  98.                                 gx, gy         :        GLOBE_3D.Real; 
  99.                                 unitary_change :        GLOBE_3D.Real; 
  100.                                 deceleration   :        GLOBE_3D.Real; 
  101.                                 vector         : in out GLOBE_3D.Vector_3D; 
  102.                                 time_step      :        GLOBE_3D.Real; 
  103.                                 rotation_speed : in out GLOBE_3D.Vector_3D) is 
  104.  
  105.       unitary_movement, mouse_rotation, key_rotation : Real; 
  106.  
  107.    begin 
  108.       if gc (run_mode) then 
  109.          unitary_movement := 40.0; 
  110.       else 
  111.          unitary_movement := 20.0; 
  112.       end if; 
  113.       unitary_movement := unitary_movement * unitary_change; 
  114.       mouse_rotation := 2.0  * unitary_movement; 
  115.       key_rotation  := 0.17 * unitary_movement; 
  116.  
  117.       if gc (swing_plus) then 
  118.          rotation_speed (2) := rotation_speed (2) + key_rotation; 
  119.       end if; 
  120.       if gc (swing_minus) then 
  121.          rotation_speed (2) := rotation_speed (2) - key_rotation; 
  122.       end if; 
  123.       if gc (turn_left) then 
  124.          rotation_speed (1) := rotation_speed (1) + key_rotation; 
  125.       end if; 
  126.       if gc (turn_right) then 
  127.          rotation_speed (1) := rotation_speed (1) - key_rotation; 
  128.       end if; 
  129.       if gc (turn_up) then 
  130.          rotation_speed (0) := rotation_speed (0) - key_rotation; 
  131.       end if; 
  132.       if gc (turn_down) then 
  133.          rotation_speed (0) := rotation_speed (0) + key_rotation; 
  134.       end if; 
  135.       if gc (turn_lateral_graduated) then 
  136.          rotation_speed (1) := rotation_speed (1) - gx * mouse_rotation; 
  137.       end if; 
  138.       if gc (turn_vertical_graduated) then 
  139.          rotation_speed (0) := rotation_speed (0) - gy * mouse_rotation; 
  140.       end if; 
  141.       vector := vector + time_step * rotation_speed; 
  142.       rotation_speed := deceleration * rotation_speed; 
  143.    end Abstract_rotation; 
  144.  
  145.    procedure Abstract_rotation (gc             :        Game_Control.Command_set; 
  146.                                 gx, gy         :        GLOBE_3D.Real; 
  147.                                 unitary_change :        GLOBE_3D.Real; 
  148.                                 deceleration   :        GLOBE_3D.Real; 
  149.                                 rot_matrix     : in out GLOBE_3D.Matrix_33; 
  150.                                 time_step      :        GLOBE_3D.Real; 
  151.                                 rotation_speed : in out GLOBE_3D.Vector_3D) is 
  152.  
  153.       incremental_rotation : Vector_3D := (0.0, 0.0, 0.0); 
  154.  
  155.    begin 
  156.       Abstract_rotation (gc, gx, gy, 
  157.                          unitary_change, deceleration, incremental_rotation, time_step, 
  158.                          rotation_speed); 
  159.       rot_matrix := rot_matrix * XYZ_rotation (incremental_rotation); 
  160.    end Abstract_rotation; 
  161.  
  162. end Actors;