소스 검색

Added gizmos for the Light component

BearishSun 10 년 전
부모
커밋
e81f552e28

+ 44 - 0
BansheeEditor/Include/BsGizmoManager.h

@@ -108,6 +108,26 @@ namespace BansheeEngine
 		 */
 		void drawLine(const Vector3& start, const Vector3& end);
 
+		/**
+		 * @brief	Draws a wireframe disc.
+		 *
+		 * @param	position	Center of the disc.
+		 * @param	normal		Orientation of the disc, pointing in the direction the disc is visible in.
+		 * @param	radius		Radius of the disc.
+		 */
+		void drawWireDisc(const Vector3& position, const Vector3& normal, float radius);
+
+		/**
+		 * @brief	Draws a wireframe arc.
+		 *
+		 * @param	position	Center of the arc.
+		 * @param	normal		Orientation of the arc, pointing in the direction the arc is visible in.
+		 * @param	radius		Radius of the arc.
+		 * @param	startAngle	Angle at which to start the arc.
+		 * @param	amountAngle	Length of the arc.
+		 */
+		void drawWireArc(const Vector3& position, const Vector3& normal, float radius, Degree startAngle, Degree amountAngle);
+
 		/**
 		 * @brief	Draws a wireframe frustum.
 		 *
@@ -221,6 +241,28 @@ namespace BansheeEngine
 			Vector3 end;
 		};
 
+		/**
+		 * @brief	Data required for rendering a wireframe disc gizmo.
+		 */
+		struct WireDiscData : public CommonData
+		{
+			Vector3 position;
+			Vector3 normal;
+			float radius;
+		};
+
+		/**
+		 * @brief	Data required for rendering a wireframe arc gizmo.
+		 */
+		struct WireArcData : public CommonData
+		{
+			Vector3 position;
+			Vector3 normal;
+			float radius;
+			Degree startAngle;
+			Degree amountAngle;
+		};
+
 		/**
 		 * @brief	Data required for rendering a frustum gizmo.
 		 */
@@ -332,6 +374,8 @@ namespace BansheeEngine
 		Vector<SphereData> mSolidSphereData;
 		Vector<SphereData> mWireSphereData;
 		Vector<LineData> mLineData;
+		Vector<WireDiscData> mWireDiscData;
+		Vector<WireArcData> mWireArcData;
 		Vector<FrustumData> mFrustumData;
 		Vector<IconData> mIconData;
 		Map<UINT32, HSceneObject> mIdxToSceneObjectMap;

+ 64 - 0
BansheeEditor/Source/BsGizmoManager.cpp

@@ -195,6 +195,45 @@ namespace BansheeEngine
 		mIdxToSceneObjectMap[lineData.idx] = mActiveSO;
 	}
 
+	void GizmoManager::drawWireDisc(const Vector3& position, const Vector3& normal, float radius)
+	{
+		mWireDiscData.push_back(WireDiscData());
+		WireDiscData& wireDiscData = mWireDiscData.back();
+
+		wireDiscData.idx = mCurrentIdx++;
+		wireDiscData.position = position;
+		wireDiscData.normal = normal;
+		wireDiscData.radius = radius;
+		wireDiscData.color = mColor;
+		wireDiscData.transform = mTransform;
+		wireDiscData.sceneObject = mActiveSO;
+		wireDiscData.pickable = mPickable;
+
+		mDrawHelper->wireDisc(position, normal, radius);
+		mIdxToSceneObjectMap[wireDiscData.idx] = mActiveSO;
+	}
+
+	void GizmoManager::drawWireArc(const Vector3& position, const Vector3& normal, float radius, 
+		Degree startAngle, Degree amountAngle)
+	{
+		mWireArcData.push_back(WireArcData());
+		WireArcData& wireArcData = mWireArcData.back();
+
+		wireArcData.idx = mCurrentIdx++;
+		wireArcData.position = position;
+		wireArcData.normal = normal;
+		wireArcData.radius = radius;
+		wireArcData.startAngle = startAngle;
+		wireArcData.amountAngle = amountAngle;
+		wireArcData.color = mColor;
+		wireArcData.transform = mTransform;
+		wireArcData.sceneObject = mActiveSO;
+		wireArcData.pickable = mPickable;
+
+		mDrawHelper->wireArc(position, normal, radius, startAngle, amountAngle);
+		mIdxToSceneObjectMap[wireArcData.idx] = mActiveSO;
+	}
+
 	void GizmoManager::drawFrustum(const Vector3& position, float aspect, Degree FOV, float near, float far)
 	{
 		mFrustumData.push_back(FrustumData());
@@ -336,6 +375,29 @@ namespace BansheeEngine
 			mPickingDrawHelper->line(lineDataEntry.start, lineDataEntry.end);
 		}
 
