CS计算机代考程序代写 Hive ada ————————————————————————-

————————————————————————-
— GLOBE_3D – GL – based, real – time, 3D engine

— Copyright (c) Gautier de Montmollin 2001 .. 2012
— SWITZERLAND
— Copyright (c) Rod Kay 2006 .. 2008
— AUSTRALIA

— Permission is hereby granted, free of charge, to any person obtaining a copy
— of this software and associated documentation files (the “Software”), to deal
— in the Software without restriction, including without limitation the rights
— to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
— copies of the Software, and to permit persons to whom the Software is
— furnished to do so, subject to the following conditions:

— The above copyright notice and this permission notice shall be included in
— all copies or substantial portions of the Software.

— THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
— IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
— FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
— AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
— LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
— OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
— THE SOFTWARE.

— N. : this is the MIT License, as found 12 – Sep – 2007 on the site
— http://www.opensource.org/licenses/mit – license.php

————————————————————————-


— Added “List_status” and “List_Id” to the Object_3D.
— by default the Display_One routine will now generate a GL command list
— instead of sending the command each time explicitely.
— To disable this feature, set Object_3D.List_Status to “No_List”.
— If memory is not sufficient to hold a list, the Display_One routine will
— automatically default back to “No_List”.

— Uwe R. Zimmer, July 2011


— Added an alternative
— display face routine which is optimized to produce a shorter list
— of GL commands. Runs slower than the original Display face routine
— yet needs to be executed only once.

— Uwe R. Zimmer, July 2011

— Cleaned up the whole code base (including the whole GL base) to address
— _every_ warning and style message. Restructed the code in places to
— take advantage of Ada 2012. No identifier hides any other in the surrounding
— scope any more. Compound assignments and function-expressions have been
— used frequently to make the code leaner and safer. The code will no longer
— compile under Ada 2005 or earlier though.

— Uwe R. Zimmer, September 2013

with GL,
GL.Geometry,
GL.Frustums,
GL.Skinned_Geometry,
GL.Materials;

use GL;

with Zip;

with Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;
with Ada.Strings.Unbounded;
with Ada.Unchecked_Deallocation;
with Ada.Containers.Hashed_Maps;
with Ada.Strings.Unbounded.Hash;

package GLOBE_3D is

subtype Ident is String (1 .. 40);
— Identifiers for naming things (textures, objects, . .. )
— Identifiers are case insensitive and stored as UPPER_CASE

empty : constant Ident := (others => ‘ ‘);

— Set the name of Zip archives containing the data.

— If an item is not found in the level (local) data, it is
— searched in the global data. The idea is to set the global
— data once in the execution of the program, and change the local data
— upon context change (e.g., in a game, a change of level).
procedure Set_local_data_name (s : String);
procedure Set_level_data_name (s : String) renames Set_local_data_name;
procedure Set_global_data_name (s : String);

data_file_not_found : exception;

— List of textures ID’s, correspond to files in
— the archives and to GL’s “names”
type Image_ID is new Integer range -1 .. Integer’Last;
null_image : constant Image_ID := -1;

subtype Real is GL.Double;
package REF is new Ada.Numerics.Generic_Elementary_Functions (Real);
package RIO is new Ada.Text_IO.Float_IO (Real);

subtype Vector_3D is GL.Double_Vector_3D;
type p_Vector_3D is access all Vector_3D;

type Vector_4D is array (0 .. 3) of Real;

subtype Point_3D is Vector_3D;

type Matrix is array (Positive range <>, Positive range <>) of aliased Real;
type Matrix_33 is new Matrix (1 .. 3, 1 .. 3);
type Matrix_44 is new Matrix (1 .. 4, 1 .. 4);

Id_33 : constant Matrix_33 := ((1.0, 0.0, 0.0),
(0.0, 1.0, 0.0),
(0.0, 0.0, 1.0));

type Point_3D_array is array (Positive range <>) of aliased Point_3D;
type p_Point_3D_array is access Point_3D_array;
type Vector_3D_array is array (Natural range <>) of Vector_3D;

