#include "Components/MeshRendererComponent.h" #include "Core/Asset/ResourceManager.h" #include namespace XCEngine { namespace Components { namespace { std::string ToStdString(const Containers::String& value) { return std::string(value.CStr()); } std::vector SplitMaterialPaths(const std::string& value) { std::vector paths; std::stringstream stream(value); std::string item; while (std::getline(stream, item, '|')) { paths.push_back(item); } if (value.empty()) { paths.clear(); } return paths; } } // namespace Resources::Material* MeshRendererComponent::GetMaterial(size_t index) const { return index < m_materials.size() ? m_materials[index].Get() : nullptr; } const Resources::ResourceHandle& MeshRendererComponent::GetMaterialHandle(size_t index) const { static const Resources::ResourceHandle kNullHandle; return index < m_materials.size() ? m_materials[index] : kNullHandle; } void MeshRendererComponent::SetMaterial(size_t index, const Resources::ResourceHandle& material) { EnsureMaterialSlot(index); m_materials[index] = material; m_materialPaths[index] = MaterialPathFromHandle(material); } void MeshRendererComponent::SetMaterial(size_t index, Resources::Material* material) { SetMaterial(index, Resources::ResourceHandle(material)); } void MeshRendererComponent::SetMaterials(const std::vector>& materials) { m_materials = materials; m_materialPaths.resize(materials.size()); for (size_t i = 0; i < materials.size(); ++i) { m_materialPaths[i] = MaterialPathFromHandle(materials[i]); } } void MeshRendererComponent::ClearMaterials() { m_materials.clear(); m_materialPaths.clear(); } void MeshRendererComponent::Serialize(std::ostream& os) const { os << "materials="; for (size_t i = 0; i < m_materialPaths.size(); ++i) { if (i > 0) { os << "|"; } os << m_materialPaths[i]; } os << ";"; os << "castShadows=" << (m_castShadows ? 1 : 0) << ";"; os << "receiveShadows=" << (m_receiveShadows ? 1 : 0) << ";"; os << "renderLayer=" << m_renderLayer << ";"; } void MeshRendererComponent::Deserialize(std::istream& is) { ClearMaterials(); m_castShadows = true; m_receiveShadows = true; m_renderLayer = 0; 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); const std::string value = token.substr(eqPos + 1); if (key == "materials") { m_materialPaths = SplitMaterialPaths(value); m_materials.resize(m_materialPaths.size()); for (size_t i = 0; i < m_materialPaths.size(); ++i) { if (!m_materialPaths[i].empty()) { m_materials[i] = Resources::ResourceManager::Get().Load(m_materialPaths[i].c_str()); } } } else if (key == "castShadows") { m_castShadows = (std::stoi(value) != 0); } else if (key == "receiveShadows") { m_receiveShadows = (std::stoi(value) != 0); } else if (key == "renderLayer") { m_renderLayer = static_cast(std::stoul(value)); } } } void MeshRendererComponent::EnsureMaterialSlot(size_t index) { if (index >= m_materials.size()) { m_materials.resize(index + 1); m_materialPaths.resize(index + 1); } } std::string MeshRendererComponent::MaterialPathFromHandle(const Resources::ResourceHandle& material) { return material.Get() != nullptr ? ToStdString(material->GetPath()) : std::string(); } } // namespace Components } // namespace XCEngine