+		for (auto& wireDiscDataEntry : mWireDiscData)
+		{
+			if (!wireDiscDataEntry.pickable)
+				continue;
+
+			mPickingDrawHelper->setColor(idxToColorCallback(wireDiscDataEntry.idx));
+			mPickingDrawHelper->setTransform(wireDiscDataEntry.transform);
+
+			mPickingDrawHelper->wireDisc(wireDiscDataEntry.position, wireDiscDataEntry.normal, wireDiscDataEntry.radius);
+		}
+
+		for (auto& wireArcDataEntry : mWireArcData)
+		{
+			if (!wireArcDataEntry.pickable)
+				continue;
+
+			mPickingDrawHelper->setColor(idxToColorCallback(wireArcDataEntry.idx));
+			mPickingDrawHelper->setTransform(wireArcDataEntry.transform);
+
+			mPickingDrawHelper->wireArc(wireArcDataEntry.position, wireArcDataEntry.normal, wireArcDataEntry.radius, 
+				wireArcDataEntry.startAngle, wireArcDataEntry.amountAngle);
+		}
+
 		for (auto& frustumDataEntry : mFrustumData)
 		{
 			if (!frustumDataEntry.pickable)
@@ -399,6 +461,8 @@ namespace BansheeEngine
 		mSolidSphereData.clear();
 		mWireSphereData.clear();
 		mLineData.clear();
+		mWireDiscData.clear();
+		mWireArcData.clear();
 		mFrustumData.clear();
 		mIconData.clear();
 		mIdxToSceneObjectMap.clear();

+ 1 - 0
MBansheeEditor/MBansheeEditor.csproj

@@ -131,6 +131,7 @@
     <Compile Include="ProjectSettings.cs" />
     <Compile Include="Library\LibraryWindow.cs" />
     <Compile Include="ProjectWindow.cs" />
+    <Compile Include="Scene\LightGizmos.cs" />
     <Compile Include="Scene\SceneAxesGUI.cs" />
     <Compile Include="Scene\SceneAxesHandle.cs" />
     <Compile Include="Scene\SceneCamera.cs" />

+ 31 - 0
MBansheeEditor/Scene/Gizmos.cs

@@ -95,6 +95,30 @@ namespace BansheeEditor
             Internal_DrawLine(ref start, ref end);
         }
 
+        /// <summary>
+        /// Draws a wireframe disc.
+        /// </summary>
+        /// <param name="position">Center of the disc.</param>
+        /// <param name="normal">Normal towards which to orient the disc.</param>
+        /// <param name="radius">Radius of the disc.</param>
+        public static void DrawWireDisc(Vector3 position, Vector3 normal, float radius)
+        {
+            Internal_DrawWireDisc(ref position, ref normal, radius);
+        }
+
+        /// <summary>
+        /// Draws a wireframe arc.
+        /// </summary>
+        /// <param name="position">Center of the disc out of which the arc is cut out of.</param>
+        /// <param name="normal">Normal towards which to orient the arc.</param>
+        /// <param name="radius">Radius of the  disc out of which the arc is cut out of.</param>
+        /// <param name="startAngle">Angle at which the arc starts.</param>
+        /// <param name="amountAngle">Length of the arc.</param>
+        public static void DrawWireArc(Vector3 position, Vector3 normal, float radius, Degree startAngle, Degree amountAngle)
+        {
+            Internal_DrawWireArc(ref position, ref normal, radius, startAngle.Degrees, amountAngle.Degrees);
+        }
+
         /// <summary>
         /// Draws a wireframe camera frustum.
         /// </summary>
