lace_gel_0.1.0_2c333035/source/gel-rig.ads

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
with
     gel.Sprite,
     gel.Joint,
     gel.World,

     openGL,
     openGL.Model,
     openGL.Program,

     ada.Strings.unbounded.Hash,
     ada.Containers.Vectors,
     ada.Containers.hashed_Maps;

private
with
     collada.Library.visual_Scenes;

package gel.Rig
--
-- Provides GEL sprites which allow placing a collada skinned/rigged model into a GEL World.
--
-- The rig motion can be controlled either by normal dynamics or pre-canned animations.
--
is
   type Item  is tagged limited private;
   type View  is access all Item'Class;

   type Views is array (Positive range <>) of View;

   use Math;


   --------------
   --- Core Types
   --

   type motion_Mode is (Dynamics, Animation);

   procedure motion_Mode_is (Self : in out Item;   Now : in motion_Mode);


   subtype bone_Id is ada.Strings.unbounded.unbounded_String;

   null_Id : constant bone_Id := ada.Strings.unbounded.null_unbounded_String;


   subtype controller_joint_Id is ada.Strings.unbounded.unbounded_String;


   --------------
   --- Containers
   --

   package inverse_bind_matrix_Vectors is new ada.Containers.Vectors (Positive, Matrix_4x4);
   subtype inverse_bind_matrix_Vector  is inverse_bind_matrix_Vectors.Vector;


   --------------
   --- Joints Ids
   --

   subtype gel_joint_Id is ada.Strings.unbounded.unbounded_String;

   package gel_joint_id_Maps_of_gel_Joint is new ada.Containers.hashed_Maps (Key_type        => gel_joint_Id,
                                                                             Element_type    => gel.Joint.view,
                                                                             Hash            => ada.Strings.unbounded.Hash,
                                                                             equivalent_Keys => ada.Strings.unbounded."=",
                                                                             "="             => gel.Joint."=");
   subtype gel_joint_id_Map_of_gel_Joint is gel_joint_id_Maps_of_gel_Joint.Map;


   package joint_Id_Maps_of_bone_site_offset is new ada.Containers.hashed_Maps (Key_type        => controller_joint_Id,
                                                                                Element_type    => Vector_3,
                                                                                Hash            => ada.Strings.unbounded.Hash,
                                                                                equivalent_Keys => ada.Strings.unbounded."=",
                                                                                "="             => "=");
   subtype joint_Id_Map_of_bone_site_offset is joint_Id_Maps_of_bone_site_offset.Map;


   ------------
   --- Bone Ids
   --

   package bone_id_Maps_of_sprite is new ada.Containers.hashed_Maps (Key_type        => bone_Id,
                                                                     Element_type    => gel.Sprite.view,
                                                                     Hash            => ada.Strings.unbounded.Hash,
                                                                     equivalent_Keys => ada.Strings.unbounded."=",
                                                                     "="             => gel.Sprite."=");
   subtype bone_id_Map_of_sprite is bone_id_Maps_of_sprite.Map;


   ----------------
   --- Bone Details
   --

   type bone_Details is
      record
         Length       : math.Real := 1.0;
         width_Factor,
         depth_Factor : math.Real := 0.1;   -- Factor * Length gives width and depth.

         pitch_Limits,
         yaw_Limits,
         roll_Limits  : gel.Sprite.DoF_Limits := (to_Radians (-15.0),
                                                  to_Radians ( 15.0));
      end record;

   Unspecified : constant := -1.0;

   function to_Details (Length       : Real := Unspecified;
                        width_Factor,
                        depth_Factor : Real := 0.1;

                        pitch_Limits,
                        yaw_Limits,
                        roll_Limits  : gel.Sprite.DoF_Limits := (to_Radians (-15.0),
                                                                 to_Radians ( 15.0))) return bone_Details;

   package bone_id_Maps_of_details is new ada.Containers.hashed_Maps (Key_Type        => bone_id,
                                                                      Element_Type    => bone_Details,
                                                                      Hash            => ada.Strings.unbounded.Hash,
                                                                      Equivalent_Keys => ada.Strings.unbounded."=",
                                                                      "="             => "=");
   subtype bone_id_Map_of_details is bone_id_Maps_of_details.Map;




   ---------
   --- Forge
   --

   package Forge
   is
      function new_Rig (in_World                : in gel.World.view;
                        Model                   : in openGL.Model.view;
                        Mass                    : in Real    := 0.0;
                        is_Kinematic            : in Boolean := False) return Rig.view;

      function new_Rig (bone_Sprites            : in bone_id_Map_of_sprite;
                        joint_inv_bind_Matrices : in inverse_bind_matrix_Vector;
                        joint_site_Offets       : in joint_Id_Map_of_bone_site_offset;
                        Model                   : in openGL.Model.view) return Rig.view;
   end Forge;


   procedure define (Self : in out Item;   in_World     : in gel.World.view;
                                           Model        : in openGL.Model.view;
                                           Mass         : in Real                   := 0.0;
                                           is_Kinematic : in Boolean                := False;
                                           bone_Details : in bone_id_Map_of_details := bone_id_Maps_of_details.empty_Map);


   --------------
   --- Attributes
   --

   procedure Site_is (Self : in out Item;   Now : in Vector_3);
   procedure Spin_is (Self : in out Item;   Now : in Matrix_3x3);

   function  bone_Sprites (Self : in Item)       return bone_id_Map_of_sprite;
   function  skin_Sprite  (Self : in Item'Class) return gel.Sprite.view;
   function  base_Sprite  (Self : in Item'Class) return gel.Sprite.view;
   function  Sprite       (Self : in Item'Class;
                           Bone : in bone_Id)    return gel.Sprite.view;

   function  Joints (Self : in Item) return gel_joint_id_Map_of_gel_Joint;

   procedure joint_inv_bind_Matrices_are (Self : in out Item'Class;   Now : in inverse_bind_matrix_Vector);
   function  joint_inv_bind_Matrices     (Self : in     Item'Class)     return inverse_bind_matrix_Vector;

   function  joint_site_Offets (Self : in Item'Class) return joint_Id_Map_of_bone_site_offset;

   procedure assume_Pose     (Self : in out Item);
   procedure enable_Graphics (Self : in out Item);
   procedure evolve          (Self : in out Item'Class;   world_Age : in Duration);


   -------------
   --- Animation
   --

   subtype scene_joint_Id is ada.Strings.unbounded.unbounded_String;

   package bone_id_Maps_of_transform is new ada.Containers.hashed_Maps (Key_Type        => bone_id,
                                                                        Element_Type    => Matrix_4x4,
                                                                        Hash            => ada.Strings.unbounded.Hash,
                                                                        Equivalent_Keys => ada.Strings.unbounded."=",
                                                                        "="             => "=");
   subtype bone_id_Map_of_transform is bone_id_Maps_of_transform.Map;

   procedure animation_Transforms_are (Self : in out Item'Class;   Now : in bone_id_Map_of_transform);


   type axis_Kind is (x_Axis, y_Axis, z_Axis);

   procedure set_rotation_Angle   (Self : in out Item'Class;   for_Joint : in scene_joint_Id;
                                                               Axis      : in Axis_Kind;
                                                               To        : in Real);     -- TODO: Use Radians type (and below).
   procedure set_x_rotation_Angle (Self : in out Item'Class;   for_Joint : in scene_joint_Id;
                                                               To        : in Real);
   procedure set_y_rotation_Angle (Self : in out Item'Class;   for_Joint : in scene_joint_Id;
                                                               To        : in Real);
   procedure set_z_rotation_Angle (Self : in out Item'Class;   for_Joint : in scene_joint_Id;
                                                               To        : in Real);

   procedure set_Location   (Self : in out Item'Class;   for_Joint : in scene_joint_Id;
                                                         To        : in Vector_3);
   procedure set_Location_x (Self : in out Item'Class;   for_Joint : in scene_joint_Id;
                                                         To        : in Real);
   procedure set_Location_y (Self : in out Item'Class;   for_Joint : in scene_joint_Id;
                                                         To        : in Real);
   procedure set_Location_z (Self : in out Item'Class;   for_Joint : in scene_joint_Id;
                                                         To        : in Real);
   procedure set_Transform  (Self : in out Item'Class;   for_Joint : in scene_joint_Id;
                                                         To        : in Matrix_4x4);

   procedure update_all_global_Transforms (Self : in out Item'Class);

   procedure animate         (Self : in out Item;   world_Age : in Duration);
   procedure reset_Animation (Self : in out Item);



private

   -- gl_transform_Vector
   --
   package gl_transform_Vectors is new ada.Containers.Vectors (Positive, openGL.Matrix_4x4);
   subtype gl_transform_Vector  is gl_transform_Vectors.Vector;


   -- joint_id_Map_of_matrix_4x4
   --
   package joint_id_Maps_of_matrix_4x4 is new ada.Containers.hashed_Maps (Key_type        => scene_joint_Id,
                                                                          Element_type    => Matrix_4x4,
                                                                          Hash            => ada.Strings.unbounded.Hash,
                                                                          equivalent_Keys => ada.Strings.unbounded."=",
                                                                          "="             => "=");
   subtype joint_id_Map_of_matrix_4x4 is joint_id_Maps_of_matrix_4x4.Map;


   -- joint_id_Map_of_scene_node
   --
   package joint_id_Maps_of_scene_node is new ada.Containers.hashed_Maps (Key_type        => scene_joint_Id,
                                                                          Element_type    => collada.Library.visual_Scenes.Node_view,
                                                                          Hash            => ada.Strings.unbounded.Hash,
                                                                          equivalent_Keys => ada.Strings.unbounded."=",
                                                                          "="             => collada.Library.visual_Scenes."=");
   subtype joint_id_Map_of_scene_node is joint_id_Maps_of_scene_node.Map;


   -- joint_id_Map_of_slot
   --
   package joint_id_Maps_of_slot is new ada.Containers.hashed_Maps (Key_type        => scene_joint_Id,
                                                                    Element_type    => Positive,
                                                                    Hash            => ada.Strings.unbounded.Hash,
                                                                    equivalent_Keys => ada.Strings.unbounded."=",
                                                                    "="             => "=");
   subtype joint_id_Map_of_slot is joint_id_Maps_of_slot.Map;


   -- skin_program_Parameters
   --
   type skin_program_Parameters is new opengl.Program.Parameters with
      record
         bone_Transforms   : gl_transform_Vector;
         joint_Map_of_slot : joint_id_Map_of_slot;
      end record;

   overriding
   procedure enable (Self : in out skin_program_Parameters);


   -- joint_id_Map_of_joint_id
   --
   package joint_id_Maps_of_joint_id is new ada.Containers.hashed_Maps (Key_type        => scene_joint_Id,
                                                                        Element_type    => scene_joint_Id,
                                                                        Hash            => ada.Strings.unbounded.Hash,
                                                                        equivalent_Keys => ada.Strings.unbounded."=",
                                                                        "="             => ada.Strings.unbounded."=");
   subtype joint_id_Map_of_joint_id is joint_id_Maps_of_joint_id.Map;


   -- scene_Joint
   --
   type scene_Joint is
      record
         Node      : collada.Library.visual_Scenes.Node_view;
         Transform : Matrix_4x4;
      end record;

   package joint_id_Maps_of_scene_Joint is new ada.Containers.hashed_Maps (Key_type        => scene_joint_Id,
                                                                           Element_type    => scene_Joint,
                                                                           Hash            => ada.Strings.unbounded.Hash,
                                                                           equivalent_Keys => ada.Strings.unbounded."=",
                                                                           "="             => "=");
   subtype joint_id_Map_of_scene_Joint is joint_id_Maps_of_scene_Joint.Map;


   -- Transform
   --
   type Transform is
      record
         Rotation    : Quaternion := linear_Algebra_3D.to_Quaternion (linear_Algebra_3D.x_Rotation_from (0.0));
         Translation : Vector_3   := (0.0, 0.0, 0.0);
      end record;

   type Transforms      is array (Positive range <>) of Transform;
   type Transforms_view is access all Transforms;


   -- animation_Channel
   --
   type animation_Channel is
      record
         Target            : access collada.Library.visual_Scenes.Transform;
         target_Joint      :        scene_joint_Id;

         Times             : access collada.float_Array;
         Values            : access collada.float_Array;

         Cursor            :        Index := 0;       -- Current frame of the anmination.

         initial_Angle     :        Real;             -- For angle interpolation during 'rotation' animation.
         current_Angle     :        Real  := 0.0;     --
         interp_Delta      :        Real  := 0.0;     --

         initial_Site      :        Vector_3;         -- For location interpolation during 'translation' animation.
         current_Site      :        Vector_3;         --
         site_interp_Delta :        Vector_3;         --

         initial_Transform :        Transform;        -- For matrix interpolation during 'full_transform' animation.
         current_Transform :        Transform;        --
         slerp_Time        :        Real;             -- Slerp Time (T) value in range '0.0 .. 1.0'.     -- TODO: use 'unit_Interval' type.
         Transforms        :        Transforms_view;
         Transform_interp_Delta :   Real;             -- Rate at which the SLERP time parameter increases.
      end record;

   subtype channel_Id is scene_joint_Id;
   package channel_id_Maps_of_animation_Channel is new ada.Containers.hashed_Maps (Key_Type        => channel_Id,
                                                                                   Element_Type    => animation_Channel,
                                                                                   Hash            => ada.Strings.unbounded.Hash,
                                                                                   Equivalent_Keys => ada.Strings.unbounded."=",
                                                                                   "="             => "=");
   subtype channel_id_Map_of_animation_Channel is channel_id_Maps_of_animation_Channel.Map;


   -- Rig Item
   --
   type Item is tagged limited
      record
         Mode                    : motion_Mode := Dynamics;

         joint_Sprites           : bone_id_Map_of_sprite;                   -- Sprite to show location/rotation of joints (mainly for debugging).
         bone_Sprites            : bone_id_Map_of_sprite;                   -- A sprite for each bone.
         skin_Sprite             : gel.Sprite.view;                         -- A sprite for the skin.

         bind_shape_Matrix       : Matrix_4x4;

         Joints                  : gel_joint_id_Map_of_gel_Joint;
         joint_inv_bind_Matrices : inverse_bind_matrix_Vector;              -- The joint inverse transforms when in the bind pose.

         phys_joint_site_Offets  : joint_Id_Map_of_bone_site_offset;        -- Offset from the bone site to the joint site when in the bind pose.
         anim_joint_site_Offets  : joint_Id_Map_of_bone_site_offset;        -- Offset from the bone site to the joint site when in the bind pose.

         joint_pose_Transforms   : joint_id_Map_of_matrix_4x4;              -- The joint transforms when in the skeletal pose.
         joint_Parent            : joint_id_Map_of_joint_id;

         collada_Joints          : joint_id_Map_of_scene_node;
         scene_Joints            : joint_id_Map_of_scene_Joint;
         root_Joint              : collada.Library.visual_scenes.Node_view;

         animation_Transforms    : bone_id_Map_of_transform;
         bone_pose_Transforms    : bone_id_Map_of_transform;                -- The bone transforms when in the skeletal pose.

         Channels                : channel_id_Map_of_animation_Channel;
         start_Time              : Duration := 0.0;

         overall_Site            : Vector_3 := (0.0, 0.0, 0.0);

         Model                   : openGL.Model.view;
         program_Parameters      : aliased skin_program_Parameters;
      end record;


   function Parent_of             (Self : in Item;   the_Bone : in bone_Id) return bone_Id;
   function joint_site_Offet      (Self : in Item;   for_Bone : in bone_Id) return Vector_3;
   function joint_inv_bind_Matrix (Self : in Item;   for_Bone : in bone_Id) return Matrix_4x4;
   function joint_bind_Matrix     (Self : in Item;   for_Bone : in bone_Id) return Matrix_4x4;


end gel.Rig;