Add Nahida model import and preview pipeline

This commit is contained in:
2026-04-11 20:16:49 +08:00
parent 8f71f99de4
commit 030230eb1f
87 changed files with 7245 additions and 117 deletions

View File

@@ -22,6 +22,7 @@ public:
const Resources::AssetRef& GetMeshAssetRef() const { return m_meshRef; }
void SetMeshPath(const std::string& meshPath);
void SetMeshAssetRef(const Resources::AssetRef& meshRef);
void SetMesh(const Resources::ResourceHandle<Resources::Mesh>& mesh);
void SetMesh(Resources::Mesh* mesh);
void ClearMesh();

View File

@@ -25,6 +25,7 @@ public:
const std::vector<Resources::AssetRef>& GetMaterialAssetRefs() const { return m_materialRefs; }
void SetMaterialPath(size_t index, const std::string& materialPath);
void SetMaterialAssetRef(size_t index, const Resources::AssetRef& materialRef);
void SetMaterial(size_t index, const Resources::ResourceHandle<Resources::Material>& material);
void SetMaterial(size_t index, Resources::Material* material);
void SetMaterials(const std::vector<Resources::ResourceHandle<Resources::Material>>& materials);

View File

@@ -0,0 +1,105 @@
#pragma once
#include <XCEngine/Core/Asset/AssetGUID.h>
#include <XCEngine/Core/Asset/ResourceTypes.h>
#include <XCEngine/Core/Containers/Array.h>
#include <XCEngine/Core/Containers/String.h>
#include <XCEngine/Core/Types.h>
namespace XCEngine {
namespace Resources {
constexpr Core::uint32 kArtifactContainerSchemaVersion = 1;
enum class ArtifactContainerCompression : Core::uint32 {
None = 0
};
struct ArtifactContainerEntry {
Containers::String name;
ResourceType resourceType = ResourceType::Unknown;
LocalID localID = kInvalidLocalID;
Core::uint32 flags = 0;
ArtifactContainerCompression compression = ArtifactContainerCompression::None;
Containers::Array<Core::uint8> payload;
};
struct ArtifactContainerEntryView {
Containers::String name;
ResourceType resourceType = ResourceType::Unknown;
LocalID localID = kInvalidLocalID;
Core::uint32 flags = 0;
ArtifactContainerCompression compression = ArtifactContainerCompression::None;
Core::uint64 payloadOffset = 0;
Core::uint64 payloadSize = 0;
};
class ArtifactContainerWriter {
public:
void Clear();
void AddEntry(const ArtifactContainerEntry& entry);
void AddEntry(ArtifactContainerEntry&& entry);
const Containers::Array<ArtifactContainerEntry>& GetEntries() const { return m_entries; }
bool WriteToFile(const Containers::String& path,
Containers::String* outErrorMessage = nullptr) const;
private:
Containers::Array<ArtifactContainerEntry> m_entries;
};
class ArtifactContainerReader {
public:
bool Open(const Containers::String& path,
Containers::String* outErrorMessage = nullptr);
void Close();
bool IsOpen() const { return !m_path.Empty(); }
const Containers::String& GetPath() const { return m_path; }
const Containers::Array<ArtifactContainerEntryView>& GetEntries() const { return m_entries; }
Core::uint32 GetEntryCount() const { return static_cast<Core::uint32>(m_entries.Size()); }
const ArtifactContainerEntryView* FindEntryByName(const Containers::String& name) const;
const ArtifactContainerEntryView* FindEntry(ResourceType resourceType,
LocalID localID) const;
bool ReadEntryPayload(const ArtifactContainerEntryView& entry,
Containers::Array<Core::uint8>& outPayload,
Containers::String* outErrorMessage = nullptr) const;
bool ReadEntryPayload(const Containers::String& name,
Containers::Array<Core::uint8>& outPayload,
Containers::String* outErrorMessage = nullptr) const;
private:
Containers::String m_path;
Containers::Array<ArtifactContainerEntryView> m_entries;
Core::uint64 m_payloadStart = 0;
Core::uint64 m_payloadSize = 0;
};
bool WriteArtifactContainer(const Containers::String& path,
const Containers::Array<ArtifactContainerEntry>& entries,
Containers::String* outErrorMessage = nullptr);
bool IsArtifactContainerFile(const Containers::String& path);
Containers::String BuildArtifactContainerEntryPath(const Containers::String& containerPath,
const Containers::String& entryName);
bool TryParseArtifactContainerEntryPath(const Containers::String& path,
Containers::String& outContainerPath,
Containers::String& outEntryName);
bool ReadArtifactContainerEntryPayload(const Containers::String& containerPath,
const Containers::String& entryName,
ResourceType expectedType,
Containers::Array<Core::uint8>& outPayload,
Containers::String* outErrorMessage = nullptr);
bool ReadArtifactContainerPayloadByPath(const Containers::String& path,
ResourceType expectedType,
Containers::Array<Core::uint8>& outPayload,
Containers::String* outErrorMessage = nullptr);
bool ReadArtifactContainerMainEntryPayload(const Containers::String& path,
ResourceType expectedType,
Containers::Array<Core::uint8>& outPayload,
Containers::String* outErrorMessage = nullptr);
} // namespace Resources
} // namespace XCEngine