@@ -147,6 +171,13 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_DrawLine(ref Vector3 start, ref Vector3 end);
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawWireDisc(ref Vector3 position, ref Vector3 normal, float radius);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_DrawWireArc(ref Vector3 position, ref Vector3 normal, float radius, 
+            float startAngle, float amountAngle);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_DrawFrustum(ref Vector3 position, float aspect, ref Degree FOV, float near, float far);
 

+ 70 - 0
MBansheeEditor/Scene/LightGizmos.cs

@@ -0,0 +1,70 @@
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+    /// <summary>
+    /// Handles drawing of gizmos for the <see cref="Light"/> component.
+    /// </summary>
+    internal class LightGizmos
+    {
+        /// <summary>
+        /// Method called by the runtime when gizmos are meant to be drawn.
+        /// </summary>
+        /// <param name="light">Light to draw gizmos for.</param>
+        [DrawGizmo(DrawGizmoFlags.Selected)]
+        private static void Draw(Light light)
+        {
+            Vector3 position = light.SceneObject.Position;
+
+            Gizmos.Color = Color.Yellow;
+            switch (light.Type)
+            {
+                case LightType.Directional:
+                {
+                    Vector3 right = light.SceneObject.Rotation.Rotate(Vector3.XAxis);
+                    Vector3 up = light.SceneObject.Rotation.Rotate(Vector3.YAxis);
+                    Vector3 forward = light.SceneObject.Forward;
+
+                    Vector3 topLeft = position - right + up;
+                    Vector3 topRight = position + right + up;
+                    Vector3 botLeft = position - right - up;
+                    Vector3 botRight = position + right - up;
+
+                    Gizmos.DrawLine(topLeft, topRight);
+                    Gizmos.DrawLine(topRight, botRight);
+                    Gizmos.DrawLine(botRight, botLeft);
+                    Gizmos.DrawLine(botLeft, topLeft);
+
+                    Gizmos.DrawLine(topLeft, topLeft + forward*5.0f);
+                    Gizmos.DrawLine(topRight, topRight + forward*5.0f);
+                    Gizmos.DrawLine(botRight, botRight + forward*5.0f);
+                    Gizmos.DrawLine(botLeft, botLeft + forward*5.0f);
+                }
+                    break;
+                case LightType.Point:
+                    Gizmos.DrawWireSphere(position, light.Range);
+
+                    break;
+                case LightType.Spot:
+                {
+                    Vector3 right = light.SceneObject.Rotation.Rotate(Vector3.XAxis);
+                    Vector3 up = light.SceneObject.Rotation.Rotate(Vector3.YAxis);
+                    Vector3 forward = light.SceneObject.Forward;
+
+                    float discRadius = light.Range*MathEx.Tan(light.SpotAngle*0.5f);
+
+                    Gizmos.DrawLine(position, position + forward * light.Range + up * discRadius);
+                    Gizmos.DrawLine(position, position + forward * light.Range - up * discRadius);
+                    Gizmos.DrawLine(position, position + forward * light.Range + right * discRadius);
+                    Gizmos.DrawLine(position, position + forward * light.Range - right * discRadius);
+
+                    float falloffDiscRadius = light.Range * MathEx.Tan(light.SpotFalloffAngle * 0.5f);
+
+                    Gizmos.DrawWireDisc(position + forward * light.Range, forward, discRadius);
+                    Gizmos.DrawWireDisc(position + forward * light.Range, forward, falloffDiscRadius);
+                }
+                    break;
+            }
+        }
+    }
+}

