EditorViewDebugIcons.as 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. // Editor debug icons
  2. // to add new std debug icons just add IconType, IconsTypesMaterials and ComponentTypes items
  3. enum IconsTypes
  4. {
  5. ICON_POINT_LIGHT = 0,
  6. ICON_SPOT_LIGHT,
  7. ICON_DIRECTIONAL_LIGHT,
  8. ICON_CAMERA,
  9. ICON_SOUND_SOURCE,
  10. ICON_SOUND_SOURCE_3D,
  11. ICON_SOUND_LISTENERS,
  12. ICON_ZONE,
  13. ICON_SPLINE_PATH,
  14. ICON_TRIGGER,
  15. ICON_CUSTOM_GEOMETRY,
  16. ICON_PARTICLE_EMITTER,
  17. ICON_COUNT
  18. }
  19. enum IconsColorType
  20. {
  21. ICON_COLOR_DEFAULT = 0,
  22. ICON_COLOR_SPLINE_PATH_BEGIN,
  23. ICON_COLOR_SPLINE_PATH_END
  24. }
  25. Array<Color> debugIconsColors = { Color(1,1,1) , Color(1,1,0), Color(0,1,0) };
  26. Array<String> IconsTypesMaterials = {"DebugIconPointLight.xml",
  27. "DebugIconSpotLight.xml",
  28. "DebugIconLight.xml",
  29. "DebugIconCamera.xml",
  30. "DebugIconSoundSource.xml",
  31. "DebugIconSoundSource.xml",
  32. "DebugIconSoundListener.xml",
  33. "DebugIconZone.xml",
  34. "DebugIconSplinePathPoint.xml",
  35. "DebugIconCollisionTrigger.xml",
  36. "DebugIconCustomGeometry.xml",
  37. "DebugIconParticleEmitter.xml"};
  38. Array<String> ComponentTypes = {"Light",
  39. "Light",
  40. "Light",
  41. "Camera",
  42. "SoundSource",
  43. "SoundSource3D",
  44. "SoundListener",
  45. "Zone",
  46. "SplinePath",
  47. "RigidBody",
  48. "CustomGeometry",
  49. "ParticleEmitter"};
  50. Array<BillboardSet@> debugIconsSet(ICON_COUNT);
  51. Node@ debugIconsNode = null;
  52. int stepDebugIconsUpdate = 100; //ms
  53. int timeToNextDebugIconsUpdate = 0;
  54. int stepDebugIconsUpdateSplinePath = 1000; //ms
  55. int timeToNextDebugIconsUpdateSplinePath = 0;
  56. const int splinePathResolution = 16;
  57. const float splineStep = 1.0f / splinePathResolution;
  58. bool debugIconsShow = true;
  59. Vector2 debugIconsSize = Vector2(0.015, 0.015);
  60. Vector2 debugIconsSizeSmall = debugIconsSize / 1.5;
  61. Vector2 debugIconsSizeBig = debugIconsSize * 1.5;
  62. Vector2 debugIconsMaxSize = debugIconsSize * 50;
  63. VariantMap debugIconsPlacement;
  64. const int debugIconsPlacementIndent = 1.0;
  65. const float debugIconsOrthoDistance = 15.0f;
  66. Vector2 Max(Vector2 a, Vector2 b)
  67. {
  68. return (a.length > b.length ? a : b);
  69. }
  70. Vector2 Clamp(Vector2 a, Vector2 b)
  71. {
  72. return Vector2((a.x > b.x ? b.x : a.x),(a.y > b.y ? b.y : a.y));
  73. }
  74. Vector2 ClampToIconMaxSize(Vector2 a)
  75. {
  76. return Clamp(a, debugIconsMaxSize);
  77. }
  78. void CreateDebugIcons(Node@ tempNode)
  79. {
  80. if (editorScene is null) return;
  81. debugIconsSet.Resize(ICON_COUNT);
  82. for (int i = 0; i < ICON_COUNT; i++)
  83. {
  84. debugIconsSet[i] = tempNode.CreateComponent("BillboardSet");
  85. debugIconsSet[i].material = cache.GetResource("Material", "Materials/Editor/" + IconsTypesMaterials[i]);
  86. debugIconsSet[i].sorted = true;
  87. debugIconsSet[i].temporary = true;
  88. debugIconsSet[i].viewMask = 0x80000000;
  89. }
  90. }
  91. void UpdateViewDebugIcons()
  92. {
  93. if (editorScene is null || timeToNextDebugIconsUpdate > time.systemTime) return;
  94. debugIconsNode = editorScene.GetChild("DebugIconsContainer", true);
  95. if (debugIconsNode is null)
  96. {
  97. debugIconsNode = editorScene.CreateChild("DebugIconsContainer", LOCAL);
  98. debugIconsNode.temporary = true;
  99. }
  100. // Checkout if debugIconsNode do not have any BBS component, add all at once
  101. BillboardSet@ isBSExist = debugIconsNode.GetComponent("BillboardSet");
  102. if (isBSExist is null) CreateDebugIcons(debugIconsNode);
  103. if (debugIconsSet[ICON_POINT_LIGHT] !is null)
  104. {
  105. for(int i=0; i < ICON_COUNT; i++)
  106. debugIconsSet[i].enabled = debugIconsShow;
  107. }
  108. if (debugIconsShow == false) return;
  109. Vector3 camPos = activeViewport.cameraNode.worldPosition;
  110. bool isOrthographic = activeViewport.camera.orthographic;
  111. debugIconsPlacement.Clear();
  112. for(int iconType=0; iconType<ICON_COUNT; iconType++)
  113. {
  114. if (debugIconsSet[iconType] !is null)
  115. {
  116. // SplinePath update resolution
  117. if (iconType == ICON_SPLINE_PATH && timeToNextDebugIconsUpdateSplinePath > time.systemTime) continue;
  118. Array<Node@> nodes = editorScene.GetChildrenWithComponent(ComponentTypes[iconType], true);
  119. // Clear old data
  120. if (iconType == ICON_SPLINE_PATH)
  121. ClearCommit(ICON_SPLINE_PATH, ICON_SPLINE_PATH+1, nodes.length * splinePathResolution);
  122. else if (iconType==ICON_POINT_LIGHT || iconType==ICON_SPOT_LIGHT || iconType==ICON_DIRECTIONAL_LIGHT)
  123. ClearCommit(ICON_POINT_LIGHT, ICON_DIRECTIONAL_LIGHT+1, nodes.length);
  124. else if (iconType==ICON_SOUND_SOURCE || iconType==ICON_SOUND_SOURCE_3D)
  125. ClearCommit(ICON_SOUND_SOURCE, ICON_SOUND_SOURCE_3D+1, nodes.length);
  126. else
  127. ClearCommit(iconType, iconType+1, nodes.length);
  128. if (nodes.length > 0)
  129. {
  130. // Fill with new data
  131. for(int i=0;i<nodes.length; i++)
  132. {
  133. Component@ component = nodes[i].GetComponent(ComponentTypes[iconType]);
  134. if (component is null) continue;
  135. Billboard@ bb = null;
  136. Color finalIconColor = debugIconsColors[ICON_COLOR_DEFAULT];
  137. float distance = (camPos - nodes[i].worldPosition).length;
  138. if (isOrthographic) distance = debugIconsOrthoDistance;
  139. int iconsOffset = debugIconsPlacement[StringHash(nodes[i].id)].GetInt();
  140. float iconsYPos = 0;
  141. if (iconType==ICON_SPLINE_PATH)
  142. {
  143. SplinePath@ sp = cast<SplinePath>(component);
  144. if (sp !is null)
  145. if (sp.length > 0.01f)
  146. {
  147. for(int step=0; step < splinePathResolution; step++)
  148. {
  149. int index = (i * splinePathResolution) + step;
  150. Vector3 splinePoint = sp.GetPoint(splineStep * step);
  151. Billboard@ bb = debugIconsSet[ICON_SPLINE_PATH].billboards[index];
  152. float stepDistance = (camPos - splinePoint).length;
  153. if (isOrthographic) stepDistance = debugIconsOrthoDistance;
  154. if (step == 0) // SplinePath start
  155. {
  156. bb.color = debugIconsColors[ICON_COLOR_SPLINE_PATH_BEGIN];
  157. bb.size = ClampToIconMaxSize(Max(debugIconsSize * stepDistance, debugIconsSize));
  158. bb.position = splinePoint;
  159. }
  160. else if ((step+1) >= (splinePathResolution - splineStep)) // SplinePath end
  161. {
  162. bb.color = debugIconsColors[ICON_COLOR_SPLINE_PATH_END];
  163. bb.size = ClampToIconMaxSize(Max(debugIconsSize * stepDistance, debugIconsSize));
  164. bb.position = splinePoint;
  165. }
  166. else // SplinePath middle points
  167. {
  168. bb.color = finalIconColor;
  169. bb.size = ClampToIconMaxSize(Max(debugIconsSizeSmall * stepDistance, debugIconsSizeSmall));
  170. bb.position = splinePoint;
  171. }
  172. bb.enabled = sp.enabled;
  173. // Blend Icon relatively by distance to it
  174. bb.color = Color(bb.color.r, bb.color.g, bb.color.b, 1.2f - 1.0f / (debugIconsMaxSize.x / bb.size.x));
  175. if (bb.color.a < 0.25f) bb.enabled = false;
  176. }
  177. }
  178. }
  179. else
  180. {
  181. bb = debugIconsSet[iconType].billboards[i];
  182. bb.size = ClampToIconMaxSize(Max(debugIconsSize * distance, debugIconsSize));
  183. if (iconType==ICON_PARTICLE_EMITTER)
  184. {
  185. bb.size = ClampToIconMaxSize(Max(debugIconsSize * distance, debugIconsSize));
  186. }
  187. else if (iconType==ICON_TRIGGER)
  188. {
  189. RigidBody@ rigidbody = cast<RigidBody>(component);
  190. if (rigidbody !is null)
  191. {
  192. if (rigidbody.trigger == false) continue;
  193. }
  194. }
  195. else if (iconType==ICON_POINT_LIGHT || iconType==ICON_SPOT_LIGHT || iconType==ICON_DIRECTIONAL_LIGHT)
  196. {
  197. Light@ light = cast<Light>(component);
  198. if (light !is null)
  199. {
  200. if (light.lightType == LIGHT_POINT)
  201. bb = debugIconsSet[ICON_POINT_LIGHT].billboards[i];
  202. else if (light.lightType == LIGHT_DIRECTIONAL)
  203. bb = debugIconsSet[ICON_DIRECTIONAL_LIGHT].billboards[i];
  204. else if (light.lightType == LIGHT_SPOT)
  205. bb = debugIconsSet[ICON_SPOT_LIGHT].billboards[i];
  206. bb.size = ClampToIconMaxSize(Max(debugIconsSize * distance, debugIconsSize));
  207. finalIconColor = light.effectiveColor;
  208. }
  209. }
  210. bb.position = nodes[i].worldPosition;
  211. // Blend Icon relatively by distance to it
  212. bb.color = Color(finalIconColor.r, finalIconColor.g, finalIconColor.b, 1.2f - 1.0f / (debugIconsMaxSize.x / bb.size.x));
  213. bb.enabled = component.enabled;
  214. // Discard billboard if it almost transparent
  215. if (bb.color.a < 0.25f) bb.enabled = false;
  216. IncrementIconPlacement(bb.enabled, nodes[i], 1 );
  217. }
  218. }
  219. Commit(iconType, iconType+1);
  220. // SplinePath update resolution
  221. if (iconType == ICON_SPLINE_PATH) timeToNextDebugIconsUpdateSplinePath = time.systemTime + stepDebugIconsUpdateSplinePath;
  222. }
  223. }
  224. }
  225. timeToNextDebugIconsUpdate = time.systemTime + stepDebugIconsUpdate;
  226. }
  227. void ClearCommit(int begin, int end, int newlength)
  228. {
  229. for(int i=begin;i<end;i++)
  230. {
  231. debugIconsSet[i].numBillboards = 0;
  232. debugIconsSet[i].Commit();
  233. debugIconsSet[i].numBillboards = newlength;
  234. }
  235. }
  236. void Commit(int begin, int end)
  237. {
  238. for(int i=begin;i<end;i++)
  239. {
  240. debugIconsSet[i].Commit();
  241. }
  242. }
  243. void IncrementIconPlacement(bool componentEnabled, Node@ node, int offset)
  244. {
  245. if (componentEnabled == true)
  246. {
  247. int oldPlacement = debugIconsPlacement[StringHash(node.id)].GetInt();
  248. debugIconsPlacement[StringHash(node.id)] = Variant(oldPlacement + offset);
  249. }
  250. }