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;
	}
	void GUIGameObjectField::dataDropped(void* data)
	{
		DraggedSceneObjects* draggedSceneObjects = reinterpret_cast<DraggedSceneObjects*>(data);

		if (draggedSceneObjects->numObjects <= 0)
			return;

		MonoClass* sceneObjectClass = ScriptAssemblyManager::instance().getSceneObjectClass();

		if (mType == sceneObjectClass->getFullName()) // A scene object
		{
			setValue(draggedSceneObjects->objects[0], true);
		}
		else // A component
		{
			for (UINT32 i = 0; i < draggedSceneObjects->numObjects; i++)
			{
				HSceneObject so = draggedSceneObjects->objects[i];

				const Vector<HComponent>& components = so->getComponents();
				for (auto& component : components)
				{
					if (component->getTypeId() == TID_ManagedComponent) // We only care about managed components
					{
						HManagedComponent managedComponent = static_object_cast<ManagedComponent>(component);

						MonoClass* acceptedClass = MonoManager::instance().findClass(mNamespace, mType);
						MonoClass* providedClass = MonoManager::instance().findClass(managedComponent->getManagedNamespace(), managedComponent->getManagedTypeName());

						if (acceptedClass != nullptr && providedClass != nullptr)
						{
							if (providedClass->isSubClassOf(acceptedClass))
							{
								setValue(managedComponent, true);
							}
						}
					}
				}
			}
		}
	}
	void CmdBreakPrefab::revert()
	{
		if (mPrefabRoot == nullptr || mPrefabRoot.isDestroyed())
			return;

		mPrefabRoot->_setPrefabLinkUUID(mPrefabLinkUUID);
		mPrefabRoot->_setPrefabDiff(mPrefabDiff);

		Stack<HSceneObject> todo;
		todo.push(mPrefabRoot);

		while (!todo.empty())
		{
			HSceneObject currentSO = todo.top();
			todo.pop();

			const Vector<HComponent>& components = currentSO->getComponents();
			for (auto& component : components)
			{
				auto iterFind = mLinkIds.find(component->getInstanceId());
				if (iterFind != mLinkIds.end())
					component->_setLinkId(iterFind->second);
			}

			UINT32 numChildren = (UINT32)currentSO->getNumChildren();
			for (UINT32 i = 0; i < numChildren; i++)
			{
				HSceneObject child = currentSO->getChild(i);

				auto iterFind = mLinkIds.find(child->getInstanceId());
				if (iterFind != mLinkIds.end())
					child->_setLinkId(iterFind->second);

				if (child->_getPrefabLinkUUID().empty())
					todo.push(child);
			}
		}
	}
