MathgeomGLS
520 строк · 14.1 Кб
1unit fEllipsoid;
2
3interface
4
5uses
6Winapi.Windows,
7Winapi.Messages,
8System.SysUtils,
9System.Variants,
10System.Classes,
11System.Math,
12Vcl.Graphics,
13Vcl.Controls,
14Vcl.Forms,
15Vcl.Dialogs,
16Vcl.Buttons,
17Vcl.ButtonGroup,
18Vcl.StdCtrls,
19Vcl.ComCtrls,
20Vcl.ExtCtrls,
21
22GLS.OpenGLTokens,
23GLS.SceneViewer,
24GLS.BaseClasses,
25GLS.Scene,
26GLS.GeomObjects,
27GLS.Objects,
28GLS.Coordinates,
29GLS.Graph,
30GLS.VectorLists,
31GLS.VectorTypes,
32GLS.Mesh,
33GLS.HUDObjects,
34GLS.BitmapFont,
35GLS.WindowsFont,
36GLS.VectorGeometry,
37GLS.Color,
38GLS.Texture,
39GLS.Context,
40GLS.Cadencer;
41
42type
43TFormEllipsoid = class(TForm)
44StatusBar: TStatusBar;
45GLScene1: TGLScene;
46GLSceneViewer1: TGLSceneViewer;
47CameraCube: TGLDummyCube;
48Camera: TGLCamera;
49ObjectsCube: TGLDummyCube;
50ArrowZ: TGLArrowLine;
51ArrowY: TGLArrowLine;
52ArrowX: TGLArrowLine;
53GLLightSource1: TGLLightSource;
54Panel1: TPanel;
55Label1: TLabel;
56Label2: TLabel;
57Label3: TLabel;
58Label4: TLabel;
59Label5: TLabel;
60Label6: TLabel;
61Label7: TLabel;
62Label8: TLabel;
63Label9: TLabel;
64Label10: TLabel;
65Label12: TLabel;
66xRadiusTrackBar: TTrackBar;
67yRadiusTrackBar: TTrackBar;
68zRadiusTrackBar: TTrackBar;
69VCurveTrackBar: TTrackBar;
70HCurveTrackBar: TTrackBar;
71GridCheckBox: TCheckBox;
72ArrowsCheckBox: TCheckBox;
73SlicesTrackBar: TTrackBar;
74StacksTrackBar: TTrackBar;
75TopCapRadioGroup: TRadioGroup;
76BottomTrackBar: TTrackBar;
77TopTrackBar: TTrackBar;
78StartTrackBar: TTrackBar;
79StopTrackBar: TTrackBar;
80BottomCapRadioGroup: TRadioGroup;
81Button1: TButton;
82GLXYZGridXZ: TGLXYZGrid;
83GLWindowsBitmapFont1: TGLWindowsBitmapFont;
84GLHUDText: TGLHUDText;
85Button2: TButton;
86GLCadencer1: TGLCadencer;
87GLLightSource: TGLLightSource;
88GLSuperellipsoid: TGLSuperellipsoid;
89GLMesh: TGLMesh;
90procedure FormShow(Sender: TObject);
91procedure FormCreate(Sender: TObject);
92procedure GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton;
93Shift: TShiftState; X, Y: Integer);
94procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
95X, Y: Integer);
96procedure GLSceneViewer1MouseUp(Sender: TObject; Button: TMouseButton;
97Shift: TShiftState; X, Y: Integer);
98
99procedure RadiusTrackBarChange(Sender: TObject);
100procedure VCurveTrackBarChange(Sender: TObject);
101procedure HCurveTrackBarChange(Sender: TObject);
102procedure SlicesTrackBarChange(Sender: TObject);
103procedure StacksTrackBarChange(Sender: TObject);
104procedure GridCheckBoxClick(Sender: TObject);
105procedure ArrowsCheckBoxClick(Sender: TObject);
106procedure TopTrackBarChange(Sender: TObject);
107procedure BottomTrackBarChange(Sender: TObject);
108procedure TopCapRadioGroupClick(Sender: TObject);
109procedure BottomCapRadioGroupClick(Sender: TObject);
110procedure StartTrackBarChange(Sender: TObject);
111procedure StopTrackBarChange(Sender: TObject);
112procedure Button1Click(Sender: TObject);
113procedure checkclick(Sender: TObject);
114procedure CheckBoxClick(Sender: TObject);
115procedure Button2Click(Sender: TObject);
116private
117MousePoint: TPoint;
118Superellipsoids: array [0 .. 5, 0 .. 5] of TGLSuperellipsoid;
119procedure ShowCameraLocation;
120procedure ShowFocalLength;
121procedure ShowDisplacement;
122procedure ShowSuperellipsoid;
123public
124
125end;
126
127var
128FormEllipsoid: TFormEllipsoid;
129
130implementation
131
132{$R *.dfm}
133{$R CURSORS.RES}
134
135const
136crLightxz = 1;
137crLightyz = 2;
138crLightxy = 3;
139crSlidexy = 4;
140crSlideyz = 5;
141crSlidexz = 6;
142crRotate = 7;
143crZoom = 8;
144crHandMove = 9;
145
146procedure TFormEllipsoid.ArrowsCheckBoxClick(Sender: TObject);
147begin
148ArrowX.Visible := not ArrowsCheckBox.Checked;
149ArrowY.Visible := ArrowX.Visible;
150ArrowZ.Visible := ArrowX.Visible;
151end;
152
153procedure TFormEllipsoid.FormCreate(Sender: TObject);
154begin
155Screen.Cursors[crSlidexy] := LoadCursor(HInstance, 'SLIDEXY');
156Screen.Cursors[crRotate] := LoadCursor(HInstance, 'ROTATE');
157Screen.Cursors[crZoom] := LoadCursor(HInstance, 'ZOOM');
158
159Randomize;
160GLSuperellipsoid := TGLSuperellipsoid
161(GLScene1.Objects.AddNewChild(TGLSuperellipsoid));
162GLSuperellipsoid.Direction.SetVector(0, 0, 1);
163GLSuperellipsoid.Up.SetVector(0, 1, 0);
164GLSuperellipsoid.Position.SetPoint(0, 1, 0);
165GLSuperellipsoid.Material.FrontProperties.Ambient.RandomColor;
166GLSuperellipsoid.Material.FrontProperties.Diffuse.RandomColor;
167GLSuperellipsoid.Material.FrontProperties.Shininess := 100;
168end;
169
170procedure TFormEllipsoid.FormShow(Sender: TObject);
171begin
172ShowCameraLocation;
173(* focallength: right mouse drag up/down *)
174ShowFocalLength;
175(*
176displace origin: x axis: ctrl/left mouse drag left/right
177y axis: ctrl/left mouse drag up/down
178*)
179ShowDisplacement;
180(*
181move light: x axis: ctrl right mouse drag left/right
182y axis: ctrl right mouse drag up/down
183z axis: shift right mouse drag up/down
184*)
185ShowSuperellipsoid;
186end;
187
188procedure TFormEllipsoid.GLSceneViewer1MouseDown(Sender: TObject;
189Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
190begin
191MousePoint.X := X;
192MousePoint.Y := Y;
193if ssShift in Shift then
194begin
195if ssLeft in Shift then
196Screen.Cursor := crZoom
197else if ssRight in Shift then
198Screen.Cursor := crLightxz;
199end
200else if ssCtrl in Shift then
201begin
202if ssLeft in Shift then
203Screen.Cursor := crSlidexy
204else if ssRight in Shift then
205Screen.Cursor := crLightxy;
206end
207else { no shift or ctrl key }
208begin
209if Shift = [ssLeft] then
210Screen.Cursor := crRotate
211else if Shift = [ssRight] then
212Screen.Cursor := crZoom;
213end;
214end;
215
216procedure TFormEllipsoid.GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
217X, Y: Integer);
218var
219dx, dy: Integer;
220nx, nz, d: TGLFloat;
221
222begin { refer GLScene\Demos\interface\camera\Camera.dpr }
223dx := MousePoint.X - X;
224dy := MousePoint.Y - Y;
225if ssShift in Shift then { shift key down }
226begin
227if ssLeft in Shift then { left mouse button }
228begin
229{ dy = a step which adjusts target distance by 1.25%; zoom in or out }
230with Camera do
231AdjustDistanceToTarget(Power(1.0125, dy));
232ShowCameraLocation;
233end
234end
235else if ssCtrl in Shift then { Ctrl key down }
236begin
237if ssLeft in Shift then { left mouse button }
238begin
239nz := Camera.Position.Z * dy;
240nx := Camera.Position.Z * dx;
241d := 5 * Camera.FocalLength;
242with CameraCube.Position do
243begin
244Z := Z - nz / d;
245X := X - nx / d;
246end;
247ShowDisplacement;
248end
249end
250else { no shift key }
251begin
252if Shift = [ssLeft] then
253{ Left mouse button changes camera angle by moving around target }
254begin
255Camera.MoveAroundTarget(dy, dx);
256ShowCameraLocation;
257end;
258if Shift = [ssRight] then
259begin
260{ Right mouse button alters the camera's focal length;
261zoom out or in by moving cursor up or down }
262with Camera do
263begin
264FocalLength := FocalLength - dy;
265if FocalLength > 1000 then
266FocalLength := 1000; { max focal length }
267if FocalLength < 20 then
268FocalLength := 20; { min focal length }
269end;
270ShowFocalLength; { display in statusbar palel }
271end;
272end;
273MousePoint.X := X; { update mouse position }
274MousePoint.Y := Y;
275end;
276
277procedure TFormEllipsoid.GLSceneViewer1MouseUp(Sender: TObject; Button: TMouseButton;
278Shift: TShiftState; X, Y: Integer);
279begin
280Screen.Cursor := crDefault;
281end;
282
283procedure TFormEllipsoid.GridCheckBoxClick(Sender: TObject);
284begin
285GLXYZGridXZ.Visible := not GridCheckBox.Checked;
286end;
287
288procedure TFormEllipsoid.CheckBoxClick(Sender: TObject);
289begin
290ShowSuperellipsoid;
291end;
292
293procedure TFormEllipsoid.VCurveTrackBarChange(Sender: TObject);
294var
295n: TGLFloat;
296
297begin
298n := VCurveTrackBar.Position / 10;
299GLSuperellipsoid.VCurve := n;
300ShowSuperellipsoid;
301end;
302
303procedure TFormEllipsoid.HCurveTrackBarChange(Sender: TObject);
304var
305n: TGLFloat;
306
307begin
308n := HCurveTrackBar.Position / 10;
309GLSuperellipsoid.HCurve := n;
310ShowSuperellipsoid;
311end;
312
313procedure TFormEllipsoid.ShowCameraLocation;
314begin
315with Camera.Position do
316StatusBar.Panels[0].Text := 'Camera: ' + FloatToStrF(X, ffNumber, 5, 2) +
317', ' + FloatToStrF(Y, ffNumber, 5, 2) + ', ' +
318FloatToStrF(Z, ffNumber, 5, 2);
319end;
320
321procedure TFormEllipsoid.ShowFocalLength;
322begin
323with Camera do
324StatusBar.Panels[1].Text := 'f = ' + FloatToStrF(FocalLength,
325ffNumber, 5, 2);
326end;
327
328procedure TFormEllipsoid.ShowDisplacement;
329begin
330with CameraCube.Position do
331StatusBar.Panels[2].Text := 'Displaced: ' + FloatToStrF(-X, ffNumber, 5, 2)
332+ ', ' + FloatToStrF(-Y, ffNumber, 5, 2);
333end;
334
335procedure TFormEllipsoid.ShowSuperellipsoid;
336begin
337// Superellipsoid.NormalDirection := ndInside;
338// Superellipsoid.Normals :=
339(*
340Determines how and if normals are smoothed.
341- nsFlat : facetted look
342- nsSmooth : smooth look
343- nsNone : unlighted rendering, usefull for decla texturing
344*)
345GLSuperellipsoid.Scale.SetVector(xRadiusTrackBar.Position,
346yRadiusTrackBar.Position, zRadiusTrackBar.Position);
347GLSuperellipsoid.Slices := SlicesTrackBar.Position;
348GLSuperellipsoid.Stacks := StacksTrackBar.Position;
349GLSuperellipsoid.Top := TopTrackBar.Position;
350
351case TopCapRadioGroup.ItemIndex of
3520: GLSuperellipsoid.TopCap := ctNone;
3531: GLSuperellipsoid.TopCap := ctCenter;
3542: GLSuperellipsoid.TopCap := ctFlat;
355end;
356
357GLSuperellipsoid.Bottom := -BottomTrackBar.Position;
358
359case BottomCapRadioGroup.ItemIndex of
3600: GLSuperellipsoid.BottomCap := ctNone;
3611: GLSuperellipsoid.BottomCap := ctCenter;
3622: GLSuperellipsoid.BottomCap := ctFlat;
363end;
364
365if (StartTrackBar.Position <= StopTrackBar.Position) and
366(StartTrackBar.Position < 360) then
367begin
368GLSuperellipsoid.Start := StartTrackBar.Position;
369GLSuperellipsoid.Stop := StopTrackBar.Position;
370end;
371GLSuperellipsoid.Normals := nsNone;
372GLHUDText.Text := 'Scale:' + FloatToStrF(xRadiusTrackBar.Position / 10,
373ffNumber, 6, 2) + ', ' + FloatToStrF(yRadiusTrackBar.Position / 10,
374ffNumber, 6, 2) + ', ' + FloatToStrF(zRadiusTrackBar.Position / 10,
375ffNumber, 6, 2) + #13#10'VCurve:' +
376FloatToStrF(VCurveTrackBar.Position / 10, ffNumber, 6, 2) + #13#10'HCurve:'
377+ FloatToStrF(HCurveTrackBar.Position / 10, ffNumber, 6, 2) +
378#13#10'Slices:' + IntToStr(SlicesTrackBar.Position) + #13#10'Stacks:' +
379IntToStr(StacksTrackBar.Position) + #13#10'Top:' +
380IntToStr(TopTrackBar.Position) + '�' + #13#10'Bottom:' +
381IntToStr(BottomTrackBar.Position) + '�' + #13#10'Start:' +
382IntToStr(StartTrackBar.Position) + '�' + #13#10'Stop:' +
383IntToStr(StopTrackBar.Position) + '�';
384end;
385
386procedure TFormEllipsoid.SlicesTrackBarChange(Sender: TObject);
387begin
388ShowSuperellipsoid;
389end;
390
391procedure TFormEllipsoid.StacksTrackBarChange(Sender: TObject);
392begin
393ShowSuperellipsoid;
394end;
395
396procedure TFormEllipsoid.StartTrackBarChange(Sender: TObject);
397begin
398if (StartTrackBar.Position >= StopTrackBar.Position) then
399StartTrackBar.Position := StopTrackBar.Position;
400ShowSuperellipsoid;
401end;
402
403procedure TFormEllipsoid.TopCapRadioGroupClick(Sender: TObject);
404begin
405ShowSuperellipsoid;
406end;
407
408procedure TFormEllipsoid.TopTrackBarChange(Sender: TObject);
409begin
410ShowSuperellipsoid;
411end;
412
413procedure TFormEllipsoid.StopTrackBarChange(Sender: TObject);
414begin
415if (StopTrackBar.Position <= StartTrackBar.Position) then
416StopTrackBar.Position := StartTrackBar.Position;
417ShowSuperellipsoid;
418end;
419
420procedure TFormEllipsoid.BottomCapRadioGroupClick(Sender: TObject);
421begin
422ShowSuperellipsoid;
423end;
424
425procedure TFormEllipsoid.BottomTrackBarChange(Sender: TObject);
426begin
427ShowSuperellipsoid;
428end;
429
430procedure TFormEllipsoid.Button1Click(Sender: TObject);
431begin
432with GLSuperellipsoid.Material.Texture do
433begin
434// We need a CubeMapImage, which unlike the "regular Images" stores
435// multiple images.
436ImageClassName := TGLCubeMapImage.ClassName;
437with Image as TGLCubeMapImage do
438begin
439// Load all 6 texture map components of the cube map
440// The 'PX', 'NX', etc. refer to 'positive X', 'negative X', etc.
441// and follow the RenderMan specs/conventions
442Picture[cmtNX].LoadFromFile('cm_left.png');
443Picture[cmtPX].LoadFromFile('cm_right.png');
444Picture[cmtNY].LoadFromFile('cm_top.png');
445Picture[cmtPY].LoadFromFile('cm_bottom.png');
446Picture[cmtPZ].LoadFromFile('cm_back.png');
447Picture[cmtNZ].LoadFromFile('cm_front.png');
448end;
449// Select reflection cube map environment mapping
450// This is the mode you'll most commonly use with cube maps, normal cube
451// map generation is also supported (used for diffuse environment lighting)
452MappingMode := tmmCubeMapReflection;
453// That's all folks, let us see the thing!
454Disabled := False;
455end;
456Button1.Visible := False;
457end;
458
459procedure TFormEllipsoid.Button2Click(Sender: TObject);
460var
461i, j: Integer;
462X, Y, d: single;
463begin
464d := 6;
465Randomize;
466for j := 0 to 5 do
467for i := 0 to 5 do
468begin
469X := -d * 2.5 + d * i;
470Y := d * 2.5 - d * j;
471Superellipsoids[i, j] := TGLSuperellipsoid
472(GLScene1.Objects.AddNewChild(TGLSuperellipsoid));
473
474with Superellipsoids[i, j] do
475begin
476Slices := 32;
477Stacks := 32;
478Scale.SetVector(5, 5, 5);
479Position.SetPoint(X, Y, 0);
480Direction.SetVector(0, 1, 0);
481Up.SetVector(0, 0, 1);
482case i of
4830: VCurve := 0.2;
4841: VCurve := 0.8;
4852: VCurve := 1.0;
4863: VCurve := 1.5;
4874: VCurve := 2.0;
4885: VCurve := 3.0;
489end;
490case j of
4910: HCurve := 0.2;
4921: HCurve := 0.8;
4932: HCurve := 1.0;
4943: HCurve := 1.5;
4954: HCurve := 2.0;
4965: HCurve := 3.0;
497end;
498with Material.FrontProperties do
499begin
500Ambient.RandomColor;
501Diffuse.RandomColor;
502Specular.RandomColor;
503Shininess := 125;
504end;
505end;
506end;
507Button2.Visible := False;
508end;
509
510procedure TFormEllipsoid.checkclick(Sender: TObject);
511begin
512ShowSuperellipsoid;
513end;
514
515procedure TFormEllipsoid.RadiusTrackBarChange(Sender: TObject);
516begin
517ShowSuperellipsoid;
518end;
519
520end.
521