GLS.Gizmo.pas 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869
  1. //
  2. // The multimedia graphics platform GLScene https://github.com/glscene
  3. //
  4. unit GLS.Gizmo;
  5. (*
  6. Invisible component for helping to Move, Rotate and Scale an Object
  7. under GLScene (usefull for an Editor).
  8. *)
  9. //
  10. // Original Header:
  11. //
  12. // ------------------------------------------------------------------------------
  13. // Unit : GLS.Gizmo RC 1.0
  14. // ------------------------------------------------------------------------------
  15. // Original Author : ??????? (GLS.Gizmo In an ODEEditor)
  16. // ------------------------------------------------------------------------------
  17. // Modified by : J.Delauney
  18. // Web Site : http://KheopsInteractive.cjb.net
  19. // EMail : [email protected]
  20. // Date : 08/05/2005
  21. //
  22. // Modified by : Marcus Oblak (8/3/2007)
  23. // - Corrected moving/rotating for children objects
  24. // - Better quantization for mouse operations (MoveCoef,RotationCoef)
  25. // - Added ScaleCoef
  26. // - Added GizmoThickness
  27. //
  28. // If you make some changes, please send your new version. Thanks
  29. // ------------------------------------------------------------------------------
  30. // Description :
  31. // Invisible component for helping to Move, Rotate and Scale an Object
  32. // under GLScene (usefull for an Editor)
  33. // ------------------------------------------------------------------------------
  34. // Features :
  35. // - Interaction When All Gizmo parts are Invisible
  36. // - Add "gpMoveGizmo and gpRotateGizmo" operations and use Like a "Pivot"
  37. // or use RootGizmo As "Pivot"
  38. // - Add Interactive Camera Movements
  39. // - Adding Extended Controls with Keys
  40. // - Maybe An Undo Function
  41. // - Others Ideas ???
  42. // ------------------------------------------------------------------------------
  43. // Bugs Known :
  44. // - When you change the BoundingBoxColor and LabelInfosColor
  45. // The New Color is not Updated immediately, only after a new Click
  46. // (see in UpdateGizmo, SetBoundingBoxColor
  47. // and SetLabelInfosColor Procedures)
  48. // - DaStr: Bounding Box is not always drawn correctly because it does not
  49. // use objects' BarryCenter. For Example, if you select Space Text.
  50. // ------------------------------------------------------------------------------
  51. interface
  52. {$I GLScene.inc}
  53. uses
  54. System.Classes,
  55. System.SysUtils,
  56. Vcl.StdCtrls,
  57. GLS.Scene,
  58. GLS.PersistentClasses,
  59. GLS.Color,
  60. GLS.Objects,
  61. GLS.VectorGeometry,
  62. GLS.Material,
  63. GLS.Strings,
  64. GLS.GeomObjects,
  65. GLS.BitmapFont,
  66. GLS.SceneViewer,
  67. GLS.VectorFileObjects,
  68. GLS.Coordinates,
  69. GLS.RenderContextInfo,
  70. GLS.State,
  71. GLS.Selection,
  72. GLS.VectorTypes;
  73. type
  74. TGLGizmoUndoCollection = class;
  75. TGLGizmo = class;
  76. TGLGizmoUndoItem = class(TCollectionItem)
  77. private
  78. FOldLibMaterialName: string;
  79. FOldAutoScaling: TGLCoordinates;
  80. FEffectedObject: TGLCustomSceneObject;
  81. FOldMatr: TGLMatrix;
  82. FOldMatrix: TGLMatrix;
  83. procedure SetEffectedObject(const Value: TGLCustomSceneObject);
  84. procedure SetOldAutoScaling(const Value: TGLCoordinates);
  85. procedure SetOldMatrix(const Value: TGLMatrix);
  86. protected
  87. procedure DoUndo; virtual;
  88. function GetParent: TGLGizmoUndoCollection;
  89. function GetGizmo: TGLGizmo;
  90. public
  91. constructor Create(AOwner: TCollection); override;
  92. destructor Destroy; override;
  93. procedure Notification(AComponent: TComponent;
  94. Operation: TOperation); virtual;
  95. procedure AssignFromObject(const AObject: TGLCustomSceneObject);
  96. // TODO: create a special type for Matrix.
  97. property OldMatrix: TGLMatrix read FOldMatrix write SetOldMatrix;
  98. published
  99. property EffectedObject: TGLCustomSceneObject read FEffectedObject
  100. write SetEffectedObject;
  101. property OldAutoScaling: TGLCoordinates read FOldAutoScaling
  102. write SetOldAutoScaling;
  103. property OldLibMaterialName: string read FOldLibMaterialName
  104. write FOldLibMaterialName;
  105. end;
  106. TGLGizmoUndoCollection = class(TOwnedCollection)
  107. private
  108. function GetItems(const Index: Integer): TGLGizmoUndoItem;
  109. procedure SetItems(const Index: Integer; const Value: TGLGizmoUndoItem);
  110. protected
  111. function GetParent: TGLGizmo;
  112. public
  113. procedure Notification(AComponent: TComponent; Operation: TOperation);
  114. procedure RemoveByObject(const AObject: TGLCustomSceneObject);
  115. function Add: TGLGizmoUndoItem;
  116. property Items[const Index: Integer]: TGLGizmoUndoItem read GetItems
  117. write SetItems; default;
  118. end;
  119. TGLGizmoElement = (geMove, geRotate, geScale, geAxisLabel, geObjectInfos,
  120. geBoundingBox);
  121. TGLGizmoElements = set of TGLGizmoElement;
  122. TGLGizmoVisibleInfoLabel = (vliName, vliOperation, vliCoords);
  123. TGLGizmoVisibleInfoLabels = set of TGLGizmoVisibleInfoLabel;
  124. TGLGizmoAxis = (gaNone, gaX, gaY, gaZ, gaXY, gaXZ, gaYZ);
  125. TGLGizmoOperation = (gopMove, gopRotate, gopScale, gopNone, gpMoveGizmo,
  126. gpRotateGizmo);
  127. TGLGizmoAcceptEvent = procedure(Sender: TObject; var Obj: TGLBaseSceneObject;
  128. var Accept: Boolean; var Dimensions: TGLVector) of object;
  129. TGLGizmoUpdateEvent = procedure(Sender: TObject; Obj: TGLBaseSceneObject;
  130. Axis: TGLGizmoAxis; Operation: TGLGizmoOperation; var Vector: TGLVector)
  131. of object;
  132. TGLGizmoPickMode = (pmGetPickedObjects, pmRayCast);
  133. TGLGizmoRayCastHitData = class(TPersistent)
  134. public
  135. Obj: TGLBaseSceneObject;
  136. Point: TGLVector;
  137. end;
  138. TGLGizmoPickCube = class(TGLCube)
  139. end;
  140. TGLGizmoPickTorus = class(TGLTorus)
  141. end;
  142. TGLGizmo = class(TComponent)
  143. private
  144. _GZObaseGizmo: TGLBaseSceneObject;
  145. _GZOBoundingcube: TGLCube;
  146. _GZOrootHelpers: TGLBaseSceneObject;
  147. _GZOrootLines: TGLBaseSceneObject;
  148. _GZOrootTorus: TGLBaseSceneObject;
  149. _GZOrootCubes: TGLBaseSceneObject;
  150. _GZORootAxisLabel: TGLBaseSceneObject;
  151. _GZORootVisibleInfoLabels: TGLBaseSceneObject;
  152. _GZOlineX, _GZOlineY, _GZOlineZ, _GZOplaneXY, _GZOplaneXZ,
  153. _GZOplaneYZ: TGLLines; // For Move
  154. _GZOTorusX, _GZOTorusY, _GZOTorusZ: TGLGizmoPickTorus; // For Rotate
  155. _GZOCubeX, _GZOCubeY, _GZOCubeZ: TGLGizmoPickCube; // For Scale
  156. _GZOAxisLabelX, _GZOAxisLabelY, _GZOAxisLabelZ: TGLFlatText;
  157. _GZOVisibleInfoLabels: TGLFlatText;
  158. FRootGizmo: TGLBaseSceneObject;
  159. FSelectedObj: TGLBaseSceneObject;
  160. // FLastOperation,
  161. FOperation: TGLGizmoOperation;
  162. FSelAxis: TGLGizmoAxis;
  163. FBoundingBoxColor: TGLColor;
  164. FSelectedColor: TGLColor;
  165. FVisibleInfoLabelsColor: TGLColor;
  166. FBoundingBoxColorChanged: Boolean;
  167. FVisibleInfoLabelsColorChanged: Boolean;
  168. FForceOperation: Boolean;
  169. FForceAxis: Boolean;
  170. FForceUniformScale: Boolean;
  171. FAutoZoom: Boolean;
  172. FExcludeObjects: Boolean;
  173. FNoZWrite: Boolean;
  174. FEnabled: Boolean;
  175. FAutoZoomFactor: Single;
  176. FZoomFactor: Single;
  177. FMoveCoef: Single;
  178. FRotationCoef: Single;
  179. FViewer: TGLSceneViewer;
  180. FGizmoElements: TGLGizmoElements;
  181. FVisibleVisibleInfoLabels: TGLGizmoVisibleInfoLabels;
  182. FExcludeObjectsList: TStrings;
  183. Moving: Boolean;
  184. Mx, My: Integer;
  185. Rx, Ry: Integer;
  186. dglEnable, dglDisable, dgtEnable, dgtDisable, dgcEnable, dgcDisable,
  187. dglaEnable, dglaDisable, dgliEnable, dgliDisable: TGLDirectOpenGL;
  188. LastMousePos: TGLVector;
  189. ObjDimensions: TGLVector;
  190. FOnBeforeSelect: TGLGizmoAcceptEvent;
  191. FOnBeforeUpdate: TGLGizmoUpdateEvent;
  192. FOnSelectionLost: TNotifyEvent;
  193. FScaleCoef: Single;
  194. FGizmoThickness: Single;
  195. FPickMode: TGLGizmoPickMode;
  196. FInternalRaycastHitData: TList;
  197. FUndoHistory: TGLGizmoUndoCollection;
  198. FLabelFont: TGLCustomBitmapFont;
  199. procedure SetRootGizmo(const AValue: TGLBaseSceneObject);
  200. procedure SetGizmoElements(const AValue: TGLGizmoElements);
  201. procedure SeTGLGizmoVisibleInfoLabels(const AValue
  202. : TGLGizmoVisibleInfoLabels);
  203. procedure SetBoundingBoxColor(const AValue: TGLColor);
  204. procedure SetSelectedColor(const AValue: TGLColor);
  205. procedure SetVisibleInfoLabelsColor(const AValue: TGLColor);
  206. procedure SetExcludeObjectsList(const AValue: TStrings);
  207. procedure DirectGlDisable(Sender: TObject; var Rci: TGLRenderContextInfo);
  208. procedure DirectGlEnable(Sender: TObject; var Rci: TGLRenderContextInfo);
  209. function MouseWorldPos(const X, Y: Integer): TGLVector;
  210. function CheckObjectInExcludeList(const Obj: TGLBaseSceneObject): Boolean;
  211. procedure UpdateVisibleInfoLabels;
  212. procedure SetGLGizmoThickness(const Value: Single);
  213. function InternalGetPickedObjects(const X1, Y1, X2, Y2: Integer;
  214. const GuessCount: Integer = 8): TGLPickList;
  215. procedure ClearInternalRaycastHitData;
  216. procedure SetViewer(const Value: TGLSceneViewer);
  217. procedure SetLabelFont(const Value: TGLCustomBitmapFont);
  218. procedure SetSelectedObj(const Value: TGLBaseSceneObject);
  219. public
  220. PickableObjectsWithRayCast: TList;
  221. constructor Create(AOwner: TComponent); override;
  222. destructor Destroy; override;
  223. procedure Loaded; override;
  224. procedure Notification(AComponent: TComponent;
  225. Operation: TOperation); override;
  226. procedure ViewerMouseMove(const X, Y: Integer);
  227. procedure ViewerMouseDown(const X, Y: Integer);
  228. procedure ViewerMouseUp(const X, Y: Integer);
  229. procedure UpdateGizmo; overload;
  230. procedure UpdateGizmo(const NewDimensions: TGLVector); overload;
  231. procedure SetVisible(const AValue: Boolean);
  232. function GetPickedObjectPoint(const Obj: TGLBaseSceneObject): TGLVector;
  233. procedure LooseSelection; virtual;
  234. procedure UndoAdd(const AObject: TGLCustomSceneObject);
  235. property RootGizmo: TGLBaseSceneObject read FRootGizmo write SetRootGizmo;
  236. // --------------------------------------------------------------------
  237. published
  238. property Viewer: TGLSceneViewer read FViewer write SetViewer;
  239. property GizmoElements: TGLGizmoElements read FGizmoElements
  240. write SetGizmoElements;
  241. property BoundingBoxColor: TGLColor read FBoundingBoxColor
  242. write SetBoundingBoxColor;
  243. property SelectedColor: TGLColor read FSelectedColor write SetSelectedColor;
  244. property SelAxis: TGLGizmoAxis read FSelAxis write FSelAxis;
  245. property ForceAxis: Boolean read FForceAxis write FForceAxis;
  246. property SelectedObj: TGLBaseSceneObject read FSelectedObj
  247. write SetSelectedObj;
  248. property Operation: TGLGizmoOperation read FOperation write FOperation;
  249. property ForceOperation: Boolean read FForceOperation write FForceoperation;
  250. property ForceUniformScale: Boolean read FForceUniformScale
  251. write FForceUniformScale;
  252. property ExcludeObjects: Boolean read FExcludeObjects write FExcludeObjects;
  253. property ExcludeObjectsList: TStrings read FExcludeObjectsList
  254. write SetExcludeObjectsList;
  255. property VisibleInfoLabels: TGLGizmoVisibleInfoLabels
  256. read FVisibleVisibleInfoLabels write SeTGLGizmoVisibleInfoLabels;
  257. property VisibleInfoLabelsColor: TGLColor read FVisibleInfoLabelsColor
  258. write SetVisibleInfoLabelsColor;
  259. property AutoZoom: Boolean read FAutoZoom write FAutoZoom;
  260. property AutoZoomFactor: Single read FAutoZoomFactor write FAutoZoomFactor;
  261. property ZoomFactor: Single read FZoomFactor write FZoomFactor;
  262. property MoveCoef: Single read FMoveCoef write FMoveCoef;
  263. property RotationCoef: Single read FRotationCoef write FRotationCoef;
  264. property ScaleCoef: Single read FScaleCoef write FScaleCoef;
  265. property NoZWrite: Boolean read FNoZWrite write FNoZWrite;
  266. property GizmoThickness: Single read FGizmoThickness
  267. write SeTGLGizmoThickness;
  268. { Indicates whether the gizmo is enabled or not.
  269. WARNING: When loading/editing (possibly whenever a structureChanged
  270. call is made) a model, sometimes the gizmo will trigger a
  271. bug if the mouse is inside the glscene Viewer. To prevent that,
  272. remember to disable the gizmo before loading, then process windows
  273. messages (i.e. application.processMessage) and then enable the gizmo
  274. again. }
  275. { Warning Enable is ReadOnly property if you set to False, Gizmo is not Hidden
  276. use Visible instead if you want to Hide, if you want to Hide but keep enabled
  277. see the VisibleGizmo property }
  278. property Enabled: Boolean read FEnabled write FEnabled default False;
  279. property LabelFont: TGLCustomBitmapFont read FLabelFont write SetLabelFont
  280. default nil;
  281. property OnBeforeSelect: TGLGizmoAcceptEvent read FOnBeforeSelect
  282. write FOnBeforeSelect;
  283. property OnSelectionLost: TNotifyEvent read FOnSelectionLost
  284. write FOnSelectionLost;
  285. { Called before an Update is applied. The "vector" parameter is the difference
  286. that will be applied to the object, according to the axis and
  287. operation selected. }
  288. property OnBeforeUpdate: TGLGizmoUpdateEvent read FOnBeforeUpdate
  289. write FOnBeforeUpdate;
  290. property PickMode: TGLGizmoPickMode read FPickMode write FPickMode
  291. default PmGetPickedObjects;
  292. end;
  293. //=========================================================
  294. implementation
  295. //=========================================================
  296. procedure RotateAroundArbitraryAxis(const AnObject: TGLBaseSceneObject;
  297. const Axis, Origin: TAffineVector; const Angle: Single);
  298. var
  299. M, M1, M2, M3: TGLMatrix;
  300. begin
  301. M1 := CreateTranslationMatrix(VectorNegate(Origin));
  302. M2 := CreateRotationMatrix(Axis, Angle * PI / 180);
  303. M3 := CreateTranslationMatrix(Origin);
  304. M := MatrixMultiply(M1, M2);
  305. M := MatrixMultiply(M, M3);
  306. AnObject.SetMatrix(MatrixMultiply(AnObject.Matrix^, M));
  307. // Just a workarround to Update angles...
  308. AnObject.Roll(0);
  309. AnObject.Pitch(0);
  310. AnObject.Turn(0);
  311. end;
  312. // ------------------------------------------------------------------------------
  313. procedure TGLGizmo.ClearInternalRaycastHitData;
  314. var
  315. T: Integer;
  316. begin
  317. for T := FInternalRaycastHitData.Count - 1 downto 0 do
  318. begin
  319. TGLGizmoRayCastHitData(FInternalRaycastHitData[T]).Free;
  320. end;
  321. FInternalRaycastHitData.Clear;
  322. end;
  323. constructor TGLGizmo.Create(AOwner: TComponent);
  324. var
  325. Cub: TGLCube;
  326. begin
  327. inherited Create(AOwner);
  328. FUndoHistory := TGLGizmoUndoCollection.Create(Self, TGLGizmoUndoItem);
  329. FPickMode := PmGetPickedObjects;
  330. PickableObjectsWithRayCast := TList.Create;
  331. FRotationCoef := 1;
  332. FMoveCoef := 0.1;
  333. FScaleCoef := 0.1;
  334. FGizmoThickness := 1;
  335. FInternalRaycastHitData := TList.Create;
  336. FBoundingBoxColor := TGLColor.Create(Self);
  337. FBoundingBoxColor.Color := ClrWhite;
  338. FBoundingBoxColorChanged := False;
  339. FSelectedColor := TGLColor.Create(Self);
  340. FSelectedColor.Color := ClrYellow;
  341. FVisibleInfoLabelsColor := TGLColor.Create(Self);
  342. FVisibleInfoLabelsColor.Color := ClrYellow;
  343. FVisibleInfoLabelsColorChanged := False;
  344. _GZObaseGizmo := TGLDummyCube.Create(Self);
  345. _GZORootHelpers := TGLDummyCube(_GZObaseGizmo.AddNewChild(TGLDummyCube));
  346. _GZOBoundingcube := TGLCube(_GZORootHelpers.AddNewChild(TGLCube));
  347. _GZORootLines := _GZORootHelpers.AddNewChild(TGLDummyCube);
  348. _GZORootTorus := _GZORootHelpers.AddNewChild(TGLDummyCube);
  349. _GZORootCubes := _GZORootHelpers.AddNewChild(TGLDummyCube);
  350. _GZORootAxisLabel := _GZORootHelpers.AddNewChild(TGLDummyCube);
  351. _GZORootVisibleInfoLabels := _GZORootHelpers.AddNewChild(TGLDummyCube);
  352. DglDisable := TGLDirectOpenGL(_GZORootLines.AddNewChild(TGLDirectOpenGL));
  353. DglDisable.OnRender := DirectGlDisable;
  354. DgtDisable := TGLDirectOpenGL(_GZORootTorus.AddNewChild(TGLDirectOpenGL));
  355. DgtDisable.OnRender := DirectGlDisable;
  356. DgcDisable := TGLDirectOpenGL(_GZORootCubes.AddNewChild(TGLDirectOpenGL));
  357. DgcDisable.OnRender := DirectGlDisable;
  358. DglaDisable := TGLDirectOpenGL
  359. (_GZORootAxisLabel.AddNewChild(TGLDirectOpenGL));
  360. DglaDisable.OnRender := DirectGlDisable;
  361. DgliDisable := TGLDirectOpenGL(_GZORootVisibleInfoLabels.AddNewChild
  362. (TGLDirectOpenGL));
  363. DgliDisable.OnRender := DirectGlDisable;
  364. with _GZOBoundingcube.Material do
  365. begin
  366. FaceCulling := FcNoCull;
  367. PolygonMode := PmLines;
  368. with FrontProperties do
  369. begin
  370. Diffuse.Color := FBoundingBoxColor.Color;
  371. Ambient.Color := FBoundingBoxColor.Color;
  372. Emission.Color := FBoundingBoxColor.Color;
  373. end;
  374. with BackProperties do
  375. begin
  376. Diffuse.Color := FBoundingBoxColor.Color;
  377. Ambient.Color := FBoundingBoxColor.Color;
  378. Emission.Color := FBoundingBoxColor.Color;
  379. end;
  380. end;
  381. _GZOlinex := TGLLines(_GZORootLines.AddnewChild(TGLLines));
  382. with _GZOlinex do
  383. begin
  384. LineColor.Color := clrRed;
  385. LineWidth := 3;
  386. NodesAspect := LnaInvisible;
  387. AddNode(0, 0, 0);
  388. AddNode(1, 0, 0);
  389. AddNode(0.9, 0, -0.1);
  390. AddNode(1, 0, 0);
  391. AddNode(0.9, 0, 0.1);
  392. // Raycast pickable object
  393. Cub := TGLGizmoPickCube(AddNewChild(TGLGizmoPickCube));
  394. Cub.Up.SetVector(1, 0, 0);
  395. Cub.CubeWidth := 0.1;
  396. Cub.CubeHeight := 1;
  397. Cub.CubeDepth := 0.1;
  398. Cub.Position.SetPoint(0.5, 0, 0);
  399. Cub.Visible := False;
  400. end;
  401. _GZOliney := TGLLines(_GZORootLines.AddnewChild(TGLLines));
  402. with _GZOliney do
  403. begin
  404. LineColor.Color := clrLime;
  405. LineWidth := 3;
  406. NodesAspect := LnaInvisible;
  407. AddNode(0, 0, 0);
  408. AddNode(0, 1, 0);
  409. AddNode(0.1, 0.9, 0);
  410. AddNode(0, 1, 0);
  411. AddNode(-0.1, 0.9, 0);
  412. // Raycast pickable object
  413. Cub := TGLGizmoPickCube(AddNewChild(TGLGizmoPickCube));
  414. Cub.Up.SetVector(0, 1, 0);
  415. Cub.CubeWidth := 0.1;
  416. Cub.CubeHeight := 1;
  417. Cub.CubeDepth := 0.1;
  418. Cub.Position.SetPoint(0, 0.5, 0);
  419. Cub.Visible := False;
  420. end;
  421. _GZOlinez := TGLLines(_GZORootLines.AddnewChild(TGLLines));
  422. with _GZOlinez do
  423. begin
  424. LineColor.Color := clrBlue;
  425. LineWidth := 3;
  426. NodesAspect := LnaInvisible;
  427. AddNode(0, 0, 0);
  428. AddNode(0, 0, 1);
  429. AddNode(0.1, 0, 0.9);
  430. AddNode(0, 0, 1);
  431. AddNode(-0.1, 0, 0.9);
  432. // Raycast pickable object
  433. Cub := TGLGizmoPickCube(AddNewChild(TGLGizmoPickCube));
  434. Cub.Up.SetVector(0, 0, 1);
  435. Cub.CubeWidth := 0.1;
  436. Cub.CubeHeight := 1;
  437. Cub.CubeDepth := 0.1;
  438. Cub.Position.SetPoint(0, 0, 0.5);
  439. Cub.Visible := False;
  440. end;
  441. _GZOplaneXY := TGLLines(_GZORootLines.AddnewChild(TGLLines));
  442. with _GZOplaneXY do
  443. begin
  444. LineWidth := 3;
  445. Options := [LoUseNodeColorForLines];
  446. NodesAspect := LnaInvisible;
  447. SplineMode := LsmSegments;
  448. AddNode(0.8, 1, 0);
  449. TGLLinesNode(Nodes[0]).Color.Color := clrRed;
  450. AddNode(1, 1, 0);
  451. TGLLinesNode(Nodes[1]).Color.Color := clrRed;
  452. AddNode(1, 1, 0);
  453. TGLLinesNode(Nodes[2]).Color.Color := clrLime;
  454. AddNode(1, 0.8, 0);
  455. TGLLinesNode(Nodes[3]).Color.Color := clrLime;
  456. // Raycast pickable object
  457. Cub := TGLGizmoPickCube(AddNewChild(TGLGizmoPickCube));
  458. Cub.Up.SetVector(1, 0, 0);
  459. Cub.CubeWidth := 0.2;
  460. Cub.CubeHeight := 0.2;
  461. Cub.CubeDepth := 0.1;
  462. Cub.Position.SetPoint(0.9, 0.9, 0);
  463. Cub.Visible := False;
  464. end;
  465. _GZOplaneXZ := TGLLines(_GZORootLines.AddnewChild(TGLLines));
  466. with _GZOplaneXZ do
  467. begin
  468. LineWidth := 3;
  469. Options := [LoUseNodeColorForLines];
  470. NodesAspect := LnaInvisible;
  471. SplineMode := LsmSegments;
  472. AddNode(1, 0, 0.8);
  473. TGLLinesNode(Nodes[0]).Color.Color := clrBlue;
  474. AddNode(1, 0, 1);
  475. TGLLinesNode(Nodes[1]).Color.Color := clrBlue;
  476. AddNode(1, 0, 1);
  477. TGLLinesNode(Nodes[2]).Color.Color := clrRed;
  478. AddNode(0.8, 0, 1);
  479. TGLLinesNode(Nodes[3]).Color.Color := clrRed;
  480. // Raycast pickable object
  481. Cub := TGLGizmoPickCube(AddNewChild(TGLGizmoPickCube));
  482. Cub.Up.SetVector(1, 0, 0);
  483. Cub.CubeWidth := 0.1;
  484. Cub.CubeHeight := 0.2;
  485. Cub.CubeDepth := 0.2;
  486. Cub.Position.SetPoint(0.9, 0, 0.9);
  487. Cub.Visible := False;
  488. end;
  489. _GZOplaneYZ := TGLLines(_GZORootLines.AddnewChild(TGLLines));
  490. with _GZOplaneYZ do
  491. begin
  492. LineWidth := 3;
  493. Options := [LoUseNodeColorForLines];
  494. NodesAspect := LnaInvisible;
  495. SplineMode := LsmSegments;
  496. AddNode(0, 0.8, 1);
  497. TGLLinesNode(Nodes[0]).Color.Color := clrLime;
  498. AddNode(0, 1, 1);
  499. TGLLinesNode(Nodes[1]).Color.Color := clrLime;
  500. AddNode(0, 1, 1);
  501. TGLLinesNode(Nodes[2]).Color.Color := clrBlue;
  502. AddNode(0, 1, 0.8);
  503. TGLLinesNode(Nodes[3]).Color.Color := clrBlue;
  504. // Raycast pickable object
  505. Cub := TGLGizmoPickCube(AddNewChild(TGLGizmoPickCube));
  506. Cub.Up.SetVector(0, 0, 1);
  507. Cub.CubeWidth := 0.2;
  508. Cub.CubeHeight := 0.2;
  509. Cub.CubeDepth := 0.1;
  510. Cub.Position.SetPoint(0, 0.9, 0.9);
  511. Cub.Visible := False;
  512. end;
  513. _GZOTorusX := TGLGizmoPickTorus(_GZORootTorus.AddnewChild(TGLGizmoPickTorus));
  514. with _GZOTorusX do
  515. begin
  516. Rings := 16;
  517. Sides := 4;
  518. MajorRadius := 0.6;
  519. MinorRadius := 0.03;
  520. PitchAngle := 90;
  521. TurnAngle := 90;
  522. with Material do
  523. begin
  524. // FaceCulling:= fcNoCull;
  525. PolygonMode := PmFill;
  526. // BackProperties.PolygonMode:= pmFill;
  527. FrontProperties.Emission.Color := clrBlue;
  528. end;
  529. end;
  530. _GZOTorusY := TGLGizmoPickTorus(_GZORootTorus.AddnewChild(TGLGizmoPickTorus));
  531. with _GZOTorusY do
  532. begin
  533. Rings := 16;
  534. Sides := 4;
  535. MajorRadius := 0.6;
  536. MinorRadius := 0.03;
  537. PitchAngle := 90;
  538. with Material do
  539. begin
  540. // FaceCulling:= fcNoCull;
  541. PolygonMode := PmFill;
  542. // BackProperties.PolygonMode:= pmFill;
  543. FrontProperties.Emission.Color := clrRed;
  544. end;
  545. end;
  546. _GZOTorusZ := TGLGizmoPickTorus(_GZORootTorus.AddnewChild(TGLGizmoPickTorus));
  547. with _GZOTorusZ do
  548. begin
  549. Rings := 16;
  550. Sides := 4;
  551. MajorRadius := 0.6;
  552. MinorRadius := 0.03;
  553. with Material do
  554. begin
  555. // FaceCulling:= fcNoCull;
  556. PolygonMode := PmFill;
  557. // BackProperties.PolygonMode:= pmFill;
  558. FrontProperties.Emission.Color := clrLime;
  559. end;
  560. end;
  561. _GZOCubeX := TGLGizmoPickCube(_GZORootCubes.AddnewChild(TGLGizmoPickCube));
  562. with _GZOCubeX do
  563. begin
  564. CubeDepth := 0.1;
  565. CubeHeight := 0.1;
  566. CubeWidth := 0.1;
  567. Position.X := 1.15;
  568. with Material do
  569. begin
  570. FaceCulling := FcNoCull;
  571. PolygonMode := PmFill;
  572. FrontProperties.Emission.Color := clrRed;
  573. end;
  574. end;
  575. _GZOCubeY := TGLGizmoPickCube(_GZORootCubes.AddnewChild(TGLGizmoPickCube));
  576. with _GZOCubeY do
  577. begin
  578. CubeDepth := 0.1;
  579. CubeHeight := 0.1;
  580. CubeWidth := 0.1;
  581. Position.Y := 1.15;
  582. with Material do
  583. begin
  584. FaceCulling := FcNoCull;
  585. PolygonMode := PmFill;
  586. FrontProperties.Emission.Color := clrLime;
  587. end;
  588. end;
  589. _GZOCubeZ := TGLGizmoPickCube(_GZORootCubes.AddnewChild(TGLGizmoPickCube));
  590. with _GZOCubeZ do
  591. begin
  592. CubeDepth := 0.1;
  593. CubeHeight := 0.1;
  594. CubeWidth := 0.1;
  595. Position.Z := 1.15;
  596. with Material do
  597. begin
  598. FaceCulling := FcNoCull;
  599. PolygonMode := PmFill;
  600. FrontProperties.Emission.Color := clrBlue;
  601. end;
  602. end;
  603. _GZOAxisLabelX := TGLFlatText(_GZORootAxisLabel.AddNewChild(TGLFlatText));
  604. with _GZOAxisLabelX do
  605. begin
  606. ModulateColor.Color := ClrRed;
  607. Alignment := TaCenter;
  608. Layout := TTextLayout.tlCenter;
  609. Options := Options + [FtoTwoSided];
  610. Position.X := 1.5;
  611. Scale.X := 0.02;
  612. Scale.Y := 0.02;
  613. Text := 'X';
  614. end;
  615. _GZOAxisLabelY := TGLFlatText(_GZORootAxisLabel.AddNewChild(TGLFlatText));
  616. with _GZOAxisLabelY do
  617. begin
  618. ModulateColor.Color := clrLime;
  619. Alignment := TaCenter;
  620. Layout := TlCenter;
  621. Options := Options + [FtoTwoSided];
  622. Position.Y := 1.5;
  623. Scale.X := 0.02;
  624. Scale.Y := 0.02;
  625. Text := 'Y';
  626. end;
  627. _GZOAxisLabelZ := TGLFlatText(_GZORootAxisLabel.AddNewChild(TGLFlatText));
  628. with _GZOAxisLabelZ do
  629. begin
  630. ModulateColor.Color := ClrBlue;
  631. Alignment := TaCenter;
  632. Layout := TlCenter;
  633. Options := Options + [FtoTwoSided];
  634. Position.Z := 1.5;
  635. Scale.X := 0.02;
  636. Scale.Y := 0.02;
  637. Text := 'Z';
  638. end;
  639. _GZOVisibleInfoLabels :=
  640. TGLFlatText(_GZORootVisibleInfoLabels.AddNewChild(TGLFlatText));
  641. with _GZOVisibleInfoLabels do
  642. begin
  643. ModulateColor.Color := clrYellow;
  644. Alignment := TaCenter;
  645. Layout := TlCenter;
  646. Options := Options + [FtoTwoSided];
  647. Position.Y := 1.8;
  648. Position.X := 0;
  649. Scale.X := 0.01;
  650. Scale.Y := 0.01;
  651. Text := '';
  652. end;
  653. DglEnable := TGLDirectOpenGL(_GZORootLines.AddNewChild(TGLDirectOpenGL));
  654. DglEnable.OnRender := DirectGlEnable;
  655. DgtEnable := TGLDirectOpenGL(_GZORootTorus.AddNewChild(TGLDirectOpenGL));
  656. DgtEnable.OnRender := DirectGlEnable;
  657. DgcEnable := TGLDirectOpenGL(_GZORootCubes.AddNewChild(TGLDirectOpenGL));
  658. DgcEnable.OnRender := DirectGlEnable;
  659. DglaEnable := TGLDirectOpenGL(_GZORootAxisLabel.AddNewChild(TGLDirectOpenGL));
  660. DglaEnable.OnRender := DirectGlEnable;
  661. DgliEnable := TGLDirectOpenGL(_GZORootVisibleInfoLabels.AddNewChild
  662. (TGLDirectOpenGL));
  663. DgliEnable.OnRender := DirectGlEnable;
  664. _GZObaseGizmo.Visible := False;
  665. FGizmoElements := FGizmoElements + [GeMove, GeRotate, GeScale, GeAxisLabel,
  666. GeObjectInfos, GeBoundingBox];
  667. FVisibleVisibleInfoLabels := FVisibleVisibleInfoLabels +
  668. [VliName, VliOperation, VliCoords];
  669. AutoZoom := True;
  670. AutoZoomFactor := 5.0;
  671. ZoomFactor := 0.35;
  672. ForceOperation := False;
  673. ForceAxis := False;
  674. ForceUniformScale := False;
  675. Enabled := True;
  676. FNoZWrite := True;
  677. FExcludeObjectsList := TStringList.Create;
  678. end;
  679. destructor TGLGizmo.Destroy;
  680. begin
  681. if Assigned(FRootGizmo) then
  682. FRootGizmo.DeleteChildren
  683. else
  684. begin
  685. _GZOBaseGizmo.DeleteChildren;
  686. _GZOBaseGizmo.Free;
  687. end;
  688. FBoundingBoxColor.Free;
  689. FSelectedColor.Free;
  690. FVisibleInfoLabelsColor.Free;
  691. PickableObjectsWithRayCast.Free;
  692. FExcludeObjectsList.Free;
  693. ClearInternalRaycastHitData;
  694. FInternalRaycastHitData.Free;
  695. // FUndoHistory has to be nil before Notification() is called.
  696. FreeAndNil(FUndoHistory);
  697. inherited Destroy;
  698. end;
  699. procedure TGLGizmo.SetVisible(const AValue: Boolean);
  700. begin
  701. _GZObaseGizmo.Visible := AValue;
  702. end;
  703. procedure TGLGizmo.SetGizmoElements(const AValue: TGLGizmoElements);
  704. begin
  705. if AValue <> FGizmoElements then
  706. begin
  707. FGizmoElements := AValue;
  708. _GZORootLines.Visible := GeMove in FGizmoElements;
  709. _GZORootTorus.Visible := GeRotate in FGizmoElements;
  710. _GZORootCubes.Visible := GeScale in FGizmoElements;
  711. _GZORootAxisLabel.Visible := GeAxisLabel in FGizmoElements;
  712. _GZORootVisibleInfoLabels.Visible := GeObjectInfos in FGizmoElements;
  713. _GZOBoundingcube.Visible := GeBoundingBox in FGizmoElements;
  714. end;
  715. end;
  716. procedure TGLGizmo.SetBoundingBoxColor(const AValue: TGLColor);
  717. begin
  718. // Bug Here New Color is not Updated
  719. if AValue <> FBoundingBoxColor then
  720. begin
  721. FBoundingBoxColor.Color := AValue.Color;
  722. with _GZOBoundingcube.Material do
  723. begin
  724. with FrontProperties do
  725. begin
  726. Diffuse.Color := FBoundingBoxColor.Color;
  727. Ambient.Color := FBoundingBoxColor.Color;
  728. Emission.Color := FBoundingBoxColor.Color;
  729. end;
  730. with BackProperties do
  731. begin
  732. Diffuse.Color := FBoundingBoxColor.Color;
  733. Ambient.Color := FBoundingBoxColor.Color;
  734. Emission.Color := FBoundingBoxColor.Color;
  735. end;
  736. end;
  737. FBoundingBoxColorChanged := True;
  738. end;
  739. end;
  740. procedure TGLGizmo.SetSelectedColor(const AValue: TGLColor);
  741. begin
  742. if AValue <> FSelectedColor then
  743. begin
  744. FSelectedColor.Color := AValue.Color;
  745. end;
  746. end;
  747. procedure TGLGizmo.SetVisibleInfoLabelsColor(const AValue: TGLColor);
  748. begin
  749. // Bug Here New Color is not Updated
  750. if AValue <> FSelectedColor then
  751. begin
  752. FVisibleInfoLabelsColor.Color := AValue.Color;
  753. _GZOVisibleInfoLabels.ModulateColor.Color := AValue.Color;
  754. FVisibleInfoLabelsColorChanged := True;
  755. end;
  756. end;
  757. procedure TGLGizmo.SeTGLGizmoVisibleInfoLabels(const AValue
  758. : TGLGizmoVisibleInfoLabels);
  759. begin
  760. if AValue <> FVisibleVisibleInfoLabels then
  761. begin
  762. FVisibleVisibleInfoLabels := AValue;
  763. if not(CsDesigning in ComponentState) then
  764. UpdateGizmo;
  765. end;
  766. end;
  767. procedure TGLGizmo.UndoAdd(const AObject: TGLCustomSceneObject);
  768. begin
  769. if AObject <> nil then
  770. begin
  771. FUndoHistory.Add.AssignFromObject(AObject)
  772. end;
  773. end;
  774. procedure TGLGizmo.SetRootGizmo(const AValue: TGLBaseSceneObject);
  775. begin
  776. if FRootGizmo <> AValue then
  777. begin
  778. if FRootGizmo <> nil then
  779. FRootGizmo.RemoveFreeNotification(Self);
  780. FRootGizmo := AValue;
  781. if FRootGizmo <> nil then
  782. FRootGizmo.FreeNotification(Self);
  783. _GZObaseGizmo.MoveTo(AValue);
  784. end;
  785. end;
  786. procedure TGLGizmo.SetExcludeObjectsList(const AValue: TStrings);
  787. begin
  788. FExcludeObjectsList.Clear;
  789. FExcludeObjectsList.AddStrings(AValue);
  790. end;
  791. procedure TGLGizmo.SetGLGizmoThickness(const Value: Single);
  792. var
  793. Thk: Single;
  794. begin
  795. if FGizmoThickness <> Value then
  796. begin
  797. Thk := MaxInteger(1, Round(3 * Value));
  798. _GZOlinex.LineWidth := Thk;
  799. _GZOliney.LineWidth := Thk;
  800. _GZOlinez.LineWidth := Thk;
  801. _GZOplaneXY.LineWidth := Thk;
  802. _GZOplaneXZ.LineWidth := Thk;
  803. _GZOplaneYZ.LineWidth := Thk;
  804. _GZOTorusX.MinorRadius := 0.03 * Value;
  805. _GZOTorusY.MinorRadius := 0.03 * Value;
  806. _GZOTorusZ.MinorRadius := 0.03 * Value;
  807. with _GZOCubeX do
  808. begin
  809. CubeDepth := 0.1 * Value;
  810. CubeHeight := 0.1 * Value;
  811. CubeWidth := 0.1 * Value;
  812. end;
  813. with _GZOCubeY do
  814. begin
  815. CubeDepth := 0.1 * Value;
  816. CubeHeight := 0.1 * Value;
  817. CubeWidth := 0.1 * Value;
  818. end;
  819. with _GZOCubeZ do
  820. begin
  821. CubeDepth := 0.1 * Value;
  822. CubeHeight := 0.1 * Value;
  823. CubeWidth := 0.1 * Value;
  824. end;
  825. FGizmoThickness := Value;
  826. end;
  827. end;
  828. // ------------------------------------------------------------------------------
  829. procedure TGLGizmo.DirectGlDisable(Sender: TObject;
  830. var Rci: TGLRenderContextInfo);
  831. begin
  832. if FNoZWrite then
  833. Rci.GLStates.Disable(StDepthTest);
  834. end;
  835. procedure TGLGizmo.SetLabelFont(const Value: TGLCustomBitmapFont);
  836. begin
  837. if FLabelFont <> Value then
  838. begin
  839. if FLabelFont <> nil then
  840. FLabelFont.RemoveFreeNotification(Self);
  841. FLabelFont := Value;
  842. if FLabelFont <> nil then
  843. FLabelFont.FreeNotification(Self);
  844. _GZOAxisLabelX.BitmapFont := Value;
  845. _GZOAxisLabelY.BitmapFont := Value;
  846. _GZOAxisLabelZ.BitmapFont := Value;
  847. _GZOVisibleInfoLabels.BitmapFont := Value;
  848. end;
  849. end;
  850. procedure TGLGizmo.DirectGlEnable(Sender: TObject; var Rci: TGLRenderContextInfo);
  851. begin
  852. if FNoZWrite then
  853. Rci.GLStates.Enable(StDepthTest);
  854. end;
  855. function TGLGizmo.GetPickedObjectPoint(const Obj: TGLBaseSceneObject): TGLVector;
  856. var
  857. T: Integer;
  858. R: TGLGizmoRayCastHitData;
  859. begin
  860. for T := 0 to FInternalRaycastHitData.Count - 1 do
  861. begin
  862. R := TGLGizmoRayCastHitData(FInternalRaycastHitData[T]);
  863. if R.Obj = Obj then
  864. begin
  865. Result := R.Point;
  866. Break;
  867. end;
  868. end;
  869. end;
  870. function TGLGizmo.InternalGetPickedObjects(const X1, Y1, X2, Y2: Integer;
  871. const GuessCount: Integer): TGLPickList;
  872. var
  873. T: Integer;
  874. RayStart, RayVector, IPoint, INormal: TGLVector;
  875. O: TGLBaseSceneObject;
  876. Dist: Single;
  877. HitData: TGLGizmoRayCastHitData;
  878. procedure AddGizmosToPicklListRecurse(const Root: TGLBaseSceneObject);
  879. var
  880. U: Integer;
  881. begin
  882. for U := 0 to Root.Count - 1 do
  883. begin
  884. if ((Root[U] is TGLGizmoPickTorus) or (Root[U] is TGLGizmoPickCube)) then
  885. PickableObjectsWithRayCast.Add(Root[U]);
  886. AddGizmosToPicklListRecurse(Root[U]);
  887. end;
  888. end;
  889. begin
  890. case FPickMode of
  891. PmGetPickedObjects:
  892. begin
  893. Result := Viewer.Buffer.GetPickedObjects(Rect(X1, Y1, X2, Y2),
  894. GuessCount);
  895. end;
  896. PmRayCast:
  897. begin
  898. Result := TGLPickList.Create(PsMinDepth);
  899. ClearInternalRaycastHitData;
  900. SetVector(RayStart, Viewer.Camera.AbsolutePosition);
  901. SetVector(RayVector, Viewer.Buffer.ScreenToVector
  902. (AffineVectorMake((X1 + X2) * 0.5,
  903. Viewer.Height - ((Y1 + Y2) * 0.5), 0)));
  904. NormalizeVector(RayVector);
  905. // Add gizmos
  906. if (RootGizmo <> nil) and (SelectedObj <> nil) then
  907. AddGizmosToPicklListRecurse(RootGizmo);
  908. // pick
  909. for T := 0 to PickableObjectsWithRayCast.Count - 1 do
  910. begin
  911. O := TGLBaseSceneObject(PickableObjectsWithRayCast[T]);
  912. if (O.RayCastIntersect(RayStart, RayVector, @IPoint, @INormal)) and
  913. (VectorDotProduct(RayVector, INormal) < 0) then
  914. begin
  915. try
  916. Dist := VectorLength(VectorSubtract(IPoint, RayStart));
  917. Result.AddHit(O, nil, Dist, 0);
  918. HitData := TGLGizmoRayCastHitData.Create;
  919. HitData.Obj := O;
  920. MakeVector(HitData.Point, IPoint);
  921. FInternalRaycastHitData.Add(HitData);
  922. except
  923. //
  924. end;
  925. end;
  926. end;
  927. end;
  928. else
  929. begin
  930. Result := nil;
  931. Assert(False, strErrorEx + strUnknownType);
  932. end;
  933. end;
  934. end;
  935. procedure TGLGizmo.Loaded;
  936. begin
  937. inherited;
  938. SeTGLGizmoThickness(GizmoThickness);
  939. end;
  940. // ------------------------------------------------------------------------------
  941. procedure TGLGizmo.UpdateVisibleInfoLabels;
  942. var
  943. T: string;
  944. X, Y, Z: Single;
  945. begin
  946. T := '';
  947. if not(Assigned(SelectedObj)) then
  948. Exit;
  949. if VliName in FVisibleVisibleInfoLabels then
  950. T := SelectedObj.Name;
  951. if VliOperation in FVisibleVisibleInfoLabels then
  952. begin
  953. if (Operation <> GopNone) then
  954. begin
  955. if Length(T) > 0 then
  956. T := T + ' - ';
  957. case Operation of
  958. GopMove:
  959. T := T + 'Move';
  960. GopRotate:
  961. T := T + 'Rotate';
  962. GopScale:
  963. T := T + 'Scale';
  964. end;
  965. end;
  966. end;
  967. if VliCoords in FVisibleVisibleInfoLabels then
  968. begin
  969. if (Operation <> GopNone) then
  970. begin
  971. if Length(T) > 0 then
  972. T := T + ' - ';
  973. case Operation of
  974. GopMove:
  975. begin
  976. X := SelectedObj.Position.X;
  977. Y := SelectedObj.Position.Y;
  978. Z := SelectedObj.Position.Z;
  979. T := T + 'X : ' + Format('%2.3f', [X]);
  980. T := T + ' Y : ' + Format('%2.3f', [Y]);
  981. T := T + ' Z : ' + Format('%2.3f', [Z]);
  982. end;
  983. GopRotate:
  984. begin
  985. X := SelectedObj.Rotation.X;
  986. Y := SelectedObj.Rotation.Y;
  987. Z := SelectedObj.Rotation.Z;
  988. T := T + 'X : ' + Format('%2.3f', [X]);
  989. T := T + ' Y : ' + Format('%2.3f', [Y]);
  990. T := T + ' Z : ' + Format('%2.3f', [Z]);
  991. end;
  992. GopScale:
  993. begin
  994. X := SelectedObj.Scale.X;
  995. Y := SelectedObj.Scale.Y;
  996. Z := SelectedObj.Scale.Z;
  997. T := T + 'X : ' + Format('%2.3f', [X]);
  998. T := T + ' Y : ' + Format('%2.3f', [Y]);
  999. T := T + ' Z : ' + Format('%2.3f', [Z]);
  1000. end;
  1001. end;
  1002. end;
  1003. end;
  1004. _GZOVisibleInfoLabels.Text := T;
  1005. _GZOVisibleInfoLabels.StructureChanged;
  1006. end;
  1007. // ------------------------------------------------------------------------------
  1008. function TGLGizmo.CheckObjectInExcludeList
  1009. (const Obj: TGLBaseSceneObject): Boolean;
  1010. var
  1011. I: Integer;
  1012. begin
  1013. Result := False;
  1014. if FExcludeObjects then
  1015. begin
  1016. for I := 0 to FExcludeObjectsList.Count - 1 do
  1017. begin
  1018. if UpperCase(Obj.Name) = UpperCase(FExcludeObjectsList[I]) then
  1019. begin
  1020. Result := True;
  1021. Exit;
  1022. end;
  1023. end;
  1024. end;
  1025. end;
  1026. function TGLGizmo.MouseWorldPos(const X, Y: Integer): TGLVector;
  1027. var
  1028. V: TGLVector;
  1029. InvertedY: Integer;
  1030. begin
  1031. InvertedY := Viewer.Height - Y;
  1032. if Assigned(SelectedObj) then
  1033. begin
  1034. SetVector(V, X, InvertedY, 0);
  1035. case SelAxis of
  1036. GaX:
  1037. if not Viewer.Buffer.ScreenVectorIntersectWithPlaneXZ(V,
  1038. SelectedObj.AbsolutePosition.Y, Result) then
  1039. MakeVector(Result, X / 5, 0, 0);
  1040. GaY:
  1041. if not Viewer.Buffer.ScreenVectorIntersectWithPlaneYZ(V,
  1042. SelectedObj.AbsolutePosition.X, Result) then
  1043. MakeVector(Result, 0, InvertedY / 5, 0);
  1044. GaZ:
  1045. if not Viewer.Buffer.ScreenVectorIntersectWithPlaneYZ(V,
  1046. SelectedObj.AbsolutePosition.X, Result) then
  1047. MakeVector(Result, 0, 0, -InvertedY / 5);
  1048. GaXY:
  1049. begin
  1050. Viewer.Buffer.ScreenVectorIntersectWithPlaneXY(V,
  1051. SelectedObj.AbsolutePosition.Z, Result);
  1052. end;
  1053. GaXZ:
  1054. begin
  1055. Viewer.Buffer.ScreenVectorIntersectWithPlaneXZ(V,
  1056. SelectedObj.AbsolutePosition.Y, Result);
  1057. end;
  1058. GaYZ:
  1059. begin
  1060. Viewer.Buffer.ScreenVectorIntersectWithPlaneYZ(V,
  1061. SelectedObj.AbsolutePosition.X, Result);
  1062. end;
  1063. end;
  1064. end
  1065. else
  1066. SetVector(Result, NullVector);
  1067. end;
  1068. procedure TGLGizmo.ViewerMouseMove(const X, Y: Integer);
  1069. var
  1070. PickList: TGLPickList;
  1071. MousePos: TGLVector;
  1072. function IndexOf(Obj: TGLBaseSceneObject): Integer;
  1073. var
  1074. I: Integer;
  1075. begin
  1076. Result := -1;
  1077. for I := 0 to PickList.Count - 1 do
  1078. if PickList.Hit[I] = Obj then
  1079. begin
  1080. Result := I;
  1081. Break;
  1082. end;
  1083. end;
  1084. function LightLine(const Line: TGLLines; const Dark: TGLVector;
  1085. const Axis: TGLGizmoAxis; AlterStyle: Boolean = False): Boolean;
  1086. var
  1087. PickObj: TGLBaseSceneObject;
  1088. begin
  1089. case FPickMode of
  1090. PmGetPickedObjects:
  1091. PickObj := Line;
  1092. PmRayCast:
  1093. PickObj := Line;
  1094. else
  1095. begin
  1096. PickObj := nil;
  1097. Assert(False, strErrorEx + strUnknownType);
  1098. end;
  1099. end;
  1100. if IndexOf(PickObj) > -1 then
  1101. begin
  1102. Line.LineColor.Color := FSelectedColor.Color;
  1103. if not(FForceOperation) then
  1104. if Operation <> GopMove then
  1105. Operation := GopMove;
  1106. Line.Options := [];
  1107. if not(FForceAxis) then
  1108. SelAxis := Axis;
  1109. Result := True;
  1110. end
  1111. else
  1112. begin
  1113. Line.LineColor.Color := Dark;
  1114. if not(FForceOperation) then
  1115. Operation := GopNone;
  1116. if AlterStyle then
  1117. Line.Options := [LoUseNodeColorForLines];
  1118. if not(FForceAxis) then
  1119. if SelAxis = Axis then
  1120. SelAxis := GaNone;
  1121. Result := False;
  1122. end;
  1123. end;
  1124. function LightTorus(const Torus: TGLGizmoPickTorus; const Dark: TGLVector;
  1125. const Axis: TGLGizmoAxis; AlterStyle: Boolean = False): Boolean;
  1126. begin
  1127. if IndexOf(Torus) > -1 then
  1128. begin
  1129. Torus.Material.FrontProperties.Emission.Color := FSelectedColor.Color;
  1130. if not(FForceOperation) then
  1131. if Operation <> GopRotate then
  1132. Operation := GopRotate;
  1133. if not(FForceAxis) then
  1134. SelAxis := Axis;
  1135. Result := True;
  1136. end
  1137. else
  1138. begin
  1139. Torus.Material.FrontProperties.Emission.Color := Dark;
  1140. if not(FForceOperation) then
  1141. Operation := GopNone;
  1142. if not(FForceAxis) then
  1143. if SelAxis = Axis then
  1144. SelAxis := GaNone;
  1145. Result := False;
  1146. end;
  1147. end;
  1148. function LightCube(const Cube: TGLCube; const Dark: TGLVector;
  1149. const Axis: TGLGizmoAxis; AlterStyle: Boolean = False): Boolean;
  1150. begin
  1151. if IndexOf(Cube) > -1 then
  1152. begin
  1153. Cube.Material.FrontProperties.Emission.Color := FSelectedColor.Color;
  1154. if not(FForceOperation) then
  1155. if Operation <> GopScale then
  1156. Operation := GopScale;
  1157. if not(FForceAxis) then
  1158. SelAxis := Axis;
  1159. Result := True;
  1160. end
  1161. else
  1162. begin
  1163. Cube.Material.FrontProperties.Emission.Color := Dark;
  1164. if not(FForceOperation) then
  1165. Operation := GopNone;
  1166. if not(FForceAxis) then
  1167. if SelAxis = Axis then
  1168. SelAxis := GaNone;
  1169. Result := False;
  1170. end;
  1171. end;
  1172. procedure OpeMove(MousePos: TGLVector);
  1173. var
  1174. Vec1, Vec2: TGLVector;
  1175. QuantizedMousePos, QuantizedMousePos2: TGLVector;
  1176. T: Integer;
  1177. begin
  1178. for T := 0 to 3 do
  1179. begin
  1180. QuantizedMousePos.V[T] := (Round(MousePos.V[T] / MoveCoef)) * MoveCoef;
  1181. QuantizedMousePos2.V[T] := (Round(LastMousePos.V[T] / MoveCoef)) * MoveCoef;
  1182. end;
  1183. case SelAxis of
  1184. GaX:
  1185. begin
  1186. MakeVector(Vec1, QuantizedMousePos.X, 0, 0);
  1187. MakeVector(Vec2, QuantizedMousePos2.X, 0, 0);
  1188. end;
  1189. GaY:
  1190. begin
  1191. MakeVector(Vec1, 0, QuantizedMousePos.Y, 0);
  1192. MakeVector(Vec2, 0, QuantizedMousePos2.Y, 0);
  1193. end;
  1194. GaZ:
  1195. begin
  1196. MakeVector(Vec1, 0, 0, QuantizedMousePos.Z);
  1197. MakeVector(Vec2, 0, 0, QuantizedMousePos2.Z);
  1198. end;
  1199. else
  1200. begin
  1201. Vec1 := QuantizedMousePos;
  1202. Vec2 := QuantizedMousePos2;
  1203. end;
  1204. end;
  1205. SubtractVector(Vec1, Vec2);
  1206. if Assigned(OnBeforeUpdate) then
  1207. OnBeforeUpdate(Self, SelectedObj, SelAxis, Operation, Vec1);
  1208. Vec1 := SelectedObj.Parent.AbsoluteToLocal(Vec1);
  1209. if (VectorLength(Vec1) > 0) then // prevents NAN problems
  1210. begin
  1211. SelectedObj.Position.Translate(Vec1);
  1212. end;
  1213. end;
  1214. procedure OpeRotate(const X, Y: Integer);
  1215. var
  1216. Vec1: TGLVector;
  1217. RotV: TAffineVector;
  1218. Pmat: TGLMatrix;
  1219. begin
  1220. Vec1.X := 0;
  1221. Vec1.Y := 0;
  1222. if Abs(X - Rx) >= RotationCoef then
  1223. begin
  1224. if RotationCoef > 1 then
  1225. Vec1.X := RotationCoef * (Round((X - Rx) / (RotationCoef)))
  1226. else
  1227. Vec1.X := RotationCoef * (X - Rx);
  1228. Rx := X;
  1229. end;
  1230. if Abs(Y - Ry) >= RotationCoef then
  1231. begin
  1232. if RotationCoef > 1 then
  1233. Vec1.Y := RotationCoef * (Round((Y - Ry) / (RotationCoef)))
  1234. else
  1235. Vec1.Y := RotationCoef * (Y - Ry);
  1236. Ry := Y;
  1237. end;
  1238. Vec1.Z := 0;
  1239. Vec1.W := 0;
  1240. if Assigned(OnBeforeUpdate) then
  1241. OnBeforeUpdate(Self, SelectedObj, SelAxis, Operation, Vec1);
  1242. Pmat := SelectedObj.Parent.InvAbsoluteMatrix;
  1243. SetVector(Pmat.V[3], NullHmgPoint);
  1244. case SelAxis of
  1245. GaX:
  1246. begin
  1247. RotV := VectorTransform(XVector, Pmat);
  1248. RotateAroundArbitraryAxis(SelectedObj, RotV,
  1249. AffineVectorMake(SelectedObj.Position.AsVector), Vec1.Y);
  1250. end;
  1251. GaY:
  1252. begin
  1253. RotV := VectorTransform(YVector, Pmat);
  1254. RotateAroundArbitraryAxis(SelectedObj, RotV,
  1255. AffineVectorMake(SelectedObj.Position.AsVector), Vec1.X);
  1256. end;
  1257. GaZ:
  1258. begin
  1259. RotV := VectorTransform(ZVector, Pmat);
  1260. RotateAroundArbitraryAxis(SelectedObj, RotV,
  1261. AffineVectorMake(SelectedObj.Position.AsVector), Vec1.Y);
  1262. end;
  1263. GaXY:
  1264. begin
  1265. RotV := VectorTransform(XVector, Pmat);
  1266. RotateAroundArbitraryAxis(SelectedObj, RotV,
  1267. AffineVectorMake(SelectedObj.Position.AsVector), Vec1.Y);
  1268. RotV := VectorTransform(YVector, Pmat);
  1269. RotateAroundArbitraryAxis(SelectedObj, RotV,
  1270. AffineVectorMake(SelectedObj.Position.AsVector), Vec1.X);
  1271. end;
  1272. GaXZ:
  1273. begin
  1274. RotV := VectorTransform(XVector, Pmat);
  1275. RotateAroundArbitraryAxis(SelectedObj, RotV,
  1276. AffineVectorMake(SelectedObj.Position.AsVector), Vec1.Y);
  1277. RotV := VectorTransform(ZVector, Pmat);
  1278. RotateAroundArbitraryAxis(SelectedObj, RotV,
  1279. AffineVectorMake(SelectedObj.Position.AsVector), Vec1.X);
  1280. end;
  1281. GaYZ:
  1282. begin
  1283. RotV := VectorTransform(YVector, Pmat);
  1284. RotateAroundArbitraryAxis(SelectedObj, RotV,
  1285. AffineVectorMake(SelectedObj.Position.AsVector), Vec1.Y);
  1286. RotV := VectorTransform(ZVector, Pmat);
  1287. RotateAroundArbitraryAxis(SelectedObj, RotV,
  1288. AffineVectorMake(SelectedObj.Position.AsVector), Vec1.X);
  1289. end;
  1290. end;
  1291. end;
  1292. procedure OpeScale(const MousePos: TGLVector);
  1293. var
  1294. Vec1, Vec2: TGLVector;
  1295. QuantizedMousePos, QuantizedMousePos2: TGLVector;
  1296. T: Integer;
  1297. begin
  1298. for T := 0 to 3 do
  1299. begin
  1300. QuantizedMousePos.V[T] := (Round(MousePos.V[T] / ScaleCoef)) * FScaleCoef;
  1301. QuantizedMousePos2.V[T] := (Round(LastMousePos.V[T] / FScaleCoef)) *
  1302. FScaleCoef;
  1303. end;
  1304. case SelAxis of
  1305. GaX:
  1306. begin
  1307. if FForceUniformScale then
  1308. begin
  1309. MakeVector(Vec1, QuantizedMousePos.X, QuantizedMousePos.X,
  1310. QuantizedMousePos.X);
  1311. MakeVector(Vec2, QuantizedMousePos2.X, QuantizedMousePos2.X,
  1312. QuantizedMousePos2.X);
  1313. end
  1314. else
  1315. begin
  1316. MakeVector(Vec1, QuantizedMousePos.X, 0, 0);
  1317. MakeVector(Vec2, QuantizedMousePos2.X, 0, 0);
  1318. end;
  1319. end;
  1320. GaY:
  1321. begin
  1322. if FForceUniformScale then
  1323. begin
  1324. MakeVector(Vec1, QuantizedMousePos.Y, QuantizedMousePos.Y,
  1325. QuantizedMousePos.Y);
  1326. MakeVector(Vec2, QuantizedMousePos2.Y, QuantizedMousePos2.Y,
  1327. QuantizedMousePos2.Y);
  1328. end
  1329. else
  1330. begin
  1331. MakeVector(Vec1, 0, QuantizedMousePos.Y, 0);
  1332. MakeVector(Vec2, 0, QuantizedMousePos2.Y, 0);
  1333. end;
  1334. end;
  1335. GaZ:
  1336. begin
  1337. if FForceUniformScale then
  1338. begin
  1339. MakeVector(Vec1, QuantizedMousePos.Z, QuantizedMousePos.Z,
  1340. QuantizedMousePos.Z);
  1341. MakeVector(Vec2, QuantizedMousePos2.Z, QuantizedMousePos2.Z,
  1342. QuantizedMousePos2.Z);
  1343. end
  1344. else
  1345. begin
  1346. MakeVector(Vec1, 0, 0, QuantizedMousePos.Z);
  1347. MakeVector(Vec2, 0, 0, QuantizedMousePos2.Z);
  1348. end;
  1349. end;
  1350. else
  1351. begin
  1352. Vec1 := QuantizedMousePos;
  1353. Vec2 := QuantizedMousePos2;
  1354. end;
  1355. end;
  1356. SubtractVector(Vec1, Vec2);
  1357. if Assigned(OnBeforeUpdate) then
  1358. OnBeforeUpdate(Self, SelectedObj, SelAxis, Operation, Vec1);
  1359. SelectedObj.Scale.Translate(Vec1);
  1360. UpdateGizmo;
  1361. end;
  1362. begin
  1363. if not Enabled then
  1364. Exit;
  1365. if Assigned(SelectedObj) and (SelAxis <> GaNone) and Moving then
  1366. begin
  1367. MousePos := MouseWorldPos(X, Y);
  1368. // moving object...
  1369. if Operation = GopMove then
  1370. begin
  1371. // FLastOperation = gopMove;
  1372. OpeMove(MousePos);
  1373. end
  1374. else if Operation = GopRotate then
  1375. begin
  1376. // FLastOperation = gopRotate;
  1377. OpeRotate(X, Y);
  1378. end
  1379. else if Operation = GopScale then
  1380. begin
  1381. // FLastOperation = gopScale;
  1382. OpeScale(MousePos);
  1383. end;
  1384. UpdateGizmo;
  1385. Mx := X;
  1386. My := Y;
  1387. LastMousePos := MousePos;
  1388. Exit;
  1389. end;
  1390. Assert(FViewer <> nil, 'Viewer not Assigned to gizmo');
  1391. Picklist := InternalGetPickedObjects(X - 1, Y - 1, X + 1, Y + 1, 8);
  1392. // Viewer.buffer.GetPickedObjects(rect(x-1, y-1, x+1, y+1), 8);
  1393. if not LightLine(_GZOlinex, ClrRed, GaX) and not LightLine(_GZOliney, ClrLime,
  1394. GaY) and not LightLine(_GZOlinez, ClrBlue, GaZ) and
  1395. not LightTorus(_GZOTorusX, ClrRed, GaX) and
  1396. not LightTorus(_GZOTorusY, ClrLime, GaY) and
  1397. not LightTorus(_GZOTorusz, ClrBlue, GaZ) and
  1398. not LightCube(_GZOCubeX, ClrRed, GaX) and not LightCube(_GZOCubeY, ClrLime,
  1399. GaY) and not LightCube(_GZOCubeZ, ClrBlue, GaZ) and
  1400. not LightLine(_GZOplaneXY, ClrWhite, GaXY, True) and
  1401. not LightLine(_GZOplaneXZ, ClrWhite, GaXZ, True) and
  1402. not LightLine(_GZOplaneYZ, ClrWhite, GaYZ, True) then
  1403. begin
  1404. if not(FForceAxis) then
  1405. SelAxis := GaNone;
  1406. if not(FForceOperation) then
  1407. Operation := GopNone;
  1408. end;
  1409. Picklist.Free;
  1410. Mx := X;
  1411. My := Y;
  1412. end;
  1413. procedure TGLGizmo.ViewerMouseDown(const X, Y: Integer);
  1414. var
  1415. Pick: TGLPickList;
  1416. I: Integer;
  1417. Accept: Boolean;
  1418. Dimensions: TGLVector;
  1419. GotPick: Boolean;
  1420. PickedObj: TGLBaseSceneObject;
  1421. begin
  1422. Mx := X;
  1423. My := Y;
  1424. Rx := X;
  1425. Ry := Y;
  1426. if not Enabled then
  1427. Exit;
  1428. Pick := InternalGetPickedObjects(X - 1, Y - 1, X + 1, Y + 1);
  1429. // Viewer.Buffer.GetPickedObjects(rect(x-1, y-1, x+1, y+1));
  1430. GotPick := False;
  1431. Accept := False;
  1432. case FPickMode of
  1433. PmGetPickedObjects:
  1434. begin
  1435. // primeiro, ver se é uma das linhas/planos
  1436. for I := 0 to Pick.Count - 1 do
  1437. if (_GZOrootLines.IndexOfChild(TGLBaseSceneObject(Pick.Hit[I])) > -1)
  1438. or (_GZOrootTorus.IndexOfChild(TGLBaseSceneObject(Pick.Hit[I])) >
  1439. -1) or (_GZOrootCubes.IndexOfChild(TGLBaseSceneObject(Pick.Hit[I]))
  1440. > -1) then
  1441. GotPick := True;
  1442. end;
  1443. PmRayCast:
  1444. begin
  1445. for I := 0 to Pick.Count - 1 do
  1446. begin
  1447. if (Pick.Hit[I] is TGLGizmoPickCube) or
  1448. (Pick.Hit[I] is TGLGizmoPickTorus) then
  1449. GotPick := True;
  1450. end;
  1451. end;
  1452. else
  1453. begin
  1454. Assert(False, strErrorEx + strUnknownType);
  1455. end;
  1456. end;
  1457. if not GotPick then
  1458. begin
  1459. for I := 0 to Pick.Count - 1 do
  1460. if (Pick.Hit[I] <> _GZOBoundingcube) and (Pick.Hit[I] <> _GZOAxisLabelX)
  1461. and (Pick.Hit[I] <> _GZOAxisLabelY) and (Pick.Hit[I] <> _GZOAxisLabelZ)
  1462. and (Pick.Hit[I] <> _GZOVisibleInfoLabels) and
  1463. not(CheckObjectInExcludeList(TGLBaseSceneObject(Pick.Hit[I]))) then
  1464. begin
  1465. Accept := True;
  1466. PickedObj := TGLBaseSceneObject(Pick.Hit[I]);
  1467. Dimensions := PickedObj.AxisAlignedDimensions;
  1468. if Assigned(OnBeforeSelect) then
  1469. OnBeforeSelect(Self, PickedObj, Accept, Dimensions);
  1470. Break;
  1471. end;
  1472. if Accept then
  1473. SetSelectedObj(PickedObj)
  1474. else
  1475. SetSelectedObj(nil);
  1476. end
  1477. else
  1478. UpdateVisibleInfoLabels();
  1479. Pick.Free;
  1480. Moving := True;
  1481. LastMousePos := MouseWorldPos(X, Y);
  1482. end;
  1483. procedure TGLGizmo.ViewerMouseUp(const X, Y: Integer);
  1484. begin
  1485. Moving := False;
  1486. end;
  1487. // ------------------------------------------------------------------------------
  1488. procedure TGLGizmo.UpdateGizmo;
  1489. var
  1490. D: Single;
  1491. begin
  1492. if SelectedObj = nil then
  1493. begin
  1494. _GZObaseGizmo.Visible := False;
  1495. Exit;
  1496. end;
  1497. _GZObaseGizmo.Position.AsVector := SelectedObj.AbsolutePosition;
  1498. if GeObjectInfos in FGizmoElements then
  1499. UpdateVisibleInfoLabels;
  1500. _GZOBoundingcube.SetMatrix(SelectedObj.AbsoluteMatrix);
  1501. _GZOBoundingcube.Position.SetPoint(0, 0, 0);
  1502. // We must Update Color Of the BoundingBox And VisibleInfoLabels Here
  1503. // If not Color is not Updated;
  1504. // if FBoundingBoxColorChanged then
  1505. // Begin
  1506. with _GZOBoundingcube.Material do
  1507. begin
  1508. with FrontProperties do
  1509. begin
  1510. Diffuse.Color := FBoundingBoxColor.Color;
  1511. Ambient.Color := FBoundingBoxColor.Color;
  1512. Emission.Color := FBoundingBoxColor.Color;
  1513. end;
  1514. with BackProperties do
  1515. begin
  1516. Diffuse.Color := FBoundingBoxColor.Color;
  1517. Ambient.Color := FBoundingBoxColor.Color;
  1518. Emission.Color := FBoundingBoxColor.Color;
  1519. end;
  1520. end;
  1521. // FBoundingBoxColorChanged:=False;
  1522. // End;
  1523. // If FVisibleInfoLabelsColorChanged then
  1524. // Begin
  1525. _GZOVisibleInfoLabels.ModulateColor.Color := FVisibleInfoLabelsColor.Color;
  1526. // FVisibleInfoLabelsColorChanged:=False;
  1527. // End;
  1528. ObjDimensions := SelectedObj.AxisAlignedDimensions;
  1529. _GZOBoundingcube.Scale.AsVector := VectorScale(ObjDimensions, 2);
  1530. Assert(Viewer <> nil, 'Viewer not Assigned to gizmo');
  1531. _GZOAxisLabelX.PointTo(Viewer.Camera.Position.AsVector,
  1532. Viewer.Camera.Up.AsVector);
  1533. _GZOAxisLabelX.StructureChanged;
  1534. _GZOAxisLabelY.PointTo(Viewer.Camera.Position.AsVector,
  1535. Viewer.Camera.Up.AsVector);
  1536. _GZOAxisLabelY.StructureChanged;
  1537. _GZOAxisLabelZ.PointTo(Viewer.Camera.Position.AsVector,
  1538. Viewer.Camera.Up.AsVector);
  1539. _GZOAxisLabelZ.StructureChanged;
  1540. _GZOVisibleInfoLabels.PointTo(Viewer.Camera.Position.AsVector,
  1541. Viewer.Camera.Up.AsVector);
  1542. _GZOVisibleInfoLabels.StructureChanged;
  1543. if FAutoZoom then
  1544. D := Viewer.Camera.DistanceTo(SelectedObj) / FAutoZoomFactor
  1545. else
  1546. D := FZoomFactor;
  1547. _GZOrootLines.Scale.AsVector := VectorMake(D, D, D);
  1548. _GZOrootTorus.Scale.AsVector := VectorMake(D, D, D);
  1549. _GZOrootCubes.Scale.AsVector := VectorMake(D, D, D);
  1550. _GZOrootAxisLabel.Scale.AsVector := VectorMake(D, D, D);
  1551. _GZOrootVisibleInfoLabels.Scale.AsVector := VectorMake(D, D, D);
  1552. end;
  1553. procedure TGLGizmo.UpdateGizmo(const NewDimensions: TGLVector);
  1554. begin
  1555. ObjDimensions := NewDimensions;
  1556. UpdateGizmo;
  1557. end;
  1558. procedure TGLGizmo.LooseSelection;
  1559. begin
  1560. SelectedObj := nil;
  1561. UpdateGizmo;
  1562. if Assigned(OnSelectionLost) then
  1563. OnSelectionLost(Self);
  1564. end;
  1565. procedure TGLGizmo.SetViewer(const Value: TGLSceneViewer);
  1566. begin
  1567. if FViewer <> Value then
  1568. begin
  1569. if FViewer <> nil then
  1570. FViewer.RemoveFreeNotification(Self);
  1571. FViewer := Value;
  1572. if FViewer <> nil then
  1573. FViewer.FreeNotification(Self);
  1574. end;
  1575. end;
  1576. procedure TGLGizmo.Notification(AComponent: TComponent; Operation: TOperation);
  1577. begin
  1578. inherited;
  1579. if Operation = OpRemove then
  1580. begin
  1581. if AComponent = FViewer then
  1582. FViewer := nil;
  1583. if AComponent = FRootGizmo then
  1584. FRootGizmo := nil;
  1585. end;
  1586. if FUndoHistory <> nil then
  1587. FUndoHistory.Notification(AComponent, Operation);
  1588. end;
  1589. procedure TGLGizmoUndoItem.AssignFromObject(const AObject
  1590. : TGLCustomSceneObject);
  1591. begin
  1592. SetEffectedObject(AObject);
  1593. SetOldMatrix(AObject.Matrix^);
  1594. if AObject is TGLFreeForm then
  1595. begin
  1596. FOldAutoScaling.Assign(TGLFreeForm(AObject).AutoScaling);
  1597. end;
  1598. FOldLibMaterialName := AObject.Material.LibMaterialName;
  1599. end;
  1600. constructor TGLGizmoUndoItem.Create(AOwner: TCollection);
  1601. begin
  1602. inherited;
  1603. FOldAutoScaling := TGLCoordinates.CreateInitialized(Self,
  1604. NullHmgVector, CsPoint);
  1605. end;
  1606. destructor TGLGizmoUndoItem.Destroy;
  1607. begin
  1608. FOldAutoScaling.Free;
  1609. inherited;
  1610. end;
  1611. procedure TGLGizmoUndoItem.DoUndo;
  1612. begin
  1613. FEffectedObject.SetMatrix(FOldMatr);
  1614. if FEffectedObject is TGLFreeForm then
  1615. TGLFreeForm(FEffectedObject).AutoScaling.Assign(FOldAutoScaling);
  1616. FEffectedObject.Material.LibMaterialName := FOldLibMaterialName;
  1617. end;
  1618. function TGLGizmoUndoItem.GetGizmo: TGLGizmo;
  1619. begin
  1620. if GetParent <> nil then
  1621. Result := GetPArent.GetParent
  1622. else
  1623. Result := nil;
  1624. end;
  1625. function TGLGizmoUndoItem.GetParent: TGLGizmoUndoCollection;
  1626. begin
  1627. Result := TGLGizmoUndoCollection(GetOwner);
  1628. end;
  1629. procedure TGLGizmoUndoItem.Notification(AComponent: TComponent;
  1630. Operation: TOperation);
  1631. begin
  1632. inherited;
  1633. if Operation = OpRemove then
  1634. begin
  1635. if AComponent = FEffectedObject then
  1636. FEffectedObject := nil;
  1637. end;
  1638. end;
  1639. procedure TGLGizmoUndoItem.SetEffectedObject(const Value: TGLCustomSceneObject);
  1640. begin
  1641. if FEffectedObject <> nil then
  1642. FEffectedObject.RemoveFreeNotification(GetGizmo);
  1643. FEffectedObject := Value;
  1644. if FEffectedObject <> nil then
  1645. FEffectedObject.FreeNotification(GetGizmo);
  1646. end;
  1647. procedure TGLGizmoUndoItem.SetOldAutoScaling(const Value: TGLCoordinates);
  1648. begin
  1649. FOldAutoScaling.Assign(Value);
  1650. end;
  1651. procedure TGLGizmoUndoItem.SetOldMatrix(const Value: TGLMatrix);
  1652. begin
  1653. FOldMatrix := Value;
  1654. end;
  1655. { TGLGizmoUndoCollection }
  1656. function TGLGizmoUndoCollection.Add: TGLGizmoUndoItem;
  1657. begin
  1658. Result := TGLGizmoUndoItem(inherited Add);
  1659. end;
  1660. function TGLGizmoUndoCollection.GetItems(const Index: Integer)
  1661. : TGLGizmoUndoItem;
  1662. begin
  1663. Result := TGLGizmoUndoItem(inherited GetItem(Index));
  1664. end;
  1665. function TGLGizmoUndoCollection.GetParent: TGLGizmo;
  1666. begin
  1667. Result := TGLGizmo(GetOwner);
  1668. end;
  1669. procedure TGLGizmoUndoCollection.Notification(AComponent: TComponent;
  1670. Operation: TOperation);
  1671. var
  1672. I: Integer;
  1673. begin
  1674. if Count <> 0 then
  1675. for I := 0 to Count - 1 do
  1676. GetItems(I).Notification(AComponent, Operation);
  1677. end;
  1678. procedure TGLGizmoUndoCollection.RemoveByObject(const AObject
  1679. : TGLCustomSceneObject);
  1680. var
  1681. I: Integer;
  1682. begin
  1683. for I := Count - 1 downto 0 do
  1684. if GetItems(I).FEffectedObject = AObject then
  1685. GetItems(I).Free;
  1686. end;
  1687. procedure TGLGizmoUndoCollection.SetItems(const Index: Integer;
  1688. const Value: TGLGizmoUndoItem);
  1689. begin
  1690. GetItems(Index).Assign(Value);
  1691. end;
  1692. procedure TGLGizmo.SetSelectedObj(const Value: TGLBaseSceneObject);
  1693. begin
  1694. if FSelectedObj <> Value then
  1695. begin
  1696. FSelectedObj := Value;
  1697. if Value <> nil then
  1698. begin
  1699. SetVisible(True);
  1700. UpdateVisibleInfoLabels();
  1701. UpdateGizmo();
  1702. end
  1703. else
  1704. begin
  1705. LooseSelection();
  1706. SetVisible(False);
  1707. end;
  1708. end;
  1709. end;
  1710. end.