Example #4
0
	void ScriptGizmoManager::update()
	{
		GizmoManager::instance().clearGizmos();

		HSceneObject rootSO = SceneManager::instance().getRootNode();

		Stack<HSceneObject> todo;
		todo.push(rootSO);

		bool isParentSelected = false;
		UINT32 parentSelectedPopIdx = 0;
		
		Vector<HSceneObject> selectedObjects = Selection::instance().getSceneObjects();

		while (!todo.empty())
		{
			if (isParentSelected && parentSelectedPopIdx == (UINT32)todo.size())
			{
				isParentSelected = false;
			}

			HSceneObject curSO = todo.top();
			todo.pop();

			bool isSelected = std::count(selectedObjects.begin(), selectedObjects.end(), curSO) > 0;
			if (isSelected && !isParentSelected)
			{
				isParentSelected = true;
				parentSelectedPopIdx = (UINT32)todo.size();
			}

			const Vector<HComponent>& components = curSO->getComponents();
			for (auto& component : components)
			{
				if (rtti_is_of_type<ManagedComponent>(component.get()))
				{
					ManagedComponent* managedComponent = static_cast<ManagedComponent*>(component.get());

					auto iterFind = mGizmoDrawers.find(managedComponent->getManagedFullTypeName());
					if (iterFind != mGizmoDrawers.end())
					{
						UINT32 flags = iterFind->second.flags;

						bool drawGizmo = false;
						if (((flags & (UINT32)DrawGizmoFlags::Selected) != 0) && isSelected)
							drawGizmo = true;

						if (((flags & (UINT32)DrawGizmoFlags::ParentSelected) != 0) && isParentSelected)
							drawGizmo = true;

						if (((flags & (UINT32)DrawGizmoFlags::NotSelected) != 0) && !isSelected && !isParentSelected)
							drawGizmo = true;

						if (drawGizmo)
						{
							bool pickable = (flags & (UINT32)DrawGizmoFlags::Pickable) != 0;
							GizmoManager::instance().startGizmo(curSO);
							GizmoManager::instance().setPickable(pickable);

							void* params[1] = { managedComponent->getManagedInstance() };
							iterFind->second.drawGizmosMethod->invoke(nullptr, params);

							GizmoManager::instance().endGizmo();
						}
					}
				}
			}

			for (UINT32 i = 0; i < curSO->getNumChildren(); i++)
				todo.push(curSO->getChild(i));
		}
	}
	void CmdBreakPrefab::commit()
	{
		clear();

		if (mSceneObject == nullptr || mSceneObject.isDestroyed())
			return;

		HSceneObject rootObj = mSceneObject;

		while (rootObj != nullptr)
		{
			if (!rootObj->_getPrefabLinkUUID().empty())
				break;

			if (rootObj->getParent() != nullptr)
				rootObj = rootObj->getParent();
			else
				rootObj = nullptr;
		}

		if (rootObj != nullptr)
		{
			mPrefabRoot = rootObj;
			mPrefabLinkUUID = rootObj->_getPrefabLinkUUID();
			mPrefabDiff = rootObj->_getPrefabDiff();

			Stack<HSceneObject> todo;
			todo.push(mPrefabRoot);

			while (!todo.empty())
			{
				HSceneObject currentSO = todo.top();
				todo.pop();

				const Vector<HComponent>& components = currentSO->getComponents();
				for (auto& component : components)
				{
					UINT32 linkId = component->getLinkId();

					if (linkId != (UINT32)-1)
						mLinkIds[component->getInstanceId()] = linkId;

					mLinkIds[component->getInstanceId()] = component->getLinkId();
				}

				UINT32 numChildren = (UINT32)currentSO->getNumChildren();
				for (UINT32 i = 0; i < numChildren; i++)
				{
					HSceneObject child = currentSO->getChild(i);
					UINT32 linkId = child->getLinkId();

					if (linkId != (UINT32)-1)
						mLinkIds[child->getInstanceId()] = linkId;

					if (child->_getPrefabLinkUUID().empty())
						todo.push(child);
				}
			}
		}

		mSceneObject->breakPrefabLink();
	}