View File

@@ -175,6 +175,7 @@ private:
Core::uint64 materialVersion = 0;
RHI::RHIResourceView* baseColorTextureView = nullptr;
RHI::RHIResourceView* shadowMapTextureView = nullptr;
std::vector<RHI::RHIResourceView*> materialTextureViews;
};
struct ResolvedShaderPass {
@@ -305,6 +306,9 @@ private:
const Resources::Texture* ResolveTexture(const Resources::Material* material) const;
RHI::RHIResourceView* ResolveTextureView(const Resources::Texture* texture);
RHI::RHIResourceView* ResolveTextureView(const VisibleRenderItem& visibleItem);
RHI::RHIResourceView* ResolveMaterialTextureView(
const Resources::Material* material,
const BuiltinPassResourceBindingDesc& binding);
static LightingConstants BuildLightingConstants(const RenderLightingData& lightingData);
static AdditionalLightConstants BuildAdditionalLightConstants(const RenderAdditionalLightData& lightData);
bool HasSkybox(const RenderSceneData& sceneData) const;

View File

@@ -5,6 +5,7 @@
#include <XCEngine/Core/Math/Bounds.h>
#include <XCEngine/Core/Math/Vector2.h>
#include <XCEngine/Core/Math/Vector3.h>
#include <XCEngine/Core/Math/Vector4.h>
#include <XCEngine/Core/Types.h>
namespace XCEngine {
@@ -38,6 +39,8 @@ struct StaticMeshVertex {
Math::Vector3 tangent = Math::Vector3::Zero();
Math::Vector3 bitangent = Math::Vector3::Zero();
Math::Vector2 uv0 = Math::Vector2::Zero();
Math::Vector2 uv1 = Math::Vector2::Zero();
Math::Vector4 color = Math::Vector4::One();
};
struct MeshSection {

View File

@@ -0,0 +1,37 @@
#pragma once
#include <XCEngine/Core/Asset/AssetRef.h>
#include <XCEngine/Core/Containers/String.h>
#include <XCEngine/Resources/Model/Model.h>
#include <vector>
namespace XCEngine {
namespace Components {
class GameObject;
class Scene;
}
struct ModelSceneInstantiationResult {
Components::GameObject* rootObject = nullptr;
std::vector<Components::GameObject*> nodeObjects;
std::vector<Components::GameObject*> meshObjects;
};
bool InstantiateModelHierarchy(
Components::Scene& scene,
const Resources::Model& model,
const Resources::AssetRef& modelAssetRef,
Components::GameObject* parent = nullptr,
ModelSceneInstantiationResult* outResult = nullptr,
Containers::String* outErrorMessage = nullptr);
bool InstantiateModelHierarchy(
Components::Scene& scene,
const Containers::String& modelPath,
Components::GameObject* parent = nullptr,
ModelSceneInstantiationResult* outResult = nullptr,
Containers::String* outErrorMessage = nullptr);
} // namespace XCEngine