| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "Utility/BsEditorUtility.h"
- #include "Scene/BsSceneObject.h"
- #include "Components/BsCRenderable.h"
- namespace bs
- {
- AABox EditorUtility::calculateBounds(const HSceneObject& object)
- {
- Vector<HSceneObject> objects = { object };
- return calculateBounds(objects);
- }
- AABox EditorUtility::calculateBounds(const Vector<HSceneObject>& objects)
- {
- if (objects.size() == 0)
- return AABox(Vector3::ZERO, Vector3::ZERO);
- AABox bounds = AABox(Vector3::INF, -Vector3::INF);
- bool gotOneMesh = false;
- for (auto& object : objects)
- {
- AABox meshBounds;
- if (calculateMeshBounds(object, meshBounds))
- {
- bounds.merge(meshBounds);
- gotOneMesh = true;
- }
- }
- if (!gotOneMesh)
- {
- for (auto& object : objects)
- {
- if (object.isDestroyed())
- continue;
- bounds.merge(object->getTransform().getPosition());
- gotOneMesh = true;
- }
- }
- if(gotOneMesh)
- return bounds;
- return AABox(Vector3::ZERO, Vector3::ZERO);
- }
- Vector3 EditorUtility::calculateCenter(const Vector<HSceneObject>& objects)
- {
- if (objects.size() == 0)
- return Vector3::ZERO;
- Vector3 center = Vector3::ZERO;
- UINT32 count = 0;
- for (auto& object : objects)
- {
- AABox meshBounds;
- if (calculateMeshBounds(object, meshBounds))
- {
- if (meshBounds.getSize() == Vector3::INF)
- center += object->getTransform().getPosition();
- else
- center += meshBounds.getCenter();
- count++;
- }
- }
- if (count == 0)
- {
- for (auto& object : objects)
- {
- if (object.isDestroyed())
- continue;
- center += object->getTransform().getPosition();
- count++;
- }
- }
- if (count > 0)
- return center / (float)count;
- return Vector3::ZERO;
- }
- bool EditorUtility::calculateMeshBounds(const HSceneObject& object, AABox& bounds)
- {
- bounds = AABox(Vector3::ZERO, Vector3::ZERO);
- if (object.isDestroyed())
- return false;
- bool foundOne = false;
- const Vector<HComponent>& components = object->getComponents();
- for (auto& component : components)
- {
- Bounds curBounds;
- if (component->calculateBounds(curBounds))
- {
- if (!foundOne)
- {
- bounds = curBounds.getBox();
- foundOne = true;
- }
- else
- bounds.merge(curBounds.getBox());
- }
- else
- {
- if (!foundOne)
- bounds = curBounds.getBox();
- }
- }
- return foundOne;
- }
- EditorUtility::SceneObjProxy EditorUtility::createProxy(const HSceneObject& sceneObject)
- {
- struct TempData
- {
- TempData(SceneObjProxy& proxy, const HSceneObject& so)
- :proxy(proxy), obj(so)
- { }
- SceneObjProxy& proxy;
- HSceneObject obj;
- };
- SceneObjProxy rootProxy;
- Stack<TempData> todo;
- todo.push(TempData(rootProxy, sceneObject));
- while (!todo.empty())
- {
- TempData data = todo.top();
- todo.pop();
- data.proxy.instanceData = data.obj->_getInstanceData();
- const Vector<HComponent>& components = data.obj->getComponents();
- for (auto& component : components)
- data.proxy.componentInstanceData.push_back(component->_getInstanceData());
- UINT32 numChildren = data.obj->getNumChildren();
- data.proxy.children.resize(numChildren);
- for (UINT32 i = 0; i < numChildren; i++)
- {
- todo.push(TempData(data.proxy.children[i], data.obj->getChild(i)));
- }
- }
- return rootProxy;
- }
- void EditorUtility::restoreIds(const HSceneObject& restored, SceneObjProxy& proxy)
- {
- // Note: This method relies that all restored GameObject handles pointing to the
- // same object also have the same shared handle data (Since I only update instance
- // data on a single handle I know exists, and expect all others will be updated
- // by that as well).
- struct TempData
- {
- TempData(SceneObjProxy* proxy, const HSceneObject& restoredObj)
- :proxy(proxy), restoredObj(restoredObj)
- { }
- SceneObjProxy* proxy;
- HSceneObject restoredObj;
- };
- Stack<TempData> todo;
- todo.push(TempData(&proxy, restored));
- while (!todo.empty())
- {
- TempData data = todo.top();
- todo.pop();
- data.restoredObj->_setInstanceData(data.proxy->instanceData);
- // Find components that are still active and swap the old ones with restored ones,
- // keep any other as is.
- const Vector<HComponent>& restoredComponents = data.restoredObj->getComponents();
- UINT32 idx = 0;
- for (auto& restoredComponent : restoredComponents)
- {
- restoredComponent->_setInstanceData(data.proxy->componentInstanceData[idx]);
- SPtr<GameObject> restoredPtr = std::static_pointer_cast<GameObject>(restoredComponent.getInternalPtr());
- HComponent restoredComponentCopy = restoredComponent; // To remove const
- restoredComponentCopy._setHandleData(restoredPtr);
- idx++;
- }
- // Find children that are still active and swap the old ones with restored ones,
- // keep any other as is
- UINT32 restoredNumChildren = data.restoredObj->getNumChildren();
- for (UINT32 i = 0; i < restoredNumChildren; i++)
- {
- todo.push(TempData(&data.proxy->children[i], data.restoredObj->getChild(i)));
- }
- }
- }
- }
|