2
// This unit is part of the GLScene Engine https://github.com/glscene
5
Invisible component for helping to Move, Rotate and Scale an Object
6
under GLScene (usefull for an Editor).
9
10/11/12 - PW - Added CPP compatibility by changing arrays to records for vectors;
10
replaced uppercase characters in prefixes for enum types to lower case
11
22/04/10 - Yar - Fixes after GLState revision
12
14/07/09 - DaStr - Bugfixed object selection from code (thanks Predator)
13
20/01/08 - DaStr - Cleaned up uses section for proper FPC support
15
18/09/07 - DaStr - Initial version (based on GLGizmo.pas by Adirex,
16
J.Delauney, Degiovani, Marcus Oblak and a bit myself)
22
// ------------------------------------------------------------------------------
23
// Unit : GLGizmo RC 1.0
24
// ------------------------------------------------------------------------------
25
// Original Author : ??????? (glGizmo In an ODEEditor)
26
// ------------------------------------------------------------------------------
27
// Modified by : J.Delauney
28
// Web Site : http://KheopsInteractive.cjb.net
29
// EMail : wmkheops@free.fr
32
// Modified by : Marcus Oblak (8/3/2007)
33
// - Corrected moving/rotating for children objects
34
// - Better quantization for mouse operations (MoveCoef,RotationCoef)
36
// - Added GizmoThickness
38
// If you make some changes, please send your new version. Thanks
39
// ------------------------------------------------------------------------------
41
// Invisible component for helping to Move, Rotate and Scale an Object
42
// under GLScene (usefull for an Editor)
43
// ------------------------------------------------------------------------------
45
// - Interaction When All Gizmo parts are Invisible
46
// - Add "gpMoveGizmo and gpRotateGizmo" operations and use Like a "Pivot"
47
// or use RootGizmo As "Pivot"
48
// - Add Interactive Camera Movements
49
// - Adding Extended Controls with Keys
50
// - Maybe An Undo Function
52
// ------------------------------------------------------------------------------
54
// - When you change the BoundingBoxColor and LabelInfosColor
55
// The New Color is not Updated immediately, only after a new Click
56
// (see in UpdateGizmo, SetBoundingBoxColor
57
// and SetLabelInfosColor Procedures)
58
// - DaStr: Bounding Box is not alway drawn correctly because it does not
59
// use objects' BarryCenter. For Example, if you select Space Text.
60
// ------------------------------------------------------------------------------
72
GLScene, GLColor, GLObjects, GLVectorGeometry, GLMaterial, GLStrings,
73
GLGeomObjects, GLBitmapFont, GLViewer, GLVectorFileObjects, GLCrossPlatform,
74
GLCoordinates, GLRenderContextInfo, GLState, GLSelection
78
TGLGizmoUndoCollection = class;
81
TGLGizmoUndoItem = class(TCollectionItem)
83
FOldLibMaterialName: string;
84
FOldAutoScaling: TGLCoordinates;
85
FEffectedObject: TGLCustomSceneObject;
88
procedure SetEffectedObject(const Value: TGLCustomSceneObject);
89
procedure SetOldAutoScaling(const Value: TGLCoordinates);
90
procedure SetOldMatrix(const Value: TMatrix);
92
procedure DoUndo; virtual;
93
function GetParent: TGLGizmoUndoCollection;
94
function GetGizmo: TGLGizmo;
96
constructor Create(AOwner: TCollection); override;
97
destructor Destroy; override;
98
procedure Notification(AComponent: TComponent;
99
Operation: TOperation); virtual;
100
procedure AssignFromObject(const AObject: TGLCustomSceneObject);
102
// TODO: create a special type for Matrix.
103
property OldMatrix: TMatrix read FOldMatrix write SetOldMatrix;
105
property EffectedObject: TGLCustomSceneObject read FEffectedObject
106
write SetEffectedObject;
107
property OldAutoScaling: TGLCoordinates read FOldAutoScaling
108
write SetOldAutoScaling;
109
property OldLibMaterialName: string read FOldLibMaterialName
110
write FOldLibMaterialName;
113
TGLGizmoUndoCollection = class(TOwnedCollection)
115
function GetItems(const Index: Integer): TGLGizmoUndoItem;
116
procedure SetItems(const Index: Integer; const Value: TGLGizmoUndoItem);
118
function GetParent: TGLGizmo;
120
procedure Notification(AComponent: TComponent; Operation: TOperation);
121
procedure RemoveByObject(const AObject: TGLCustomSceneObject);
122
function Add: TGLGizmoUndoItem;
123
property Items[const Index: Integer]: TGLGizmoUndoItem read GetItems
124
write SetItems; default;
127
TGLGizmoElement = (geMove, geRotate, geScale, geAxisLabel, geObjectInfos,
129
TGLGizmoElements = set of TGLGizmoElement;
131
TGLGizmoVisibleInfoLabel = (vliName, vliOperation, vliCoords);
132
TGLGizmoVisibleInfoLabels = set of TGLGizmoVisibleInfoLabel;
134
TGLGizmoAxis = (gaNone, gaX, gaY, gaZ, gaXY, gaXZ, gaYZ);
136
TGLGizmoOperation = (gopMove, gopRotate, gopScale, gopNone, gpMoveGizmo,
139
TGLGizmoAcceptEvent = procedure(Sender: TObject; var Obj: TGLBaseSceneObject;
140
var Accept: Boolean; var Dimensions: TVector) of object;
141
TGLGizmoUpdateEvent = procedure(Sender: TObject; Obj: TGLBaseSceneObject;
142
Axis: TGLGizmoAxis; Operation: TGLGizmoOperation; var Vector: TVector)
145
TGLGizmoPickMode = (pmGetPickedObjects, pmRayCast);
147
TGLGizmoRayCastHitData = class(TPersistent)
149
Obj: TGLBaseSceneObject;
153
TGLGizmoPickCube = class(TGLCube)
156
TGLGizmoPickTorus = class(TGLTorus)
159
TGLGizmo = class(TComponent)
161
_GZObaseGizmo: TGLBaseSceneObject;
163
_GZOBoundingcube: TGLCube;
165
_GZOrootHelpers: TGLBaseSceneObject;
166
_GZOrootLines: TGLBaseSceneObject;
167
_GZOrootTorus: TGLBaseSceneObject;
168
_GZOrootCubes: TGLBaseSceneObject;
169
_GZORootAxisLabel: TGLBaseSceneObject;
170
_GZORootVisibleInfoLabels: TGLBaseSceneObject;
172
_GZOlineX, _GZOlineY, _GZOlineZ, _GZOplaneXY, _GZOplaneXZ,
173
_GZOplaneYZ: TGLLines; // For Move
174
_GZOTorusX, _GZOTorusY, _GZOTorusZ: TGLGizmoPickTorus; // For Rotate
175
_GZOCubeX, _GZOCubeY, _GZOCubeZ: TGLGizmoPickCube; // For Scale
177
_GZOAxisLabelX, _GZOAxisLabelY, _GZOAxisLabelZ: TGLFlatText;
178
_GZOVisibleInfoLabels: TGLFlatText;
180
FRootGizmo: TGLBaseSceneObject;
181
FSelectedObj: TGLBaseSceneObject;
183
FOperation: TGLGizmoOperation;
184
FSelAxis: TGLGizmoAxis;
186
FBoundingBoxColor: TGLColor;
187
FSelectedColor: TGLColor;
188
FVisibleInfoLabelsColor: TGLColor;
190
FBoundingBoxColorChanged: Boolean;
191
FVisibleInfoLabelsColorChanged: Boolean;
193
FForceOperation: Boolean;
195
FForceUniformScale: Boolean;
197
FExcludeObjects: Boolean;
201
FAutoZoomFactor: Single;
204
FRotationCoef: Single;
206
FViewer: TGLSceneViewer;
208
FGizmoElements: TGLGizmoElements;
209
FVisibleVisibleInfoLabels: TGLGizmoVisibleInfoLabels;
211
FExcludeObjectsList: TStrings;
217
dglEnable, dglDisable, dgtEnable, dgtDisable, dgcEnable, dgcDisable,
218
dglaEnable, dglaDisable, dgliEnable, dgliDisable: TGLDirectOpenGL;
220
LastMousePos: TVector;
221
ObjDimensions: TVector;
223
FOnBeforeSelect: TGLGizmoAcceptEvent;
224
FOnBeforeUpdate: TGLGizmoUpdateEvent;
225
FOnSelectionLost: TNotifyEvent;
227
FGizmoThickness: Single;
228
FPickMode: TGLGizmoPickMode;
229
FInternalRaycastHitData: TList;
231
FUndoHistory: TGLGizmoUndoCollection;
232
FLabelFont: TGLCustomBitmapFont;
234
procedure SetRootGizmo(const AValue: TGLBaseSceneObject);
236
procedure SetGizmoElements(const AValue: TGLGizmoElements);
237
procedure SeTGLGizmoVisibleInfoLabels(const AValue
238
: TGLGizmoVisibleInfoLabels);
239
procedure SetBoundingBoxColor(const AValue: TGLColor);
240
procedure SetSelectedColor(const AValue: TGLColor);
241
procedure SetVisibleInfoLabelsColor(const AValue: TGLColor);
243
procedure SetExcludeObjectsList(const AValue: TStrings);
245
procedure DirectGlDisable(Sender: TObject; var Rci: TGLRenderContextInfo);
246
procedure DirectGlEnable(Sender: TObject; var Rci: TGLRenderContextInfo);
248
function MouseWorldPos(const X, Y: Integer): TVector;
249
function CheckObjectInExcludeList(const Obj: TGLBaseSceneObject): Boolean;
250
procedure UpdateVisibleInfoLabels;
251
procedure SetGLGizmoThickness(const Value: Single);
253
function InternalGetPickedObjects(const X1, Y1, X2, Y2: Integer;
254
const GuessCount: Integer = 8): TGLPickList;
255
procedure ClearInternalRaycastHitData;
256
procedure SetViewer(const Value: TGLSceneViewer);
257
procedure SetLabelFont(const Value: TGLCustomBitmapFont);
258
procedure SetSelectedObj(const Value: TGLBaseSceneObject);
260
PickableObjectsWithRayCast: TList;
261
constructor Create(AOwner: TComponent); override;
262
destructor Destroy; override;
263
procedure Loaded; override;
264
procedure Notification(AComponent: TComponent;
265
Operation: TOperation); override;
267
procedure ViewerMouseMove(const X, Y: Integer);
268
procedure ViewerMouseDown(const X, Y: Integer);
269
procedure ViewerMouseUp(const X, Y: Integer);
271
procedure UpdateGizmo; overload;
272
procedure UpdateGizmo(const NewDimensions: TVector); overload;
273
procedure SetVisible(const AValue: Boolean);
274
function GetPickedObjectPoint(const Obj: TGLBaseSceneObject): TVector;
276
procedure LooseSelection; virtual;
278
procedure UndoAdd(const AObject: TGLCustomSceneObject);
279
property RootGizmo: TGLBaseSceneObject read FRootGizmo write SetRootGizmo;
281
// --------------------------------------------------------------------
284
property Viewer: TGLSceneViewer read FViewer write SetViewer;
286
property GizmoElements: TGLGizmoElements read FGizmoElements
287
write SetGizmoElements;
289
property BoundingBoxColor: TGLColor read FBoundingBoxColor
290
write SetBoundingBoxColor;
291
property SelectedColor: TGLColor read FSelectedColor write SetSelectedColor;
293
property SelAxis: TGLGizmoAxis read FSelAxis write FSelAxis;
294
property ForceAxis: Boolean read FForceAxis write FForceAxis;
296
property SelectedObj: TGLBaseSceneObject read FSelectedObj
297
write SetSelectedObj;
299
property Operation: TGLGizmoOperation read FOperation write FOperation;
300
property ForceOperation: Boolean read FForceOperation write FForceoperation;
301
property ForceUniformScale: Boolean read FForceUniformScale
302
write FForceUniformScale;
304
property ExcludeObjects: Boolean read FExcludeObjects write FExcludeObjects;
305
property ExcludeObjectsList: TStrings read FExcludeObjectsList
306
write SetExcludeObjectsList;
308
property VisibleInfoLabels: TGLGizmoVisibleInfoLabels
309
read FVisibleVisibleInfoLabels write SeTGLGizmoVisibleInfoLabels;
310
property VisibleInfoLabelsColor: TGLColor read FVisibleInfoLabelsColor
311
write SetVisibleInfoLabelsColor;
313
property AutoZoom: Boolean read FAutoZoom write FAutoZoom;
314
property AutoZoomFactor: Single read FAutoZoomFactor write FAutoZoomFactor;
315
property ZoomFactor: Single read FZoomFactor write FZoomFactor;
317
property MoveCoef: Single read FMoveCoef write FMoveCoef;
318
property RotationCoef: Single read FRotationCoef write FRotationCoef;
319
property ScaleCoef: Single read FScaleCoef write FScaleCoef;
320
property NoZWrite: Boolean read FNoZWrite write FNoZWrite;
322
property GizmoThickness: Single read FGizmoThickness
323
write SeTGLGizmoThickness;
325
{ : Indicates whether the gizmo is enabled or not.
326
WARNING: When loading/editing (possibly whenever a structureChanged
327
call is made) a model, sometimes the gizmo will trigger a
328
bug if the mouse is inside the glscene Viewer. To prevent that,
329
remember to disable the gizmo before loading, then process windows
330
messages (i.e. application.processMessage) and then enable the gizmo
333
{ : Warning Enable is ReadOnly property if you set to False, Gizmo is not Hidden
334
use Visible instead if you want to Hide, if you want to Hide but keep enabled
335
see the VisibleGizmo property }
336
property Enabled: Boolean read FEnabled write FEnabled default False;
338
property LabelFont: TGLCustomBitmapFont read FLabelFont write SetLabelFont
341
property OnBeforeSelect: TGLGizmoAcceptEvent read FOnBeforeSelect
342
write FOnBeforeSelect;
343
property OnSelectionLost: TNotifyEvent read FOnSelectionLost
344
write FOnSelectionLost;
346
{ : Called before an Update is applied. The "vector" parameter is the difference
347
that will be applied to the object, according to the axis and
348
operation selected. }
349
property OnBeforeUpdate: TGLGizmoUpdateEvent read FOnBeforeUpdate
350
write FOnBeforeUpdate;
351
property PickMode: TGLGizmoPickMode read FPickMode write FPickMode
352
default PmGetPickedObjects;
357
procedure RotateAroundArbitraryAxis(const AnObject: TGLBaseSceneObject;
358
const Axis, Origin: TAffineVector; const Angle: Single);
360
M, M1, M2, M3: TMatrix;
362
M1 := CreateTranslationMatrix(VectorNegate(Origin));
363
M2 := CreateRotationMatrix(Axis, Angle * PI / 180);
364
M3 := CreateTranslationMatrix(Origin);
365
M := MatrixMultiply(M1, M2);
366
M := MatrixMultiply(M, M3);
367
AnObject.Matrix := MatrixMultiply(AnObject.Matrix, M);
369
// Just a workarround to Update angles...
375
// ------------------------------------------------------------------------------
377
procedure TGLGizmo.ClearInternalRaycastHitData;
381
for T := FInternalRaycastHitData.Count - 1 downto 0 do
383
TGLGizmoRayCastHitData(FInternalRaycastHitData[T]).Free;
385
FInternalRaycastHitData.Clear;
388
constructor TGLGizmo.Create(AOwner: TComponent);
392
inherited Create(AOwner);
393
FUndoHistory := TGLGizmoUndoCollection.Create(Self, TGLGizmoUndoItem);
394
FPickMode := PmGetPickedObjects;
395
PickableObjectsWithRayCast := TList.Create;
399
FGizmoThickness := 1;
401
FInternalRaycastHitData := TList.Create;
402
FBoundingBoxColor := TGLColor.Create(Self);
403
FBoundingBoxColor.Color := ClrWhite;
404
FBoundingBoxColorChanged := False;
405
FSelectedColor := TGLColor.Create(Self);
406
FSelectedColor.Color := ClrYellow;
407
FVisibleInfoLabelsColor := TGLColor.Create(Self);
408
FVisibleInfoLabelsColor.Color := ClrYellow;
409
FVisibleInfoLabelsColorChanged := False;
411
_GZObaseGizmo := TGLDummyCube.Create(Self);
412
_GZORootHelpers := TGLDummyCube(_GZObaseGizmo.AddNewChild(TGLDummyCube));
413
_GZOBoundingcube := TGLCube(_GZORootHelpers.AddNewChild(TGLCube));
415
_GZORootLines := _GZORootHelpers.AddNewChild(TGLDummyCube);
416
_GZORootTorus := _GZORootHelpers.AddNewChild(TGLDummyCube);
417
_GZORootCubes := _GZORootHelpers.AddNewChild(TGLDummyCube);
418
_GZORootAxisLabel := _GZORootHelpers.AddNewChild(TGLDummyCube);
419
_GZORootVisibleInfoLabels := _GZORootHelpers.AddNewChild(TGLDummyCube);
421
DglDisable := TGLDirectOpenGL(_GZORootLines.AddNewChild(TGLDirectOpenGL));
422
DglDisable.OnRender := DirectGlDisable;
423
DgtDisable := TGLDirectOpenGL(_GZORootTorus.AddNewChild(TGLDirectOpenGL));
424
DgtDisable.OnRender := DirectGlDisable;
425
DgcDisable := TGLDirectOpenGL(_GZORootCubes.AddNewChild(TGLDirectOpenGL));
426
DgcDisable.OnRender := DirectGlDisable;
427
DglaDisable := TGLDirectOpenGL
428
(_GZORootAxisLabel.AddNewChild(TGLDirectOpenGL));
429
DglaDisable.OnRender := DirectGlDisable;
430
DgliDisable := TGLDirectOpenGL(_GZORootVisibleInfoLabels.AddNewChild
432
DgliDisable.OnRender := DirectGlDisable;
434
with _GZOBoundingcube.Material do
436
FaceCulling := FcNoCull;
437
PolygonMode := PmLines;
438
with FrontProperties do
440
Diffuse.Color := FBoundingBoxColor.Color;
441
Ambient.Color := FBoundingBoxColor.Color;
442
Emission.Color := FBoundingBoxColor.Color;
444
with BackProperties do
446
Diffuse.Color := FBoundingBoxColor.Color;
447
Ambient.Color := FBoundingBoxColor.Color;
448
Emission.Color := FBoundingBoxColor.Color;
452
_GZOlinex := TGLLines(_GZORootLines.AddnewChild(TGLLines));
455
LineColor.Color := clrRed;
457
NodesAspect := LnaInvisible;
460
AddNode(0.9, 0, -0.1);
462
AddNode(0.9, 0, 0.1);
463
// Raycast pickable object
464
Cub := TGLGizmoPickCube(AddNewChild(TGLGizmoPickCube));
465
Cub.Up.SetVector(1, 0, 0);
466
Cub.CubeWidth := 0.1;
468
Cub.CubeDepth := 0.1;
469
Cub.Position.SetPoint(0.5, 0, 0);
470
Cub.Visible := False;
473
_GZOliney := TGLLines(_GZORootLines.AddnewChild(TGLLines));
476
LineColor.Color := clrLime;
478
NodesAspect := LnaInvisible;
481
AddNode(0.1, 0.9, 0);
483
AddNode(-0.1, 0.9, 0);
484
// Raycast pickable object
485
Cub := TGLGizmoPickCube(AddNewChild(TGLGizmoPickCube));
486
Cub.Up.SetVector(0, 1, 0);
487
Cub.CubeWidth := 0.1;
489
Cub.CubeDepth := 0.1;
490
Cub.Position.SetPoint(0, 0.5, 0);
491
Cub.Visible := False;
494
_GZOlinez := TGLLines(_GZORootLines.AddnewChild(TGLLines));
497
LineColor.Color := clrBlue;
499
NodesAspect := LnaInvisible;
502
AddNode(0.1, 0, 0.9);
504
AddNode(-0.1, 0, 0.9);
505
// Raycast pickable object
506
Cub := TGLGizmoPickCube(AddNewChild(TGLGizmoPickCube));
507
Cub.Up.SetVector(0, 0, 1);
508
Cub.CubeWidth := 0.1;
510
Cub.CubeDepth := 0.1;
511
Cub.Position.SetPoint(0, 0, 0.5);
512
Cub.Visible := False;
515
_GZOplaneXY := TGLLines(_GZORootLines.AddnewChild(TGLLines));
519
Options := [LoUseNodeColorForLines];
520
NodesAspect := LnaInvisible;
521
SplineMode := LsmSegments;
523
TGLLinesNode(Nodes[0]).Color.Color := clrRed;
525
TGLLinesNode(Nodes[1]).Color.Color := clrRed;
527
TGLLinesNode(Nodes[2]).Color.Color := clrLime;
529
TGLLinesNode(Nodes[3]).Color.Color := clrLime;
530
// Raycast pickable object
531
Cub := TGLGizmoPickCube(AddNewChild(TGLGizmoPickCube));
532
Cub.Up.SetVector(1, 0, 0);
533
Cub.CubeWidth := 0.2;
534
Cub.CubeHeight := 0.2;
535
Cub.CubeDepth := 0.1;
536
Cub.Position.SetPoint(0.9, 0.9, 0);
537
Cub.Visible := False;
540
_GZOplaneXZ := TGLLines(_GZORootLines.AddnewChild(TGLLines));
544
Options := [LoUseNodeColorForLines];
545
NodesAspect := LnaInvisible;
546
SplineMode := LsmSegments;
548
TGLLinesNode(Nodes[0]).Color.Color := clrBlue;
550
TGLLinesNode(Nodes[1]).Color.Color := clrBlue;
552
TGLLinesNode(Nodes[2]).Color.Color := clrRed;
554
TGLLinesNode(Nodes[3]).Color.Color := clrRed;
555
// Raycast pickable object
556
Cub := TGLGizmoPickCube(AddNewChild(TGLGizmoPickCube));
557
Cub.Up.SetVector(1, 0, 0);
558
Cub.CubeWidth := 0.1;
559
Cub.CubeHeight := 0.2;
560
Cub.CubeDepth := 0.2;
561
Cub.Position.SetPoint(0.9, 0, 0.9);
562
Cub.Visible := False;
565
_GZOplaneYZ := TGLLines(_GZORootLines.AddnewChild(TGLLines));
569
Options := [LoUseNodeColorForLines];
570
NodesAspect := LnaInvisible;
571
SplineMode := LsmSegments;
573
TGLLinesNode(Nodes[0]).Color.Color := clrLime;
575
TGLLinesNode(Nodes[1]).Color.Color := clrLime;
577
TGLLinesNode(Nodes[2]).Color.Color := clrBlue;
579
TGLLinesNode(Nodes[3]).Color.Color := clrBlue;
580
// Raycast pickable object
581
Cub := TGLGizmoPickCube(AddNewChild(TGLGizmoPickCube));
582
Cub.Up.SetVector(0, 0, 1);
583
Cub.CubeWidth := 0.2;
584
Cub.CubeHeight := 0.2;
585
Cub.CubeDepth := 0.1;
586
Cub.Position.SetPoint(0, 0.9, 0.9);
587
Cub.Visible := False;
590
_GZOTorusX := TGLGizmoPickTorus(_GZORootTorus.AddnewChild(TGLGizmoPickTorus));
601
// FaceCulling:= fcNoCull;
602
PolygonMode := PmFill;
603
// BackProperties.PolygonMode:= pmFill;
604
FrontProperties.Emission.Color := clrBlue;
608
_GZOTorusY := TGLGizmoPickTorus(_GZORootTorus.AddnewChild(TGLGizmoPickTorus));
618
// FaceCulling:= fcNoCull;
619
PolygonMode := PmFill;
620
// BackProperties.PolygonMode:= pmFill;
621
FrontProperties.Emission.Color := clrRed;
625
_GZOTorusZ := TGLGizmoPickTorus(_GZORootTorus.AddnewChild(TGLGizmoPickTorus));
634
// FaceCulling:= fcNoCull;
635
PolygonMode := PmFill;
636
// BackProperties.PolygonMode:= pmFill;
637
FrontProperties.Emission.Color := clrLime;
641
_GZOCubeX := TGLGizmoPickCube(_GZORootCubes.AddnewChild(TGLGizmoPickCube));
650
FaceCulling := FcNoCull;
651
PolygonMode := PmFill;
652
FrontProperties.Emission.Color := clrRed;
656
_GZOCubeY := TGLGizmoPickCube(_GZORootCubes.AddnewChild(TGLGizmoPickCube));
665
FaceCulling := FcNoCull;
666
PolygonMode := PmFill;
667
FrontProperties.Emission.Color := clrLime;
671
_GZOCubeZ := TGLGizmoPickCube(_GZORootCubes.AddnewChild(TGLGizmoPickCube));
680
FaceCulling := FcNoCull;
681
PolygonMode := PmFill;
682
FrontProperties.Emission.Color := clrBlue;
686
_GZOAxisLabelX := TGLFlatText(_GZORootAxisLabel.AddNewChild(TGLFlatText));
687
with _GZOAxisLabelX do
689
ModulateColor.Color := ClrRed;
690
Alignment := TaCenter;
692
Options := Options + [FtoTwoSided];
699
_GZOAxisLabelY := TGLFlatText(_GZORootAxisLabel.AddNewChild(TGLFlatText));
700
with _GZOAxisLabelY do
702
ModulateColor.Color := clrLime;
703
Alignment := TaCenter;
705
Options := Options + [FtoTwoSided];
712
_GZOAxisLabelZ := TGLFlatText(_GZORootAxisLabel.AddNewChild(TGLFlatText));
713
with _GZOAxisLabelZ do
715
ModulateColor.Color := ClrBlue;
716
Alignment := TaCenter;
718
Options := Options + [FtoTwoSided];
725
_GZOVisibleInfoLabels :=
726
TGLFlatText(_GZORootVisibleInfoLabels.AddNewChild(TGLFlatText));
727
with _GZOVisibleInfoLabels do
729
ModulateColor.Color := clrYellow;
730
Alignment := TaCenter;
732
Options := Options + [FtoTwoSided];
740
DglEnable := TGLDirectOpenGL(_GZORootLines.AddNewChild(TGLDirectOpenGL));
741
DglEnable.OnRender := DirectGlEnable;
742
DgtEnable := TGLDirectOpenGL(_GZORootTorus.AddNewChild(TGLDirectOpenGL));
743
DgtEnable.OnRender := DirectGlEnable;
744
DgcEnable := TGLDirectOpenGL(_GZORootCubes.AddNewChild(TGLDirectOpenGL));
745
DgcEnable.OnRender := DirectGlEnable;
746
DglaEnable := TGLDirectOpenGL(_GZORootAxisLabel.AddNewChild(TGLDirectOpenGL));
747
DglaEnable.OnRender := DirectGlEnable;
748
DgliEnable := TGLDirectOpenGL(_GZORootVisibleInfoLabels.AddNewChild
750
DgliEnable.OnRender := DirectGlEnable;
752
_GZObaseGizmo.Visible := False;
753
FGizmoElements := FGizmoElements + [GeMove, GeRotate, GeScale, GeAxisLabel,
754
GeObjectInfos, GeBoundingBox];
755
FVisibleVisibleInfoLabels := FVisibleVisibleInfoLabels +
756
[VliName, VliOperation, VliCoords];
758
AutoZoomFactor := 5.0;
760
ForceOperation := False;
762
ForceUniformScale := False;
765
FExcludeObjectsList := TStringList.Create;
768
destructor TGLGizmo.Destroy;
770
if Assigned(FRootGizmo) then
771
FRootGizmo.DeleteChildren
774
_GZOBaseGizmo.DeleteChildren;
778
FBoundingBoxColor.Free;
780
FVisibleInfoLabelsColor.Free;
781
PickableObjectsWithRayCast.Free;
782
FExcludeObjectsList.Free;
783
ClearInternalRaycastHitData;
784
FInternalRaycastHitData.Free;
786
// FUndoHistory has to be nil before Notification() is called.
787
FreeAndNil(FUndoHistory);
791
procedure TGLGizmo.SetVisible(const AValue: Boolean);
793
_GZObaseGizmo.Visible := AValue;
796
procedure TGLGizmo.SetGizmoElements(const AValue: TGLGizmoElements);
798
if AValue <> FGizmoElements then
800
FGizmoElements := AValue;
801
_GZORootLines.Visible := GeMove in FGizmoElements;
802
_GZORootTorus.Visible := GeRotate in FGizmoElements;
803
_GZORootCubes.Visible := GeScale in FGizmoElements;
804
_GZORootAxisLabel.Visible := GeAxisLabel in FGizmoElements;
805
_GZORootVisibleInfoLabels.Visible := GeObjectInfos in FGizmoElements;
806
_GZOBoundingcube.Visible := GeBoundingBox in FGizmoElements;
810
procedure TGLGizmo.SetBoundingBoxColor(const AValue: TGLColor);
812
// Bug Here New Color is not Updated
813
if AValue <> FBoundingBoxColor then
815
FBoundingBoxColor.Color := AValue.Color;
816
with _GZOBoundingcube.Material do
818
with FrontProperties do
820
Diffuse.Color := FBoundingBoxColor.Color;
821
Ambient.Color := FBoundingBoxColor.Color;
822
Emission.Color := FBoundingBoxColor.Color;
824
with BackProperties do
826
Diffuse.Color := FBoundingBoxColor.Color;
827
Ambient.Color := FBoundingBoxColor.Color;
828
Emission.Color := FBoundingBoxColor.Color;
831
FBoundingBoxColorChanged := True;
835
procedure TGLGizmo.SetSelectedColor(const AValue: TGLColor);
837
if AValue <> FSelectedColor then
839
FSelectedColor.Color := AValue.Color;
843
procedure TGLGizmo.SetVisibleInfoLabelsColor(const AValue: TGLColor);
845
// Bug Here New Color is not Updated
846
if AValue <> FSelectedColor then
848
FVisibleInfoLabelsColor.Color := AValue.Color;
849
_GZOVisibleInfoLabels.ModulateColor.Color := AValue.Color;
850
FVisibleInfoLabelsColorChanged := True;
854
procedure TGLGizmo.SeTGLGizmoVisibleInfoLabels(const AValue
855
: TGLGizmoVisibleInfoLabels);
857
if AValue <> FVisibleVisibleInfoLabels then
859
FVisibleVisibleInfoLabels := AValue;
860
if not(CsDesigning in ComponentState) then
865
procedure TGLGizmo.UndoAdd(const AObject: TGLCustomSceneObject);
867
if AObject <> nil then
869
FUndoHistory.Add.AssignFromObject(AObject)
873
procedure TGLGizmo.SetRootGizmo(const AValue: TGLBaseSceneObject);
875
if FRootGizmo <> AValue then
877
if FRootGizmo <> nil then
878
FRootGizmo.RemoveFreeNotification(Self);
879
FRootGizmo := AValue;
880
if FRootGizmo <> nil then
881
FRootGizmo.FreeNotification(Self);
882
_GZObaseGizmo.MoveTo(AValue);
886
procedure TGLGizmo.SetExcludeObjectsList(const AValue: TStrings);
888
FExcludeObjectsList.Clear;
889
FExcludeObjectsList.AddStrings(AValue);
892
procedure TGLGizmo.SetGLGizmoThickness(const Value: Single);
896
if FGizmoThickness <> Value then
898
Thk := MaxInteger(1, Round(3 * Value));
899
_GZOlinex.LineWidth := Thk;
900
_GZOliney.LineWidth := Thk;
901
_GZOlinez.LineWidth := Thk;
902
_GZOplaneXY.LineWidth := Thk;
903
_GZOplaneXZ.LineWidth := Thk;
904
_GZOplaneYZ.LineWidth := Thk;
906
_GZOTorusX.MinorRadius := 0.03 * Value;
907
_GZOTorusY.MinorRadius := 0.03 * Value;
908
_GZOTorusZ.MinorRadius := 0.03 * Value;
912
CubeDepth := 0.1 * Value;
913
CubeHeight := 0.1 * Value;
914
CubeWidth := 0.1 * Value;
918
CubeDepth := 0.1 * Value;
919
CubeHeight := 0.1 * Value;
920
CubeWidth := 0.1 * Value;
924
CubeDepth := 0.1 * Value;
925
CubeHeight := 0.1 * Value;
926
CubeWidth := 0.1 * Value;
929
FGizmoThickness := Value;
933
// ------------------------------------------------------------------------------
935
procedure TGLGizmo.DirectGlDisable(Sender: TObject;
936
var Rci: TGLRenderContextInfo);
939
Rci.GLStates.Disable(StDepthTest);
942
procedure TGLGizmo.SetLabelFont(const Value: TGLCustomBitmapFont);
944
if FLabelFont <> Value then
946
if FLabelFont <> nil then
947
FLabelFont.RemoveFreeNotification(Self);
949
if FLabelFont <> nil then
950
FLabelFont.FreeNotification(Self);
952
_GZOAxisLabelX.BitmapFont := Value;
953
_GZOAxisLabelY.BitmapFont := Value;
954
_GZOAxisLabelZ.BitmapFont := Value;
955
_GZOVisibleInfoLabels.BitmapFont := Value;
959
procedure TGLGizmo.DirectGlEnable(Sender: TObject; var Rci: TGLRenderContextInfo);
962
Rci.GLStates.Enable(StDepthTest);
965
function TGLGizmo.GetPickedObjectPoint(const Obj: TGLBaseSceneObject): TVector;
968
R: TGLGizmoRayCastHitData;
970
for T := 0 to FInternalRaycastHitData.Count - 1 do
972
R := TGLGizmoRayCastHitData(FInternalRaycastHitData[T]);
981
function TGLGizmo.InternalGetPickedObjects(const X1, Y1, X2, Y2: Integer;
982
const GuessCount: Integer): TGLPickList;
985
RayStart, RayVector, IPoint, INormal: TVector;
986
O: TGLBaseSceneObject;
988
HitData: TGLGizmoRayCastHitData;
990
procedure AddGizmosToPicklListRecurse(const Root: TGLBaseSceneObject);
994
for U := 0 to Root.Count - 1 do
996
if ((Root[U] is TGLGizmoPickTorus) or (Root[U] is TGLGizmoPickCube)) then
997
PickableObjectsWithRayCast.Add(Root[U]);
998
AddGizmosToPicklListRecurse(Root[U]);
1006
Result := Viewer.Buffer.GetPickedObjects(Rect(X1, Y1, X2, Y2),
1012
Result := TGLPickList.Create(PsMinDepth);
1013
ClearInternalRaycastHitData;
1014
SetVector(RayStart, Viewer.Camera.AbsolutePosition);
1015
SetVector(RayVector, Viewer.Buffer.ScreenToVector
1016
(AffineVectorMake((X1 + X2) * 0.5,
1017
Viewer.Height - ((Y1 + Y2) * 0.5), 0)));
1018
NormalizeVector(RayVector);
1020
if (RootGizmo <> nil) and (SelectedObj <> nil) then
1021
AddGizmosToPicklListRecurse(RootGizmo);
1023
for T := 0 to PickableObjectsWithRayCast.Count - 1 do
1025
O := TGLBaseSceneObject(PickableObjectsWithRayCast[T]);
1026
if (O.RayCastIntersect(RayStart, RayVector, @IPoint, @INormal)) and
1027
(VectorDotProduct(RayVector, INormal) < 0) then
1030
Dist := VectorLength(VectorSubtract(IPoint, RayStart));
1031
Result.AddHit(O, nil, Dist, 0);
1032
HitData := TGLGizmoRayCastHitData.Create;
1034
MakeVector(HitData.Point, IPoint);
1035
FInternalRaycastHitData.Add(HitData);
1046
Assert(False, GlsErrorEx + GlsUnknownType);
1052
procedure TGLGizmo.Loaded;
1055
SeTGLGizmoThickness(GizmoThickness);
1058
// ------------------------------------------------------------------------------
1059
procedure TGLGizmo.UpdateVisibleInfoLabels;
1065
if not(Assigned(SelectedObj)) then
1067
if VliName in FVisibleVisibleInfoLabels then
1068
T := SelectedObj.Name;
1070
if VliOperation in FVisibleVisibleInfoLabels then
1072
if (Operation <> GopNone) then
1074
if Length(T) > 0 then
1087
if VliCoords in FVisibleVisibleInfoLabels then
1089
if (Operation <> GopNone) then
1091
if Length(T) > 0 then
1096
X := SelectedObj.Position.X;
1097
Y := SelectedObj.Position.Y;
1098
Z := SelectedObj.Position.Z;
1099
T := T + 'X : ' + Format('%2.3f', [X]);
1100
T := T + ' Y : ' + Format('%2.3f', [Y]);
1101
T := T + ' Z : ' + Format('%2.3f', [Z]);
1105
X := SelectedObj.Rotation.X;
1106
Y := SelectedObj.Rotation.Y;
1107
Z := SelectedObj.Rotation.Z;
1108
T := T + 'X : ' + Format('%2.3f', [X]);
1109
T := T + ' Y : ' + Format('%2.3f', [Y]);
1110
T := T + ' Z : ' + Format('%2.3f', [Z]);
1114
X := SelectedObj.Scale.X;
1115
Y := SelectedObj.Scale.Y;
1116
Z := SelectedObj.Scale.Z;
1117
T := T + 'X : ' + Format('%2.3f', [X]);
1118
T := T + ' Y : ' + Format('%2.3f', [Y]);
1119
T := T + ' Z : ' + Format('%2.3f', [Z]);
1125
_GZOVisibleInfoLabels.Text := T;
1126
_GZOVisibleInfoLabels.StructureChanged;
1129
// ------------------------------------------------------------------------------
1131
function TGLGizmo.CheckObjectInExcludeList
1132
(const Obj: TGLBaseSceneObject): Boolean;
1137
if FExcludeObjects then
1139
for I := 0 to FExcludeObjectsList.Count - 1 do
1141
if UpperCase(Obj.Name) = UpperCase(FExcludeObjectsList[I]) then
1150
function TGLGizmo.MouseWorldPos(const X, Y: Integer): TVector;
1155
InvertedY := Viewer.Height - Y;
1156
if Assigned(SelectedObj) then
1158
SetVector(V, X, InvertedY, 0);
1162
if not Viewer.Buffer.ScreenVectorIntersectWithPlaneXZ(V,
1163
SelectedObj.AbsolutePosition.V[1], Result) then
1164
MakeVector(Result, X / 5, 0, 0);
1167
if not Viewer.Buffer.ScreenVectorIntersectWithPlaneYZ(V,
1168
SelectedObj.AbsolutePosition.V[0], Result) then
1169
MakeVector(Result, 0, InvertedY / 5, 0);
1172
if not Viewer.Buffer.ScreenVectorIntersectWithPlaneYZ(V,
1173
SelectedObj.AbsolutePosition.V[0], Result) then
1174
MakeVector(Result, 0, 0, -InvertedY / 5);
1178
Viewer.Buffer.ScreenVectorIntersectWithPlaneXY(V,
1179
SelectedObj.AbsolutePosition.V[2], Result);
1183
Viewer.Buffer.ScreenVectorIntersectWithPlaneXZ(V,
1184
SelectedObj.AbsolutePosition.V[1], Result);
1188
Viewer.Buffer.ScreenVectorIntersectWithPlaneYZ(V,
1189
SelectedObj.AbsolutePosition.V[0], Result);
1195
SetVector(Result, NullVector);
1198
procedure TGLGizmo.ViewerMouseMove(const X, Y: Integer);
1200
PickList: TGLPickList;
1203
function IndexOf(Obj: TGLBaseSceneObject): Integer;
1208
for I := 0 to PickList.Count - 1 do
1209
if PickList.Hit[I] = Obj then
1216
function LightLine(const Line: TGLLines; const Dark: TVector;
1217
const Axis: TGLGizmoAxis; AlterStyle: Boolean = False): Boolean;
1219
PickObj: TGLBaseSceneObject;
1229
Assert(False, GlsErrorEx + GlsUnknownType);
1233
if IndexOf(PickObj) > -1 then
1235
Line.LineColor.Color := FSelectedColor.Color;
1236
if not(FForceOperation) then
1237
if Operation <> GopMove then
1238
Operation := GopMove;
1240
if not(FForceAxis) then
1246
Line.LineColor.Color := Dark;
1247
if not(FForceOperation) then
1248
Operation := GopNone;
1250
Line.Options := [LoUseNodeColorForLines];
1251
if not(FForceAxis) then
1252
if SelAxis = Axis then
1258
function LightTorus(const Torus: TGLGizmoPickTorus; const Dark: TVector;
1259
const Axis: TGLGizmoAxis; AlterStyle: Boolean = False): Boolean;
1261
if IndexOf(Torus) > -1 then
1263
Torus.Material.FrontProperties.Emission.Color := FSelectedColor.Color;
1264
if not(FForceOperation) then
1265
if Operation <> GopRotate then
1266
Operation := GopRotate;
1267
if not(FForceAxis) then
1273
Torus.Material.FrontProperties.Emission.Color := Dark;
1274
if not(FForceOperation) then
1275
Operation := GopNone;
1276
if not(FForceAxis) then
1277
if SelAxis = Axis then
1283
function LightCube(const Cube: TGLCube; const Dark: TVector;
1284
const Axis: TGLGizmoAxis; AlterStyle: Boolean = False): Boolean;
1286
if IndexOf(Cube) > -1 then
1288
Cube.Material.FrontProperties.Emission.Color := FSelectedColor.Color;
1289
if not(FForceOperation) then
1290
if Operation <> GopScale then
1291
Operation := GopScale;
1292
if not(FForceAxis) then
1298
Cube.Material.FrontProperties.Emission.Color := Dark;
1299
if not(FForceOperation) then
1300
Operation := GopNone;
1301
if not(FForceAxis) then
1302
if SelAxis = Axis then
1308
procedure OpeMove(MousePos: TVector);
1310
Vec1, Vec2: TVector;
1311
QuantizedMousePos, QuantizedMousePos2: TVector;
1316
QuantizedMousePos.V[T] := (Round(MousePos.V[T] / MoveCoef)) * MoveCoef;
1317
QuantizedMousePos2.V[T] := (Round(LastMousePos.V[T] / MoveCoef)) * MoveCoef;
1322
MakeVector(Vec1, QuantizedMousePos.V[0], 0, 0);
1323
MakeVector(Vec2, QuantizedMousePos2.V[0], 0, 0);
1327
MakeVector(Vec1, 0, QuantizedMousePos.V[1], 0);
1328
MakeVector(Vec2, 0, QuantizedMousePos2.V[1], 0);
1332
MakeVector(Vec1, 0, 0, QuantizedMousePos.V[2]);
1333
MakeVector(Vec2, 0, 0, QuantizedMousePos2.V[2]);
1337
Vec1 := QuantizedMousePos;
1338
Vec2 := QuantizedMousePos2;
1341
SubtractVector(Vec1, Vec2);
1342
if Assigned(OnBeforeUpdate) then
1343
OnBeforeUpdate(Self, SelectedObj, SelAxis, Operation, Vec1);
1344
Vec1 := SelectedObj.Parent.AbsoluteToLocal(Vec1);
1345
if (VectorLength(Vec1) > 0) then // prevents NAN problems
1347
SelectedObj.Position.Translate(Vec1);
1351
procedure OpeRotate(const X, Y: Integer);
1354
RotV: TAffineVector;
1360
if Abs(X - Rx) >= RotationCoef then
1362
if RotationCoef > 1 then
1363
Vec1.V[0] := RotationCoef * (Round((X - Rx) / (RotationCoef)))
1365
Vec1.V[0] := RotationCoef * (X - Rx);
1368
if Abs(Y - Ry) >= RotationCoef then
1370
if RotationCoef > 1 then
1371
Vec1.V[1] := RotationCoef * (Round((Y - Ry) / (RotationCoef)))
1373
Vec1.V[1] := RotationCoef * (Y - Ry);
1379
if Assigned(OnBeforeUpdate) then
1380
OnBeforeUpdate(Self, SelectedObj, SelAxis, Operation, Vec1);
1382
Pmat := SelectedObj.Parent.InvAbsoluteMatrix;
1383
SetVector(Pmat.V[3], NullHmgPoint);
1387
RotV := VectorTransform(XVector, Pmat);
1388
RotateAroundArbitraryAxis(SelectedObj, RotV,
1389
AffineVectorMake(SelectedObj.Position.AsVector), Vec1.V[1]);
1393
RotV := VectorTransform(YVector, Pmat);
1394
RotateAroundArbitraryAxis(SelectedObj, RotV,
1395
AffineVectorMake(SelectedObj.Position.AsVector), Vec1.V[0]);
1399
RotV := VectorTransform(ZVector, Pmat);
1400
RotateAroundArbitraryAxis(SelectedObj, RotV,
1401
AffineVectorMake(SelectedObj.Position.AsVector), Vec1.V[1]);
1405
RotV := VectorTransform(XVector, Pmat);
1406
RotateAroundArbitraryAxis(SelectedObj, RotV,
1407
AffineVectorMake(SelectedObj.Position.AsVector), Vec1.V[1]);
1408
RotV := VectorTransform(YVector, Pmat);
1409
RotateAroundArbitraryAxis(SelectedObj, RotV,
1410
AffineVectorMake(SelectedObj.Position.AsVector), Vec1.V[0]);
1414
RotV := VectorTransform(XVector, Pmat);
1415
RotateAroundArbitraryAxis(SelectedObj, RotV,
1416
AffineVectorMake(SelectedObj.Position.AsVector), Vec1.V[1]);
1417
RotV := VectorTransform(ZVector, Pmat);
1418
RotateAroundArbitraryAxis(SelectedObj, RotV,
1419
AffineVectorMake(SelectedObj.Position.AsVector), Vec1.V[0]);
1423
RotV := VectorTransform(YVector, Pmat);
1424
RotateAroundArbitraryAxis(SelectedObj, RotV,
1425
AffineVectorMake(SelectedObj.Position.AsVector), Vec1.V[1]);
1426
RotV := VectorTransform(ZVector, Pmat);
1427
RotateAroundArbitraryAxis(SelectedObj, RotV,
1428
AffineVectorMake(SelectedObj.Position.AsVector), Vec1.V[0]);
1433
procedure OpeScale(const MousePos: TVector);
1435
Vec1, Vec2: TVector;
1436
QuantizedMousePos, QuantizedMousePos2: TVector;
1441
QuantizedMousePos.V[T] := (Round(MousePos.V[T] / ScaleCoef)) * FScaleCoef;
1442
QuantizedMousePos2.V[T] := (Round(LastMousePos.V[T] / FScaleCoef)) *
1448
if FForceUniformScale then
1450
MakeVector(Vec1, QuantizedMousePos.V[0], QuantizedMousePos.V[0],
1451
QuantizedMousePos.V[0]);
1452
MakeVector(Vec2, QuantizedMousePos2.V[0], QuantizedMousePos2.V[0],
1453
QuantizedMousePos2.V[0]);
1457
MakeVector(Vec1, QuantizedMousePos.V[0], 0, 0);
1458
MakeVector(Vec2, QuantizedMousePos2.V[0], 0, 0);
1465
if FForceUniformScale then
1467
MakeVector(Vec1, QuantizedMousePos.V[1], QuantizedMousePos.V[1],
1468
QuantizedMousePos.V[1]);
1469
MakeVector(Vec2, QuantizedMousePos2.V[1], QuantizedMousePos2.V[1],
1470
QuantizedMousePos2.V[1]);
1474
MakeVector(Vec1, 0, QuantizedMousePos.V[1], 0);
1475
MakeVector(Vec2, 0, QuantizedMousePos2.V[1], 0);
1481
if FForceUniformScale then
1483
MakeVector(Vec1, QuantizedMousePos.V[2], QuantizedMousePos.V[2],
1484
QuantizedMousePos.V[2]);
1485
MakeVector(Vec2, QuantizedMousePos2.V[2], QuantizedMousePos2.V[2],
1486
QuantizedMousePos2.V[2]);
1490
MakeVector(Vec1, 0, 0, QuantizedMousePos.V[2]);
1491
MakeVector(Vec2, 0, 0, QuantizedMousePos2.V[2]);
1496
Vec1 := QuantizedMousePos;
1497
Vec2 := QuantizedMousePos2;
1500
SubtractVector(Vec1, Vec2);
1501
if Assigned(OnBeforeUpdate) then
1502
OnBeforeUpdate(Self, SelectedObj, SelAxis, Operation, Vec1);
1503
SelectedObj.Scale.Translate(Vec1);
1511
if Assigned(SelectedObj) and (SelAxis <> GaNone) and Moving then
1513
MousePos := MouseWorldPos(X, Y);
1516
if Operation = GopMove then
1518
// FLastOperation = gopMove;
1521
else if Operation = GopRotate then
1523
// FLastOperation = gopRotate;
1526
else if Operation = GopScale then
1528
// FLastOperation = gopScale;
1535
LastMousePos := MousePos;
1539
Assert(FViewer <> nil, 'Viewer not Assigned to gizmo');
1540
Picklist := InternalGetPickedObjects(X - 1, Y - 1, X + 1, Y + 1, 8);
1541
// Viewer.buffer.GetPickedObjects(rect(x-1, y-1, x+1, y+1), 8);
1543
if not LightLine(_GZOlinex, ClrRed, GaX) and not LightLine(_GZOliney, ClrLime,
1544
GaY) and not LightLine(_GZOlinez, ClrBlue, GaZ) and
1545
not LightTorus(_GZOTorusX, ClrRed, GaX) and
1546
not LightTorus(_GZOTorusY, ClrLime, GaY) and
1547
not LightTorus(_GZOTorusz, ClrBlue, GaZ) and
1548
not LightCube(_GZOCubeX, ClrRed, GaX) and not LightCube(_GZOCubeY, ClrLime,
1549
GaY) and not LightCube(_GZOCubeZ, ClrBlue, GaZ) and
1550
not LightLine(_GZOplaneXY, ClrWhite, GaXY, True) and
1551
not LightLine(_GZOplaneXZ, ClrWhite, GaXZ, True) and
1552
not LightLine(_GZOplaneYZ, ClrWhite, GaYZ, True) then
1554
if not(FForceAxis) then
1556
if not(FForceOperation) then
1557
Operation := GopNone;
1566
procedure TGLGizmo.ViewerMouseDown(const X, Y: Integer);
1571
Dimensions: TVector;
1573
PickedObj: TGLBaseSceneObject;
1583
Pick := InternalGetPickedObjects(X - 1, Y - 1, X + 1, Y + 1);
1584
// Viewer.Buffer.GetPickedObjects(rect(x-1, y-1, x+1, y+1));
1591
// primeiro, ver se � uma das linhas/planos
1592
for I := 0 to Pick.Count - 1 do
1593
if (_GZOrootLines.IndexOfChild(TGLBaseSceneObject(Pick.Hit[I])) > -1)
1594
or (_GZOrootTorus.IndexOfChild(TGLBaseSceneObject(Pick.Hit[I])) >
1595
-1) or (_GZOrootCubes.IndexOfChild(TGLBaseSceneObject(Pick.Hit[I]))
1602
for I := 0 to Pick.Count - 1 do
1604
if (Pick.Hit[I] is TGLGizmoPickCube) or
1605
(Pick.Hit[I] is TGLGizmoPickTorus) then
1611
Assert(False, GlsErrorEx + GlsUnknownType);
1618
for I := 0 to Pick.Count - 1 do
1620
if (Pick.Hit[I] <> _GZOBoundingcube) and (Pick.Hit[I] <> _GZOAxisLabelX)
1621
and (Pick.Hit[I] <> _GZOAxisLabelY) and (Pick.Hit[I] <> _GZOAxisLabelZ)
1622
and (Pick.Hit[I] <> _GZOVisibleInfoLabels) and
1623
not(CheckObjectInExcludeList(TGLBaseSceneObject(Pick.Hit[I]))) then
1626
PickedObj := TGLBaseSceneObject(Pick.Hit[I]);
1627
Dimensions := PickedObj.AxisAlignedDimensions;
1628
if Assigned(OnBeforeSelect) then
1629
OnBeforeSelect(Self, PickedObj, Accept, Dimensions);
1635
SetSelectedObj(PickedObj)
1637
SetSelectedObj(nil);
1640
UpdateVisibleInfoLabels();
1645
LastMousePos := MouseWorldPos(X, Y);
1648
procedure TGLGizmo.ViewerMouseUp(const X, Y: Integer);
1653
// ------------------------------------------------------------------------------
1655
procedure TGLGizmo.UpdateGizmo;
1659
if SelectedObj = nil then
1661
_GZObaseGizmo.Visible := False;
1665
_GZObaseGizmo.Position.AsVector := SelectedObj.AbsolutePosition;
1666
if GeObjectInfos in FGizmoElements then
1667
UpdateVisibleInfoLabels;
1669
_GZOBoundingcube.Matrix := SelectedObj.AbsoluteMatrix;
1670
_GZOBoundingcube.Position.SetPoint(0, 0, 0);
1672
// We must Update Color Of the BoundingBox And VisibleInfoLabels Here
1673
// If not Color is not Updated;
1675
// if FBoundingBoxColorChanged then
1677
with _GZOBoundingcube.Material do
1679
with FrontProperties do
1681
Diffuse.Color := FBoundingBoxColor.Color;
1682
Ambient.Color := FBoundingBoxColor.Color;
1683
Emission.Color := FBoundingBoxColor.Color;
1685
with BackProperties do
1687
Diffuse.Color := FBoundingBoxColor.Color;
1688
Ambient.Color := FBoundingBoxColor.Color;
1689
Emission.Color := FBoundingBoxColor.Color;
1692
// FBoundingBoxColorChanged:=False;
1694
// If FVisibleInfoLabelsColorChanged then
1696
_GZOVisibleInfoLabels.ModulateColor.Color := FVisibleInfoLabelsColor.Color;
1697
// FVisibleInfoLabelsColorChanged:=False;
1700
ObjDimensions := SelectedObj.AxisAlignedDimensions;
1701
_GZOBoundingcube.Scale.AsVector := VectorScale(ObjDimensions, 2);
1703
Assert(Viewer <> nil, 'Viewer not Assigned to gizmo');
1705
_GZOAxisLabelX.PointTo(Viewer.Camera.Position.AsVector,
1706
Viewer.Camera.Up.AsVector);
1707
_GZOAxisLabelX.StructureChanged;
1708
_GZOAxisLabelY.PointTo(Viewer.Camera.Position.AsVector,
1709
Viewer.Camera.Up.AsVector);
1710
_GZOAxisLabelY.StructureChanged;
1711
_GZOAxisLabelZ.PointTo(Viewer.Camera.Position.AsVector,
1712
Viewer.Camera.Up.AsVector);
1713
_GZOAxisLabelZ.StructureChanged;
1714
_GZOVisibleInfoLabels.PointTo(Viewer.Camera.Position.AsVector,
1715
Viewer.Camera.Up.AsVector);
1716
_GZOVisibleInfoLabels.StructureChanged;
1718
D := Viewer.Camera.DistanceTo(SelectedObj) / FAutoZoomFactor
1721
_GZOrootLines.Scale.AsVector := VectorMake(D, D, D);
1722
_GZOrootTorus.Scale.AsVector := VectorMake(D, D, D);
1723
_GZOrootCubes.Scale.AsVector := VectorMake(D, D, D);
1724
_GZOrootAxisLabel.Scale.AsVector := VectorMake(D, D, D);
1725
_GZOrootVisibleInfoLabels.Scale.AsVector := VectorMake(D, D, D);
1728
procedure TGLGizmo.UpdateGizmo(const NewDimensions: TVector);
1730
ObjDimensions := NewDimensions;
1734
procedure TGLGizmo.LooseSelection;
1738
if Assigned(OnSelectionLost) then
1739
OnSelectionLost(Self);
1742
procedure TGLGizmo.SetViewer(const Value: TGLSceneViewer);
1744
if FViewer <> Value then
1746
if FViewer <> nil then
1747
FViewer.RemoveFreeNotification(Self);
1749
if FViewer <> nil then
1750
FViewer.FreeNotification(Self);
1754
procedure TGLGizmo.Notification(AComponent: TComponent; Operation: TOperation);
1757
if Operation = OpRemove then
1759
if AComponent = FViewer then
1761
if AComponent = FRootGizmo then
1765
if FUndoHistory <> nil then
1766
FUndoHistory.Notification(AComponent, Operation);
1769
procedure TGLGizmoUndoItem.AssignFromObject(const AObject
1770
: TGLCustomSceneObject);
1772
SetEffectedObject(AObject);
1773
SetOldMatrix(AObject.Matrix);
1774
if AObject is TGLFreeForm then
1776
FOldAutoScaling.Assign(TGLFreeForm(AObject).AutoScaling);
1778
FOldLibMaterialName := AObject.Material.LibMaterialName;
1781
constructor TGLGizmoUndoItem.Create(AOwner: TCollection);
1784
FOldAutoScaling := TGLCoordinates.CreateInitialized(Self,
1785
NullHmgVector, CsPoint);
1788
destructor TGLGizmoUndoItem.Destroy;
1790
FOldAutoScaling.Free;
1794
procedure TGLGizmoUndoItem.DoUndo;
1796
FEffectedObject.Matrix := FOldMatr;
1797
if FEffectedObject is TGLFreeForm then
1798
TGLFreeForm(FEffectedObject).AutoScaling.Assign(FOldAutoScaling);
1799
FEffectedObject.Material.LibMaterialName := FOldLibMaterialName;
1802
function TGLGizmoUndoItem.GetGizmo: TGLGizmo;
1804
if GetParent <> nil then
1805
Result := GetPArent.GetParent
1810
function TGLGizmoUndoItem.GetParent: TGLGizmoUndoCollection;
1812
Result := TGLGizmoUndoCollection(GetOwner);
1815
procedure TGLGizmoUndoItem.Notification(AComponent: TComponent;
1816
Operation: TOperation);
1819
if Operation = OpRemove then
1821
if AComponent = FEffectedObject then
1822
FEffectedObject := nil;
1826
procedure TGLGizmoUndoItem.SetEffectedObject(const Value: TGLCustomSceneObject);
1828
if FEffectedObject <> nil then
1829
FEffectedObject.RemoveFreeNotification(GetGizmo);
1830
FEffectedObject := Value;
1831
if FEffectedObject <> nil then
1832
FEffectedObject.FreeNotification(GetGizmo);
1835
procedure TGLGizmoUndoItem.SetOldAutoScaling(const Value: TGLCoordinates);
1837
FOldAutoScaling.Assign(Value);
1840
procedure TGLGizmoUndoItem.SetOldMatrix(const Value: TMatrix);
1842
FOldMatrix := Value;
1845
{ TGLGizmoUndoCollection }
1847
function TGLGizmoUndoCollection.Add: TGLGizmoUndoItem;
1849
Result := TGLGizmoUndoItem(inherited Add);
1852
function TGLGizmoUndoCollection.GetItems(const Index: Integer)
1855
Result := TGLGizmoUndoItem(inherited GetItem(Index));
1858
function TGLGizmoUndoCollection.GetParent: TGLGizmo;
1860
Result := TGLGizmo(GetOwner);
1863
procedure TGLGizmoUndoCollection.Notification(AComponent: TComponent;
1864
Operation: TOperation);
1869
for I := 0 to Count - 1 do
1870
GetItems(I).Notification(AComponent, Operation);
1873
procedure TGLGizmoUndoCollection.RemoveByObject(const AObject
1874
: TGLCustomSceneObject);
1878
for I := Count - 1 downto 0 do
1879
if GetItems(I).FEffectedObject = AObject then
1883
procedure TGLGizmoUndoCollection.SetItems(const Index: Integer;
1884
const Value: TGLGizmoUndoItem);
1886
GetItems(Index).Assign(Value);
1889
procedure TGLGizmo.SetSelectedObj(const Value: TGLBaseSceneObject);
1891
if FSelectedObj <> Value then
1893
FSelectedObj := Value;
1895
if Value <> nil then
1898
UpdateVisibleInfoLabels();