type Natural_Index_array is array (Natural range <>) of aliased Natural; — tbd : make GL.unsigned_Int (or unsigned_Short)?

—————————————————————-
— Portal rendering definitions (methods in GLOBE_3D.Portals) —
—————————————————————-

type Rectangle is record
X1, Y1, X2, Y2 : Integer;
end record;

subtype Clipping_area is Rectangle;

— ^ Cheap but fast portal culling & clipping method with rectangles.
— Usually, a bit too much is displayed.
— With graphics cards as of 2005 + , it doesn’t matter at all
— The important aspect is the culling of the objects when the
— intersection is empty.

type Clipping_data is record
Eye_Position : aliased Point_3D;
view_direction : Vector_3D;
max_dot_product : Real; — depends on the field of view
main_clipping : Clipping_area;
end record;

— Camera

fairly_Far : constant := 50_000.0;
default_field_of_view_Angle : constant := 55.0;

type Camera is tagged
record
Clipper : Clipping_data := (Eye_Position => (0.0, 0.0, 5.0),
view_direction => (0.0, 0.0, -1.0),
max_dot_product => 0.0,
main_clipping => (0, 0, 0, 0));
World_Rotation : Matrix_33 := Id_33;
Speed : Vector_3D := (0.0, 0.0, 0.0);
rotation_Speed : Vector_3D := (0.0, 0.0, 0.0);
compose_rotations : Boolean := True;
— True : apply successive rotations from rotation_Speed directly
— to world_Rotation. Good for totally free 3D movement, no gravity.
— Drawback : rotations around x axis, then y, then x, .. . induce a
— rotation around z (the nose) which is x rotated around y.
— False : world_Rotation is set as XYZ_rotation of the rotation vector below;
— x, y, z keep separate.
— Cf implementation in the package Actors
rotation : Vector_3D := (0.0, 0.0, 0.0);
— ^ this vector is updated, whatever the state of ‘compose_rotations’

FOVy : Real := default_field_of_view_Angle; — field of view angle (deg) in the y direction
Aspect : Real; — x/y aspect ratio

near_plane_Distance : Real := 1.0; — distance to the near clipping plane
near_plane_Width : Real;
near_plane_Height : Real;

far_plane_Distance : Real := fairly_Far; — distance to the far clipping plane
far_plane_Width : Real;
far_plane_Height : Real;

Projection_Matrix : Matrix_44;

frustum_Planes : GL.Frustums.plane_Array;
end record;

type p_Camera is access all Camera’Class;

— ‘Visual’ class hierarchy

type Visual is abstract tagged
record
ID : Ident := “-Nameless- “;
— 1234567890123456789012345678901234567890

Centre : Point_3D := (0.0, 0.0, 0.0); — vertex coords are relative to the centre.
Centre_Camera_Space : Point_3D; — the visuals ‘centre’ in camera space.
rotation : Matrix_33 := Id_33;

is_Terrain : Boolean := False;
end record;

type p_Visual is access all Visual’Class;
type Visual_array is array (Positive range <>) of p_Visual;

procedure Destroy (o : in out Visual) is abstract;
procedure Free (o : in out p_Visual);

procedure Pre_calculate (o : in out Visual) is abstract;

procedure set_Alpha (o : in out Visual;
Alpha : GL.Double) is abstract;

function is_Transparent (o : Visual) return Boolean is abstract;

— returns ‘True’ if any part of the ‘visual’ is potentially transparent.

function face_Count (o : Visual) return Natural is abstract;
function Bounds (o : Visual) return GL.Geometry.Bounds_record is abstract;

function skinned_Geometrys (o : Visual) return GL.Skinned_Geometry.skinned_Geometrys;

procedure Display (o : in out Visual;
clip : Clipping_data) is abstract;

procedure Set_name (o : in out Visual’class; new_name : String);
— Give a new name (no need of space – filling) to the object

