spatial_editor_gizmos.cpp 102 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718
  1. /*************************************************************************/
  2. /* spatial_editor_gizmos.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "spatial_editor_gizmos.h"
  31. #include "geometry.h"
  32. #include "quick_hull.h"
  33. #include "scene/3d/camera.h"
  34. #include "scene/resources/box_shape.h"
  35. #include "scene/resources/capsule_shape.h"
  36. #include "scene/resources/convex_polygon_shape.h"
  37. #include "scene/resources/plane_shape.h"
  38. #include "scene/resources/primitive_meshes.h"
  39. #include "scene/resources/ray_shape.h"
  40. #include "scene/resources/sphere_shape.h"
  41. #include "scene/resources/surface_tool.h"
  42. // Keep small children away from this file.
  43. // It's so ugly it will eat them alive
  44. #define HANDLE_HALF_SIZE 0.05
  45. bool EditorSpatialGizmo::can_draw() const {
  46. return is_editable();
  47. }
  48. bool EditorSpatialGizmo::is_editable() const {
  49. ERR_FAIL_COND_V(!spatial_node, false);
  50. Node *edited_root = spatial_node->get_tree()->get_edited_scene_root();
  51. if (spatial_node == edited_root)
  52. return true;
  53. if (spatial_node->get_owner() == edited_root)
  54. return true;
  55. if (edited_root->is_editable_instance(spatial_node->get_owner()))
  56. return true;
  57. return false;
  58. }
  59. void EditorSpatialGizmo::clear() {
  60. for (int i = 0; i < instances.size(); i++) {
  61. if (instances[i].instance.is_valid())
  62. VS::get_singleton()->free(instances[i].instance);
  63. }
  64. billboard_handle = false;
  65. collision_segments.clear();
  66. collision_mesh = Ref<TriangleMesh>();
  67. instances.clear();
  68. handles.clear();
  69. secondary_handles.clear();
  70. }
  71. void EditorSpatialGizmo::redraw() {
  72. if (get_script_instance() && get_script_instance()->has_method("redraw"))
  73. get_script_instance()->call("redraw");
  74. }
  75. void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base) {
  76. instance = VS::get_singleton()->instance_create2(mesh->get_rid(), p_base->get_world()->get_scenario());
  77. VS::get_singleton()->instance_attach_object_instance_id(instance, p_base->get_instance_id());
  78. if (skeleton.is_valid())
  79. VS::get_singleton()->instance_attach_skeleton(instance, skeleton);
  80. if (extra_margin)
  81. VS::get_singleton()->instance_set_extra_visibility_margin(instance, 1);
  82. VS::get_singleton()->instance_geometry_set_cast_shadows_setting(instance, VS::SHADOW_CASTING_SETTING_OFF);
  83. VS::get_singleton()->instance_set_layer_mask(instance, 1 << SpatialEditorViewport::GIZMO_EDIT_LAYER); //gizmos are 26
  84. }
  85. void EditorSpatialGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard, const RID &p_skeleton) {
  86. ERR_FAIL_COND(!spatial_node);
  87. Instance ins;
  88. ins.billboard = p_billboard;
  89. ins.mesh = p_mesh;
  90. ins.skeleton = p_skeleton;
  91. if (valid) {
  92. ins.create_instance(spatial_node);
  93. VS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform());
  94. }
  95. instances.push_back(ins);
  96. }
  97. void EditorSpatialGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard) {
  98. ERR_FAIL_COND(!spatial_node);
  99. Instance ins;
  100. Ref<ArrayMesh> mesh = memnew(ArrayMesh);
  101. Array a;
  102. a.resize(Mesh::ARRAY_MAX);
  103. a[Mesh::ARRAY_VERTEX] = p_lines;
  104. PoolVector<Color> color;
  105. color.resize(p_lines.size());
  106. {
  107. PoolVector<Color>::Write w = color.write();
  108. for (int i = 0; i < p_lines.size(); i++) {
  109. if (is_selected())
  110. w[i] = Color(1, 1, 1, 0.8);
  111. else
  112. w[i] = Color(1, 1, 1, 0.2);
  113. }
  114. }
  115. a[Mesh::ARRAY_COLOR] = color;
  116. mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a);
  117. mesh->surface_set_material(0, p_material);
  118. if (p_billboard) {
  119. float md = 0;
  120. for (int i = 0; i < p_lines.size(); i++) {
  121. md = MAX(0, p_lines[i].length());
  122. }
  123. if (md) {
  124. mesh->set_custom_aabb(Rect3(Vector3(-md, -md, -md), Vector3(md, md, md) * 2.0));
  125. }
  126. }
  127. ins.billboard = p_billboard;
  128. ins.mesh = mesh;
  129. if (valid) {
  130. ins.create_instance(spatial_node);
  131. VS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform());
  132. }
  133. instances.push_back(ins);
  134. }
  135. void EditorSpatialGizmo::add_unscaled_billboard(const Ref<Material> &p_material, float p_scale) {
  136. ERR_FAIL_COND(!spatial_node);
  137. Instance ins;
  138. Vector<Vector3> vs;
  139. Vector<Vector2> uv;
  140. vs.push_back(Vector3(-p_scale, p_scale, 0));
  141. vs.push_back(Vector3(p_scale, p_scale, 0));
  142. vs.push_back(Vector3(p_scale, -p_scale, 0));
  143. vs.push_back(Vector3(-p_scale, -p_scale, 0));
  144. uv.push_back(Vector2(0, 0));
  145. uv.push_back(Vector2(1, 0));
  146. uv.push_back(Vector2(1, 1));
  147. uv.push_back(Vector2(0, 1));
  148. Ref<ArrayMesh> mesh = memnew(ArrayMesh);
  149. Array a;
  150. a.resize(Mesh::ARRAY_MAX);
  151. a[Mesh::ARRAY_VERTEX] = vs;
  152. a[Mesh::ARRAY_TEX_UV] = uv;
  153. mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLE_FAN, a);
  154. mesh->surface_set_material(0, p_material);
  155. if (true) {
  156. float md = 0;
  157. for (int i = 0; i < vs.size(); i++) {
  158. md = MAX(0, vs[i].length());
  159. }
  160. if (md) {
  161. mesh->set_custom_aabb(Rect3(Vector3(-md, -md, -md), Vector3(md, md, md) * 2.0));
  162. }
  163. }
  164. ins.mesh = mesh;
  165. ins.unscaled = true;
  166. ins.billboard = true;
  167. if (valid) {
  168. ins.create_instance(spatial_node);
  169. VS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform());
  170. }
  171. instances.push_back(ins);
  172. }
  173. void EditorSpatialGizmo::add_collision_triangles(const Ref<TriangleMesh> &p_tmesh, const Rect3 &p_bounds) {
  174. collision_mesh = p_tmesh;
  175. collision_mesh_bounds = p_bounds;
  176. }
  177. void EditorSpatialGizmo::add_collision_segments(const Vector<Vector3> &p_lines) {
  178. int from = collision_segments.size();
  179. collision_segments.resize(from + p_lines.size());
  180. for (int i = 0; i < p_lines.size(); i++) {
  181. collision_segments[from + i] = p_lines[i];
  182. }
  183. }
  184. void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_billboard, bool p_secondary) {
  185. billboard_handle = p_billboard;
  186. if (!is_selected() || !is_editable())
  187. return;
  188. ERR_FAIL_COND(!spatial_node);
  189. ERR_FAIL_COND(!spatial_node);
  190. Instance ins;
  191. Ref<ArrayMesh> mesh = memnew(ArrayMesh);
  192. Array a;
  193. a.resize(VS::ARRAY_MAX);
  194. a[VS::ARRAY_VERTEX] = p_handles;
  195. PoolVector<Color> colors;
  196. {
  197. colors.resize(p_handles.size());
  198. PoolVector<Color>::Write w = colors.write();
  199. for (int i = 0; i < p_handles.size(); i++) {
  200. Color col(1, 1, 1, 1);
  201. if (SpatialEditor::get_singleton()->get_over_gizmo_handle() != i)
  202. col = Color(0.9, 0.9, 0.9, 0.9);
  203. w[i] = col;
  204. }
  205. }
  206. a[VS::ARRAY_COLOR] = colors;
  207. mesh->add_surface_from_arrays(Mesh::PRIMITIVE_POINTS, a);
  208. if (p_billboard)
  209. mesh->surface_set_material(0, SpatialEditorGizmos::singleton->handle2_material_billboard);
  210. else
  211. mesh->surface_set_material(0, SpatialEditorGizmos::singleton->handle2_material);
  212. if (p_billboard) {
  213. float md = 0;
  214. for (int i = 0; i < p_handles.size(); i++) {
  215. md = MAX(0, p_handles[i].length());
  216. }
  217. if (md) {
  218. mesh->set_custom_aabb(Rect3(Vector3(-md, -md, -md), Vector3(md, md, md) * 2.0));
  219. }
  220. }
  221. ins.mesh = mesh;
  222. ins.billboard = p_billboard;
  223. ins.extra_margin = true;
  224. if (valid) {
  225. ins.create_instance(spatial_node);
  226. VS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform());
  227. }
  228. instances.push_back(ins);
  229. if (!p_secondary) {
  230. int chs = handles.size();
  231. handles.resize(chs + p_handles.size());
  232. for (int i = 0; i < p_handles.size(); i++) {
  233. handles[i + chs] = p_handles[i];
  234. }
  235. } else {
  236. int chs = secondary_handles.size();
  237. secondary_handles.resize(chs + p_handles.size());
  238. for (int i = 0; i < p_handles.size(); i++) {
  239. secondary_handles[i + chs] = p_handles[i];
  240. }
  241. }
  242. }
  243. void EditorSpatialGizmo::add_solid_box(Ref<Material> &p_material, Vector3 p_size) {
  244. ERR_FAIL_COND(!spatial_node);
  245. CubeMesh cubem;
  246. cubem.set_size(p_size);
  247. Ref<ArrayMesh> m = memnew(ArrayMesh);
  248. m->add_surface_from_arrays(cubem.surface_get_primitive_type(0), cubem.surface_get_arrays(0));
  249. m->surface_set_material(0, p_material);
  250. add_mesh(m);
  251. Instance ins;
  252. ins.mesh = m;
  253. if (valid) {
  254. ins.create_instance(spatial_node);
  255. VS::get_singleton()->instance_set_transform(ins.instance, spatial_node->get_global_transform());
  256. }
  257. instances.push_back(ins);
  258. }
  259. void EditorSpatialGizmo::set_spatial_node(Spatial *p_node) {
  260. ERR_FAIL_NULL(p_node);
  261. spatial_node = p_node;
  262. }
  263. bool EditorSpatialGizmo::intersect_frustum(const Camera *p_camera, const Vector<Plane> &p_frustum) {
  264. ERR_FAIL_COND_V(!spatial_node, false);
  265. ERR_FAIL_COND_V(!valid, false);
  266. if (collision_segments.size()) {
  267. const Plane *p = p_frustum.ptr();
  268. int fc = p_frustum.size();
  269. int vc = collision_segments.size();
  270. const Vector3 *vptr = collision_segments.ptr();
  271. Transform t = spatial_node->get_global_transform();
  272. for (int i = 0; i < vc / 2; i++) {
  273. Vector3 a = t.xform(vptr[i * 2 + 0]);
  274. Vector3 b = t.xform(vptr[i * 2 + 1]);
  275. bool any_out = false;
  276. for (int j = 0; j < fc; j++) {
  277. if (p[j].distance_to(a) > 0 && p[j].distance_to(b) > 0) {
  278. any_out = true;
  279. break;
  280. }
  281. }
  282. if (!any_out)
  283. return true;
  284. }
  285. return false;
  286. }
  287. if (collision_mesh_bounds.size != Vector3(0.0, 0.0, 0.0)) {
  288. Transform t = spatial_node->get_global_transform();
  289. const Plane *p = p_frustum.ptr();
  290. int fc = p_frustum.size();
  291. Vector3 mins = t.xform(collision_mesh_bounds.get_position());
  292. Vector3 max = t.xform(collision_mesh_bounds.get_position() + collision_mesh_bounds.get_size());
  293. bool any_out = false;
  294. for (int j = 0; j < fc; j++) {
  295. if (p[j].distance_to(mins) > 0 || p[j].distance_to(max) > 0) {
  296. any_out = true;
  297. break;
  298. }
  299. }
  300. if (!any_out)
  301. return true;
  302. }
  303. return false;
  304. }
  305. bool EditorSpatialGizmo::intersect_ray(const Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle, bool p_sec_first) {
  306. ERR_FAIL_COND_V(!spatial_node, false);
  307. ERR_FAIL_COND_V(!valid, false);
  308. if (r_gizmo_handle) {
  309. Transform t = spatial_node->get_global_transform();
  310. t.orthonormalize();
  311. if (billboard_handle) {
  312. t.set_look_at(t.origin, t.origin - p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1));
  313. }
  314. float min_d = 1e20;
  315. int idx = -1;
  316. for (int i = 0; i < secondary_handles.size(); i++) {
  317. Vector3 hpos = t.xform(secondary_handles[i]);
  318. Vector2 p = p_camera->unproject_position(hpos);
  319. if (p.distance_to(p_point) < SpatialEditorGizmos::singleton->handle_t->get_width() * 0.6) {
  320. real_t dp = p_camera->get_transform().origin.distance_to(hpos);
  321. if (dp < min_d) {
  322. r_pos = t.xform(hpos);
  323. r_normal = p_camera->get_transform().basis.get_axis(2);
  324. min_d = dp;
  325. idx = i + handles.size();
  326. }
  327. }
  328. }
  329. if (p_sec_first && idx != -1) {
  330. *r_gizmo_handle = idx;
  331. return true;
  332. }
  333. min_d = 1e20;
  334. for (int i = 0; i < handles.size(); i++) {
  335. Vector3 hpos = t.xform(handles[i]);
  336. Vector2 p = p_camera->unproject_position(hpos);
  337. if (p.distance_to(p_point) < SpatialEditorGizmos::singleton->handle_t->get_width() * 0.6) {
  338. real_t dp = p_camera->get_transform().origin.distance_to(hpos);
  339. if (dp < min_d) {
  340. r_pos = t.xform(hpos);
  341. r_normal = p_camera->get_transform().basis.get_axis(2);
  342. min_d = dp;
  343. idx = i;
  344. }
  345. }
  346. }
  347. if (idx >= 0) {
  348. *r_gizmo_handle = idx;
  349. return true;
  350. }
  351. }
  352. if (collision_segments.size()) {
  353. Plane camp(p_camera->get_transform().origin, (-p_camera->get_transform().basis.get_axis(2)).normalized());
  354. int vc = collision_segments.size();
  355. const Vector3 *vptr = collision_segments.ptr();
  356. Transform t = spatial_node->get_global_transform();
  357. if (billboard_handle) {
  358. t.set_look_at(t.origin, t.origin - p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1));
  359. }
  360. Vector3 cp;
  361. float cpd = 1e20;
  362. for (int i = 0; i < vc / 2; i++) {
  363. Vector3 a = t.xform(vptr[i * 2 + 0]);
  364. Vector3 b = t.xform(vptr[i * 2 + 1]);
  365. Vector2 s[2];
  366. s[0] = p_camera->unproject_position(a);
  367. s[1] = p_camera->unproject_position(b);
  368. Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, s);
  369. float pd = p.distance_to(p_point);
  370. if (pd < cpd) {
  371. float d = s[0].distance_to(s[1]);
  372. Vector3 tcp;
  373. if (d > 0) {
  374. float d2 = s[0].distance_to(p) / d;
  375. tcp = a + (b - a) * d2;
  376. } else {
  377. tcp = a;
  378. }
  379. if (camp.distance_to(tcp) < p_camera->get_znear())
  380. continue;
  381. cp = tcp;
  382. cpd = pd;
  383. }
  384. }
  385. if (cpd < 8) {
  386. r_pos = cp;
  387. r_normal = -p_camera->project_ray_normal(p_point);
  388. return true;
  389. }
  390. return false;
  391. }
  392. if (collision_mesh.is_valid()) {
  393. Transform gt = spatial_node->get_global_transform();
  394. if (billboard_handle) {
  395. gt.set_look_at(gt.origin, gt.origin - p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1));
  396. }
  397. Transform ai = gt.affine_inverse();
  398. Vector3 ray_from = ai.xform(p_camera->project_ray_origin(p_point));
  399. Vector3 ray_dir = ai.basis.xform(p_camera->project_ray_normal(p_point)).normalized();
  400. Vector3 rpos, rnorm;
  401. if (collision_mesh->intersect_ray(ray_from, ray_dir, rpos, rnorm)) {
  402. r_pos = gt.xform(rpos);
  403. r_normal = gt.basis.xform(rnorm).normalized();
  404. return true;
  405. }
  406. }
  407. return false;
  408. }
  409. void EditorSpatialGizmo::create() {
  410. ERR_FAIL_COND(!spatial_node);
  411. ERR_FAIL_COND(valid);
  412. valid = true;
  413. for (int i = 0; i < instances.size(); i++) {
  414. instances[i].create_instance(spatial_node);
  415. }
  416. transform();
  417. }
  418. void EditorSpatialGizmo::transform() {
  419. ERR_FAIL_COND(!spatial_node);
  420. ERR_FAIL_COND(!valid);
  421. for (int i = 0; i < instances.size(); i++) {
  422. VS::get_singleton()->instance_set_transform(instances[i].instance, spatial_node->get_global_transform());
  423. }
  424. }
  425. void EditorSpatialGizmo::free() {
  426. ERR_FAIL_COND(!spatial_node);
  427. ERR_FAIL_COND(!valid);
  428. for (int i = 0; i < instances.size(); i++) {
  429. if (instances[i].instance.is_valid())
  430. VS::get_singleton()->free(instances[i].instance);
  431. instances[i].instance = RID();
  432. }
  433. valid = false;
  434. }
  435. Ref<SpatialMaterial> EditorSpatialGizmo::create_material(const String &p_name, const Color &p_color, bool p_billboard, bool p_on_top, bool p_use_vertex_color) {
  436. String name = p_name;
  437. if (!is_editable()) {
  438. name += "@readonly";
  439. } else if (is_selected()) {
  440. name += "@selected";
  441. }
  442. if (SpatialEditorGizmos::singleton->material_cache.has(name)) {
  443. return SpatialEditorGizmos::singleton->material_cache[name];
  444. }
  445. Color color = p_color;
  446. if (!is_editable()) {
  447. color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/instanced");
  448. }
  449. if (!is_selected()) {
  450. color.a *= 0.3;
  451. }
  452. Ref<SpatialMaterial> line_material;
  453. line_material.instance();
  454. line_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  455. line_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  456. if (p_use_vertex_color) {
  457. line_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
  458. line_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
  459. }
  460. if (p_billboard) {
  461. line_material->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
  462. }
  463. if (p_on_top && is_selected()) {
  464. line_material->set_on_top_of_alpha();
  465. }
  466. line_material->set_albedo(color);
  467. SpatialEditorGizmos::singleton->material_cache[name] = line_material;
  468. return line_material;
  469. }
  470. Ref<SpatialMaterial> EditorSpatialGizmo::create_icon_material(const String &p_name, const Ref<Texture> &p_texture, bool p_on_top, const Color &p_albedo) {
  471. String name = p_name;
  472. if (!is_editable()) {
  473. name += "@readonly";
  474. } else if (is_selected()) {
  475. name += "@selected";
  476. }
  477. if (SpatialEditorGizmos::singleton->material_cache.has(name)) {
  478. return SpatialEditorGizmos::singleton->material_cache[name];
  479. }
  480. Color color = p_albedo;
  481. if (!is_editable()) {
  482. color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/instanced");
  483. } else if (!is_selected()) {
  484. color.a *= 0.3;
  485. }
  486. Ref<SpatialMaterial> icon;
  487. icon.instance();
  488. icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  489. icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
  490. icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
  491. icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  492. icon->set_albedo(color);
  493. icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, p_texture);
  494. icon->set_flag(SpatialMaterial::FLAG_FIXED_SIZE, true);
  495. icon->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
  496. if (p_on_top && is_selected()) {
  497. icon->set_on_top_of_alpha();
  498. }
  499. SpatialEditorGizmos::singleton->material_cache[name] = icon;
  500. return icon;
  501. }
  502. void EditorSpatialGizmo::_bind_methods() {
  503. ClassDB::bind_method(D_METHOD("add_lines", "lines", "material", "billboard"), &EditorSpatialGizmo::add_lines, DEFVAL(false));
  504. ClassDB::bind_method(D_METHOD("add_mesh", "mesh", "billboard", "skeleton"), &EditorSpatialGizmo::add_mesh, DEFVAL(false), DEFVAL(RID()));
  505. ClassDB::bind_method(D_METHOD("add_collision_segments", "segments"), &EditorSpatialGizmo::add_collision_segments);
  506. ClassDB::bind_method(D_METHOD("add_collision_triangles", "triangles", "bounds"), &EditorSpatialGizmo::add_collision_triangles);
  507. ClassDB::bind_method(D_METHOD("add_unscaled_billboard", "material", "default_scale"), &EditorSpatialGizmo::add_unscaled_billboard, DEFVAL(1));
  508. ClassDB::bind_method(D_METHOD("add_handles", "handles", "billboard", "secondary"), &EditorSpatialGizmo::add_handles, DEFVAL(false), DEFVAL(false));
  509. ClassDB::bind_method(D_METHOD("set_spatial_node", "node"), &EditorSpatialGizmo::_set_spatial_node);
  510. ClassDB::bind_method(D_METHOD("clear"), &EditorSpatialGizmo::clear);
  511. BIND_VMETHOD(MethodInfo("redraw"));
  512. BIND_VMETHOD(MethodInfo(Variant::STRING, "get_handle_name", PropertyInfo(Variant::INT, "index")));
  513. MethodInfo hvget(Variant::NIL, "get_handle_value", PropertyInfo(Variant::INT, "index"));
  514. hvget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
  515. BIND_VMETHOD(hvget);
  516. BIND_VMETHOD(MethodInfo("set_handle", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera"), PropertyInfo(Variant::VECTOR2, "point")));
  517. MethodInfo cm = MethodInfo("commit_handle", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::NIL, "restore"), PropertyInfo(Variant::BOOL, "cancel"));
  518. cm.default_arguments.push_back(false);
  519. BIND_VMETHOD(cm);
  520. }
  521. EditorSpatialGizmo::EditorSpatialGizmo() {
  522. valid = false;
  523. billboard_handle = false;
  524. base = NULL;
  525. spatial_node = NULL;
  526. }
  527. EditorSpatialGizmo::~EditorSpatialGizmo() {
  528. clear();
  529. }
  530. Vector3 EditorSpatialGizmo::get_handle_pos(int p_idx) const {
  531. ERR_FAIL_INDEX_V(p_idx, handles.size(), Vector3());
  532. return handles[p_idx];
  533. }
  534. //// light gizmo
  535. String LightSpatialGizmo::get_handle_name(int p_idx) const {
  536. if (p_idx == 0)
  537. return "Radius";
  538. else
  539. return "Aperture";
  540. }
  541. Variant LightSpatialGizmo::get_handle_value(int p_idx) const {
  542. if (p_idx == 0)
  543. return light->get_param(Light::PARAM_RANGE);
  544. if (p_idx == 1)
  545. return light->get_param(Light::PARAM_SPOT_ANGLE);
  546. return Variant();
  547. }
  548. static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vector3 &p_to, float p_arc_radius, const Transform &p_arc_xform) {
  549. //bleh, discrete is simpler
  550. static const int arc_test_points = 64;
  551. float min_d = 1e20;
  552. Vector3 min_p;
  553. for (int i = 0; i < arc_test_points; i++) {
  554. float a = i * Math_PI * 0.5 / arc_test_points;
  555. float an = (i + 1) * Math_PI * 0.5 / arc_test_points;
  556. Vector3 p = Vector3(Math::cos(a), 0, -Math::sin(a)) * p_arc_radius;
  557. Vector3 n = Vector3(Math::cos(an), 0, -Math::sin(an)) * p_arc_radius;
  558. Vector3 ra, rb;
  559. Geometry::get_closest_points_between_segments(p, n, p_from, p_to, ra, rb);
  560. float d = ra.distance_to(rb);
  561. if (d < min_d) {
  562. min_d = d;
  563. min_p = ra;
  564. }
  565. }
  566. //min_p = p_arc_xform.affine_inverse().xform(min_p);
  567. float a = (Math_PI * 0.5) - Vector2(min_p.x, -min_p.z).angle();
  568. return a * 180.0 / Math_PI;
  569. }
  570. void LightSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
  571. Transform gt = light->get_global_transform();
  572. gt.orthonormalize();
  573. Transform gi = gt.affine_inverse();
  574. Vector3 ray_from = p_camera->project_ray_origin(p_point);
  575. Vector3 ray_dir = p_camera->project_ray_normal(p_point);
  576. Vector3 s[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
  577. if (p_idx == 0) {
  578. if (Object::cast_to<SpotLight>(light)) {
  579. Vector3 ra, rb;
  580. Geometry::get_closest_points_between_segments(Vector3(), Vector3(0, 0, -4096), s[0], s[1], ra, rb);
  581. float d = -ra.z;
  582. if (d < 0)
  583. d = 0;
  584. light->set_param(Light::PARAM_RANGE, d);
  585. } else if (Object::cast_to<OmniLight>(light)) {
  586. Plane cp = Plane(gt.origin, p_camera->get_transform().basis.get_axis(2));
  587. Vector3 inters;
  588. if (cp.intersects_ray(ray_from, ray_dir, &inters)) {
  589. float r = inters.distance_to(gt.origin);
  590. light->set_param(Light::PARAM_RANGE, r);
  591. }
  592. }
  593. } else if (p_idx == 1) {
  594. float a = _find_closest_angle_to_half_pi_arc(s[0], s[1], light->get_param(Light::PARAM_RANGE), gt);
  595. light->set_param(Light::PARAM_SPOT_ANGLE, CLAMP(a, 0.01, 89.99));
  596. }
  597. }
  598. void LightSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
  599. if (p_cancel) {
  600. light->set_param(p_idx == 0 ? Light::PARAM_RANGE : Light::PARAM_SPOT_ANGLE, p_restore);
  601. } else if (p_idx == 0) {
  602. UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
  603. ur->create_action(TTR("Change Light Radius"));
  604. ur->add_do_method(light, "set_param", Light::PARAM_RANGE, light->get_param(Light::PARAM_RANGE));
  605. ur->add_undo_method(light, "set_param", Light::PARAM_RANGE, p_restore);
  606. ur->commit_action();
  607. } else if (p_idx == 1) {
  608. UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
  609. ur->create_action(TTR("Change Light Radius"));
  610. ur->add_do_method(light, "set_param", Light::PARAM_SPOT_ANGLE, light->get_param(Light::PARAM_SPOT_ANGLE));
  611. ur->add_undo_method(light, "set_param", Light::PARAM_SPOT_ANGLE, p_restore);
  612. ur->commit_action();
  613. }
  614. }
  615. void LightSpatialGizmo::redraw() {
  616. Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/light");
  617. if (Object::cast_to<DirectionalLight>(light)) {
  618. Ref<Material> material = create_material("light_directional_material", gizmo_color);
  619. Ref<Material> icon = create_icon_material("light_directional_icon", SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight", "EditorIcons"));
  620. const int arrow_points = 7;
  621. const float arrow_length = 1.5;
  622. Vector3 arrow[arrow_points] = {
  623. Vector3(0, 0, -1),
  624. Vector3(0, 0.8, 0),
  625. Vector3(0, 0.3, 0),
  626. Vector3(0, 0.3, arrow_length),
  627. Vector3(0, -0.3, arrow_length),
  628. Vector3(0, -0.3, 0),
  629. Vector3(0, -0.8, 0)
  630. };
  631. int arrow_sides = 2;
  632. Vector<Vector3> lines;
  633. for (int i = 0; i < arrow_sides; i++) {
  634. for (int j = 0; j < arrow_points; j++) {
  635. Basis ma(Vector3(0, 0, 1), Math_PI * i / arrow_sides);
  636. Vector3 v1 = arrow[j] - Vector3(0, 0, arrow_length);
  637. Vector3 v2 = arrow[(j + 1) % arrow_points] - Vector3(0, 0, arrow_length);
  638. lines.push_back(ma.xform(v1));
  639. lines.push_back(ma.xform(v2));
  640. }
  641. }
  642. add_lines(lines, material);
  643. add_collision_segments(lines);
  644. add_unscaled_billboard(icon, 0.05);
  645. }
  646. if (Object::cast_to<OmniLight>(light)) {
  647. Ref<Material> material = create_material("light_omni_material", gizmo_color, true);
  648. Ref<Material> icon = create_icon_material("light_omni_icon", SpatialEditor::get_singleton()->get_icon("GizmoLight", "EditorIcons"));
  649. clear();
  650. OmniLight *on = Object::cast_to<OmniLight>(light);
  651. float r = on->get_param(Light::PARAM_RANGE);
  652. Vector<Vector3> points;
  653. for (int i = 0; i <= 360; i++) {
  654. float ra = Math::deg2rad((float)i);
  655. float rb = Math::deg2rad((float)i + 1);
  656. Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
  657. Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;
  658. /*points.push_back(Vector3(a.x,0,a.y));
  659. points.push_back(Vector3(b.x,0,b.y));
  660. points.push_back(Vector3(0,a.x,a.y));
  661. points.push_back(Vector3(0,b.x,b.y));*/
  662. points.push_back(Vector3(a.x, a.y, 0));
  663. points.push_back(Vector3(b.x, b.y, 0));
  664. }
  665. add_lines(points, material, true);
  666. add_collision_segments(points);
  667. add_unscaled_billboard(icon, 0.05);
  668. Vector<Vector3> handles;
  669. handles.push_back(Vector3(r, 0, 0));
  670. add_handles(handles, true);
  671. }
  672. if (Object::cast_to<SpotLight>(light)) {
  673. Ref<Material> material = create_material("light_spot_material", gizmo_color);
  674. Ref<Material> icon = create_icon_material("light_spot_icon", SpatialEditor::get_singleton()->get_icon("GizmoSpotLight", "EditorIcons"));
  675. clear();
  676. Vector<Vector3> points;
  677. SpotLight *on = Object::cast_to<SpotLight>(light);
  678. float r = on->get_param(Light::PARAM_RANGE);
  679. float w = r * Math::sin(Math::deg2rad(on->get_param(Light::PARAM_SPOT_ANGLE)));
  680. float d = r * Math::cos(Math::deg2rad(on->get_param(Light::PARAM_SPOT_ANGLE)));
  681. for (int i = 0; i < 360; i++) {
  682. float ra = Math::deg2rad((float)i);
  683. float rb = Math::deg2rad((float)i + 1);
  684. Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w;
  685. Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w;
  686. points.push_back(Vector3(a.x, a.y, -d));
  687. points.push_back(Vector3(b.x, b.y, -d));
  688. if (i % 90 == 0) {
  689. points.push_back(Vector3(a.x, a.y, -d));
  690. points.push_back(Vector3());
  691. }
  692. }
  693. points.push_back(Vector3(0, 0, -r));
  694. points.push_back(Vector3());
  695. add_lines(points, material);
  696. Vector<Vector3> handles;
  697. handles.push_back(Vector3(0, 0, -r));
  698. Vector<Vector3> collision_segments;
  699. for (int i = 0; i < 64; i++) {
  700. float ra = i * Math_PI * 2.0 / 64.0;
  701. float rb = (i + 1) * Math_PI * 2.0 / 64.0;
  702. Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w;
  703. Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w;
  704. collision_segments.push_back(Vector3(a.x, a.y, -d));
  705. collision_segments.push_back(Vector3(b.x, b.y, -d));
  706. if (i % 16 == 0) {
  707. collision_segments.push_back(Vector3(a.x, a.y, -d));
  708. collision_segments.push_back(Vector3());
  709. }
  710. if (i == 16) {
  711. handles.push_back(Vector3(a.x, a.y, -d));
  712. }
  713. }
  714. collision_segments.push_back(Vector3(0, 0, -r));
  715. collision_segments.push_back(Vector3());
  716. add_handles(handles);
  717. add_collision_segments(collision_segments);
  718. add_unscaled_billboard(icon, 0.05);
  719. }
  720. }
  721. LightSpatialGizmo::LightSpatialGizmo(Light *p_light) {
  722. light = p_light;
  723. set_spatial_node(p_light);
  724. }
  725. //////
  726. //// player gizmo
  727. String AudioStreamPlayer3DSpatialGizmo::get_handle_name(int p_idx) const {
  728. return "Emission Radius";
  729. }
  730. Variant AudioStreamPlayer3DSpatialGizmo::get_handle_value(int p_idx) const {
  731. return player->get_emission_angle();
  732. }
  733. void AudioStreamPlayer3DSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
  734. Transform gt = player->get_global_transform();
  735. gt.orthonormalize();
  736. Transform gi = gt.affine_inverse();
  737. Vector3 ray_from = p_camera->project_ray_origin(p_point);
  738. Vector3 ray_dir = p_camera->project_ray_normal(p_point);
  739. Vector3 ray_to = ray_from + ray_dir * 4096;
  740. ray_from = gi.xform(ray_from);
  741. ray_to = gi.xform(ray_to);
  742. float closest_dist = 1e20;
  743. float closest_angle = 1e20;
  744. for (int i = 0; i < 180; i++) {
  745. float a = i * Math_PI / 180.0;
  746. float an = (i + 1) * Math_PI / 180.0;
  747. Vector3 from(Math::sin(a), 0, -Math::cos(a));
  748. Vector3 to(Math::sin(an), 0, -Math::cos(an));
  749. Vector3 r1, r2;
  750. Geometry::get_closest_points_between_segments(from, to, ray_from, ray_to, r1, r2);
  751. float d = r1.distance_to(r2);
  752. if (d < closest_dist) {
  753. closest_dist = d;
  754. closest_angle = i;
  755. }
  756. }
  757. if (closest_angle < 91) {
  758. player->set_emission_angle(closest_angle);
  759. }
  760. }
  761. void AudioStreamPlayer3DSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
  762. if (p_cancel) {
  763. player->set_emission_angle(p_restore);
  764. } else {
  765. UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
  766. ur->create_action(TTR("Change AudioStreamPlayer3D Emission Angle"));
  767. ur->add_do_method(player, "set_emission_angle", player->get_emission_angle());
  768. ur->add_undo_method(player, "set_emission_angle", p_restore);
  769. ur->commit_action();
  770. }
  771. }
  772. void AudioStreamPlayer3DSpatialGizmo::redraw() {
  773. clear();
  774. Ref<Material> icon = create_icon_material("stream_player_3d_material", SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer", "EditorIcons"));
  775. if (player->is_emission_angle_enabled()) {
  776. Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/stream_player_3d");
  777. Ref<Material> material = create_material("stream_player_3d_material", gizmo_color);
  778. float pc = player->get_emission_angle();
  779. Vector<Vector3> points;
  780. points.resize(208);
  781. float ofs = -Math::cos(Math::deg2rad(pc));
  782. float radius = Math::sin(Math::deg2rad(pc));
  783. for (int i = 0; i < 100; i++) {
  784. float a = i * 2.0 * Math_PI / 100.0;
  785. float an = (i + 1) * 2.0 * Math_PI / 100.0;
  786. Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
  787. Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs);
  788. points[i * 2 + 0] = from;
  789. points[i * 2 + 1] = to;
  790. }
  791. for (int i = 0; i < 4; i++) {
  792. float a = i * 2.0 * Math_PI / 4.0;
  793. Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
  794. points[200 + i * 2 + 0] = from;
  795. points[200 + i * 2 + 1] = Vector3();
  796. }
  797. add_lines(points, material);
  798. add_collision_segments(points);
  799. Vector<Vector3> handles;
  800. float ha = Math::deg2rad(player->get_emission_angle());
  801. handles.push_back(Vector3(Math::sin(ha), 0, -Math::cos(ha)));
  802. add_handles(handles);
  803. }
  804. add_unscaled_billboard(icon, 0.05);
  805. }
  806. AudioStreamPlayer3DSpatialGizmo::AudioStreamPlayer3DSpatialGizmo(AudioStreamPlayer3D *p_player) {
  807. player = p_player;
  808. set_spatial_node(p_player);
  809. }
  810. //////
  811. String CameraSpatialGizmo::get_handle_name(int p_idx) const {
  812. if (camera->get_projection() == Camera::PROJECTION_PERSPECTIVE) {
  813. return "FOV";
  814. } else {
  815. return "Size";
  816. }
  817. }
  818. Variant CameraSpatialGizmo::get_handle_value(int p_idx) const {
  819. if (camera->get_projection() == Camera::PROJECTION_PERSPECTIVE) {
  820. return camera->get_fov();
  821. } else {
  822. return camera->get_size();
  823. }
  824. }
  825. void CameraSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
  826. Transform gt = camera->get_global_transform();
  827. gt.orthonormalize();
  828. Transform gi = gt.affine_inverse();
  829. Vector3 ray_from = p_camera->project_ray_origin(p_point);
  830. Vector3 ray_dir = p_camera->project_ray_normal(p_point);
  831. Vector3 s[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
  832. if (camera->get_projection() == Camera::PROJECTION_PERSPECTIVE) {
  833. Transform gt = camera->get_global_transform();
  834. float a = _find_closest_angle_to_half_pi_arc(s[0], s[1], 1.0, gt);
  835. camera->set("fov", a);
  836. } else {
  837. Vector3 ra, rb;
  838. Geometry::get_closest_points_between_segments(Vector3(0, 0, -1), Vector3(4096, 0, -1), s[0], s[1], ra, rb);
  839. float d = ra.x * 2.0;
  840. if (d < 0)
  841. d = 0;
  842. camera->set("size", d);
  843. }
  844. }
  845. void CameraSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
  846. if (camera->get_projection() == Camera::PROJECTION_PERSPECTIVE) {
  847. if (p_cancel) {
  848. camera->set("fov", p_restore);
  849. } else {
  850. UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
  851. ur->create_action(TTR("Change Camera FOV"));
  852. ur->add_do_property(camera, "fov", camera->get_fov());
  853. ur->add_undo_property(camera, "fov", p_restore);
  854. ur->commit_action();
  855. }
  856. } else {
  857. if (p_cancel) {
  858. camera->set("size", p_restore);
  859. } else {
  860. UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
  861. ur->create_action(TTR("Change Camera Size"));
  862. ur->add_do_property(camera, "size", camera->get_size());
  863. ur->add_undo_property(camera, "size", p_restore);
  864. ur->commit_action();
  865. }
  866. }
  867. }
  868. void CameraSpatialGizmo::redraw() {
  869. clear();
  870. Vector<Vector3> lines;
  871. Vector<Vector3> handles;
  872. Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/camera");
  873. Ref<Material> material = create_material("camera_material", gizmo_color);
  874. Ref<Material> icon = create_icon_material("camera_icon", SpatialEditor::get_singleton()->get_icon("GizmoCamera", "EditorIcons"));
  875. switch (camera->get_projection()) {
  876. case Camera::PROJECTION_PERSPECTIVE: {
  877. float fov = camera->get_fov();
  878. Vector3 side = Vector3(Math::sin(Math::deg2rad(fov)), 0, -Math::cos(Math::deg2rad(fov)));
  879. Vector3 nside = side;
  880. nside.x = -nside.x;
  881. Vector3 up = Vector3(0, side.x, 0);
  882. #define ADD_TRIANGLE(m_a, m_b, m_c) \
  883. { \
  884. lines.push_back(m_a); \
  885. lines.push_back(m_b); \
  886. lines.push_back(m_b); \
  887. lines.push_back(m_c); \
  888. lines.push_back(m_c); \
  889. lines.push_back(m_a); \
  890. }
  891. ADD_TRIANGLE(Vector3(), side + up, side - up);
  892. ADD_TRIANGLE(Vector3(), nside + up, nside - up);
  893. ADD_TRIANGLE(Vector3(), side + up, nside + up);
  894. ADD_TRIANGLE(Vector3(), side - up, nside - up);
  895. handles.push_back(side);
  896. side.x *= 0.25;
  897. nside.x *= 0.25;
  898. Vector3 tup(0, up.y * 3 / 2, side.z);
  899. ADD_TRIANGLE(tup, side + up, nside + up);
  900. } break;
  901. case Camera::PROJECTION_ORTHOGONAL: {
  902. #define ADD_QUAD(m_a, m_b, m_c, m_d) \
  903. { \
  904. lines.push_back(m_a); \
  905. lines.push_back(m_b); \
  906. lines.push_back(m_b); \
  907. lines.push_back(m_c); \
  908. lines.push_back(m_c); \
  909. lines.push_back(m_d); \
  910. lines.push_back(m_d); \
  911. lines.push_back(m_a); \
  912. }
  913. float size = camera->get_size();
  914. float hsize = size * 0.5;
  915. Vector3 right(hsize, 0, 0);
  916. Vector3 up(0, hsize, 0);
  917. Vector3 back(0, 0, -1.0);
  918. Vector3 front(0, 0, 0);
  919. ADD_QUAD(-up - right, -up + right, up + right, up - right);
  920. ADD_QUAD(-up - right + back, -up + right + back, up + right + back, up - right + back);
  921. ADD_QUAD(up + right, up + right + back, up - right + back, up - right);
  922. ADD_QUAD(-up + right, -up + right + back, -up - right + back, -up - right);
  923. handles.push_back(right + back);
  924. right.x *= 0.25;
  925. Vector3 tup(0, up.y * 3 / 2, back.z);
  926. ADD_TRIANGLE(tup, right + up + back, -right + up + back);
  927. } break;
  928. }
  929. add_lines(lines, material);
  930. add_collision_segments(lines);
  931. add_unscaled_billboard(icon, 0.05);
  932. add_handles(handles);
  933. }
  934. CameraSpatialGizmo::CameraSpatialGizmo(Camera *p_camera) {
  935. camera = p_camera;
  936. set_spatial_node(camera);
  937. }
  938. //////
  939. bool MeshInstanceSpatialGizmo::can_draw() const {
  940. return true; //mesh can always draw (even though nothing is displayed)
  941. }
  942. void MeshInstanceSpatialGizmo::redraw() {
  943. Ref<Mesh> m = mesh->get_mesh();
  944. if (!m.is_valid())
  945. return; //none
  946. Ref<TriangleMesh> tm = m->generate_triangle_mesh();
  947. if (tm.is_valid()) {
  948. Rect3 aabb;
  949. add_collision_triangles(tm, aabb);
  950. }
  951. }
  952. MeshInstanceSpatialGizmo::MeshInstanceSpatialGizmo(MeshInstance *p_mesh) {
  953. mesh = p_mesh;
  954. set_spatial_node(p_mesh);
  955. }
  956. /////
  957. void Position3DSpatialGizmo::redraw() {
  958. clear();
  959. add_mesh(SpatialEditorGizmos::singleton->pos3d_mesh);
  960. Vector<Vector3> cursor_points;
  961. float cs = 0.25;
  962. cursor_points.push_back(Vector3(+cs, 0, 0));
  963. cursor_points.push_back(Vector3(-cs, 0, 0));
  964. cursor_points.push_back(Vector3(0, +cs, 0));
  965. cursor_points.push_back(Vector3(0, -cs, 0));
  966. cursor_points.push_back(Vector3(0, 0, +cs));
  967. cursor_points.push_back(Vector3(0, 0, -cs));
  968. add_collision_segments(cursor_points);
  969. }
  970. Position3DSpatialGizmo::Position3DSpatialGizmo(Position3D *p_p3d) {
  971. p3d = p_p3d;
  972. set_spatial_node(p3d);
  973. }
  974. /////
  975. void SkeletonSpatialGizmo::redraw() {
  976. clear();
  977. Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/skeleton");
  978. Ref<Material> material = create_material("skeleton_material", gizmo_color);
  979. Ref<SurfaceTool> surface_tool(memnew(SurfaceTool));
  980. surface_tool->begin(Mesh::PRIMITIVE_LINES);
  981. surface_tool->set_material(material);
  982. Vector<Transform> grests;
  983. grests.resize(skel->get_bone_count());
  984. Vector<int> bones;
  985. Vector<float> weights;
  986. bones.resize(4);
  987. weights.resize(4);
  988. for (int i = 0; i < 4; i++) {
  989. bones[i] = 0;
  990. weights[i] = 0;
  991. }
  992. weights[0] = 1;
  993. Rect3 aabb;
  994. Color bonecolor = Color(1.0, 0.4, 0.4, 0.3);
  995. Color rootcolor = Color(0.4, 1.0, 0.4, 0.1);
  996. for (int i = 0; i < skel->get_bone_count(); i++) {
  997. int parent = skel->get_bone_parent(i);
  998. if (parent >= 0) {
  999. grests[i] = grests[parent] * skel->get_bone_rest(i);
  1000. Vector3 v0 = grests[parent].origin;
  1001. Vector3 v1 = grests[i].origin;
  1002. Vector3 d = (v1 - v0).normalized();
  1003. float dist = v0.distance_to(v1);
  1004. //find closest axis
  1005. int closest = -1;
  1006. float closest_d = 0.0;
  1007. for (int j = 0; j < 3; j++) {
  1008. float dp = Math::abs(grests[parent].basis[j].normalized().dot(d));
  1009. if (j == 0 || dp > closest_d)
  1010. closest = j;
  1011. }
  1012. //find closest other
  1013. Vector3 first;
  1014. Vector3 points[4];
  1015. int pointidx = 0;
  1016. for (int j = 0; j < 3; j++) {
  1017. bones[0] = parent;
  1018. surface_tool->add_bones(bones);
  1019. surface_tool->add_weights(weights);
  1020. surface_tool->add_color(rootcolor);
  1021. surface_tool->add_vertex(v0 - grests[parent].basis[j].normalized() * dist * 0.05);
  1022. surface_tool->add_bones(bones);
  1023. surface_tool->add_weights(weights);
  1024. surface_tool->add_color(rootcolor);
  1025. surface_tool->add_vertex(v0 + grests[parent].basis[j].normalized() * dist * 0.05);
  1026. if (j == closest)
  1027. continue;
  1028. Vector3 axis;
  1029. if (first == Vector3()) {
  1030. axis = d.cross(d.cross(grests[parent].basis[j])).normalized();
  1031. first = axis;
  1032. } else {
  1033. axis = d.cross(first).normalized();
  1034. }
  1035. for (int k = 0; k < 2; k++) {
  1036. if (k == 1)
  1037. axis = -axis;
  1038. Vector3 point = v0 + d * dist * 0.2;
  1039. point += axis * dist * 0.1;
  1040. bones[0] = parent;
  1041. surface_tool->add_bones(bones);
  1042. surface_tool->add_weights(weights);
  1043. surface_tool->add_color(bonecolor);
  1044. surface_tool->add_vertex(v0);
  1045. surface_tool->add_bones(bones);
  1046. surface_tool->add_weights(weights);
  1047. surface_tool->add_color(bonecolor);
  1048. surface_tool->add_vertex(point);
  1049. bones[0] = parent;
  1050. surface_tool->add_bones(bones);
  1051. surface_tool->add_weights(weights);
  1052. surface_tool->add_color(bonecolor);
  1053. surface_tool->add_vertex(point);
  1054. bones[0] = i;
  1055. surface_tool->add_bones(bones);
  1056. surface_tool->add_weights(weights);
  1057. surface_tool->add_color(bonecolor);
  1058. surface_tool->add_vertex(v1);
  1059. points[pointidx++] = point;
  1060. }
  1061. }
  1062. SWAP(points[1], points[2]);
  1063. for (int j = 0; j < 4; j++) {
  1064. bones[0] = parent;
  1065. surface_tool->add_bones(bones);
  1066. surface_tool->add_weights(weights);
  1067. surface_tool->add_color(bonecolor);
  1068. surface_tool->add_vertex(points[j]);
  1069. surface_tool->add_bones(bones);
  1070. surface_tool->add_weights(weights);
  1071. surface_tool->add_color(bonecolor);
  1072. surface_tool->add_vertex(points[(j + 1) % 4]);
  1073. }
  1074. /*
  1075. bones[0]=parent;
  1076. surface_tool->add_bones(bones);
  1077. surface_tool->add_weights(weights);
  1078. surface_tool->add_color(Color(0.4,1,0.4,0.4));
  1079. surface_tool->add_vertex(v0);
  1080. bones[0]=i;
  1081. surface_tool->add_bones(bones);
  1082. surface_tool->add_weights(weights);
  1083. surface_tool->add_color(Color(0.4,1,0.4,0.4));
  1084. surface_tool->add_vertex(v1);
  1085. */
  1086. } else {
  1087. grests[i] = skel->get_bone_rest(i);
  1088. bones[0] = i;
  1089. }
  1090. /*
  1091. Transform t = grests[i];
  1092. t.orthonormalize();
  1093. for (int i=0;i<6;i++) {
  1094. Vector3 face_points[4];
  1095. for (int j=0;j<4;j++) {
  1096. float v[3];
  1097. v[0]=1.0;
  1098. v[1]=1-2*((j>>1)&1);
  1099. v[2]=v[1]*(1-2*(j&1));
  1100. for (int k=0;k<3;k++) {
  1101. if (i<3)
  1102. face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1);
  1103. else
  1104. face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1);
  1105. }
  1106. }
  1107. for(int j=0;j<4;j++) {
  1108. surface_tool->add_bones(bones);
  1109. surface_tool->add_weights(weights);
  1110. surface_tool->add_color(Color(1.0,0.4,0.4,0.4));
  1111. surface_tool->add_vertex(t.xform(face_points[j]*0.04));
  1112. surface_tool->add_bones(bones);
  1113. surface_tool->add_weights(weights);
  1114. surface_tool->add_color(Color(1.0,0.4,0.4,0.4));
  1115. surface_tool->add_vertex(t.xform(face_points[(j+1)%4]*0.04));
  1116. }
  1117. }
  1118. */
  1119. }
  1120. Ref<ArrayMesh> m = surface_tool->commit();
  1121. add_mesh(m, false, skel->get_skeleton());
  1122. }
  1123. SkeletonSpatialGizmo::SkeletonSpatialGizmo(Skeleton *p_skel) {
  1124. skel = p_skel;
  1125. set_spatial_node(p_skel);
  1126. }
  1127. #if 0
  1128. void RoomSpatialGizmo::redraw() {
  1129. clear();
  1130. Ref<RoomBounds> roomie = room->get_room();
  1131. if (roomie.is_null())
  1132. return;
  1133. PoolVector<Face3> faces = roomie->get_geometry_hint();
  1134. Vector<Vector3> lines;
  1135. int fc = faces.size();
  1136. PoolVector<Face3>::Read r = faces.read();
  1137. Map<_EdgeKey, Vector3> edge_map;
  1138. for (int i = 0; i < fc; i++) {
  1139. Vector3 fn = r[i].get_plane().normal;
  1140. for (int j = 0; j < 3; j++) {
  1141. _EdgeKey ek;
  1142. ek.from = r[i].vertex[j].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
  1143. ek.to = r[i].vertex[(j + 1) % 3].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
  1144. if (ek.from < ek.to)
  1145. SWAP(ek.from, ek.to);
  1146. Map<_EdgeKey, Vector3>::Element *E = edge_map.find(ek);
  1147. if (E) {
  1148. if (E->get().dot(fn) > 0.9) {
  1149. E->get() = Vector3();
  1150. }
  1151. } else {
  1152. edge_map[ek] = fn;
  1153. }
  1154. }
  1155. }
  1156. for (Map<_EdgeKey, Vector3>::Element *E = edge_map.front(); E; E = E->next()) {
  1157. if (E->get() != Vector3()) {
  1158. lines.push_back(E->key().from);
  1159. lines.push_back(E->key().to);
  1160. }
  1161. }
  1162. add_lines(lines, SpatialEditorGizmos::singleton->room_material);
  1163. add_collision_segments(lines);
  1164. }
  1165. RoomSpatialGizmo::RoomSpatialGizmo(Room *p_room) {
  1166. set_spatial_node(p_room);
  1167. room = p_room;
  1168. }
  1169. /////
  1170. void PortalSpatialGizmo::redraw() {
  1171. clear();
  1172. Vector<Point2> points = portal->get_shape();
  1173. if (points.size() == 0) {
  1174. return;
  1175. }
  1176. Vector<Vector3> lines;
  1177. Vector3 center;
  1178. for (int i = 0; i < points.size(); i++) {
  1179. Vector3 f;
  1180. f.x = points[i].x;
  1181. f.y = points[i].y;
  1182. Vector3 fn;
  1183. fn.x = points[(i + 1) % points.size()].x;
  1184. fn.y = points[(i + 1) % points.size()].y;
  1185. center += f;
  1186. lines.push_back(f);
  1187. lines.push_back(fn);
  1188. }
  1189. center /= points.size();
  1190. lines.push_back(center);
  1191. lines.push_back(center + Vector3(0, 0, 1));
  1192. add_lines(lines, SpatialEditorGizmos::singleton->portal_material);
  1193. add_collision_segments(lines);
  1194. }
  1195. PortalSpatialGizmo::PortalSpatialGizmo(Portal *p_portal) {
  1196. set_spatial_node(p_portal);
  1197. portal = p_portal;
  1198. }
  1199. #endif
  1200. /////
  1201. void RayCastSpatialGizmo::redraw() {
  1202. clear();
  1203. Vector<Vector3> lines;
  1204. lines.push_back(Vector3());
  1205. lines.push_back(raycast->get_cast_to());
  1206. Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
  1207. Ref<Material> material = create_material("shape_material", gizmo_color);
  1208. add_lines(lines, material);
  1209. add_collision_segments(lines);
  1210. }
  1211. RayCastSpatialGizmo::RayCastSpatialGizmo(RayCast *p_raycast) {
  1212. set_spatial_node(p_raycast);
  1213. raycast = p_raycast;
  1214. }
  1215. /////
  1216. void VehicleWheelSpatialGizmo::redraw() {
  1217. clear();
  1218. Vector<Vector3> points;
  1219. float r = car_wheel->get_radius();
  1220. const int skip = 10;
  1221. for (int i = 0; i <= 360; i += skip) {
  1222. float ra = Math::deg2rad((float)i);
  1223. float rb = Math::deg2rad((float)i + skip);
  1224. Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
  1225. Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;
  1226. points.push_back(Vector3(0, a.x, a.y));
  1227. points.push_back(Vector3(0, b.x, b.y));
  1228. const int springsec = 4;
  1229. for (int j = 0; j < springsec; j++) {
  1230. float t = car_wheel->get_suspension_rest_length() * 5;
  1231. points.push_back(Vector3(a.x, i / 360.0 * t / springsec + j * (t / springsec), a.y) * 0.2);
  1232. points.push_back(Vector3(b.x, (i + skip) / 360.0 * t / springsec + j * (t / springsec), b.y) * 0.2);
  1233. }
  1234. }
  1235. //travel
  1236. points.push_back(Vector3(0, 0, 0));
  1237. points.push_back(Vector3(0, car_wheel->get_suspension_rest_length(), 0));
  1238. //axis
  1239. points.push_back(Vector3(r * 0.2, car_wheel->get_suspension_rest_length(), 0));
  1240. points.push_back(Vector3(-r * 0.2, car_wheel->get_suspension_rest_length(), 0));
  1241. //axis
  1242. points.push_back(Vector3(r * 0.2, 0, 0));
  1243. points.push_back(Vector3(-r * 0.2, 0, 0));
  1244. //forward line
  1245. points.push_back(Vector3(0, -r, 0));
  1246. points.push_back(Vector3(0, -r, r * 2));
  1247. points.push_back(Vector3(0, -r, r * 2));
  1248. points.push_back(Vector3(r * 2 * 0.2, -r, r * 2 * 0.8));
  1249. points.push_back(Vector3(0, -r, r * 2));
  1250. points.push_back(Vector3(-r * 2 * 0.2, -r, r * 2 * 0.8));
  1251. Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
  1252. Ref<Material> material = create_material("shape_material", gizmo_color);
  1253. add_lines(points, material);
  1254. add_collision_segments(points);
  1255. }
  1256. VehicleWheelSpatialGizmo::VehicleWheelSpatialGizmo(VehicleWheel *p_car_wheel) {
  1257. set_spatial_node(p_car_wheel);
  1258. car_wheel = p_car_wheel;
  1259. }
  1260. ///////////
  1261. String CollisionShapeSpatialGizmo::get_handle_name(int p_idx) const {
  1262. Ref<Shape> s = cs->get_shape();
  1263. if (s.is_null())
  1264. return "";
  1265. if (Object::cast_to<SphereShape>(*s)) {
  1266. return "Radius";
  1267. }
  1268. if (Object::cast_to<BoxShape>(*s)) {
  1269. return "Extents";
  1270. }
  1271. if (Object::cast_to<CapsuleShape>(*s)) {
  1272. return p_idx == 0 ? "Radius" : "Height";
  1273. }
  1274. if (Object::cast_to<RayShape>(*s)) {
  1275. return "Length";
  1276. }
  1277. return "";
  1278. }
  1279. Variant CollisionShapeSpatialGizmo::get_handle_value(int p_idx) const {
  1280. Ref<Shape> s = cs->get_shape();
  1281. if (s.is_null())
  1282. return Variant();
  1283. if (Object::cast_to<SphereShape>(*s)) {
  1284. Ref<SphereShape> ss = s;
  1285. return ss->get_radius();
  1286. }
  1287. if (Object::cast_to<BoxShape>(*s)) {
  1288. Ref<BoxShape> bs = s;
  1289. return bs->get_extents();
  1290. }
  1291. if (Object::cast_to<CapsuleShape>(*s)) {
  1292. Ref<CapsuleShape> cs = s;
  1293. return p_idx == 0 ? cs->get_radius() : cs->get_height();
  1294. }
  1295. if (Object::cast_to<RayShape>(*s)) {
  1296. Ref<RayShape> cs = s;
  1297. return cs->get_length();
  1298. }
  1299. return Variant();
  1300. }
  1301. void CollisionShapeSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
  1302. Ref<Shape> s = cs->get_shape();
  1303. if (s.is_null())
  1304. return;
  1305. Transform gt = cs->get_global_transform();
  1306. gt.orthonormalize();
  1307. Transform gi = gt.affine_inverse();
  1308. Vector3 ray_from = p_camera->project_ray_origin(p_point);
  1309. Vector3 ray_dir = p_camera->project_ray_normal(p_point);
  1310. Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
  1311. if (Object::cast_to<SphereShape>(*s)) {
  1312. Ref<SphereShape> ss = s;
  1313. Vector3 ra, rb;
  1314. Geometry::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb);
  1315. float d = ra.x;
  1316. if (d < 0.001)
  1317. d = 0.001;
  1318. ss->set_radius(d);
  1319. }
  1320. if (Object::cast_to<RayShape>(*s)) {
  1321. Ref<RayShape> rs = s;
  1322. Vector3 ra, rb;
  1323. Geometry::get_closest_points_between_segments(Vector3(), Vector3(0, 0, 4096), sg[0], sg[1], ra, rb);
  1324. float d = ra.z;
  1325. if (d < 0.001)
  1326. d = 0.001;
  1327. rs->set_length(d);
  1328. }
  1329. if (Object::cast_to<BoxShape>(*s)) {
  1330. Vector3 axis;
  1331. axis[p_idx] = 1.0;
  1332. Ref<BoxShape> bs = s;
  1333. Vector3 ra, rb;
  1334. Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
  1335. float d = ra[p_idx];
  1336. if (d < 0.001)
  1337. d = 0.001;
  1338. Vector3 he = bs->get_extents();
  1339. he[p_idx] = d;
  1340. bs->set_extents(he);
  1341. }
  1342. if (Object::cast_to<CapsuleShape>(*s)) {
  1343. Vector3 axis;
  1344. axis[p_idx == 0 ? 0 : 2] = 1.0;
  1345. Ref<CapsuleShape> cs = s;
  1346. Vector3 ra, rb;
  1347. Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
  1348. float d = axis.dot(ra);
  1349. if (p_idx == 1)
  1350. d -= cs->get_radius();
  1351. if (d < 0.001)
  1352. d = 0.001;
  1353. if (p_idx == 0)
  1354. cs->set_radius(d);
  1355. else if (p_idx == 1)
  1356. cs->set_height(d * 2.0);
  1357. }
  1358. }
  1359. void CollisionShapeSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
  1360. Ref<Shape> s = cs->get_shape();
  1361. if (s.is_null())
  1362. return;
  1363. if (Object::cast_to<SphereShape>(*s)) {
  1364. Ref<SphereShape> ss = s;
  1365. if (p_cancel) {
  1366. ss->set_radius(p_restore);
  1367. return;
  1368. }
  1369. UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
  1370. ur->create_action(TTR("Change Sphere Shape Radius"));
  1371. ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius());
  1372. ur->add_undo_method(ss.ptr(), "set_radius", p_restore);
  1373. ur->commit_action();
  1374. }
  1375. if (Object::cast_to<BoxShape>(*s)) {
  1376. Ref<BoxShape> ss = s;
  1377. if (p_cancel) {
  1378. ss->set_extents(p_restore);
  1379. return;
  1380. }
  1381. UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
  1382. ur->create_action(TTR("Change Box Shape Extents"));
  1383. ur->add_do_method(ss.ptr(), "set_extents", ss->get_extents());
  1384. ur->add_undo_method(ss.ptr(), "set_extents", p_restore);
  1385. ur->commit_action();
  1386. }
  1387. if (Object::cast_to<CapsuleShape>(*s)) {
  1388. Ref<CapsuleShape> ss = s;
  1389. if (p_cancel) {
  1390. if (p_idx == 0)
  1391. ss->set_radius(p_restore);
  1392. else
  1393. ss->set_height(p_restore);
  1394. return;
  1395. }
  1396. UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
  1397. if (p_idx == 0) {
  1398. ur->create_action(TTR("Change Capsule Shape Radius"));
  1399. ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius());
  1400. ur->add_undo_method(ss.ptr(), "set_radius", p_restore);
  1401. } else {
  1402. ur->create_action(TTR("Change Capsule Shape Height"));
  1403. ur->add_do_method(ss.ptr(), "set_height", ss->get_height());
  1404. ur->add_undo_method(ss.ptr(), "set_height", p_restore);
  1405. }
  1406. ur->commit_action();
  1407. }
  1408. if (Object::cast_to<RayShape>(*s)) {
  1409. Ref<RayShape> ss = s;
  1410. if (p_cancel) {
  1411. ss->set_length(p_restore);
  1412. return;
  1413. }
  1414. UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
  1415. ur->create_action(TTR("Change Ray Shape Length"));
  1416. ur->add_do_method(ss.ptr(), "set_length", ss->get_length());
  1417. ur->add_undo_method(ss.ptr(), "set_length", p_restore);
  1418. ur->commit_action();
  1419. }
  1420. }
  1421. void CollisionShapeSpatialGizmo::redraw() {
  1422. clear();
  1423. Ref<Shape> s = cs->get_shape();
  1424. if (s.is_null())
  1425. return;
  1426. Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
  1427. Ref<Material> material = create_material("shape_material", gizmo_color);
  1428. if (Object::cast_to<SphereShape>(*s)) {
  1429. Ref<SphereShape> sp = s;
  1430. float r = sp->get_radius();
  1431. Vector<Vector3> points;
  1432. for (int i = 0; i <= 360; i++) {
  1433. float ra = Math::deg2rad((float)i);
  1434. float rb = Math::deg2rad((float)i + 1);
  1435. Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
  1436. Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;
  1437. points.push_back(Vector3(a.x, 0, a.y));
  1438. points.push_back(Vector3(b.x, 0, b.y));
  1439. points.push_back(Vector3(0, a.x, a.y));
  1440. points.push_back(Vector3(0, b.x, b.y));
  1441. points.push_back(Vector3(a.x, a.y, 0));
  1442. points.push_back(Vector3(b.x, b.y, 0));
  1443. }
  1444. Vector<Vector3> collision_segments;
  1445. for (int i = 0; i < 64; i++) {
  1446. float ra = i * Math_PI * 2.0 / 64.0;
  1447. float rb = (i + 1) * Math_PI * 2.0 / 64.0;
  1448. Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
  1449. Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * r;
  1450. collision_segments.push_back(Vector3(a.x, 0, a.y));
  1451. collision_segments.push_back(Vector3(b.x, 0, b.y));
  1452. collision_segments.push_back(Vector3(0, a.x, a.y));
  1453. collision_segments.push_back(Vector3(0, b.x, b.y));
  1454. collision_segments.push_back(Vector3(a.x, a.y, 0));
  1455. collision_segments.push_back(Vector3(b.x, b.y, 0));
  1456. }
  1457. add_lines(points, material);
  1458. add_collision_segments(collision_segments);
  1459. Vector<Vector3> handles;
  1460. handles.push_back(Vector3(r, 0, 0));
  1461. add_handles(handles);
  1462. }
  1463. if (Object::cast_to<BoxShape>(*s)) {
  1464. Ref<BoxShape> bs = s;
  1465. Vector<Vector3> lines;
  1466. Rect3 aabb;
  1467. aabb.position = -bs->get_extents();
  1468. aabb.size = aabb.position * -2;
  1469. for (int i = 0; i < 12; i++) {
  1470. Vector3 a, b;
  1471. aabb.get_edge(i, a, b);
  1472. lines.push_back(a);
  1473. lines.push_back(b);
  1474. }
  1475. Vector<Vector3> handles;
  1476. for (int i = 0; i < 3; i++) {
  1477. Vector3 ax;
  1478. ax[i] = bs->get_extents()[i];
  1479. handles.push_back(ax);
  1480. }
  1481. add_lines(lines, material);
  1482. add_collision_segments(lines);
  1483. add_handles(handles);
  1484. }
  1485. if (Object::cast_to<CapsuleShape>(*s)) {
  1486. Ref<CapsuleShape> cs = s;
  1487. float radius = cs->get_radius();
  1488. float height = cs->get_height();
  1489. Vector<Vector3> points;
  1490. Vector3 d(0, 0, height * 0.5);
  1491. for (int i = 0; i < 360; i++) {
  1492. float ra = Math::deg2rad((float)i);
  1493. float rb = Math::deg2rad((float)i + 1);
  1494. Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
  1495. Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius;
  1496. points.push_back(Vector3(a.x, a.y, 0) + d);
  1497. points.push_back(Vector3(b.x, b.y, 0) + d);
  1498. points.push_back(Vector3(a.x, a.y, 0) - d);
  1499. points.push_back(Vector3(b.x, b.y, 0) - d);
  1500. if (i % 90 == 0) {
  1501. points.push_back(Vector3(a.x, a.y, 0) + d);
  1502. points.push_back(Vector3(a.x, a.y, 0) - d);
  1503. }
  1504. Vector3 dud = i < 180 ? d : -d;
  1505. points.push_back(Vector3(0, a.y, a.x) + dud);
  1506. points.push_back(Vector3(0, b.y, b.x) + dud);
  1507. points.push_back(Vector3(a.y, 0, a.x) + dud);
  1508. points.push_back(Vector3(b.y, 0, b.x) + dud);
  1509. }
  1510. add_lines(points, material);
  1511. Vector<Vector3> collision_segments;
  1512. for (int i = 0; i < 64; i++) {
  1513. float ra = i * Math_PI * 2.0 / 64.0;
  1514. float rb = (i + 1) * Math_PI * 2.0 / 64.0;
  1515. Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
  1516. Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius;
  1517. collision_segments.push_back(Vector3(a.x, a.y, 0) + d);
  1518. collision_segments.push_back(Vector3(b.x, b.y, 0) + d);
  1519. collision_segments.push_back(Vector3(a.x, a.y, 0) - d);
  1520. collision_segments.push_back(Vector3(b.x, b.y, 0) - d);
  1521. if (i % 16 == 0) {
  1522. collision_segments.push_back(Vector3(a.x, a.y, 0) + d);
  1523. collision_segments.push_back(Vector3(a.x, a.y, 0) - d);
  1524. }
  1525. Vector3 dud = i < 32 ? d : -d;
  1526. collision_segments.push_back(Vector3(0, a.y, a.x) + dud);
  1527. collision_segments.push_back(Vector3(0, b.y, b.x) + dud);
  1528. collision_segments.push_back(Vector3(a.y, 0, a.x) + dud);
  1529. collision_segments.push_back(Vector3(b.y, 0, b.x) + dud);
  1530. }
  1531. add_collision_segments(collision_segments);
  1532. Vector<Vector3> handles;
  1533. handles.push_back(Vector3(cs->get_radius(), 0, 0));
  1534. handles.push_back(Vector3(0, 0, cs->get_height() * 0.5 + cs->get_radius()));
  1535. add_handles(handles);
  1536. }
  1537. if (Object::cast_to<PlaneShape>(*s)) {
  1538. Ref<PlaneShape> ps = s;
  1539. Plane p = ps->get_plane();
  1540. Vector<Vector3> points;
  1541. Vector3 n1 = p.get_any_perpendicular_normal();
  1542. Vector3 n2 = p.normal.cross(n1).normalized();
  1543. Vector3 pface[4] = {
  1544. p.normal * p.d + n1 * 10.0 + n2 * 10.0,
  1545. p.normal * p.d + n1 * 10.0 + n2 * -10.0,
  1546. p.normal * p.d + n1 * -10.0 + n2 * -10.0,
  1547. p.normal * p.d + n1 * -10.0 + n2 * 10.0,
  1548. };
  1549. points.push_back(pface[0]);
  1550. points.push_back(pface[1]);
  1551. points.push_back(pface[1]);
  1552. points.push_back(pface[2]);
  1553. points.push_back(pface[2]);
  1554. points.push_back(pface[3]);
  1555. points.push_back(pface[3]);
  1556. points.push_back(pface[0]);
  1557. points.push_back(p.normal * p.d);
  1558. points.push_back(p.normal * p.d + p.normal * 3);
  1559. add_lines(points, material);
  1560. add_collision_segments(points);
  1561. }
  1562. if (Object::cast_to<ConvexPolygonShape>(*s)) {
  1563. PoolVector<Vector3> points = Object::cast_to<ConvexPolygonShape>(*s)->get_points();
  1564. if (points.size() > 3) {
  1565. QuickHull qh;
  1566. Vector<Vector3> varr = Variant(points);
  1567. Geometry::MeshData md;
  1568. Error err = qh.build(varr, md);
  1569. if (err == OK) {
  1570. Vector<Vector3> points;
  1571. points.resize(md.edges.size() * 2);
  1572. for (int i = 0; i < md.edges.size(); i++) {
  1573. points[i * 2 + 0] = md.vertices[md.edges[i].a];
  1574. points[i * 2 + 1] = md.vertices[md.edges[i].b];
  1575. }
  1576. add_lines(points, material);
  1577. add_collision_segments(points);
  1578. }
  1579. }
  1580. }
  1581. if (Object::cast_to<RayShape>(*s)) {
  1582. Ref<RayShape> rs = s;
  1583. Vector<Vector3> points;
  1584. points.push_back(Vector3());
  1585. points.push_back(Vector3(0, 0, rs->get_length()));
  1586. add_lines(points, material);
  1587. add_collision_segments(points);
  1588. Vector<Vector3> handles;
  1589. handles.push_back(Vector3(0, 0, rs->get_length()));
  1590. add_handles(handles);
  1591. }
  1592. }
  1593. CollisionShapeSpatialGizmo::CollisionShapeSpatialGizmo(CollisionShape *p_cs) {
  1594. cs = p_cs;
  1595. set_spatial_node(p_cs);
  1596. }
  1597. /////
  1598. void CollisionPolygonSpatialGizmo::redraw() {
  1599. clear();
  1600. Vector<Vector2> points = polygon->get_polygon();
  1601. float depth = polygon->get_depth() * 0.5;
  1602. Vector<Vector3> lines;
  1603. for (int i = 0; i < points.size(); i++) {
  1604. int n = (i + 1) % points.size();
  1605. lines.push_back(Vector3(points[i].x, points[i].y, depth));
  1606. lines.push_back(Vector3(points[n].x, points[n].y, depth));
  1607. lines.push_back(Vector3(points[i].x, points[i].y, -depth));
  1608. lines.push_back(Vector3(points[n].x, points[n].y, -depth));
  1609. lines.push_back(Vector3(points[i].x, points[i].y, depth));
  1610. lines.push_back(Vector3(points[i].x, points[i].y, -depth));
  1611. }
  1612. Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/shape");
  1613. Ref<Material> material = create_material("shape_material", gizmo_color);
  1614. add_lines(lines, material);
  1615. add_collision_segments(lines);
  1616. }
  1617. CollisionPolygonSpatialGizmo::CollisionPolygonSpatialGizmo(CollisionPolygon *p_polygon) {
  1618. set_spatial_node(p_polygon);
  1619. polygon = p_polygon;
  1620. }
  1621. ///
  1622. String VisibilityNotifierGizmo::get_handle_name(int p_idx) const {
  1623. switch (p_idx) {
  1624. case 0: return "X";
  1625. case 1: return "Y";
  1626. case 2: return "Z";
  1627. }
  1628. return "";
  1629. }
  1630. Variant VisibilityNotifierGizmo::get_handle_value(int p_idx) const {
  1631. return notifier->get_aabb();
  1632. }
  1633. void VisibilityNotifierGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
  1634. Transform gt = notifier->get_global_transform();
  1635. //gt.orthonormalize();
  1636. Transform gi = gt.affine_inverse();
  1637. Rect3 aabb = notifier->get_aabb();
  1638. Vector3 ray_from = p_camera->project_ray_origin(p_point);
  1639. Vector3 ray_dir = p_camera->project_ray_normal(p_point);
  1640. Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
  1641. Vector3 ofs = aabb.position + aabb.size * 0.5;
  1642. Vector3 axis;
  1643. axis[p_idx] = 1.0;
  1644. Vector3 ra, rb;
  1645. Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb);
  1646. float d = ra[p_idx];
  1647. if (d < 0.001)
  1648. d = 0.001;
  1649. aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d;
  1650. aabb.size[p_idx] = d * 2;
  1651. notifier->set_aabb(aabb);
  1652. }
  1653. void VisibilityNotifierGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
  1654. if (p_cancel) {
  1655. notifier->set_aabb(p_restore);
  1656. return;
  1657. }
  1658. UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
  1659. ur->create_action(TTR("Change Notifier Extents"));
  1660. ur->add_do_method(notifier, "set_aabb", notifier->get_aabb());
  1661. ur->add_undo_method(notifier, "set_aabb", p_restore);
  1662. ur->commit_action();
  1663. }
  1664. void VisibilityNotifierGizmo::redraw() {
  1665. Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/visibility_notifier");
  1666. Ref<Material> material = create_material("visibility_notifier_material", gizmo_color);
  1667. clear();
  1668. Vector<Vector3> lines;
  1669. Rect3 aabb = notifier->get_aabb();
  1670. for (int i = 0; i < 12; i++) {
  1671. Vector3 a, b;
  1672. aabb.get_edge(i, a, b);
  1673. lines.push_back(a);
  1674. lines.push_back(b);
  1675. }
  1676. Vector<Vector3> handles;
  1677. for (int i = 0; i < 3; i++) {
  1678. Vector3 ax;
  1679. ax[i] = aabb.position[i] + aabb.size[i];
  1680. handles.push_back(ax);
  1681. }
  1682. add_lines(lines, material);
  1683. //add_unscaled_billboard(SpatialEditorGizmos::singleton->visi,0.05);
  1684. add_collision_segments(lines);
  1685. add_handles(handles);
  1686. }
  1687. VisibilityNotifierGizmo::VisibilityNotifierGizmo(VisibilityNotifier *p_notifier) {
  1688. notifier = p_notifier;
  1689. set_spatial_node(p_notifier);
  1690. }
  1691. ////////
  1692. ///
  1693. String ParticlesGizmo::get_handle_name(int p_idx) const {
  1694. switch (p_idx) {
  1695. case 0: return "Size X";
  1696. case 1: return "Size Y";
  1697. case 2: return "Size Z";
  1698. case 3: return "Pos X";
  1699. case 4: return "Pos Y";
  1700. case 5: return "Pos Z";
  1701. }
  1702. return "";
  1703. }
  1704. Variant ParticlesGizmo::get_handle_value(int p_idx) const {
  1705. return particles->get_visibility_aabb();
  1706. }
  1707. void ParticlesGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
  1708. Transform gt = particles->get_global_transform();
  1709. //gt.orthonormalize();
  1710. Transform gi = gt.affine_inverse();
  1711. bool move = p_idx >= 3;
  1712. p_idx = p_idx % 3;
  1713. Rect3 aabb = particles->get_visibility_aabb();
  1714. Vector3 ray_from = p_camera->project_ray_origin(p_point);
  1715. Vector3 ray_dir = p_camera->project_ray_normal(p_point);
  1716. Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
  1717. Vector3 ofs = aabb.position + aabb.size * 0.5;
  1718. Vector3 axis;
  1719. axis[p_idx] = 1.0;
  1720. if (move) {
  1721. Vector3 ra, rb;
  1722. Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb);
  1723. float d = ra[p_idx];
  1724. aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5;
  1725. particles->set_visibility_aabb(aabb);
  1726. } else {
  1727. Vector3 ra, rb;
  1728. Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb);
  1729. float d = ra[p_idx] - ofs[p_idx];
  1730. if (d < 0.001)
  1731. d = 0.001;
  1732. //resize
  1733. aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d;
  1734. aabb.size[p_idx] = d * 2;
  1735. particles->set_visibility_aabb(aabb);
  1736. }
  1737. }
  1738. void ParticlesGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
  1739. if (p_cancel) {
  1740. particles->set_visibility_aabb(p_restore);
  1741. return;
  1742. }
  1743. UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
  1744. ur->create_action(TTR("Change Particles AABB"));
  1745. ur->add_do_method(particles, "set_custom_aabb", particles->get_visibility_aabb());
  1746. ur->add_undo_method(particles, "set_custom_aabb", p_restore);
  1747. ur->commit_action();
  1748. }
  1749. void ParticlesGizmo::redraw() {
  1750. clear();
  1751. Vector<Vector3> lines;
  1752. Rect3 aabb = particles->get_visibility_aabb();
  1753. for (int i = 0; i < 12; i++) {
  1754. Vector3 a, b;
  1755. aabb.get_edge(i, a, b);
  1756. lines.push_back(a);
  1757. lines.push_back(b);
  1758. }
  1759. Vector<Vector3> handles;
  1760. for (int i = 0; i < 3; i++) {
  1761. Vector3 ax;
  1762. ax[i] = aabb.position[i] + aabb.size[i];
  1763. ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5;
  1764. ax[(i + 2) % 3] = aabb.position[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5;
  1765. handles.push_back(ax);
  1766. }
  1767. Vector3 center = aabb.position + aabb.size * 0.5;
  1768. for (int i = 0; i < 3; i++) {
  1769. Vector3 ax;
  1770. ax[i] = 1.0;
  1771. handles.push_back(center + ax);
  1772. lines.push_back(center);
  1773. lines.push_back(center + ax);
  1774. }
  1775. Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/particles");
  1776. Ref<Material> material = create_material("particles_material", gizmo_color);
  1777. Ref<Material> icon = create_icon_material("particles_icon", SpatialEditor::get_singleton()->get_icon("GizmoParticles", "EditorIcons"));
  1778. add_lines(lines, material);
  1779. add_collision_segments(lines);
  1780. if (is_selected()) {
  1781. gizmo_color.a = 0.1;
  1782. Ref<Material> solid_material = create_material("particles_solid_material", gizmo_color);
  1783. add_solid_box(solid_material, aabb.get_size());
  1784. }
  1785. //add_unscaled_billboard(SpatialEditorGizmos::singleton->visi,0.05);
  1786. add_unscaled_billboard(icon, 0.05);
  1787. add_handles(handles);
  1788. }
  1789. ParticlesGizmo::ParticlesGizmo(Particles *p_particles) {
  1790. particles = p_particles;
  1791. set_spatial_node(p_particles);
  1792. }
  1793. ////////
  1794. ///
  1795. String ReflectionProbeGizmo::get_handle_name(int p_idx) const {
  1796. switch (p_idx) {
  1797. case 0: return "Extents X";
  1798. case 1: return "Extents Y";
  1799. case 2: return "Extents Z";
  1800. case 3: return "Origin X";
  1801. case 4: return "Origin Y";
  1802. case 5: return "Origin Z";
  1803. }
  1804. return "";
  1805. }
  1806. Variant ReflectionProbeGizmo::get_handle_value(int p_idx) const {
  1807. return Rect3(probe->get_extents(), probe->get_origin_offset());
  1808. }
  1809. void ReflectionProbeGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
  1810. Transform gt = probe->get_global_transform();
  1811. //gt.orthonormalize();
  1812. Transform gi = gt.affine_inverse();
  1813. if (p_idx < 3) {
  1814. Vector3 extents = probe->get_extents();
  1815. Vector3 ray_from = p_camera->project_ray_origin(p_point);
  1816. Vector3 ray_dir = p_camera->project_ray_normal(p_point);
  1817. Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
  1818. Vector3 axis;
  1819. axis[p_idx] = 1.0;
  1820. Vector3 ra, rb;
  1821. Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
  1822. float d = ra[p_idx];
  1823. if (d < 0.001)
  1824. d = 0.001;
  1825. extents[p_idx] = d;
  1826. probe->set_extents(extents);
  1827. } else {
  1828. p_idx -= 3;
  1829. Vector3 origin = probe->get_origin_offset();
  1830. origin[p_idx] = 0;
  1831. Vector3 ray_from = p_camera->project_ray_origin(p_point);
  1832. Vector3 ray_dir = p_camera->project_ray_normal(p_point);
  1833. Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
  1834. Vector3 axis;
  1835. axis[p_idx] = 1.0;
  1836. Vector3 ra, rb;
  1837. Geometry::get_closest_points_between_segments(origin - axis * 16384, origin + axis * 16384, sg[0], sg[1], ra, rb);
  1838. float d = ra[p_idx];
  1839. d += 0.25;
  1840. origin[p_idx] = d;
  1841. probe->set_origin_offset(origin);
  1842. }
  1843. }
  1844. void ReflectionProbeGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
  1845. Rect3 restore = p_restore;
  1846. if (p_cancel) {
  1847. probe->set_extents(restore.position);
  1848. probe->set_origin_offset(restore.size);
  1849. return;
  1850. }
  1851. UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
  1852. ur->create_action(TTR("Change Probe Extents"));
  1853. ur->add_do_method(probe, "set_extents", probe->get_extents());
  1854. ur->add_do_method(probe, "set_origin_offset", probe->get_origin_offset());
  1855. ur->add_undo_method(probe, "set_extents", restore.position);
  1856. ur->add_undo_method(probe, "set_origin_offset", restore.size);
  1857. ur->commit_action();
  1858. }
  1859. void ReflectionProbeGizmo::redraw() {
  1860. clear();
  1861. Vector<Vector3> lines;
  1862. Vector<Vector3> internal_lines;
  1863. Vector3 extents = probe->get_extents();
  1864. Rect3 aabb;
  1865. aabb.position = -extents;
  1866. aabb.size = extents * 2;
  1867. for (int i = 0; i < 12; i++) {
  1868. Vector3 a, b;
  1869. aabb.get_edge(i, a, b);
  1870. lines.push_back(a);
  1871. lines.push_back(b);
  1872. }
  1873. for (int i = 0; i < 8; i++) {
  1874. Vector3 ep = aabb.get_endpoint(i);
  1875. internal_lines.push_back(probe->get_origin_offset());
  1876. internal_lines.push_back(ep);
  1877. }
  1878. Vector<Vector3> handles;
  1879. for (int i = 0; i < 3; i++) {
  1880. Vector3 ax;
  1881. ax[i] = aabb.position[i] + aabb.size[i];
  1882. handles.push_back(ax);
  1883. }
  1884. for (int i = 0; i < 3; i++) {
  1885. Vector3 orig_handle = probe->get_origin_offset();
  1886. orig_handle[i] -= 0.25;
  1887. lines.push_back(orig_handle);
  1888. handles.push_back(orig_handle);
  1889. orig_handle[i] += 0.5;
  1890. lines.push_back(orig_handle);
  1891. }
  1892. Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/reflection_probe");
  1893. Ref<Material> material = create_material("reflection_probe_material", gizmo_color);
  1894. Ref<Material> icon = create_icon_material("reflection_probe_icon", SpatialEditor::get_singleton()->get_icon("GizmoReflectionProbe", "EditorIcons"));
  1895. Color gizmo_color_internal = gizmo_color;
  1896. gizmo_color_internal.a = 0.5;
  1897. Ref<Material> material_internal = create_material("reflection_internal_material", gizmo_color_internal);
  1898. add_lines(lines, material);
  1899. add_lines(internal_lines, material_internal);
  1900. if (is_selected()) {
  1901. gizmo_color.a = 0.1;
  1902. Ref<Material> solid_material = create_material("reflection_probe_solid_material", gizmo_color);
  1903. add_solid_box(solid_material, probe->get_extents() * 2.0);
  1904. }
  1905. //add_unscaled_billboard(SpatialEditorGizmos::singleton->visi,0.05);
  1906. add_unscaled_billboard(icon, 0.05);
  1907. add_collision_segments(lines);
  1908. add_handles(handles);
  1909. }
  1910. ReflectionProbeGizmo::ReflectionProbeGizmo(ReflectionProbe *p_probe) {
  1911. probe = p_probe;
  1912. set_spatial_node(p_probe);
  1913. }
  1914. ////////
  1915. ///
  1916. String GIProbeGizmo::get_handle_name(int p_idx) const {
  1917. switch (p_idx) {
  1918. case 0: return "Extents X";
  1919. case 1: return "Extents Y";
  1920. case 2: return "Extents Z";
  1921. }
  1922. return "";
  1923. }
  1924. Variant GIProbeGizmo::get_handle_value(int p_idx) const {
  1925. return probe->get_extents();
  1926. }
  1927. void GIProbeGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
  1928. Transform gt = probe->get_global_transform();
  1929. //gt.orthonormalize();
  1930. Transform gi = gt.affine_inverse();
  1931. Vector3 extents = probe->get_extents();
  1932. Vector3 ray_from = p_camera->project_ray_origin(p_point);
  1933. Vector3 ray_dir = p_camera->project_ray_normal(p_point);
  1934. Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
  1935. Vector3 axis;
  1936. axis[p_idx] = 1.0;
  1937. Vector3 ra, rb;
  1938. Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
  1939. float d = ra[p_idx];
  1940. if (d < 0.001)
  1941. d = 0.001;
  1942. extents[p_idx] = d;
  1943. probe->set_extents(extents);
  1944. }
  1945. void GIProbeGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
  1946. Vector3 restore = p_restore;
  1947. if (p_cancel) {
  1948. probe->set_extents(restore);
  1949. return;
  1950. }
  1951. UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
  1952. ur->create_action(TTR("Change Probe Extents"));
  1953. ur->add_do_method(probe, "set_extents", probe->get_extents());
  1954. ur->add_undo_method(probe, "set_extents", restore);
  1955. ur->commit_action();
  1956. }
  1957. void GIProbeGizmo::redraw() {
  1958. Color gizmo_color = EDITOR_GET("editors/3d_gizmos/gizmo_colors/gi_probe");
  1959. Ref<Material> material = create_material("gi_probe_material", gizmo_color);
  1960. Ref<Material> icon = create_icon_material("gi_probe_icon", SpatialEditor::get_singleton()->get_icon("GizmoGIProbe", "EditorIcons"));
  1961. Color gizmo_color_internal = gizmo_color;
  1962. gizmo_color_internal.a = 0.1;
  1963. Ref<Material> material_internal = create_material("gi_probe_internal_material", gizmo_color_internal);
  1964. clear();
  1965. Vector<Vector3> lines;
  1966. Vector3 extents = probe->get_extents();
  1967. static const int subdivs[GIProbe::SUBDIV_MAX] = { 64, 128, 256, 512 };
  1968. Rect3 aabb = Rect3(-extents, extents * 2);
  1969. int subdiv = subdivs[probe->get_subdiv()];
  1970. float cell_size = aabb.get_longest_axis_size() / subdiv;
  1971. for (int i = 0; i < 12; i++) {
  1972. Vector3 a, b;
  1973. aabb.get_edge(i, a, b);
  1974. lines.push_back(a);
  1975. lines.push_back(b);
  1976. }
  1977. add_lines(lines, material);
  1978. add_collision_segments(lines);
  1979. lines.clear();
  1980. for (int i = 1; i < subdiv; i++) {
  1981. for (int j = 0; j < 3; j++) {
  1982. if (cell_size * i > aabb.size[j]) {
  1983. continue;
  1984. }
  1985. Vector2 dir;
  1986. dir[j] = 1.0;
  1987. Vector2 ta, tb;
  1988. int j_n1 = (j + 1) % 3;
  1989. int j_n2 = (j + 2) % 3;
  1990. ta[j_n1] = 1.0;
  1991. tb[j_n2] = 1.0;
  1992. for (int k = 0; k < 4; k++) {
  1993. Vector3 from = aabb.position, to = aabb.position;
  1994. from[j] += cell_size * i;
  1995. to[j] += cell_size * i;
  1996. if (k & 1) {
  1997. to[j_n1] += aabb.size[j_n1];
  1998. } else {
  1999. to[j_n2] += aabb.size[j_n2];
  2000. }
  2001. if (k & 2) {
  2002. from[j_n1] += aabb.size[j_n1];
  2003. from[j_n2] += aabb.size[j_n2];
  2004. }
  2005. lines.push_back(from);
  2006. lines.push_back(to);
  2007. }
  2008. }
  2009. }
  2010. add_lines(lines, material_internal);
  2011. Vector<Vector3> handles;
  2012. for (int i = 0; i < 3; i++) {
  2013. Vector3 ax;
  2014. ax[i] = aabb.position[i] + aabb.size[i];
  2015. handles.push_back(ax);
  2016. }
  2017. if (is_selected()) {
  2018. gizmo_color.a = 0.1;
  2019. Ref<Material> solid_material = create_material("gi_probe_solid_material", gizmo_color);
  2020. add_solid_box(solid_material, aabb.get_size());
  2021. }
  2022. add_unscaled_billboard(icon, 0.05);
  2023. add_handles(handles);
  2024. }
  2025. GIProbeGizmo::GIProbeGizmo(GIProbe *p_probe) {
  2026. probe = p_probe;
  2027. set_spatial_node(p_probe);
  2028. }
  2029. ////////
  2030. void NavigationMeshSpatialGizmo::redraw() {
  2031. Ref<Material> edge_material = create_material("navigation_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/navigation_edge"));
  2032. Ref<Material> edge_material_disabled = create_material("navigation_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/navigation_edge_disabled"));
  2033. Ref<Material> solid_material = create_material("navigation_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/navigation_solid"));
  2034. Ref<Material> solid_material_disabled = create_material("navigation_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/navigation_solid_disabled"));
  2035. clear();
  2036. Ref<NavigationMesh> navmeshie = navmesh->get_navigation_mesh();
  2037. if (navmeshie.is_null())
  2038. return;
  2039. PoolVector<Vector3> vertices = navmeshie->get_vertices();
  2040. PoolVector<Vector3>::Read vr = vertices.read();
  2041. List<Face3> faces;
  2042. for (int i = 0; i < navmeshie->get_polygon_count(); i++) {
  2043. Vector<int> p = navmeshie->get_polygon(i);
  2044. for (int j = 2; j < p.size(); j++) {
  2045. Face3 f;
  2046. f.vertex[0] = vr[p[0]];
  2047. f.vertex[1] = vr[p[j - 1]];
  2048. f.vertex[2] = vr[p[j]];
  2049. faces.push_back(f);
  2050. }
  2051. }
  2052. if (faces.empty())
  2053. return;
  2054. Map<_EdgeKey, bool> edge_map;
  2055. PoolVector<Vector3> tmeshfaces;
  2056. tmeshfaces.resize(faces.size() * 3);
  2057. {
  2058. PoolVector<Vector3>::Write tw = tmeshfaces.write();
  2059. int tidx = 0;
  2060. for (List<Face3>::Element *E = faces.front(); E; E = E->next()) {
  2061. const Face3 &f = E->get();
  2062. for (int j = 0; j < 3; j++) {
  2063. tw[tidx++] = f.vertex[j];
  2064. _EdgeKey ek;
  2065. ek.from = f.vertex[j].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
  2066. ek.to = f.vertex[(j + 1) % 3].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
  2067. if (ek.from < ek.to)
  2068. SWAP(ek.from, ek.to);
  2069. Map<_EdgeKey, bool>::Element *E = edge_map.find(ek);
  2070. if (E) {
  2071. E->get() = false;
  2072. } else {
  2073. edge_map[ek] = true;
  2074. }
  2075. }
  2076. }
  2077. }
  2078. Vector<Vector3> lines;
  2079. for (Map<_EdgeKey, bool>::Element *E = edge_map.front(); E; E = E->next()) {
  2080. if (E->get()) {
  2081. lines.push_back(E->key().from);
  2082. lines.push_back(E->key().to);
  2083. }
  2084. }
  2085. Ref<TriangleMesh> tmesh = memnew(TriangleMesh);
  2086. tmesh->create(tmeshfaces);
  2087. if (lines.size())
  2088. add_lines(lines, navmesh->is_enabled() ? edge_material : edge_material_disabled);
  2089. add_collision_triangles(tmesh);
  2090. Ref<ArrayMesh> m = memnew(ArrayMesh);
  2091. Array a;
  2092. a.resize(Mesh::ARRAY_MAX);
  2093. a[0] = tmeshfaces;
  2094. m->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, a);
  2095. m->surface_set_material(0, navmesh->is_enabled() ? solid_material : solid_material_disabled);
  2096. add_mesh(m);
  2097. add_collision_segments(lines);
  2098. }
  2099. NavigationMeshSpatialGizmo::NavigationMeshSpatialGizmo(NavigationMeshInstance *p_navmesh) {
  2100. set_spatial_node(p_navmesh);
  2101. navmesh = p_navmesh;
  2102. }
  2103. //////
  2104. ///
  2105. ///
  2106. void PinJointSpatialGizmo::redraw() {
  2107. clear();
  2108. Vector<Vector3> cursor_points;
  2109. float cs = 0.25;
  2110. cursor_points.push_back(Vector3(+cs, 0, 0));
  2111. cursor_points.push_back(Vector3(-cs, 0, 0));
  2112. cursor_points.push_back(Vector3(0, +cs, 0));
  2113. cursor_points.push_back(Vector3(0, -cs, 0));
  2114. cursor_points.push_back(Vector3(0, 0, +cs));
  2115. cursor_points.push_back(Vector3(0, 0, -cs));
  2116. add_collision_segments(cursor_points);
  2117. Ref<Material> material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint"));
  2118. add_lines(cursor_points, material);
  2119. }
  2120. PinJointSpatialGizmo::PinJointSpatialGizmo(PinJoint *p_p3d) {
  2121. p3d = p_p3d;
  2122. set_spatial_node(p3d);
  2123. }
  2124. ////
  2125. void HingeJointSpatialGizmo::redraw() {
  2126. clear();
  2127. Vector<Vector3> cursor_points;
  2128. float cs = 0.25;
  2129. /*cursor_points.push_back(Vector3(+cs,0,0));
  2130. cursor_points.push_back(Vector3(-cs,0,0));
  2131. cursor_points.push_back(Vector3(0,+cs,0));
  2132. cursor_points.push_back(Vector3(0,-cs,0));*/
  2133. cursor_points.push_back(Vector3(0, 0, +cs * 2));
  2134. cursor_points.push_back(Vector3(0, 0, -cs * 2));
  2135. float ll = p3d->get_param(HingeJoint::PARAM_LIMIT_LOWER);
  2136. float ul = p3d->get_param(HingeJoint::PARAM_LIMIT_UPPER);
  2137. if (p3d->get_flag(HingeJoint::FLAG_USE_LIMIT) && ll < ul) {
  2138. const int points = 32;
  2139. for (int i = 0; i < points; i++) {
  2140. float s = ll + i * (ul - ll) / points;
  2141. float n = ll + (i + 1) * (ul - ll) / points;
  2142. Vector3 from = Vector3(-Math::sin(s), Math::cos(s), 0) * cs;
  2143. Vector3 to = Vector3(-Math::sin(n), Math::cos(n), 0) * cs;
  2144. if (i == points - 1) {
  2145. cursor_points.push_back(to);
  2146. cursor_points.push_back(Vector3());
  2147. }
  2148. if (i == 0) {
  2149. cursor_points.push_back(from);
  2150. cursor_points.push_back(Vector3());
  2151. }
  2152. cursor_points.push_back(from);
  2153. cursor_points.push_back(to);
  2154. }
  2155. cursor_points.push_back(Vector3(0, cs * 1.5, 0));
  2156. cursor_points.push_back(Vector3());
  2157. } else {
  2158. const int points = 32;
  2159. for (int i = 0; i < points; i++) {
  2160. float s = ll + i * (Math_PI * 2.0) / points;
  2161. float n = ll + (i + 1) * (Math_PI * 2.0) / points;
  2162. Vector3 from = Vector3(-Math::sin(s), Math::cos(s), 0) * cs;
  2163. Vector3 to = Vector3(-Math::sin(n), Math::cos(n), 0) * cs;
  2164. cursor_points.push_back(from);
  2165. cursor_points.push_back(to);
  2166. }
  2167. }
  2168. Ref<Material> material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint"));
  2169. add_collision_segments(cursor_points);
  2170. add_lines(cursor_points, material);
  2171. }
  2172. HingeJointSpatialGizmo::HingeJointSpatialGizmo(HingeJoint *p_p3d) {
  2173. p3d = p_p3d;
  2174. set_spatial_node(p3d);
  2175. }
  2176. ///////
  2177. ///
  2178. ////
  2179. void SliderJointSpatialGizmo::redraw() {
  2180. clear();
  2181. Vector<Vector3> cursor_points;
  2182. float cs = 0.25;
  2183. /*cursor_points.push_back(Vector3(+cs,0,0));
  2184. cursor_points.push_back(Vector3(-cs,0,0));
  2185. cursor_points.push_back(Vector3(0,+cs,0));
  2186. cursor_points.push_back(Vector3(0,-cs,0));*/
  2187. cursor_points.push_back(Vector3(0, 0, +cs * 2));
  2188. cursor_points.push_back(Vector3(0, 0, -cs * 2));
  2189. float ll = p3d->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_LOWER);
  2190. float ul = p3d->get_param(SliderJoint::PARAM_ANGULAR_LIMIT_UPPER);
  2191. float lll = -p3d->get_param(SliderJoint::PARAM_LINEAR_LIMIT_LOWER);
  2192. float lul = -p3d->get_param(SliderJoint::PARAM_LINEAR_LIMIT_UPPER);
  2193. if (lll > lul) {
  2194. cursor_points.push_back(Vector3(lul, 0, 0));
  2195. cursor_points.push_back(Vector3(lll, 0, 0));
  2196. cursor_points.push_back(Vector3(lul, -cs, -cs));
  2197. cursor_points.push_back(Vector3(lul, -cs, cs));
  2198. cursor_points.push_back(Vector3(lul, -cs, cs));
  2199. cursor_points.push_back(Vector3(lul, cs, cs));
  2200. cursor_points.push_back(Vector3(lul, cs, cs));
  2201. cursor_points.push_back(Vector3(lul, cs, -cs));
  2202. cursor_points.push_back(Vector3(lul, cs, -cs));
  2203. cursor_points.push_back(Vector3(lul, -cs, -cs));
  2204. cursor_points.push_back(Vector3(lll, -cs, -cs));
  2205. cursor_points.push_back(Vector3(lll, -cs, cs));
  2206. cursor_points.push_back(Vector3(lll, -cs, cs));
  2207. cursor_points.push_back(Vector3(lll, cs, cs));
  2208. cursor_points.push_back(Vector3(lll, cs, cs));
  2209. cursor_points.push_back(Vector3(lll, cs, -cs));
  2210. cursor_points.push_back(Vector3(lll, cs, -cs));
  2211. cursor_points.push_back(Vector3(lll, -cs, -cs));
  2212. } else {
  2213. cursor_points.push_back(Vector3(+cs * 2, 0, 0));
  2214. cursor_points.push_back(Vector3(-cs * 2, 0, 0));
  2215. }
  2216. if (ll < ul) {
  2217. const int points = 32;
  2218. for (int i = 0; i < points; i++) {
  2219. float s = ll + i * (ul - ll) / points;
  2220. float n = ll + (i + 1) * (ul - ll) / points;
  2221. Vector3 from = Vector3(0, Math::cos(s), -Math::sin(s)) * cs;
  2222. Vector3 to = Vector3(0, Math::cos(n), -Math::sin(n)) * cs;
  2223. if (i == points - 1) {
  2224. cursor_points.push_back(to);
  2225. cursor_points.push_back(Vector3());
  2226. }
  2227. if (i == 0) {
  2228. cursor_points.push_back(from);
  2229. cursor_points.push_back(Vector3());
  2230. }
  2231. cursor_points.push_back(from);
  2232. cursor_points.push_back(to);
  2233. }
  2234. cursor_points.push_back(Vector3(0, cs * 1.5, 0));
  2235. cursor_points.push_back(Vector3());
  2236. } else {
  2237. const int points = 32;
  2238. for (int i = 0; i < points; i++) {
  2239. float s = ll + i * (Math_PI * 2.0) / points;
  2240. float n = ll + (i + 1) * (Math_PI * 2.0) / points;
  2241. Vector3 from = Vector3(0, Math::cos(s), -Math::sin(s)) * cs;
  2242. Vector3 to = Vector3(0, Math::cos(n), -Math::sin(n)) * cs;
  2243. cursor_points.push_back(from);
  2244. cursor_points.push_back(to);
  2245. }
  2246. }
  2247. Ref<Material> material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint"));
  2248. add_collision_segments(cursor_points);
  2249. add_lines(cursor_points, material);
  2250. }
  2251. SliderJointSpatialGizmo::SliderJointSpatialGizmo(SliderJoint *p_p3d) {
  2252. p3d = p_p3d;
  2253. set_spatial_node(p3d);
  2254. }
  2255. ///////
  2256. ///
  2257. ////
  2258. void ConeTwistJointSpatialGizmo::redraw() {
  2259. clear();
  2260. Vector<Vector3> points;
  2261. float r = 1.0;
  2262. float w = r * Math::sin(p3d->get_param(ConeTwistJoint::PARAM_SWING_SPAN));
  2263. float d = r * Math::cos(p3d->get_param(ConeTwistJoint::PARAM_SWING_SPAN));
  2264. //swing
  2265. for (int i = 0; i < 360; i += 10) {
  2266. float ra = Math::deg2rad((float)i);
  2267. float rb = Math::deg2rad((float)i + 10);
  2268. Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w;
  2269. Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w;
  2270. /*points.push_back(Vector3(a.x,0,a.y));
  2271. points.push_back(Vector3(b.x,0,b.y));
  2272. points.push_back(Vector3(0,a.x,a.y));
  2273. points.push_back(Vector3(0,b.x,b.y));*/
  2274. points.push_back(Vector3(d, a.x, a.y));
  2275. points.push_back(Vector3(d, b.x, b.y));
  2276. if (i % 90 == 0) {
  2277. points.push_back(Vector3(d, a.x, a.y));
  2278. points.push_back(Vector3());
  2279. }
  2280. }
  2281. points.push_back(Vector3());
  2282. points.push_back(Vector3(1, 0, 0));
  2283. //twist
  2284. /*
  2285. */
  2286. float ts = Math::rad2deg(p3d->get_param(ConeTwistJoint::PARAM_TWIST_SPAN));
  2287. ts = MIN(ts, 720);
  2288. for (int i = 0; i < int(ts); i += 5) {
  2289. float ra = Math::deg2rad((float)i);
  2290. float rb = Math::deg2rad((float)i + 5);
  2291. float c = i / 720.0;
  2292. float cn = (i + 5) / 720.0;
  2293. Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w * c;
  2294. Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w * cn;
  2295. /*points.push_back(Vector3(a.x,0,a.y));
  2296. points.push_back(Vector3(b.x,0,b.y));
  2297. points.push_back(Vector3(0,a.x,a.y));
  2298. points.push_back(Vector3(0,b.x,b.y));*/
  2299. points.push_back(Vector3(c, a.x, a.y));
  2300. points.push_back(Vector3(cn, b.x, b.y));
  2301. }
  2302. Ref<Material> material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint"));
  2303. add_collision_segments(points);
  2304. add_lines(points, material);
  2305. }
  2306. ConeTwistJointSpatialGizmo::ConeTwistJointSpatialGizmo(ConeTwistJoint *p_p3d) {
  2307. p3d = p_p3d;
  2308. set_spatial_node(p3d);
  2309. }
  2310. ////////
  2311. /// \brief SpatialEditorGizmos::singleton
  2312. ///
  2313. ///////
  2314. ///
  2315. ////
  2316. void Generic6DOFJointSpatialGizmo::redraw() {
  2317. clear();
  2318. Vector<Vector3> cursor_points;
  2319. float cs = 0.25;
  2320. for (int ax = 0; ax < 3; ax++) {
  2321. /*cursor_points.push_back(Vector3(+cs,0,0));
  2322. cursor_points.push_back(Vector3(-cs,0,0));
  2323. cursor_points.push_back(Vector3(0,+cs,0));
  2324. cursor_points.push_back(Vector3(0,-cs,0));
  2325. cursor_points.push_back(Vector3(0,0,+cs*2));
  2326. cursor_points.push_back(Vector3(0,0,-cs*2)); */
  2327. float ll;
  2328. float ul;
  2329. float lll;
  2330. float lul;
  2331. int a1, a2, a3;
  2332. bool enable_ang;
  2333. bool enable_lin;
  2334. switch (ax) {
  2335. case 0:
  2336. ll = p3d->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT);
  2337. ul = p3d->get_param_x(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT);
  2338. lll = -p3d->get_param_x(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT);
  2339. lul = -p3d->get_param_x(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT);
  2340. enable_ang = p3d->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT);
  2341. enable_lin = p3d->get_flag_x(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT);
  2342. a1 = 0;
  2343. a2 = 1;
  2344. a3 = 2;
  2345. break;
  2346. case 1:
  2347. ll = p3d->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT);
  2348. ul = p3d->get_param_y(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT);
  2349. lll = -p3d->get_param_y(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT);
  2350. lul = -p3d->get_param_y(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT);
  2351. enable_ang = p3d->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT);
  2352. enable_lin = p3d->get_flag_y(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT);
  2353. a1 = 2;
  2354. a2 = 0;
  2355. a3 = 1;
  2356. break;
  2357. case 2:
  2358. ll = p3d->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_LOWER_LIMIT);
  2359. ul = p3d->get_param_z(Generic6DOFJoint::PARAM_ANGULAR_UPPER_LIMIT);
  2360. lll = -p3d->get_param_z(Generic6DOFJoint::PARAM_LINEAR_LOWER_LIMIT);
  2361. lul = -p3d->get_param_z(Generic6DOFJoint::PARAM_LINEAR_UPPER_LIMIT);
  2362. enable_ang = p3d->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_ANGULAR_LIMIT);
  2363. enable_lin = p3d->get_flag_z(Generic6DOFJoint::FLAG_ENABLE_LINEAR_LIMIT);
  2364. a1 = 1;
  2365. a2 = 2;
  2366. a3 = 0;
  2367. break;
  2368. }
  2369. #define ADD_VTX(x, y, z) \
  2370. { \
  2371. Vector3 v; \
  2372. v[a1] = (x); \
  2373. v[a2] = (y); \
  2374. v[a3] = (z); \
  2375. cursor_points.push_back(v); \
  2376. }
  2377. #define SET_VTX(what, x, y, z) \
  2378. { \
  2379. Vector3 v; \
  2380. v[a1] = (x); \
  2381. v[a2] = (y); \
  2382. v[a3] = (z); \
  2383. what = v; \
  2384. }
  2385. if (enable_lin && lll >= lul) {
  2386. ADD_VTX(lul, 0, 0);
  2387. ADD_VTX(lll, 0, 0);
  2388. ADD_VTX(lul, -cs, -cs);
  2389. ADD_VTX(lul, -cs, cs);
  2390. ADD_VTX(lul, -cs, cs);
  2391. ADD_VTX(lul, cs, cs);
  2392. ADD_VTX(lul, cs, cs);
  2393. ADD_VTX(lul, cs, -cs);
  2394. ADD_VTX(lul, cs, -cs);
  2395. ADD_VTX(lul, -cs, -cs);
  2396. ADD_VTX(lll, -cs, -cs);
  2397. ADD_VTX(lll, -cs, cs);
  2398. ADD_VTX(lll, -cs, cs);
  2399. ADD_VTX(lll, cs, cs);
  2400. ADD_VTX(lll, cs, cs);
  2401. ADD_VTX(lll, cs, -cs);
  2402. ADD_VTX(lll, cs, -cs);
  2403. ADD_VTX(lll, -cs, -cs);
  2404. } else {
  2405. ADD_VTX(+cs * 2, 0, 0);
  2406. ADD_VTX(-cs * 2, 0, 0);
  2407. }
  2408. if (enable_ang && ll <= ul) {
  2409. const int points = 32;
  2410. for (int i = 0; i < points; i++) {
  2411. float s = ll + i * (ul - ll) / points;
  2412. float n = ll + (i + 1) * (ul - ll) / points;
  2413. Vector3 from;
  2414. SET_VTX(from, 0, Math::cos(s), -Math::sin(s));
  2415. from *= cs;
  2416. Vector3 to;
  2417. SET_VTX(to, 0, Math::cos(n), -Math::sin(n));
  2418. to *= cs;
  2419. if (i == points - 1) {
  2420. cursor_points.push_back(to);
  2421. cursor_points.push_back(Vector3());
  2422. }
  2423. if (i == 0) {
  2424. cursor_points.push_back(from);
  2425. cursor_points.push_back(Vector3());
  2426. }
  2427. cursor_points.push_back(from);
  2428. cursor_points.push_back(to);
  2429. }
  2430. ADD_VTX(0, cs * 1.5, 0);
  2431. cursor_points.push_back(Vector3());
  2432. } else {
  2433. const int points = 32;
  2434. for (int i = 0; i < points; i++) {
  2435. float s = ll + i * (Math_PI * 2.0) / points;
  2436. float n = ll + (i + 1) * (Math_PI * 2.0) / points;
  2437. //Vector3 from=Vector3(0,Math::cos(s),-Math::sin(s) )*cs;
  2438. //Vector3 to=Vector3( 0,Math::cos(n),-Math::sin(n) )*cs;
  2439. Vector3 from;
  2440. SET_VTX(from, 0, Math::cos(s), -Math::sin(s));
  2441. from *= cs;
  2442. Vector3 to;
  2443. SET_VTX(to, 0, Math::cos(n), -Math::sin(n));
  2444. to *= cs;
  2445. cursor_points.push_back(from);
  2446. cursor_points.push_back(to);
  2447. }
  2448. }
  2449. }
  2450. #undef ADD_VTX
  2451. #undef SET_VTX
  2452. Ref<Material> material = create_material("joint_material", EDITOR_GET("editors/3d_gizmos/gizmo_colors/joint"));
  2453. add_collision_segments(cursor_points);
  2454. add_lines(cursor_points, material);
  2455. }
  2456. Generic6DOFJointSpatialGizmo::Generic6DOFJointSpatialGizmo(Generic6DOFJoint *p_p3d) {
  2457. p3d = p_p3d;
  2458. set_spatial_node(p3d);
  2459. }
  2460. ///////
  2461. ///
  2462. ////
  2463. SpatialEditorGizmos *SpatialEditorGizmos::singleton = NULL;
  2464. Ref<SpatialEditorGizmo> SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) {
  2465. if (Object::cast_to<Light>(p_spatial)) {
  2466. Ref<LightSpatialGizmo> lsg = memnew(LightSpatialGizmo(Object::cast_to<Light>(p_spatial)));
  2467. return lsg;
  2468. }
  2469. if (Object::cast_to<Camera>(p_spatial)) {
  2470. Ref<CameraSpatialGizmo> lsg = memnew(CameraSpatialGizmo(Object::cast_to<Camera>(p_spatial)));
  2471. return lsg;
  2472. }
  2473. if (Object::cast_to<Skeleton>(p_spatial)) {
  2474. Ref<SkeletonSpatialGizmo> lsg = memnew(SkeletonSpatialGizmo(Object::cast_to<Skeleton>(p_spatial)));
  2475. return lsg;
  2476. }
  2477. if (Object::cast_to<Position3D>(p_spatial)) {
  2478. Ref<Position3DSpatialGizmo> lsg = memnew(Position3DSpatialGizmo(Object::cast_to<Position3D>(p_spatial)));
  2479. return lsg;
  2480. }
  2481. if (Object::cast_to<MeshInstance>(p_spatial)) {
  2482. Ref<MeshInstanceSpatialGizmo> misg = memnew(MeshInstanceSpatialGizmo(Object::cast_to<MeshInstance>(p_spatial)));
  2483. return misg;
  2484. }
  2485. /*if (Object::cast_to<Room>(p_spatial)) {
  2486. Ref<RoomSpatialGizmo> misg = memnew(RoomSpatialGizmo(Object::cast_to<Room>(p_spatial)));
  2487. return misg;
  2488. }*/
  2489. if (Object::cast_to<NavigationMeshInstance>(p_spatial)) {
  2490. Ref<NavigationMeshSpatialGizmo> misg = memnew(NavigationMeshSpatialGizmo(Object::cast_to<NavigationMeshInstance>(p_spatial)));
  2491. return misg;
  2492. }
  2493. if (Object::cast_to<RayCast>(p_spatial)) {
  2494. Ref<RayCastSpatialGizmo> misg = memnew(RayCastSpatialGizmo(Object::cast_to<RayCast>(p_spatial)));
  2495. return misg;
  2496. }
  2497. /*
  2498. if (Object::cast_to<Portal>(p_spatial)) {
  2499. Ref<PortalSpatialGizmo> misg = memnew(PortalSpatialGizmo(Object::cast_to<Portal>(p_spatial)));
  2500. return misg;
  2501. }
  2502. */
  2503. if (Object::cast_to<CollisionShape>(p_spatial)) {
  2504. Ref<CollisionShapeSpatialGizmo> misg = memnew(CollisionShapeSpatialGizmo(Object::cast_to<CollisionShape>(p_spatial)));
  2505. return misg;
  2506. }
  2507. if (Object::cast_to<VisibilityNotifier>(p_spatial)) {
  2508. Ref<VisibilityNotifierGizmo> misg = memnew(VisibilityNotifierGizmo(Object::cast_to<VisibilityNotifier>(p_spatial)));
  2509. return misg;
  2510. }
  2511. if (Object::cast_to<Particles>(p_spatial)) {
  2512. Ref<ParticlesGizmo> misg = memnew(ParticlesGizmo(Object::cast_to<Particles>(p_spatial)));
  2513. return misg;
  2514. }
  2515. if (Object::cast_to<ReflectionProbe>(p_spatial)) {
  2516. Ref<ReflectionProbeGizmo> misg = memnew(ReflectionProbeGizmo(Object::cast_to<ReflectionProbe>(p_spatial)));
  2517. return misg;
  2518. }
  2519. if (Object::cast_to<GIProbe>(p_spatial)) {
  2520. Ref<GIProbeGizmo> misg = memnew(GIProbeGizmo(Object::cast_to<GIProbe>(p_spatial)));
  2521. return misg;
  2522. }
  2523. if (Object::cast_to<VehicleWheel>(p_spatial)) {
  2524. Ref<VehicleWheelSpatialGizmo> misg = memnew(VehicleWheelSpatialGizmo(Object::cast_to<VehicleWheel>(p_spatial)));
  2525. return misg;
  2526. }
  2527. if (Object::cast_to<PinJoint>(p_spatial)) {
  2528. Ref<PinJointSpatialGizmo> misg = memnew(PinJointSpatialGizmo(Object::cast_to<PinJoint>(p_spatial)));
  2529. return misg;
  2530. }
  2531. if (Object::cast_to<HingeJoint>(p_spatial)) {
  2532. Ref<HingeJointSpatialGizmo> misg = memnew(HingeJointSpatialGizmo(Object::cast_to<HingeJoint>(p_spatial)));
  2533. return misg;
  2534. }
  2535. if (Object::cast_to<SliderJoint>(p_spatial)) {
  2536. Ref<SliderJointSpatialGizmo> misg = memnew(SliderJointSpatialGizmo(Object::cast_to<SliderJoint>(p_spatial)));
  2537. return misg;
  2538. }
  2539. if (Object::cast_to<ConeTwistJoint>(p_spatial)) {
  2540. Ref<ConeTwistJointSpatialGizmo> misg = memnew(ConeTwistJointSpatialGizmo(Object::cast_to<ConeTwistJoint>(p_spatial)));
  2541. return misg;
  2542. }
  2543. if (Object::cast_to<Generic6DOFJoint>(p_spatial)) {
  2544. Ref<Generic6DOFJointSpatialGizmo> misg = memnew(Generic6DOFJointSpatialGizmo(Object::cast_to<Generic6DOFJoint>(p_spatial)));
  2545. return misg;
  2546. }
  2547. if (Object::cast_to<CollisionPolygon>(p_spatial)) {
  2548. Ref<CollisionPolygonSpatialGizmo> misg = memnew(CollisionPolygonSpatialGizmo(Object::cast_to<CollisionPolygon>(p_spatial)));
  2549. return misg;
  2550. }
  2551. if (Object::cast_to<AudioStreamPlayer3D>(p_spatial)) {
  2552. Ref<AudioStreamPlayer3DSpatialGizmo> misg = memnew(AudioStreamPlayer3DSpatialGizmo(Object::cast_to<AudioStreamPlayer3D>(p_spatial)));
  2553. return misg;
  2554. }
  2555. return Ref<SpatialEditorGizmo>();
  2556. }
  2557. SpatialEditorGizmos::SpatialEditorGizmos() {
  2558. singleton = this;
  2559. handle_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
  2560. handle_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  2561. handle_material->set_on_top_of_alpha();
  2562. handle_material->set_albedo(Color(0.8, 0.8, 0.8));
  2563. handle_material_billboard = handle_material->duplicate();
  2564. handle_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
  2565. handle2_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
  2566. handle2_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  2567. handle2_material->set_flag(SpatialMaterial::FLAG_USE_POINT_SIZE, true);
  2568. handle_t = SpatialEditor::get_singleton()->get_icon("Editor3DHandle", "EditorIcons");
  2569. handle2_material->set_point_size(handle_t->get_width());
  2570. handle2_material->set_texture(SpatialMaterial::TEXTURE_ALBEDO, handle_t);
  2571. handle2_material->set_albedo(Color(1, 1, 1));
  2572. handle2_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  2573. handle2_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
  2574. handle2_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
  2575. handle2_material->set_on_top_of_alpha();
  2576. handle2_material_billboard = handle2_material->duplicate();
  2577. handle2_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
  2578. handle2_material_billboard->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
  2579. handle2_material_billboard->set_on_top_of_alpha();
  2580. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/light", Color(1, 1, 0.2));
  2581. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/stream_player_3d", Color(0.4, 0.8, 1));
  2582. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/camera", Color(0.8, 0.4, 0.8));
  2583. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/skeleton", Color(1, 0.8, 0.4));
  2584. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/visibility_notifier", Color(0.8, 0.5, 0.7));
  2585. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/particles", Color(0.8, 0.7, 0.4));
  2586. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/reflection_probe", Color(0.6, 1, 0.5));
  2587. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/gi_probe", Color(0.5, 1, 0.6));
  2588. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
  2589. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1));
  2590. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_edge", Color(0.5, 1, 1));
  2591. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_edge_disabled", Color(0.7, 0.7, 0.7));
  2592. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_solid", Color(0.5, 1, 1, 0.4));
  2593. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/navigation_solid_disabled", Color(0.7, 0.7, 0.7, 0.4));
  2594. EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.5));
  2595. #if 0
  2596. light_material = create_line_material(Color(1, 1, 0.2));
  2597. light_material_omni = create_line_material(Color(1, 1, 0.2));
  2598. light_material_omni->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
  2599. light_material_omni_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
  2600. light_material_omni_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  2601. light_material_omni_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
  2602. light_material_omni_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
  2603. light_material_omni_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  2604. light_material_omni_icon->set_albedo(Color(1, 1, 1, 0.9));
  2605. light_material_omni_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoLight", "EditorIcons"));
  2606. light_material_omni_icon->set_flag(SpatialMaterial::FLAG_FIXED_SIZE, true);
  2607. light_material_omni_icon->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
  2608. light_material_directional_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
  2609. light_material_directional_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  2610. light_material_directional_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
  2611. light_material_directional_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
  2612. light_material_directional_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  2613. light_material_directional_icon->set_albedo(Color(1, 1, 1, 0.9));
  2614. light_material_directional_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight", "EditorIcons"));
  2615. light_material_directional_icon->set_billboard_mode(SpatialMaterial::BILLBOARD_ENABLED);
  2616. light_material_directional_icon->set_depth_scale(1);
  2617. camera_material = create_line_material(Color(1.0, 0.5, 1.0));
  2618. navmesh_edge_material = create_line_material(Color(0.1, 0.8, 1.0));
  2619. navmesh_solid_material = create_solid_material(Color(0.1, 0.8, 1.0, 0.4));
  2620. navmesh_edge_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, false);
  2621. navmesh_edge_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, false);
  2622. navmesh_solid_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
  2623. navmesh_edge_material_disabled = create_line_material(Color(1.0, 0.8, 0.1));
  2624. navmesh_solid_material_disabled = create_solid_material(Color(1.0, 0.8, 0.1, 0.4));
  2625. navmesh_edge_material_disabled->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, false);
  2626. navmesh_edge_material_disabled->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, false);
  2627. navmesh_solid_material_disabled->set_cull_mode(SpatialMaterial::CULL_DISABLED);
  2628. skeleton_material = create_line_material(Color(0.6, 1.0, 0.3));
  2629. skeleton_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
  2630. skeleton_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  2631. skeleton_material->set_on_top_of_alpha();
  2632. skeleton_material->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
  2633. //position 3D Shared mesh
  2634. pos3d_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
  2635. {
  2636. PoolVector<Vector3> cursor_points;
  2637. PoolVector<Color> cursor_colors;
  2638. float cs = 0.25;
  2639. cursor_points.push_back(Vector3(+cs, 0, 0));
  2640. cursor_points.push_back(Vector3(-cs, 0, 0));
  2641. cursor_points.push_back(Vector3(0, +cs, 0));
  2642. cursor_points.push_back(Vector3(0, -cs, 0));
  2643. cursor_points.push_back(Vector3(0, 0, +cs));
  2644. cursor_points.push_back(Vector3(0, 0, -cs));
  2645. cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7));
  2646. cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7));
  2647. cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7));
  2648. cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7));
  2649. cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7));
  2650. cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7));
  2651. Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
  2652. mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  2653. mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
  2654. mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
  2655. mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  2656. mat->set_line_width(3);
  2657. Array d;
  2658. d.resize(VS::ARRAY_MAX);
  2659. d[Mesh::ARRAY_VERTEX] = cursor_points;
  2660. d[Mesh::ARRAY_COLOR] = cursor_colors;
  2661. pos3d_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d);
  2662. pos3d_mesh->surface_set_material(0, mat);
  2663. }
  2664. listener_line_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
  2665. {
  2666. PoolVector<Vector3> cursor_points;
  2667. PoolVector<Color> cursor_colors;
  2668. cursor_points.push_back(Vector3(0, 0, 0));
  2669. cursor_points.push_back(Vector3(0, 0, -1.0));
  2670. cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7));
  2671. cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7));
  2672. Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
  2673. mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  2674. mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
  2675. mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
  2676. mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  2677. mat->set_line_width(3);
  2678. Array d;
  2679. d.resize(VS::ARRAY_MAX);
  2680. d[Mesh::ARRAY_VERTEX] = cursor_points;
  2681. d[Mesh::ARRAY_COLOR] = cursor_colors;
  2682. listener_line_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d);
  2683. listener_line_mesh->surface_set_material(0, mat);
  2684. }
  2685. room_material = create_line_material(Color(1.0, 0.6, 0.9));
  2686. portal_material = create_line_material(Color(1.0, 0.8, 0.6));
  2687. raycast_material = create_line_material(Color(1.0, 0.8, 0.6));
  2688. car_wheel_material = create_line_material(Color(0.6, 0.8, 1.0));
  2689. visibility_notifier_material = create_line_material(Color(1.0, 0.5, 1.0));
  2690. particles_material = create_line_material(Color(1.0, 1.0, 0.5));
  2691. reflection_probe_material = create_line_material(Color(0.5, 1.0, 0.7));
  2692. reflection_probe_material_internal = create_line_material(Color(0.3, 0.8, 0.5, 0.15));
  2693. gi_probe_material = create_line_material(Color(0.7, 1.0, 0.5));
  2694. gi_probe_material_internal = create_line_material(Color(0.5, 0.8, 0.3, 0.1));
  2695. joint_material = create_line_material(Color(0.6, 0.8, 1.0));
  2696. stream_player_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
  2697. stream_player_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  2698. stream_player_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
  2699. stream_player_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
  2700. stream_player_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  2701. stream_player_icon->set_albedo(Color(1, 1, 1, 0.9));
  2702. stream_player_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoSpatialStreamPlayer", "EditorIcons"));
  2703. visibility_notifier_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
  2704. visibility_notifier_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  2705. visibility_notifier_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
  2706. visibility_notifier_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
  2707. visibility_notifier_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  2708. visibility_notifier_icon->set_albedo(Color(1, 1, 1, 0.9));
  2709. visibility_notifier_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("Visible", "EditorIcons"));
  2710. listener_icon = Ref<SpatialMaterial>(memnew(SpatialMaterial));
  2711. listener_icon->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  2712. listener_icon->set_cull_mode(SpatialMaterial::CULL_DISABLED);
  2713. listener_icon->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_DISABLED);
  2714. listener_icon->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  2715. listener_icon->set_albedo(Color(1, 1, 1, 0.9));
  2716. listener_icon->set_texture(SpatialMaterial::TEXTURE_ALBEDO, SpatialEditor::get_singleton()->get_icon("GizmoListener", "EditorIcons"));
  2717. {
  2718. PoolVector<Vector3> vertices;
  2719. #undef ADD_VTX
  2720. #define ADD_VTX(m_idx) \
  2721. vertices.push_back(face_points[m_idx]);
  2722. for (int i = 0; i < 6; i++) {
  2723. Vector3 face_points[4];
  2724. for (int j = 0; j < 4; j++) {
  2725. float v[3];
  2726. v[0] = 1.0;
  2727. v[1] = 1 - 2 * ((j >> 1) & 1);
  2728. v[2] = v[1] * (1 - 2 * (j & 1));
  2729. for (int k = 0; k < 3; k++) {
  2730. if (i < 3)
  2731. face_points[j][(i + k) % 3] = v[k] * (i >= 3 ? -1 : 1);
  2732. else
  2733. face_points[3 - j][(i + k) % 3] = v[k] * (i >= 3 ? -1 : 1);
  2734. }
  2735. }
  2736. //tri 1
  2737. ADD_VTX(0);
  2738. ADD_VTX(1);
  2739. ADD_VTX(2);
  2740. //tri 2
  2741. ADD_VTX(2);
  2742. ADD_VTX(3);
  2743. ADD_VTX(0);
  2744. }
  2745. test_cube_tm = Ref<TriangleMesh>(memnew(TriangleMesh));
  2746. test_cube_tm->create(vertices);
  2747. }
  2748. shape_material = create_line_material(Color(0.2, 1, 1.0));
  2749. #endif
  2750. pos3d_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
  2751. {
  2752. PoolVector<Vector3> cursor_points;
  2753. PoolVector<Color> cursor_colors;
  2754. float cs = 0.25;
  2755. cursor_points.push_back(Vector3(+cs, 0, 0));
  2756. cursor_points.push_back(Vector3(-cs, 0, 0));
  2757. cursor_points.push_back(Vector3(0, +cs, 0));
  2758. cursor_points.push_back(Vector3(0, -cs, 0));
  2759. cursor_points.push_back(Vector3(0, 0, +cs));
  2760. cursor_points.push_back(Vector3(0, 0, -cs));
  2761. cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7));
  2762. cursor_colors.push_back(Color(1, 0.5, 0.5, 0.7));
  2763. cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7));
  2764. cursor_colors.push_back(Color(0.5, 1, 0.5, 0.7));
  2765. cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7));
  2766. cursor_colors.push_back(Color(0.5, 0.5, 1, 0.7));
  2767. Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
  2768. mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  2769. mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
  2770. mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
  2771. mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  2772. mat->set_line_width(3);
  2773. Array d;
  2774. d.resize(VS::ARRAY_MAX);
  2775. d[Mesh::ARRAY_VERTEX] = cursor_points;
  2776. d[Mesh::ARRAY_COLOR] = cursor_colors;
  2777. pos3d_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d);
  2778. pos3d_mesh->surface_set_material(0, mat);
  2779. }
  2780. listener_line_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
  2781. {
  2782. PoolVector<Vector3> cursor_points;
  2783. PoolVector<Color> cursor_colors;
  2784. cursor_points.push_back(Vector3(0, 0, 0));
  2785. cursor_points.push_back(Vector3(0, 0, -1.0));
  2786. cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7));
  2787. cursor_colors.push_back(Color(0.5, 0.5, 0.5, 0.7));
  2788. Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
  2789. mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
  2790. mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
  2791. mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
  2792. mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
  2793. mat->set_line_width(3);
  2794. Array d;
  2795. d.resize(VS::ARRAY_MAX);
  2796. d[Mesh::ARRAY_VERTEX] = cursor_points;
  2797. d[Mesh::ARRAY_COLOR] = cursor_colors;
  2798. listener_line_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, d);
  2799. listener_line_mesh->surface_set_material(0, mat);
  2800. }
  2801. }