Fix editor scene persistence and XC scene workflow
This commit is contained in:
77
engine/src/Components/CameraComponent.cpp
Normal file
77
engine/src/Components/CameraComponent.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "Components/CameraComponent.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
|
||||
void CameraComponent::SetFieldOfView(float value) {
|
||||
m_fieldOfView = std::clamp(value, 1.0f, 179.0f);
|
||||
}
|
||||
|
||||
void CameraComponent::SetOrthographicSize(float value) {
|
||||
m_orthographicSize = std::max(0.001f, value);
|
||||
}
|
||||
|
||||
void CameraComponent::SetNearClipPlane(float value) {
|
||||
m_nearClipPlane = std::max(0.001f, value);
|
||||
if (m_farClipPlane <= m_nearClipPlane) {
|
||||
m_farClipPlane = m_nearClipPlane + 0.001f;
|
||||
}
|
||||
}
|
||||
|
||||
void CameraComponent::SetFarClipPlane(float value) {
|
||||
m_farClipPlane = std::max(m_nearClipPlane + 0.001f, value);
|
||||
}
|
||||
|
||||
void CameraComponent::Serialize(std::ostream& os) const {
|
||||
os << "projection=" << static_cast<int>(m_projectionType) << ";";
|
||||
os << "fov=" << m_fieldOfView << ";";
|
||||
os << "orthoSize=" << m_orthographicSize << ";";
|
||||
os << "near=" << m_nearClipPlane << ";";
|
||||
os << "far=" << m_farClipPlane << ";";
|
||||
os << "depth=" << m_depth << ";";
|
||||
os << "primary=" << (m_primary ? 1 : 0) << ";";
|
||||
os << "clearColor=" << m_clearColor.r << "," << m_clearColor.g << "," << m_clearColor.b << "," << m_clearColor.a << ";";
|
||||
}
|
||||
|
||||
void CameraComponent::Deserialize(std::istream& is) {
|
||||
std::string token;
|
||||
while (std::getline(is, token, ';')) {
|
||||
if (token.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const size_t eqPos = token.find('=');
|
||||
if (eqPos == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string key = token.substr(0, eqPos);
|
||||
std::string value = token.substr(eqPos + 1);
|
||||
|
||||
if (key == "projection") {
|
||||
m_projectionType = static_cast<CameraProjectionType>(std::stoi(value));
|
||||
} else if (key == "fov") {
|
||||
SetFieldOfView(std::stof(value));
|
||||
} else if (key == "orthoSize") {
|
||||
SetOrthographicSize(std::stof(value));
|
||||
} else if (key == "near") {
|
||||
SetNearClipPlane(std::stof(value));
|
||||
} else if (key == "far") {
|
||||
SetFarClipPlane(std::stof(value));
|
||||
} else if (key == "depth") {
|
||||
m_depth = std::stof(value);
|
||||
} else if (key == "primary") {
|
||||
m_primary = (std::stoi(value) != 0);
|
||||
} else if (key == "clearColor") {
|
||||
std::replace(value.begin(), value.end(), ',', ' ');
|
||||
std::istringstream ss(value);
|
||||
ss >> m_clearColor.r >> m_clearColor.g >> m_clearColor.b >> m_clearColor.a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Components
|
||||
} // namespace XCEngine
|
||||
@@ -48,32 +48,30 @@ void GameObject::SetParent(GameObject* parent) {
|
||||
}
|
||||
|
||||
void GameObject::SetParent(GameObject* parent, bool worldPositionStays) {
|
||||
if (m_parent == parent) {
|
||||
if (m_parent == parent || parent == this) {
|
||||
return;
|
||||
}
|
||||
|
||||
Math::Vector3 worldPos = worldPositionStays ? GetTransform()->GetPosition() : GetTransform()->GetLocalPosition();
|
||||
Math::Quaternion worldRot = worldPositionStays ? GetTransform()->GetRotation() : GetTransform()->GetLocalRotation();
|
||||
Math::Vector3 worldScale = worldPositionStays ? GetTransform()->GetScale() : GetTransform()->GetLocalScale();
|
||||
|
||||
if (m_parent) {
|
||||
auto& siblings = m_parent->m_children;
|
||||
siblings.erase(std::remove(siblings.begin(), siblings.end(), this), siblings.end());
|
||||
} else if (m_scene) {
|
||||
auto& roots = m_scene->m_rootGameObjects;
|
||||
roots.erase(std::remove(roots.begin(), roots.end(), m_id), roots.end());
|
||||
}
|
||||
|
||||
m_parent = parent;
|
||||
|
||||
if (m_parent) {
|
||||
m_parent->m_children.push_back(this);
|
||||
} else if (m_scene) {
|
||||
auto& roots = m_scene->m_rootGameObjects;
|
||||
if (std::find(roots.begin(), roots.end(), m_id) == roots.end()) {
|
||||
roots.push_back(m_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (worldPositionStays) {
|
||||
GetTransform()->SetPosition(worldPos);
|
||||
GetTransform()->SetRotation(worldRot);
|
||||
GetTransform()->SetScale(worldScale);
|
||||
}
|
||||
|
||||
GetTransform()->SetDirty();
|
||||
GetTransform()->SetParent(parent ? parent->GetTransform() : nullptr, worldPositionStays);
|
||||
}
|
||||
|
||||
GameObject* GameObject::GetChild(size_t index) const {
|
||||
@@ -88,32 +86,17 @@ std::vector<GameObject*> GameObject::GetChildren() const {
|
||||
}
|
||||
|
||||
void GameObject::DetachChildren() {
|
||||
for (auto* child : m_children) {
|
||||
auto children = m_children;
|
||||
for (auto* child : children) {
|
||||
if (child) {
|
||||
child->m_parent = nullptr;
|
||||
child->SetParent(nullptr, true);
|
||||
}
|
||||
}
|
||||
m_children.clear();
|
||||
}
|
||||
|
||||
void GameObject::DetachFromParent() {
|
||||
if (m_parent) {
|
||||
Math::Vector3 worldPos = GetTransform()->GetPosition();
|
||||
Math::Quaternion worldRot = GetTransform()->GetRotation();
|
||||
Math::Vector3 worldScale = GetTransform()->GetScale();
|
||||
|
||||
auto& siblings = m_parent->m_children;
|
||||
siblings.erase(std::remove(siblings.begin(), siblings.end(), this), siblings.end());
|
||||
m_parent = nullptr;
|
||||
|
||||
if (m_scene) {
|
||||
m_scene->m_rootGameObjects.push_back(m_id);
|
||||
}
|
||||
|
||||
GetTransform()->SetPosition(worldPos);
|
||||
GetTransform()->SetRotation(worldRot);
|
||||
GetTransform()->SetScale(worldScale);
|
||||
GetTransform()->SetDirty();
|
||||
SetParent(nullptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,4 +243,4 @@ void GameObject::Deserialize(std::istream& is) {
|
||||
}
|
||||
|
||||
} // namespace Components
|
||||
} // namespace XCEngine
|
||||
} // namespace XCEngine
|
||||
|
||||
64
engine/src/Components/LightComponent.cpp
Normal file
64
engine/src/Components/LightComponent.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "Components/LightComponent.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
|
||||
void LightComponent::SetIntensity(float value) {
|
||||
m_intensity = std::max(0.0f, value);
|
||||
}
|
||||
|
||||
void LightComponent::SetRange(float value) {
|
||||
m_range = std::max(0.001f, value);
|
||||
}
|
||||
|
||||
void LightComponent::SetSpotAngle(float value) {
|
||||
m_spotAngle = std::clamp(value, 1.0f, 179.0f);
|
||||
}
|
||||
|
||||
void LightComponent::Serialize(std::ostream& os) const {
|
||||
os << "type=" << static_cast<int>(m_lightType) << ";";
|
||||
os << "color=" << m_color.r << "," << m_color.g << "," << m_color.b << "," << m_color.a << ";";
|
||||
os << "intensity=" << m_intensity << ";";
|
||||
os << "range=" << m_range << ";";
|
||||
os << "spotAngle=" << m_spotAngle << ";";
|
||||
os << "shadows=" << (m_castsShadows ? 1 : 0) << ";";
|
||||
}
|
||||
|
||||
void LightComponent::Deserialize(std::istream& is) {
|
||||
std::string token;
|
||||
while (std::getline(is, token, ';')) {
|
||||
if (token.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const size_t eqPos = token.find('=');
|
||||
if (eqPos == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string key = token.substr(0, eqPos);
|
||||
std::string value = token.substr(eqPos + 1);
|
||||
|
||||
if (key == "type") {
|
||||
m_lightType = static_cast<LightType>(std::stoi(value));
|
||||
} else if (key == "color") {
|
||||
std::replace(value.begin(), value.end(), ',', ' ');
|
||||
std::istringstream ss(value);
|
||||
ss >> m_color.r >> m_color.g >> m_color.b >> m_color.a;
|
||||
} else if (key == "intensity") {
|
||||
SetIntensity(std::stof(value));
|
||||
} else if (key == "range") {
|
||||
SetRange(std::stof(value));
|
||||
} else if (key == "spotAngle") {
|
||||
SetSpotAngle(std::stof(value));
|
||||
} else if (key == "shadows") {
|
||||
m_castsShadows = (std::stoi(value) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Components
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user