1894 lines
81 KiB
Ada
1894 lines
81 KiB
Ada
with
|
|
openGL.Model.any,
|
|
openGL.Model.box.colored,
|
|
openGL.texture_Set,
|
|
-- openGL.Model.box.lit_colored_textured,
|
|
-- gel.cone_twist_Joint,
|
|
gel.Conversions,
|
|
|
|
collada.Document,
|
|
collada.Library,
|
|
collada.Library.controllers,
|
|
-- collada.Library.visual_scenes,
|
|
collada.Library.animations,
|
|
|
|
opengl.Palette,
|
|
opengl.Geometry.lit_textured_skinned,
|
|
opengl.Program.lit.textured_skinned,
|
|
|
|
ada.Strings.unbounded,
|
|
ada.unchecked_Deallocation,
|
|
ada.Text_IO;
|
|
|
|
|
|
package body gel.Human_v1
|
|
is
|
|
use ada.Text_IO,
|
|
gel.linear_Algebra_3D;
|
|
|
|
package std_Physics renames standard.Physics;
|
|
|
|
|
|
my_Scale : constant := 1.0;
|
|
model_Name : access String;
|
|
|
|
|
|
procedure use_Model (Named : in String)
|
|
is
|
|
begin
|
|
if model_Name /= null then
|
|
raise Program_Error with "'gel.human' model name has already been set";
|
|
end if;
|
|
|
|
model_Name := new String' (Named);
|
|
end use_Model;
|
|
|
|
|
|
-----------
|
|
--- Utility
|
|
--
|
|
|
|
function "+" (From : in ada.strings.unbounded.unbounded_String) return String
|
|
renames ada.strings.unbounded.to_String;
|
|
|
|
|
|
function to_joint_Id (From : in String) return scene_joint_Id
|
|
is
|
|
Pad : String := From;
|
|
begin
|
|
if From = "" then
|
|
raise Constraint_Error;
|
|
-- return Armature;
|
|
end if;
|
|
|
|
for Each in Pad'Range loop
|
|
if Pad (Each) = '-'
|
|
or Pad (Each) = '.'
|
|
then
|
|
Pad (Each) := '_';
|
|
end if;
|
|
end loop;
|
|
|
|
-- put_Line ("Pad: '" & Pad & "'");
|
|
|
|
return scene_joint_Id'Value (Pad);
|
|
end to_joint_Id;
|
|
|
|
|
|
|
|
function to_Math (From : in collada.Matrix_4x4) return math.Matrix_4x4
|
|
is
|
|
use type math.Real;
|
|
begin
|
|
return (1 => (From (1, 1), From (1, 2), From (1, 3), From (1, 4)),
|
|
2 => (From (2, 1), From (2, 2), From (2, 3), From (2, 4)),
|
|
3 => (From (3, 1), From (3, 2), From (3, 3), From (3, 4)),
|
|
4 => (From (4, 1), From (4, 2), From (4, 3), From (4, 4)));
|
|
end to_Math;
|
|
|
|
|
|
to_scene_joint_Id : array (controller_joint_Id) of scene_joint_Id;
|
|
to_controller_joint_Id : array (scene_joint_Id ) of controller_joint_Id;
|
|
|
|
|
|
---------
|
|
--- Forge
|
|
--
|
|
|
|
package body Forge
|
|
is
|
|
|
|
function new_Human (World : access gel .World.item'Class;
|
|
Model : access openGL .Model.item'Class;
|
|
physics_Model : access std_Physics.Model.item'Class;
|
|
Mass : in math.Real := 0.0;
|
|
is_Kinematic : in Boolean := False) return Human_v1.view
|
|
is
|
|
Self : constant Human_v1.view := new Human_v1.item;
|
|
begin
|
|
Self.define (World, --Space,
|
|
Model,
|
|
physics_Model,
|
|
Mass,
|
|
is_Kinematic);
|
|
return Self;
|
|
end new_Human;
|
|
|
|
|
|
|
|
function new_Human (bone_Sprites : in human_v1.bone_Sprites;
|
|
controller_Joints : in human_types_v1.controller_Joints;
|
|
Model : access openGL.Model.item'Class) return Human_v1.view
|
|
is
|
|
the_Human : constant human_v1.View := new human_v1.item;
|
|
begin
|
|
the_Human.bone_Sprites := bone_Sprites;
|
|
the_Human.controller_Joints := controller_Joints;
|
|
the_Human.Model := Model;
|
|
|
|
return the_Human;
|
|
end new_Human;
|
|
|
|
end Forge;
|
|
|
|
|
|
|
|
---------------------------
|
|
--- Skin Program Parameters
|
|
--
|
|
|
|
overriding
|
|
procedure enable (Self : in out skin_program_Parameters)
|
|
is
|
|
begin
|
|
for Each in Self.bone_Transforms'Range
|
|
loop
|
|
openGL.Program.lit.textured_skinned.view (Self.Program)
|
|
.bone_Transform_is (which => controller_joint_Id'Pos (Each) + 1,
|
|
now => Self.bone_Transforms (Each));
|
|
end loop;
|
|
end enable;
|
|
|
|
|
|
|
|
procedure set_global_Transform_for (Self : in out Item'Class;
|
|
the_Joint : in collada.Library.visual_scenes.Node_view)
|
|
is
|
|
use collada.Library, Math;
|
|
|
|
which_Joint : constant scene_joint_Id := to_joint_Id (+the_Joint.Name);
|
|
child_Joints : constant visual_scenes.Nodes := the_Joint.Children;
|
|
|
|
begin
|
|
Self.scene_Joints (which_Joint).Transform := (the_Joint.global_Transform);
|
|
|
|
declare
|
|
use type gel.Sprite.view;
|
|
|
|
the_bone_Id : bone_Id := bone_Id'Value (scene_joint_Id'Image (which_Joint));
|
|
the_global_Transform : Matrix_4x4 := the_Joint.global_Transform; -- * to_rotate_Matrix (X_Rotation_from (to_Radians (90.0)));
|
|
|
|
the_controller_Joint : controller_Joint renames Self.controller_Joints (controller_joint_Id (the_Bone_Id));
|
|
|
|
Site : Vector_3;
|
|
Rotation : Matrix_3x3;
|
|
|
|
bone_Offset : Vector_3 := the_controller_Joint.joint_to_bone_site_Offet;
|
|
begin
|
|
-- put_Line ("KKK: " & scene_joint_Id'Image (which_Joint));
|
|
|
|
if Self.bone_Sprites (the_bone_Id) /= null
|
|
then
|
|
if false -- which_Joint = Hips
|
|
then
|
|
null;
|
|
-- Site := get_Translation (the_global_Transform);
|
|
-- Site := (Site (1), Site (3), -Site (2)); -- Convert from Z-up to Y-up.
|
|
-- -- Site := get_Translation (to_translation_Matrix ( (Site (1), Site (3), -Site (2)))); -- Convert from Z-up to Y-up.
|
|
-- -- * Self.bone_Sprites (Hips).Transform);
|
|
--
|
|
-- Rotation := Inverse (get_Rotation (the_global_Transform));
|
|
-- Rotation := (1 => ( Rotation (1, 1), Rotation (1, 2), Rotation (1, 3)), -- Convert from Z-up to Y-up.
|
|
-- 2 => ( Rotation (3, 1), Rotation (3, 2), Rotation (3, 3)), --
|
|
-- 3 => (-Rotation (2, 1), -Rotation (2, 2), -Rotation (2, 3))); --
|
|
--
|
|
-- -- Rotation := Inverse (get_Rotation (Self.bone_Sprites (Hips).Transform))
|
|
-- -- * Rotation;
|
|
--
|
|
-- Site := Rotation * Site;
|
|
-- Self.bone_Sprites (the_bone_Id).Site_is (Site);
|
|
-- -- Self.bone_Sprites (the_bone_Id).Spin_is (Rotation);
|
|
else
|
|
Rotation := Inverse (get_Rotation (the_global_Transform));
|
|
Rotation := (1 => ( Rotation (1, 1), Rotation (1, 2), Rotation (1, 3)), -- Convert from Z-up to Y-up.
|
|
2 => ( Rotation (3, 1), Rotation (3, 2), Rotation (3, 3)), --
|
|
3 => (-Rotation (2, 1), -Rotation (2, 2), -Rotation (2, 3))); --
|
|
|
|
-- -- Rotation := Inverse (get_Rotation (Self.bone_Sprites (Hips).Transform))
|
|
-- Rotation := Inverse (get_Rotation (Self.skin_Sprite.Transform)) -- animation_Origin))
|
|
-- * Rotation;
|
|
-- Rotation := Rotation * get_Rotation (Self.skin_Sprite.Transform);
|
|
|
|
|
|
Site := get_Translation (the_global_Transform);
|
|
|
|
Site := Site - the_controller_Joint.joint_to_bone_site_Offet * (get_Rotation (the_global_Transform));
|
|
-- Site := Site - the_controller_Joint.joint_to_bone_site_Offet * Inverse (Rotation);
|
|
|
|
-- Site := (Site (1), Site (3), -Site (2)) -- Convert from Z-up to Y-up.
|
|
-- * get_Rotation (Self.animation_Origin);
|
|
Site := (Site (1), Site (3), -Site (2)) -- Convert from Z-up to Y-up.
|
|
* Self.skin_Sprite.Transform; -- animation_Origin);
|
|
-- * Self.bone_Sprites (Hips).Transform);
|
|
|
|
bone_Offset := (bone_Offset (1), bone_Offset (3), -bone_Offset (2));
|
|
bone_Offset := bone_Offset * (Rotation);
|
|
-- Site := Site - bone_Offset;
|
|
-- Site := Site + (bone_Offset (1), bone_Offset (3), -bone_Offset (2));
|
|
-- Site := Site + (bone_Offset (1), bone_Offset (2), bone_Offset (3));
|
|
|
|
|
|
Self.bone_Sprites (the_bone_Id).Site_is (Site);
|
|
Self.bone_Sprites (the_bone_Id).Spin_is (Rotation);
|
|
end if;
|
|
end if;
|
|
end;
|
|
|
|
Self.scene_Joints (which_Joint).Node := the_Joint; -- tbd: move this to initialisation.
|
|
|
|
for Each in child_Joints'Range
|
|
loop
|
|
set_global_Transform_for (Self, child_Joints (Each)); -- Recurse over children.
|
|
end loop;
|
|
end set_global_Transform_for;
|
|
|
|
|
|
|
|
procedure update_all_global_Transforms (Self : in out Item'Class)
|
|
is
|
|
begin
|
|
set_global_Transform_for (Self, Self.root_Joint); -- Re-determine all joint transforms, recursively.
|
|
-- Self.skin_Sprite.Transform_is (Self.animation_Origin);
|
|
end update_all_global_Transforms;
|
|
|
|
|
|
|
|
procedure set_rotation_Angle (Self : in out Item'Class; for_Joint : in scene_joint_Id;
|
|
Axis : in Axis_Kind;
|
|
To : in math.Real)
|
|
is
|
|
begin
|
|
case Axis is
|
|
when x_Axis => Self.set_x_rotation_Angle (for_Joint, To);
|
|
when y_Axis => Self.set_y_rotation_Angle (for_Joint, To);
|
|
when z_Axis => Self.set_z_rotation_Angle (for_Joint, To);
|
|
end case;
|
|
end set_rotation_Angle;
|
|
|
|
|
|
|
|
procedure set_Location (Self : in out Item'Class; for_Joint : in scene_joint_Id;
|
|
To : in math.Vector_3)
|
|
is
|
|
begin
|
|
Self.scene_Joints (for_Joint).Node.set_Location (To);
|
|
end set_Location;
|
|
|
|
|
|
|
|
procedure set_Transform (Self : in out Item'Class; for_Joint : in scene_joint_Id;
|
|
To : in math.Matrix_4x4)
|
|
is
|
|
begin
|
|
Self.scene_Joints (for_Joint).Node.set_Transform (To);
|
|
end set_Transform;
|
|
|
|
|
|
|
|
procedure set_x_rotation_Angle (Self : in out Item'Class; for_Joint : in scene_joint_Id;
|
|
To : in math.Real)
|
|
is
|
|
begin
|
|
Self.scene_Joints (for_Joint).Node.set_x_rotation_Angle (To);
|
|
end set_x_rotation_Angle;
|
|
|
|
|
|
|
|
procedure set_y_rotation_Angle (Self : in out Item'Class; for_Joint : in scene_joint_Id;
|
|
To : in math.Real)
|
|
is
|
|
begin
|
|
Self.scene_Joints (for_Joint).Node.set_y_rotation_Angle (To);
|
|
end set_y_rotation_Angle;
|
|
|
|
|
|
|
|
procedure set_z_rotation_Angle (Self : in out Item'Class; for_Joint : in scene_joint_Id;
|
|
To : in math.Real)
|
|
is
|
|
begin
|
|
Self.scene_Joints (for_Joint).Node.set_z_rotation_Angle (To);
|
|
end set_z_rotation_Angle;
|
|
|
|
|
|
|
|
procedure destroy (Self : in out Item)
|
|
is
|
|
use openGL.Model, gel.Sprite;
|
|
|
|
the_base_Sprite : gel.Sprite.view := Self.base_Sprite;
|
|
|
|
|
|
procedure free_Model_for (the_Sprite : in out gel.Sprite.view)
|
|
is
|
|
type Model_view is access all openGL.Model.item'Class;
|
|
procedure deallocate is new ada.unchecked_Deallocation (openGL.Model.item'Class, Model_view);
|
|
|
|
the_Model : Model_view := Model_view (the_sprite.graphics_Model);
|
|
the_child_Joints : constant gel.Joint.views := the_Sprite.child_Joints;
|
|
the_Child : gel.Sprite.view;
|
|
begin
|
|
if the_Sprite /= the_base_Sprite then
|
|
destroy (the_Model.all);
|
|
deallocate (the_Model);
|
|
end if;
|
|
|
|
-- do children
|
|
--
|
|
for Each in the_child_Joints'Range loop
|
|
the_Child := the_child_Joints (Each).Sprite_B.all'Access;
|
|
free_Model_for (the_Child); -- recurse
|
|
end loop;
|
|
end free_Model_for;
|
|
|
|
|
|
begin
|
|
free_Model_for (the_base_Sprite);
|
|
free (the_base_Sprite);
|
|
end destroy;
|
|
|
|
|
|
|
|
procedure free (Self : in out View)
|
|
is
|
|
procedure deallocate is new ada.Unchecked_Deallocation (Item'Class, View);
|
|
begin
|
|
Self.destroy;
|
|
deallocate (Self);
|
|
end free;
|
|
|
|
|
|
|
|
--------------
|
|
--- Human Item
|
|
--
|
|
the_global_Document : collada.Document.item;
|
|
the_global_Document_is_defined : Boolean := False;
|
|
|
|
procedure define (Self : in out Item; World : access gel .World.item'Class;
|
|
Model : access openGL .Model.item'Class;
|
|
physics_Model : access std_Physics.Model.item'Class;
|
|
Mass : in math.Real := 0.0;
|
|
is_Kinematic : in Boolean := True)
|
|
is
|
|
pragma Unreferenced (Mass);
|
|
|
|
use collada.Library,
|
|
collada.Library.visual_scenes,
|
|
math.Algebra.linear.d3,
|
|
ada.Strings,
|
|
ada.Strings.unbounded;
|
|
|
|
|
|
type gl_Model_view is access all openGL.Model.any.item;
|
|
|
|
-- the_Model : constant gl_Model_view := gl_Model_view (Model);
|
|
|
|
|
|
function the_Document return collada.Document.item
|
|
is
|
|
begin
|
|
if not the_global_Document_is_defined then
|
|
the_global_Document := collada.Document.to_Document (model_Name.all); -- tbd: free this at app close.
|
|
the_global_Document_is_defined := True;
|
|
end if;
|
|
|
|
return the_global_Document;
|
|
end the_Document;
|
|
|
|
|
|
-- the_root_Joint : visual_scenes.Node_view := the_Document.libraries.visual_Scenes.Contents (1).root_Node;
|
|
the_root_Joint : constant visual_scenes.Node_view
|
|
:= the_Document.libraries.visual_Scenes.Contents (1).root_Node.Child (1);
|
|
|
|
|
|
joint_Sites : array (scene_joint_Id) of math.Vector_3;
|
|
|
|
|
|
procedure set_Site_for (the_Joint : visual_scenes.Node_view; parent_Site : in math.Vector_3)
|
|
is
|
|
pragma Unreferenced (parent_Site);
|
|
use Math;
|
|
|
|
-- collada_Translation : collada.Vector_3 := the_Joint.Translation;
|
|
-- the_Site : math.Vector_3 := parent_Site + math.Vector_3'(math.Real (collada_Translation (1)),
|
|
-- math.Real (collada_Translation (2)),
|
|
-- math.Real (collada_Translation (3)));
|
|
which_Joint : constant scene_joint_Id := to_joint_Id (+the_Joint.Name);
|
|
child_Joints : constant visual_scenes.Nodes := the_Joint.Children;
|
|
begin
|
|
-- joint_Sites (which_Joint) := the_Site;
|
|
-- joint_Sites (which_Joint) := get_Translation (the_Joint.global_Transform);
|
|
|
|
joint_Sites (which_Joint)
|
|
:= get_Translation (Inverse (Self.controller_Joints (to_controller_joint_Id (which_Joint))
|
|
.inverse_bind_Matrix));
|
|
|
|
-- joint_Sites (which_Joint) := joint_Sites (which_Joint) * my_Scale;
|
|
|
|
for Each in child_Joints'Range
|
|
loop
|
|
set_Site_for (child_Joints (Each), parent_site => joint_Sites (which_Joint)); -- do children, recursively
|
|
end loop;
|
|
end set_Site_for;
|
|
|
|
|
|
begin
|
|
-- Set the inverse bind matrices for all joints.
|
|
--
|
|
declare
|
|
use collada.Library.controllers, Math;
|
|
|
|
the_Skin : constant controllers.Skin := the_Document.libraries.controllers.Contents (1).Skin;
|
|
the_bind_Poses : constant collada.Matrix_4x4_array := bind_Poses_of (the_Skin);
|
|
begin
|
|
for Each in Self.controller_Joints'Range
|
|
loop
|
|
Self.controller_Joints (Each).inverse_bind_Matrix
|
|
:= Transpose (the_bind_Poses (controller_joint_Id'Pos (Each) + 1)); -- Transpose to correct for collada col major.
|
|
|
|
-- Scale the site in the joints inverse bind matrix.
|
|
declare
|
|
the_Site : math.Vector_3 := get_Translation (Self.controller_Joints (Each).inverse_bind_Matrix);
|
|
begin
|
|
-- the_Site := (the_Site (1),-- * my_Scale * 1.0,
|
|
-- the_Site (2),-- * my_Scale * 1.0,
|
|
-- the_Site (3));-- * my_Scale * 1.0);
|
|
the_Site := (the_Site (1) * my_Scale * 1.0,
|
|
the_Site (2) * my_Scale * 1.0,
|
|
the_Site (3) * my_Scale * 1.0);
|
|
|
|
set_Translation (Self.controller_Joints (Each).inverse_bind_Matrix,
|
|
the_Site);
|
|
end;
|
|
end loop;
|
|
end;
|
|
|
|
|
|
set_global_Transform_for (Self, the_root_Joint); -- Determine all joint transforms, recursively.
|
|
set_Site_for (the_root_Joint, parent_site => (0.0, 0.0, 0.0)); -- Determine all joint sites.
|
|
|
|
Self.Model := Model; --.all'Unchecked_Access; -- Remember our model.
|
|
Self.root_Joint := the_root_Joint; -- Remember our root joint.
|
|
|
|
-- the_Model.Scale := (my_Scale, my_Scale, my_Scale);
|
|
|
|
|
|
-- Define a sprite for each bone.
|
|
--
|
|
declare
|
|
use openGL.Model.box.colored, openGL.Model.box,
|
|
openGL, opengl.Palette,
|
|
math.Vectors;
|
|
|
|
use type math.Degrees;
|
|
|
|
procedure create_Bone (the_Bone : in human_Types_v1.bone_Id;
|
|
start_Joint : in scene_joint_Id;
|
|
end_Point : in math.Vector_3;
|
|
Scale : in math.Vector_3;
|
|
Mass : in math.Real)
|
|
is
|
|
use Math;
|
|
|
|
the_bone_Site : constant math.Vector_3 := midPoint (joint_Sites (start_Joint), end_Point);
|
|
the_controller_Joint : controller_Joint renames Self.controller_Joints (controller_joint_Id (the_Bone));
|
|
sprite_Name : constant String := "human.bone_Sprite" & bone_Id'Image (the_Bone);
|
|
|
|
function get_Mass return math.Real
|
|
is
|
|
begin
|
|
if is_Kinematic then
|
|
return 0.0;
|
|
else
|
|
return Mass;
|
|
end if;
|
|
end get_Mass;
|
|
|
|
|
|
the_physics_Model : constant standard.physics.Model.view
|
|
:= standard.physics.Model.Forge.new_physics_Model (shape_Info => (kind => std_Physics.Model.Cube,
|
|
half_extents => Scale / 2.0),
|
|
Mass => get_Mass);
|
|
begin
|
|
-- if the_Bone = Hips
|
|
-- then
|
|
-- declare
|
|
-- the_graphics_Model : constant gel.graphics_Model.box.lit_colored_textured.view
|
|
-- := gel.graphics_Model.Box.lit_colored_textured.Forge.new_Box
|
|
-- (scale => 1.0 * (Scale (1) * my_Scale, Scale (2) * my_Scale, Scale (3) * my_Scale), -- Self.Model.Scale,
|
|
-- faces => (front => (colors => (others => (Red, Opaque)),
|
|
-- texture_Name => null_Asset,
|
|
-- texture_object => <>),
|
|
-- rear => (colors => (others => (Blue, Opaque)),
|
|
-- texture_Name => null_Asset,
|
|
-- texture_object => <>),
|
|
-- upper => (colors => (others => (Green, Opaque)),
|
|
-- texture_Name => null_Asset,
|
|
-- texture_object => <>),
|
|
-- lower => (colors => (others => (Yellow, Opaque)),
|
|
-- texture_Name => null_Asset,
|
|
-- texture_object => <>),
|
|
-- left => (colors => (others => (Cyan, Opaque)),
|
|
-- texture_Name => null_Asset,
|
|
-- texture_object => <>),
|
|
-- right => (colors => (others => (Magenta, Opaque)),
|
|
-- texture_Name => null_Asset,
|
|
-- texture_object => <>)));
|
|
--
|
|
-- -- the_human_graphics_Model : aliased gel.graphics_Model.open_gl.view
|
|
-- -- := gel.graphics_Model.open_gl.forge.new_Model (scale => (1.0, 1.0, 1.0),
|
|
-- -- -- model => gel.to_Asset ("assets/gel/model/gel-human.dae"),
|
|
-- -- model => to_Asset (model_Name.all), --gel.to_Asset ("assets/gel/collada/mh-human-dae.dae"),
|
|
-- -- -- model => gel.to_Asset ("assets/gel/collada/alfieri.dae"),
|
|
-- -- texture => gel.null_Asset, -- gel.to_Asset ("assets/collada/gel-human-texture.tga"),
|
|
-- -- Texture_is_lucid => False);
|
|
-- begin
|
|
-- -- if the_display_Mode = Skin
|
|
-- -- or the_display_Mode = Skin_and_Bones
|
|
-- -- then
|
|
-- -- Self.bone_Sprites (the_Bone) := gel.Sprite.forge.new_Sprite (sprite_Name,
|
|
-- -- World,
|
|
-- -- the_human_graphics_Model,
|
|
-- -- -- Model,
|
|
-- -- the_physics_Model,
|
|
-- -- owns_graphics => True,
|
|
-- -- owns_physics => True,
|
|
-- -- is_kinematic => is_Kinematic);
|
|
-- -- else
|
|
-- Self.bone_Sprites (the_Bone) := gel.Sprite.forge.new_Sprite (sprite_Name,
|
|
-- World,
|
|
-- the_graphics_Model,
|
|
-- the_physics_Model,
|
|
-- owns_graphics => True,
|
|
-- owns_physics => True,
|
|
-- is_kinematic => is_Kinematic);
|
|
--
|
|
-- -- end if;
|
|
-- end;
|
|
-- else
|
|
declare
|
|
the_graphics_Model : constant openGL.Model.box.colored.view
|
|
:= openGL.Model.Box.colored.new_Box
|
|
(Size => (Scale (1) * my_Scale, Scale (2) * my_Scale, Scale (3) * my_Scale),
|
|
Faces => (front => (colors => (others => (Red, Opaque))),
|
|
rear => (colors => (others => (Blue, Opaque))),
|
|
upper => (colors => (others => (Green, Opaque))),
|
|
lower => (colors => (others => (Yellow, Opaque))),
|
|
left => (colors => (others => (Cyan, Opaque))),
|
|
right => (colors => (others => (Magenta, Opaque)))));
|
|
begin
|
|
Self.bone_Sprites (the_Bone) := gel.Sprite.forge.new_Sprite (Name => sprite_Name,
|
|
World => gel.sprite.World_view (World),
|
|
graphics_Model => the_graphics_Model,
|
|
physics_Model => the_physics_Model,
|
|
owns_graphics => True,
|
|
owns_physics => True,
|
|
is_kinematic => is_Kinematic);
|
|
if the_display_Mode = Skin
|
|
then
|
|
Self.bone_Sprites (the_Bone).is_Visible (False);
|
|
end if;
|
|
end;
|
|
-- end if;
|
|
|
|
-- the_bone_Site := the_bone_Site * my_Scale;
|
|
|
|
Self.bone_Sprites (the_Bone).Site_is (the_bone_Site);
|
|
|
|
-- if the_Bone = Hips
|
|
-- then
|
|
-- Self.bone_Sprites (the_Bone).Spin_is (get_Rotation (the_controller_Joint.inverse_bind_Matrix)); -- * x_Rotation_from (to_Radians (180.0)));
|
|
-- else
|
|
Self.bone_Sprites (the_Bone).Spin_is (get_Rotation (the_controller_Joint.inverse_bind_Matrix));
|
|
-- end if;
|
|
|
|
the_controller_Joint.joint_to_bone_site_Offet
|
|
:= Inverse (get_Rotation (the_controller_Joint.inverse_bind_Matrix))
|
|
* (joint_Sites (start_Joint) - the_bone_Site);
|
|
end create_Bone;
|
|
|
|
|
|
procedure attach_via_Ball (bone_A_Id,
|
|
bone_B_Id : in Bone_Id;
|
|
pitch_limits,
|
|
yaw_limits,
|
|
roll_Limits : in gel.Sprite.dof_limits := (math.to_Radians (-0.0),
|
|
math.to_Radians ( 0.0))) -- -20.0 .. 20.0
|
|
is
|
|
use Math;
|
|
joint_Id : constant controller_joint_Id
|
|
:= controller_joint_Id (bone_B_Id);
|
|
|
|
the_joint_Site : constant math.Vector_3
|
|
:= joint_Sites (scene_joint_id'Value (bone_id'Image (bone_B_Id)));
|
|
|
|
Bone_A : constant gel.Sprite.view := Self.bone_Sprites (bone_A_Id);
|
|
Bone_B : constant gel.Sprite.view := Self.bone_Sprites (bone_B_Id);
|
|
|
|
Frame_A : math.Matrix_4x4 := Self.controller_Joints (controller_joint_Id (bone_A_Id)).inverse_bind_Matrix;
|
|
Frame_B : math.Matrix_4x4 := Self.controller_Joints (controller_joint_Id (bone_B_Id)).inverse_bind_Matrix;
|
|
|
|
A_rot : constant math.Matrix_3x3 := inverse (get_Rotation (Frame_A));
|
|
B_rot : constant math.Matrix_3x3 := inverse (get_Rotation (Frame_B));
|
|
|
|
begin
|
|
set_Translation (Frame_A, A_rot * (the_joint_Site - Bone_A.Site));
|
|
set_Translation (Frame_B, B_rot * (the_joint_Site - Bone_B.Site));
|
|
-- set_Translation (Frame_A, A_rot * (the_joint_Site - Bone_A.Site) * my_Scale);
|
|
-- set_Translation (Frame_B, B_rot * (the_joint_Site - Bone_B.Site) * my_Scale);
|
|
|
|
-- if bone_A_Id = hips
|
|
-- and bone_B_Id = spine1
|
|
-- then
|
|
-- set_Rotation (Frame_B, X_Rotation_from (to_Radians (180.0)));
|
|
-- end if;
|
|
|
|
|
|
Self.bone_Sprites (bone_A_Id).attach_via_ball_Socket (Self.bone_Sprites (bone_B_Id),
|
|
frame_in_parent => Frame_A,
|
|
frame_in_child => Frame_B,
|
|
pitch_limits => pitch_Limits,
|
|
yaw_limits => yaw_limits,
|
|
roll_limits => roll_limits,
|
|
new_joint => Self.Joints (joint_Id));
|
|
end attach_via_Ball;
|
|
|
|
|
|
procedure attach_via_Hinge (bone_A_Id,
|
|
bone_B_Id : in Bone_Id;
|
|
Limits : in gel.Sprite.dof_limits := (math.to_Radians ( 0.0),
|
|
math.to_Radians (90.0)))
|
|
is
|
|
use Math;
|
|
joint_Id : constant controller_joint_Id
|
|
:= controller_joint_Id (bone_B_Id);
|
|
|
|
the_joint_Site : constant math.Vector_3
|
|
:= joint_Sites (scene_joint_id'Value (bone_id'Image (bone_B_Id)));
|
|
|
|
Bone_A : constant gel.Sprite.view := Self.bone_Sprites (bone_A_Id);
|
|
Bone_B : constant gel.Sprite.view := Self.bone_Sprites (bone_B_Id);
|
|
|
|
Frame_A : math.Matrix_4x4 := Self.controller_Joints (controller_joint_Id (bone_A_Id)).inverse_bind_Matrix;
|
|
Frame_B : math.Matrix_4x4 := Self.controller_Joints (controller_joint_Id (bone_B_Id)).inverse_bind_Matrix;
|
|
|
|
A_rot : constant math.Matrix_3x3 := inverse (get_Rotation (Frame_A));
|
|
B_rot : constant math.Matrix_3x3 := inverse (get_Rotation (Frame_B));
|
|
begin
|
|
set_Translation (Frame_A, A_rot * (the_joint_Site - Bone_A.Site));
|
|
set_Translation (Frame_B, B_rot * (the_joint_Site - Bone_B.Site));
|
|
-- set_Translation (Frame_A, A_rot * (the_joint_Site - Bone_A.Site) * my_Scale);
|
|
-- set_Translation (Frame_B, B_rot * (the_joint_Site - Bone_B.Site) * my_Scale);
|
|
|
|
set_Rotation (Frame_A, A_rot * z_rotation_from (math.to_Radians (-90.0)));
|
|
set_Rotation (Frame_B, B_rot * z_rotation_from (math.to_Radians (-90.0)));
|
|
|
|
|
|
Self.bone_Sprites (bone_A_Id).attach_via_Hinge (Self.bone_Sprites (bone_B_Id),
|
|
Frame_in_parent => Frame_A,
|
|
Frame_in_child => Frame_B,
|
|
Limits => Limits,
|
|
collide_Connected => False,
|
|
new_Joint => Self.Joints (joint_Id));
|
|
end attach_via_Hinge;
|
|
|
|
use Math;
|
|
|
|
|
|
bone_Extent : math.Real;
|
|
|
|
begin
|
|
-- Skin
|
|
--
|
|
declare
|
|
the_human_graphics_Model : aliased openGL.Model.any.view
|
|
:= openGL.Model.any.new_Model (Model => to_Asset (model_Name.all),
|
|
Texture => openGL.null_Asset, -- gel.to_Asset ("assets/collada/gel-human-texture.tga"),
|
|
texture_Details => openGL.texture_Set.to_Details ([1 => openGL.to_Asset ("./assets/opengl/texture/wooden-crate.jpg")]),
|
|
Texture_is_lucid => False);
|
|
|
|
the_physics_Model : constant standard.physics.Model.view
|
|
:= standard.physics.Model.Forge.new_physics_Model (shape_Info => (Kind => standard.physics.Model.Cube,
|
|
half_Extents => (0.1, 0.1, 0.1)),
|
|
Mass => 1.0,
|
|
is_Tangible => False);
|
|
begin
|
|
Self.skin_Sprite := gel.Sprite.forge.new_Sprite (Name => "human.skin_Sprite",
|
|
World => gel.sprite.World_view (World),
|
|
graphics_Model => the_human_graphics_Model,
|
|
physics_Model =>the_physics_Model,
|
|
owns_graphics => True,
|
|
owns_physics => True,
|
|
is_kinematic => is_Kinematic);
|
|
if the_display_Mode = Bones
|
|
then
|
|
Self.skin_Sprite.is_Visible (False);
|
|
end if;
|
|
end;
|
|
|
|
|
|
-- Hips
|
|
--
|
|
bone_Extent := 0.25 * Distance (joint_Sites (Hips), to => joint_Sites (Spine));
|
|
create_Bone (Hips,
|
|
Hips,
|
|
joint_Sites (Spine),
|
|
bone_Extent * (1.3, 0.6, 0.6),
|
|
Mass => 1.0);
|
|
|
|
|
|
-- Thigh_L
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Thigh_L), to => joint_Sites (Shin_L));
|
|
create_Bone (Thigh_L, Thigh_L, joint_Sites (Shin_L), (0.25, 0.5, 0.25) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (bone_A_Id => Hips,
|
|
bone_B_Id => Thigh_L,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_Limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Shin_L
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Shin_L), to => joint_Sites (Foot_L));
|
|
create_Bone (Shin_L, Shin_L, joint_Sites (Foot_L), (0.2, 0.8, 0.2) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (bone_A_Id => Thigh_L,
|
|
bone_B_Id => Shin_L,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_Limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Foot_L
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Foot_L), to => joint_Sites (Toe_L));
|
|
create_Bone (Foot_L, Foot_L, joint_Sites (Toe_L), (0.4, 0.8, 0.2) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (bone_A_Id => Shin_L,
|
|
bone_B_Id => Foot_L,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_Limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Toe_L
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Toe_L), to => joint_Sites (Foot_L));
|
|
create_Bone (Toe_L, Toe_L, joint_Sites (Toe_L) + (0.0, -0.05, 0.0), (0.6, 0.3, 0.1) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (bone_A_Id => Foot_L,
|
|
bone_B_Id => Toe_L,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_Limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Thigh_R
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Thigh_R), to => joint_Sites (Shin_R));
|
|
create_Bone (Thigh_R, Thigh_R, joint_Sites (Shin_R), (0.25, 0.5, 0.25) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (bone_A_Id => Hips,
|
|
bone_B_Id => Thigh_R,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_Limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Shin_R
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Shin_R), to => joint_Sites (Foot_R));
|
|
create_Bone (Shin_R, Shin_R, joint_Sites (Foot_R), (0.2, 0.8, 0.2) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (bone_A_Id => Thigh_R,
|
|
bone_B_Id => Shin_R,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_Limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Foot_R
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Foot_R), to => joint_Sites (Toe_R));
|
|
create_Bone (Foot_R, Foot_R, joint_Sites (Toe_R), (0.4, 0.8, 0.2) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (bone_A_Id => Shin_R,
|
|
bone_B_Id => Foot_R,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_Limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Toe_R
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Toe_R), to => joint_Sites (Foot_R));
|
|
create_Bone (Toe_R, Toe_R, joint_Sites (Toe_R) + (0.0, -0.05, 0.0), (0.6, 0.3, 0.1) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (bone_A_Id => Foot_R,
|
|
bone_B_Id => Toe_R,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_Limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Spine
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Spine), to => joint_Sites (Chest));
|
|
create_Bone (Spine, Spine, joint_Sites (Chest), (1.4, 0.6, 0.9) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (bone_A_Id => Hips,
|
|
bone_B_Id => Spine,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_Limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Chest
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Chest), to => joint_Sites (Neck));
|
|
create_Bone (Chest, Chest, joint_Sites (Neck), (0.8, 0.2, 0.20) * bone_Extent, 0.5); -- 0.6 * 0.5);
|
|
|
|
attach_via_Ball (bone_A_Id => Spine,
|
|
bone_B_Id => Chest,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_Limits => (-0.5, 0.5));
|
|
|
|
|
|
--- Right Arm
|
|
--
|
|
|
|
-- Right Clavicle
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Clavicle_R), to => joint_Sites (upper_Arm_R));
|
|
create_Bone (Clavicle_R, Clavicle_R, joint_Sites (upper_Arm_R), (0.25, 0.25, 0.25) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (Chest, Clavicle_R,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Right Upper Arm
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (upper_Arm_R), to => joint_Sites (Forearm_R));
|
|
create_Bone (upper_Arm_R, upper_Arm_R, joint_Sites (Forearm_R), (0.2, 0.7, 0.2) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (Clavicle_R, upper_Arm_R,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Right Forearm
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Forearm_R), to => joint_Sites (Hand_R));
|
|
create_Bone (Forearm_R, Forearm_R, joint_Sites (Hand_R), (0.2, 0.8, 0.2) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (upper_Arm_R, Forearm_R,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Right Hand
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Hand_R), to => joint_Sites (Thumb_02_R));
|
|
create_Bone (Hand_R, Hand_R, joint_Sites (Thumb_02_R) - (0.0, 0.0, 0.0), (0.8, 0.9, 0.2) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (Forearm_R, Hand_R,
|
|
pitch_limits => (-0.5, 0.0),
|
|
yaw_limits => (-0.5, 0.0),
|
|
roll_limits => (-0.0, 0.0));
|
|
|
|
-- -- Right Thumb_02
|
|
-- --
|
|
-- bone_Extent := 1.0 * Distance (joint_Sites (Thumb_02_R), to => joint_Sites (Hand_R));
|
|
-- create_Bone (Thumb_02_R, Thumb_02_R, joint_Sites (Hand_R) - (0.5, 0.0, 0.0), (0.4, 0.15, 0.08) * bone_Extent, 0.5);
|
|
--
|
|
-- attach_via_Ball (Hand_R, Thumb_02_R,
|
|
-- pitch_limits => (-0.5, 0.0),
|
|
-- yaw_limits => (-0.5, 0.0),
|
|
-- roll_limits => (-0.0, 0.0));
|
|
--
|
|
-- -- Right Thumb_03
|
|
-- --
|
|
-- bone_Extent := 1.0 * Distance (joint_Sites (Thumb_03_R), to => joint_Sites (Hand_R));
|
|
-- create_Bone (Thumb_03_R, Thumb_03_R, joint_Sites (Hand_R) - (0.5, 0.0, 0.0), (0.4, 0.15, 0.08) * bone_Extent, 0.5);
|
|
--
|
|
-- attach_via_Ball (Hand_R, Thumb_03_R,
|
|
-- pitch_limits => (-0.5, 0.0),
|
|
-- yaw_limits => (-0.5, 0.0),
|
|
-- roll_limits => (-0.0, 0.0));
|
|
--
|
|
-- -- Right Index Finger
|
|
-- --
|
|
-- bone_Extent := 1.0 * Distance (joint_Sites (F_ring_01_R), to => joint_Sites (Hand_R));
|
|
-- create_Bone (F_ring_01_R, F_ring_01_R, joint_Sites (Hand_R) - (0.5, 0.0, 0.0), (0.4, 0.15, 0.08) * bone_Extent, 0.5);
|
|
--
|
|
-- attach_via_Ball (Hand_R, F_ring_01_R,
|
|
-- pitch_limits => (-0.5, 0.0),
|
|
-- yaw_limits => (-0.5, 0.0),
|
|
-- roll_limits => (-0.0, 0.0));
|
|
--
|
|
-- -- Right Ring Finger
|
|
-- --
|
|
-- bone_Extent := 1.0 * Distance (joint_Sites (F_index_01_R), to => joint_Sites (Hand_R));
|
|
-- create_Bone (F_index_01_R, F_index_01_R, joint_Sites (Hand_R) - (0.5, 0.0, 0.0), (0.4, 0.15, 0.08) * bone_Extent, 0.5);
|
|
--
|
|
-- attach_via_Ball (Hand_R, F_index_01_R,
|
|
-- pitch_limits => (-0.5, 0.0),
|
|
-- yaw_limits => (-0.5, 0.0),
|
|
-- roll_limits => (-0.0, 0.0));
|
|
|
|
|
|
--- Left Arm
|
|
--
|
|
|
|
-- Left Clavicle
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Clavicle_L), to => joint_Sites (upper_Arm_L));
|
|
create_Bone (Clavicle_L, Clavicle_L, joint_Sites (upper_Arm_L), (0.25, 0.25, 0.25) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (Chest, Clavicle_L,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Left Upper Arm
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (upper_Arm_L), to => joint_Sites (Forearm_L));
|
|
create_Bone (upper_Arm_L, upper_Arm_L, joint_Sites (Forearm_L), (0.2, 0.7, 0.2) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (Clavicle_L, upper_Arm_L,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Left Forearm
|
|
--
|
|
bone_Extent := 0.75 * Distance (joint_Sites (Forearm_L), to => joint_Sites (Hand_L));
|
|
create_Bone (Forearm_L, Forearm_L, joint_Sites (Hand_L), (0.2, 0.8, 0.2) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (upper_Arm_L, Forearm_L,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_limits => (-0.5, 0.5));
|
|
|
|
|
|
-- Left Hand
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Hand_L), to => joint_Sites (Thumb_02_L));
|
|
create_Bone (Hand_L, Hand_L, joint_Sites (Thumb_02_L) - (0.0, 0.0, 0.0), (0.8, 0.9, 0.2) * bone_Extent, 0.5);
|
|
|
|
attach_via_Ball (Forearm_L, Hand_L,
|
|
pitch_limits => (-0.5, 0.0),
|
|
yaw_limits => (-0.5, 0.0),
|
|
roll_limits => (-0.0, 0.0));
|
|
|
|
|
|
-- -- Left Thumb_02
|
|
-- --
|
|
-- bone_Extent := 1.0 * Distance (joint_Sites (Thumb_02_L), to => joint_Sites (Hand_L));
|
|
-- create_Bone (Thumb_02_L, Thumb_02_L, joint_Sites (Hand_L) + (0.5, 0.0, 0.0), (0.4, 0.15, 0.08) * bone_Extent, 0.5);
|
|
--
|
|
-- attach_via_Ball (Hand_L, Thumb_02_L,
|
|
-- pitch_limits => (-0.5, 0.0),
|
|
-- yaw_limits => (-0.5, 0.0),
|
|
-- roll_limits => (-0.0, 0.0));
|
|
--
|
|
-- -- Left Thumb_03
|
|
-- --
|
|
-- bone_Extent := 1.0 * Distance (joint_Sites (Thumb_03_L), to => joint_Sites (Hand_L));
|
|
-- create_Bone (Thumb_03_L, Thumb_03_L, joint_Sites (Hand_L) + (0.5, 0.0, 0.0), (0.4, 0.15, 0.08) * bone_Extent, 0.5);
|
|
--
|
|
-- attach_via_Ball (Hand_L, Thumb_03_L,
|
|
-- pitch_limits => (-0.5, 0.0),
|
|
-- yaw_limits => (-0.5, 0.0),
|
|
-- roll_limits => (-0.0, 0.0));
|
|
--
|
|
-- -- Left Index Finger
|
|
-- --
|
|
-- bone_Extent := 1.0 * Distance (joint_Sites (F_ring_01_L), to => joint_Sites (Hand_L));
|
|
-- create_Bone (F_ring_01_L, F_ring_01_L, joint_Sites (Hand_L) + (0.5, 0.0, 0.0), (0.4, 0.15, 0.08) * bone_Extent, 0.5);
|
|
--
|
|
-- attach_via_Ball (Hand_L, F_ring_01_L,
|
|
-- pitch_limits => (-0.5, 0.0),
|
|
-- yaw_limits => (-0.5, 0.0),
|
|
-- roll_limits => (-0.0, 0.0));
|
|
--
|
|
-- -- Left Ring Finger
|
|
-- --
|
|
-- bone_Extent := 1.0 * Distance (joint_Sites (F_index_01_L), to => joint_Sites (Hand_L));
|
|
-- create_Bone (F_index_01_L, F_index_01_L, joint_Sites (Hand_L) + (0.5, 0.0, 0.0), (0.4, 0.15, 0.08) * bone_Extent, 0.5);
|
|
--
|
|
-- attach_via_Ball (Hand_L, F_index_01_L,
|
|
-- pitch_limits => (-0.5, 0.0),
|
|
-- yaw_limits => (-0.5, 0.0),
|
|
-- roll_limits => (-0.0, 0.0));
|
|
|
|
|
|
-- Neck
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Neck), to => joint_Sites (Head));
|
|
create_Bone (Neck, Neck, joint_Sites (Head), (0.4, 0.6, 0.4) * bone_Extent, 0.4); -- 0.4 * 0.5);
|
|
|
|
attach_via_Ball (bone_A_Id => Chest,
|
|
bone_B_Id => Neck,
|
|
pitch_limits => (-0.4, 0.3),
|
|
yaw_limits => (-0.3, 0.3),
|
|
roll_Limits => (-0.2, 0.2));
|
|
|
|
|
|
-- Head
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Head), to => joint_Sites (Neck));
|
|
create_Bone (Head, Head, joint_Sites (Head) + (0.0, 0.0, 0.05), (0.8, 0.6, 0.7) * bone_Extent, 0.25);
|
|
|
|
attach_via_Ball (bone_A_Id => Neck,
|
|
bone_B_Id => Head,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_Limits => (-0.5, 0.5));
|
|
|
|
-- Jaw
|
|
--
|
|
bone_Extent := 1.0 * Distance (joint_Sites (Jaw), to => joint_Sites (Head));
|
|
create_Bone (Jaw, Jaw, joint_Sites (Jaw) + (0.0, -0.07, 0.03), (0.9, 1.0, 0.3) * bone_Extent, 0.25);
|
|
|
|
attach_via_Ball (bone_A_Id => Head,
|
|
bone_B_Id => Jaw,
|
|
pitch_limits => (-0.5, 0.5),
|
|
yaw_limits => (-0.5, 0.5),
|
|
roll_Limits => (-0.5, 0.5));
|
|
|
|
-- -- Eye_R
|
|
-- --
|
|
-- bone_Extent := 0.1 * Distance (joint_Sites (Eye_R), to => joint_Sites (Head));
|
|
-- create_Bone (Eye_R, Eye_R, joint_Sites (Eye_R) + (0.0, 0.0, 0.0), (1.0, 1.4, 0.7) * bone_Extent, 0.25);
|
|
--
|
|
-- attach_via_Ball (Head, Eye_R);
|
|
--
|
|
-- -- Eye_L
|
|
-- --
|
|
-- bone_Extent := 0.1 * Distance (joint_Sites (Eye_L), to => joint_Sites (Head));
|
|
-- create_Bone (Eye_L, Eye_L, joint_Sites (Eye_L) + (0.0, 0.0, 0.0), (1.0, 1.4, 0.7) * bone_Extent, 0.25);
|
|
--
|
|
-- attach_via_Ball (Head, Eye_L);
|
|
end;
|
|
|
|
|
|
--- Parse the Collada animations file.
|
|
--
|
|
declare
|
|
use collada.Library.animations;
|
|
the_Animations : constant access animations.Animation_array := the_Document.Libraries.Animations.Contents;
|
|
begin
|
|
if the_Animations /= null
|
|
then
|
|
for Each in the_Animations'Range
|
|
loop
|
|
declare
|
|
the_Animation : constant animations.Animation := the_Animations (Each);
|
|
the_Inputs : access collada.float_Array := Inputs_of (the_Animation);
|
|
|
|
procedure common_setup (Channel : channel_Id; scene_Joint : scene_Joint_Id; Sid : in String)
|
|
is
|
|
begin
|
|
Self.Channels (Channel).Target := Self.scene_Joints (scene_Joint).Node.fetch_Transform (Sid);
|
|
Self.Channels (Channel).Times := Inputs_of (the_Animation);
|
|
Self.Channels (Channel).Values := Outputs_of (the_Animation);
|
|
|
|
for Each in Self.Channels (Channel).Times'Range
|
|
loop
|
|
Self.Channels (Channel).Times (Each) := Self.Channels (Channel).Times (Each) / 1.0; -- ???
|
|
end loop;
|
|
end common_setup;
|
|
|
|
procedure setup_Rotation (Channel : channel_Id; scene_Joint : scene_Joint_Id; Sid : in String)
|
|
is
|
|
begin
|
|
common_setup (Channel, scene_Joint, Sid);
|
|
|
|
-- For angle interpolation during 'rotation' animation.
|
|
--
|
|
Self.Channels (Channel).initial_Angle := Self.Channels (Channel).Values (1);
|
|
Self.Channels (Channel).current_Angle := Self.Channels (Channel).initial_Angle;
|
|
end setup_Rotation;
|
|
|
|
procedure setup_Location (Channel : channel_Id; scene_Joint : scene_Joint_Id; Sid : in String)
|
|
is
|
|
begin
|
|
common_setup (Channel, scene_Joint, Sid);
|
|
|
|
-- For location interpolation during 'translation' animation.
|
|
--
|
|
Self.Channels (Channel).current_Site := (Self.Channels (Channel).Values (1),
|
|
Self.Channels (Channel).Values (2),
|
|
Self.Channels (Channel).Values (3));
|
|
Self.Channels (Channel).initial_Site := Self.Channels (Channel).current_Site;
|
|
end setup_Location;
|
|
|
|
procedure setup_full_Transform (Channel : channel_Id; scene_Joint : scene_Joint_Id; Sid : in String)
|
|
is
|
|
begin
|
|
common_setup (Channel, scene_Joint, Sid);
|
|
|
|
-- For matrix interpolation during 'full_transform' animation.
|
|
--
|
|
Self.Channels (Channel).Transforms := new Transforms (1 .. Collada.matrix_Count (Self.Channels (Channel).Values.all));
|
|
|
|
for i in Self.Channels (Channel).Transforms'Range
|
|
loop
|
|
declare
|
|
the_Matrix : math.Matrix_4x4 := math.Transpose (Collada.get_Matrix (Self.Channels (Channel).Values.all, which => i));
|
|
begin
|
|
Self.Channels (Channel).Transforms (i) := (rotation => to_Quaternion (get_Rotation (the_Matrix)),
|
|
translation => get_Translation (the_Matrix));
|
|
end;
|
|
|
|
end loop;
|
|
|
|
Self.Channels (Channel).initial_Transform := Self.Channels (Channel).Transforms (1);
|
|
Self.Channels (Channel).current_Transform := Self.Channels (Channel).initial_Transform;
|
|
|
|
Self.Channels (Channel).current_Site := Self.Channels (Channel).initial_Transform.Translation;
|
|
Self.Channels (Channel).initial_Site := Self.Channels (Channel).current_Site;
|
|
end setup_full_Transform;
|
|
|
|
begin
|
|
if Index (the_Animation.Channel.Target, "hips/transform") /= 0 then
|
|
setup_full_Transform (Hips, Hips, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "thigh_L/transform") /= 0 then
|
|
setup_full_Transform (Thigh_L, Thigh_L, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "shin_L/transform") /= 0 then
|
|
setup_full_Transform (Shin_L, Shin_L, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "foot_L/transform") /= 0 then
|
|
setup_full_Transform (Foot_L, Foot_L, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "toe_L/transform") /= 0 then
|
|
setup_full_Transform (Toe_L, Toe_L, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "thigh_R/transform") /= 0 then
|
|
setup_full_Transform (Thigh_R, Thigh_R, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "shin_R/transform") /= 0 then
|
|
setup_full_Transform (Shin_R, Shin_R, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "foot_R/transform") /= 0 then
|
|
setup_full_Transform (Foot_R, Foot_R, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "toe_R/transform") /= 0 then
|
|
setup_full_Transform (Toe_R, Toe_R, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "spine/transform") /= 0 then
|
|
setup_full_Transform (Spine, Spine, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "chest/transform") /= 0 then
|
|
setup_full_Transform (Chest, Chest, "transform");
|
|
|
|
|
|
elsif Index (the_Animation.Channel.Target, "clavicle_R/transform") /= 0 then
|
|
setup_full_Transform (Clavicle_R, Clavicle_R, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "upper_arm_R/transform") /= 0 then
|
|
setup_full_Transform (upper_Arm_R, upper_Arm_R, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "forearm_R/transform") /= 0 then
|
|
setup_full_Transform (Forearm_R, Forearm_R, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "hand_R/transform") /= 0 then
|
|
setup_full_Transform (Hand_R, Hand_R, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "thumb_02_R/transform") /= 0 then
|
|
setup_full_Transform (Thumb_02_R, Thumb_02_R, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "thumb_03_R/transform") /= 0 then
|
|
setup_full_Transform (Thumb_03_R, Thumb_03_R, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "f_ring_01_R/transform") /= 0 then
|
|
setup_full_Transform (F_ring_01_R, F_ring_01_R, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "f_index_01_R/transform") /= 0 then
|
|
setup_full_Transform (F_index_01_R, F_index_01_R, "transform");
|
|
|
|
|
|
elsif Index (the_Animation.Channel.Target, "clavicle_L/transform") /= 0 then
|
|
setup_full_Transform (Clavicle_L, Clavicle_L, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "upper_arm_L/transform") /= 0 then
|
|
setup_full_Transform (upper_Arm_L, upper_Arm_L, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "forearm_L/transform") /= 0 then
|
|
setup_full_Transform (Forearm_L, Forearm_L, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "hand_L/transform") /= 0 then
|
|
setup_full_Transform (Hand_L, Hand_L, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "thumb_02_L/transform") /= 0 then
|
|
setup_full_Transform (Thumb_02_L, Thumb_02_L, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "thumb_03_L/transform") /= 0 then
|
|
setup_full_Transform (Thumb_03_L, Thumb_03_L, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "f_ring_01_L/transform") /= 0 then
|
|
setup_full_Transform (F_ring_01_L, F_ring_01_L, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "f_index_01_L/transform") /= 0 then
|
|
setup_full_Transform (F_index_01_L, F_index_01_L, "transform");
|
|
|
|
|
|
elsif Index (the_Animation.Channel.Target, "neck/transform") /= 0 then
|
|
setup_full_Transform (Neck, Neck, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "head/transform") /= 0 then
|
|
setup_full_Transform (Head, Head, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "jaw/transform") /= 0 then
|
|
setup_full_Transform (Jaw, Jaw, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "eye_R/transform") /= 0 then
|
|
setup_full_Transform (Eye_R, Eye_R, "transform");
|
|
|
|
elsif Index (the_Animation.Channel.Target, "eye_L/transform") /= 0 then
|
|
setup_full_Transform (Eye_L, Eye_L, "transform");
|
|
end if;
|
|
end;
|
|
end loop;
|
|
end if;
|
|
|
|
end;
|
|
|
|
end define;
|
|
|
|
|
|
|
|
procedure motion_Mode_is (Self : in out Item; Now : in motion_Mode)
|
|
is
|
|
begin
|
|
Self.Mode := Now;
|
|
end motion_Mode_is;
|
|
|
|
|
|
|
|
procedure enable_Graphics (Self : in out Item)
|
|
is
|
|
begin
|
|
if the_display_Mode /= Bones
|
|
then
|
|
Self.program_Parameters.Program_is (opengl.Program.view (opengl.Geometry.lit_textured_skinned.Program));
|
|
Self.skin_Sprite.program_Parameters_are (Self.program_Parameters'Unchecked_Access);
|
|
-- Self.base_Sprite.program_Parameters_are (Self.program_Parameters'Unchecked_Access);
|
|
end if;
|
|
end enable_Graphics;
|
|
|
|
|
|
|
|
function controller_Joints (Self : in Item'Class) return human_types_v1.controller_Joints
|
|
is
|
|
begin
|
|
return Self.controller_Joints;
|
|
end controller_Joints;
|
|
|
|
|
|
|
|
procedure controller_Joints_are (Self : in out Item'Class; Now : in human_types_v1.controller_Joints)
|
|
is
|
|
begin
|
|
Self.controller_Joints := Now;
|
|
end controller_Joints_are;
|
|
|
|
|
|
--------------
|
|
--- Attributes
|
|
--
|
|
|
|
function Sprite (Self : in Item'Class; for_Bone : in bone_Id) return gel.Sprite.view
|
|
is
|
|
begin
|
|
return Self.bone_Sprites (for_Bone);
|
|
end Sprite;
|
|
|
|
|
|
|
|
function base_Sprite (Self : in Item'Class) return gel.Sprite.view
|
|
is
|
|
begin
|
|
return Self.bone_Sprites (Hips);
|
|
end base_Sprite;
|
|
|
|
|
|
|
|
function skin_Sprite (Self : in Item'Class) return gel.Sprite.view
|
|
is
|
|
begin
|
|
return Self.skin_Sprite;
|
|
end skin_Sprite;
|
|
|
|
|
|
|
|
procedure set_GL_program_Parameters (Self : in out Item'Class; for_Bone : in controller_joint_Id;
|
|
To : in math.Matrix_4x4)
|
|
is
|
|
use gel.Conversions;
|
|
begin
|
|
Self.program_Parameters.bone_Transforms (for_Bone) := to_GL (To);
|
|
end set_GL_program_Parameters;
|
|
|
|
|
|
--------------
|
|
--- Operations
|
|
--
|
|
|
|
procedure evolve (Self : in out Item'Class; world_Age : in Duration)
|
|
is
|
|
use Math, math.Vectors;
|
|
|
|
|
|
function get_root_Transform return math.Matrix_4x4
|
|
is
|
|
begin
|
|
if Self.Mode = Physics
|
|
then
|
|
put_Line ("Self.base_Sprite.Transform: ");
|
|
put_Line (math.Image (math.Matrix (Self.base_Sprite.Transform)));
|
|
return Self.base_Sprite.Transform;
|
|
-- return math.Identity_4x4;
|
|
-- return to_transform_Matrix (Rotation => x_Rotation_from (the_Angle => to_Radians (-90.0)),
|
|
-- Translation => (0.0, 0.0, 0.0));
|
|
|
|
else -- Is an animation.
|
|
-- return (Self.skin_Sprite.Transform);
|
|
-- return Inverse (Self.animation_Origin);
|
|
|
|
declare
|
|
the_Transform : math.Matrix_4x4 := math.Identity_4x4;
|
|
begin
|
|
set_Rotation (the_Transform, x_Rotation_from (to_Radians (-90.0))); -- Convert from Z-up to Y-up.
|
|
-- set_Rotation (the_Transform, Inverse (get_Rotation ( (Self.controller_Joints (Hips).inverse_bind_Matrix))));
|
|
set_Translation (the_Transform,
|
|
-- -get_Translation (Inverse (Self.animation_Origin)));
|
|
-get_Translation (Inverse (Self.controller_Joints (Hips).inverse_bind_Matrix)));
|
|
return the_Transform;
|
|
end;
|
|
end if;
|
|
end get_root_Transform;
|
|
|
|
|
|
root_Transform : constant math.Matrix_4x4 := get_root_Transform;
|
|
inv_root_Transform : constant math.Matrix_4x4 := Inverse (root_Transform);
|
|
|
|
|
|
function joint_Transform_for (the_collada_Joint : in controller_joint_Id) return math.Matrix_4x4
|
|
is
|
|
begin
|
|
-- put_Line ("KKKKKKKK: '" & controller_joint_Id'Image (the_collada_Joint) & "'");
|
|
|
|
if Self.Mode = Physics
|
|
then
|
|
declare
|
|
the_bone_Transform : constant math.Matrix_4x4
|
|
:= Self.bone_Sprites (bone_Id (the_collada_Joint)).Transform;
|
|
|
|
the_bone_Rotation : constant math.Matrix_3x3
|
|
:= get_Rotation (the_bone_Transform);
|
|
-- the_inv_bone_Rotation : math.Matrix_3x3 := Inverse (the_bone_Rotation);
|
|
|
|
the_joint_site_Offset : constant math.Vector_3
|
|
:= Self.controller_Joints (the_collada_Joint).joint_to_bone_site_Offet * the_bone_Rotation;
|
|
|
|
the_joint_Transform : math.Matrix_4x4;
|
|
begin
|
|
set_Translation (the_joint_Transform, get_Translation (the_bone_Transform) + the_joint_site_Offset);
|
|
set_Rotation (the_joint_Transform, get_Rotation (the_bone_Transform));
|
|
|
|
return the_joint_Transform;
|
|
end;
|
|
|
|
else -- Must be animation mode.
|
|
return Self.scene_Joints (to_scene_joint_Id (the_collada_Joint)).Transform;
|
|
end if;
|
|
end joint_Transform_for;
|
|
|
|
|
|
|
|
procedure set_Transform_for (the_Bone : in controller_joint_Id)
|
|
is
|
|
begin
|
|
-- new_Line;
|
|
-- put_Line ("JOINT_TRANS for Bone:" & controller_joint_Id'Image (the_Bone));
|
|
-- put_Line (math.Image (math.Matrix (joint_Transform_for (the_Bone))));
|
|
--
|
|
-- new_Line;
|
|
-- put_Line ("Self.controller_Joints (the_Bone).inverse_bind_Matrix:");
|
|
-- put_Line (math.Image (math.Matrix (Self.controller_Joints (the_Bone).inverse_bind_Matrix)));
|
|
|
|
Self.set_GL_program_Parameters (for_bone => the_Bone,
|
|
to => Self.controller_Joints (the_Bone).inverse_bind_Matrix
|
|
* joint_Transform_for (the_Bone)
|
|
* inv_root_Transform);
|
|
end set_Transform_for;
|
|
|
|
|
|
|
|
procedure set_proxy_Transform_for (the_Bone : in controller_joint_Id; the_Proxy : in controller_joint_Id)
|
|
is
|
|
begin
|
|
Self.set_GL_program_Parameters (for_bone => the_Bone,
|
|
to => Self.controller_Joints (the_Proxy).inverse_bind_Matrix
|
|
* joint_Transform_for (the_Proxy)
|
|
* inv_root_Transform);
|
|
end set_proxy_Transform_for;
|
|
|
|
|
|
begin
|
|
if not Self.Graphics_enabled
|
|
then
|
|
Self.enable_Graphics;
|
|
Self.Graphics_enabled := True;
|
|
end if;
|
|
|
|
if Self.Mode = Animation
|
|
then
|
|
Self.animate (world_Age);
|
|
else
|
|
-- -- Self.skin_Sprite.Transform_is (Self.base_Sprite.Transform);
|
|
Self.skin_Sprite.rotate (Self.base_Sprite.Spin);
|
|
Self.skin_Sprite.move (Self.base_Sprite.Site);
|
|
null;
|
|
end if;
|
|
|
|
|
|
-- tbd: Can probly do the below 'set_Transform_for' calls in a loop.
|
|
|
|
-- Torso
|
|
--
|
|
set_Transform_for (Hips);
|
|
-- set_Transform_for (Spine);
|
|
-- set_Transform_for (Chest);
|
|
-- set_Transform_for (Neck);
|
|
--
|
|
-- set_Transform_for (Head);
|
|
-- set_Transform_for (Jaw);
|
|
-- set_proxy_Transform_for (Eye_R, Head);
|
|
-- set_proxy_Transform_for (Eye_L, Head);
|
|
--
|
|
--
|
|
-- -- Left Arm
|
|
-- --
|
|
-- set_Transform_for (Clavicle_L);
|
|
-- set_Transform_for (upper_Arm_L);
|
|
-- set_Transform_for (Forearm_L);
|
|
-- set_Transform_for (Hand_L);
|
|
-- set_proxy_Transform_for (Thumb_02_L, Hand_L);
|
|
-- set_proxy_Transform_for (Thumb_03_L, Hand_L);
|
|
-- set_proxy_Transform_for (F_ring_01_L, Hand_L);
|
|
-- set_proxy_Transform_for (F_index_01_L, Hand_L);
|
|
--
|
|
--
|
|
-- -- Right Arm
|
|
-- --
|
|
-- set_Transform_for (Clavicle_R);
|
|
-- set_Transform_for (upper_Arm_R);
|
|
-- set_Transform_for (Forearm_R);
|
|
-- set_Transform_for (Hand_R);
|
|
-- set_proxy_Transform_for (Thumb_02_R, Hand_R);
|
|
-- set_proxy_Transform_for (Thumb_03_R, Hand_R);
|
|
-- set_proxy_Transform_for (F_ring_01_R, Hand_R);
|
|
-- set_proxy_Transform_for (F_index_01_R, Hand_R);
|
|
--
|
|
--
|
|
-- -- Left Leg
|
|
-- --
|
|
-- set_Transform_for (Thigh_L);
|
|
-- set_Transform_for (Shin_L);
|
|
-- set_Transform_for (Foot_L);
|
|
-- set_Transform_for (Toe_L);
|
|
--
|
|
--
|
|
-- -- Right Leg
|
|
-- --
|
|
-- set_Transform_for (Thigh_R);
|
|
-- set_Transform_for (Shin_R);
|
|
-- set_Transform_for (Foot_R);
|
|
-- set_Transform_for (Toe_R);
|
|
end evolve;
|
|
|
|
|
|
-------------
|
|
-- Animation
|
|
--
|
|
procedure animate (Self : in out Item; world_Age : in Duration)
|
|
is
|
|
Now : Duration;
|
|
Elapsed : Duration;
|
|
|
|
|
|
procedure update_rotation_Animation (for_Channel : in channel_Id;
|
|
for_Joint : in gel.human_v1.scene_joint_Id;
|
|
for_Axis : in axis_Kind)
|
|
is
|
|
use Math;
|
|
|
|
the_Channel : animation_Channel renames Self.Channels (for_Channel);
|
|
Cursor : math.Index renames the_Channel.Cursor;
|
|
-- Elapsed : Duration := Now - start_Time;
|
|
|
|
function Reduced (Angle : in math.Real) return math.Real
|
|
is
|
|
begin
|
|
if Angle > 180.0 then return -360.0 + Angle;
|
|
elsif Angle < -180.0 then return 360.0 + Angle;
|
|
else return Angle;
|
|
end if;
|
|
end Reduced;
|
|
|
|
begin
|
|
if Cursor < the_Channel.Times'Last
|
|
then
|
|
if Cursor = 0
|
|
or else Elapsed > Duration (the_Channel.Times (Cursor))
|
|
then
|
|
Cursor := Cursor + 1;
|
|
|
|
if Cursor = 1
|
|
then
|
|
if the_Channel.Times (Cursor) = 0.0
|
|
then
|
|
the_Channel.interp_Delta := Reduced (the_Channel.Values (Cursor) - the_Channel.current_Angle);
|
|
else
|
|
the_Channel.interp_Delta := Reduced (the_Channel.Values (Cursor) - the_Channel.current_Angle)
|
|
/ (the_Channel.Times (Cursor));
|
|
end if;
|
|
else
|
|
the_Channel.interp_Delta := Reduced (the_Channel.Values (Cursor) - the_Channel.current_Angle)
|
|
/ (the_Channel.Times (Cursor) - the_Channel.Times (Cursor - 1));
|
|
end if;
|
|
|
|
the_Channel.interp_Delta := the_Channel.interp_Delta / 60.0; -- 60.0 is frames/sec
|
|
end if;
|
|
end if;
|
|
|
|
if Elapsed < Duration (the_Channel.Times (the_Channel.Times'Last))
|
|
then
|
|
the_Channel.current_Angle := Reduced ( the_Channel.current_Angle
|
|
+ the_Channel.interp_Delta);
|
|
Self.set_rotation_Angle (for_Joint, for_Axis,
|
|
to => to_Radians (math.Degrees (the_Channel.current_Angle)));
|
|
end if;
|
|
end update_rotation_Animation;
|
|
|
|
|
|
|
|
procedure update_location_Animation (for_Channel : in channel_Id;
|
|
for_Joint : in gel.human_v1.scene_joint_Id)
|
|
is
|
|
the_Channel : animation_Channel renames Self.Channels (for_Channel);
|
|
Cursor : math.Index renames the_Channel.Cursor;
|
|
Elapsed : constant Duration := Now - Self.start_Time;
|
|
|
|
function site_X return math.Real is begin return the_Channel.Values ((Cursor - 1) * 3 + 1); end site_X;
|
|
function site_Y return math.Real is begin return the_Channel.Values ((Cursor - 1) * 3 + 2); end site_Y;
|
|
function site_Z return math.Real is begin return the_Channel.Values ((Cursor - 1) * 3 + 3); end site_Z;
|
|
|
|
begin
|
|
if Cursor < the_Channel.Times'Last
|
|
then
|
|
if Cursor = 0
|
|
or else Elapsed > Duration (the_Channel.Times (Cursor))
|
|
then
|
|
Cursor := Cursor + 1;
|
|
|
|
if Cursor = 1 then
|
|
if the_Channel.Times (Cursor) = 0.0
|
|
then
|
|
the_Channel.site_interp_Delta (1) := site_X - the_Channel.current_Site (1);
|
|
the_Channel.site_interp_Delta (2) := site_Y - the_Channel.current_Site (2);
|
|
the_Channel.site_interp_Delta (3) := site_Z - the_Channel.current_Site (3);
|
|
else
|
|
the_Channel.site_interp_Delta (1) := (site_X - the_Channel.current_Site (1))
|
|
/ (the_Channel.Times (Cursor));
|
|
the_Channel.site_interp_Delta (2) := (site_Y - the_Channel.current_Site (2))
|
|
/ (the_Channel.Times (Cursor));
|
|
the_Channel.site_interp_Delta (3) := (site_Z - the_Channel.current_Site (3))
|
|
/ (the_Channel.Times (Cursor));
|
|
end if;
|
|
else
|
|
the_Channel.site_interp_Delta (1) := (site_X - the_Channel.current_Site (1))
|
|
/ (the_Channel.Times (Cursor) - the_Channel.Times (Cursor - 1));
|
|
the_Channel.site_interp_Delta (2) := (site_Y - the_Channel.current_Site (2))
|
|
/ (the_Channel.Times (Cursor) - the_Channel.Times (Cursor - 1));
|
|
the_Channel.site_interp_Delta (3) := (site_Z - the_Channel.current_Site (3))
|
|
/ (the_Channel.Times (Cursor) - the_Channel.Times (Cursor - 1));
|
|
end if;
|
|
|
|
the_Channel.site_interp_Delta (1) := the_Channel.site_interp_Delta (1) / 60.0; -- 60.0 is frames/sec
|
|
the_Channel.site_interp_Delta (2) := the_Channel.site_interp_Delta (2) / 60.0; -- 60.0 is frames/sec
|
|
the_Channel.site_interp_Delta (3) := the_Channel.site_interp_Delta (3) / 60.0; -- 60.0 is frames/sec
|
|
end if;
|
|
|
|
Self.set_Location (for_Joint, to => the_Channel.current_Site);
|
|
|
|
the_Channel.current_Site (1) := the_Channel.current_Site (1) + the_Channel.site_interp_Delta (1);
|
|
the_Channel.current_Site (2) := the_Channel.current_Site (2) + the_Channel.site_interp_Delta (2);
|
|
the_Channel.current_Site (3) := the_Channel.current_Site (3) + the_Channel.site_interp_Delta (3);
|
|
|
|
end if;
|
|
end update_location_Animation;
|
|
|
|
|
|
procedure update_full_transform_Animation (for_Channel : in channel_Id;
|
|
for_Joint : in gel.Human_v1.scene_joint_Id)
|
|
is
|
|
the_Channel : animation_Channel renames Self.Channels (for_Channel);
|
|
Cursor : math.Index renames the_Channel.Cursor;
|
|
Cursor_updated : Boolean := False;
|
|
new_Transform : math.Matrix_4x4;
|
|
|
|
begin
|
|
if Cursor = the_Channel.Times'Last
|
|
then
|
|
-- the_Channel.initial_Transform := the_Channel.Transforms (1);
|
|
-- the_Channel.current_Transform := the_Channel.initial_Transform;
|
|
--
|
|
-- the_Channel.current_Site := the_Channel.initial_Transform.Translation;
|
|
-- the_Channel.initial_Site := the_Channel.current_Site;
|
|
|
|
Cursor := 0;
|
|
Self.start_Time := Now;
|
|
end if;
|
|
|
|
-- Rotation
|
|
--
|
|
declare
|
|
use Math;
|
|
Initial : Transform;
|
|
begin
|
|
if Cursor < the_Channel.Times'Last
|
|
then
|
|
if Cursor = 0
|
|
or else Elapsed > Duration (the_Channel.Times (Cursor))
|
|
then
|
|
Cursor := Cursor + 1;
|
|
Cursor_updated := True;
|
|
|
|
if Cursor = 1
|
|
then
|
|
Initial := the_Channel.current_Transform;
|
|
|
|
if the_Channel.Times (Cursor) = 0.0
|
|
then
|
|
the_Channel.Transform_interp_Delta := 1.0 / 60.0; -- the_Channel.Values (Cursor) - the_Channel.current_Angle;
|
|
else
|
|
the_Channel.Transform_interp_Delta := the_Channel.Times (Cursor);
|
|
end if;
|
|
else
|
|
Initial := the_Channel.Transforms (Cursor - 1);
|
|
the_Channel.Transform_interp_Delta := the_Channel.Times (Cursor) - the_Channel.Times (Cursor - 1);
|
|
end if;
|
|
|
|
the_Channel.current_Transform := the_Channel.Transforms (Cursor);
|
|
the_Channel.Transform_interp_Delta := 1.0 / (the_Channel.Transform_interp_Delta * 60.0); -- 60.0 is frames/sec
|
|
the_Channel.slerp_Time := 0.0;
|
|
else
|
|
if Cursor > 1 then
|
|
Initial := the_Channel.Transforms (Cursor - 1);
|
|
else
|
|
Initial := the_Channel.Transforms (Cursor);
|
|
end if;
|
|
end if;
|
|
else
|
|
Initial := the_Channel.Transforms (1);
|
|
end if;
|
|
|
|
if Elapsed < Duration (the_Channel.Times (the_Channel.Times'Last))
|
|
then
|
|
-- put_Line ("Initial.Rotation: " & Image (Initial.Rotation)
|
|
-- & " current_Transform.Rotation: " & Image (the_Channel.current_Transform.Rotation));
|
|
|
|
set_Rotation (new_Transform, to_Matrix (Interpolated (Initial.Rotation,
|
|
the_Channel.current_Transform.Rotation,
|
|
to_Percentage (the_Channel.slerp_Time))));
|
|
-- set_Rotation (new_Transform, to_Matrix (Slerp (the_Channel.Transforms (Cursor ).Rotation,
|
|
-- the_Channel.Transforms (Cursor+1).Rotation,
|
|
-- the_Channel.slerp_Time)));
|
|
-- put_Line ("SLERP Time: " & Real'Image (the_Channel.slerp_Time)
|
|
-- & " Transform_interp_Delta: " & Real'Image (the_Channel.Transform_interp_Delta));
|
|
the_Channel.slerp_Time := the_Channel.slerp_Time
|
|
+ the_Channel.Transform_interp_Delta;
|
|
end if;
|
|
end;
|
|
|
|
-- new_Line;
|
|
-- put_Line ("Cursor: " & math.Index'Image (Cursor));
|
|
-- put_Line ("Elapsed: " & Duration'Image (Elapsed));
|
|
-- put_Line ("next Time: " & math.Real'Image (the_Channel.Times (Cursor)));
|
|
--
|
|
-- if cursor = 2
|
|
-- and elapsed > Duration (the_Channel.Times (Cursor))
|
|
-- then
|
|
-- put_Line ("*** Cursor: " & math.Index'Image (Cursor));
|
|
-- end if;
|
|
|
|
-- Location
|
|
--
|
|
declare
|
|
use type math.Vector_3;
|
|
|
|
-- function site_X return math.Real is begin return the_Channel.Values ((Cursor - 1) * 3 + 1); end site_X;
|
|
-- function site_Y return math.Real is begin return the_Channel.Values ((Cursor - 1) * 3 + 2); end site_Y;
|
|
-- function site_Z return math.Real is begin return the_Channel.Values ((Cursor - 1) * 3 + 3); end site_Z;
|
|
|
|
desired_Site : math.Vector_3 := the_Channel.Transforms (Cursor + 0).Translation;
|
|
|
|
begin
|
|
if Cursor < the_Channel.Times'Last
|
|
then
|
|
if Cursor_updated -- Cursor = 1
|
|
-- or else Elapsed > Duration (the_Channel.Times (Cursor))
|
|
then
|
|
if Cursor = 1
|
|
then
|
|
if the_Channel.Times (Cursor) = 0.0
|
|
then
|
|
the_Channel.site_interp_Delta := desired_Site - the_Channel.current_Site;
|
|
else
|
|
the_Channel.site_interp_Delta := (desired_Site - the_Channel.current_Site)
|
|
/ (the_Channel.Times (Cursor));
|
|
end if;
|
|
else
|
|
the_Channel.site_interp_Delta := (desired_Site - the_Channel.current_Site)
|
|
/ (the_Channel.Times (Cursor) - the_Channel.Times (Cursor - 1));
|
|
end if;
|
|
|
|
the_Channel.site_interp_Delta := the_Channel.site_interp_Delta / 60.0; -- 60.0 is frames/sec
|
|
end if;
|
|
|
|
the_Channel.current_Site := the_Channel.current_Site + the_Channel.site_interp_Delta;
|
|
|
|
-- if for_Channel = Hips
|
|
-- then
|
|
-- new_Line;
|
|
-- put_Line ("the_Channel.site_interp_Delta: " & math.Image (the_Channel.site_interp_Delta));
|
|
-- put_Line ("the_Channel.current_Site: " & math.Image (the_Channel.current_Site));
|
|
-- end if;
|
|
|
|
set_Translation (new_Transform, to => the_Channel.current_Site);
|
|
else
|
|
null;
|
|
end if;
|
|
end;
|
|
|
|
|
|
-- Scale
|
|
--
|
|
-- (TODO)
|
|
|
|
|
|
-- Store the new transform.
|
|
--
|
|
Self.set_Transform (for_Joint, to => new_Transform);
|
|
|
|
end update_full_transform_Animation;
|
|
|
|
|
|
begin
|
|
Now := world_Age;
|
|
|
|
if Self.start_Time = 0.0 then
|
|
Self.start_Time := Now;
|
|
end if;
|
|
|
|
Elapsed := Now - Self.start_Time;
|
|
|
|
update_full_transform_Animation (Hips, Hips);
|
|
update_full_transform_Animation (Thigh_L, Thigh_L);
|
|
update_full_transform_Animation (Shin_L, Shin_L);
|
|
update_full_transform_Animation (Foot_L, Foot_L);
|
|
update_full_transform_Animation (Toe_L, Toe_L);
|
|
update_full_transform_Animation (Thigh_R, Thigh_R);
|
|
update_full_transform_Animation (Shin_R, Shin_R);
|
|
update_full_transform_Animation (Foot_R, Foot_R);
|
|
update_full_transform_Animation (Toe_R, Toe_R);
|
|
update_full_transform_Animation (Spine, Spine);
|
|
update_full_transform_Animation (Chest, Chest);
|
|
update_full_transform_Animation (Clavicle_R, Clavicle_R);
|
|
update_full_transform_Animation (upper_Arm_R, upper_Arm_R);
|
|
update_full_transform_Animation (Forearm_R, Forearm_R);
|
|
update_full_transform_Animation (Hand_R, Hand_R);
|
|
-- update_full_transform_Animation (Thumb_02_R, Thumb_02_R);
|
|
-- update_full_transform_Animation (Thumb_03_R, Thumb_03_R);
|
|
-- update_full_transform_Animation (F_ring_01_R, F_ring_01_R);
|
|
-- update_full_transform_Animation (F_index_01_R, F_index_01_R);
|
|
update_full_transform_Animation (Clavicle_L, Clavicle_L);
|
|
update_full_transform_Animation (upper_Arm_L, upper_Arm_L);
|
|
update_full_transform_Animation (Forearm_L, Forearm_L);
|
|
update_full_transform_Animation (Hand_L, Hand_L);
|
|
-- update_full_transform_Animation (Thumb_02_L, Thumb_02_L);
|
|
-- update_full_transform_Animation (Thumb_03_L, Thumb_03_L);
|
|
-- update_full_transform_Animation (F_ring_01_L, F_ring_01_L);
|
|
-- update_full_transform_Animation (F_index_01_L, F_index_01_L);
|
|
update_full_transform_Animation (Neck, Neck);
|
|
update_full_transform_Animation (Head, Head);
|
|
update_full_transform_Animation (Jaw, Jaw);
|
|
-- update_full_transform_Animation (Eye_R, Eye_R);
|
|
-- update_full_transform_Animation (Eye_L, Eye_L);
|
|
|
|
Self.update_all_global_Transforms;
|
|
end animate;
|
|
|
|
|
|
|
|
procedure reset_Animation (Self : in out Item)
|
|
is
|
|
begin
|
|
Self.start_Time := 0.0;
|
|
|
|
for Each in Self.Channels'Range
|
|
loop
|
|
Self.Channels (Each).Cursor := 0;
|
|
Self.Channels (Each).current_Angle := Self.Channels (Each).initial_Angle;
|
|
Self.Channels (Each).current_Site := Self.Channels (Each).initial_Site;
|
|
Self.Channels (Each).interp_Delta := 0.0;
|
|
end loop;
|
|
end reset_Animation;
|
|
|
|
|
|
|
|
procedure Mode_is (Now : in display_Mode)
|
|
is
|
|
begin
|
|
the_display_Mode := Now;
|
|
end Mode_is;
|
|
|
|
|
|
|
|
begin
|
|
|
|
for Each in to_scene_joint_Id'Range
|
|
loop
|
|
to_scene_joint_Id (Each) := scene_joint_Id'Value (controller_joint_Id'Image (Each));
|
|
end loop;
|
|
|
|
|
|
for Each in to_controller_joint_Id'Range
|
|
loop
|
|
begin
|
|
to_controller_joint_Id (Each) := controller_joint_Id'Value (scene_joint_Id'Image (Each));
|
|
-- exception
|
|
-- when constraint_Error =>
|
|
-- if Each /= Armature then raise; end if;
|
|
end;
|
|
end loop;
|
|
|
|
|
|
end gel.Human_v1;
|