Source file : brick.adb
-- 3D model of a "brick" of a space station, seen from inside.
-- Copyright (c) Gautier de Montmollin 2005
-- CH-8810 Horgen
-- SWITZERLAND
-- Permission granted to use the herein contained 3D model for any purpose,
-- provided this copyright note remains attached and unmodified.
with GL, GL.Math;
package body Brick is
procedure Create(
object : in out GLOBE_3D.p_Object_3D;
scale : GLOBE_3D.Real;
centre : GLOBE_3D.Point_3D;
kind : Brick_kind;
opening: Cubic_Face_set; -- needed opening on which face
portal : out Cubic_Face_index; -- corresponding connecting faces
texture: Cubic_Face_texture
)
is
use GL, GL.Math, GLOBE_3D;
type Ipoint is array(1..3) of Natural;
scale_2: constant Real:= scale / 3.0;
procedure Trans(i: Ipoint; p: out Point_3D) is
begin
p:= scale_2 * (Real(i(1))-1.5,Real(i(2))-1.5,Real(i(3))-1.5);
end Trans;
point : Point_3D_array(1..6*16);
face : Face_array(1..6*9);
face_proto : Face_type; -- takes defaults values
po, fa: Natural:= 0;
----------------
-- Kind: cube --
----------------
procedure Cube is
procedure Do_Face( iP1,iP2,iP3,iP4: Ipoint) is
P: array(1..4) of Point_3D;
vtx: GLOBE_3D.Index_array(1..4);
begin
Trans(iP1,P(1));
Trans(iP2,P(2));
Trans(iP3,P(3));
Trans(iP4,P(4));
for pt in P'Range loop
vtx(pt):= 0;
for op in 1..po loop
if Almost_zero(Norm2(P(pt)-point(op))) then -- exists already
vtx(pt):= op;
end if;
end loop;
if vtx(pt)= 0 then
po:= po + 1;
point(po):= P(pt);
vtx(pt):= po;
end if;
end loop;
face_proto.P:= vtx;
fa:= fa+1;
face(fa):= face_proto;
end Do_Face;
begin
face_proto.skin:= texture_only;
face_proto.repeat_U:= 1;
face_proto.repeat_V:= 1;
for dir in Cubic_Face_count loop
face_proto.texture:= texture(dir);
for r in 0..2 loop
for s in 0..2 loop
case dir is
when 1 => Do_Face( (r+1,0,s), (r,0,s), (r,0,s+1), (r+1,0,s+1) );
when 2 => Do_Face( (3,r+1,s), (3,r,s), (3,r,s+1), (3,r+1,s+1) );
when 3 => Do_Face( (r,3,s), (r+1,3,s), (r+1,3,s+1), (r,3,s+1) );
when 4 => Do_Face( (0,r,s), (0,r+1,s), (0,r+1,s+1), (0,r,s+1) );
when 5 => Do_Face( (r,s,0), (r+1,s,0), (r+1,s+1,0), (r,s+1,0) );
when 6 => Do_Face( (r+1,s,3), (r,s,3), (r,s+1,3), (r+1,s+1,3) );
end case;
if r=1 and s=1 then
if opening(dir) then
face(fa).skin:= invisible;
end if;
portal(dir):= fa;
end if;
end loop;
end loop;
end loop;
end Cube;
begin
case kind is
when cube => Cube;
when cross => null; --!!
end case;
object:= new Object_3D(po,fa);
object.point:= point(1..po);
object.face := face(1..fa);
object.centre:= centre;
Set_name(object.all, "Space station brick");
end Create;
end Brick;
GLOBE_3D: Ada library for real-time 3D rendering.
Ada programming.