SceneView.txt 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. TODO:
  2. - Core thread gets stuck on shutdown when OpenGL is used...Somewhere in kernel
  3. CONCRETE TASK:
  4. - Similar to how I have onRenderViewport callback in Renderer have another one that gets triggered from core thread
  5. - Hook up gizmo rendering there
  6. - Hook up gizmo manager to ScenePicking so gizmos are considered when picking
  7. - I'll likely need to update GizmoManager so I can query gizmo SceneObject based on gizmo index
  8. - Selection/ScenePicking/GizmoManager need to be started
  9. IMMEDIATE:
  10. - SceneGrid is very ugly. Consider using default lines for now and come back with a better approach later.
  11. - Potentially enable line AA?
  12. - Picking code is completely untested and will likely need major fixing
  13. - Disable DX9 for editor as I will likely want to use geometry shaders for icon rendering, and possibly new AA line shader
  14. - Or just use MeshHeap and update the icon/lines every frame?
  15. - Test all the new DrawHelper3D methods
  16. GIZMO TODO:
  17. - IMPORTANT: Gizmo rendering happens in update() but it should happen whenever scene view is being rendered as the render target isn't set anywhere
  18. - Figure out how to deal with builtin components like Camera and Renderable (e.g. how will they have gizmos since they're not managed components?)
  19. LATER:
  20. - Need a way to render text for gizmos and handles, and in scene in general
  21. ----------------------------------------------------------------------
  22. Handles
  23. SliderLine - position, direction, length
  24. - When initially activated it records position nearest so the line as the starting point
  25. - Further mouse dragging also finds nearest position to the line
  26. - Difference between those two results in a float value (how much to move along direction from position to reach new position)
  27. - Slider line has a capsule + sphere collider size of which can be set manually
  28. SliderPlane - position, normal, size
  29. - Similar to line slider only the direction is determined dynamically as well as distance
  30. - Outputs a Vector2 (direction * distance moved)
  31. - A OOB is used as a collider
  32. SliderDisc - position, normal, radius
  33. - When initially activated it records position nearest so the disc as the starting point
  34. - Further movement calculates the dynamic direction from the starting point to the current point on the plane the disc lies on
  35. - Distance along that direction is returned as amount of movement (similar to line slider)
  36. - Outputs a single float
  37. - A torus is used as a collider
  38. Handles are always the same size regardless of the distance from camera. (Use same code as from gizmo rendering?)
  39. These three types can be used for creating MoveHandle, RotationHandle, ScaleHandle
  40. In C# user can call Handles class for managing handles
  41. - It will allow you to draw various handle shapes, similar to gizmo drawing (unify that code? - probably not initially)
  42. - e.g. DrawCone, DrawSphere, DrawWireDisc, etc.
  43. - Including more complex ones like DrawArrow and similar
  44. - Using the same class user can also set up Sliders which don't have a visible representation
  45. - AND finally user can also set up combined premade handles like FreeMove which sets up all sliders and draw methods needed automatically
  46. SliderLine, SliderPlane, SliderDisc will all be separate classes in C# and C++
  47. - They need to have a matrix and color property you can modify on the go
  48. - As well a specific properties like length/size/radius (possibly others)
  49. - Since all of the above are just normal classes C++ can follow the same approach for default handles and custom user ones
  50. Certain classes are marked with [Handle] attribute. The attribute also accepts a type the handle is to be used on.
  51. Each such class must implement IHandle interface which requires you to implement an Update method
  52. - Update method receives the instance of the object currently being processed
  53. - Then you may call handle specific methods like "position = mySliderLine.Update(object.currentPosition)"
  54. - Drawing - Immediate mode in the Update method. You call Handle.DrawArrow, etc.
  55. - Complex handles like FreeMoveHandle are also their own class, but they have their own Update in which they call immediate mode drawing
  56. - TODO: Since this entire class essentially boils down to a single method it might be worth making handle sliders immediate mode as well
  57. - ACTUALLY looking at Unity code I definitely don't want to do that. It's too clumsy and impossible to guarantee selection if the order of handles changes
  58. CONCRETE TASKS:
  59. - Need nearest point to disc/arc code
  60. Take into consideration local vs. global handles
  61. Free move/rotate/scale handles need to exist as well
  62. - Scale is easy, just perform uniform scale. Use SliderPlane oriented towards camera
  63. - Move also use SliderPlane oriented towards camera
  64. - Rotation use SliderDisc oriented towards camera
  65. See for inspiration: http://docs.unity3d.com/ScriptReference/Handles.html
  66. EXAMPLE:
  67. [CustomHandle(typeof(Camera))]
  68. class CameraHandle : IHandle
  69. {
  70. SliderLine xAxis;
  71. SliderLine yAxis;
  72. CameraHandle()
  73. {
  74. xAxis = new SliderLine(Vector3.right, 10.0f);
  75. yAxis = new SliderLine(Vector3.up, 10.0f);
  76. xAxis.onDragged += onXAxis();
  77. yAxis.onDragged += onYAxis();
  78. }
  79. void onXAxis()
  80. {
  81. // Here I can decide whether or not I want to use handle data or not, per object instance
  82. target.position = xAxis.getMove(target.position);
  83. }
  84. void onYAxis()
  85. {
  86. target.position = yAxis.getMove(target.position);
  87. }
  88. void Update()
  89. {
  90. // Resize handle, change matrix, etc.
  91. }
  92. void Draw()
  93. {
  94. xAxis.Draw();
  95. HandleDraw.Arrow(target.position, Vector3.right, 10.0f);
  96. HandleDraw.Arrow(target.position, Vector3.up, 10.0f);
  97. }
  98. }
  99. ------------
  100. What if I want a different handle per-object (e.g. object has some flag that makes different handles render)
  101. - SOLVED
  102. How I can easily access the current target object
  103. - Manually implement a generic getter?
  104. How will I implement this in C++ and use for default handles?
  105. - I'm still using classes in C# and C++ can use equivalents. Handle manager can do a special pass to draw default handles before calling the custom handle code.
  106. Do I want to unify gizmo and handle drawing?
  107. - Not at the moment. Too much to think about, I can always refactor and it will be easier.
  108. Handles can be mouse overed and selected. How will I handle that if I just use normal drawing methods???
  109. - This can be set in HandleSlider class itself with "isHovering", "isActive". And then its draw method can change appearance appropriately.
  110. Do I handle handle transforms via a matrix that is automatically set by the handle manager, or manually like unity does?
  111. - I shouldn't allow non-uniform scale.
  112. - In both cases I need to set handle transform in its Update() method
  113. - ALLOW custom matrix (or just custom offset and rotation?) but have handle manager set it normally
  114. - custom matrix sounds better for easier control?
  115. How do I handle when an object with a custom handle is deleted?
  116. - How do I detect that and remove the handle.
  117. - I SHOULDN'T HAVE TO
  118. - I should probably just instantiate he IHandle implementation class once object is selected, and destroy it after
  119. ----------------------------------------------------------------------
  120. SelectionRenderer
  121. Retrieve a list of selected objects from SelectionManager
  122. Find ones with Renderable components
  123. Retrieve Meshes, and world transforms from them
  124. Draw that same mesh with either a wireframe or a grayed out shader with a slight depth bias
  125. ----------------------------------------------------------------------
  126. SceneView editor flow:
  127. Hook up gizmo, handle and selection rendering methods to be executed after the scene is rendered
  128. Calculate mouse coords manually relative to the window and to the render texture GUI element
  129. - Don't use GUI events as we require more precise control (do we?)
  130. Detect mouse clicks on the scene render target
  131. Forward those mouse coordinates to HandleManager
  132. It checks if screen ray intersects any handles and returns the handle if it does
  133. If handle is found it is activated and method returns
  134. Otherwise we mark the coordinates as selection start
  135. Detect mouse drag on the scene render target
  136. - If we have an active handle
  137. Forward mouse coordinates to the active handle so it can do its thing
  138. return
  139. - Otherwise its assumed we are dragging a selection
  140. Update selection endpoint and send it to ScenePicking
  141. Use Selection to select picked objects if any
  142. return
  143. Detect mouse release on scene render target
  144. If we have an active handle
  145. Clear active handle
  146. return
  147. Otheriwse its assumed we are dragging a selection
  148. Do nothing
  149. return