+ 1 - 1
MBansheeEngine/SceneObject.cs

@@ -168,7 +168,7 @@ namespace BansheeEngine
         }
 
         /// <summary>
-        /// Direction in world space that points along the local positive Z axis.
+        /// Direction in world space that points along the local negative Z axis.
         /// </summary>
         public Vector3 Forward
         {

+ 1 - 1
RenderBeast/Source/BsLightRendering.cpp

@@ -51,7 +51,7 @@ namespace BansheeEngine
 		lightGeometry.y = (float)LightCore::LIGHT_CONE_NUM_SLICES;
 		lightGeometry.z = light->getBounds().getRadius();
 
-		float coneRadius = Math::sin(light->getSpotFalloffAngle()) * light->getRange();
+		float coneRadius = Math::sin(light->getSpotAngle()) * light->getRange();
 		lightGeometry.w = coneRadius;
 
 		mBuffer.gLightGeometry.set(lightGeometry);

+ 2 - 0
SBansheeEditor/Include/BsScriptGizmos.h

@@ -29,6 +29,8 @@ namespace BansheeEngine
 		static void internal_DrawWireCube(Vector3* position, Vector3* extents);
 		static void internal_DrawWireSphere(Vector3* position, float radius);
 		static void internal_DrawLine(Vector3* start, Vector3* end);
+		static void internal_DrawWireDisc(Vector3* position, Vector3* normal, float radius);
+		static void internal_DrawWireArc(Vector3* position, Vector3* normal, float radius, float startAngle, float amountAngle);
 		static void internal_DrawFrustum(Vector3* position, float aspect, Degree* FOV, float near, float far);
 		static void internal_DrawIcon(Vector3* position, MonoObject* image, bool fixedScale);
 	};

+ 13 - 0
SBansheeEditor/Source/BsScriptGizmos.cpp

@@ -17,6 +17,8 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_DrawSphere", &ScriptGizmos::internal_DrawSphere);
 		metaData.scriptClass->addInternalCall("Internal_DrawWireCube", &ScriptGizmos::internal_DrawWireCube);
 		metaData.scriptClass->addInternalCall("Internal_DrawWireSphere", &ScriptGizmos::internal_DrawWireSphere);
+		metaData.scriptClass->addInternalCall("Internal_DrawWireDisc", &ScriptGizmos::internal_DrawWireDisc);
+		metaData.scriptClass->addInternalCall("Internal_DrawWireArc", &ScriptGizmos::internal_DrawWireArc);
 		metaData.scriptClass->addInternalCall("Internal_DrawLine", &ScriptGizmos::internal_DrawLine);
 		metaData.scriptClass->addInternalCall("Internal_DrawFrustum", &ScriptGizmos::internal_DrawFrustum);
 		metaData.scriptClass->addInternalCall("Internal_DrawIcon", &ScriptGizmos::internal_DrawIcon);
@@ -67,6 +69,17 @@ namespace BansheeEngine
 		GizmoManager::instance().drawLine(*start, *end);
 	}
 
+	void ScriptGizmos::internal_DrawWireDisc(Vector3* position, Vector3* normal, float radius)
+	{
+		GizmoManager::instance().drawWireDisc(*position, *normal, radius);
+	}
+
+	void ScriptGizmos::internal_DrawWireArc(Vector3* position, Vector3* normal, float radius, float startAngle, 
+		float amountAngle)
+	{
+		GizmoManager::instance().drawWireArc(*position, *normal, radius, Degree(startAngle), Degree(amountAngle));
+	}
+
 	void ScriptGizmos::internal_DrawFrustum(Vector3* position, float aspect, Degree* FOV, float near, float far)
 	{
 		GizmoManager::instance().drawFrustum(*position, aspect, *FOV, near, far);