Example #6
0
	void PrefabDiff::applyDiff(const SPtr<PrefabObjectDiff>& diff, const HSceneObject& object)
	{
		if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Name) != 0)
			object->setName(diff->name);

		if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Position) != 0)
			object->setPosition(diff->position);

		if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Rotation) != 0)
			object->setRotation(diff->rotation);

		if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Scale) != 0)
			object->setScale(diff->scale);

		if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Active) != 0)
			object->setActive(diff->isActive);

		// Note: It is important to remove objects and components first, before adding them.
		//		 Some systems rely on the fact that applyDiff added components/objects are 
		//       always at the end.
		const Vector<HComponent>& components = object->getComponents();
		for (auto& removedId : diff->removedComponents)
		{
			for (auto component : components)
			{
				if (removedId == component->getLinkId())
				{
					component->destroy();
					break;
				}
			}
		}

		for (auto& removedId : diff->removedChildren)
		{
			UINT32 childCount = object->getNumChildren();
			for (UINT32 i = 0; i < childCount; i++)
			{
				HSceneObject child = object->getChild(i);
				if (removedId == child->getLinkId())
				{
					child->destroy();
					break;
				}
			}
		}

		for (auto& addedComponentData : diff->addedComponents)
		{
			BinarySerializer bs;
			SPtr<Component> component = std::static_pointer_cast<Component>(bs._decodeFromIntermediate(addedComponentData));

			object->addAndInitializeComponent(component);
		}

		for (auto& addedChildData : diff->addedChildren)
		{
			BinarySerializer bs;
			SPtr<SceneObject> sceneObject = std::static_pointer_cast<SceneObject>(bs._decodeFromIntermediate(addedChildData));
			sceneObject->setParent(object);

			if(object->isInstantiated())
				sceneObject->_instantiate();
		}

		for (auto& componentDiff : diff->componentDiffs)
		{
			for (auto& component : components)
			{
				if (componentDiff->id == component->getLinkId())
				{
					IDiff& diffHandler = component->getRTTI()->getDiffHandler();
					diffHandler.applyDiff(component.getInternalPtr(), componentDiff->data);
					break;
				}
			}
		}

		for (auto& childDiff : diff->childDiffs)
		{
			UINT32 childCount = object->getNumChildren();
			for (UINT32 i = 0; i < childCount; i++)
			{
				HSceneObject child = object->getChild(i);
				if (childDiff->id == child->getLinkId())
				{
					applyDiff(childDiff, child);
					break;
				}
			}
		}
	}