function Get_name (o : Visual’class) return String;

function Width (o : Visual’class) return Real;
function Height (o : Visual’class) return Real;
function Depth (o : Visual’class) return Real;

null_Visuals : constant Visual_array (1 .. 0) := (others => null);

procedure render (the_Visuals : Visual_array; the_Camera : Camera);

— clears the color buffer and renders each of the visuals.

— Map_of_Visuals

— We define here a way of finding quickly a Visual’s access
— through its identifier.

type Map_of_Visuals is private;
— One can begin with empty_map, then Add Visuals one per one:
function empty_map return Map_of_Visuals;
procedure Add (to_map : in out Map_of_Visuals; what : p_Visual);
Duplicate_name : exception;
— One can also get a map of an array of visuals in one go:
function Map_of (va : Visual_array) return Map_of_Visuals;

— original G3D Object class

type Object_3D;
type p_Object_3D is access all Object_3D;

——————-
— Define a face —
——————-

type Skin_Type is (texture_only,
colour_only,
coloured_texture,
material_only,
material_texture,
invisible);

type Set_of_Skin is array (Skin_Type) of Boolean;

is_textured : constant Set_of_Skin :=
(texture_only | coloured_texture | material_texture => True,
others => False);

null_colour : constant GL.Material_Float_vector := (0.0, 0.0, 0.0, 0.0);

subtype Idx_3_array is Natural_Index_array (1 .. 3);

subtype Idx_4_array is Natural_Index_array (1 .. 4);
type Idx_4_array_array is array (Positive range <>) of Idx_4_array;

type Map_idx_pair is record U, V : aliased GL.Double; end record;
type Map_idx_pair_array is array (Natural range <>) of Map_idx_pair;
subtype Map_idx_pair_4_array is Map_idx_pair_array (1 .. 4);

type Face_type is record
P : Idx_4_array; — indices of the edges (anticlockwise)
— one of them can be 0 (triangle); then the
— “missing” edge indicates how to put texture
— *** Portals :
connecting : p_Object_3D := null; — object behind – if there is one

— *** Surface
skin : Skin_Type;
mirror : Boolean := False; — mirror just behind the skin ?
alpha : GL.Double := 1.0;
— alpha in [0;1] for blending colours and textures.
— NB : when this value (or all of material colours) is equal to
— one, the blending for transparency is switched off to gain
— speed; GLOBE_3D can switch on the blending again when loading
— a texture that has an alpha layer
— *** > colour part (data ignored when irrelevant):
colour : GL.RGB_Color;
— *** > material part (data ignored when irrelevant):
material : GL.Materials.Material_type :=
GL.Materials.neutral_material;
— *** > texture – mapping part (data ignored when irrelevant):
texture : Image_ID := null_image;
— Alternative to setting an Image_id, if it is not known at
— time of building the object : use Texture_name_hint, then
— Rebuild_links

— Whole texture or part of one ?
whole_texture : Boolean := True;
— – in case of a whole texture, automatic mapping, we just need
— to know how many times is it tiled:
repeat_U,
repeat_V : Positive := 1;
— – in case of a partial texture (e.g. for a texture spread
— across several faces), we need a deterministic mapping:
texture_edge_map :
Map_idx_pair_4_array;
end record;

type Face_array is array (Natural range <>) of aliased Face_type;
type p_Face_array is access Face_array;

subtype Edge_count is Positive range 3 .. 4;

— Invariants : things that don’t change during the object’s life

type Face_invariant_type is private; — GLOBE_3D – internal, nothing for users

type Face_invariant_array is array (Natural range <>) of Face_invariant_type;

type Object_3D_list;
type p_Object_3D_list is access Object_3D_list;
type Object_3D_list is record
objc : p_Object_3D;
next : p_Object_3D_list;
end record;

type Object_3D_array is array (Positive range <>) of p_Object_3D;
type p_Object_3D_array is access Object_3D_array;

———————————–
— Now : the Object_3D definition —
———————————–

