Sfoglia il codice sorgente

Merge branch 'master' of https://github.com/BearishSun/BansheeEngine.git

BearishSun 9 anni fa
parent
commit
1fe0f301c7

+ 3 - 0
Source/BansheeEditor/Include/BsEditorUtility.h

@@ -27,6 +27,9 @@ namespace BansheeEngine
 		 */
 		static AABox calculateBounds(const Vector<HSceneObject>& objects);
 
+		/** Calculates world space center of the specified scene objects. */
+		static Vector3 calculateCenter(const Vector<HSceneObject>& objects);
+
 	private:
 		/**
 		 * Retrieves all components containing meshes on the specified object and outputs their bounds.

+ 44 - 1
Source/BansheeEditor/Source/BsEditorUtility.cpp

@@ -27,7 +27,6 @@ namespace BansheeEngine
 			if (calculateMeshBounds(object, meshBounds))
 			{
 				bounds.merge(meshBounds);
-
 				gotOneMesh = true;
 			}
 		}
@@ -50,6 +49,50 @@ namespace BansheeEngine
 		return AABox(Vector3::ZERO, Vector3::ZERO);
 	}
 
+	Vector3 EditorUtility::calculateCenter(const Vector<HSceneObject>& objects)
+	{
+		if (objects.size() == 0)
+			return Vector3::ZERO;
+
+		Vector3 center = Vector3::ZERO;
+		bool gotOneMesh = false;
+		UINT32 count = 0;
+
+		for (auto& object : objects)
+		{
+			AABox meshBounds;
+			if (calculateMeshBounds(object, meshBounds))
+			{
+				count++;
+				if (meshBounds.getSize() == Vector3::INF)
+					center += object->getWorldPosition();
+				else
+					center += meshBounds.getCenter();
+
+				gotOneMesh = true;
+			}
+		}
+
+		if (!gotOneMesh)
+		{
+			for (auto& object : objects)
+			{
+				if (object.isDestroyed())
+					continue;
+
+				center += object->getWorldPosition();
+				count++;
+				gotOneMesh = true;
+			}
+		}
+
+		if (gotOneMesh)
+			return center / count;
+
+		return Vector3::ZERO;
+	}
+
+
 	bool EditorUtility::calculateMeshBounds(const HSceneObject& object, AABox& bounds)
 	{
 		bounds = AABox(Vector3::ZERO, Vector3::ZERO);

+ 16 - 0
Source/MBansheeEditor/Utility/EditorUtility.cs

@@ -43,6 +43,19 @@ namespace BansheeEditor
             return bounds;
         }
 
+        /// <summary>
+        /// Calculates the center of all axis aligned boxes of the provided scene objects.
+        /// Only certain components like <see cref="Renderable"/> will be included in center calculations.
+        /// </summary>
+        /// <param name="objects">Scene objects to calculate the center for.</param>
+        /// <returns>Center of the objects group in world space.</returns>
+        public static Vector3 CalculateCenter(SceneObject[] objects)
+        {
+            Vector3 center;
+            Internal_CalculateArrayCenter(objects, out center);
+            return center;
+        }
+
         /// <summary>
         /// Converts a hierarchy of scene objects and their children into a flat array. Doesn't modify the scene object's
         /// themselves. 
@@ -100,6 +113,9 @@ namespace BansheeEditor
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_CalculateBoundsArray(SceneObject[] objects, out AABox bounds);
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_CalculateArrayCenter(SceneObject[] objects, out Vector3 center);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern Resource[] Internal_FindDependencies(Resource resource, bool recursive);
 

+ 1 - 2
Source/MBansheeEditor/Windows/Scene/Handles/DefaultHandleManager.cs

@@ -105,8 +105,7 @@ namespace BansheeEditor
                     foreach (var so in selectedSceneObjects)
                         flatenedHierarchy.AddRange(EditorUtility.FlattenHierarchy(so));
 
-                    AABox selectionBounds = EditorUtility.CalculateBounds(flatenedHierarchy.ToArray());
-                    position = selectionBounds.Center;
+                    position = EditorUtility.CalculateCenter(flatenedHierarchy.ToArray());
                 }
 
                 activeHandle.Position = position;

+ 1 - 0
Source/SBansheeEditor/Include/BsScriptEditorUtility.h

@@ -27,6 +27,7 @@ namespace BansheeEngine
 		static void internal_CalculateBoundsArray(MonoArray* objects, AABox* bounds);
 		static MonoArray* internal_FindDependencies(MonoObject* resource, bool recursive);
 		static bool internal_IsInternal(ScriptSceneObject* soPtr);
+		static void internal_CalculateArrayCenter(MonoArray* objects, Vector3* center);
 	};
 
 	/** @} */

+ 20 - 0
Source/SBansheeEditor/Source/BsScriptEditorUtility.cpp

@@ -23,6 +23,7 @@ namespace BansheeEngine
 	{
 		metaData.scriptClass->addInternalCall("Internal_CalculateBounds", &ScriptEditorUtility::internal_CalculateBounds);
 		metaData.scriptClass->addInternalCall("Internal_CalculateBoundsArray", &ScriptEditorUtility::internal_CalculateBoundsArray);
+		metaData.scriptClass->addInternalCall("Internal_CalculateArrayCenter", &ScriptEditorUtility::internal_CalculateArrayCenter);
 		metaData.scriptClass->addInternalCall("Internal_FindDependencies", &ScriptEditorUtility::internal_FindDependencies);
 		metaData.scriptClass->addInternalCall("Internal_IsInternal", &ScriptEditorUtility::internal_IsInternal);
 	}
@@ -81,6 +82,25 @@ namespace BansheeEngine
 		return output.getInternal();
 	}
 
+	void ScriptEditorUtility::internal_CalculateArrayCenter(MonoArray* objects, Vector3* center)
+	{
+		Vector<HSceneObject> sceneObjects;
+
+		ScriptArray scriptArray(objects);
+		UINT32 arrayLen = scriptArray.size();
+		for (UINT32 i = 0; i < arrayLen; i++)
+		{
+			MonoObject* curObject = scriptArray.get<MonoObject*>(i);
+
+			ScriptSceneObject* scriptSO = ScriptSceneObject::toNative(curObject);
+
+			if (scriptSO != nullptr)
+				sceneObjects.push_back(static_object_cast<SceneObject>(scriptSO->getNativeHandle()));
+		}
+
+		*center = EditorUtility::calculateCenter(sceneObjects);
+	}
+
 	bool ScriptEditorUtility::internal_IsInternal(ScriptSceneObject* soPtr)
 	{
 		if (ScriptSceneObject::checkIfDestroyed(soPtr))