GXS.GizmoEx.pas 134 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487
  1. //
  2. // The graphics engine GXScene https://github.com/glscene
  3. //
  4. unit GXS.GizmoEx;
  5. (*
  6. Invisible component for helping to Move, Rotate and Scale an Object
  7. This is an enhanced version of TgxGizmo usefull for an Editor.
  8. *)
  9. interface
  10. {$I Stage.Defines.inc}
  11. uses
  12. Winapi.OpenGL,
  13. Winapi.OpenGLext,
  14. Winapi.Windows,
  15. System.Types,
  16. System.Classes,
  17. System.SysUtils,
  18. System.Math,
  19. FMX.TextLayout,
  20. Stage.VectorTypes,
  21. Stage.VectorGeometry,
  22. Stage.PipelineTransform,
  23. Stage.Strings,
  24. GXS.PersistentClasses,
  25. GXS.GeometryBB,
  26. GXS.Scene,
  27. GXS.Color,
  28. GXS.Material,
  29. GXS.Objects,
  30. GXS.SceneViewer,
  31. GXS.GeomObjects,
  32. GXS.BitmapFont,
  33. GXS.VectorFileObjects,
  34. GXS.Coordinates,
  35. GXS.RenderContextInfo,
  36. GXS.Canvas,
  37. GXS.Screen,
  38. GXS.State,
  39. GXS.Selection,
  40. GXS.ImageUtils,
  41. GXS.Context;
  42. type
  43. TgxGizmoExObjectCollection = class;
  44. TgxGizmoEx = class;
  45. TgxGizmoExObjectItem = class(TCollectionItem)
  46. private
  47. FOldAutoScaling: TVector4f;
  48. FEffectedObject: TgxBaseSceneObject;
  49. FParentOldObject: TgxBaseSceneObject;
  50. FIndexOldObject: Integer;
  51. FNameOldObject: string;
  52. FReturnObject: Boolean;
  53. FOldMatrix: TMatrix4f;
  54. FGizmoTmpRoot: TgxBaseSceneObject;
  55. procedure SetEffectedObject(const Value: TgxBaseSceneObject);
  56. procedure SetOldMatrix(const Value: TMatrix4f);
  57. protected
  58. procedure DoUndo;
  59. function GetParent: TgxGizmoExObjectCollection;
  60. function GetGizmo: TgxGizmoEx;
  61. public
  62. property GizmoTmpRoot: TgxBaseSceneObject read FGizmoTmpRoot write FGizmoTmpRoot;
  63. constructor Create(AOwner: TCollection); override;
  64. destructor Destroy; override;
  65. procedure Notification(AComponent: TComponent; Operation: TOperation); virtual;
  66. procedure AssignFromObject(const AObject: TgxBaseSceneObject; AssignAndRemoveObj: Boolean = False);
  67. // TODO: create a special type for Matrix.
  68. property OldMatrix: TMatrix4f read FOldMatrix write SetOldMatrix;
  69. published
  70. property EffectedObject: TgxBaseSceneobject read FEffectedObject write SetEffectedObject;
  71. end;
  72. TgxGizmoExObjectCollection = class(TOwnedCollection)
  73. private
  74. function GetItems(const Index: Integer): TgxGizmoExObjectItem;
  75. procedure SetItems(const Index: Integer; const Value: TgxGizmoExObjectItem);
  76. protected
  77. function GetParent: TgxGizmoEx;
  78. procedure DoUndo;
  79. public
  80. procedure Notification(AComponent: TComponent; Operation: TOperation);
  81. procedure RemoveByObject(const AObject: TgxCustomSceneObject);
  82. function Add: TgxGizmoExObjectItem;
  83. property Items[const Index: Integer]: TgxGizmoExObjectItem read GetItems write SetItems; default;
  84. end;
  85. TgxGizmoExActionHistoryItem = class(TCollectionItem)
  86. private
  87. FObject: TObject;
  88. FGizmoObjectCollection: TgxGizmoExObjectCollection;
  89. procedure SetObject(aValue: TObject);
  90. procedure SetGizmoObjectCollection(aValue: TgxGizmoExObjectCollection);
  91. public
  92. constructor Create(AOwner: TCollection); override;
  93. destructor Destroy; override;
  94. property BaseObject: TObject read FObject write SetObject;
  95. property GizmoObjectCollection: TgxGizmoExObjectCollection read FGizmoObjectCollection write SetGizmoObjectCollection;
  96. end;
  97. TgxGizmoExActionHistoryCollection = class(TOwnedCollection)
  98. private
  99. FItemIndex: Integer;
  100. FItemsMaxCount: Integer;
  101. FGizmoTmpRoot: TgxBaseSceneObject;
  102. function GetItems(const Index: Integer): TgxGizmoExActionHistoryItem;
  103. procedure SetItems(const Index: Integer; const Value: TgxGizmoExActionHistoryItem);
  104. function Add: TgxGizmoExActionHistoryItem;
  105. public
  106. constructor Create(AOwner: TPersistent; ItemClass: TCollectionItemClass);
  107. procedure Notification(AComponent: TComponent; Operation: TOperation);
  108. property ItemIndex: Integer read FItemIndex write FItemIndex;
  109. function Undo: TgxGizmoExActionHistoryItem;
  110. function Redo: TgxGizmoExActionHistoryItem;
  111. procedure AddObjects(objs: TgxPickList);
  112. procedure AddObject(obj: TObject);
  113. procedure RemoveObjects(objs: TgxPickList);
  114. property MaxCount: Integer read FItemsMaxCount write FItemsMaxCount;
  115. property Items[const Index: Integer]: TgxGizmoExActionHistoryItem read GetItems write SetItems; default;
  116. property GizmoTmpRoot: TgxBaseSceneObject read FGizmoTmpRoot write FGizmoTmpRoot;
  117. end;
  118. TgxGizmoExVisibleInfoLabel = (vliName, vliOperation, vliCoords);
  119. TgxGizmoExVisibleInfoLabels = set of TgxGizmoExVisibleInfoLabel;
  120. TInfoLabelCoordType = (ilcChanging, ilcChangeRate);
  121. TgxGizmoExAxis = (gaNone, gaX, gaY, gaZ, gaXY, gaXZ, gaYZ, gaXYZ);
  122. TgxGizmoExSelectionRegion = (gsrRectangular, gsrCircular, gsrFence,
  123. gsrLasso);
  124. TgxGizmoExReferenceCoordinateSystem = (rcsView, rcsLocal);
  125. TgxGizmoExSelRec = array of TPoint;
  126. TgxGizmoExOperation = (gopMove, gopRotate, gopScale, gopNone);
  127. TgxGizmoExOperationMode = (gomNone, gomSelect, gomMove, gomRotate, gomScale);
  128. TgxGizmoExAcceptEvent = procedure(Sender: TObject; var objs: TgxPickList) of object;
  129. TgxGizmoExAxisSelected = procedure(Sender: TObject; var Axis: TgxGizmoExAxis) of object;
  130. TgxGizmoExPickMode = (pmGetPickedObjects, pmRayCast);
  131. //Gizmo objects
  132. TgxGizmoExUIFrustrum = class(TgxFrustrum)
  133. private
  134. FNoZWrite: Boolean;
  135. public
  136. constructor Create(AOwner: TComponent); override;
  137. procedure BuildList(var rci: TgxRenderContextInfo); override;
  138. property NoZWrite: Boolean read FNoZWrite write FNoZWrite;
  139. end;
  140. TgxGizmoExUISphere = class(TgxSphere)
  141. private
  142. FNoZWrite: Boolean;
  143. public
  144. constructor Create(AOwner: TComponent); override;
  145. procedure BuildList(var rci: TgxRenderContextInfo); override;
  146. property NoZWrite: Boolean read FNoZWrite write FNoZWrite;
  147. end;
  148. TgxGizmoExUIDisk = class(TgxDisk)
  149. private
  150. FNoZWrite: Boolean;
  151. public
  152. constructor Create(AOwner: TComponent); override;
  153. procedure BuildList(var rci: TgxRenderContextInfo); override;
  154. property NoZWrite: Boolean read FNoZWrite write FNoZWrite;
  155. end;
  156. TgxGizmoExUITorus = class(TgxTorus)
  157. private
  158. FNoZWrite: Boolean;
  159. public
  160. constructor Create(AOwner: TComponent); override;
  161. procedure BuildList(var rci: TgxRenderContextInfo); override;
  162. property NoZWrite: Boolean read FNoZWrite write FNoZWrite;
  163. end;
  164. TgxGizmoExUIPolygon = class(TgxPolygon)
  165. private
  166. FNoZWrite: Boolean;
  167. public
  168. constructor Create(AOwner: TComponent); override;
  169. procedure BuildList(var rci: TgxRenderContextInfo); override;
  170. property NoZWrite: Boolean read FNoZWrite write FNoZWrite;
  171. end;
  172. TgxGizmoExUIArrowLine = class(TgxArrowLine)
  173. private
  174. FNoZWrite: Boolean;
  175. public
  176. constructor Create(AOwner: TComponent); override;
  177. procedure BuildList(var rci: TgxRenderContextInfo); override;
  178. property NoZWrite: Boolean read FNoZWrite write FNoZWrite;
  179. end;
  180. TgxGizmoExUILines = class(TgxLines)
  181. private
  182. FNoZWrite: Boolean;
  183. public
  184. constructor Create(AOwner: TComponent); override;
  185. procedure BuildList(var rci: TgxRenderContextInfo); override;
  186. property NoZWrite: Boolean read FNoZWrite write FNoZWrite;
  187. end;
  188. TgxGizmoExUIFlatText = class(TgxFlatText)
  189. private
  190. FNoZWrite: Boolean;
  191. public
  192. constructor Create(AOwner: TComponent); override;
  193. procedure BuildList(var rci: TgxRenderContextInfo); override;
  194. property NoZWrite: Boolean read FNoZWrite write FNoZWrite;
  195. end;
  196. TgxGizmoEx = class(TComponent)
  197. private
  198. FUIBaseGizmo: TgxBaseSceneObject;
  199. FUIRootHelpers: TgxBaseSceneObject;
  200. FUIRootSelect: TgxBaseSceneObject; // for None
  201. FUIRootMovement: TgxBaseSceneObject; // for Move
  202. FUIRootRotate: TgxBaseSceneObject; //for Rotate
  203. FUIRootRotateAxisLabel: TgxBaseSceneObject;
  204. FUIRootScale: TgxBaseSceneObject; // for Scale
  205. FUIRootAxisLabel: TgxBaseSceneObject;
  206. FUIRootVisibleInfoLabels: TgxBaseSceneObject;
  207. FInterfaceRender: TgxDirectOpenGL;
  208. FInternalRender: TgxDirectOpenGL;
  209. FUISelectLineX, FUISelectLineY, FUISelectLineZ: TgxGizmoExUILines; // For None (Select)
  210. //IC- Invisible Contro, for move
  211. FUIICMovementLineX, FUIICMovementLineY, FUIICMovementLineZ, FUIICMovementLineXY, FUIICMovementLineXZ, FUIICMovementLineYZ: TgxGizmoExUIFrustrum;
  212. FUIMovementArrowX, FUIMovementArrowY, FUIMovementArrowZ: TgxGizmoExUIArrowLine; // For Move
  213. FUIMovementLineX, FUIMovementLineY, FUIMovementLineZ, FUIMovementLineXY, FUIMovementLineXZ, FUIMovementLineYZ: TgxGizmoExUILines; // For Move
  214. FUIMovementPlaneXY, FUIMovementPlaneXZ, FUIMovementPlaneYZ: TgxGizmoExUIPolyGon; // For Move
  215. //ForRotate
  216. FUIRotateLineX, FUIRotateLineY, FUIRotateLineZ, FUIRotateLineXY, FUIRotateLineXZ: TgxGizmoExUILines;
  217. FUIICRotateTorusX, FUIICRotateTorusY, FUIICRotateTorusZ, FUIICRotateTorusXZ: TgxGizmoExUITorus; // For Rotate
  218. FUIRotateDiskXY, FUIRotateDiskX, FUIRotateDiskX2, FUIRotateDiskY, FUIRotateDiskY2, FUIRotateDiskZ, FUIRotateDiskZ2: TgxGizmoExUIDisk;
  219. FUIRotateLineArrowX, FUIRotateLineArrowY, FUIRotateLineArrowZ: TgxGizmoExUILines;
  220. FUIICRotateSphereXY: TgxGizmoExUISphere;
  221. FUIRotateAxisLabelX, FUIRotateAxisLabelY, FUIRotateAxisLabelZ: TgxGizmoExUIFlatText;
  222. //ForScale
  223. FUIScaleArrowX, FUIScaleArrowY, FUIScaleArrowZ: TgxGizmoExUISphere;
  224. FUIScaleLineX, FUIScaleLineY, FUIScaleLineZ, FUIScaleLineXY, FUIScaleLineYZ, FUIScaleLineXZ: TgxGizmoExUILines;
  225. FUIICScaleLineX, FUIICScaleLineY, FUIICScaleLineZ, FUIICScaleLineXY, FUIICScaleLineXZ, FUIICScaleLineYZ, FUIICScaleLineXYZ: TgxGizmoExUIFrustrum;
  226. FUIScalePlaneXY, FUIScalePlaneXZ, FUIScalePlaneYZ, FUIScalePlaneXYZ: TgxGizmoExUIPolyGon; // For Move
  227. FUIAxisLabelX, FUIAxisLabelY, FUIAxisLabelZ: TgxGizmoExUIFlatText;
  228. FUIVisibleInfoLabels: TgxGizmoExUIFlatText;
  229. FRootGizmo: TgxBaseSceneObject;
  230. FRootObjects: TgxBaseSceneObject;
  231. FGizmoTmpRoot: TgxBaseSceneObject;
  232. FSelectedObj: TgxBaseSceneObject;
  233. FOperation: TgxGizmoExOperation;
  234. FOperationMode: TgxGizmoExOperationMode;
  235. FSelAxis: TgxGizmoExAxis;
  236. fInfoLabelCoordType: TInfoLabelCoordType;
  237. FReferenceCoordSystem: TgxGizmoExReferenceCoordinateSystem;
  238. FBoundingBoxColor: TgxColor;
  239. FSelectedColor: TgxColor;
  240. FVisibleInfoLabelsColor: TgxColor;
  241. FSelectionRegionColor: TgxColor;
  242. FVisibleInfoLabelsColorChanged: Boolean;
  243. FAutoZoom: Boolean;
  244. FExcludeObjects: Boolean;
  245. FExcludeClassname: Boolean;
  246. FNoZWrite: Boolean;
  247. FEnabled: Boolean;
  248. FAutoZoomFactor: Single;
  249. FZoomFactor: Single;
  250. FMoveCoef: Single;
  251. FRotationCoef: Single;
  252. FViewer: TgxSceneViewer;
  253. FVisibleVisibleInfoLabels: TgxGizmoExVisibleInfoLabels;
  254. FExcludeObjectsList: TStrings;
  255. FExcludeClassNameList: TStrings;
  256. FSelectionRegion: TgxGizmoExSelectionRegion;
  257. FEnableMultiSelection: Boolean;
  258. FShowMultiSelecting: Boolean;
  259. FSelectionRec: TgxGizmoExSelRec;
  260. FCanAddObjToSelectionList: Boolean;
  261. FCanRemoveObjFromSelectionList: Boolean;
  262. FSelectedObjects: TgxPickList;
  263. FAntiAliasedLines: Boolean;
  264. FShowAxisLabel: Boolean;
  265. FShowObjectInfos: Boolean;
  266. FShowBoundingBox: Boolean;
  267. FCanChangeWithChildren: Boolean;
  268. moving: Boolean;
  269. mx, my: Integer;
  270. fCursorPos: TPoint;
  271. fLastCursorPos: TPoint;
  272. fChangeRate: TAffineVector; //total rotate angle
  273. FEnableLoopCursorMoving: Boolean;
  274. lastMousePos: TVector4f;
  275. FOnUpdate: TNotifyEvent;
  276. FOnSelect: TgxGizmoExAcceptEvent;
  277. FOnOperationChange: TNotifyEvent;
  278. FOnOperationModeChange: TNotifyEvent;
  279. FOnSelectionLost: TNotifyEvent;
  280. FOnAxisSelected: TgxGizmoExAxisSelected;
  281. FScaleCoef: Single;
  282. FGizmoThickness: Single;
  283. FPickMode: TgxGizmoExPickMode;
  284. FEnableHistory: Boolean;
  285. FHistory: TgxGizmoExActionHistoryCollection;
  286. FHistoryStepsCount: Integer;
  287. FLabelFont: TgxCustomBitmapFont;
  288. procedure SetRootGizmo(const AValue: TgxBaseSceneObject);
  289. procedure SetRootObjects(const AValue: TgxBaseSceneObject);
  290. procedure SetGizmoTmpRoot(const AValue: TgxBaseSceneObject);
  291. procedure SetGizmoExVisibleInfoLabels(const AValue: TgxGizmoExVisibleInfoLabels);
  292. procedure SetBoundingBoxColor(const AValue: TgxColor);
  293. procedure SetSelectedColor(const AValue: TgxColor);
  294. procedure SetVisibleInfoLabelsColor(const AValue: TgxColor);
  295. procedure SetSelectionRegionColor(const AValue: TgxColor);
  296. procedure SetCanChangeWithChildren(AValue: Boolean);
  297. procedure SetAALines(aValue: Boolean);
  298. procedure SetInfoLabelCoordType(aValue: TInfoLabelCoordType);
  299. procedure SetReferenceCoordSystem(aValue: TgxGizmoExReferenceCoordinateSystem);
  300. procedure SetHistoryStepsCount(aValue: Integer);
  301. procedure SetExcludeObjectsList(const AValue: TStrings);
  302. procedure SetExcludeClassNameList(const AValue: TStrings);
  303. function MouseWorldPos(const X, Y: Integer): TVector4f;
  304. function CheckObjectInExcludeList(const Obj: TgxBaseSceneObject): Boolean;
  305. function CheckClassNameInExcludeList(const Obj: TgxBaseSceneObject): Boolean;
  306. procedure UpdateVisibleInfoLabels;
  307. procedure SetGizmoExThickness(const Value: Single);
  308. procedure ActivatingElements(PickList: TgxPickList);
  309. procedure InterfaceRender(Sender: TObject; var rci: TgxRenderContextInfo);
  310. procedure InternalRender(Sender: TObject; var rci: TgxRenderContextInfo);
  311. function InternalGetPickedObjects(const x1, y1, x2, y2: Integer; const guessCount: Integer = 8): TgxPickList;
  312. procedure SetViewer(const Value: TgxSceneViewer);
  313. procedure SetLabelFont(const Value: TgxCustomBitmapFont);
  314. procedure SetSelectedObj(const Value: TgxBaseSceneObject);
  315. function GetSelectedObj: TgxBaseSceneObject;
  316. procedure SetNoZWrite(const Value: Boolean);
  317. procedure SetOperation(const Value: TgxGizmoExOperation);
  318. procedure SetOperationMode(const Value: TgxGizmoExOperationMode);
  319. procedure SetAngleDisk(aAngle: Single);
  320. procedure SetEnableLoopCursorMoving(const AValue: Boolean);
  321. procedure SetEnableMultiSelection(const AValue: Boolean);
  322. procedure SetSelectionRegion(const AValue: TgxGizmoExSelectionRegion);
  323. procedure SetShowAxisLabel(const AValue: Boolean);
  324. procedure SetShowObjectInfos(const AValue: Boolean);
  325. procedure SetShowBoundingBox(const AValue: Boolean);
  326. procedure SetAutoZoomFactor(const AValue: Single);
  327. procedure SetZoomFactor(const AValue: Single);
  328. procedure SetSelAxis(aValue: TgxGizmoExAxis);
  329. procedure SetPickMode(APickMode: TgxGizmoExPickMode);
  330. procedure AssignPickList(aList: TgxPickList; RemoveObj: Boolean = False);
  331. procedure AddObjToSelectionList(Obj: TgxBaseSceneObject);
  332. procedure RemoveObjFromSelectionList(Obj: TgxBaseSceneObject);
  333. procedure MultiSelMouseDown(X, Y: Integer);
  334. procedure MultiSelMouseUp(X, Y: Integer);
  335. procedure MultiSelMouseMove(X, Y: Integer);
  336. function GetPickList: TgxPickList;
  337. procedure SetPickList(aValue: TgxPickList);
  338. property SelAxis: TgxGizmoExAxis read FSelAxis write SetSelAxis;
  339. property Operation: TgxGizmoExOperation read FOperation write SetOperation;
  340. procedure ClearSelection;
  341. procedure SetVisible(const AValue: Boolean);
  342. function GetVisible: Boolean;
  343. public
  344. constructor Create(AOwner: TComponent); override;
  345. destructor Destroy; override;
  346. procedure Loaded; override;
  347. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  348. procedure ViewerMouseMove(const X, Y: Integer);
  349. procedure ViewerMouseDown(const X, Y: Integer);
  350. procedure ViewerMouseUp(const X, Y: Integer);
  351. procedure UpdateGizmo; overload;
  352. procedure LooseSelection; virtual;
  353. procedure UndoAdd(const AObject: TObject);
  354. procedure RemoveSelectedObjects;
  355. function Undo: TgxGizmoExActionHistoryItem;
  356. function Redo: TgxGizmoExActionHistoryItem;
  357. property CanAddObjToSelectionList: Boolean read FCanAddObjToSelectionList write FCanAddObjToSelectionList;
  358. property CanRemoveObjFromSelectionList: Boolean read FCanRemoveObjFromSelectionList write FCanRemoveObjFromSelectionList;
  359. procedure LooseCursorSelection;
  360. property CursorSelectingRegion: Boolean read FShowMultiSelecting;
  361. property RootObjects: TgxBaseSceneObject read FRootObjects write SetRootObjects;
  362. property RootGizmo: TgxBaseSceneObject read FRootGizmo write SetRootGizmo;
  363. property GizmoTmpRoot: TgxBaseSceneObject read FGizmoTmpRoot write SetGizmoTmpRoot;
  364. //--------------------------------------------------------------------
  365. published
  366. property Viewer: TgxSceneViewer read FViewer write SetViewer;
  367. property BoundingBoxColor: TgxColor read FBoundingBoxColor write SetBoundingBoxColor;
  368. property SelectedColor: TgxColor read FSelectedColor write SetSelectedColor;
  369. property SelectionRegionColor: TgxColor read FSelectionRegionColor write SetSelectionRegionColor;
  370. property SelectedObj: TgxBaseSceneObject read GetSelectedObj write SetSelectedObj;
  371. property SelectedObjects: TgxPickList read GetPickList write SetPickList;
  372. property OperationMode: TgxGizmoExOperationMode read FOperationMode write SetOperationMode default gomSelect;
  373. property ExcludeObjects: Boolean read FExcludeObjects write FExcludeObjects;
  374. property ExcludeObjectsList: TStrings read FExcludeObjectsList write SetExcludeObjectsList;
  375. property ExcludeClassname: Boolean read FExcludeClassname write FExcludeClassname;
  376. property ExcludeClassnameList: TStrings read FExcludeClassnameList write SetExcludeClassnameList;
  377. property VisibleInfoLabels: TgxGizmoExVisibleInfoLabels read FVisibleVisibleInfoLabels write SetGizmoExVisibleInfoLabels;
  378. property VisibleInfoLabelsColor: TgxColor read FVisibleInfoLabelsColor write SetVisibleInfoLabelsColor;
  379. property AutoZoom: Boolean read FAutoZoom write FAutoZoom default True;
  380. property AutoZoomFactor: Single read FAutoZoomFactor write SetAutoZoomFactor;
  381. property ZoomFactor: Single read FZoomFactor write SetZoomFactor;
  382. property MoveCoef: Single read FMoveCoef write FMoveCoef;
  383. property RotationCoef: Single read FRotationCoef write FRotationCoef;
  384. property ScaleCoef: Single read FScaleCoef write FScaleCoef;
  385. property NoZWrite: Boolean read FNoZWrite write SetNoZWrite default True;
  386. property GizmoThickness: Single read FGizmoThickness write SetGizmoExThickness;
  387. (* Indicates whether the gizmo is enabled or not.
  388. WARNING: When loading/editing (possibly whenever a structureChanged
  389. call is made) a model, sometimes the gizmo will trigger a
  390. bug if the mouse is inside the glscene Viewer. To prevent that,
  391. remember to disable the gizmo before loading, then process windows
  392. messages (i.e. application.processMessage) and then enable the gizmo
  393. again. *)
  394. (* Warning Enable is ReadOnly property if you set to False, Gizmo is not Hidden
  395. use Visible instead if you want to Hide, if you want to Hide but keep enabled
  396. see the VisibleGizmo property *)
  397. (* Use the property OperationMode=gomNone to unactivate gizmo and make it invisible *)
  398. property Enabled: Boolean read FEnabled write FEnabled default True;
  399. property LabelFont: TgxCustomBitmapFont read FLabelFont write SetLabelFont default nil;
  400. property OnSelectionLost: TNotifyEvent read FOnSelectionLost write FOnSelectionLost;
  401. property OnOperationChange: TNotifyEvent read FOnOperationChange write FOnOperationChange;
  402. property OnOperationModeChange: TNotifyEvent read FOnOperationModeChange write FOnOperationModeChange;
  403. property OnSelect: TgxGizmoExAcceptEvent read FOnSelect write FOnSelect;
  404. property OnAxisSelected: TgxGizmoExAxisSelected read FOnAxisSelected write FOnAxisSelected;
  405. property OnUpdate: TNotifyEvent read FOnUpdate write FOnUpdate;
  406. property PickMode: TgxGizmoExPickMode read FPickMode write SetPickMode default pmGetPickedObjects;
  407. property EnableActionHistory: Boolean read FEnableHistory write FEnableHistory default True;
  408. property HistoryStepsCount: Integer read FHistoryStepsCount write SetHistoryStepsCount;
  409. property EnableLoopCursorMoving: Boolean read FEnableLoopCursorMoving write SetEnableLoopCursorMoving default True;
  410. property EnableMultiSelection: Boolean read FEnableMultiSelection write SetEnableMultiSelection default True;
  411. property CanChangeWithChildren: Boolean read FCanChangeWithChildren write SetCanChangeWithChildren;
  412. property AntiAliasedLines: Boolean read FAntiAliasedLines write SetAALines default True;
  413. property InfoLabelCoordType: TInfoLabelCoordType read fInfoLabelCoordType write SetInfoLabelCoordType default ilcChangeRate;
  414. property SelectionRegion: TgxGizmoExSelectionRegion read FSelectionRegion write SetSelectionRegion default gsrRectangular;
  415. property ShowAxisLabel: Boolean read FShowAxisLabel write SetShowAxisLabel default True;
  416. property ShowObjectInfos: Boolean read FShowObjectInfos write SetShowObjectInfos default True;
  417. property ShowBoundingBox: Boolean read FShowBoundingBox write SetShowBoundingBox default True;
  418. property ReferenceCoordSystem: TgxGizmoExReferenceCoordinateSystem read FReferenceCoordSystem write SetReferenceCoordSystem default rcsView;
  419. property Visible: Boolean read GetVisible write SetVisible;
  420. end;
  421. //--------------------------------------------------------------------
  422. implementation
  423. //---------------------------------------------------------------------
  424. procedure RotateAroundArbitraryAxis(const anObject: TgxBaseSceneObject; const Axis, Origin: TAffineVector; const angle: Single);
  425. var
  426. M, M1, M2, M3: TMatrix4f;
  427. begin
  428. M1 := CreateTranslationMatrix(VectorNegate(Origin));
  429. M2 := CreateRotationMatrix(Axis, Angle * PI / 180);
  430. M3 := CreateTranslationMatrix(Origin);
  431. M := MatrixMultiply(M1, M2);
  432. M := MatrixMultiply(M, M3);
  433. anObject.AbsoluteMatrix := MatrixMultiply(anObject.AbsoluteMatrix, M);
  434. //Just a workarround to Update angles...
  435. anObject.Roll(0);
  436. anObject.Pitch(0);
  437. anObject.Turn(0);
  438. end;
  439. //-------------------------------------------------------------------
  440. // Mathematical functions for canvas
  441. //-------------------------------------------------------------------
  442. function Det(const a, b, c, d: real): real;
  443. begin
  444. Det := a * d - b * c;
  445. end;
  446. //Distance between two points
  447. function Dist(const P1, P2: TPoint): real;
  448. begin
  449. Result := Sqrt(Sqr(P1.X - P2.X) + Sqr(P1.Y - P2.Y));
  450. end;
  451. function CrossingPointLine(p: TPoint; p1, p2: TPoint): Boolean;
  452. begin
  453. Result := (abs(p1.X - p.X) + abs(p2.X - p.X) = abs(p2.X - p1.X)) and
  454. (abs(p1.Y - p.Y) + abs(p2.Y - p.Y) = abs(p2.Y - p1.Y));
  455. end;
  456. //Intersection between two lines, return true or false
  457. //converted from http://doc-for-prog.narod.ru/topics/math/crossing.html
  458. function IsLineIntLine(p11, p12, p21, p22: TPoint; var p: TPoint): Boolean; // êîîðäèíàòû âòîðîãî îòðåçêà
  459. var
  460. Z, ca, cb, ua, ub: Single;
  461. begin
  462. // demominator
  463. Z := (p12.Y - p11.Y) * (p21.X - p22.X) - (p21.Y - p22.Y) * (p12.X - p11.X);
  464. // numerator 1
  465. Ca := (p12.Y - p11.Y) * (p21.X - p11.X) - (p21.Y - p11.Y) * (p12.X - p11.X);
  466. // numerator 2
  467. Cb := (p21.Y - p11.Y) * (p21.X - p22.X) - (p21.Y - p22.Y) * (p21.X - p11.X);
  468. // if numerator and demominator = 0, then coincide lines
  469. if (Z = 0) and (Ca = 0) and (Cb = 0) then
  470. begin
  471. Result := False;
  472. Exit;
  473. end
  474. else
  475. // if demominator = 0, then parallel lines
  476. if Z = 0 then
  477. begin
  478. Result := False;
  479. Exit;
  480. end;
  481. Ua := Ca / Z;
  482. Ub := Cb / Z;
  483. // if 0<=Ua<=1 and 0<=Ub<=1, then the intersection point is inside intervals
  484. if (0 <= Ua) and (Ua <= 1) and (0 <= Ub) and (Ub <= 1) then
  485. begin
  486. p.X := round(p11.X + (p12.X - p11.X) * Ub);
  487. p.Y := round(p11.Y + (p12.Y - p11.Y) * Ub);
  488. Result := True;
  489. end
  490. // otherwise the intersection point is outside intervals
  491. else
  492. Result := False;
  493. end;
  494. //Intersection of line and circle
  495. function IsLineIntCirlce(CR: Single; CC: TPoint; LP1, LP2: TPoint; var PIL1, PIL2: TPoint): Smallint;
  496. var
  497. d, K, b: Single;
  498. begin
  499. K := (LP1.Y - LP2.Y) / (LP1.X - LP2.X);
  500. b := LP1.Y - K * LP1.X;
  501. //determine decrement of quadratic equation
  502. d := (power((2 * K * b - 2 * CC.X - 2 * CC.Y * K), 2) - (4 + 4 * K * K) * (b * b - cr * cr + CC.X * CC.X + CC.Y * CC.Y - 2 * CC.Y * b));
  503. //if decrement = 0, then no decision and line and circle do not intersect
  504. if (d < 0) then
  505. begin
  506. Result := -1;
  507. PIL1 := point(0, 0);
  508. PIL2 := point(0, 0);
  509. Exit;
  510. end;
  511. //otherwise find roots of quadratic equation
  512. PIL1.X := round((-(2 * K * b - 2 * CC.X - 2 * CC.Y * K) - sqrt(d)) / (2 + 2 * K * K));
  513. PIL2.X := round((-(2 * K * b - 2 * CC.X - 2 * CC.Y * K) + sqrt(d)) / (2 + 2 * K * K));
  514. //if abscissas of points are coinside, then the intersection is only in one point
  515. //and line and circle have a point of contact
  516. if (PIL1.X = PIL2.X) then
  517. begin
  518. Result := 0;
  519. PIL1.Y := round(K * PIL1.X + b);
  520. PIL2 := PIL1;
  521. Exit;
  522. end;
  523. //otherwise find ordinates of intersection points
  524. PIL1.Y := round(K * PIL1.X + b);
  525. PIL2.Y := round(K * PIL2.X + b);
  526. Result := 1;
  527. end;
  528. constructor TgxGizmoExUIArrowLine.Create(AOwner: TComponent);
  529. begin
  530. FNoZWrite := True;
  531. inherited;
  532. end;
  533. procedure TgxGizmoExUIArrowLine.BuildList(var rci: TgxRenderContextInfo);
  534. begin
  535. if FNoZWrite then
  536. rci.gxStates.Disable(stDepthTest)
  537. else
  538. rci.gxStates.Enable(stDepthTest);
  539. inherited;
  540. end;
  541. constructor TgxGizmoExUIDisk.Create(AOwner: TComponent);
  542. begin
  543. FNoZWrite := True;
  544. inherited;
  545. end;
  546. procedure TgxGizmoExUIDisk.BuildList(var rci: TgxRenderContextInfo);
  547. begin
  548. if FNoZWrite then
  549. rci.gxStates.Disable(stDepthTest)
  550. else
  551. rci.gxStates.Enable(stDepthTest);
  552. inherited;
  553. end;
  554. constructor TgxGizmoExUISphere.Create(AOwner: TComponent);
  555. begin
  556. FNoZWrite := True;
  557. inherited;
  558. end;
  559. procedure TgxGizmoExUISphere.BuildList(var rci: TgxRenderContextInfo);
  560. begin
  561. if FNoZWrite then
  562. rci.gxStates.Disable(stDepthTest)
  563. else
  564. rci.gxStates.Enable(stDepthTest);
  565. inherited;
  566. end;
  567. constructor TgxGizmoExUIPolyGon.Create(AOwner: TComponent);
  568. begin
  569. FNoZWrite := True;
  570. inherited;
  571. end;
  572. procedure TgxGizmoExUIPolyGon.BuildList(var rci: TgxRenderContextInfo);
  573. begin
  574. if FNoZWrite then
  575. rci.gxStates.Disable(stDepthTest)
  576. else
  577. rci.gxStates.Enable(stDepthTest);
  578. inherited;
  579. end;
  580. constructor TgxGizmoExUIFrustrum.Create(AOwner: TComponent);
  581. begin
  582. FNoZWrite := True;
  583. inherited;
  584. end;
  585. procedure TgxGizmoExUIFrustrum.BuildList(var rci: TgxRenderContextInfo);
  586. begin
  587. if FNoZWrite then
  588. rci.gxStates.Disable(stDepthTest)
  589. else
  590. rci.gxStates.Enable(stDepthTest);
  591. inherited;
  592. end;
  593. constructor TgxGizmoExUITorus.Create(AOwner: TComponent);
  594. begin
  595. FNoZWrite := True;
  596. inherited;
  597. end;
  598. procedure TgxGizmoExUITorus.BuildList(var rci: TgxRenderContextInfo);
  599. begin
  600. if FNoZWrite then
  601. rci.gxStates.Disable(stDepthTest)
  602. else
  603. rci.gxStates.Enable(stDepthTest);
  604. inherited;
  605. end;
  606. constructor TgxGizmoExUILines.Create(AOwner: TComponent);
  607. begin
  608. FNoZWrite := True;
  609. inherited;
  610. end;
  611. procedure TgxGizmoExUILines.BuildList(var rci: TgxRenderContextInfo);
  612. begin
  613. if FNoZWrite then
  614. rci.gxStates.Disable(stDepthTest)
  615. else
  616. rci.gxStates.Enable(stDepthTest);
  617. inherited;
  618. end;
  619. constructor TgxGizmoExUIFlatText.Create(AOwner: TComponent);
  620. begin
  621. FNoZWrite := True;
  622. inherited;
  623. end;
  624. procedure TgxGizmoExUIFlatText.BuildList(var rci: TgxRenderContextInfo);
  625. begin
  626. if FNoZWrite then
  627. rci.gxStates.Disable(stDepthTest)
  628. else
  629. rci.gxStates.Enable(stDepthTest);
  630. inherited;
  631. end;
  632. //------------------------------------------------------------------------------
  633. constructor TgxGizmoEx.Create(aOwner: TComponent);
  634. var
  635. I: Integer;
  636. begin
  637. inherited Create(aOwner);
  638. FHistory := TgxGizmoExActionHistoryCollection.Create(Self, TgxGizmoExActionHistoryItem);
  639. FPickMode := pmGetPickedObjects;
  640. FRotationCoef := 1;
  641. FMoveCoef := 0.1;
  642. FScaleCoef := 0.1;
  643. FBoundingBoxColor := TgxColor.Create(Self);
  644. FBoundingBoxColor.Color := clrWhite;
  645. FSelectionRegionColor := TgxColor.Create(Self);
  646. SelectionRegionColor.Color := clrBlack;
  647. FSelectedColor := TgxColor.Create(Self);
  648. FSelectedColor.Color := clrYellow;
  649. FVisibleInfoLabelsColor := TgxColor.Create(Self);
  650. FVisibleInfoLabelsColor.Color := clrYellow;
  651. FVisibleInfoLabelsColorChanged := False;
  652. FUIBaseGizmo := TgxDummyCube.Create(Self);
  653. //BoundingBoxes...
  654. FInternalRender := TgxDirectOpenGL(FUIBaseGizmo.AddNewChild(TgxDirectOpenGL));
  655. FInternalRender.OnRender := InternalRender;
  656. FUIRootHelpers := TgxDummyCube(FUIBaseGizmo.AddNewChild(TgxDummyCube));
  657. //Canvas...
  658. FInterfaceRender := TgxDirectOpenGL(FUIBaseGizmo.AddNewChild(TgxDirectOpenGL));
  659. FInterfaceRender.OnRender := InterfaceRender;
  660. FSelectedObjects := TgxPickList.Create(psMinDepth);
  661. //For None
  662. FUIRootSelect := FUIRootHelpers.AddNewChild(TgxDummyCube); // for None
  663. FUIRootMovement := FUIRootHelpers.AddNewChild(TgxDummyCube);
  664. FUIRootRotate := FUIRootHelpers.AddNewChild(TgxDummyCube);
  665. FUIRootScale := FUIRootHelpers.AddNewChild(TgxDummyCube);
  666. FUIRootAxisLabel := FUIRootHelpers.AddNewChild(TgxDummyCube);
  667. FUIRootVisibleInfoLabels := FUIRootHelpers.AddNewChild(TgxDummyCube);
  668. FUISelectLineX := TgxGizmoExUILines(FUIRootSelect.addnewChild(TgxGizmoExUILines));
  669. with FUISelectLineX do
  670. begin
  671. LineColor.Color := clrRed;
  672. LineWidth := 1;
  673. NodesAspect := lnaInvisible;
  674. AddNode(0, 0, 0);
  675. AddNode(1, 0, 0);
  676. AddNode(0.9, 0, -0.1);
  677. addNode(1, 0, 0);
  678. addNode(0.9, 0, 0.1);
  679. end;
  680. FUISelectLineY := TgxGizmoExUILines(FUIRootSelect.addnewChild(TgxGizmoExUILines));
  681. with FUISelectLineY do
  682. begin
  683. LineColor.Color := clrLime;
  684. LineWidth := 1;
  685. NodesAspect := lnaInvisible;
  686. AddNode(0, 0, 0);
  687. AddNode(0, 1, 0);
  688. AddNode(0.1, 0.9, 0);
  689. addNode(0, 1, 0);
  690. addNode(-0.1, 0.9, 0);
  691. end;
  692. FUISelectLineZ := TgxGizmoExUILines(FUIRootSelect.addnewChild(TgxGizmoExUILines));
  693. with FUISelectLineZ do
  694. begin
  695. LineColor.Color := clrBlue;
  696. LineWidth := 1;
  697. NodesAspect := lnaInvisible;
  698. AddNode(0, 0, 0);
  699. AddNode(0, 0, 1);
  700. AddNode(0.1, 0, 0.9);
  701. addNode(0, 0, 1);
  702. addNode(-0.1, 0, 0.9);
  703. end;
  704. //For movement
  705. FUIMovementLineX := TgxGizmoExUILines(FUIRootMovement.addnewChild(TgxGizmoExUILines));
  706. with FUIMovementLineX do
  707. begin
  708. LineColor.Color := clrRed;
  709. LineWidth := 1;
  710. NodesAspect := lnaInvisible;
  711. AddNode(0.2, 0, 0);
  712. AddNode(1, 0, 0);
  713. // Raycast pickable object
  714. FUIICMovementLineX := TgxGizmoExUIFrustrum(AddNewChild(TgxGizmoExUIFrustrum));
  715. with FUIICMovementLineX do
  716. begin
  717. Material.MaterialOptions := [moNoLighting];
  718. Material.BlendingMode := bmTransparency;
  719. Material.FrontProperties.Diffuse.Color := clrYellow;
  720. Material.FrontProperties.Diffuse.Alpha := 0;
  721. Up.SetVector(1, 0, 0);
  722. Height := 0.8;
  723. ApexHeight := 8;
  724. BaseDepth := 0.15;
  725. BaseWidth := 0.15;
  726. position.SetPoint(0.6, 0, 0);
  727. end;
  728. FUIMovementArrowX := TgxGizmoExUIArrowLine(addnewChild(TgxGizmoExUIArrowLine));
  729. with FUIMovementArrowX do
  730. begin
  731. Material.MaterialOptions := [moNoLighting];
  732. Material.BlendingMode := bmTransparency;
  733. Material.FrontProperties.Diffuse.Color := clrRed;
  734. TurnAngle := 90;
  735. Height := 0.3;
  736. Position.X := 1;
  737. Slices := 8;
  738. Stacks := 2;
  739. TopRadius := 0;
  740. TopArrowHeadHeight := 0;
  741. TopArrowHeadRadius := 0;
  742. BottomArrowHeadHeight := 0.1;
  743. BottomRadius := 0.06;
  744. end;
  745. end;
  746. FUIMovementLineY := TgxGizmoExUILines(FUIRootMovement.addnewChild(TgxGizmoExUILines));
  747. with FUIMovementLineY do
  748. begin
  749. LineColor.Color := clrLime;
  750. LineWidth := 1;
  751. NodesAspect := lnaInvisible;
  752. AddNode(0, 0.2, 0);
  753. AddNode(0, 1, 0);
  754. FUIMovementArrowY := TgxGizmoExUIArrowLine(addnewChild(TgxGizmoExUIArrowLine));
  755. with FUIMovementArrowY do
  756. begin
  757. Material.MaterialOptions := [moNoLighting];
  758. Material.BlendingMode := bmTransparency;
  759. Material.FrontProperties.Diffuse.Color := clrLime;
  760. PitchAngle := 90;
  761. Height := 0.3;
  762. Position.Y := 1;
  763. Slices := 8;
  764. Stacks := 2;
  765. TopRadius := 0;
  766. TopArrowHeadHeight := 0;
  767. TopArrowHeadRadius := 0;
  768. BottomArrowHeadHeight := 0.1;
  769. BottomRadius := 0.06;
  770. end;
  771. // Raycast pickable object
  772. FUIICMovementLineY := TgxGizmoExUIFrustrum(AddNewChild(TgxGizmoExUIFrustrum));
  773. with FUIICMovementLineY do
  774. begin
  775. Material.MaterialOptions := [moNoLighting];
  776. Material.BlendingMode := bmTransparency;
  777. Material.FrontProperties.Diffuse.Alpha := 0;
  778. Up.SetVector(0, 1, 0);
  779. Height := 0.8;
  780. ApexHeight := 8;
  781. BaseDepth := 0.15;
  782. BaseWidth := 0.15;
  783. position.SetPoint(0, 0.6, 0);
  784. end;
  785. end;
  786. FUIMovementLineZ := TgxGizmoExUILines(FUIRootMovement.addnewChild(TgxGizmoExUILines));
  787. with FUIMovementLineZ do
  788. begin
  789. LineColor.Color := clrBlue;
  790. LineWidth := 1;
  791. NodesAspect := lnaInvisible;
  792. AddNode(0, 0, 0.2);
  793. AddNode(0, 0, 1);
  794. FUIMovementArrowZ := TgxGizmoExUIArrowLine(addnewChild(TgxGizmoExUIArrowLine));
  795. with FUIMovementArrowZ do
  796. begin
  797. Material.MaterialOptions := [moNoLighting];
  798. Material.BlendingMode := bmTransparency;
  799. Material.FrontProperties.Diffuse.Color := clrBlue;
  800. RollAngle := 90;
  801. Height := 0.3;
  802. Position.Z := 1;
  803. Slices := 8;
  804. Stacks := 2;
  805. TopRadius := 0;
  806. TopArrowHeadHeight := 0;
  807. TopArrowHeadRadius := 0;
  808. BottomArrowHeadHeight := 0.1;
  809. BottomRadius := 0.06;
  810. end;
  811. // Raycast pickable object
  812. FUIICMovementLineZ := TgxGizmoExUIFrustrum(AddNewChild(TgxGizmoExUIFrustrum));
  813. with FUIICMovementLineZ do
  814. begin
  815. Material.MaterialOptions := [moNoLighting];
  816. Material.BlendingMode := bmTransparency;
  817. Material.FrontProperties.Diffuse.Alpha := 0;
  818. Up.SetVector(0, 0, 1);
  819. Height := 0.8;
  820. ApexHeight := 8;
  821. BaseDepth := 0.15;
  822. BaseWidth := 0.15;
  823. position.SetPoint(0, 0, 0.6);
  824. end;
  825. end;
  826. FUIMovementLineXY := TgxGizmoExUILines(FUIRootMovement.addnewChild(TgxGizmoExUILines));
  827. with FUIMovementLineXY do
  828. begin
  829. LineWidth := 1;
  830. Options := [loUseNodeColorForLines];
  831. NodesAspect := lnaInvisible;
  832. SplineMode := lsmSegments;
  833. addNode(0, 0.4, 0);
  834. TgxLinesNode(Nodes[0]).Color.color := clrLime;
  835. addNode(0.4, 0.4, 0);
  836. TgxLinesNode(Nodes[1]).Color.color := clrLime;
  837. addNode(0.4, 0.4, 0);
  838. TgxLinesNode(Nodes[2]).Color.color := clrRed;
  839. addNode(0.4, 0, 0);
  840. TgxLinesNode(Nodes[3]).Color.color := clrRed;
  841. // Raycast pickable object
  842. FUIMovementPlaneXY := TgxGizmoExUIPolyGon(addnewChild(TgxGizmoExUIPolyGon));
  843. with FUIMovementPlaneXY do
  844. begin
  845. Material.MaterialOptions := [moNoLighting];
  846. Material.BlendingMode := bmTransparency;
  847. Material.FrontProperties.Diffuse.Color := clrYellow;
  848. Material.FrontProperties.Diffuse.Alpha := 0.01;
  849. addNode(0.01, 0.39, 0);
  850. addNode(0.39, 0.39, 0);
  851. addNode(0.39, 0.01, 0);
  852. addNode(0.01, 0.01, 0);
  853. end;
  854. FUIICMovementLineXY := TgxGizmoExUIFrustrum(AddNewChild(TgxGizmoExUIFrustrum));
  855. with FUIICMovementLineXY do
  856. begin
  857. Material.MaterialOptions := [moNoLighting];
  858. Material.BlendingMode := bmTransparency;
  859. Material.FrontProperties.Diffuse.Alpha := 0;
  860. Up.SetVector(1, 0, 0);
  861. Height := 0.35;
  862. ApexHeight := 8;
  863. BaseDepth := 0.1;
  864. BaseWidth := 0.35;
  865. position.SetPoint(0.25, 0.25, 0);
  866. end;
  867. end;
  868. FUIMovementLineXZ := TgxGizmoExUILines(FUIRootMovement.addnewChild(TgxGizmoExUILines));
  869. with FUIMovementLineXZ do
  870. begin
  871. LineWidth := 1;
  872. Options := [loUseNodeColorForLines];
  873. NodesAspect := lnaInvisible;
  874. SplineMode := lsmSegments;
  875. addNode(0.4, 0, 0);
  876. TgxLinesNode(Nodes[0]).Color.color := clrRed;
  877. addNode(0.4, 0, 0.4);
  878. TgxLinesNode(Nodes[1]).Color.color := clrRed;
  879. addNode(0.4, 0, 0.4);
  880. TgxLinesNode(Nodes[2]).Color.color := clrBlue;
  881. addNode(0, 0, 0.4);
  882. TgxLinesNode(Nodes[3]).Color.color := clrBlue;
  883. FUIMovementPlaneXZ := TgxGizmoExUIPolyGon(addnewChild(TgxGizmoExUIPolyGon));
  884. with FUIMovementPlaneXZ do
  885. begin
  886. Material.MaterialOptions := [moNoLighting];
  887. Material.BlendingMode := bmTransparency;
  888. Material.FrontProperties.Diffuse.Color := clrYellow;
  889. Material.FrontProperties.Diffuse.Alpha := 0.01;
  890. addNode(0.39, 0, 0.01);
  891. addNode(0.39, 0, 0.39);
  892. addNode(0.01, 0, 0.39);
  893. addNode(0, 0, 0.01);
  894. end;
  895. // Raycast pickable object
  896. FUIICMovementLineXZ := TgxGizmoExUIFrustrum(AddNewChild(TgxGizmoExUIFrustrum));
  897. with FUIICMovementLineXZ do
  898. begin
  899. Material.MaterialOptions := [moNoLighting];
  900. Material.BlendingMode := bmTransparency;
  901. Material.FrontProperties.Diffuse.Alpha := 0;
  902. pitchAngle := 90;
  903. Height := 0.35;
  904. ApexHeight := 8;
  905. BaseDepth := 0.1;
  906. BaseWidth := 0.35;
  907. position.SetPoint(0.25, 0, 0.25);
  908. end;
  909. end;
  910. FUIMovementLineYZ := TgxGizmoExUILines(FUIRootMovement.addnewChild(TgxGizmoExUILines));
  911. with FUIMovementLineYZ do
  912. begin
  913. LineWidth := 1;
  914. Options := [loUseNodeColorForLines];
  915. NodesAspect := lnaInvisible;
  916. SplineMode := lsmSegments;
  917. addNode(0, 0, 0.4);
  918. TgxLinesNode(Nodes[0]).Color.color := clrBlue;
  919. addNode(0, 0.4, 0.4);
  920. TgxLinesNode(Nodes[1]).Color.color := clrBlue;
  921. addNode(0, 0.4, 0.4);
  922. TgxLinesNode(Nodes[2]).Color.color := clrLime;
  923. addNode(0, 0.4, 0);
  924. TgxLinesNode(Nodes[3]).Color.color := clrLime;
  925. FUIMovementPlaneYZ := TgxGizmoExUIPolyGon(addnewChild(TgxGizmoExUIPolyGon));
  926. with FUIMovementPlaneYZ do
  927. begin
  928. Material.MaterialOptions := [moNoLighting];
  929. Material.BlendingMode := bmTransparency;
  930. Material.FrontProperties.Diffuse.Color := clrYellow;
  931. Material.FrontProperties.Diffuse.Alpha := 0.01;
  932. addNode(0, 0.01, 0.39);
  933. addNode(0, 0.39, 0.39);
  934. addNode(0, 0.39, 0);
  935. addNode(0, 0.01, 0);
  936. end;
  937. // Raycast pickable object
  938. FUIICMovementLineYZ := TgxGizmoExUIFrustrum(AddNewChild(TgxGizmoExUIFrustrum));
  939. with FUIICMovementLineYZ do
  940. begin
  941. Material.MaterialOptions := [moNoLighting];
  942. Material.BlendingMode := bmTransparency;
  943. Material.FrontProperties.Diffuse.Alpha := 0;
  944. Up.SetVector(0, 0, 1);
  945. Height := 0.35;
  946. ApexHeight := 8;
  947. BaseDepth := 0.1;
  948. BaseWidth := 0.35;
  949. position.SetPoint(0, 0.25, 0.25);
  950. end;
  951. end;
  952. //Rotate
  953. FUIRotateLineXY := TgxGizmoExUILines(FUIRootRotate.addnewChild(TgxGizmoExUILines));
  954. with FUIRotateLineXY do
  955. begin
  956. LineColor.Color := clrGray50;
  957. SplineMode := lsmCubicSpline;
  958. NodesAspect := lnaInvisible;
  959. LineWidth := 1;
  960. Nodes.AddXYArc(1, 1, 0, 360, 24, AffineVectorMake(0, 0, 0));
  961. FUIRotateDiskXY := TgxGizmoExUIDisk(addnewChild(TgxGizmoExUIDisk));
  962. with FUIRotateDiskXY do
  963. begin
  964. OuterRadius := 1;
  965. Slices := 18;
  966. with Material do
  967. begin
  968. MaterialOptions := [moNoLighting];
  969. BlendingMode := bmTransparency;
  970. FrontProperties.Diffuse.Color := clrGray50;
  971. FrontProperties.Diffuse.Alpha := 0;
  972. end;
  973. end;
  974. FUIICRotateSphereXY := TgxGizmoExUISphere(addnewChild(TgxGizmoExUISphere));
  975. with FUIICRotateSphereXY do
  976. begin
  977. Radius := 1;
  978. Stop := 180;
  979. Slices := 18;
  980. TurnAngle := -90;
  981. with Material do
  982. begin
  983. MaterialOptions := [moNoLighting];
  984. BlendingMode := bmTransparency;
  985. FrontProperties.Diffuse.Color := clryellow;
  986. FrontProperties.Diffuse.Alpha := 0;
  987. end;
  988. end;
  989. end;
  990. FUIRotateLineXZ := TgxGizmoExUILines(FUIRootRotate.addnewChild(TgxGizmoExUILines));
  991. with FUIRotateLineXZ do
  992. begin
  993. LineColor.Color := clrGray75;
  994. SplineMode := lsmCubicSpline;
  995. NodesAspect := lnaInvisible;
  996. LineWidth := 1;
  997. Nodes.AddXYArc(1.3, 1.3, 0, 360, 24, AffineVectorMake(0, 0, 0));
  998. FUIICRotateTorusXZ := TgxGizmoExUITorus(addnewChild(TgxGizmoExUITorus));
  999. with FUIICRotateTorusXZ do
  1000. begin
  1001. Rings := 18;
  1002. Sides := 0;
  1003. MajorRadius := 1.3;
  1004. MinorRadius := 0.07;
  1005. with material do
  1006. begin
  1007. FaceCulling := fcNoCull;
  1008. MaterialOptions := [moNoLighting];
  1009. BlendingMode := bmTransparency;
  1010. FrontProperties.Diffuse.Color := clrYellow;
  1011. FrontProperties.Diffuse.Alpha := 0;
  1012. end;
  1013. end;
  1014. end;
  1015. FUIRotateLineX := TgxGizmoExUILines(FUIRootRotate.addnewChild(TgxGizmoExUILines));
  1016. with FUIRotateLineX do
  1017. begin
  1018. Options := [loUseNodeColorForLines];
  1019. // To fix transparency issues
  1020. lineColor.Alpha := 0.1;
  1021. Nodecolor.Color := clrred;
  1022. Nodecolor.Alpha := 0.1;
  1023. TurnAngle := 90;
  1024. SplineMode := lsmCubicSpline;
  1025. NodesAspect := lnaInvisible;
  1026. LineWidth := 1;
  1027. Nodes.AddXYArc(1, 1, 0, 360, 24, AffineVectorMake(0, 0, 0));
  1028. for I := 0 to 24 do
  1029. begin
  1030. TgxLinesNode(Nodes[I]).Color.color := clrred;
  1031. end;
  1032. end;
  1033. FUIRotateLineArrowX := TgxGizmoExUILines(FUIRootRotate.addnewChild(TgxGizmoExUILines));
  1034. with FUIRotateLineArrowX do
  1035. begin
  1036. LineColor.Color := clrRed;
  1037. LineWidth := 1;
  1038. NodesAspect := lnaInvisible;
  1039. AddNode(0, 0, 0);
  1040. AddNode(0.4, 0, 0);
  1041. end;
  1042. FUIRotateDiskX := TgxGizmoExUIDisk(FUIRootRotate.addnewChild(TgxGizmoExUIDisk));
  1043. with FUIRotateDiskX do
  1044. begin
  1045. OuterRadius := 1.01;
  1046. Slices := 18;
  1047. sweepangle := 10;
  1048. StartAngle := 0;
  1049. TurnAngle := 90;
  1050. with Material do
  1051. begin
  1052. FaceCulling := fcNoCull;
  1053. MaterialOptions := [moNoLighting];
  1054. BlendingMode := bmTransparency;
  1055. FrontProperties.Diffuse.Color := clrred;
  1056. FrontProperties.Diffuse.Alpha := 0;
  1057. end;
  1058. end;
  1059. FUIRotateDiskX2 := TgxGizmoExUIDisk(FUIRootRotate.addnewChild(TgxGizmoExUIDisk));
  1060. with FUIRotateDiskX2 do
  1061. begin
  1062. OuterRadius := 1.01;
  1063. Slices := 18;
  1064. sweepangle := 10;
  1065. StartAngle := 0;
  1066. TurnAngle := 90;
  1067. with Material do
  1068. begin
  1069. FaceCulling := fcNoCull;
  1070. MaterialOptions := [moNoLighting];
  1071. BlendingMode := bmTransparency;
  1072. FrontProperties.Diffuse.Color := clrred;
  1073. FrontProperties.Diffuse.Alpha := 0;
  1074. end;
  1075. end;
  1076. FUIICRotateTorusX := TgxGizmoExUITorus(FUIRootRotate.addnewChild(TgxGizmoExUITorus));
  1077. with FUIICRotateTorusX do
  1078. begin
  1079. Rings := 18;
  1080. Sides := 0;
  1081. MajorRadius := 1;
  1082. MinorRadius := 0.07;
  1083. TurnAngle := 90;
  1084. with material do
  1085. begin
  1086. FaceCulling := fcNoCull;
  1087. MaterialOptions := [moNoLighting];
  1088. BlendingMode := bmTransparency;
  1089. FrontProperties.Diffuse.Color := clrYellow;
  1090. FrontProperties.Diffuse.Alpha := 0;
  1091. end;
  1092. end;
  1093. FUIRotateLineY := TgxGizmoExUILines(FUIRootRotate.addnewChild(TgxGizmoExUILines));
  1094. with FUIRotateLineY do
  1095. begin
  1096. Options := [loUseNodeColorForLines];
  1097. // To fix transparency issues
  1098. lineColor.Alpha := 0.1;
  1099. Nodecolor.Color := clrLime;
  1100. Nodecolor.Alpha := 0.1;
  1101. SplineMode := lsmCubicSpline;
  1102. NodesAspect := lnaInvisible;
  1103. LineWidth := 1;
  1104. Nodes.AddXYArc(1, 1, 0, 360, 24, AffineVectorMake(0, 0, 0));
  1105. PitchAngle := 90;
  1106. for I := 0 to 24 do
  1107. begin
  1108. TgxLinesNode(Nodes[I]).Color.color := clrLime;
  1109. end;
  1110. end;
  1111. FUIRotateLineArrowY := TgxGizmoExUILines(FUIRootRotate.addnewChild(TgxGizmoExUILines));
  1112. with FUIRotateLineArrowY do
  1113. begin
  1114. LineColor.Color := clrLime;
  1115. LineWidth := 1;
  1116. NodesAspect := lnaInvisible;
  1117. AddNode(0, 0, 0);
  1118. AddNode(0, 0.4, 0);
  1119. end;
  1120. FUIRotateDiskY := TgxGizmoExUIDisk(FUIRootRotate.addnewChild(TgxGizmoExUIDisk));
  1121. with FUIRotateDiskY do
  1122. begin
  1123. OuterRadius := 1;
  1124. Slices := 18;
  1125. sweepangle := 20;
  1126. startangle := 0;
  1127. PitchAngle := 90;
  1128. with Material do
  1129. begin
  1130. FaceCulling := fcNoCull;
  1131. MaterialOptions := [moNoLighting];
  1132. BlendingMode := bmTransparency;
  1133. FrontProperties.Diffuse.Color := clrLime;
  1134. FrontProperties.Diffuse.Alpha := 0;
  1135. end;
  1136. end;
  1137. FUIRotateDiskY2 := TgxGizmoExUIDisk(FUIRootRotate.addnewChild(TgxGizmoExUIDisk));
  1138. with FUIRotateDiskY2 do
  1139. begin
  1140. OuterRadius := 1;
  1141. Slices := 18;
  1142. sweepangle := 20;
  1143. startangle := 0;
  1144. PitchAngle := 90;
  1145. with Material do
  1146. begin
  1147. FaceCulling := fcNoCull;
  1148. MaterialOptions := [moNoLighting];
  1149. BlendingMode := bmTransparency;
  1150. FrontProperties.Diffuse.Color := clrLime;
  1151. FrontProperties.Diffuse.Alpha := 0;
  1152. end;
  1153. end;
  1154. FUIICRotateTorusY := TgxGizmoExUITorus(FUIRootRotate.addnewChild(TgxGizmoExUITorus));
  1155. with FUIICRotateTorusY do
  1156. begin
  1157. Rings := 18;
  1158. Sides := 0;
  1159. MajorRadius := 1;
  1160. MinorRadius := 0.07;
  1161. PitchAngle := 90;
  1162. with material do
  1163. begin
  1164. FaceCulling := fcNoCull;
  1165. MaterialOptions := [moNoLighting];
  1166. BlendingMode := bmTransparency;
  1167. FrontProperties.Diffuse.Color := clrYellow;
  1168. FrontProperties.Diffuse.Alpha := 0;
  1169. end;
  1170. end;
  1171. FUIRotateLineZ := TgxGizmoExUILines(FUIRootRotate.addnewChild(TgxGizmoExUILines));
  1172. with FUIRotateLineZ do
  1173. begin
  1174. Options := [loUseNodeColorForLines];
  1175. //to correct transparency problem
  1176. lineColor.Alpha := 0.1;
  1177. Nodecolor.Color := clrBlue;
  1178. Nodecolor.Alpha := 0.1;
  1179. SplineMode := lsmCubicSpline;
  1180. NodesAspect := lnaInvisible;
  1181. LineWidth := 1;
  1182. Nodes.AddXYArc(1, 1, 0, 360, 24, AffineVectorMake(0, 0, 0));
  1183. for I := 0 to 24 do
  1184. begin
  1185. TgxLinesNode(Nodes[I]).Color.color := clrBlue;
  1186. end;
  1187. end;
  1188. FUIRotateLineArrowZ := TgxGizmoExUILines(FUIRootRotate.addnewChild(TgxGizmoExUILines));
  1189. with FUIRotateLineArrowZ do
  1190. begin
  1191. LineColor.Color := clrBlue;
  1192. LineWidth := 1;
  1193. NodesAspect := lnaInvisible;
  1194. AddNode(0, 0, 0);
  1195. AddNode(0, 0, 0.4);
  1196. end;
  1197. FUIRotateDiskZ := TgxGizmoExUIDisk(FUIRootRotate.addnewChild(TgxGizmoExUIDisk));
  1198. with FUIRotateDiskZ do
  1199. begin
  1200. OuterRadius := 1;
  1201. Slices := 18;
  1202. SweepAngle := 10;
  1203. StartAngle := 0;
  1204. with Material do
  1205. begin
  1206. FaceCulling := fcNoCull;
  1207. MaterialOptions := [moNoLighting];
  1208. BlendingMode := bmTransparency;
  1209. FrontProperties.Diffuse.Color := clrBlue;
  1210. BackProperties.Diffuse.Color := clrBlue;
  1211. FrontProperties.Diffuse.Alpha := 0;
  1212. end;
  1213. end;
  1214. FUIRotateDiskZ2 := TgxGizmoExUIDisk(FUIRootRotate.addnewChild(TgxGizmoExUIDisk));
  1215. with FUIRotateDiskZ2 do
  1216. begin
  1217. OuterRadius := 1;
  1218. Slices := 18;
  1219. SweepAngle := 10;
  1220. StartAngle := 0;
  1221. with Material do
  1222. begin
  1223. FaceCulling := fcNoCull;
  1224. MaterialOptions := [moNoLighting];
  1225. BlendingMode := bmTransparency;
  1226. FrontProperties.Diffuse.Color := clrBlue;
  1227. FrontProperties.Diffuse.Alpha := 0;
  1228. end;
  1229. end;
  1230. FUIICRotateTorusZ := TgxGizmoExUITorus(FUIRootRotate.addnewChild(TgxGizmoExUITorus));
  1231. with FUIICRotateTorusZ do
  1232. begin
  1233. Rings := 18;
  1234. Sides := 0;
  1235. MajorRadius := 1;
  1236. MinorRadius := 0.07;
  1237. with material do
  1238. begin
  1239. FaceCulling := fcNoCull;
  1240. MaterialOptions := [moNoLighting];
  1241. BlendingMode := bmTransparency;
  1242. FrontProperties.Diffuse.Color := clrYellow;
  1243. FrontProperties.Diffuse.Alpha := 0;
  1244. end;
  1245. end;
  1246. FUIRootRotateAxisLabel := FUIRootRotate.AddNewChild(TgxDummyCube);
  1247. FUIRotateAxisLabelX := TgxGizmoExUIFlatText(FUIRootRotateAxisLabel.AddNewChild(TgxGizmoExUIFlatText));
  1248. with FUIRotateAxisLabelX do
  1249. begin
  1250. ModulateColor.Color := clrRed;
  1251. Alignment := taCenter;
  1252. Layout := tlCenter;
  1253. Options := Options + [ftoTwoSided];
  1254. Position.X := 0.5;
  1255. Scale.X := 0.010;
  1256. Scale.Y := 0.010;
  1257. Text := 'X';
  1258. end;
  1259. FUIRotateAxisLabelY := TgxGizmoExUIFlatText(FUIRootRotateAxisLabel.AddNewChild(TgxGizmoExUIFlatText));
  1260. with FUIRotateAxisLabelY do
  1261. begin
  1262. ModulateColor.Color := clrLime;
  1263. Alignment := taCenter;
  1264. Layout := tlCenter;
  1265. Options := Options + [ftoTwoSided];
  1266. Position.Y := 0.5;
  1267. Scale.X := 0.010;
  1268. Scale.Y := 0.010;
  1269. Text := 'Y';
  1270. end;
  1271. FUIRotateAxisLabelZ := TgxGizmoExUIFlatText(FUIRootRotateAxisLabel.AddNewChild(TgxGizmoExUIFlatText));
  1272. with FUIRotateAxisLabelZ do
  1273. begin
  1274. ModulateColor.Color := clrBlue;
  1275. Alignment := taCenter;
  1276. Layout := tlCenter;
  1277. Options := Options + [ftoTwoSided];
  1278. Position.Z := 0.5;
  1279. Scale.X := 0.010;
  1280. Scale.Y := 0.010;
  1281. Text := 'Z';
  1282. end;
  1283. //for Scale
  1284. FUIScaleLineX := TgxGizmoExUILines(FUIRootScale.addnewChild(TgxGizmoExUILines));
  1285. with FUIScaleLineX do
  1286. begin
  1287. LineColor.Color := clrRed;
  1288. LineWidth := 1;
  1289. NodesAspect := lnaInvisible;
  1290. AddNode(0, 0, 0);
  1291. AddNode(1, 0, 0);
  1292. // Raycast pickable object
  1293. FUIICScaleLineX := TgxGizmoExUIFrustrum(AddNewChild(TgxGizmoExUIFrustrum));
  1294. with FUIICScaleLineX do
  1295. begin
  1296. Material.MaterialOptions := [moNoLighting];
  1297. Material.BlendingMode := bmTransparency;
  1298. Material.FrontProperties.Diffuse.Color := clrYellow;
  1299. Material.FrontProperties.Diffuse.Alpha := 0;
  1300. Up.SetVector(1, 0, 0);
  1301. Height := 0.5;
  1302. ApexHeight := 8;
  1303. BaseDepth := 0.15;
  1304. BaseWidth := 0.15;
  1305. position.SetPoint(0.8, 0, 0);
  1306. end;
  1307. end;
  1308. FUIScaleLineY := TgxGizmoExUILines(FUIRootScale.addnewChild(TgxGizmoExUILines));
  1309. with FUIScaleLineY do
  1310. begin
  1311. LineColor.Color := clrLime;
  1312. LineWidth := 1;
  1313. NodesAspect := lnaInvisible;
  1314. AddNode(0, 0, 0);
  1315. AddNode(0, 1, 0);
  1316. // Raycast pickable object
  1317. FUIICScaleLineY := TgxGizmoExUIFrustrum(AddNewChild(TgxGizmoExUIFrustrum));
  1318. with FUIICScaleLineY do
  1319. begin
  1320. Material.MaterialOptions := [moNoLighting];
  1321. Material.BlendingMode := bmTransparency;
  1322. Material.FrontProperties.Diffuse.Color := clrYellow;
  1323. Material.FrontProperties.Diffuse.Alpha := 0;
  1324. Up.SetVector(0, 1, 0);
  1325. Height := 0.5;
  1326. ApexHeight := 8;
  1327. BaseDepth := 0.15;
  1328. BaseWidth := 0.15;
  1329. position.SetPoint(0, 0.8, 0);
  1330. end;
  1331. end;
  1332. FUIScaleLineZ := TgxGizmoExUILines(FUIRootScale.addnewChild(TgxGizmoExUILines));
  1333. with FUIScaleLineZ do
  1334. begin
  1335. LineColor.Color := clrBlue;
  1336. LineWidth := 1;
  1337. NodesAspect := lnaInvisible;
  1338. AddNode(0, 0, 0);
  1339. AddNode(0, 0, 1);
  1340. // Raycast pickable object
  1341. FUIICScaleLineZ := TgxGizmoExUIFrustrum(AddNewChild(TgxGizmoExUIFrustrum));
  1342. with FUIICScaleLineZ do
  1343. begin
  1344. Material.MaterialOptions := [moNoLighting];
  1345. Material.BlendingMode := bmTransparency;
  1346. Material.FrontProperties.Diffuse.Color := clrYellow;
  1347. Material.FrontProperties.Diffuse.Alpha := 0;
  1348. Up.SetVector(0, 0, 1);
  1349. Height := 0.5;
  1350. ApexHeight := 8;
  1351. BaseDepth := 0.1;
  1352. BaseWidth := 0.1;
  1353. position.SetPoint(0, 0, 0.8);
  1354. end;
  1355. end;
  1356. FUIScaleLineXY := TgxGizmoExUILines(FUIRootScale.addnewChild(TgxGizmoExUILines));
  1357. with FUIScaleLineXY do
  1358. begin
  1359. Options := [loUseNodeColorForLines];
  1360. SplineMode := lsmSegments;
  1361. LineColor.Color := clrRed;
  1362. LineWidth := 1;
  1363. NodesAspect := lnaInvisible;
  1364. AddNode(0, 0.7, 0);
  1365. AddNode(0.35, 0.35, 0);
  1366. TgxLinesNode(Nodes[0]).Color.color := clrLime;
  1367. TgxLinesNode(Nodes[1]).Color.color := clrLime;
  1368. AddNode(0.35, 0.35, 0);
  1369. AddNode(0.7, 0, 0);
  1370. TgxLinesNode(Nodes[2]).Color.color := clrRed;
  1371. TgxLinesNode(Nodes[3]).Color.color := clrRed;
  1372. AddNode(0.5, 0, 0);
  1373. AddNode(0.25, 0.25, 0);
  1374. TgxLinesNode(Nodes[4]).Color.color := clrRed;
  1375. TgxLinesNode(Nodes[5]).Color.color := clrRed;
  1376. AddNode(0.25, 0.25, 0);
  1377. AddNode(0, 0.5, 0);
  1378. TgxLinesNode(Nodes[6]).Color.color := clrLime;
  1379. TgxLinesNode(Nodes[7]).Color.color := clrLime;
  1380. FUIScalePlaneXY := TgxGizmoExUIPolyGon(addnewChild(TgxGizmoExUIPolyGon));
  1381. with FUIScalePlaneXY do
  1382. begin
  1383. with Material do
  1384. begin
  1385. MaterialOptions := [moNoLighting];
  1386. BlendingMode := bmTransparency;
  1387. FrontProperties.Diffuse.Color := clrYellow;
  1388. FrontProperties.Diffuse.Alpha := 0.01;
  1389. end;
  1390. AddNode(0, 0.7, 0);
  1391. AddNode(0.35, 0.35, 0);
  1392. AddNode(0.7, 0, 0);
  1393. AddNode(0.5, 0, 0);
  1394. AddNode(0.25, 0.25, 0);
  1395. AddNode(0, 0.5, 0);
  1396. end;
  1397. // Raycast pickable object
  1398. FUIICScaleLineXY := TgxGizmoExUIFrustrum(AddNewChild(TgxGizmoExUIFrustrum));
  1399. with FUIICScaleLineXY do
  1400. begin
  1401. Material.MaterialOptions := [moNoLighting];
  1402. Material.BlendingMode := bmTransparency;
  1403. Material.FrontProperties.Diffuse.Color := clrYellow;
  1404. Material.FrontProperties.Diffuse.Alpha := 0;
  1405. rollAngle := 45;
  1406. turnAngle := 45;
  1407. Height := 0.8;
  1408. ApexHeight := 8;
  1409. BaseDepth := 0.1;
  1410. BaseWidth := 0.1;
  1411. position.SetPoint(0.3, 0.3, 0);
  1412. end;
  1413. end;
  1414. FUIScaleLineXZ := TgxGizmoExUILines(FUIRootScale.addnewChild(TgxGizmoExUILines));
  1415. with FUIScaleLineXZ do
  1416. begin
  1417. Options := [loUseNodeColorForLines];
  1418. SplineMode := lsmSegments;
  1419. LineColor.Color := clrRed;
  1420. LineWidth := 1;
  1421. NodesAspect := lnaInvisible;
  1422. AddNode(0.7, 0, 0);
  1423. AddNode(0.35, 0, 0.35);
  1424. TgxLinesNode(Nodes[0]).Color.color := clrRed;
  1425. TgxLinesNode(Nodes[1]).Color.color := clrRed;
  1426. AddNode(0.35, 0, 0.35);
  1427. AddNode(0, 0, 0.7);
  1428. TgxLinesNode(Nodes[2]).Color.color := clrBlue;
  1429. TgxLinesNode(Nodes[3]).Color.color := clrBlue;
  1430. AddNode(0, 0, 0.5);
  1431. AddNode(0.25, 0, 0.25);
  1432. TgxLinesNode(Nodes[4]).Color.color := clrBlue;
  1433. TgxLinesNode(Nodes[5]).Color.color := clrBlue;
  1434. AddNode(0.25, 0, 0.25);
  1435. AddNode(0.5, 0, 0);
  1436. TgxLinesNode(Nodes[6]).Color.color := clrRed;
  1437. TgxLinesNode(Nodes[7]).Color.color := clrRed;
  1438. FUIScalePlaneXZ := TgxGizmoExUIPolyGon(addnewChild(TgxGizmoExUIPolyGon));
  1439. with FUIScalePlaneXZ do
  1440. begin
  1441. with Material do
  1442. begin
  1443. MaterialOptions := [moNoLighting];
  1444. BlendingMode := bmTransparency;
  1445. FrontProperties.Diffuse.Color := clrYellow;
  1446. FrontProperties.Diffuse.Alpha := 0;
  1447. end;
  1448. AddNode(0.7, 0, 0);
  1449. AddNode(0.35, 0, 0.35);
  1450. AddNode(0, 0, 0.7);
  1451. AddNode(0, 0, 0.5);
  1452. AddNode(0.25, 0, 0.25);
  1453. AddNode(0.5, 0, 0);
  1454. end;
  1455. // Raycast pickable object
  1456. FUIICScaleLineXZ := TgxGizmoExUIFrustrum(AddNewChild(TgxGizmoExUIFrustrum));
  1457. with FUIICScaleLineXZ do
  1458. begin
  1459. Material.MaterialOptions := [moNoLighting];
  1460. Material.BlendingMode := bmTransparency;
  1461. Material.FrontProperties.Diffuse.Color := clrYellow;
  1462. Material.FrontProperties.Diffuse.Alpha := 0;
  1463. turnAngle := -45;
  1464. pitchAngle := 90;
  1465. Height := 0.8;
  1466. ApexHeight := 8;
  1467. BaseDepth := 0.1;
  1468. BaseWidth := 0.1;
  1469. position.SetPoint(0.3, 0, 0.3);
  1470. end;
  1471. end;
  1472. FUIScaleLineYZ := TgxGizmoExUILines(FUIRootScale.addnewChild(TgxGizmoExUILines));
  1473. with FUIScaleLineYZ do
  1474. begin
  1475. Options := [loUseNodeColorForLines];
  1476. SplineMode := lsmSegments;
  1477. LineColor.Color := clrRed;
  1478. LineWidth := 1;
  1479. NodesAspect := lnaInvisible;
  1480. AddNode(0, 0.7, 0);
  1481. AddNode(0, 0.35, 0.35);
  1482. TgxLinesNode(Nodes[0]).Color.color := clrLime;
  1483. TgxLinesNode(Nodes[1]).Color.color := clrLime;
  1484. AddNode(0, 0.35, 0.35);
  1485. AddNode(0, 0, 0.7);
  1486. TgxLinesNode(Nodes[2]).Color.color := clrBlue;
  1487. TgxLinesNode(Nodes[3]).Color.color := clrBlue;
  1488. AddNode(0, 0, 0.5);
  1489. AddNode(0, 0.25, 0.25);
  1490. TgxLinesNode(Nodes[4]).Color.color := clrBlue;
  1491. TgxLinesNode(Nodes[5]).Color.color := clrBlue;
  1492. AddNode(0, 0.25, 0.25);
  1493. AddNode(0, 0.5, 0);
  1494. TgxLinesNode(Nodes[6]).Color.color := clrLime;
  1495. TgxLinesNode(Nodes[7]).Color.color := clrLime;
  1496. FUIScalePlaneYZ := TgxGizmoExUIPolyGon(addnewChild(TgxGizmoExUIPolyGon));
  1497. with FUIScalePlaneYZ do
  1498. begin
  1499. with Material do
  1500. begin
  1501. MaterialOptions := [moNoLighting];
  1502. BlendingMode := bmTransparency;
  1503. FrontProperties.Diffuse.Color := clrYellow;
  1504. FrontProperties.Diffuse.Alpha := 0;
  1505. end;
  1506. AddNode(0, 0.7, 0);
  1507. AddNode(0, 0.35, 0.35);
  1508. AddNode(0, 0, 0.7);
  1509. AddNode(0, 0, 0.5);
  1510. AddNode(0, 0.25, 0.25);
  1511. AddNode(0, 0.5, 0);
  1512. end;
  1513. // Raycast pickable object
  1514. FUIICScaleLineYZ := TgxGizmoExUIFrustrum(AddNewChild(TgxGizmoExUIFrustrum));
  1515. with FUIICScaleLineYZ do
  1516. begin
  1517. Material.MaterialOptions := [moNoLighting];
  1518. Material.BlendingMode := bmTransparency;
  1519. Material.FrontProperties.Diffuse.Color := clrYellow;
  1520. Material.FrontProperties.Diffuse.Alpha := 0;
  1521. pitchAngle := 45;
  1522. Height := 0.8;
  1523. ApexHeight := 8;
  1524. BaseDepth := 0.1;
  1525. BaseWidth := 0.1;
  1526. position.SetPoint(0, 0.3, 0.3);
  1527. end;
  1528. end;
  1529. FUIScalePlaneXYZ := TgxGizmoExUIPolyGon(FUIRootScale.addnewChild(TgxGizmoExUIPolyGon));
  1530. with FUIScalePlaneXYZ do
  1531. begin
  1532. with Material do
  1533. begin
  1534. MaterialOptions := [moNoLighting];
  1535. BlendingMode := bmTransparency;
  1536. FrontProperties.Diffuse.Color := clrYellow;
  1537. FrontProperties.Diffuse.Alpha := 0;
  1538. end;
  1539. AddNode(0.5, 0, 0);
  1540. AddNode(0, 0.5, 0);
  1541. AddNode(0, 0, 0.5);
  1542. AddNode(0.5, 0, 0);
  1543. // Raycast pickable object
  1544. FUIICScaleLineXYZ := TgxGizmoExUIFrustrum(FUIRootScale.AddNewChild(TgxGizmoExUIFrustrum));
  1545. with FUIICScaleLineXYZ do
  1546. begin
  1547. Material.MaterialOptions := [moNoLighting];
  1548. Material.BlendingMode := bmTransparency;
  1549. Material.FrontProperties.Diffuse.Color := clrYellow;
  1550. Material.FrontProperties.Diffuse.Alpha := 0;
  1551. turnAngle := -45;
  1552. rollAngle := 35;
  1553. Height := 0.5;
  1554. ApexHeight := 0.6;
  1555. BaseDepth := 0.6;
  1556. BaseWidth := 0.05;
  1557. position.SetPoint(0.15, 0.2, 0.15);
  1558. end;
  1559. end;
  1560. FUIScaleArrowX := TgxGizmoExUISphere(FUIRootScale.addnewChild(TgxGizmoExUISphere));
  1561. with FUIScaleArrowX do
  1562. begin
  1563. Slices := 8;
  1564. Stacks := 2;
  1565. Radius := 0.04;
  1566. Position.X := 1;
  1567. with material do
  1568. begin
  1569. MaterialOptions := [moNoLighting];
  1570. FrontProperties.Diffuse.Color := clrRed;
  1571. end;
  1572. end;
  1573. FUIScaleArrowY := TgxGizmoExUISphere(FUIRootScale.addnewChild(TgxGizmoExUISphere));
  1574. with FUIScaleArrowY do
  1575. begin
  1576. Slices := 8;
  1577. Stacks := 2;
  1578. Radius := 0.04;
  1579. Position.Y := 1;
  1580. with material do
  1581. begin
  1582. //FaceCulling := fcNoCull;
  1583. // FrontProperties.PolygonMode := pmFill;
  1584. // BackProperties.PolygonMode := pmFill;
  1585. MaterialOptions := [moNoLighting];
  1586. FrontProperties.Diffuse.Color := clrLime;
  1587. //FrontProperties.Emission.Color := clrLime;
  1588. end;
  1589. end;
  1590. FUIScaleArrowZ := TgxGizmoExUISphere(FUIRootScale.addnewChild(TgxGizmoExUISphere));
  1591. with FUIScaleArrowZ do
  1592. begin
  1593. Slices := 8;
  1594. Stacks := 2;
  1595. Radius := 0.04;
  1596. Position.Z := 1;
  1597. with material do
  1598. begin
  1599. // FaceCulling := fcNoCull;
  1600. //FrontProperties.PolygonMode := pmFill;
  1601. //BackProperties.PolygonMode := pmFill;
  1602. MaterialOptions := [moNoLighting];
  1603. FrontProperties.Diffuse.Color := clrBlue;
  1604. //FrontProperties.Emission.Color := clrBlue;
  1605. end;
  1606. end;
  1607. //For Axis
  1608. FUIAxisLabelX := TgxGizmoExUIFlatText(FUIRootAxisLabel.AddNewChild(TgxGizmoExUIFlatText));
  1609. with FUIAxisLabelX do
  1610. begin
  1611. ModulateColor.Color := clrRed;
  1612. Alignment := taCenter;
  1613. Layout := tlCenter;
  1614. Options := Options + [ftoTwoSided];
  1615. Position.X := 1.3;
  1616. Scale.X := 0.015;
  1617. Scale.Y := 0.015;
  1618. Text := 'X';
  1619. end;
  1620. FUIAxisLabelY := TgxGizmoExUIFlatText(FUIRootAxisLabel.AddNewChild(TgxGizmoExUIFlatText));
  1621. with FUIAxisLabelY do
  1622. begin
  1623. ModulateColor.Color := clrLime;
  1624. Alignment := taCenter;
  1625. Layout := tlCenter;
  1626. Options := Options + [ftoTwoSided];
  1627. Position.Y := 1.3;
  1628. Scale.X := 0.015;
  1629. Scale.Y := 0.015;
  1630. Text := 'Y';
  1631. end;
  1632. FUIAxisLabelZ := TgxGizmoExUIFlatText(FUIRootAxisLabel.AddNewChild(TgxGizmoExUIFlatText));
  1633. with FUIAxisLabelZ do
  1634. begin
  1635. ModulateColor.Color := clrBlue;
  1636. Alignment := taCenter;
  1637. Layout := tlCenter;
  1638. Options := Options + [ftoTwoSided];
  1639. Position.Z := 1.3;
  1640. Scale.X := 0.015;
  1641. Scale.Y := 0.015;
  1642. Text := 'Z';
  1643. end;
  1644. FUIVisibleInfoLabels := TgxGizmoExUIFlatText(FUIRootVisibleInfoLabels.AddNewChild(TgxGizmoExUIFlatText));
  1645. with FUIVisibleInfoLabels do
  1646. begin
  1647. ModulateColor.Color := clrYellow;
  1648. Alignment := taCenter;
  1649. Layout := tlCenter;
  1650. Options := Options + [ftoTwoSided];
  1651. Position.Y := 1.8;
  1652. Position.X := 0;
  1653. Scale.X := 0.01;
  1654. Scale.Y := 0.01;
  1655. Text := '';
  1656. end;
  1657. HistoryStepsCount := 30;
  1658. BoundingBoxColor.Color := clrWhite;
  1659. VisibleInfoLabelsColor.Color := clrYellow;
  1660. SelectedColor.Color := clrYellow;
  1661. SelectionRegionColor.Color := clrBlack;
  1662. ShowAxisLabel := True;
  1663. ShowObjectInfos := True;
  1664. ShowBoundingBox := True;
  1665. FReferenceCoordSystem := rcsView;
  1666. FEnableHistory := True;
  1667. FinfoLabelCoordType := ilcChangeRate;
  1668. AntiAliasedLines := True;
  1669. FOperation := gopNone;
  1670. FSelAxis := gaNone;
  1671. EnableMultiSelection := True;
  1672. FSelectionRegion := gsrRectangular;
  1673. EnableLoopCursorMoving := True;
  1674. FUIRootHelpers.Visible := False;
  1675. OperationMode := gomSelect;
  1676. FVisibleVisibleInfoLabels := FVisibleVisibleInfoLabels + [vliName, vliOperation, vliCoords];
  1677. GizmoThickness := 1;
  1678. AutoZoom := True;
  1679. AutoZoomFactor := 5.0;
  1680. ZoomFactor := 0.35;
  1681. Enabled := True;
  1682. FNoZWrite := True;
  1683. FExcludeObjectsList := TStringList.Create;
  1684. FExcludeClassNameList := TStringList.Create;
  1685. end;
  1686. destructor TgxGizmoEx.Destroy;
  1687. begin
  1688. if Assigned(FRootGizmo) then
  1689. FRootGizmo.DeleteChildren
  1690. else
  1691. begin
  1692. FUIBaseGizmo.DeleteChildren;
  1693. FUIBaseGizmo.Free;
  1694. end;
  1695. FRootObjects := nil;
  1696. FGizmoTmpRoot := nil;
  1697. FBoundingBoxColor.Free;
  1698. SelectionRegionColor.Free;
  1699. FSelectedObjects.Free;
  1700. FSelectedColor.Free;
  1701. FVisibleInfoLabelsColor.Free;
  1702. FExcludeObjectsList.Free;
  1703. FExcludeClassNameList.Free;
  1704. // FUndoHistory has to be nil before Notification() is called.
  1705. FreeAndNil(FHistory);
  1706. inherited Destroy;
  1707. end;
  1708. procedure TgxGizmoEx.SetVisible(const AValue: Boolean);
  1709. begin
  1710. FUIBaseGizmo.Visible := AValue;
  1711. end;
  1712. function TgxGizmoEx.GetVisible: Boolean;
  1713. begin
  1714. Result := FUIBaseGizmo.Visible;
  1715. end;
  1716. procedure TgxGizmoEx.SetSelectionRegion(const AValue: TgxGizmoExSelectionRegion);
  1717. begin
  1718. if FSelectionRegion <> AValue then
  1719. FSelectionRegion := AValue;
  1720. end;
  1721. procedure TgxGizmoEx.SetShowAxisLabel(const AValue: Boolean);
  1722. begin
  1723. if FShowAxisLabel <> AValue then
  1724. begin
  1725. FShowAxisLabel := AValue;
  1726. FUIRootRotateAxisLabel.Visible := AValue;
  1727. if FOperationMode <> gomRotate then
  1728. FUIRootAxisLabel.Visible := AValue;
  1729. end;
  1730. end;
  1731. procedure TgxGizmoEx.SetSelAxis(aValue: TgxGizmoExAxis);
  1732. begin
  1733. if FSelAxis <> aValue then
  1734. begin
  1735. FSelAxis := aValue;
  1736. if Assigned(OnAxisSelected) then
  1737. OnAxisSelected(self, FSelAxis);
  1738. end;
  1739. end;
  1740. procedure TgxGizmoEx.SetPickMode(APickMode: TgxGizmoExPickMode);
  1741. begin
  1742. if APickMode <> FPickMode then
  1743. FPickMode := APickMode;
  1744. end;
  1745. procedure TgxGizmoEx.SetAutoZoomFactor(const AValue: Single);
  1746. begin
  1747. if (FAutoZoomFactor <> AValue) and (AValue > 0) then
  1748. begin
  1749. FAutoZoomFactor := AValue;
  1750. UpdateGizmo;
  1751. end;
  1752. end;
  1753. procedure TgxGizmoEx.SetZoomFactor(const AValue: Single);
  1754. begin
  1755. if (FZoomFactor <> AValue) and (AValue > 0) then
  1756. begin
  1757. FZoomFactor := AValue;
  1758. UpdateGizmo;
  1759. end;
  1760. end;
  1761. procedure TgxGizmoEx.SetShowObjectInfos(const AValue: Boolean);
  1762. begin
  1763. if FShowObjectInfos <> AValue then
  1764. begin
  1765. FShowObjectInfos := AValue;
  1766. FUIRootVisibleInfoLabels.Visible := FShowObjectInfos;
  1767. end;
  1768. end;
  1769. procedure TgxGizmoEx.SetShowBoundingBox(const AValue: Boolean);
  1770. begin
  1771. if FShowBoundingBox <> AValue then
  1772. FShowBoundingBox := AValue;
  1773. end;
  1774. function TgxGizmoEx.GetPickList: TgxPickList;
  1775. begin
  1776. Result := FSelectedObjects;
  1777. end;
  1778. procedure TgxGizmoEx.SetPickList(aValue: TgxPickList);
  1779. var
  1780. I: Integer;
  1781. begin
  1782. if FSelectedObjects <> aValue then
  1783. if aValue.Count - 1 >= 0 then
  1784. begin
  1785. FSelectedObjects.Clear;
  1786. for I := 0 to aValue.Count - 1 do
  1787. with aValue do
  1788. FSelectedObjects.AddHit(hit[I], SubObjects[I], NearDistance[I], FarDistance[I]);
  1789. UpdateGizmo();
  1790. end
  1791. else
  1792. LooseSelection();
  1793. end;
  1794. procedure TgxGizmoEx.SetSelectedObj(const Value: TgxBaseSceneObject);
  1795. begin
  1796. if FSelectedObjects.FindObject(Value) <> -1 then
  1797. Exit;
  1798. if (FSelectedObjects.Count - 1 >= 0) or (Value = nil) then
  1799. ClearSelection;
  1800. if Value <> nil then
  1801. FSelectedObjects.AddHit(Value, nil, 0, 0);
  1802. UpdateGizmo();
  1803. end;
  1804. function TgxGizmoEx.GetSelectedObj: TgxBaseSceneObject;
  1805. begin
  1806. Result := nil;
  1807. if FSelectedObjects.Count - 1 = -1 then
  1808. Result := nil
  1809. else
  1810. if FSelectedObjects.Count - 1 >= 0 then
  1811. Result := TgxBaseSceneObject(FSelectedObjects.Hit[0]);
  1812. end;
  1813. procedure TgxGizmoEx.AddObjToSelectionList(Obj: TgxBaseSceneObject);
  1814. begin
  1815. if (Obj <> nil) and (FSelectedObjects.FindObject(Obj) = -1) then
  1816. FSelectedObjects.AddHit(Obj, nil, 0, 0);
  1817. end;
  1818. procedure TgxGizmoEx.RemoveObjFromSelectionList(Obj: TgxBaseSceneObject);
  1819. var
  1820. I: Integer;
  1821. begin
  1822. I := FSelectedObjects.FindObject(Obj);
  1823. if I <> -1 then
  1824. FSelectedObjects.Delete(I);
  1825. end;
  1826. procedure TgxGizmoEx.AssignPickList(aList: TgxPickList; RemoveObj: Boolean = False);
  1827. function WithOutGizmoElements(obj: TgxBaseSceneObject): Boolean;
  1828. begin
  1829. if (obj <> FInterfaceRender) and (obj <> FInternalRender) and
  1830. not(obj is TgxGizmoExUISphere) and not(obj is TgxGizmoExUIPolygon) and
  1831. not(obj is TgxGizmoExUITorus) and not(obj is TgxGizmoExUIFrustrum) and
  1832. not(obj is TgxGizmoExUIArrowLine) and not(obj is TgxGizmoExUILines) and
  1833. not(obj is TgxGizmoExUIDisk) and not(obj is TgxGizmoExUIFlatText) and
  1834. not(CheckObjectInExcludeList(obj)) and
  1835. not(CheckClassNameInExcludeList(obj)) then
  1836. Result := True
  1837. else
  1838. Result := False;
  1839. end;
  1840. var
  1841. I: Integer;
  1842. begin
  1843. for I := 0 to aList.Count - 1 do
  1844. with aList do
  1845. if WithOutGizmoElements(TgxBaseSceneObject(hit[I])) then
  1846. if not RemoveObj then
  1847. begin
  1848. if (hit[I] <> nil) and (FSelectedObjects.FindObject(hit[I]) = -1) then
  1849. FSelectedObjects.AddHit(hit[I], SubObjects[I], NearDistance[I],
  1850. FarDistance[I]);
  1851. end
  1852. else if (hit[I] <> nil) and (FSelectedObjects.FindObject(hit[I]) <> -1)
  1853. then
  1854. FSelectedObjects.Delete(FSelectedObjects.FindObject(hit[I]));
  1855. end;
  1856. procedure TgxGizmoEx.InterfaceRender(Sender: TObject; var rci: TgxRenderContextInfo);
  1857. procedure cLine(glc: TgxCanvas; p1, p2: TPoint);
  1858. begin
  1859. glc.Line(p1.X, p1.Y, p2.X, p2.Y);
  1860. end;
  1861. var
  1862. glc: TgxCanvas;
  1863. I: Integer;
  1864. LastCurPosX, LastCurPosY, CurPosX, CurPosY: Single;
  1865. begin
  1866. if (not Enabled) or (RootGizmo = nil) or (RootObjects = nil) then
  1867. Exit;
  1868. //here takes place rendering of lines and circles on canvas
  1869. //according to modes, it's a pity that canvas has restrictions
  1870. if FShowMultiSelecting then
  1871. begin
  1872. glc := TgxCanvas.Create(Round(Viewer.Width), Round(Viewer.Height));
  1873. glc.PenColor := FSelectionRegionColor.AsWinColor;
  1874. glc.PenWidth := 1;
  1875. LastCurPosX := fLastCursorPos.X;
  1876. LastCurPosY := fLastCursorPos.Y;
  1877. CurPosX := fCursorPos.X;
  1878. CurPosY := fCursorPos.Y;
  1879. with glc do
  1880. case FSelectionRegion of
  1881. gsrRectangular: FrameRect(LastCurPosX, LastCurPosY, CurPosX, CurPosY);
  1882. gsrCircular: Ellipse(LastCurPosX, LastCurPosY,
  1883. MaxFloat(abs(CurPosX - LastCurPosX),
  1884. abs(CurPosY - LastCurPosY)));
  1885. gsrFence:
  1886. begin
  1887. for I := Low(FSelectionRec) to High(FSelectionRec) do
  1888. if I <> High(FSelectionRec) then
  1889. cLine(glc, FSelectionRec[I], FSelectionRec[I + 1])
  1890. else
  1891. cLine(glc, FSelectionRec[I], fcursorPos);
  1892. //glc.PenWidth thickness of rectangle
  1893. //it's necessary to show that the begining and the end
  1894. // of a figure are joining and when cursor is near begining of array
  1895. // then appears square, that show to user that he picked right object
  1896. if High(FSelectionRec) > 0 then
  1897. with FSelectionRec[Low(FSelectionRec)] do
  1898. if IsInRange(CurPosX, X + 2, X - 2) and IsInRange(CurPosY, Y + 2, Y - 2) then
  1899. FillRect(CurPosX - PenWidth - 2, CurPosY - PenWidth - 2,
  1900. CurPosX + PenWidth + 2, CurPosY + PenWidth + 2);
  1901. end;
  1902. gsrLasso:
  1903. begin
  1904. //here showing arrays of lines
  1905. //when additional line formed by begining and and of array
  1906. for I := Low(FSelectionRec) to High(FSelectionRec) do
  1907. if I <> High(FSelectionRec) then
  1908. cLine(glc, FSelectionRec[I], FSelectionRec[I + 1])
  1909. else
  1910. cLine(glc, FSelectionRec[I], FSelectionRec[Low(FSelectionRec)]);
  1911. end;
  1912. end;
  1913. glc.Destroy;
  1914. end;
  1915. end;
  1916. procedure TgxGizmoEx.InternalRender(Sender: TObject; var rci: TgxRenderContextInfo);
  1917. procedure ShowBoundingBox(aObject: TgxBaseSceneObject);
  1918. const
  1919. ACorners: array [0..7, 0..2] of Byte = ((1, 3, 4),
  1920. (0, 2, 5),
  1921. (1, 6, 3),
  1922. (0, 2, 7),
  1923. (0, 5, 7),
  1924. (1, 4, 6),
  1925. (2, 5, 7),
  1926. (3, 4, 6));
  1927. var
  1928. I, J: Byte;
  1929. BB: THmgBoundingBox;
  1930. AVector: TVector4f;
  1931. begin
  1932. if aObject = nil then
  1933. Exit;
  1934. BB := aObject.BoundingBoxAbsolute(False);
  1935. for I := 0 to 7 do
  1936. begin
  1937. for J := 0 to 2 do
  1938. begin
  1939. AVector := VectorSubtract(BB.BBox[ACorners[I][J]], BB.BBox[I]);
  1940. AVector := VectorScale(AVector, 0.25);
  1941. AVector := VectorAdd(AVector, BB.BBox[I]);
  1942. glBegin(GL_LINES);
  1943. glVertex3f(BB.BBox[I].X, BB.BBox[I].Y, BB.BBox[I].Z);
  1944. glVertex3f(AVector.X, AVector.Y, AVector.Z);
  1945. glEnd;
  1946. end;
  1947. end;
  1948. end;
  1949. //test#12 result is positive, but only for 2d
  1950. procedure ShowText(const Text: UnicodeString; Position: TVector4f; Scale: TVector4f; Color: TVector4f);
  1951. var
  1952. FLayout: TgxTextLayout;
  1953. FAlignment: TAlignment;
  1954. wm: TMatrix4f;
  1955. I, J: Integer;
  1956. begin
  1957. if not Assigned(FLabelFont) and (Text = '') then
  1958. Exit;
  1959. rci.gxStates.Enable(stDepthTest);
  1960. FLayout := tlCenter;
  1961. FAlignment := taCenter;
  1962. glMatrixMode(GL_MODELVIEW);
  1963. glPushMatrix;
  1964. wm := rci.PipelineTransformation.ViewMatrix^;
  1965. TransposeMatrix(wm);
  1966. for I := 0 to 2 do
  1967. for J := 0 to 2 do
  1968. if I = J then
  1969. wm.V[I].V[J] := 1
  1970. else
  1971. wm.V[I].V[J] := 0;
  1972. glLoadMatrixf(@wm);
  1973. rci.gxStates.PolygonMode := pmFill;
  1974. glScalef(Scale.X, Scale.Y, Scale.Z);
  1975. glTranslatef(Position.X, Position.Y, Position.Z);
  1976. if Color.W <> 1 then
  1977. begin
  1978. rci.gxStates.Enable(stBlend);
  1979. rci.gxStates.SetBlendFunc(bfSrcAlpha, bfOneMinusSrcAlpha);
  1980. end;
  1981. rci.gxStates.Disable(stDepthTest);
  1982. rci.gxStates.Disable(stCullFace);
  1983. FLabelFont.RenderString(rci, Text, FAlignment, FLayout, Color);
  1984. glPopMatrix;
  1985. end;
  1986. var
  1987. I: Integer;
  1988. begin
  1989. if (not Enabled) or (RootGizmo = nil) or (RootObjects = nil) then
  1990. Exit;
  1991. if FShowBoundingBox and (FSelectedObjects.Count - 1 >= 0) then
  1992. begin
  1993. rci.gxStates.Disable(stLighting);
  1994. if FAntiAliasedLines then
  1995. rci.gxStates.Enable(stLineSmooth);
  1996. if (FGizmoThickness >= 0.5) and (FGizmoThickness <= 7) then
  1997. rci.gxStates.LineWidth := FGizmoThickness
  1998. else
  1999. rci.gxStates.LineWidth := 1;
  2000. glColorMaterial(GL_FRONT, GL_EMISSION);
  2001. rci.gxStates.Enable(stColorMaterial);
  2002. glColor4fv(@FBoundingBoxColor.Color);
  2003. for I := 0 to FSelectedObjects.Count - 1 do
  2004. ShowBoundingBox(TgxBaseSceneObject(FSelectedObjects.Hit[I]));
  2005. end;
  2006. rci.gxStates.Disable(stColorMaterial);
  2007. end;
  2008. procedure TgxGizmoEx.SetReferenceCoordSystem(aValue: TgxGizmoExReferenceCoordinateSystem);
  2009. begin
  2010. if FReferenceCoordSystem <> aValue then
  2011. begin
  2012. FReferenceCoordSystem := aValue;
  2013. UpdateGizmo;
  2014. end;
  2015. end;
  2016. procedure TgxGizmoEx.SetHistoryStepsCount(aValue: Integer);
  2017. begin
  2018. if (FHistoryStepsCount <> aValue) and (aValue > 5) then
  2019. begin
  2020. FHistoryStepsCount := aValue;
  2021. FHistory.FItemsMaxCount := aValue;
  2022. end;
  2023. end;
  2024. procedure TgxGizmoEx.SetCanChangeWithChildren(AValue: Boolean);
  2025. begin
  2026. if FCanChangeWithChildren <> AValue then
  2027. FCanChangeWithChildren := AValue;
  2028. end;
  2029. procedure TgxGizmoEx.SetAALines(aValue: Boolean);
  2030. begin
  2031. if FAntiAliasedLines <> aValue then
  2032. begin
  2033. FAntiAliasedLines := aValue;
  2034. FUISelectLineX.AntiAliased := aValue;
  2035. FUISelectLineY.AntiAliased := aValue;
  2036. FUISelectLineZ.AntiAliased := aValue;
  2037. FUIMovementLineX.AntiAliased := aValue;
  2038. FUIMovementLineY.AntiAliased := aValue;
  2039. FUIMovementLineZ.AntiAliased := aValue;
  2040. FUIMovementLineXY.AntiAliased := aValue;
  2041. FUIMovementLineXZ.AntiAliased := aValue;
  2042. FUIMovementLineYZ.AntiAliased := aValue;
  2043. FUIRotateLineX.AntiAliased := aValue;
  2044. FUIRotateLineY.AntiAliased := aValue;
  2045. FUIRotateLineZ.AntiAliased := aValue;
  2046. FUIrotateLineXY.AntiAliased := aValue;
  2047. FUIRotateLineXZ.AntiAliased := aValue;
  2048. FUIRotateLineArrowX.AntiAliased := aValue;
  2049. FUIRotateLineArrowY.AntiAliased := aValue;
  2050. FUIRotateLineArrowZ.AntiAliased := aValue;
  2051. FUIScaleLineX.AntiAliased := aValue;
  2052. FUIScaleLineY.AntiAliased := aValue;
  2053. FUIScaleLineZ.AntiAliased := aValue;
  2054. FUIScaleLineXY.AntiAliased := aValue;
  2055. FUIScaleLineXZ.AntiAliased := aValue;
  2056. FUIScaleLineYZ.AntiAliased := aValue;
  2057. end;
  2058. end;
  2059. procedure TgxGizmoEx.SetInfoLabelCoordType(aValue: TInfoLabelCoordType);
  2060. begin
  2061. if fInfoLabelCoordType <> aValue then
  2062. begin
  2063. fInfoLabelCoordType := aValue;
  2064. UpdateVisibleInfoLabels;
  2065. end;
  2066. end;
  2067. procedure TgxGizmoEx.SetAngleDisk(aAngle: Single);
  2068. var
  2069. Disk1alpha, Disk2alpha, Disk1Angle, Disk2Angle: Single;
  2070. begin
  2071. Disk1alpha := 0;
  2072. Disk2alpha := 0;
  2073. Disk1Angle := 0;
  2074. Disk2Angle := 0;
  2075. if aAngle = 0 then
  2076. begin
  2077. fchangerate := NullVector;
  2078. FUIRotateDiskX.SweepAngle := 0;
  2079. FUIRotateDiskY.SweepAngle := 0;
  2080. FUIRotateDiskZ.SweepAngle := 0;
  2081. FUIRotateDiskX.Material.FrontProperties.Diffuse.Alpha := 0;
  2082. FUIRotateDiskY.Material.FrontProperties.Diffuse.Alpha := 0;
  2083. FUIRotateDiskZ.Material.FrontProperties.Diffuse.Alpha := 0;
  2084. FUIRotateDiskX2.SweepAngle := 0;
  2085. FUIRotateDiskY2.SweepAngle := 0;
  2086. FUIRotateDiskZ2.SweepAngle := 0;
  2087. FUIRotateDiskX2.Material.FrontProperties.Diffuse.Alpha := 0;
  2088. FUIRotateDiskY2.Material.FrontProperties.Diffuse.Alpha := 0;
  2089. FUIRotateDiskZ2.Material.FrontProperties.Diffuse.Alpha := 0;
  2090. end
  2091. else
  2092. if (abs(aAngle) > 0) and (abs(aAngle) <= 360) then
  2093. begin
  2094. Disk1alpha := 0.3;
  2095. Disk2alpha := 0;
  2096. Disk1Angle := aAngle;
  2097. Disk2Angle := 0;
  2098. end
  2099. else
  2100. if (abs(aAngle) > 360) and (abs(aAngle) <= 720) then
  2101. begin
  2102. Disk1alpha := 0.3;
  2103. Disk2alpha := 0.3;
  2104. Disk1Angle := 360;
  2105. if aAngle > 0 then
  2106. Disk2Angle := aAngle - 360
  2107. else
  2108. Disk2Angle := aAngle + 360;
  2109. end
  2110. else
  2111. if (abs(aAngle) > 720) and (abs(aAngle) <= 1080) then
  2112. begin
  2113. Disk1alpha := 0.5;
  2114. Disk2alpha := 0.3;
  2115. Disk1Angle := 360;
  2116. if aAngle > 0 then
  2117. Disk2Angle := aAngle - 720
  2118. else
  2119. Disk2Angle := aAngle + 720;
  2120. end
  2121. else
  2122. if (abs(aAngle) > 1080) and (abs(aAngle) <= 1440) then
  2123. begin
  2124. Disk1alpha := 0.6;
  2125. Disk2alpha := 0.3;
  2126. Disk1Angle := 360;
  2127. if aAngle > 0 then
  2128. Disk2Angle := aAngle - 1080
  2129. else
  2130. Disk2Angle := aAngle + 1080;
  2131. end
  2132. else
  2133. if (abs(aAngle) > 1440) then
  2134. begin
  2135. Disk1alpha := 0.6;
  2136. Disk2alpha := 0.3;
  2137. Disk1Angle := 360;
  2138. Disk2Angle := 360;
  2139. end;
  2140. case SelAxis of
  2141. gaX:
  2142. begin
  2143. FUIRotateDiskX.SweepAngle := Disk1Angle;
  2144. FUIRotateDiskX.Material.FrontProperties.Diffuse.Alpha := Disk1alpha;
  2145. FUIRotateDiskX2.SweepAngle := Disk2Angle;
  2146. FUIRotateDiskX2.Material.FrontProperties.Diffuse.Alpha := Disk2alpha;
  2147. end;
  2148. gaY:
  2149. begin
  2150. FUIRotateDiskY.SweepAngle := Disk1Angle;
  2151. FUIRotateDiskY.Material.FrontProperties.Diffuse.Alpha := Disk1alpha;
  2152. FUIRotateDiskY2.SweepAngle := Disk2Angle;
  2153. FUIRotateDiskY2.Material.FrontProperties.Diffuse.Alpha := Disk2alpha;
  2154. end;
  2155. gaZ:
  2156. begin
  2157. FUIRotateDiskZ.SweepAngle := Disk1Angle;
  2158. FUIRotateDiskZ.Material.FrontProperties.Diffuse.Alpha := Disk1alpha;
  2159. FUIRotateDiskZ2.SweepAngle := Disk2Angle;
  2160. FUIRotateDiskZ2.Material.FrontProperties.Diffuse.Alpha := Disk2alpha;
  2161. end;
  2162. end;
  2163. end;
  2164. procedure TgxGizmoEx.SetBoundingBoxColor(const AValue: TgxColor);
  2165. begin
  2166. if AValue <> FBoundingBoxColor then
  2167. begin
  2168. FBoundingBoxColor.Color := AValue.Color;
  2169. UpdateGizmo;
  2170. end;
  2171. end;
  2172. procedure TgxGizmoEx.SetSelectedColor(const AValue: TgxColor);
  2173. begin
  2174. if AValue <> FSelectedColor then
  2175. begin
  2176. FSelectedColor.Color := AValue.Color;
  2177. UpdateGizmo;
  2178. end;
  2179. end;
  2180. procedure TgxGizmoEx.SetOperation(const Value: TgxGizmoExOperation);
  2181. begin
  2182. if FOperation <> Value then
  2183. begin
  2184. FOperation := Value;
  2185. if Assigned(OnOperationChange) then
  2186. OnOperationChange(self);
  2187. end;
  2188. end;
  2189. procedure TgxGizmoEx.SetOperationMode(const Value: TgxGizmoExOperationMode);
  2190. begin
  2191. if FOperationMode <> Value then
  2192. begin
  2193. FOperationMode := Value;
  2194. if Value = gomNone then
  2195. begin
  2196. Visible := False;
  2197. Enabled := False;
  2198. end
  2199. else
  2200. begin
  2201. Visible := True;
  2202. Enabled := True;
  2203. end;
  2204. if Value = gomSelect then
  2205. FUIRootSelect.Visible := True
  2206. else
  2207. FUIRootSelect.Visible := False;
  2208. if Value = gomMove then
  2209. FUIRootMovement.Visible := True
  2210. else
  2211. FUIRootMovement.Visible := False;
  2212. if Value = gomrotate then
  2213. begin
  2214. FUIRootAxisLabel.Visible := False;
  2215. FUIRootRotate.Visible := True;
  2216. end
  2217. else
  2218. begin
  2219. FUIRootRotate.Visible := False;
  2220. FUIRootAxisLabel.Visible := ShowAxisLabel;
  2221. end;
  2222. if Value = gomscale then
  2223. FUIRootScale.Visible := True
  2224. else
  2225. FUIRootScale.Visible := False;
  2226. if Assigned(OnOperationModeChange) then
  2227. OnOperationModeChange(self);
  2228. UpdateGizmo;
  2229. end;
  2230. end;
  2231. procedure TgxGizmoEx.SetNoZWrite(const Value: Boolean);
  2232. begin
  2233. if fNoZWrite <> Value then
  2234. begin
  2235. fNoZWrite := Value;
  2236. //For Select
  2237. FUISelectLineX.NoZWrite := Value;
  2238. FUISelectLineY.NoZWrite := Value;
  2239. FUISelectLineZ.NoZWrite := Value;
  2240. //For Move
  2241. FUIMovementLineX.NoZWrite := Value;
  2242. FUIMovementLineY.NoZWrite := Value;
  2243. FUIMovementLineZ.NoZWrite := Value;
  2244. FUIMovementLineXY.NoZWrite := Value;
  2245. FUIMovementLineXZ.NoZWrite := Value;
  2246. FUIMovementLineYZ.NoZWrite := Value;
  2247. FUIMovementArrowX.NoZWrite := Value;
  2248. FUIMovementArrowY.NoZWrite := Value;
  2249. FUIMovementArrowZ.NoZWrite := Value;
  2250. FUIMovementPlaneXY.NoZWrite := Value;
  2251. FUIMovementPlaneXZ.NoZWrite := Value;
  2252. FUIMovementPlaneYZ.NoZWrite := Value;
  2253. FUIICMovementLineX.NoZWrite := Value;
  2254. FUIICMovementLineY.NoZWrite := Value;
  2255. FUIICMovementLineZ.NoZWrite := Value;
  2256. FUIICMovementLineXY.NoZWrite := Value;
  2257. FUIICMovementLineXZ.NoZWrite := Value;
  2258. FUIICMovementLineYZ.NoZWrite := Value;
  2259. //ForRotate
  2260. FUIRotateLineX.NoZWrite := Value;
  2261. FUIRotateLineY.NoZWrite := Value;
  2262. FUIRotateLineZ.NoZWrite := Value;
  2263. FUIRotateLineXY.NoZWrite := Value;
  2264. FUIRotateLineXZ.NoZWrite := Value;
  2265. FUIICRotateTorusX.NoZWrite := Value;
  2266. FUIICRotateTorusY.NoZWrite := Value;
  2267. FUIICRotateTorusZ.NoZWrite := Value;
  2268. FUIICRotateTorusXZ.NoZWrite := Value;
  2269. FUIRotateDiskXY.NoZWrite := Value;
  2270. FUIRotateDiskX.NoZWrite := Value;
  2271. FUIRotateDiskY.NoZWrite := Value;
  2272. FUIRotateDiskZ.NoZWrite := Value;
  2273. FUIRotateDiskX2.NoZWrite := Value;
  2274. FUIRotateDiskY2.NoZWrite := Value;
  2275. FUIRotateDiskZ2.NoZWrite := Value;
  2276. FUIICRotateSphereXY.NoZWrite := Value;
  2277. FUIRotateLineArrowX.NoZWrite := Value;
  2278. FUIRotateLineArrowY.NoZWrite := Value;
  2279. FUIRotateLineArrowZ.NoZWrite := Value;
  2280. FUIRotateAxisLabelX.NoZWrite := Value;
  2281. FUIRotateAxisLabelY.NoZWrite := Value;
  2282. FUIRotateAxisLabelZ.NoZWrite := Value;
  2283. //ForScale
  2284. FUIScaleArrowX.NoZWrite := Value;
  2285. FUIScaleArrowY.NoZWrite := Value;
  2286. FUIScaleArrowZ.NoZWrite := Value;
  2287. FUIScaleLineX.NoZWrite := Value;
  2288. FUIScaleLineY.NoZWrite := Value;
  2289. FUIScaleLineZ.NoZWrite := Value;
  2290. FUIScaleLineXY.NoZWrite := Value;
  2291. FUIScaleLineYZ.NoZWrite := Value;
  2292. FUIScaleLineXZ.NoZWrite := Value;
  2293. FUIICScaleLineX.NoZWrite := Value;
  2294. FUIICScaleLineY.NoZWrite := Value;
  2295. FUIICScaleLineZ.NoZWrite := Value;
  2296. FUIICScaleLineXY.NoZWrite := Value;
  2297. FUIICScaleLineXZ.NoZWrite := Value;
  2298. FUIICScaleLineYZ.NoZWrite := Value;
  2299. FUIICScaleLineXYZ.NoZWrite := Value;
  2300. FUIScalePlaneXY.NoZWrite := Value;
  2301. FUIScalePlaneXZ.NoZWrite := Value;
  2302. FUIScalePlaneYZ.NoZWrite := Value;
  2303. FUIScalePlaneXYZ.NoZWrite := Value;
  2304. FUIAxisLabelX.NoZWrite := Value;
  2305. FUIAxisLabelY.NoZWrite := Value;
  2306. FUIAxisLabelZ.NoZWrite := Value;
  2307. FUIVisibleInfoLabels.NoZWrite := Value;
  2308. end;
  2309. end;
  2310. procedure TgxGizmoEx.SetEnableLoopCursorMoving(const AValue: Boolean);
  2311. begin
  2312. if FEnableLoopCursorMoving <> AValue then
  2313. FEnableLoopCursorMoving := AValue;
  2314. end;
  2315. procedure TgxGizmoEx.SetEnableMultiSelection(const AValue: Boolean);
  2316. begin
  2317. if FEnableMultiSelection <> AValue then
  2318. begin
  2319. FEnableMultiSelection := AValue;
  2320. FInterfaceRender.Visible := AValue;
  2321. end;
  2322. end;
  2323. procedure TgxGizmoEx.MultiSelMouseDown(X, Y: Integer);
  2324. begin
  2325. flastcursorPos := Point(X, Y);
  2326. fcursorPos := point(X, Y);
  2327. if (fSelectionRegion = gsrFence) and FShowMultiSelecting then
  2328. begin
  2329. SetLength(FSelectionRec, Length(FSelectionRec) + 1);
  2330. FSelectionRec[high(FSelectionRec)] := point(X, Y);
  2331. end;
  2332. end;
  2333. procedure TgxGizmoEx.MultiSelMouseMove(X, Y: Integer);
  2334. begin
  2335. //calculation starts when the mouse button is down
  2336. //ans distance from pick pisition is not more then 10
  2337. if Moving and not FShowMultiSelecting and
  2338. (Dist(point(X, Y), flastcursorPos) > 10) then
  2339. begin
  2340. FShowMultiSelecting := True;
  2341. if fSelectionRegion = gsrFence then
  2342. begin
  2343. SetLength(FSelectionRec, Length(FSelectionRec) + 1);
  2344. FSelectionRec[high(FSelectionRec)] := point(X, Y);
  2345. end;
  2346. end;
  2347. if FShowMultiSelecting then
  2348. begin
  2349. fcursorPos := point(X, Y);
  2350. //creating lines when moving mouse
  2351. if (fSelectionRegion = gsrLasso) and
  2352. //clculate distance between two points to view as in 3D Max
  2353. (Dist(point(X, Y), flastcursorPos) > 20) then
  2354. begin
  2355. flastcursorPos := point(X, Y);
  2356. SetLength(FSelectionRec, Length(FSelectionRec) + 1);
  2357. FSelectionRec[high(FSelectionRec)] := point(X, Y);
  2358. end;
  2359. end;
  2360. end;
  2361. procedure TgxGizmoEx.MultiSelMouseUp(X, Y: Integer);
  2362. procedure SelectAssignMode(pick: TgxPickList);
  2363. begin
  2364. if not FCanRemoveObjFromSelectionList and not FCanAddObjtoSelectionList then
  2365. AssignPickList(pick)
  2366. else
  2367. if FCanRemoveObjFromSelectionList then
  2368. AssignPickList(pick, FCanRemoveObjFromSelectionList)
  2369. else
  2370. if FCanAddObjtoSelectionList then
  2371. AssignPickList(pick);
  2372. end;
  2373. var
  2374. I, J: Integer;
  2375. pick: TgxPickList;
  2376. p1, p2: TPoint;
  2377. Line: TgxGizmoExSelRec;
  2378. LastCurPosX, LastCurPosY, CurPosX, CurPosY: Single;
  2379. begin
  2380. LastCurPosX := flastcursorPos.X;
  2381. LastCurPosY := flastcursorPos.Y;
  2382. CurPosX := fcursorPos.X;
  2383. CurPosY := fcursorPos.Y;
  2384. if (fSelectionRegion = gsrRectangular) then
  2385. begin
  2386. pick := InternalGetPickedObjects(X - 1, Y - 1, flastcursorPos.X + 1, flastcursorPos.Y + 1, 8);
  2387. if not FCanRemoveObjFromSelectionList and not FCanAddObjtoSelectionList then
  2388. FSelectedObjects.Clear;
  2389. SelectAssignMode(pick);
  2390. pick.Free;
  2391. if Assigned(onSelect) then
  2392. onSelect(self, FSelectedObjects);
  2393. FShowMultiSelecting := False;
  2394. end;
  2395. if (fSelectionRegion = gsrCircular) then
  2396. begin
  2397. FShowMultiSelecting := False;
  2398. if not FCanRemoveObjFromSelectionList and not FCanAddObjtoSelectionList then
  2399. FSelectedObjects.Clear;
  2400. for I := 0 to Round(viewer.Height) - 1 do
  2401. if IsLineIntCirlce(Maxfloat(abs(CurPosX - LastCurPosX),
  2402. abs(CurPosY - LastCurPosY)),
  2403. flastcursorPos, point(0, I), point(Round(viewer.Width), I), p1, p2) >= 0 then
  2404. if (I mod 2 = 0) then
  2405. begin
  2406. pick := InternalGetPickedObjects(p2.X - 1, p2.Y - 1, p1.X + 1, p1.Y + 1, 8);
  2407. SelectAssignMode(pick);
  2408. pick.Free;
  2409. end;
  2410. if Assigned(onSelect) then
  2411. onSelect(self, FSelectedObjects);
  2412. end;
  2413. if (fSelectionRegion = gsrFence) and (high(FSelectionRec) > 0) then
  2414. with FSelectionRec[Low(FSelectionRec)] do
  2415. //verify if a pick is near point, not to seek a centre
  2416. if IsInRange(CurPosX, X + 2, X - 2) and IsInRange(CurPosY, Y + 2, Y - 2) then
  2417. begin
  2418. FShowMultiSelecting := False;
  2419. //connect the begining and end
  2420. SetLength(FSelectionRec, Length(FSelectionRec) + 1);
  2421. FSelectionRec[high(FSelectionRec)] := point(X, Y);
  2422. if not FCanRemoveObjFromSelectionList and not FCanAddObjtoSelectionList then
  2423. FSelectedObjects.Clear;
  2424. for J := 0 to Round(viewer.Height) - 1 do
  2425. for I := 0 to Round(viewer.Width) - 1 do
  2426. begin
  2427. if IsPointInPolygon(FSelectionRec, point(I, J)) then
  2428. begin
  2429. if not IsPointInPolygon(FSelectionRec, point(I + 1, J)) then
  2430. begin
  2431. SetLength(line, Length(line) + 1);
  2432. line[high(line)] := point(I, J);
  2433. end;
  2434. end
  2435. else
  2436. if IsPointInPolygon(FSelectionRec, point(I + 1, J)) then
  2437. begin
  2438. SetLength(line, Length(line) + 1);
  2439. line[high(line)] := point(I, J);
  2440. end;
  2441. end;
  2442. for I := 0 to High(line) do
  2443. if (I mod 2 = 0) then
  2444. begin
  2445. pick := InternalGetPickedObjects(line[I].X - 1, line[I].Y - 1, line[I + 1].X + 1, line[I + 1].Y + 1, 8);
  2446. SelectAssignMode(pick);
  2447. pick.Free;
  2448. end;
  2449. if Assigned(onSelect) then
  2450. onSelect(self, FSelectedObjects);
  2451. //nulling of array
  2452. SetLength(line, 0);
  2453. SetLength(FSelectionRec, 0);
  2454. end;
  2455. if (fSelectionRegion = gsrLasso) then
  2456. begin
  2457. FShowMultiSelecting := False;
  2458. SetLength(FSelectionRec, Length(FSelectionRec) + 1);
  2459. FSelectionRec[high(FSelectionRec)] := FSelectionRec[Low(FSelectionRec)];
  2460. if not FCanRemoveObjFromSelectionList and not FCanAddObjtoSelectionList then
  2461. FSelectedObjects.Clear;
  2462. for J := 0 to Round(viewer.Height) - 1 do
  2463. for I := 0 to Round(viewer.Width) - 1 do
  2464. begin
  2465. if IsPointInPolygon(FSelectionRec, point(I, J)) then
  2466. begin
  2467. if not IsPointInPolygon(FSelectionRec, point(I + 1, J)) then
  2468. begin
  2469. SetLength(line, Length(line) + 1);
  2470. line[high(line)] := point(I, J);
  2471. end;
  2472. end
  2473. else
  2474. if IsPointInPolygon(FSelectionRec, point(I + 1, J)) then
  2475. begin
  2476. SetLength(line, Length(line) + 1);
  2477. line[high(line)] := point(I, J);
  2478. end;
  2479. end;
  2480. for I := 0 to High(line) do
  2481. if (I mod 2 = 0) then
  2482. begin
  2483. pick := InternalGetPickedObjects(line[I].X - 1, line[I].Y - 1, line[I + 1].X + 1, line[I + 1].Y + 1, 8);
  2484. SelectAssignMode(pick);
  2485. pick.Free;
  2486. end;
  2487. SetLength(line, 0);
  2488. SetLength(FSelectionRec, 0);
  2489. if Assigned(onSelect) then
  2490. onSelect(self, FSelectedObjects);
  2491. end;
  2492. end;
  2493. procedure TgxGizmoEx.SetVisibleInfoLabelsColor(const AValue: TgxColor);
  2494. begin
  2495. if AValue <> FSelectedColor then
  2496. begin
  2497. FVisibleInfoLabelsColor.Color := AValue.Color;
  2498. FUIVisibleInfoLabels.ModulateColor.Color := AValue.Color;
  2499. FVisibleInfoLabelsColorChanged := True;
  2500. UpdateGizmo;
  2501. end;
  2502. end;
  2503. procedure TgxGizmoEx.SetSelectionRegionColor(const AValue: TgxColor);
  2504. begin
  2505. if AValue <> FSelectionRegionColor then
  2506. begin
  2507. FSelectionRegionColor.Color := AValue.Color;
  2508. end;
  2509. end;
  2510. procedure TgxGizmoEx.SetGizmoExVisibleInfoLabels(const AValue: TgxGizmoExVisibleInfoLabels);
  2511. begin
  2512. if AValue <> FVisibleVisibleInfoLabels then
  2513. begin
  2514. FVisibleVisibleInfoLabels := AValue;
  2515. if not (csDesigning in ComponentState) then
  2516. UpdateGizmo;
  2517. end;
  2518. end;
  2519. procedure TgxGizmoEx.UndoAdd(const AObject: TObject);
  2520. begin
  2521. if AObject <> nil then
  2522. FHistory.AddObject(AObject);
  2523. end;
  2524. procedure TgxGizmoEx.RemoveSelectedObjects;
  2525. begin
  2526. if not Assigned(FHistory.FGizmoTmpRoot) then
  2527. Exit;
  2528. FHistory.RemoveObjects(SelectedObjects);
  2529. FHistory.AddObjects(SelectedObjects);
  2530. UpdateGizmo();
  2531. end;
  2532. procedure TgxGizmoEx.SetRootGizmo(const AValue: TgxBaseSceneObject);
  2533. begin
  2534. if FRootGizmo <> AValue then
  2535. begin
  2536. if FRootGizmo <> nil then
  2537. FRootGizmo.RemoveFreeNotification(Self);
  2538. FRootGizmo := AValue;
  2539. if FRootGizmo <> nil then
  2540. FRootGizmo.FreeNotification(Self);
  2541. FUIBaseGizmo.MoveTo(AValue);
  2542. end;
  2543. end;
  2544. procedure TgxGizmoEx.SetGizmoTmpRoot(const AValue: TgxBaseSceneObject);
  2545. begin
  2546. if FGizmoTmpRoot <> AValue then
  2547. begin
  2548. if FGizmoTmpRoot <> nil then
  2549. FGizmoTmpRoot.RemoveFreeNotification(Self);
  2550. FGizmoTmpRoot := AValue;
  2551. FGizmoTmpRoot.Visible := False;
  2552. FHistory.GizmoTmpRoot := FGizmoTmpRoot;
  2553. end;
  2554. end;
  2555. procedure TgxGizmoEx.SetRootObjects(const AValue: TgxBaseSceneObject);
  2556. begin
  2557. if fRootObjects <> AValue then
  2558. begin
  2559. if fRootObjects <> nil then
  2560. fRootObjects.RemoveFreeNotification(Self);
  2561. fRootObjects := AValue;
  2562. end;
  2563. end;
  2564. procedure TgxGizmoEx.SetExcludeObjectsList(const AValue: TStrings);
  2565. begin
  2566. FExcludeObjectsList.Clear;
  2567. FExcludeObjectsList.AddStrings(AValue);
  2568. end;
  2569. procedure TgxGizmoEx.SetExcludeClassNameList(const AValue: TStrings);
  2570. begin
  2571. FExcludeClassNameList.Clear;
  2572. FExcludeClassNameList.AddStrings(AValue);
  2573. end;
  2574. procedure TgxGizmoEx.SetGizmoExThickness(const Value: Single);
  2575. begin
  2576. if (FGizmoThickness <> Value) and (Value > 0.2) then
  2577. begin
  2578. FGizmoThickness := Value;
  2579. FUISelectLineX.LineWidth := 1 * Value;
  2580. FUISelectLineY.LineWidth := 1 * Value;
  2581. FUISelectLineZ.LineWidth := 1 * Value;
  2582. FUIMovementLineX.LineWidth := 1 * Value;
  2583. FUIMovementLineY.LineWidth := 1 * Value;
  2584. FUIMovementLineZ.LineWidth := 1 * Value;
  2585. FUIMovementLineXY.LineWidth := 1 * Value;
  2586. FUIMovementLineXZ.LineWidth := 1 * Value;
  2587. FUIMovementLineYZ.LineWidth := 1 * Value;
  2588. FUIRotateLineX.LineWidth := 1 * Value;
  2589. FUIRotateLineY.LineWidth := 1 * Value;
  2590. FUIRotateLineZ.LineWidth := 1 * Value;
  2591. FUIrotateLineXY.LineWidth := 1 * Value;
  2592. FUIRotateLineXZ.LineWidth := 1 * Value;
  2593. FUIRotateLineArrowX.LineWidth := 1 * Value;
  2594. FUIRotateLineArrowY.LineWidth := 1 * Value;
  2595. FUIRotateLineArrowZ.LineWidth := 1 * Value;
  2596. FUIScaleLineX.LineWidth := 1 * Value;
  2597. FUIScaleLineY.LineWidth := 1 * Value;
  2598. FUIScaleLineZ.LineWidth := 1 * Value;
  2599. FUIScaleLineXY.LineWidth := 1 * Value;
  2600. FUIScaleLineXZ.LineWidth := 1 * Value;
  2601. FUIScaleLineYZ.LineWidth := 1 * Value;
  2602. end;
  2603. end;
  2604. //------------------------------------------------------------------------------
  2605. procedure TgxGizmoEx.SetLabelFont(const Value: TgxCustomBitmapFont);
  2606. begin
  2607. if FLabelFont <> Value then
  2608. begin
  2609. if FLabelFont <> nil then
  2610. FLabelFont.RemoveFreeNotification(Self);
  2611. FLabelFont := Value;
  2612. if FLabelFont <> nil then
  2613. FLabelFont.FreeNotification(Self);
  2614. FUIAxisLabelX.BitmapFont := Value;
  2615. FUIAxisLabelY.BitmapFont := Value;
  2616. FUIAxisLabelZ.BitmapFont := Value;
  2617. FUIRotateAxisLabelX.BitmapFont := Value;
  2618. FUIRotateAxisLabelY.BitmapFont := Value;
  2619. FUIRotateAxisLabelZ.BitmapFont := Value;
  2620. FUIVisibleInfoLabels.BitmapFont := Value;
  2621. end;
  2622. end;
  2623. function TgxGizmoEx.InternalGetPickedObjects(const x1, y1, x2, y2: Integer; const guessCount: Integer): TgxPickList;
  2624. procedure AddObjectToPicklList(const root: TgxBaseSceneObject; PickList: TgxPickList; X, Y: Integer);
  2625. var
  2626. t: Integer;
  2627. dist: Single;
  2628. rayStart, rayVector, iPoint, iNormal: TVector4f;
  2629. begin
  2630. SetVector(rayStart, Viewer.Camera.AbsolutePosition);
  2631. SetVector(rayVector, Viewer.Buffer.ScreenToVector(AffineVectorMake(X, Viewer.Height - Y, 0)));
  2632. NormalizeVector(rayVector);
  2633. for t := 0 to root.Count - 1 do
  2634. if root[t].Visible then
  2635. begin
  2636. if (root[t].RayCastIntersect(rayStart, rayVector, @iPoint, @iNormal)) and
  2637. (VectorDotProduct(rayVector, iNormal) < 0) then
  2638. if PickList.FindObject(root[t]) = -1 then
  2639. begin
  2640. dist := VectorLength(VectorSubtract(iPoint, rayStart));
  2641. PickList.AddHit(root[t], nil, dist, 0);
  2642. end;
  2643. AddObjectToPicklList(root[t], PickList, X, Y);
  2644. end;
  2645. end;
  2646. var
  2647. I, J: Integer;
  2648. minx, miny, maxx, maxy: Integer;
  2649. begin
  2650. case FPickMode of
  2651. pmGetPickedObjects:
  2652. begin
  2653. Result := Viewer.Buffer.GetPickedObjects(rect(x1, y1, x2, y2), guessCount);
  2654. end;
  2655. pmRayCast:
  2656. begin
  2657. Result := TgxPickList.Create(psMinDepth);
  2658. maxX := MaxInteger(x1, x2);
  2659. maxY := MaxInteger(Y1, Y2);
  2660. minX := MinInteger(x1, x2);
  2661. minY := MinInteger(Y1, Y2);
  2662. for J := minY to maxY do
  2663. for I := minX to maxX do
  2664. //uploading to exclude hanging of application :)
  2665. if (I mod 4 = 0) or (J mod 4 = 0) then
  2666. AddObjectToPicklList(RootObjects, Result, I, J);
  2667. AddObjectToPicklList(RootGizmo, Result, round((x1 + x2) * 0.5), round((y1 + y2) * 0.5));
  2668. end;
  2669. else
  2670. begin
  2671. Result := nil;
  2672. Assert(False, strUnknownType);
  2673. end;
  2674. end;
  2675. end;
  2676. procedure TgxGizmoEx.Loaded;
  2677. begin
  2678. inherited;
  2679. SetGizmoExThickness(GizmoThickness);
  2680. end;
  2681. //------------------------------------------------------------------------------
  2682. procedure TgxGizmoEx.UpdateVisibleInfoLabels;
  2683. var
  2684. T: string;
  2685. X, Y, Z: Single;
  2686. obj: TgxBaseSceneObject;
  2687. begin
  2688. t := '';
  2689. X := 0;
  2690. Y := 0;
  2691. Z := 0;
  2692. if FSelectedObjects.Count - 1 < 0 then
  2693. Exit;
  2694. if (FSelectedObjects.Count - 1 = 0) and (vliName in FVisibleVisibleInfoLabels) then
  2695. t := TgxBaseSceneObject(FSelectedObjects[0]).Name;
  2696. if vliOperation in FVisibleVisibleInfoLabels then
  2697. begin
  2698. begin
  2699. if Length(t) > 0 then
  2700. T := T + ' - ';
  2701. case Operation of
  2702. gopNone: T := T + 'Selected';
  2703. gopMove: T := T + 'Move';
  2704. gopRotate: T := T + 'Rotate';
  2705. gopScale: T := T + 'Scale';
  2706. end;
  2707. end;
  2708. end;
  2709. if vliCoords in FVisibleVisibleInfoLabels then
  2710. begin
  2711. if (Operation <> gopNone) then
  2712. begin
  2713. if Length(t) > 0 then
  2714. T := T + ' - ';
  2715. if FinfoLabelCoordType = ilcChanging then
  2716. begin
  2717. obj := TgxBaseSceneObject(FSelectedObjects[0]);
  2718. case Operation of
  2719. gopMove:
  2720. begin
  2721. X := obj.Position.X;
  2722. Y := obj.Position.Y;
  2723. Z := obj.Position.Z;
  2724. end;
  2725. gopRotate:
  2726. begin
  2727. X := obj.Rotation.X;
  2728. Y := obj.Rotation.Y;
  2729. Z := obj.Rotation.Z;
  2730. end;
  2731. gopScale:
  2732. begin
  2733. X := obj.Scale.X;
  2734. Y := obj.Scale.Y;
  2735. Z := obj.Scale.Z;
  2736. end;
  2737. end;
  2738. T := T + '[' + Format('%2.2f', [X]);
  2739. T := T + ' ' + Format('%2.2f', [Y]);
  2740. T := T + ' ' + Format('%2.2f', [Z]) + ']';
  2741. end
  2742. else
  2743. begin
  2744. T := T + '[' + Format('%2.2f', [FChangeRate.X]);
  2745. T := T + ' ' + Format('%2.2f', [FChangeRate.Y]);
  2746. T := T + ' ' + Format('%2.2f', [FChangeRate.Z]) + ']';
  2747. end;
  2748. end;
  2749. end;
  2750. FUIVisibleInfoLabels.Text := T;
  2751. FUIVisibleInfoLabels.StructureChanged;
  2752. end;
  2753. //------------------------------------------------------------------------------
  2754. function TgxGizmoEx.CheckObjectInExcludeList(const Obj: TgxBaseSceneObject): Boolean;
  2755. var
  2756. I: Integer;
  2757. begin
  2758. Result := False;
  2759. if FExcludeObjects then
  2760. begin
  2761. for I := 0 to FExcludeObjectsList.Count - 1 do
  2762. begin
  2763. if UpperCase(obj.Name) = UpperCase(FExcludeObjectsList[I]) then
  2764. begin
  2765. Result := True;
  2766. Exit;
  2767. end;
  2768. end;
  2769. end;
  2770. end;
  2771. function TgxGizmoEx.CheckClassNameInExcludeList(const Obj: TgxBaseSceneObject): Boolean;
  2772. var
  2773. I: Integer;
  2774. begin
  2775. Result := False;
  2776. if FExcludeClassName then
  2777. begin
  2778. for I := 0 to FExcludeClassNameList.Count - 1 do
  2779. begin
  2780. if UpperCase(obj.ClassName) = UpperCase(FExcludeClassNameList[I]) then
  2781. begin
  2782. Result := True;
  2783. Exit;
  2784. end;
  2785. end;
  2786. end;
  2787. end;
  2788. function TgxGizmoEx.MouseWorldPos(const X, Y: Integer): TVector4f;
  2789. var
  2790. v: TVector4f;
  2791. InvertedY: Integer;
  2792. begin
  2793. InvertedY := Round(Viewer.Height) - Y;
  2794. SetVector(v, X, InvertedY, 0);
  2795. case selAxis of
  2796. gaX: Viewer.Buffer.ScreenVectorIntersectWithPlaneXZ(v, FUIRootHelpers.AbsolutePosition.Y, Result);
  2797. gaY: Viewer.Buffer.ScreenVectorIntersectWithPlaneYZ(v, FUIRootHelpers.AbsolutePosition.X, Result);
  2798. gaZ: Viewer.Buffer.ScreenVectorIntersectWithPlaneYZ(v, FUIRootHelpers.AbsolutePosition.X, Result);
  2799. gaXY: Viewer.Buffer.ScreenVectorIntersectWithPlaneXY(v, FUIRootHelpers.AbsolutePosition.Z, Result);
  2800. gaYZ: Viewer.Buffer.ScreenVectorIntersectWithPlaneYZ(v, FUIRootHelpers.AbsolutePosition.X, Result);
  2801. gaXZ: Viewer.Buffer.ScreenVectorIntersectWithPlaneXZ(v, FUIRootHelpers.AbsolutePosition.Y, Result);
  2802. gaXYZ:
  2803. begin
  2804. Viewer.Buffer.ScreenVectorIntersectWithPlaneXZ(v, FUIRootHelpers.AbsolutePosition.Y, Result);
  2805. MakeVector(Result, InvertedY / 25, InvertedY / 25, InvertedY / 25);
  2806. end;
  2807. end;
  2808. end;
  2809. procedure TgxGizmoEx.ActivatingElements(PickList: TgxPickList);
  2810. procedure ActlightRotateLine(const line: TgxLines; const dark: TVector4f);
  2811. var
  2812. v: TVector4f;
  2813. I: Integer;
  2814. begin
  2815. line.options := [loUseNodeColorForLines];
  2816. for I := 0 to line.Nodes.Count - 1 do
  2817. begin
  2818. v := FUIRotateLineXY.AbsoluteToLocal((line.LocalToAbsolute(line.Nodes[I].AsVector)));
  2819. if v.Z >= 0 then
  2820. begin
  2821. TgxLinesNode(line.Nodes[I]).Color.Color := FSelectedColor.Color;
  2822. TgxLinesNode(line.Nodes[I]).Color.Alpha := 1;
  2823. end
  2824. else
  2825. begin
  2826. TgxLinesNode(line.Nodes[I]).Color.Color := dark;
  2827. TgxLinesNode(line.Nodes[I]).Color.Alpha := 1;
  2828. end;
  2829. end;
  2830. end;
  2831. procedure DeActlightRotateLine(const line: TgxLines; const dark: TVector4f);
  2832. var
  2833. v: TVector4f;
  2834. I: Integer;
  2835. begin
  2836. line.options := [loUseNodeColorForLines];
  2837. for I := 0 to line.Nodes.Count - 1 do
  2838. begin
  2839. v := FUIRotateLineXY.AbsoluteToLocal((line.LocalToAbsolute(line.Nodes[I].AsVector)));
  2840. if v.Z >= 0 then
  2841. begin
  2842. TgxLinesNode(line.Nodes[I]).Color.Color := dark;
  2843. TgxLinesNode(line.Nodes[I]).Color.Alpha := 1;
  2844. end
  2845. else
  2846. begin
  2847. TgxLinesNode(line.Nodes[I]).Color.Color := dark;
  2848. TgxLinesNode(line.Nodes[I]).Color.Alpha := 0;
  2849. end;
  2850. end;
  2851. end;
  2852. procedure ActlightLine(const line: TgxLines);
  2853. begin
  2854. line.LineColor.color := FSelectedColor.Color;
  2855. line.Options := [];
  2856. end;
  2857. procedure DeActlightLine(const line: TgxLines; const dark: TVector4f; alterStyle: Boolean = False);
  2858. begin
  2859. with line.LineColor do
  2860. if (AsWinColor = FSelectedColor.AsWinColor) then
  2861. begin
  2862. color := dark;
  2863. line.Options := [];
  2864. if alterStyle then
  2865. line.options := [loUseNodeColorForLines];
  2866. end;
  2867. end;
  2868. procedure ActlightRotateArrowLine(const line: TgxLines; Color: TVector4f);
  2869. begin
  2870. line.LineColor.color := Color;
  2871. line.Options := [];
  2872. end;
  2873. procedure DeActlightRotateArrowLine(const line: TgxLines; const dark: TVector4f);
  2874. begin
  2875. if not VectorEquals(line.LineColor.Color, dark) then
  2876. begin
  2877. line.LineColor.Color := dark;
  2878. line.Options := [];
  2879. end;
  2880. end;
  2881. procedure Actlightobject(const aObject: TgxCustomSceneObject);
  2882. begin
  2883. aObject.Material.FrontProperties.Diffuse.Alpha := 0.4;
  2884. aObject.Visible := True;
  2885. end;
  2886. procedure DeActlightObject(const aObject: TgxCustomSceneObject);
  2887. begin
  2888. aObject.Visible := False;
  2889. end;
  2890. procedure ActlightText(const FlatText: TgxFlatText);
  2891. begin
  2892. FlatText.ModulateColor.Color := FSelectedColor.Color;
  2893. end;
  2894. procedure DeActlightText(const FlatText: TgxFlatText; const dark: TVector4f);
  2895. begin
  2896. with FlatText.ModulateColor do
  2897. if AsWinColor = FSelectedColor.AsWinColor then
  2898. Color := dark;
  2899. end;
  2900. procedure ActlightTextRotate(const FlatText: TgxFlatText; Color: TVector4f);
  2901. begin
  2902. FlatText.ModulateColor.Color := Color;
  2903. end;
  2904. procedure DeActlightTextRotate(const FlatText: TgxFlatText; const dark: TVector4f);
  2905. begin
  2906. with FlatText.ModulateColor do
  2907. if not VectorEquals(Color, dark) then
  2908. Color := dark;
  2909. end;
  2910. procedure AssingOpertion(const aOperation: TgxGizmoExOperation; const axis: TgxGizmoExAxis);
  2911. begin
  2912. if Operation <> aOperation then
  2913. Operation := aOperation;
  2914. if SelAxis <> axis then
  2915. SelAxis := axis;
  2916. end;
  2917. var
  2918. I: Integer;
  2919. begin
  2920. AssingOpertion(gopNone, gaNone);
  2921. if FUIRootMovement.Visible then
  2922. begin
  2923. DeActlightObject(FUIMovementPlaneXY);
  2924. DeActlightObject(FUIMovementPlaneXZ);
  2925. DeActlightObject(FUIMovementPlaneYZ);
  2926. DeActlightLine(FUIMovementLineX, clrRed);
  2927. DeActlightLine(FUIMovementLineY, clrLime);
  2928. DeActlightLine(FUIMovementLineZ, clrBlue);
  2929. DeActlightLine(FUIMovementLineXY, clrWhite, True);
  2930. DeActlightLine(FUIMovementLineXZ, clrWhite, True);
  2931. DeActlightLine(FUIMovementLineYZ, clrWhite, True);
  2932. end;
  2933. if FUIRootRotate.Visible then
  2934. begin
  2935. DeActlightObject(FUIRotateDiskXY);
  2936. DeActlightLine(FUIRotateLineXZ, clrgray70);
  2937. DeActlightRotateArrowLine(FUIRotateLineArrowX, clrgray70);
  2938. DeActlightRotateArrowLine(FUIRotateLineArrowY, clrgray70);
  2939. DeActlightRotateArrowLine(FUIRotateLineArrowZ, clrgray70);
  2940. DeActlightRotateLine(FUIRotateLineX, clrRed);
  2941. DeActlightRotateLine(FUIRotateLineY, clrLime);
  2942. DeActlightRotateLine(FUIRotateLineZ, clrBlue);
  2943. DeActlightTextRotate(FUIRotateAxisLabelX, clrgray70);
  2944. DeActlightTextRotate(FUIRotateAxisLabelY, clrgray70);
  2945. DeActlightTextRotate(FUIRotateAxisLabelZ, clrgray70);
  2946. end;
  2947. if FUIRootScale.Visible then
  2948. begin
  2949. DeActlightLine(FUIScaleLineX, clrRed);
  2950. DeActlightLine(FUIScaleLineY, clrLime);
  2951. DeActlightLine(FUIScaleLineZ, clrBlue);
  2952. DeActlightLine(FUIScaleLineXY, clrWhite, True);
  2953. DeActlightLine(FUIScaleLineYZ, clrWhite, True);
  2954. DeActlightLine(FUIScaleLineXZ, clrWhite, True);
  2955. DeActlightObject(FUIScalePlaneXY);
  2956. DeActlightObject(FUIScalePlaneXZ);
  2957. DeActlightObject(FUIScalePlaneYZ);
  2958. DeActlightObject(FUIScalePlaneXYZ);
  2959. end;
  2960. DeActlightText(FUIAxisLabelX, clrRed);
  2961. DeActlightText(FUIAxisLabelY, clrLime);
  2962. DeActlightText(FUIAxisLabelZ, clrBlue);
  2963. for I := 0 to pickList.Count - 1 do
  2964. with pickList do
  2965. begin
  2966. if FUIRootMovement.Visible then
  2967. begin
  2968. if hit[I] = FUIICMovementLineXY then
  2969. begin
  2970. AssingOpertion(gopMove, gaXY);
  2971. ActlightObject(FUIMovementPlaneXY);
  2972. ActlightLine(FUIMovementLineX);
  2973. ActlightLine(FUIMovementLineY);
  2974. ActlightLine(FUIMovementLineXY);
  2975. ActlightText(FUIAxisLabelX);
  2976. ActlightText(FUIAxisLabelY);
  2977. Break;
  2978. end;
  2979. if hit[I] = FUIICMovementLineXZ then
  2980. begin
  2981. AssingOpertion(gopMove, gaXZ);
  2982. Actlightobject(FUIMovementPlaneXZ);
  2983. ActlightLine(FUIMovementLineX);
  2984. ActlightLine(FUIMovementLineZ);
  2985. ActlightLine(FUIMovementLineXZ);
  2986. ActlightText(FUIAxisLabelX);
  2987. ActlightText(FUIAxisLabelZ);
  2988. Break;
  2989. end;
  2990. if hit[I] = FUIICMovementLineYZ then
  2991. begin
  2992. AssingOpertion(gopMove, gaYZ);
  2993. Actlightobject(FUIMovementPlaneYZ);
  2994. ActlightLine(FUIMovementLineY);
  2995. ActlightLine(FUIMovementLineZ);
  2996. ActlightLine(FUIMovementLineYZ);
  2997. ActlightText(FUIAxisLabelY);
  2998. ActlightText(FUIAxisLabelZ);
  2999. Break;
  3000. end;
  3001. if hit[I] = FUIICMovementLineX then
  3002. begin
  3003. AssingOpertion(gopMove, gaX);
  3004. ActlightLine(FUIMovementLineX);
  3005. ActlightText(FUIAxisLabelX);
  3006. Break;
  3007. end;
  3008. if hit[I] = FUIICMovementLineY then
  3009. begin
  3010. AssingOpertion(gopMove, gaY);
  3011. ActlightLine(FUIMovementLineY);
  3012. ActlightText(FUIAxisLabelY);
  3013. Break;
  3014. end;
  3015. if hit[I] = FUIICMovementLineZ then
  3016. begin
  3017. AssingOpertion(gopMove, gaZ);
  3018. ActlightLine(FUIMovementLineZ);
  3019. ActlightText(FUIAxisLabelZ);
  3020. Break;
  3021. end;
  3022. end;
  3023. if FUIRootRotate.Visible then
  3024. begin
  3025. if hit[I] = FUIICRotateTorusX then
  3026. begin
  3027. AssingOpertion(gopRotate, gaX);
  3028. ActlightRotateLine(FUIRotateLineX, clrgray50);
  3029. ActlightRotateArrowLine(FUIRotateLineArrowX, clrRed);
  3030. DeActlightTextRotate(FUIRotateAxisLabelX, clrRed);
  3031. Break;
  3032. end;
  3033. if hit[I] = FUIICRotateTorusY then
  3034. begin
  3035. AssingOpertion(gopRotate, gaY);
  3036. ActlightRotateLine(FUIRotateLineY, clrgray50);
  3037. ActlightRotateArrowLine(FUIRotateLineArrowY, clrLime);
  3038. DeActlightTextRotate(FUIRotateAxisLabelY, clrLime);
  3039. Break;
  3040. end;
  3041. if hit[I] = FUIICRotateTorusZ then
  3042. begin
  3043. AssingOpertion(gopRotate, gaZ);
  3044. ActlightRotateLine(FUIRotateLineZ, clrgray50);
  3045. ActlightRotateArrowLine(FUIRotateLineArrowZ, clrBlue);
  3046. DeActlightTextRotate(FUIRotateAxisLabelZ, clrBlue);
  3047. Break;
  3048. end;
  3049. if hit[I] = FUIICRotateSphereXY then
  3050. begin
  3051. AssingOpertion(gopRotate, gaXY);
  3052. ActlightObject(FUIRotateDiskXY);
  3053. DeActlightTextRotate(FUIRotateAxisLabelX, clrRed);
  3054. DeActlightTextRotate(FUIRotateAxisLabelY, clrLime);
  3055. ActlightRotateArrowLine(FUIRotateLineArrowX, clrRed);
  3056. ActlightRotateArrowLine(FUIRotateLineArrowY, clrLime);
  3057. Break;
  3058. end;
  3059. if hit[I] = FUIICRotateTorusXZ then
  3060. begin
  3061. AssingOpertion(gopRotate, gaXZ);
  3062. ActlightLine(FUIRotateLineXZ);
  3063. DeActlightTextRotate(FUIRotateAxisLabelX, clrRed);
  3064. DeActlightTextRotate(FUIRotateAxisLabelZ, clrBlue);
  3065. ActlightRotateArrowLine(FUIRotateLineArrowX, clrRed);
  3066. ActlightRotateArrowLine(FUIRotateLineArrowZ, clrBlue);
  3067. Break;
  3068. end;
  3069. end;
  3070. if FUIRootScale.Visible then
  3071. begin
  3072. if hit[I] = FUIICScaleLineX then
  3073. begin
  3074. AssingOpertion(gopScale, gaX);
  3075. ActlightLine(FUIScaleLineX);
  3076. ActlightText(FUIAxisLabelX);
  3077. Break;
  3078. end;
  3079. if hit[I] = FUIICScaleLineY then
  3080. begin
  3081. AssingOpertion(gopScale, gaY);
  3082. ActlightLine(FUIScaleLineY);
  3083. ActlightText(FUIAxisLabelY);
  3084. Break;
  3085. end;
  3086. if hit[I] = FUIICScaleLineZ then
  3087. begin
  3088. AssingOpertion(gopScale, gaZ);
  3089. ActlightLine(FUIScaleLineZ);
  3090. ActlightText(FUIAxisLabelZ);
  3091. Break;
  3092. end;
  3093. if hit[I] = FUIICScaleLineXY then
  3094. begin
  3095. AssingOpertion(gopScale, gaXY);
  3096. Actlightobject(FUIScalePlaneXY);
  3097. ActlightLine(FUIScaleLineXY);
  3098. ActlightText(FUIAxisLabelX);
  3099. ActlightText(FUIAxisLabelY);
  3100. Break;
  3101. end;
  3102. if hit[I] = FUIICScaleLineXZ then
  3103. begin
  3104. AssingOpertion(gopScale, gaXZ);
  3105. Actlightobject(FUIScalePlaneXZ);
  3106. ActlightLine(FUIScaleLineXZ);
  3107. ActlightText(FUIAxisLabelX);
  3108. ActlightText(FUIAxisLabelZ);
  3109. Break;
  3110. end;
  3111. if hit[I] = FUIICScaleLineYZ then
  3112. begin
  3113. AssingOpertion(gopScale, gaYZ);
  3114. Actlightobject(FUIScalePlaneYZ);
  3115. ActlightLine(FUIScaleLineYZ);
  3116. ActlightText(FUIAxisLabelY);
  3117. ActlightText(FUIAxisLabelZ);
  3118. Break;
  3119. end;
  3120. if hit[I] = FUIICScaleLineXYZ then
  3121. begin
  3122. AssingOpertion(gopScale, gaXYZ);
  3123. Actlightobject(FUIScalePlaneXYZ);
  3124. ActlightText(FUIAxisLabelX);
  3125. ActlightText(FUIAxisLabelY);
  3126. ActlightText(FUIAxisLabelZ);
  3127. Actlightobject(FUIScalePlaneXY);
  3128. ActlightLine(FUIScaleLineXY);
  3129. Actlightobject(FUIScalePlaneYZ);
  3130. ActlightLine(FUIScaleLineYZ);
  3131. Actlightobject(FUIScalePlaneXZ);
  3132. ActlightLine(FUIScaleLineXZ);
  3133. Break;
  3134. end;
  3135. end;
  3136. end;
  3137. end;
  3138. procedure TgxGizmoEx.ViewerMouseMove(const X, Y: Integer);
  3139. var
  3140. pickList: TgxPickList;
  3141. mousePos: TVector4f;
  3142. includeCh: Boolean;
  3143. function FindParent(parent: TgxBaseSceneObject): Boolean;
  3144. begin
  3145. Result := False;
  3146. if assigned(parent) then
  3147. begin
  3148. if parent = rootobjects then
  3149. Exit;
  3150. Result := FSelectedObjects.FindObject(parent) = -1;
  3151. end;
  3152. end;
  3153. procedure OpeMove(mousePos: TVector4f);
  3154. var
  3155. vec1, vec2: TVector4f;
  3156. quantizedMousePos, quantizedMousePos2: TVector4f;
  3157. I: Integer;
  3158. begin
  3159. if VectorNorm(lastMousePos) = 0 then
  3160. Exit;
  3161. for I := 0 to 3 do
  3162. begin
  3163. quantizedMousePos.V[I] := (Round(mousePos.V[I] / MoveCoef)) * MoveCoef;
  3164. quantizedMousePos2.V[I] := (Round(lastMousePos.V[I] / MoveCoef)) * MoveCoef;
  3165. end;
  3166. case SelAxis of
  3167. gaX:
  3168. begin
  3169. MakeVector(vec1, quantizedMousePos.X, 0, 0);
  3170. makeVector(vec2, quantizedMousePos2.X, 0, 0);
  3171. end;
  3172. gaY:
  3173. begin
  3174. MakeVector(vec1, 0, quantizedMousePos.Y, 0);
  3175. makeVector(vec2, 0, quantizedMousePos2.Y, 0);
  3176. end;
  3177. gaZ:
  3178. begin
  3179. MakeVector(vec1, 0, 0, quantizedMousePos.Z);
  3180. makeVector(vec2, 0, 0, quantizedMousePos2.Z);
  3181. end;
  3182. else
  3183. begin
  3184. vec1 := quantizedMousePos;
  3185. vec2 := quantizedMousePos2;
  3186. end;
  3187. end;
  3188. SubtractVector(vec1, vec2);
  3189. //Control of object flying to infinity
  3190. if (VectorLength(Vec1) > 5) then
  3191. Exit;// prevents NAN problems
  3192. case SelAxis of
  3193. gaX: fchangerate.X := fchangerate.X + vec1.X;
  3194. gaY: fchangerate.Y := fchangerate.Y + vec1.Y;
  3195. gaZ: fchangerate.Z := fchangerate.Z + vec1.Z;
  3196. gaXY:
  3197. begin
  3198. fchangerate.X := fchangerate.X + vec1.X;
  3199. fchangerate.Y := fchangerate.Y + vec1.Y;
  3200. end;
  3201. gaYZ:
  3202. begin
  3203. fchangerate.Z := fchangerate.Z + vec1.Z;
  3204. fchangerate.Y := fchangerate.Y + vec1.Y;
  3205. end;
  3206. gaXZ:
  3207. begin
  3208. fchangerate.X := fchangerate.X + vec1.X;
  3209. fchangerate.Z := fchangerate.Z + vec1.Z;
  3210. end;
  3211. end;
  3212. for I := 0 to FSelectedObjects.Count - 1 do
  3213. with TgxBaseSceneObject(FSelectedObjects.Hit[I]) do
  3214. begin
  3215. IncludeCh := True;
  3216. if not CanChangeWithChildren and (parent <> RootObjects) and (FSelectedObjects.Count - 1 > 0) then
  3217. IncludeCh := FindParent(parent);
  3218. if IncludeCh then
  3219. case Ord(ReferenceCoordSystem) of
  3220. 0: AbsolutePosition := VectorAdd(absoluteposition, vec1);
  3221. 1:
  3222. begin
  3223. vec1 := LocalToAbsolute(vec1);
  3224. absoluteposition := VectorAdd(absoluteposition, vec1);
  3225. end;
  3226. end;
  3227. end;
  3228. end;
  3229. procedure OpeRotate(const X, Y: Integer);
  3230. var
  3231. vec1: TVector4f;
  3232. rotV: TAffineVector;
  3233. pmat: TMatrix4f;
  3234. I: Integer;
  3235. IncludeCh: Boolean;
  3236. v: TVector4f;
  3237. begin
  3238. vec1.X := 0;
  3239. vec1.Y := 0;
  3240. if abs(X - mx) >= RotationCoef then
  3241. begin
  3242. if RotationCoef > 1 then
  3243. vec1.X := RotationCoef * (Round((X - mx) / (RotationCoef)))
  3244. else
  3245. vec1.X := RotationCoef * (X - mx);
  3246. mx := X;
  3247. end;
  3248. if abs(Y - my) >= RotationCoef then
  3249. begin
  3250. if RotationCoef > 1 then
  3251. vec1.Y := RotationCoef * (Round((Y - my) / (RotationCoef)))
  3252. else
  3253. vec1.Y := RotationCoef * (Y - my);
  3254. my := Y;
  3255. end;
  3256. vec1.Z := 0;
  3257. vec1.W := 0;
  3258. case SelAxis of
  3259. gaX: fchangerate.Y := fchangerate.Y + vec1.Y;
  3260. gaY: fchangerate.X := fchangerate.X + vec1.X;
  3261. gaZ: fchangerate.Y := fchangerate.Y + vec1.Y;
  3262. end;
  3263. for I := 0 to FSelectedObjects.Count - 1 do
  3264. with FSelectedObjects do
  3265. begin
  3266. case Ord(FReferenceCoordSystem) of
  3267. 0: v := FUIRootHelpers.AbsolutePosition;
  3268. 1: v := TgxBaseSceneObject(Hit[I]).AbsolutePosition;
  3269. end;
  3270. IncludeCh := True;
  3271. if not CanChangeWithChildren
  3272. and (TgxBaseSceneObject(Hit[I]).parent <> RootObjects)
  3273. and (FSelectedObjects.Count - 1 > 0) then
  3274. IncludeCh := FindParent(TgxBaseSceneObject(Hit[I]).parent);
  3275. pmat := TgxBaseSceneObject(Hit[I]).parent.InvAbsoluteMatrix;
  3276. SetVector(pmat.W, NullHmgPoint);
  3277. if IncludeCh then
  3278. case SelAxis of
  3279. gaX:
  3280. begin
  3281. rotV := VectorTransform(XVector, pmat);
  3282. RotateAroundArbitraryAxis(TgxBaseSceneObject(Hit[I]), rotV, AffineVectorMake(v), vec1.Y);
  3283. end;
  3284. gaY:
  3285. begin
  3286. rotV := VectorTransform(YVector, pmat);
  3287. RotateAroundArbitraryAxis(TgxBaseSceneObject(Hit[I]), rotV, AffineVectorMake(v), vec1.X);
  3288. end;
  3289. gaZ:
  3290. begin
  3291. rotV := VectorTransform(ZVector, pmat);
  3292. RotateAroundArbitraryAxis(TgxBaseSceneObject(Hit[I]), rotV, AffineVectorMake(v), vec1.Y);
  3293. end;
  3294. gaXY:
  3295. begin
  3296. rotV := VectorTransform(XVector, pmat);
  3297. RotateAroundArbitraryAxis(TgxBaseSceneObject(Hit[I]), rotV, AffineVectorMake(v), vec1.Y);
  3298. rotV := VectorTransform(YVector, pmat);
  3299. RotateAroundArbitraryAxis(TgxBaseSceneObject(Hit[I]), rotV, AffineVectorMake(v), vec1.X);
  3300. end;
  3301. gaXZ:
  3302. begin
  3303. rotV := VectorTransform(XVector, pmat);
  3304. RotateAroundArbitraryAxis(TgxBaseSceneObject(Hit[I]), rotV, AffineVectorMake(v), vec1.Y);
  3305. rotV := VectorTransform(ZVector, pmat);
  3306. RotateAroundArbitraryAxis(TgxBaseSceneObject(Hit[I]), rotV, AffineVectorMake(v), vec1.X);
  3307. end;
  3308. gaYZ:
  3309. begin
  3310. rotV := VectorTransform(YVector, pmat);
  3311. RotateAroundArbitraryAxis(TgxBaseSceneObject(Hit[I]), rotV, AffineVectorMake(v), vec1.Y);
  3312. rotV := VectorTransform(ZVector, pmat);
  3313. RotateAroundArbitraryAxis(TgxBaseSceneObject(Hit[I]), rotV, AffineVectorMake(v), vec1.X);
  3314. end;
  3315. end;
  3316. end;
  3317. end;
  3318. procedure OpeScale(const mousePos: TVector4f);
  3319. var
  3320. vec1, vec2: TVector4f;
  3321. quantizedMousePos, quantizedMousePos2: TVector4f;
  3322. t: Integer;
  3323. begin
  3324. if VectorNorm(lastMousePos) = 0 then
  3325. Exit;
  3326. for t := 0 to 3 do
  3327. begin
  3328. quantizedMousePos.V[t] := (Round(mousePos.V[t] / ScaleCoef)) * FScaleCoef;
  3329. quantizedMousePos2.V[t] := (Round(lastMousePos.V[t] / FScaleCoef)) * FScaleCoef;
  3330. end;
  3331. case SelAxis of
  3332. gaX:
  3333. begin
  3334. MakeVector(vec1, quantizedMousePos.X, 0, 0);
  3335. makeVector(vec2, quantizedMousePos2.X, 0, 0);
  3336. end;
  3337. gaY:
  3338. begin
  3339. MakeVector(vec1, 0, quantizedMousePos.Y, 0);
  3340. makeVector(vec2, 0, quantizedMousePos2.Y, 0);
  3341. end;
  3342. gaZ:
  3343. begin
  3344. MakeVector(vec1, 0, 0, quantizedMousePos.Z);
  3345. makeVector(vec2, 0, 0, quantizedMousePos2.Z);
  3346. end;
  3347. gaXY:
  3348. begin
  3349. MakeVector(vec1, quantizedMousePos.X, quantizedMousePos.Y, 0);
  3350. makeVector(vec2, quantizedMousePos2.X, quantizedMousePos2.Y, 0);
  3351. end;
  3352. gaXYZ:
  3353. begin
  3354. MakeVector(vec1, quantizedMousePos.X, quantizedMousePos.Y, quantizedMousePos.Z);
  3355. makeVector(vec2, quantizedMousePos2.X, quantizedMousePos2.Y, quantizedMousePos2.Z);
  3356. end
  3357. else
  3358. begin
  3359. vec1 := quantizedMousePos;
  3360. vec2 := quantizedMousePos2;
  3361. end;
  3362. end;
  3363. SubtractVector(vec1, vec2);
  3364. if (VectorLength(Vec1) > 5) then
  3365. Exit;// prevents NAN problems
  3366. case SelAxis of
  3367. gaX: fchangerate.X := fchangerate.X + vec1.X;
  3368. gaY: fchangerate.Y := fchangerate.Y + vec1.Y;
  3369. gaZ: fchangerate.Z := fchangerate.Z + vec1.Z;
  3370. gaXY:
  3371. begin
  3372. fchangerate.X := fchangerate.X + vec1.X;
  3373. fchangerate.Y := fchangerate.Y + vec1.Y;
  3374. end;
  3375. gaYZ:
  3376. begin
  3377. fchangerate.Z := fchangerate.Z + vec1.Z;
  3378. fchangerate.Y := fchangerate.Y + vec1.Y;
  3379. end;
  3380. gaXZ:
  3381. begin
  3382. fchangerate.X := fchangerate.X + vec1.X;
  3383. fchangerate.Z := fchangerate.Z + vec1.Z;
  3384. end;
  3385. gaXYZ:
  3386. fchangerate := VectorAdd(fchangerate, AffineVectorMake(vec1));
  3387. end;
  3388. for t := 0 to FSelectedObjects.Count - 1 do
  3389. with TgxBaseSceneObject(FSelectedObjects.Hit[t]) do
  3390. begin
  3391. IncludeCh := True;
  3392. if not CanChangeWithChildren and (parent <> RootObjects) and (FSelectedObjects.Count - 1 > 0) then
  3393. IncludeCh := FindParent(parent);
  3394. FUIRootScale.Scale.Translate(vec1);
  3395. if IncludeCh then
  3396. begin
  3397. (* case ord(ReferenceCoordSystem) of
  3398. 0:begin
  3399. vec1:=LocalToAbsolute(vec1);
  3400. absoluteScale:=VectorAdd(absolutescale,vec1);
  3401. end;
  3402. 1:Scale.Translate(vec1);
  3403. end; *)
  3404. Scale.Translate(vec1);
  3405. end;
  3406. end;
  3407. end;
  3408. procedure LoopCursorMoving(isvector: Boolean = False);
  3409. {$IFDEF MSWINDOWS}
  3410. var
  3411. R, vR: TRect;
  3412. cp: TPoint;
  3413. {$ENDIF}
  3414. begin
  3415. {$IFDEF MSWINDOWS}
  3416. (* Procedure for moving the cursor from beginning to end
  3417. without loss of operations on the object *)
  3418. GetWindowRect(GetDesktopWindow, R);
  3419. { TODO : E2003 Undeclared identifier: 'Handle' }
  3420. (*GetWindowRect(viewer.Handle, VR);*)
  3421. GLGetCursorPos(cp);
  3422. if cp.Y = R.Bottom - 1 then
  3423. begin
  3424. SetCursorPos(cp.X, R.Top + 3);
  3425. if not isvector then
  3426. my := r.Top - vr.Top
  3427. else
  3428. begin
  3429. lastMousePos := MouseWorldPos(X, r.Top + 3 - vr.Top);
  3430. // entered so that the object does not twitch
  3431. mousepos := lastMousePos;
  3432. end;
  3433. end;
  3434. if cp.Y = R.Top then
  3435. begin
  3436. SetCursorPos(cp.X, R.Bottom - 3);
  3437. if not isvector then
  3438. my := R.Bottom - 1 - vr.top
  3439. else
  3440. begin
  3441. lastMousePos := MouseWorldPos(X, R.Bottom - 1 - vr.top);
  3442. mousepos := lastMousePos;
  3443. end;
  3444. end;
  3445. if cp.X = R.Right - 1 then
  3446. begin
  3447. SetCursorPos(r.Left + 3, cp.Y);
  3448. if not isvector then
  3449. mx := r.Left - vr.Left
  3450. else
  3451. begin
  3452. lastMousePos := MouseWorldPos(r.Left - vr.Left, Y);
  3453. mousepos := lastMousePos;
  3454. end;
  3455. end;
  3456. if cp.X = R.Left then
  3457. begin
  3458. SetCursorPos(r.Right - 3, cp.Y);
  3459. if not isvector then
  3460. mx := r.Right - 1 - vr.Left
  3461. else
  3462. begin
  3463. lastMousePos := MouseWorldPos(r.Right - 1 - vr.Left, Y);
  3464. mousepos := lastMousePos;
  3465. end;
  3466. end;
  3467. {$ENDIF}
  3468. end;
  3469. begin
  3470. if (not Enabled) or (RootGizmo = nil) or (RootObjects = nil) then
  3471. Exit;
  3472. if not FShowMultiSelecting then
  3473. begin
  3474. if (FSelectedObjects.Count - 1 >= 0) and (SelAxis <> gaNone) and moving then
  3475. begin
  3476. mousePos := MouseWorldPos(X, Y);
  3477. //moving object...
  3478. if Operation = gopMove then
  3479. begin
  3480. OpeMove(MousePos);
  3481. end
  3482. else if Operation = gopRotate then
  3483. begin
  3484. if EnableLoopCursorMoving then
  3485. LoopCursorMoving;
  3486. OpeRotate(X, Y);
  3487. if (SelAxis = gax) or (SelAxis = gaz) then
  3488. SetAngleDisk(fchangerate.Y)
  3489. else
  3490. if SelAxis = gaY then
  3491. SetAngleDisk(fchangerate.X);
  3492. end
  3493. else if Operation = gopScale then
  3494. begin
  3495. if EnableLoopCursorMoving then
  3496. LoopCursorMoving(True);
  3497. OpeScale(MousePos);
  3498. end;
  3499. UpdateGizmo;
  3500. mx := X;
  3501. my := Y;
  3502. lastMousePos := mousePos;
  3503. Exit;
  3504. end;
  3505. Assert(FViewer <> nil, 'Viewer not Assigned to gizmo');
  3506. picklist := InternalGetPickedObjects(X - 1, Y - 1, X + 1, Y + 1, 8);//Viewer.buffer.GetPickedObjects(rect(x-1, y-1, x+1, y+1), 8);
  3507. ActivatingElements(picklist);
  3508. picklist.Free;
  3509. end;
  3510. if EnableMultiSelection and (Operation = gopNone) and (SelAxis = gaNone) then
  3511. MultiSelMouseMove(X, Y);
  3512. mx := X;
  3513. my := Y;
  3514. end;
  3515. procedure TgxGizmoEx.ViewerMouseDown(const X, Y: Integer);
  3516. function SetInitialDiskPostition(aObject, aObject2: TgxCustomSceneObject): TVector4f;
  3517. var
  3518. rayStart, rayVector, iPoint, iNormal: TVector4f;
  3519. begin
  3520. if (Viewer = nil) then
  3521. Exit;
  3522. if (Viewer.Camera = nil) then
  3523. Exit;
  3524. SetVector(rayStart, Viewer.Camera.AbsolutePosition);
  3525. SetVector(rayVector, Viewer.Buffer.ScreenToVector(AffineVectorMake(X, Viewer.Height - Y, 0)));
  3526. NormalizeVector(rayVector);
  3527. if aObject.RayCastIntersect(rayStart, rayVector, @iPoint, @iNormal) then
  3528. aObject2.Up.Setvector(VectorNormalize(VectorSubtract(iPoint, FUIRootHelpers.Position.AsVector)));
  3529. aObject2.StructureChanged;
  3530. Result := iPoint;
  3531. end;
  3532. var
  3533. pick: TgxPickList;
  3534. I: Integer;
  3535. gotPick: Boolean;
  3536. begin
  3537. if not Enabled or
  3538. not Assigned(RootGizmo) or
  3539. not Assigned(RootObjects) or
  3540. not Assigned(Viewer) then
  3541. Exit;
  3542. mx := X;
  3543. my := Y;
  3544. pick := InternalGetPickedObjects(X - 1, Y - 1, X + 1, Y + 1);
  3545. gotPick := False;
  3546. for I := 0 to pick.Count - 1 do
  3547. if (pick.Hit[I] is TgxGizmoExUIDisk) or
  3548. (pick.Hit[I] is TgxGizmoExUISphere) or
  3549. (pick.Hit[I] is TgxGizmoExUIPolyGon) or
  3550. (pick.Hit[I] is TgxGizmoExuITorus) or
  3551. (pick.Hit[I] is TgxGizmoExUIFrustrum) or
  3552. (pick.Hit[I] is TgxGizmoExUIArrowLine) or
  3553. (pick.Hit[I] is TgxGizmoExUIFlatText) or
  3554. (pick.Hit[I] is TgxGizmoExUILines) then
  3555. begin
  3556. gotPick := True;
  3557. case fOperation of
  3558. gopRotate:
  3559. begin
  3560. if (pick.Hit[I] = FUIICRotateTorusX) then
  3561. begin
  3562. SetInitialDiskPostition(FUIICRotateTorusX, FUIRotateDiskx);
  3563. SetInitialDiskPostition(FUIICRotateTorusX, FUIRotateDiskx2);
  3564. end;
  3565. if (pick.Hit[I] = FUIICRotateTorusY) then
  3566. begin
  3567. SetInitialDiskPostition(FUIICRotateTorusY, FUIRotateDiskY);
  3568. SetInitialDiskPostition(FUIICRotateTorusY, FUIRotateDiskY2);
  3569. end;
  3570. if (pick.Hit[I] = FUIICRotateTorusZ) then
  3571. begin
  3572. SetInitialDiskPostition(FUIICRotateTorusZ, FUIRotateDiskZ);
  3573. SetInitialDiskPostition(FUIICRotateTorusZ, FUIRotateDiskZ2);
  3574. end;
  3575. end;
  3576. end;
  3577. end;
  3578. if not FShowMultiSelecting and not gotPick then
  3579. begin
  3580. for I := 0 to pick.Count - 1 do
  3581. if (pick.Hit[I] <> FInterfaceRender) and
  3582. (pick.Hit[I] <> FInternalRender) and not (pick.Hit[I] is TgxGizmoExUISphere)
  3583. and not (pick.Hit[I] is TgxGizmoExUIPolyGon)
  3584. and not (pick.Hit[I] is TgxGizmoExuITorus)
  3585. and not (pick.Hit[I] is TgxGizmoExUIFrustrum)
  3586. and not (pick.Hit[I] is TgxGizmoExUIArrowLine)
  3587. and not (pick.Hit[I] is TgxGizmoExUILines)
  3588. and not (pick.Hit[I] is TgxGizmoExUIFlatText)
  3589. and not (CheckObjectInExcludeList(TgxBaseSceneObject(pick.hit[I])))
  3590. and not (CheckClassNameInExcludeList(TgxBaseSceneObject(pick.hit[I]))) then
  3591. begin
  3592. //Clear list
  3593. if not EnableMultiSelection then
  3594. ClearSelection
  3595. else
  3596. if (pick.Count - 1 >= 0) and
  3597. (FSelectedObjects.FindObject(pick.Hit[I]) = -1) then
  3598. if not FCanAddObjToSelectionList and not FCanRemoveObjFromSelectionList then
  3599. ClearSelection;
  3600. if not FCanRemoveObjFromSelectionList then
  3601. AddObjToSelectionList(TgxBaseSceneObject(pick.Hit[I]))
  3602. else
  3603. RemoveObjFromSelectionList(TgxBaseSceneObject(pick.Hit[I]));
  3604. if Assigned(onSelect) then
  3605. onSelect(self, FSelectedObjects);
  3606. UpdateGizmo();
  3607. Break;
  3608. end;
  3609. end
  3610. else
  3611. UpdateVisibleInfoLabels();
  3612. pick.Free;
  3613. moving := True;
  3614. lastMousePos := MouseWorldPos(X, Y);
  3615. if EnableMultiSelection then
  3616. MultiSelMouseDown(X, Y);
  3617. end;
  3618. procedure TgxGizmoEx.ViewerMouseUp(const X, Y: Integer);
  3619. var
  3620. pick: TgxPickList;
  3621. begin
  3622. if (not Enabled) or (RootGizmo = nil) or (RootObjects = nil) then
  3623. Exit;
  3624. moving := False;
  3625. case fOperation of
  3626. gopRotate: SetAngleDisk(0);
  3627. end;
  3628. fchangerate := NullVector;
  3629. //MassSelection+\-add mass selected obj
  3630. if operation = gopNone then
  3631. begin
  3632. pick := InternalGetPickedObjects(X - 1, Y - 1, X + 1, Y + 1, 8);
  3633. // clear the list if clicked into the void
  3634. if not FCanAddObjToSelectionList and not FCanRemoveObjFromSelectionList and (pick.Count = 0) then
  3635. ClearSelection;
  3636. pick.Free;
  3637. end;
  3638. if EnableMultiSelection and FShowMultiSelecting then
  3639. MultiSelMouseUp(X, Y);
  3640. if not FShowMultiSelecting and EnableActionHistory then
  3641. FHistory.AddObjects(FSelectedObjects);
  3642. Updategizmo;
  3643. end;
  3644. //------------------------------------------------------------------------------
  3645. procedure TgxGizmoEx.UpdateGizmo;
  3646. var
  3647. d: Single;
  3648. v: TVector4f;
  3649. I: Integer;
  3650. begin
  3651. if not Assigned(RootGizmo) or
  3652. not Assigned(RootObjects) or
  3653. not Assigned(Viewer) then
  3654. Exit;
  3655. if FSelectedObjects.Count - 1 < 0 then
  3656. begin
  3657. FUIRootHelpers.Visible := False;
  3658. Exit;
  3659. end
  3660. else
  3661. begin
  3662. FUIRootHelpers.Visible := True;
  3663. if Assigned(onUpdate) then
  3664. OnUpdate(self);
  3665. v := VectorMake(0, 0, 0);
  3666. // set the gizmo to the desired position!
  3667. for I := 0 to FSelectedObjects.Count - 1 do
  3668. VectorAdd(v, TgxBaseSceneObject(FSelectedObjects.Hit[I]).AbsolutePosition, v);
  3669. if FSelectedObjects.Count = 1 then
  3670. I := 1
  3671. else
  3672. I := FSelectedObjects.Count;
  3673. FUIRootHelpers.Position.AsVector := VectorDivide(v, VectorMake(I, I, I));
  3674. end;
  3675. case Ord(ReferenceCoordSystem) of
  3676. 0:
  3677. begin
  3678. FUIRootHelpers.Direction := FUIBaseGizmo.Direction;
  3679. FUIRootHelpers.Up := FUIBaseGizmo.Up;
  3680. end;
  3681. 1:
  3682. begin
  3683. FUIRootHelpers.AbsoluteDirection := TgxBaseSceneObject(FSelectedObjects.Hit[0]).AbsoluteDirection;
  3684. FUIRootHelpers.AbsoluteUp := TgxBaseSceneObject(FSelectedObjects.Hit[0]).AbsoluteUp;
  3685. end;
  3686. end;
  3687. Assert(Viewer <> nil, 'Viewer not Assigned to gizmo');
  3688. if FAutoZoom then
  3689. d := Viewer.Camera.distanceTo(FUIRootHelpers) / FAutoZoomFactor
  3690. else
  3691. d := FZoomFactor;
  3692. if FUIRootAxisLabel.Visible then
  3693. begin
  3694. FUIAxisLabelX.PointTo(Viewer.Camera.Position.AsVector, Viewer.Camera.Up.AsVector);
  3695. FUIAxisLabelX.StructureChanged;
  3696. FUIAxisLabelY.PointTo(Viewer.Camera.Position.AsVector, Viewer.Camera.Up.AsVector);
  3697. FUIAxisLabelY.StructureChanged;
  3698. FUIAxisLabelZ.PointTo(Viewer.Camera.Position.AsVector, Viewer.Camera.Up.AsVector);
  3699. FUIAxisLabelZ.StructureChanged;
  3700. FUIRootAxisLabel.Scale.AsVector := VectorMake(d, d, d);
  3701. end;
  3702. if FUIRootSelect.Visible then
  3703. FUIRootSelect.Scale.AsVector := VectorMake(d, d, d);
  3704. if FUIRootMovement.Visible then
  3705. FUIRootMovement.Scale.AsVector := VectorMake(d, d, d);
  3706. if FUIRootRotate.Visible then
  3707. begin
  3708. FUIRotateLineXY.PointTo(Viewer.Camera.Position.AsVector, Viewer.Camera.Up.AsVector);
  3709. FUIRotateLineXY.StructureChanged;
  3710. FUIRotateLineXZ.PointTo(Viewer.Camera.Position.AsVector, Viewer.Camera.Up.AsVector);
  3711. FUIRotateLineXZ.StructureChanged;
  3712. FUIRotateAxisLabelX.PointTo(Viewer.Camera.Position.AsVector, Viewer.Camera.Up.AsVector);
  3713. FUIRotateAxisLabelX.StructureChanged;
  3714. FUIRotateAxisLabelY.PointTo(Viewer.Camera.Position.AsVector, Viewer.Camera.Up.AsVector);
  3715. FUIRotateAxisLabelY.StructureChanged;
  3716. FUIRotateAxisLabelZ.PointTo(Viewer.Camera.Position.AsVector, Viewer.Camera.Up.AsVector);
  3717. FUIRotateAxisLabelZ.StructureChanged;
  3718. FUIRootRotate.Scale.AsVector := VectorMake(d, d, d);
  3719. end;
  3720. if not moving and FUIRootScale.Visible then
  3721. FUIRootScale.Scale.AsVector := VectorMake(d, d, d);
  3722. if FUIRootVisibleInfoLabels.Visible then
  3723. begin
  3724. UpdateVisibleInfoLabels;
  3725. FUIRootVisibleInfoLabels.AbsoluteDirection := FUIBaseGizmo.AbsoluteDirection;
  3726. FUIRootVisibleInfoLabels.AbsoluteUp := FUIBaseGizmo.AbsoluteUp;
  3727. FUIVisibleInfoLabels.ModulateColor.Color := FVisibleInfoLabelsColor.Color;
  3728. FUIVisibleInfoLabels.PointTo(Viewer.Camera.Position.AsVector, Viewer.Camera.Up.AsVector);
  3729. FUIVisibleInfoLabels.StructureChanged;
  3730. FUIRootVisibleInfoLabels.Scale.AsVector := VectorMake(d, d, d);
  3731. end;
  3732. end;
  3733. procedure TgxGizmoEx.LooseSelection;
  3734. begin
  3735. ClearSelection;
  3736. UpdateGizmo;
  3737. if Assigned(onSelectionLost) then
  3738. OnSelectionLost(self);
  3739. end;
  3740. procedure TgxGizmoEx.ClearSelection;
  3741. begin
  3742. FSelectedObj := nil;
  3743. FSelectedObjects.Clear;
  3744. end;
  3745. procedure TgxGizmoEx.LooseCursorSelection;
  3746. begin
  3747. FShowMultiSelecting := False;
  3748. if high(FSelectionRec) > 0 then
  3749. SetLength(FSelectionRec, 0);
  3750. flastcursorPos := Point(0, 0);
  3751. fcursorPos := point(0, 0);
  3752. end;
  3753. procedure TgxGizmoEx.SetViewer(const Value: TgxSceneViewer);
  3754. begin
  3755. if FViewer <> Value then
  3756. begin
  3757. if FViewer <> nil then
  3758. FViewer.RemoveFreeNotification(Self);
  3759. FViewer := Value;
  3760. if FViewer <> nil then
  3761. FViewer.FreeNotification(Self);
  3762. end;
  3763. end;
  3764. procedure TgxGizmoEx.Notification(AComponent: TComponent; Operation: TOperation);
  3765. begin
  3766. inherited;
  3767. if Operation = opRemove then
  3768. begin
  3769. if AComponent = FViewer then
  3770. FViewer := nil;
  3771. if AComponent = FRootGizmo then
  3772. FRootGizmo := nil;
  3773. if AComponent = FRootObjects then
  3774. FRootObjects := nil;
  3775. if AComponent = FGizmoTmpRoot then
  3776. FGizmoTmpRoot := nil;
  3777. end;
  3778. if FHistory <> nil then
  3779. FHistory.Notification(AComponent, Operation);
  3780. end;
  3781. function TgxGizmoEx.Undo: TgxGizmoExActionHistoryItem;
  3782. var
  3783. I: Integer;
  3784. begin
  3785. Result := FHistory.Undo;
  3786. if Result = nil then
  3787. Exit;
  3788. FSelectedObjects.Clear;
  3789. for I := 0 to Result.GizmoObjectCollection.Count - 1 do
  3790. FSelectedObjects.AddHit(Result.GizmoObjectCollection.Items[I].EffectedObject, nil, 0, 0);
  3791. UpdateGizmo;
  3792. end;
  3793. function TgxGizmoEx.Redo: TgxGizmoExActionHistoryItem;
  3794. var
  3795. I: Integer;
  3796. begin
  3797. Result := FHistory.Redo;
  3798. if Result = nil then
  3799. Exit;
  3800. FSelectedObjects.Clear;
  3801. for I := 0 to Result.GizmoObjectCollection.Count - 1 do
  3802. if not Result.GizmoObjectCollection.Items[I].FReturnObject then
  3803. FSelectedObjects.AddHit(Result.GizmoObjectCollection.Items[I].EffectedObject, nil, 0, 0);
  3804. UpdateGizmo;
  3805. end;
  3806. //************************)
  3807. procedure TgxGizmoExObjectItem.AssignFromObject(const AObject: TgxBaseSceneObject; AssignAndRemoveObj: Boolean = False);
  3808. begin
  3809. if not AssignAndRemoveObj then
  3810. begin
  3811. EffectedObject := AObject;
  3812. SetOldMatrix(AObject.Matrix^);
  3813. if AObject is TgxFreeForm then
  3814. FOldAutoScaling := TgxFreeForm(AObject).AutoScaling.AsVector;
  3815. end
  3816. else
  3817. begin
  3818. EffectedObject := AObject;
  3819. FParentOldObject := EffectedObject.Parent;
  3820. FIndexOldObject := EffectedObject.Index;
  3821. FNameOldObject := EffectedObject.Name;
  3822. FEffectedObject.MoveTo(GizmoTmpRoot);
  3823. FReturnObject := True;
  3824. end;
  3825. end;
  3826. constructor TgxGizmoExObjectItem.Create(AOwner: TCollection);
  3827. begin
  3828. FReturnObject := False;
  3829. inherited;
  3830. end;
  3831. destructor TgxGizmoExObjectItem.Destroy;
  3832. begin
  3833. if FReturnObject then
  3834. if assigned(fEffectedObject) then
  3835. FreeAndNil(fEffectedObject);
  3836. inherited;
  3837. end;
  3838. function TgxGizmoExObjectItem.GetGizmo: TgxGizmoEx;
  3839. begin
  3840. if GetParent <> nil then
  3841. Result := GetPArent.GetParent
  3842. else
  3843. Result := nil;
  3844. end;
  3845. function TgxGizmoExObjectItem.GetParent: TgxGizmoExObjectCollection;
  3846. begin
  3847. Result := TgxGizmoExObjectCollection(GetOwner);
  3848. end;
  3849. procedure TgxGizmoExObjectItem.DoUndo;
  3850. begin
  3851. if FEffectedObject = nil then
  3852. Exit;
  3853. if not FReturnObject then
  3854. begin
  3855. FEffectedObject.SetMatrix(FOldMatrix);
  3856. if FEffectedObject is TgxFreeForm then
  3857. TgxFreeForm(FEffectedObject).AutoScaling.AsVector := FOldAutoScaling;
  3858. end
  3859. else
  3860. begin
  3861. if fEffectedObject.Parent <> GizmoTmpRoot then
  3862. begin
  3863. fEffectedObject.MoveTo(FGizmoTmpRoot);
  3864. Exit;
  3865. end;
  3866. FParentOldObject.Insert(FIndexOldObject, fEffectedObject);
  3867. end;
  3868. end;
  3869. procedure TgxGizmoExObjectItem.Notification(AComponent: TComponent; Operation: TOperation);
  3870. begin
  3871. inherited;
  3872. if Operation = opRemove then
  3873. begin
  3874. if AComponent = FEffectedObject then
  3875. if FReturnObject then
  3876. FreeAndNil(FEffectedObject)
  3877. else
  3878. FEffectedObject := nil;
  3879. GizmoTmpRoot := nil;
  3880. end;
  3881. end;
  3882. procedure TgxGizmoExObjectItem.SetEffectedObject(const Value: TgxBaseSceneObject);
  3883. begin
  3884. FEffectedObject := Value;
  3885. end;
  3886. procedure TgxGizmoExObjectItem.SetOldMatrix(const Value: TMatrix4f);
  3887. begin
  3888. FOldMatrix := Value;
  3889. end;
  3890. //------------------------------------
  3891. // TgxGizmoExUndoCollection
  3892. //------------------------------------
  3893. function TgxGizmoExObjectCollection.Add: TgxGizmoExObjectItem;
  3894. begin
  3895. Result := TgxGizmoExObjectItem(inherited Add);
  3896. end;
  3897. function TgxGizmoExObjectCollection.GetItems(const Index: Integer): TgxGizmoExObjectItem;
  3898. begin
  3899. Result := TgxGizmoExObjectItem(inherited GetItem(Index));
  3900. end;
  3901. function TgxGizmoExObjectCollection.GetParent: TgxGizmoEx;
  3902. begin
  3903. Result := TgxGizmoEx(GetOwner);
  3904. end;
  3905. procedure TgxGizmoExObjectCollection.Notification(AComponent: TComponent; Operation: TOperation);
  3906. var
  3907. I: Integer;
  3908. begin
  3909. if Count <> 0 then
  3910. for I := 0 to Count - 1 do
  3911. GetItems(I).Notification(AComponent, Operation);
  3912. end;
  3913. procedure TgxGizmoExObjectCollection.RemoveByObject(const AObject: TgxCustomSceneObject);
  3914. var
  3915. I: Integer;
  3916. begin
  3917. for I := Count - 1 downto 0 do
  3918. if GetItems(I).FEffectedObject = AObject then
  3919. GetItems(I).Free;
  3920. end;
  3921. procedure TgxGizmoExObjectCollection.SetItems(const Index: Integer; const Value: TgxGizmoExObjectItem);
  3922. begin
  3923. GetItems(Index).Assign(Value);
  3924. end;
  3925. procedure TgxGizmoExObjectCollection.DoUndo;
  3926. var
  3927. I: Integer;
  3928. begin
  3929. for I := Count - 1 downto 0 do
  3930. GetItems(I).DoUndo;
  3931. end;
  3932. //**********)
  3933. constructor TgxGizmoExActionHistoryItem.Create(AOwner: TCollection);
  3934. begin
  3935. inherited;
  3936. FGizmoObjectCollection := TgxGizmoExObjectCollection.Create(self, TgxGizmoExObjectItem);
  3937. end;
  3938. destructor TgxGizmoExActionHistoryItem.Destroy;
  3939. begin
  3940. FGizmoObjectCollection.Free;
  3941. inherited;
  3942. end;
  3943. procedure TgxGizmoExActionHistoryItem.SetObject(aValue: TObject);
  3944. begin
  3945. if FObject <> AValue then
  3946. FObject := AValue;
  3947. end;
  3948. procedure TgxGizmoExActionHistoryItem.SetGizmoObjectCollection(aValue: TgxGizmoExObjectCollection);
  3949. begin
  3950. if FGizmoObjectCollection <> aValue then
  3951. FGizmoObjectCollection := aValue;
  3952. end;
  3953. //----------------------------------------
  3954. // TgxGizmoExUndoCollection
  3955. //----------------------------------------
  3956. constructor TgxGizmoExActionHistoryCollection.Create(AOwner: TPersistent; ItemClass: TCollectionItemClass);
  3957. begin
  3958. MaxCount := 30;
  3959. FItemIndex := -1;
  3960. inherited;
  3961. end;
  3962. function TgxGizmoExActionHistoryCollection.Add: TgxGizmoExActionHistoryItem;
  3963. begin
  3964. Result := nil;
  3965. //If used undo then rewrite previous record
  3966. if FItemIndex = Count - 1 then
  3967. begin
  3968. Result := TgxGizmoExActionHistoryItem(inherited Add);
  3969. FItemIndex := FItemIndex + 1;
  3970. ;
  3971. end
  3972. else
  3973. if (FItemIndex >= 0) or (FItemIndex < Count - 1) then
  3974. begin
  3975. Result := Items[FItemIndex];
  3976. FItemIndex := FItemIndex + 1;
  3977. end;
  3978. // if number of record greater then maxcount then delete elements
  3979. if Count - 1 > MaxCount then
  3980. begin
  3981. Delete(0);
  3982. FItemIndex := Count - 1;
  3983. end;
  3984. end;
  3985. function TgxGizmoExActionHistoryCollection.GetItems(const Index: Integer): TgxGizmoExActionHistoryItem;
  3986. begin
  3987. Result := TgxGizmoExActionHistoryItem(inherited GetItem(Index));
  3988. end;
  3989. procedure TgxGizmoExActionHistoryCollection.Notification(AComponent: TComponent; Operation: TOperation);
  3990. var
  3991. I: Integer;
  3992. begin
  3993. if Count <> 0 then
  3994. for I := 0 to Count - 1 do
  3995. GetItems(I).FGizmoObjectCollection.Notification(AComponent, Operation);
  3996. end;
  3997. procedure TgxGizmoExActionHistoryCollection.SetItems(const Index: Integer; const Value: TgxGizmoExActionHistoryItem);
  3998. begin
  3999. GetItems(Index).Assign(Value);
  4000. end;
  4001. function TgxGizmoExActionHistoryCollection.Undo: TgxGizmoExActionHistoryItem;
  4002. begin
  4003. Result := nil;
  4004. if not (FItemIndex > 0) or not (FItemIndex <= Count - 1) then
  4005. Exit;
  4006. if FItemIndex <> 0 then
  4007. FItemIndex := FItemIndex - 1;
  4008. Result := Items[FItemIndex];
  4009. Result.GizmoObjectCollection.DoUndo;
  4010. end;
  4011. function TgxGizmoExActionHistoryCollection.Redo: TgxGizmoExActionHistoryItem;
  4012. begin
  4013. Result := nil;
  4014. if not (FItemIndex >= 0) or not (FItemIndex < Count - 1) then
  4015. Exit;
  4016. if FItemIndex <> Count - 1 then
  4017. FItemIndex := FItemIndex + 1;
  4018. Result := Items[FItemIndex];
  4019. Result.GizmoObjectCollection.DoUndo;
  4020. end;
  4021. procedure TgxGizmoExActionHistoryCollection.AddObjects(objs: TgxPickList);
  4022. var
  4023. I: Integer;
  4024. begin
  4025. with Add do
  4026. begin
  4027. for I := 0 to objs.Count - 1 do
  4028. GizmoObjectCollection.Add.AssignFromObject(TgxBaseSceneObject(objs.Hit[I]));
  4029. end;
  4030. end;
  4031. procedure TgxGizmoExActionHistoryCollection.AddObject(obj: TObject);
  4032. begin
  4033. if obj = nil then
  4034. Exit;
  4035. Add.FObject := obj;
  4036. end;
  4037. procedure TgxGizmoExActionHistoryCollection.RemoveObjects(objs: TgxPickList);
  4038. var
  4039. I: Integer;
  4040. begin
  4041. if not Assigned(self.GizmoTmpRoot) then
  4042. Exit;
  4043. with Add do
  4044. for I := 0 to objs.Count - 1 do
  4045. if objs.Hit[I] <> nil then
  4046. with GizmoObjectCollection.Add do
  4047. begin
  4048. GizmoTmpRoot := self.GizmoTmpRoot;
  4049. AssignFromObject(TgxBaseSceneObject(objs.Hit[I]), True);
  4050. end;
  4051. objs.Clear;
  4052. end;
  4053. end.