Example #7
0
	SPtr<PrefabObjectDiff> PrefabDiff::generateDiff(const HSceneObject& prefab, const HSceneObject& instance)
	{
		SPtr<PrefabObjectDiff> output;

		if (prefab->getName() != instance->getName())
		{
			if (output == nullptr)
				output = bs_shared_ptr_new<PrefabObjectDiff>();

			output->name = instance->getName();
			output->soFlags |= (UINT32)SceneObjectDiffFlags::Name;
		}

		if (prefab->getPosition() != instance->getPosition())
		{
			if (output == nullptr)
				output = bs_shared_ptr_new<PrefabObjectDiff>();

			output->position = instance->getPosition();
			output->soFlags |= (UINT32)SceneObjectDiffFlags::Position;
		}

		if (prefab->getRotation() != instance->getRotation())
		{
			if (output == nullptr)
				output = bs_shared_ptr_new<PrefabObjectDiff>();

			output->rotation = instance->getRotation();
			output->soFlags |= (UINT32)SceneObjectDiffFlags::Rotation;
		}

		if (prefab->getScale() != instance->getScale())
		{
			if (output == nullptr)
				output = bs_shared_ptr_new<PrefabObjectDiff>();

			output->scale = instance->getScale();
			output->soFlags |= (UINT32)SceneObjectDiffFlags::Scale;
		}

		if (prefab->getActive() != instance->getActive())
		{
			if (output == nullptr)
				output = bs_shared_ptr_new<PrefabObjectDiff>();

			output->isActive = instance->getActive();
			output->soFlags |= (UINT32)SceneObjectDiffFlags::Active;
		}

		UINT32 prefabChildCount = prefab->getNumChildren();
		UINT32 instanceChildCount = instance->getNumChildren();

		// Find modified and removed children
		for (UINT32 i = 0; i < prefabChildCount; i++)
		{
			HSceneObject prefabChild = prefab->getChild(i);

			SPtr<PrefabObjectDiff> childDiff;
			bool foundMatching = false;
			for (UINT32 j = 0; j < instanceChildCount; j++)
			{
				HSceneObject instanceChild = instance->getChild(j);

				if (prefabChild->getLinkId() == instanceChild->getLinkId())
				{
					if (instanceChild->mPrefabLinkUUID.empty())
						childDiff = generateDiff(prefabChild, instanceChild);

					foundMatching = true;
					break;
				}
			}

			if (foundMatching)
			{
				if (childDiff != nullptr)
				{
					if (output == nullptr)
						output = bs_shared_ptr_new<PrefabObjectDiff>();

					output->childDiffs.push_back(childDiff);
				}
			}
			else
			{
				if (output == nullptr)
					output = bs_shared_ptr_new<PrefabObjectDiff>();

				output->removedChildren.push_back(prefabChild->getLinkId());
			}	
		}

		// Find added children
		for (UINT32 i = 0; i < instanceChildCount; i++)
		{
			HSceneObject instanceChild = instance->getChild(i);

			if (instanceChild->hasFlag(SOF_DontSave))
				continue;

			bool foundMatching = false;
			if (instanceChild->getLinkId() != -1)
			{
				for (UINT32 j = 0; j < prefabChildCount; j++)
				{
					HSceneObject prefabChild = prefab->getChild(j);

					if (prefabChild->getLinkId() == instanceChild->getLinkId())
					{
						foundMatching = true;
						break;
					}
				}
			}

			if (!foundMatching)
			{
				BinarySerializer bs;
				SPtr<SerializedObject> obj = bs._encodeToIntermediate(instanceChild.get());

				if (output == nullptr)
					output = bs_shared_ptr_new<PrefabObjectDiff>();

				output->addedChildren.push_back(obj);
			}
		}

		const Vector<HComponent>& prefabComponents = prefab->getComponents();
		const Vector<HComponent>& instanceComponents = instance->getComponents();

		UINT32 prefabComponentCount = (UINT32)prefabComponents.size();
		UINT32 instanceComponentCount = (UINT32)instanceComponents.size();

		// Find modified and removed components
		for (UINT32 i = 0; i < prefabComponentCount; i++)
		{
			HComponent prefabComponent = prefabComponents[i];

			SPtr<PrefabComponentDiff> childDiff;
			bool foundMatching = false;
			for (UINT32 j = 0; j < instanceComponentCount; j++)
			{
				HComponent instanceComponent = instanceComponents[j];

				if (prefabComponent->getLinkId() == instanceComponent->getLinkId())
				{
					BinarySerializer bs;
					SPtr<SerializedObject> encodedPrefab = bs._encodeToIntermediate(prefabComponent.get());
					SPtr<SerializedObject> encodedInstance = bs._encodeToIntermediate(instanceComponent.get());

					IDiff& diffHandler = prefabComponent->getRTTI()->getDiffHandler();
					SPtr<SerializedObject> diff = diffHandler.generateDiff(encodedPrefab, encodedInstance);

					if (diff != nullptr)
					{
						childDiff = bs_shared_ptr_new<PrefabComponentDiff>();
						childDiff->id = prefabComponent->getLinkId();
						childDiff->data = diff;
					}

					foundMatching = true;
					break;
				}
			}

			if (foundMatching)
			{
				if (childDiff != nullptr)
				{
					if (output == nullptr)
						output = bs_shared_ptr_new<PrefabObjectDiff>();

					output->componentDiffs.push_back(childDiff);
				}
			}
			else
			{
				if (output == nullptr)
					output = bs_shared_ptr_new<PrefabObjectDiff>();

				output->removedComponents.push_back(prefabComponent->getLinkId());
			}
		}

		// Find added components
		for (UINT32 i = 0; i < instanceComponentCount; i++)
		{
			HComponent instanceComponent = instanceComponents[i];

			bool foundMatching = false;
			if (instanceComponent->getLinkId() != -1)
			{
				for (UINT32 j = 0; j < prefabComponentCount; j++)
				{
					HComponent prefabComponent = prefabComponents[j];

					if (prefabComponent->getLinkId() == instanceComponent->getLinkId())
					{
						foundMatching = true;
						break;
					}
				}
			}

			if (!foundMatching)
			{
				BinarySerializer bs;
				SPtr<SerializedObject> obj = bs._encodeToIntermediate(instanceComponent.get());

				if (output == nullptr)
					output = bs_shared_ptr_new<PrefabObjectDiff>();

				output->addedComponents.push_back(obj);
			}
		}

		if (output != nullptr)
			output->id = instance->getLinkId();

		return output;
	}