type List_Cases is (No_List, Generate_List, Is_List);
subtype List_Ids is Positive;


— Added “List_status” and “List_Id” to the Object_3D.
— by default the Display_One routine will now generate a GL command list
— instead of sending the command each time explicitely.
— To disable this feature, set Object_3D.List_Status to “No_List”.
— If memory is not sufficient to hold a list, the Display_One routine will
— automatically default back to “No_List”.

— Uwe R. Zimmer, July 2011

type Object_3D (Max_points, Max_faces : Integer) is new Visual with record
Point : Point_3D_array (1 .. Max_points); — vertices
edge_vector : Vector_3D_array (1 .. Max_points); — normals for lighting
face : Face_array (1 .. Max_faces);
sub_objects : p_Object_3D_list := null;
— List of objects to be drawn AFTER the
— object itself e.g., things inside a room
pre_calculated : Boolean := False;
List_Status : List_Cases := Generate_List;
— private:
List_Id : List_Ids;
Face_Invariant : Face_invariant_array (1 .. Max_faces);
Bounds : GL.Geometry.Bounds_record;
transparent : Boolean := False;
end record; — Object_3D

overriding procedure Destroy (o : in out Object_3D);
overriding procedure set_Alpha (o : in out Object_3D; Alpha : GL.Double);
overriding function is_Transparent (o : Object_3D) return Boolean;
overriding function face_Count (o : Object_3D) return Natural;
overriding function Bounds (o : Object_3D) return GL.Geometry.Bounds_record;

procedure Check_object (o : Object_3D);
— Check object for invalid or duplicate vertices

procedure Texture_name_hint (
o : in out Object_3D;
face : Positive;
name : String
);
— Indicate a texture’s name that can be resolved later by Rebuild_links

procedure Portal_name_hint (
o : in out Object_3D;
face : Positive;
name : String
);
— Indicate a portal’s name that can be resolved later by Rebuild_links

procedure Rebuild_links (
o : in out Object_3D’Class; — object to be relinked
neighbouring : Map_of_Visuals; — neighbourhood
tolerant_obj : Boolean; — tolerant on missing objects
tolerant_tex : Boolean — tolerant on missing textures
);
— Does nothing when texture or object name is empty
Portal_connection_failed : exception;

bad_vertex_number, duplicated_vertex,
duplicated_vertex_location : exception;
point_unmatched, too_many_adjacences : exception;
bad_edge_number : exception;

overriding procedure Pre_calculate (o : in out Object_3D);
— Done automatically at first display, but sometimes
— it’s better to do it before : operation can be long!

————————————————————
— Display of a whole scene, viewed from a certain object —
————————————————————

overriding procedure Display (
o : in out Object_3D;
clip : Clipping_data
);
— – “out” for o because object might be pre_calculated if not yet
— – clip:
— allows to cull rendering of neighbouring objects that are not
— visible from current point of view; also avoids infinite
— recursion in case of mutually connected objects.
— – neighbouring objects being drawn more than once, e.g. two parts
— visible through two portals, is admissible with adequate clipping.

——————————–
— Display of a single object —
——————————–

procedure Display_one (o : in out Object_3D);
— Display only this object and not connected objects
— “out” for o because object might be pre_calculated if not yet

— Abstract windowing management

type Window is abstract tagged
record
Camera : aliased GLOBE_3D.Camera;
end record;

type p_Window is access all Window’Class; pragma No_Strict_Aliasing (p_Window);

procedure Enable (Self : in out Window) is abstract;
procedure Freshen (Self : in out Window;
time_Step : GLOBE_3D.Real;
Extras : GLOBE_3D.Visual_array := GLOBE_3D.null_Visuals) is abstract;

— Exceptions

Missing_level_data : exception;
Missing_global_data : exception;

Missing_texture : exception;
Missing_object : exception;

zero_normal : exception;
zero_summed_normal : exception;
zero_averaged_normal : exception;

————–
— Lighting —
————–

