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); } } }
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(); }
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; } } } }
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; }