home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Homebrewer's Handbook
/
vr.iso
/
vroom
/
vroom.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-03-19
|
34KB
|
1,040 lines
unit vroom;
interface
uses graph, crt, msmouse, dos, fix_math;
{$L 3dfill}
{$L trans}
const dl=0; dr=319; dt=0; db=239;
page0=0; page1=19200;
infinity=1.7e38;
{------------------------------------------------}
{ Type declarations }
{------------------------------------------------}
type
pcx_header = record
code, version, mode, bits_p_pixel : byte;
X1, Y1, X2, Y2, Hres, Vres : word;
palette : array[1..16,1..3] of byte;
junk, Nplanes : byte;
bytes_p_line, palette_type : word;
padding : array[1..58] of byte;
end;
clock_ptr=^real;
keyproc=function(key : char) : boolean;
textproc=procedure;
vector3d=record
x, y, z : longint;
end;
screen3d=record
x, y, z : integer;
end;
vertex_ptr=^vertex;
vertex=object
screen : screen3d;
next : vertex_ptr;
clip : byte;
world : vector3d;
screen_depth : longint;
procedure data(x1, y1, z1 : real);
end;
vertex_copy_ptr=^vertex_copy;
vertex_copy=record
old_vertex, new_vertex : vertex_ptr;
next : vertex_copy_ptr;
end;
face_vertex_ptr=^face_vertex;
face_vertex=record
this_vertex : vertex_ptr;
next : face_vertex_ptr;
end;
face_ptr=^face;
fillproc=procedure(this_face : face_ptr);
fixed_matrix_4x4=object
el : array[1..4,1..4] of longint;
procedure data(x11, x12, x13, x14,
x21, x22, x23, x24,
x31, x32, x33, x34,
x41, x42, x43, x44 : longint);
end;
titletype=string;
object3d_ptr=^object3d;
selectproc=procedure(thisobject : object3d_ptr);
child_object3d_ptr=^child_object3d;
child_object3d=record
this_child : object3d_ptr;
next : child_object3d_ptr;
end;
object3d=object
first_vertex : vertex_ptr; {!! Must be first - used for self-reference}
first_face : face_ptr;
shown, redraw : boolean;
reference_point, lo, hi : vector3d;
child : child_object3d_ptr;
next : object3d_ptr;
select_procedure : selectproc;
constructor Init;
destructor Done;
function Add_Vertex(x1, y1, z1 : real) : vertex_ptr; virtual;
procedure Remove_Vertex(this_vertex : vertex_ptr); virtual;
procedure Build_Normals; virtual;
procedure Save_to_Disk(filename : string);
procedure Unit_Normals; virtual;
procedure Transform_to_Screen; virtual;
procedure Screen_Position(var x_pos, y_pos, z_pos); virtual;
procedure Screen_Limits(var xmin, xmax, ymin, ymax : integer); virtual;
procedure Apply_Transform(M : fixed_matrix_4x4); virtual;
procedure Apply_XForm(M : fixed_matrix_4x4); virtual;
procedure Set_Reference_Point(x, y, z : real); virtual;
procedure Translate(X, Y, Z : real); virtual;
procedure Scale(Sx, Sy, Sz : real); virtual;
procedure RotateX(theta : real); virtual;
procedure RotateY(theta : real); virtual;
procedure RotateZ(theta : real); virtual;
procedure Scale_About(Sx, Sy, Sz, X, Y, Z : real); virtual;
procedure RotateX_About(theta, X, Y, Z : real); virtual;
procedure RotateY_About(theta, X, Y, Z : real); virtual;
procedure RotateZ_About(theta, X, Y, Z : real); virtual;
procedure MoveTo(X, Y, Z : real); virtual;
procedure Timed_Translate(X, Y, Z, TStart, Duration : real); virtual;
procedure Timed_Scale(Sx, Sy, Sz, TStart, Duration : real); virtual;
procedure Timed_RotateX(theta, TStart, Duration : real); virtual;
procedure Timed_RotateY(theta, TStart, Duration : real); virtual;
procedure Timed_RotateZ(theta, TStart, Duration : real); virtual;
procedure Timed_Scale_About(Sx, Sy, Sz, X, Y, Z, TStart, Duration : real); virtual;
procedure Timed_RotateX_About(theta, X, Y, Z, TStart, Duration : real); virtual;
procedure Timed_RotateY_About(theta, X, Y, Z, TStart, Duration : real); virtual;
procedure Timed_RotateZ_About(theta, X, Y, Z, TStart, Duration : real); virtual;
procedure Timed_MoveTo(X, Y, Z, TStart, Duration : real); virtual;
procedure Timed_Translate_At(dX, dY, dZ, TStart, Duration : real); virtual;
procedure Timed_Scale_At(dSx, dSy, dSz, TStart, Duration : real); virtual;
procedure Timed_RotateX_At(dtheta, TStart, Duration : real); virtual;
procedure Timed_RotateY_At(dtheta, TStart, Duration : real); virtual;
procedure Timed_RotateZ_At(dtheta, TStart, Duration : real); virtual;
procedure Timed_Scale_About_At(dSx, dSy, dSz, X, Y, Z, TStart, Duration : real); virtual;
procedure Timed_RotateX_About_At(dtheta, X, Y, Z, TStart, Duration : real); virtual;
procedure Timed_RotateY_About_At(dtheta, X, Y, Z, TStart, Duration : real); virtual;
procedure Timed_RotateZ_About_At(dtheta, X, Y, Z, TStart, Duration : real); virtual;
procedure Remove_All_Timed_Transformations;
procedure Change_Colour(color_in : byte; inten : real);
procedure Show; virtual;
procedure Hide; virtual;
procedure AddChild(this_object : object3d_ptr);
procedure RemoveChild(this_object : object3d_ptr);
end;
file_object3d_ptr=^file_object3d;
file_object3d=object(object3d)
constructor Init(fname : titletype);
end;
copy_object3d_ptr=^copy_object3d;
copy_object3d=object(object3d)
constructor Init(source_object : object3d_ptr);
end;
face=object
vertex1 : face_vertex_ptr; {Leave as first variable - used for self referencing}
color : byte;
seen : boolean;
normal : vector3d;
D : longint;
sort_z : integer;
next_order, next : face_ptr;
intensity : longint;
colour : byte;
long_sort_z : longint;
two_d : boolean;
this_fillproc : fillproc;
constructor Init(var owner : object3d; face_color : byte; inten : real);
procedure Add_Vertex(this_vertex : vertex_ptr);
procedure Build_Normal;
procedure Unit_Normal;
procedure Shading;
procedure Fill;
destructor Done;
end;
timed_xform_ptr=^timed_xform;
timed_xform=object
t_start, t_last, t_end : real;
this_ob : object3d_ptr;
next : timed_xform_ptr;
constructor Init(this_object : object3d_ptr; start, duration : real);
procedure Update; virtual;
destructor Done;
end;
timed_rotX_ptr=^timed_rotX;
timed_rotX=object(timed_xform)
dth : real;
constructor Init(this_object : object3d_ptr; start, duration, dtheta : real);
procedure Update; virtual;
end;
timed_rotY_ptr=^timed_rotY;
timed_rotY=object(timed_rotX)
procedure Update; virtual;
end;
timed_rotZ_ptr=^timed_rotZ;
timed_rotZ=object(timed_rotX)
procedure Update; virtual;
end;
timed_rotX_About_ptr=^timed_rotX_About;
timed_rotX_About=object(timed_xform)
dth, X, Y, Z : real;
constructor Init(this_object : object3d_ptr; start, duration, dtheta, x1, y1, z1 : real);
procedure Update; virtual;
end;
timed_rotY_About_ptr=^timed_rotY_About;
timed_rotY_About=object(timed_rotX_About)
procedure Update; virtual;
end;
timed_rotZ_About_ptr=^timed_rotZ_About;
timed_rotZ_About=object(timed_rotX_About)
procedure Update; virtual;
end;
timed_scale_ptr=^timed_scale;
timed_scale=object(timed_xform)
tsx,tsy,tsz : real;
constructor Init(this_object : object3d_ptr; start, duration, sx1, sy1, sz1 : real);
procedure Update; virtual;
end;
timed_scale_About_ptr=^timed_scale_about;
timed_scale_About=object(timed_xform)
tsx,tsy,tsz,X,Y,Z : real;
constructor Init(this_object : object3d_ptr; start, duration, sx1, sy1, sz1, x1, y1, z1 : real);
procedure Update; virtual;
end;
timed_translate_ptr=^timed_translate;
timed_translate=object(timed_xform)
X,Y,Z : real;
constructor Init(this_object : object3d_ptr; start, duration, x1, y1, z1 : real);
procedure Update; virtual;
end;
{--------------------------------------------------------------------------------------------------}
procedure multiply_4x4(first, second : fixed_matrix_4x4; var out : fixed_matrix_4x4);
procedure Store_Settings;
function Keyboard_Check : boolean;
function mouse_available : boolean;
function mouse_check : boolean;
procedure flip_cursor2D_mode;
function cursor2D_check : boolean;
procedure User_KeyCheck_Proc(new_keyproc : keyproc);
procedure Init_System;
procedure Sort_by_Nearest_Point;
procedure Sort_by_Furthest_Point;
procedure Sort_by_Middle_Point;
procedure Set_Window(wl,wb,wr,wt : real);
procedure Set_View(x,y,z, azimuth_in, colatitude_in, roll_in : real);
procedure Set_World_to_View(x,y,z : longint; azimuth_in, colatitude_in, roll_in : real);
procedure Redraw_Scene;
procedure Set_Ambient_Intensity(inten : real);
procedure Set_Light(inten, dx, dy, dz : real);
procedure Set_Background_Colour(color_in : byte; inten : real);
procedure Set_Palette;
procedure New_Color(col_no : byte; r, g, b : real);
procedure Save_Colors(fname : titletype);
procedure Load_Colors(fname : titletype);
procedure ClGSc;
procedure Fill_Face(this_face : face_ptr);
procedure Fill_Face_Point(this_face : face_ptr);
procedure Fill_Face_Line(this_face : face_ptr);
procedure Show_Page(page_offset : integer);
procedure Stop_Graphics;
procedure Start_Graphics;
procedure Sort_Face_List;
procedure Clip_Stuff;
procedure Text_At(x,y : integer; text : string; colour : byte);
procedure Background_At(x,y : integer; text : string; colour : byte);
procedure Apply_Timed_Transforms;
procedure Send_Screen_to_PCX(fname : titletype);
procedure Write_Text_At(x,y : integer; text : string; tcolour : byte; tintensity : real; bcolour : byte;
bintensity : real);
procedure Set_Text_Proc(temp_textproc : textproc);
procedure Set_Default_Cursor2D;
procedure Cursor2D_Colour(number : byte; intens : real);
procedure Draw_Cursor2D(xpos, ypos : integer);
function Cursor_Inside_Face(this_face : face_ptr; xpos, ypos : integer) : boolean;
function Now : real;
procedure Transform_World_to_Screen;
function NulKeyProc(key : char) : boolean;
procedure NulSelectProc(this_object : object3d_ptr);
function Load_Picture(filename : string) : pointer;
function Number_of_Objects : integer;
function Number_of_Faces : integer;
function Number_of_Vertices : integer;
var x_pos, y_pos, z_pos : real;
viewpoint, setviewpoint, light : vector3d;
azimuth, colatitude, roll, setazimuth, setcolatitude, setroll : real;
screen_page_offset, font_segment, font_offset : word;
eye_screen_distance, speed, setspeed : longint;
light_intensity, ambient_intensity : longint;
hither, yon, picture_num, cursor_x, cursor_y : integer;
first_object : object3d_ptr;
first_list_face : face_ptr;
Sx,Sy,Rx,Ry : longint;
main_matrix, w2v : fixed_matrix_4x4;
redraw_all, timed_Xforms_separately, any_textproc, cursor2D_mode : boolean;
sort_type : byte;
first_timed_Xform : timed_Xform_ptr;
graphics_time : clock_ptr;
this_keyproc : keyproc;
this_textproc : textproc;
cursor_icon : pointer;
background_colour : longint;
cursor_colour : byte;
cursor_y_offset, cursor_x_offset : integer;
default_cursor_icon : array[1..12] of word;
implementation
{------------------------------------------------}
{ Type initialisation method implementations }
{------------------------------------------------}
procedure fixed_matrix_4x4.data(x11, x12, x13, x14,
x21, x22, x23, x24,
x31, x32, x33, x34,
x41, x42, x43, x44 : longint);
begin
el[1,1]:=x11; el[1,2]:=x12; el[1,3]:=x13; el[1,4]:=x14;
el[2,1]:=x21; el[2,2]:=x22; el[2,3]:=x23; el[2,4]:=x24;
el[3,1]:=x31; el[3,2]:=x32; el[3,3]:=x33; el[3,4]:=x34;
el[4,1]:=x41; el[4,2]:=x42; el[4,3]:=x43; el[4,4]:=x44;
end;
procedure vertex.data(x1, y1, z1 : real);
begin
world.x:=real_to_fixed(x1);
world.y:=real_to_fixed(y1);
world.z:=real_to_fixed(z1);
end;
{------------------------------------------------}
{ Vector and matrix manipulation procedures }
{------------------------------------------------}
procedure multiply_4x4(first, second : fixed_matrix_4x4; var out : fixed_matrix_4x4);
var col : integer;
begin
for col:=1 to 3 do
begin
out.el[1,col]:=fixedmul(first.el[1,1],second.el[1,col])+fixedmul(first.el[1,2],second.el[2,col])
+fixedmul(first.el[1,3],second.el[3,col])+fixedmul(first.el[1,4],second.el[4,col]);
end;
for col:=1 to 3 do
begin
out.el[2,col]:=fixedmul(first.el[2,1],second.el[1,col])+fixedmul(first.el[2,2],second.el[2,col])
+fixedmul(first.el[2,3],second.el[3,col])+fixedmul(first.el[2,4],second.el[4,col]);
end;
for col:=1 to 3 do
begin
out.el[3,col]:=fixedmul(first.el[3,1],second.el[1,col])+fixedmul(first.el[3,2],second.el[2,col])
+fixedmul(first.el[3,3],second.el[3,col])+fixedmul(first.el[3,4],second.el[4,col]);
end;
for col:=1 to 3 do
begin
out.el[4,col]:=fixedmul(first.el[4,1],second.el[1,col])+fixedmul(first.el[4,2],second.el[2,col])
+fixedmul(first.el[4,3],second.el[3,col])+fixedmul(first.el[4,4],second.el[4,col]);
end;
out.el[1,4]:=0; out.el[2,4]:=0; out.el[3,4]:=0; out.el[4,4]:=1;
end;
{------------------------------------------------}
{ Object_3d method implementations }
{------------------------------------------------}
constructor object3d.Init;
begin
first_vertex:=nil;
first_face:=nil;
next:=first_object;
first_object:=@first_vertex;
shown:=true;
redraw:=false;
reference_point.x:=0;
reference_point.y:=0;
reference_point.z:=0;
child:=nil;
select_procedure:=NulSelectProc;
end;
destructor object3d.Done;
var temp : object3d_ptr;
temp_child : child_object3d_ptr;
next_vertex : vertex_ptr;
next_face : face_ptr;
begin
while first_vertex<>nil do
begin
next_vertex:=first_vertex^.next;
dispose(first_vertex);
first_vertex:=next_vertex;
end;
while first_face<>nil do
begin
next_face:=first_face^.next;
first_face^.Done;
dispose(first_face);
first_face:=next_face;
end;
{Removes this object from object list}
if first_object=@first_vertex then first_object:=next
else
begin
temp:=first_object;
while (temp<>nil) and (temp^.next<>@first_vertex) do temp:=temp^.next;
if temp<>nil then temp^.next:=next;
end;
{Disposes any child object pointers}
while child<>nil do
begin
temp_child:=child^.next;
dispose(child);
child:=temp_child;
end;
Remove_All_Timed_Transformations;
end;
function object3d.Add_Vertex(x1,y1,z1 : real) : vertex_ptr;
var temp_vertex : vertex_ptr;
begin
new(temp_vertex);
temp_vertex^.data(x1,y1,z1);
temp_vertex^.next:=first_vertex;
first_vertex:=temp_vertex;
Add_vertex:=temp_vertex;
end;
procedure object3d.Remove_Vertex(this_vertex : vertex_ptr);
var temp_vertex, last_vertex : vertex_ptr;
last_face_vertex, temp_face_vertex : face_vertex_ptr;
temp_face, old_face : face_ptr;
count : integer;
found : boolean;
begin
{Remove vertex from object's vertex list}
if first_vertex=temp_vertex then
begin
first_vertex:=first_vertex^.next;
end
else
begin
last_vertex:=first_vertex;
while (last_vertex^.next<>this_vertex) and (last_vertex^.next<>nil) do last_vertex:=last_vertex^.next;
if last_vertex^.next=this_vertex then last_vertex^.next:=this_vertex^.next;
end;
dispose(this_vertex);
{Find faces referencing vertex and remove vertex from list}
{Any faces with less than 3 vertices removed}
temp_face:=first_face;
while temp_face<>nil do
begin
found:=false;
last_face_vertex:=temp_face^.vertex1;
if temp_face^.vertex1^.this_vertex=this_vertex
then
begin
found:=true;
temp_face_vertex:=temp_face^.vertex1;
temp_face^.vertex1:=temp_face^.vertex1^.next;
dispose(temp_face_vertex);
end
else
begin
while (last_face_vertex^.next<>nil) and
(last_face_vertex^.next^.this_vertex<>this_vertex) do last_face_vertex:=last_face_vertex^.next;
if last_face_vertex^.next^.this_vertex=this_vertex then
begin
found:=true;
temp_face_vertex:=last_face_vertex^.next;
last_face_vertex^.next:=last_face_vertex^.next^.next;
dispose(temp_face_vertex);
end;
end;
if found then
begin
count:=0;
temp_face_vertex:=temp_face^.vertex1;
while temp_face_vertex<>nil do
begin
inc(count);
temp_face_vertex:=temp_face_vertex^.next;
end;
if count<3 then
begin
old_face:=temp_face;
temp_face:=temp_face^.next;
dispose(old_face,done);
end
else
temp_face:=temp_face^.next;
end
else
temp_face:=temp_face^.next;
end;
end;
procedure object3d.Build_Normals;
var temp_face : face_ptr;
temp_vertex : vertex_ptr;
begin
temp_face:=first_face;
while temp_face<>nil do
begin
temp_face^.Build_Normal;
temp_face:=temp_face^.next;
end;
lo.x:=$7FFFFFFF; lo.y:=$7FFFFFFF; lo.z:=$7FFFFFFF;
hi.x:=$80000000; hi.y:=$80000000; hi.z:=$80000000;
temp_vertex:=first_vertex;
while temp_vertex<>nil do
begin
with temp_vertex^.world do
begin
if x>hi.x then hi.x:=x else if x<lo.x then lo.x:=x;
if y>hi.y then hi.y:=y else if y<lo.y then lo.y:=y;
if z>hi.z then hi.z:=z else if z<lo.z then lo.z:=z;
end;
temp_vertex:=temp_vertex^.next;
end;
end;
procedure object3d.Save_to_Disk(filename : string);
var f : text;
temp_vertex : vertex_ptr;
temp_face : face_ptr;
temp_face_vertex : face_vertex_ptr;
count : integer;
temp_string1, temp_string2 : string;
begin
assign(f,filename);
rewrite(f);
count:=0;
temp_vertex:=first_vertex;
while temp_vertex<>nil do
begin
inc(count);
temp_vertex:=temp_vertex^.next;
end;
writeln(f,count);
temp_vertex:=first_vertex;
while temp_vertex<>nil do
begin
with temp_vertex^.world do
writeln(f,fixed_to_real(x) : 2 : 5,' ',fixed_to_real(y) : 2 : 5,' ',fixed_to_real(z) : 2 : 5);
temp_vertex:=temp_vertex^.next;
end;
writeln(f,0);
count:=0;
temp_face:=first_face;
while temp_face<>nil do
begin
inc(count);
temp_face:=temp_face^.next;
end;
writeln(f,count);
temp_face:=first_face;
while temp_face<>nil do
begin
writeln(f,temp_face^.colour,' ', fixed_to_real(temp_face^.intensity) : 3 : 2);
count:=0;
temp_face_vertex:=temp_face^.vertex1;
while temp_face_vertex<>nil do
begin
inc(count);
temp_face_vertex:=temp_face_vertex^.next;
end;
writeln(f,count);
temp_string1:='';
temp_face_vertex:=temp_face^.vertex1;
while temp_face_vertex<>nil do
begin
count:=1;
temp_vertex:=first_vertex;
while (temp_vertex<>nil) and (temp_vertex<>temp_face_vertex^.this_vertex) do
begin
inc(count);
temp_vertex:=temp_vertex^.next;
end;
if temp_vertex=nil then
begin
writeln('Error - face vertex not in object');
halt;
end
else
begin
str(count,temp_string2);
temp_string1:=temp_string2+' '+temp_string1;
end;
temp_face_vertex:=temp_face_vertex^.next;
end;
writeln(f,temp_string1);
writeln(f,0);
temp_face:=temp_face^.next;
end;
writeln(f,0);
close(f);
end;
procedure object3d.Unit_Normals;
var temp_face : face_ptr;
begin
temp_face:=first_face;
while temp_face<>nil do
begin
temp_face^.Unit_Normal;
temp_face:=temp_face^.next;
end;
end;
procedure object3d.Transform_to_Screen; external;
procedure object3d.Screen_Position(var x_pos, y_pos, z_pos); external;
procedure object3d.Screen_Limits(var xmin, xmax, ymin, ymax : integer); external;
procedure object3d.Apply_Xform(M : fixed_matrix_4x4); external;
procedure object3d.Apply_Transform(M : fixed_matrix_4x4);
var temp_face : face_ptr;
temp_child : child_object3d_ptr;
begin
self.Apply_XForm(M);
temp_face:=first_face;
while temp_face<>nil do
begin
temp_face^.Shading;
temp_face:=temp_face^.next;
end;
redraw:=true;
if child=nil then exit;
temp_child:=child;
while temp_child<>nil do
begin
temp_child^.this_child^.Apply_Transform(M);
temp_child:=temp_child^.next;
end;
end;
procedure object3d.Set_Reference_Point(x, y, z : real);
begin
reference_point.x:=real_to_fixed(x);
reference_point.y:=real_to_fixed(y);
reference_point.z:=real_to_fixed(z)
end;
procedure object3d.Translate(X, Y, Z : real);
var temp_vertex : vertex_ptr;
temp_face : face_ptr;
temp_child : child_object3d_ptr;
xf,yf,zf : longint;
begin
xf:=real_to_fixed(x); yf:=real_to_fixed(y); zf:=real_to_fixed(z);
temp_vertex:=first_vertex;
while temp_vertex<>nil do
begin
temp_vertex^.world.x:=temp_vertex^.world.x+xf;
temp_vertex^.world.y:=temp_vertex^.world.y+yf;
temp_vertex^.world.z:=temp_vertex^.world.z+zf;
temp_vertex:=temp_vertex^.next;
end;
reference_point.x:=reference_point.x+xf;
reference_point.y:=reference_point.y+yf;
reference_point.z:=reference_point.z+zf;
lo.x:=lo.x+xf;
lo.y:=lo.y+yf;
lo.z:=lo.z+zf;
hi.x:=hi.x+xf;
hi.y:=hi.y+yf;
hi.z:=hi.z+zf;
redraw:=true;
if child=nil then exit;
temp_child:=child;
while temp_child<>nil do
begin
temp_child^.this_child^.Translate(x,y,z);
temp_child:=temp_child^.next;
end;
end;
procedure object3d.Scale(Sx, Sy, Sz : real);
var m : fixed_matrix_4x4;
sxf, syf, szf : longint;
begin
sxf:=real_to_fixed(Sx);
syf:=real_to_fixed(Sy);
szf:=real_to_fixed(Sz);
m.data(sxf,0,0,0,
0,syf,0,0,
0,0,szf,0,
fixedmul(reference_point.x,(65536-sxf)),fixedmul(reference_point.Y,(65536-syf)),
fixedmul(reference_point.Z,(65536-szf)),1);
Apply_Transform(m);
end;
procedure object3d.RotateX(theta : real);
var c, s : longint;
m : fixed_matrix_4x4;
begin
CosSin(round(theta*10),c,s);
m.data(65536,0,0,0,
0,c,s,0,
0,-s,c,0,
0,FixedMul(reference_point.z,s)+FixedMul(reference_point.y,(65536-c)),
FixedMul(-reference_point.y,s)+FixedMul(reference_point.z,(65536-c)),1);
Apply_Transform(m);
end;
procedure object3d.RotateY(theta : real);
var c, s : longint;
m : fixed_matrix_4x4;
begin
CosSin(round(theta*10),c,s);
m.data(c,0,-s,0,
0,65536,0,0,
s,0,c,0,
FixedMul(-reference_point.z,s)+FixedMul(reference_point.x,(65536-c)),0,
FixedMul(reference_point.x,s)+FixedMul(reference_point.z,(65536-c)),1);
Apply_Transform(m);
end;
procedure object3d.RotateZ(theta : real);
var c, s : longint;
m : fixed_matrix_4x4;
begin
CosSin(round(theta*10),c,s);
m.data(c,s,0,0,
-s,c,0,0,
0,0,65536,0,
FixedMul(reference_point.y,s)+FixedMul(reference_point.x,(65536-c)),
FixedMul(-reference_point.x,s)+FixedMul(reference_point.y,(65536-c)),0,1);
Apply_Transform(m);
end;
procedure object3d.Scale_About(Sx, Sy, Sz, X, Y, Z : real);
var m : fixed_matrix_4x4;
begin
m.data(real_to_fixed(Sx),0,0,0,
0,real_to_fixed(Sy),0,0,
0,0,real_to_fixed(Sz),0,
real_to_fixed(X*(1-Sx)),real_to_fixed(Y*(1-Sy)),real_to_fixed(Z*(1-Sz)),1);
Apply_Transform(m);
end;
procedure object3d.RotateX_About(theta, X, Y, Z : real);
var c, s : longint;
m : fixed_matrix_4x4;
yf,zf : longint;
begin
yf:=real_to_fixed(Y);
zf:=real_to_fixed(Z);
CosSin(round(theta*10),c,s);
m.data(65536,0,0,0,
0,c,s,0,
0,-s,c,0,
0,FixedMul(zf,s)+FixedMul(yf,(65536-c)),FixedMul(-yf,s)+FixedMul(zf,(65536-c)),1);
Apply_Transform(m);
end;
procedure object3d.RotateY_About(theta, X, Y, Z : real);
var c, s : longint;
m : fixed_matrix_4x4;
xf,zf : longint;
row, col : integer;
begin
xf:=real_to_fixed(X);
zf:=real_to_fixed(Z);
CosSin(round(theta*10),c,s);
m.data(c,0,-s,0,
0,65536,0,0,
s,0,c,0,
FixedMul(-zf,s)+FixedMul(xf,(65536-c)),0,FixedMul(xf,s)+FixedMul(zf,(65536-c)),1);
Apply_Transform(m);
end;
procedure object3d.RotateZ_About(theta, X, Y, Z : real);
var c, s : longint;
m : fixed_matrix_4x4;
xf,yf : longint;
row,col : integer;
begin
xf:=real_to_fixed(X);
yf:=real_to_fixed(Y);
CosSin(round(theta*10),c,s);
m.data(c,s,0,0,
-s,c,0,0,
0,0,65536,0,
FixedMul(yf,s)+FixedMul(xf,(65536-c)),FixedMul(-xf,s)+FixedMul(yf,(65536-c)),0,1);
Apply_Transform(m);
end;
procedure object3d.MoveTo(X, Y, Z : real);
var dx, dy, dz : real;
begin
dx:=X-fixed_to_real(reference_point.x);
dy:=Y-fixed_to_real(reference_point.y);
dz:=Z-fixed_to_real(reference_point.z);
Translate(dx,dy,dz);
end;
procedure object3d.Timed_Translate(X, Y, Z, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_translate_ptr,Init(@first_vertex,TStart,Duration,X/Duration,Y/Duration,Z/Duration));
end;
procedure object3d.Timed_Scale(Sx, Sy, Sz, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_scale_ptr,Init(@first_vertex,TStart,Duration,SX/Duration,SY/Duration,SZ/Duration));
end;
procedure object3d.Timed_RotateX(theta, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_rotx_ptr,Init(@first_vertex,TStart,Duration,theta/Duration));
end;
procedure object3d.Timed_RotateY(theta, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_roty_ptr,Init(@first_vertex,TStart,Duration,theta/Duration));
end;
procedure object3d.Timed_RotateZ(theta, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_rotz_ptr,Init(@first_vertex,TStart,Duration,theta/Duration));
end;
procedure object3d.Timed_Scale_About(Sx, Sy, Sz, X, Y, Z, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_scale_about_ptr,Init(@first_vertex,TStart,Duration,SX/Duration,SY/Duration,SZ/Duration,X,Y,Z));
end;
procedure object3d.Timed_RotateX_About(theta, X, Y, Z, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_rotx_about_ptr,Init(@first_vertex,TStart,Duration,theta/Duration,X,Y,Z));
end;
procedure object3d.Timed_RotateY_About(theta, X, Y, Z, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_roty_about_ptr,Init(@first_vertex,TStart,Duration,theta/Duration,X,Y,Z));
end;
procedure object3d.Timed_RotateZ_About(theta, X, Y, Z, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_rotz_about_ptr,Init(@first_vertex,TStart,Duration,theta/Duration,X,Y,Z));
end;
procedure object3d.Timed_MoveTo(X, Y, Z, TStart, Duration : real);
var junk : pointer;
dx, dy, dz : real;
begin
dx:=X-fixed_to_real(reference_point.x);
dy:=Y-fixed_to_real(reference_point.y);
dz:=Z-fixed_to_real(reference_point.z);
junk:=new(timed_translate_ptr,Init(@first_vertex,TStart,Duration,dx/Duration,dy/Duration,dz/Duration));
end;
procedure object3d.Timed_Translate_At(dX, dY, dZ, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_translate_ptr,Init(@first_vertex,TStart,Duration,dX,dY,dZ));
end;
procedure object3d.Timed_Scale_At(dSx, dSy, dSz, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_scale_ptr,Init(@first_vertex,TStart,Duration,dSX,dSY,dSZ));
end;
procedure object3d.Timed_RotateX_At(dtheta, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_rotx_ptr,Init(@first_vertex,TStart,Duration,dtheta));
end;
procedure object3d.Timed_RotateY_At(dtheta, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_roty_ptr,Init(@first_vertex,TStart,Duration,dtheta));
end;
procedure object3d.Timed_RotateZ_At(dtheta, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_rotz_ptr,Init(@first_vertex,TStart,Duration,dtheta));
end;
procedure object3d.Timed_Scale_About_At(dSx, dSy, dSz, X, Y, Z, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_scale_about_ptr,Init(@first_vertex,TStart,Duration,dSX,dSY,dSZ,X,Y,Z));
end;
procedure object3d.Timed_RotateX_About_At(dtheta, X, Y, Z, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_rotx_about_ptr,Init(@first_vertex,TStart,Duration,dtheta,X,Y,Z));
end;
procedure object3d.Timed_RotateY_About_At(dtheta, X, Y, Z, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_roty_about_ptr,Init(@first_vertex,TStart,Duration,dtheta,X,Y,Z));
end;
procedure object3d.Timed_RotateZ_About_At(dtheta, X, Y, Z, TStart, Duration : real);
var junk : pointer;
begin
junk:=new(timed_rotz_about_ptr,Init(@first_vertex,TStart,Duration,dtheta,X,Y,Z));
end;
procedure object3d.Remove_All_Timed_Transformations;
var temp, temp2 : timed_xform_ptr;
begin
temp:=first_timed_Xform;
while temp<>nil do
begin
if temp^.this_ob=@first_vertex then
begin
temp2:=temp;
temp:=temp^.next;
dispose(temp2,Done);
end
else
temp:=temp^.next;
end;
end;
procedure object3d.Change_Colour(color_in : byte; inten : real);
var temp : face_ptr;
f_inten : longint;
begin
if (color_in<0) or (color_in>15) then exit;
if (inten<0) or (inten>1) then exit;
f_inten:=real_to_fixed(inten);
temp:=first_face;
while temp<>nil do
begin
temp^.colour:=color_in;
temp^.intensity:=f_inten;
temp^.shading;
temp:=temp^.next;
end;
redraw:=true;
end;
procedure object3d.Show;
begin
shown:=true;
redraw:=true;
end;
procedure object3d.Hide;
begin
shown:=false;
end;
procedure object3d.AddChild(this_object : object3d_ptr);
var temp_child : child_object3d_ptr;
begin
if this_object=nil then exit;
temp_child:=child;
while temp_child<>nil do
begin
if temp_child^.this_child=this_object then exit;
temp_child:=temp_child^.next;
end;
new(temp_child);
temp_child^.next:=child;
child:=temp_child;
temp_child^.this_child:=this_object;
end;
procedure object3d.RemoveChild(this_object : object3d_ptr);
var temp_child : child_object3d_ptr;
begin
if child=nil then exit;
if child^.this_child=this_object then
begin
temp_child:=child;
child:=child^.next;
dispose(temp_child);
end
else
temp_child:=child;
while (temp_child^.next<>nil)and(temp_child^.next^.this_child<>this_object) do temp_child:=temp_child^.next;
if temp_child^.next=nil then exit;
temp_child^.next:=temp_child^.next^.next;
dispose(temp_child^.next);
end;
{$I vroom1}
end.