subtype Light_count is Natural range 0 .. 8;
— GL supports up to 8 sources.
subtype Light_ident is Light_count range 1 .. Light_count’Last;

type Light_definition is record
position, ambient, diffuse, specular : GL.Light_Float_vector;
end record;

procedure Define (which : Light_ident; as : Light_definition);

procedure Switch_lights (on : Boolean);
procedure Switch_light (which : Light_ident; on : Boolean);

procedure Reverse_light_switch (which : Light_ident);

function Is_light_switched (which : Light_ident) return Boolean;

———-
— Misc —
———-

function Image (r : Real) return String;

function Coords (p : Point_3D) return String;

procedure Angles_modulo_360 (v : in out Vector_3D);

——————————–
— Free heap – allocated memory —
——————————–

procedure Dispose is
new Ada.Unchecked_Deallocation (Point_3D_array, p_Point_3D_array);

procedure Dispose is
new Ada.Unchecked_Deallocation (Face_array, p_Face_array);

—————————————————————
— Trash : provisory variables for some development checkings —
—————————————————————

— info_?_ .. . : ?= letter; change letter to clean – up debug infos

info_b_real1,
info_b_real2 : Real := 123.0;
info_b_vect : Vector_3D := (others => 123.0);
info_b_bool1,
info_b_bool2 : Boolean := False;
info_b_clip : Clipping_area := (0, 0, 0, 0);
info_b_pnt : array (0 .. 4) of Point_3D := (others => (others => 123.0));
info_b_ntl1,
info_b_ntl2,
info_b_ntl3 : Natural := 0;
info_b_str1 : Ada.Strings.Unbounded.Unbounded_String :=
Ada.Strings.Unbounded.Null_Unbounded_String;

private

type p_String is access String;

type Face_invariant_type is record
P_compact : Idx_4_array;
— indices of the edges (anticlockwise),
— in compact range : 1 .. 3 for triangle
last_edge : Edge_count;
UV_extrema : Map_idx_pair_4_array;
— mapping of texture edges according to an eventual
— 0 in P (triangle). Compact range : 1 .. 3 for triangle
normal : Vector_3D;
blending : Boolean; — is any alpha < 1 ? connect_name : Ident := empty; -- ^ Used for loading connected objects. -- When the object group has been loaded, that name is set; -- the face (f).connecting accesses can be resolved using -- the face_invariant (f).connect_name . texture_name : Ident := empty; -- ^ face (f).texture must be resolved using -- face_invariant (f).texture_name . portal_seen : Boolean := False; -- ^ always False, except during Display to avoid possible infinite -- recursion; reset to False at the end of Display. end record; -- A few global variables - shocking! Don't look, it's private here : - ) -- Name of Zip archives containing the Level / Global data -- If an item is not found in the level data, it is -- searched in the global one level_data_name : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.To_Unbounded_String ("*undefined_level_data*"); global_data_name : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.To_Unbounded_String ("*undefined_global_data*"); -- Corresponding zip file infos for quick search zif_level, zif_global : Zip.Zip_info; procedure Load_if_needed (zif : in out Zip.Zip_info; name : String); -- General support functions available to child packages . .. -- -- blending support -- function Is_to_blend (m : GL.Double) return Boolean; function Is_to_blend (m : GL.C_Float) return Boolean; function Is_to_blend (m : GL.Material_Float_vector) return Boolean; function Is_to_blend (m : GL.Materials.Material_type) return Boolean; -- material support -- procedure Set_Material (m : GL.Materials.Material_type); -- Maps of Visuals - quick dictionary search -- package Visuals_Mapping is new Ada.Containers.Hashed_Maps (Key_Type => Ada.Strings.Unbounded.Unbounded_String,
Element_Type => p_Visual,
Hash => Ada.Strings.Unbounded.Hash,
Equivalent_Keys => Ada.Strings.Unbounded.”=”);

type Map_of_Visuals is new Visuals_Mapping.Map with null record;

end GLOBE_3D;