Formalize material-driven panoramic skybox path
This commit is contained in:
@@ -1,11 +1,49 @@
|
||||
#include "Components/CameraComponent.h"
|
||||
|
||||
#include "Core/Asset/ResourceManager.h"
|
||||
#include "Resources/Material/Material.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string ToStdString(const Containers::String& value) {
|
||||
return std::string(value.CStr());
|
||||
}
|
||||
|
||||
bool HasVirtualPathScheme(const std::string& path) {
|
||||
return path.find("://") != std::string::npos;
|
||||
}
|
||||
|
||||
std::string EncodeAssetRef(const Resources::AssetRef& assetRef) {
|
||||
if (!assetRef.IsValid()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return ToStdString(assetRef.assetGuid.ToString()) + "," +
|
||||
std::to_string(assetRef.localID) + "," +
|
||||
std::to_string(static_cast<int>(assetRef.resourceType));
|
||||
}
|
||||
|
||||
bool TryDecodeAssetRef(const std::string& value, Resources::AssetRef& outRef) {
|
||||
const size_t firstComma = value.find(',');
|
||||
const size_t secondComma = firstComma == std::string::npos ? std::string::npos : value.find(',', firstComma + 1);
|
||||
if (firstComma == std::string::npos || secondComma == std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outRef.assetGuid = Resources::AssetGUID::ParseOrDefault(Containers::String(value.substr(0, firstComma).c_str()));
|
||||
outRef.localID = static_cast<Resources::LocalID>(std::stoull(value.substr(firstComma + 1, secondComma - firstComma - 1)));
|
||||
outRef.resourceType = static_cast<Resources::ResourceType>(std::stoi(value.substr(secondComma + 1)));
|
||||
return outRef.IsValid();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void CameraComponent::SetFieldOfView(float value) {
|
||||
m_fieldOfView = std::clamp(value, 1.0f, 179.0f);
|
||||
}
|
||||
@@ -35,7 +73,64 @@ void CameraComponent::SetViewportRect(const Math::Rect& value) {
|
||||
m_viewportRect = Math::Rect(x, y, right - x, bottom - y);
|
||||
}
|
||||
|
||||
void CameraComponent::SetSkyboxMaterialPath(const std::string& materialPath) {
|
||||
m_skyboxMaterialPath = materialPath;
|
||||
m_skyboxMaterialRef.Reset();
|
||||
|
||||
if (materialPath.empty()) {
|
||||
m_skyboxMaterial.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
m_skyboxMaterial = Resources::ResourceManager::Get().Load<Resources::Material>(materialPath.c_str());
|
||||
if (!Resources::ResourceManager::Get().TryGetAssetRef(
|
||||
materialPath.c_str(),
|
||||
Resources::ResourceType::Material,
|
||||
m_skyboxMaterialRef)) {
|
||||
m_skyboxMaterialRef.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void CameraComponent::SetSkyboxMaterial(const Resources::ResourceHandle<Resources::Material>& material) {
|
||||
m_skyboxMaterial = material;
|
||||
m_skyboxMaterialPath =
|
||||
material.Get() != nullptr
|
||||
? ToStdString(material->GetPath())
|
||||
: std::string();
|
||||
|
||||
if (m_skyboxMaterialPath.empty() ||
|
||||
!Resources::ResourceManager::Get().TryGetAssetRef(
|
||||
m_skyboxMaterialPath.c_str(),
|
||||
Resources::ResourceType::Material,
|
||||
m_skyboxMaterialRef)) {
|
||||
m_skyboxMaterialRef.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void CameraComponent::SetSkyboxMaterial(Resources::Material* material) {
|
||||
SetSkyboxMaterial(Resources::ResourceHandle<Resources::Material>(material));
|
||||
}
|
||||
|
||||
void CameraComponent::Serialize(std::ostream& os) const {
|
||||
Resources::AssetRef serializedSkyboxMaterialRef = m_skyboxMaterialRef;
|
||||
std::string serializedSkyboxMaterialPath = m_skyboxMaterialPath;
|
||||
if (serializedSkyboxMaterialPath.empty() && m_skyboxMaterial.Get() != nullptr) {
|
||||
serializedSkyboxMaterialPath = ToStdString(m_skyboxMaterial->GetPath());
|
||||
}
|
||||
|
||||
if (!serializedSkyboxMaterialRef.IsValid() &&
|
||||
!serializedSkyboxMaterialPath.empty() &&
|
||||
!HasVirtualPathScheme(serializedSkyboxMaterialPath) &&
|
||||
Resources::ResourceManager::Get().TryGetAssetRef(
|
||||
serializedSkyboxMaterialPath.c_str(),
|
||||
Resources::ResourceType::Material,
|
||||
serializedSkyboxMaterialRef)) {
|
||||
}
|
||||
|
||||
if (serializedSkyboxMaterialRef.IsValid() || !HasVirtualPathScheme(serializedSkyboxMaterialPath)) {
|
||||
serializedSkyboxMaterialPath.clear();
|
||||
}
|
||||
|
||||
os << "projection=" << static_cast<int>(m_projectionType) << ";";
|
||||
os << "fov=" << m_fieldOfView << ";";
|
||||
os << "orthoSize=" << m_orthographicSize << ";";
|
||||
@@ -49,13 +144,21 @@ void CameraComponent::Serialize(std::ostream& os) const {
|
||||
os << "viewportRect=" << m_viewportRect.x << "," << m_viewportRect.y << "," << m_viewportRect.width << "," << m_viewportRect.height << ";";
|
||||
os << "clearColor=" << m_clearColor.r << "," << m_clearColor.g << "," << m_clearColor.b << "," << m_clearColor.a << ";";
|
||||
os << "skyboxEnabled=" << (m_skyboxEnabled ? 1 : 0) << ";";
|
||||
os << "skyboxMaterialPath=" << serializedSkyboxMaterialPath << ";";
|
||||
os << "skyboxMaterialRef=" << EncodeAssetRef(serializedSkyboxMaterialRef) << ";";
|
||||
os << "skyboxTopColor=" << m_skyboxTopColor.r << "," << m_skyboxTopColor.g << "," << m_skyboxTopColor.b << "," << m_skyboxTopColor.a << ";";
|
||||
os << "skyboxHorizonColor=" << m_skyboxHorizonColor.r << "," << m_skyboxHorizonColor.g << "," << m_skyboxHorizonColor.b << "," << m_skyboxHorizonColor.a << ";";
|
||||
os << "skyboxBottomColor=" << m_skyboxBottomColor.r << "," << m_skyboxBottomColor.g << "," << m_skyboxBottomColor.b << "," << m_skyboxBottomColor.a << ";";
|
||||
}
|
||||
|
||||
void CameraComponent::Deserialize(std::istream& is) {
|
||||
m_skyboxMaterial.Reset();
|
||||
m_skyboxMaterialPath.clear();
|
||||
m_skyboxMaterialRef.Reset();
|
||||
|
||||
std::string token;
|
||||
std::string pendingSkyboxMaterialPath;
|
||||
Resources::AssetRef pendingSkyboxMaterialRef;
|
||||
while (std::getline(is, token, ';')) {
|
||||
if (token.empty()) {
|
||||
continue;
|
||||
@@ -101,6 +204,10 @@ void CameraComponent::Deserialize(std::istream& is) {
|
||||
ss >> m_clearColor.r >> m_clearColor.g >> m_clearColor.b >> m_clearColor.a;
|
||||
} else if (key == "skyboxEnabled") {
|
||||
m_skyboxEnabled = (std::stoi(value) != 0);
|
||||
} else if (key == "skyboxMaterialPath") {
|
||||
pendingSkyboxMaterialPath = value;
|
||||
} else if (key == "skyboxMaterialRef") {
|
||||
TryDecodeAssetRef(value, pendingSkyboxMaterialRef);
|
||||
} else if (key == "skyboxTopColor") {
|
||||
std::replace(value.begin(), value.end(), ',', ' ');
|
||||
std::istringstream ss(value);
|
||||
@@ -115,6 +222,28 @@ void CameraComponent::Deserialize(std::istream& is) {
|
||||
ss >> m_skyboxBottomColor.r >> m_skyboxBottomColor.g >> m_skyboxBottomColor.b >> m_skyboxBottomColor.a;
|
||||
}
|
||||
}
|
||||
|
||||
if (pendingSkyboxMaterialRef.IsValid()) {
|
||||
m_skyboxMaterialRef = pendingSkyboxMaterialRef;
|
||||
m_skyboxMaterial = Resources::ResourceManager::Get().Load<Resources::Material>(pendingSkyboxMaterialRef);
|
||||
if (m_skyboxMaterial.Get() != nullptr) {
|
||||
m_skyboxMaterialPath = ToStdString(m_skyboxMaterial->GetPath());
|
||||
} else {
|
||||
Containers::String resolvedPath;
|
||||
if (Resources::ResourceManager::Get().TryResolveAssetPath(pendingSkyboxMaterialRef, resolvedPath)) {
|
||||
SetSkyboxMaterialPath(ToStdString(resolvedPath));
|
||||
m_skyboxMaterialRef = pendingSkyboxMaterialRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_skyboxMaterial.Get() == nullptr && !pendingSkyboxMaterialPath.empty()) {
|
||||
SetSkyboxMaterialPath(pendingSkyboxMaterialPath);
|
||||
}
|
||||
|
||||
if (m_skyboxMaterial.Get() == nullptr && pendingSkyboxMaterialRef.IsValid()) {
|
||||
m_skyboxMaterialRef = pendingSkyboxMaterialRef;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Components
|
||||
|
||||
Reference in New Issue
Block a user