// 3D Object Viewer // 1998 Spring Geometric Modeling Term Project // Professor : Genji Shimada // Programmed by Joonhong Lim unit Main; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Menus, UrickGL, U3Dpolys, StdCtrls, Buttons, gl, ColorGrd, ComCtrls, Spin, Unit2; type TVdata = array[0..11,0..2] of single; TIndices = array[0..19,0..2] of integer; TVector = array[0..2] of single; TForm1 = class(TForm) Panel1: TPanel; Panel2: TPanel; Panel3: TPanel; MainMenu1: TMainMenu; N1: TMenuItem; Timer1: TTimer; Panel5: TPanel; Panel4: TPanel; Panel7: TPanel; GroupBox2: TGroupBox; Cube: TBitBtn; Sphere: TBitBtn; Panel6: TPanel; GroupBox4: TGroupBox; Panel8: TPanel; GroupBox5: TGroupBox; Back: TBitBtn; Panel9: TPanel; MouseMove: TBitBtn; GroupBox6: TGroupBox; ColorGrid1: TColorGrid; GroupBox3: TGroupBox; GroupBox7: TGroupBox; Up: TBitBtn; Down: TBitBtn; Go: TBitBtn; MoveLeft: TBitBtn; MoveRight: TBitBtn; BitBtn7: TBitBtn; MoveDown: TBitBtn; GroupBox8: TGroupBox; ZAxisRight: TBitBtn; ZAxisLeft: TBitBtn; RotateLeft: TBitBtn; RotateRight: TBitBtn; Panel11: TPanel; GroupBox1: TGroupBox; Label1: TLabel; label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; Panel12: TPanel; BitBtn3: TBitBtn; ColorDialog1: TColorDialog; SpinEdit1: TSpinEdit; Delete: TBitBtn; Label7: TLabel; Label8: TLabel; StatusBar1: TStatusBar; Panel10: TPanel; BitBtn2: TBitBtn; Corn: TBitBtn; Tube: TBitBtn; Panel13: TPanel; GroupBox9: TGroupBox; Spin: TBitBtn; procedure N1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure CubeClick(Sender: TObject); procedure Panel2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure MouseMoveClick(Sender: TObject); procedure FormResize(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure SphereClick(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure BackMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure BackMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ZAxisLeftMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ZAxisLeftMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure GoMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure GoMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ZAxisRightMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ZAxisRightMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure UpMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure UpMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure DownMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure DownMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure RotateLeftMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure RotateLeftMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure RotateRightMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure RotateRightMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure BitBtn7MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure BitBtn7MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure MoveDownMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure MoveDownMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ColorGrid1Click(Sender: TObject); procedure BitBtn3Click(Sender: TObject); procedure MoveLeftMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure MoveLeftMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure MoveRightMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure MoveRightMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure SpinEdit1Change(Sender: TObject); procedure DeleteClick(Sender: TObject); procedure BitBtn2Click(Sender: TObject); procedure CornClick(Sender: TObject); procedure TubeClick(Sender: TObject); procedure SpinClick(Sender: TObject); private { Private declarations } public { Public declarations } Scene: TSceneGL; light: Tlight; num_entity: Integer; mouse: T3DMouse; mouse_mode: Integer; go_move: boolean; Back_move: boolean; z_axis_left: boolean; z_axis_right: boolean; rotate_right: boolean; rotate_left: boolean; rotate_up: boolean; rotate_down: boolean; move_up: boolean; move_down: boolean; move_left: boolean; move_right: boolean; spin_on: boolean; angle_z: single; bR, bG, bB: byte; // RGB color primitive_num: integer; procedure LabelMark; end; procedure Normalize(var v: TVector); procedure Subdivide(var v1, v2, v3: TVector; depth: integer; sphere: TEntity); procedure Drawtriangle(v1, v2, v3: TVector; sphere: TEntity); procedure CalcNormal(v1, v2, v3: TVector; var nx, ny, nz: single); const // This declaration came from P.84 of OpenGL Programming Guide X = 0.525731112119133606; Z = 0.850650808352039932; vdata: TVdata = ((-X,0,Z),(X,0,Z),(-X,0,-Z),(X,0,-Z),(0,Z,X) ,(0,Z,-X),(0,-Z,X),(0,-Z,-X),(Z,X,0),(-Z,X,0),(Z,-X,0),(-Z,-X,0)); indices: TIndices = ((0,4,1),(0,9,4),(9,5,4),(4,5,8),(4,8,1) ,(8,10,1),(8,3,10),(5,3,8),(5,2,3),(2,7,3) ,(7,10,3),(7,6,10),(7,11,6),(11,0,6),(0,1,6) ,(6,1,10),(9,0,11),(9,11,2),(9,2,5),(7,2,11)); var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.N1Click(Sender: TObject); begin Close; end; procedure TForm1.FormCreate(Sender: TObject); begin Scene := TSceneGL.create; light:=Tlight.create(1); {create a white light} Scene.lights.add(light); {add light to scene} Scene.InitRC(panel2.handle); {initialice Rendering context} Scene.UpdateArea(panel2.width,panel2.height); Scene.Redraw; num_entity := -1; mouse := nil; mouse_mode := 1; go_move:= false; back_move := false; z_axis_left := false; z_axis_right := false; rotate_left := false; rotate_right := false; rotate_up := false; rotate_down := false; move_up := false; move_down := false; move_left := false; move_right := false; spin_on := false; bR := $FF; bG := $FF; bB := $FF; panel12.Color := clWhite; primitive_num := -1; end; procedure TForm1.CornClick(Sender: TObject); var Corn: TEntity; Face: TFace; i: integer; px, pz, xx, zz, r, theta, dtheta: single; nx, ny, nz: single; // normal vector v1, v2, v3: TVector; vv: array[1..25] of TVector; begin if(mouse <> nil) then begin mouse.Free; mouse := nil; end; num_entity := num_entity + 1; SpinEdit1.MaxValue := SpinEdit1.MaxValue + 1; primitive_num := num_entity; Corn := TEntity.Create; Corn.SetColor(bR,bG,bB); r := 0.8; px := r; pz := 0; theta := 0; dtheta := pi/12; v1[0] := 0; v1[1] := 1.5; v1[2] := 0; for i := 1 to 24 do begin Face := Corn.AddFace; theta := theta + dtheta; xx := r*cos(theta); zz := r*sin(theta); v2[0] := px; v2[1] := -0.5; v2[2] := pz; v3[0] := xx; v3[1] := -0.5; v3[2] := zz; vv[i,0] := xx; vv[i,1] := -0.5; vv[i,2] := zz; CalcNormal(v1,v3,v2,nx,ny,nz); Face.AddVertex(px, -0.5, pz, nx, ny, nz); Face.AddVertex(0, 1.5, 0, nx, ny, nz); if i = 24 then Face.AddVertex(r, -0.5, 0, nx, ny, nz) else Face.AddVertex(xx, -0.5, zz, nx, ny, nz); px := xx; pz := zz; end; vv[25,0] := r; vv[25,1] := -0.5; vv[25,2] := 0; Face := Corn.AddFace; for i := 1 to 25 do begin Face.AddVertex(vv[i,0],vv[i,1],vv[i,2],0,-1,0); end; corn.Move(0, 0, -10); Scene.Entities.Add(corn); SpinEdit1.Value := num_entity; SpinEdit1.MinValue := 0; Scene.Redraw; labelmark; end; procedure TForm1.TubeClick(Sender: TObject); var Tube: TEntity; Face: TFace; r, px, pz: single; theta, dtheta: single; xx, zz, nx, ny, nz: single; vv: array[1..24] of TVector; v1, v2, v3: TVector; i, i1: integer; begin if(mouse <> nil) then begin mouse.Free; mouse := nil; end; num_entity := num_entity + 1; SpinEdit1.MaxValue := SpinEdit1.MaxValue + 1; primitive_num := num_entity; Tube := TEntity.Create; Tube.SetColor(bR,bG,bB); r := 0.8; px := r; pz := 0; theta := 0; dtheta := pi/12; for i := 1 to 24 do begin Face := Tube.AddFace; theta := theta + dtheta; xx := r*cos(theta); zz := r*sin(theta); v1[0] := px; v1[1] := -1.0; v1[2] := pz; v2[0] := px; v2[1] := 1.0; v2[2] := pz; v3[0] := xx; v3[1] := -1.0; v3[2] := zz; vv[i,0] := xx; vv[i,2] := zz; CalcNormal(v1,v2,v3,nx,ny,nz); Face.AddVertex(px, -1, pz, nx, ny, nz); Face.AddVertex(px, 1, pz, nx, ny, nz); if i = 24 then begin Face.AddVertex(r, 1, 0, nx, ny, nz); Face.AddVertex(r, -1, 0, nx, ny, nz); end else begin Face.AddVertex(xx, 1, zz, nx, ny, nz); Face.AddVertex(xx, -1, zz, nx, ny, nz); end; px := xx; pz := zz; end; Face := Tube.AddFace; for i := 1 to 24 do Face.AddVertex(vv[i,0],-1.0,vv[i,2],0,-1,0); i1 := 24; Face := Tube.AddFace; for i := 1 to 24 do begin Face.AddVertex(vv[i1,0],1.0,vv[i1,2],0,1,0); i1 := i1 - 1; // We have to maintain Count Clock Wise.. end; Tube.Move(0, 0, -10); Scene.Entities.Add(Tube); SpinEdit1.Value := num_entity; SpinEdit1.MinValue := 0; Scene.Redraw; labelmark; end; procedure TForm1.CubeClick(Sender: TObject); var Cube: TEntity; Face: TFace; begin if(mouse <> nil) then begin mouse.Free; mouse := nil; end; num_entity := num_entity + 1; SpinEdit1.MaxValue := SpinEdit1.MaxValue + 1; primitive_num := num_entity; Cube := TEntity.Create; Cube.SetColor(bR,bG,bB); Face:=cube.addFace; {create the first face of the cube} Face.AddVertex(1, 1.0, 1.0,0.0, 0.0, 1.0); {add the 1st vertex} Face.AddVertex(-1, 1.0, 1.0,0.0, 0.0, 1.0); {add the 2nd vertex} Face.AddVertex(-1, -1.0, 1.0,0.0, 0.0, 1.0); {add the 3th vertex} Face.AddVertex(1, -1.0, 1.0,0.0, 0.0, 1.0); {add the 4th vertex} Face:=cube.addFace; Face.AddVertex(1, 1.0, -1.0,0.0, 0.0, -1.0); Face.AddVertex(1, -1.0, -1.0,0.0, 0.0, -1.0); Face.AddVertex(-1, -1.0, -1.0,0.0, 0.0, -1.0); Face.AddVertex(-1, 1.0, -1.0,0.0, 0.0, -1.0); Face:=cube.addFace; Face.AddVertex(-1, 1.0, 1.0,-1.0, 0.0, 0.0); Face.AddVertex(-1, 1.0, -1.0,-1.0, 0.0, 0.0); Face.AddVertex(-1, -1.0, -1.0,-1.0, 0.0, 0.0); Face.AddVertex(-1, -1.0, 1.0,-1.0, 0.0, 0.0); Face:=cube.addFace; Face.AddVertex(1, 1.0, 1.0,1.0, 0.0, 0.0); Face.AddVertex(1, -1.0, 1.0,1.0, 0.0, 0.0); Face.AddVertex(1, -1.0, -1.0,1.0, 0.0, 0.0); Face.AddVertex(1, 1.0, -1.0,1.0, 0.0, 0.0); Face:=cube.addFace; Face.AddVertex(-1, 1.0, -1.0,0.0, 1.0, 0.0); Face.AddVertex(-1, 1.0, 1.0,0.0, 1.0, 0.0); Face.AddVertex(1, 1.0, 1.0,0.0, 1.0, 0.0); Face.AddVertex(1, 1.0, -1.0,0.0, 1.0, 0.0); Face:=cube.addFace; Face.AddVertex(-1, -1.0, -1.0,0.0, -1.0, 0.0); Face.AddVertex(1, -1.0, -1.0,0.0, -1.0, 0.0); Face.AddVertex(1, -1.0, 1.0,0.0, -1.0, 0.0); Face.AddVertex(-1, -1.0, 1.0,0.0, -1.0, 0.0); cube.Move(0, 0, -10); Scene.Entities.Add(cube); SpinEdit1.Value := num_entity; SpinEdit1.MinValue := 0; Scene.Redraw; labelmark; end; procedure TForm1.SphereClick(Sender: TObject); type T3Vector = array[0..2] of TVector; var sphere: TEntity; i, j: Integer; xx, yy, zz : single; v33: T3Vector; v1, v2, v3: TVector; begin if(mouse <> nil) then begin mouse.Free; mouse := nil; end; num_entity := num_entity + 1; SpinEdit1.MaxValue := SpinEdit1.MaxValue + 1; primitive_num := num_entity; sphere := TEntity.Create; sphere.SetColor(bR,bG,bB); for i := 0 to 19 do begin for j := 0 to 2 do begin xx := vdata[indices[i,j], 0]; yy := vdata[indices[i,j], 1]; zz := vdata[indices[i,j], 2]; v33[j,0] := xx; v33[j,1] := yy; v33[j,2] := zz; end; v1[0] := v33[0,0]; v1[1] := v33[0,1]; v1[2] := v33[0,2]; v2[0] := v33[1,0]; v2[1] := v33[1,1]; v2[2] := v33[1,2]; v3[0] := v33[2,0]; v3[1] := v33[2,1]; v3[2] := v33[2,2]; Subdivide(v1, v2, v3, 2, sphere); end; sphere.Move(0, 0, -10); Scene.Entities.Add(sphere); SpinEdit1.Value := num_entity; SpinEdit1.MinValue := 0; Scene.Redraw; Labelmark; end; procedure Subdivide(var v1, v2, v3: TVector; depth: integer; sphere: TEntity); var v12, v23, v31: TVector; i : integer; begin if( depth = 0 ) then begin Drawtriangle(v1, v2, v3, sphere) end else begin for i := 0 to 2 do begin v12[i] := v1[i] + v2[i]; v23[i] := v2[i] + v3[i]; v31[i] := v3[i] + v1[i]; end; Normalize(v12); Normalize(v23); Normalize(v31); Subdivide(v1, v12, v31, depth - 1, sphere); Subdivide(v2, v23, v12, depth - 1, sphere); Subdivide(v3, v31, v23, depth - 1, sphere); Subdivide(v12, v23, v31, depth - 1, sphere); end; end; procedure Normalize(var v: TVector); var f: single; begin f := sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] ); v[0] := v[0] / f; v[1] := v[1] / f; v[2] := v[2] / f; end; procedure Drawtriangle(v1, v2, v3: TVector; sphere: TEntity); var face: TFace; nx, ny, nz: single; begin face := sphere.AddFace; CalcNormal(v1, v3, v2, nx, ny, nz); face.AddVertex(v2[0], v2[1], v2[2], nx, ny, nz); face.AddVertex(v1[0], v1[1], v1[2], nx, ny, nz); face.AddVertex(v3[0], v3[1], v3[2], nx, ny, nz); end; procedure CalcNormal(v1, v2, v3: TVector; var nx, ny, nz: single); var dv1, dv2: TVector; f : single; begin // Generate direction vector dv1, dv2. dv1[0] := v2[0]-v1[0]; dv1[1] := v2[1]-v1[1]; dv1[2] := v2[2]-v1[2]; dv2[0] := v3[0]-v1[0]; dv2[1] := v3[1]-v1[1]; dv2[2] := v3[2]-v1[2]; // Cross Product for normal vector. Here I reuse v3 as a normal vector v3[0] := dv1[1]*dv2[2] - dv1[2]*dv2[1]; v3[1] := dv1[2]*dv2[0] - dv1[0]*dv2[2]; v3[2] := dv1[0]*dv2[1] - dv1[1]*dv2[0]; // Normalization f := sqrt(v3[0]*v3[0] + v3[1]*v3[1] + v3[2]*v3[2]); nx := v3[0] / f; ny := v3[1] / f; nz := v3[2] / f; end; procedure TForm1.Panel2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if mouse <> nil then begin mouse.Move(x,y,Shift); Scene.Redraw; Labelmark; end; end; procedure TForm1.MouseMoveClick(Sender: TObject); begin if mouse <> nil then begin If mouse.mode=1 then begin mouse.mode:=3; mouse_mode := 3; MouseMove.caption:='Rotation'; end else begin mouse.mode:=1; mouse_mode := 1; MouseMove.caption:='Move'; end; end; end; procedure TForm1.Labelmark; begin if num_entity <> -1 then begin Label8.Caption := Format('%d',[primitive_num]); label4.Caption := Format('%4.2f', [Tentity(Scene.Entities.Items[primitive_num]).position[1]]); label5.Caption := Format('%4.2f', [Tentity(Scene.Entities.Items[primitive_num]).position[2]]); label6.Caption := Format('%4.2f', [Tentity(Scene.Entities.Items[primitive_num]).position[3]]); end; end; procedure TForm1.FormResize(Sender: TObject); begin panel2.Width := panel1.Width - 246; Scene.UpdateArea(panel2.width,panel2.height); if num_entity <> -1 then Scene.Redraw; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); var i: Integer; begin Tlight(Scene.Lights.Items[0]).free; for i:=0 to num_entity do TEntity(Scene.Entities.Items[i]).Free; Scene.Free; mouse.Free; end; procedure TForm1.Timer1Timer(Sender: TObject); const da: single = pi/18; // The changing rate of angle. radian. var i: integer; xx, yy, zz: single; R, theta: single; // theta is radian. begin if back_move then begin for i := 0 to num_entity do begin xx := Tentity(Scene.Entities.Items[i]).position[1]; yy := Tentity(Scene.Entities.Items[i]).position[2]; zz := Tentity(Scene.Entities.Items[i]).position[3]; Tentity(Scene.Entities.Items[i]).move(xx, yy, zz - 1); end; Scene.Redraw; labelmark; end; if go_move then begin for i := 0 to num_entity do begin xx := Tentity(Scene.Entities.Items[i]).position[1]; yy := Tentity(Scene.Entities.Items[i]).position[2]; zz := Tentity(Scene.Entities.Items[i]).position[3]; Tentity(Scene.Entities.Items[i]).move(xx, yy, zz + 1); end; Scene.Redraw; labelmark; end; if move_up then begin for i := 0 to num_entity do begin xx := Tentity(Scene.Entities.Items[i]).position[1]; yy := Tentity(Scene.Entities.Items[i]).position[2]; zz := Tentity(Scene.Entities.Items[i]).position[3]; Tentity(Scene.Entities.Items[i]).move(xx, yy+1, zz); end; Scene.Redraw; labelmark; end; if move_down then begin for i := 0 to num_entity do begin xx := Tentity(Scene.Entities.Items[i]).position[1]; yy := Tentity(Scene.Entities.Items[i]).position[2]; zz := Tentity(Scene.Entities.Items[i]).position[3]; Tentity(Scene.Entities.Items[i]).move(xx, yy-1, zz); end; Scene.Redraw; labelmark; end; if move_left then begin for i := 0 to num_entity do begin xx := Tentity(Scene.Entities.Items[i]).position[1]; yy := Tentity(Scene.Entities.Items[i]).position[2]; zz := Tentity(Scene.Entities.Items[i]).position[3]; Tentity(Scene.Entities.Items[i]).move(xx-1, yy, zz); end; Scene.Redraw; labelmark; end; if move_right then begin for i := 0 to num_entity do begin xx := Tentity(Scene.Entities.Items[i]).position[1]; yy := Tentity(Scene.Entities.Items[i]).position[2]; zz := Tentity(Scene.Entities.Items[i]).position[3]; Tentity(Scene.Entities.Items[i]).move(xx+1, yy, zz); end; Scene.Redraw; labelmark; end; if z_axis_left then begin for i := 0 to num_entity do begin xx := Tentity(Scene.Entities.Items[i]).position[1]; yy := Tentity(Scene.Entities.Items[i]).position[2]; zz := Tentity(Scene.Entities.Items[i]).position[3]; if xx <> 0 then theta := Arctan(yy / xx) else if yy < 0 then theta := 1.5*pi else theta := 0.5*pi; r := sqrt(xx*xx + yy*yy); if (xx > 0) then theta := theta + da else if (xx < 0) then theta := theta + da + pi; xx := r*cos(theta); yy := r*sin(theta); Tentity(Scene.Entities.Items[i]).move(xx, yy, zz); end; Scene.Redraw; labelmark; end; if z_axis_right then begin for i := 0 to num_entity do begin xx := Tentity(Scene.Entities.Items[i]).position[1]; yy := Tentity(Scene.Entities.Items[i]).position[2]; zz := Tentity(Scene.Entities.Items[i]).position[3]; if xx <> 0 then theta := Arctan(yy / xx) else if yy < 0 then theta := 1.5*pi else theta := 0.5*pi; r := sqrt(xx*xx + yy*yy); if (xx > 0) then theta := theta - da else if (xx < 0) then theta := theta - da - pi; xx := r*cos(theta); yy := r*sin(theta); Tentity(Scene.Entities.Items[i]).move(xx, yy, zz); end; Scene.Redraw; labelmark; end; if rotate_up then begin for i := 0 to num_entity do begin xx := Tentity(Scene.Entities.Items[i]).position[1]; yy := Tentity(Scene.Entities.Items[i]).position[2]; zz := Tentity(Scene.Entities.Items[i]).position[3]; if zz <> 0 then theta := Arctan(yy / zz) else if yy < 0 then theta := 1.5*pi else theta := 0.5*pi; r := sqrt(zz*zz + yy*yy); if (zz > 0) then theta := theta + da / 2 else if (zz < 0) then theta := theta + da/2 + pi; zz := r*cos(theta); yy := r*sin(theta); Tentity(Scene.Entities.Items[i]).move(xx, yy, zz); end; Scene.Redraw; labelmark; end; if rotate_down then begin for i := 0 to num_entity do begin xx := Tentity(Scene.Entities.Items[i]).position[1]; yy := Tentity(Scene.Entities.Items[i]).position[2]; zz := Tentity(Scene.Entities.Items[i]).position[3]; if zz <> 0 then theta := Arctan(yy / zz) else if yy < 0 then theta := 1.5*pi else theta := 0.5*pi; r := sqrt(zz*zz + yy*yy); if (zz > 0) then theta := theta - da / 2 else if (zz < 0) then theta := theta - da/2 - pi; zz := r*cos(theta); yy := r*sin(theta); Tentity(Scene.Entities.Items[i]).move(xx, yy, zz); end; Scene.Redraw; labelmark; end; if rotate_left then begin for i := 0 to num_entity do begin xx := Tentity(Scene.Entities.Items[i]).position[1]; yy := Tentity(Scene.Entities.Items[i]).position[2]; zz := Tentity(Scene.Entities.Items[i]).position[3]; if zz <> 0 then theta := Arctan(xx / zz) else if xx < 0 then theta := 1.5*pi else theta := 0.5*pi; r := sqrt(xx*xx + zz*zz); if (zz > 0) then theta := theta + da/2 else if (zz < 0) then theta := theta + da/2 + pi; zz := r*cos(theta); xx := r*sin(theta); Tentity(Scene.Entities.Items[i]).move(xx, yy, zz); end; Scene.Redraw; labelmark; end; if rotate_right then begin for i := 0 to num_entity do begin xx := Tentity(Scene.Entities.Items[i]).position[1]; yy := Tentity(Scene.Entities.Items[i]).position[2]; zz := Tentity(Scene.Entities.Items[i]).position[3]; if zz <> 0 then theta := Arctan(xx / zz) else if xx < 0 then theta := 1.5*pi else theta := 0.5*pi; r := sqrt(xx*xx + zz*zz); if (zz > 0) then theta := theta - da/2 else if (zz < 0) then theta := theta - da/2 - pi; zz := r*cos(theta); xx := r*sin(theta); Tentity(Scene.Entities.Items[i]).move(xx, yy, zz); end; Scene.Redraw; labelmark; end; if spin_on then begin for i := 0 to num_entity do begin xx := Tentity(Scene.Entities.Items[i]).rotation[1]; yy := Tentity(Scene.Entities.Items[i]).rotation[2]; zz := Tentity(Scene.Entities.Items[i]).rotation[3]; Tentity(Scene.Entities.Items[i]).rotate(xx+3, yy+3, zz+3 ); end; Scene.Redraw; labelmark; end; end; procedure TForm1.BackMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin back_move := True; Timer1.Enabled := True; end; procedure TForm1.BackMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin back_move := False; Timer1.Enabled := False; end; procedure TForm1.ZAxisLeftMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin z_axis_left := TRUE; timer1.Enabled := TRUE; end; procedure TForm1.ZAxisLeftMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin z_axis_left := FALSE; timer1.Enabled := FALSE; end; procedure TForm1.GoMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin go_move := TRUE; Timer1.Enabled := TRUE; end; procedure TForm1.GoMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin go_move := FALSE; Timer1.Enabled := FALSE; end; procedure TForm1.ZAxisRightMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin z_axis_right := TRUE; Timer1.Enabled := TRUE; end; procedure TForm1.ZAxisRightMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin z_axis_right := FALSE; Timer1.Enabled := FALSE; end; procedure TForm1.UpMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin rotate_down := TRUE; Timer1.Enabled := TRUE; end; procedure TForm1.UpMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin rotate_down := FALSE; Timer1.Enabled := FALSE; end; procedure TForm1.DownMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin rotate_up := TRUE; Timer1.Enabled := TRUE; end; procedure TForm1.DownMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin rotate_up := FALSE; Timer1.Enabled := FALSE; end; procedure TForm1.RotateLeftMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin rotate_left := TRUE; Timer1.Enabled := TRUE; end; procedure TForm1.RotateLeftMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin rotate_left := FALSE; Timer1.Enabled := FALSE; end; procedure TForm1.RotateRightMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin rotate_right := TRUE; Timer1.Enabled := TRUE; end; procedure TForm1.RotateRightMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin rotate_right := FALSE; Timer1.Enabled := FALSE; end; procedure TForm1.BitBtn7MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin move_up := FALSE; Timer1.Enabled := FALSE; end; procedure TForm1.BitBtn7MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin move_up := TRUE; Timer1.Enabled := TRUE; end; procedure TForm1.MoveDownMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin move_down := TRUE; Timer1.Enabled := TRUE; end; procedure TForm1.MoveDownMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin move_down := FALSE; Timer1.Enabled := FALSE; end; procedure TForm1.ColorGrid1Click(Sender: TObject); var p: PByteArray; begin Panel12.Color := ColorGrid1.ForegroundColor; p := @Panel12.Color; bR := p[0]; bG := p[1]; bB := p[2]; end; procedure TForm1.BitBtn3Click(Sender: TObject); var p: PByteArray; begin if ColorDialog1.Execute then begin Panel12.Color := ColorDialog1.Color; p := @Panel12.Color; bR := p[0]; bG := p[1]; bB := p[2]; end; end; procedure TForm1.MoveLeftMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin move_left := TRUE; Timer1.Enabled := TRUE; end; procedure TForm1.MoveLeftMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin move_left := FALSE; Timer1.Enabled := FALSE; end; procedure TForm1.MoveRightMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin move_right := TRUE; Timer1.Enabled := TRUE; end; procedure TForm1.MoveRightMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin move_right := FALSE; Timer1.Enabled := TRUE; end; procedure TForm1.SpinEdit1Change(Sender: TObject); begin if (num_entity <> -1) and (SpinEdit1.Value > -1) and (SpinEdit1.Value <= SpinEdit1.MaxValue) then begin primitive_num := SpinEdit1.Value; if primitive_num > num_entity then primitive_num := num_entity; if (mouse <> nil) then mouse.Free; mouse := T3dMouse.Create(TEntity(Scene.Entities.Items[primitive_num])); mouse.scale(0.1,-0.1,0.1,1,1,1); mouse.Mode := mouse_mode; end; end; procedure TForm1.DeleteClick(Sender: TObject); begin if (num_entity <> -1) and (SpinEdit1.Value > -1) and (SpinEdit1.Value <= SpinEdit1.MaxValue) then begin TEntity(Scene.Entities.Items[SpinEdit1.Value]).Free; // Free the memory Scene.Entities.Delete(SpinEdit1.Value); // Remove the item from List num_entity := num_entity - 1; SpinEdit1.MaxValue := num_entity; if SpinEdit1.Value > num_entity then SpinEdit1.Value := num_entity else if num_entity <> -1 then begin primitive_num := SpinEdit1.Value; if (mouse <> nil) then mouse.Free; mouse := T3dMouse.Create(TEntity(Scene.Entities.Items[primitive_num])); mouse.scale(0.1,-0.1,0.1,1,1,1); mouse.Mode := mouse_mode; end; Scene.Redraw; end; end; procedure TForm1.BitBtn2Click(Sender: TObject); begin Form2.ShowModal; end; procedure TForm1.SpinClick(Sender: TObject); begin if Spin_on then begin Spin_on := FALSE; Timer1.Enabled := FALSE; Spin.Caption := 'Auto Spin' end else begin Spin_on := TRUE; Timer1.Enabled := TRUE; Spin.Caption := 'Stop'; end; end; end.