Add VolumeField NanoVDB asset pipeline
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
#include <XCEngine/Resources/Shader/ShaderLoader.h>
|
||||
#include <XCEngine/Resources/Texture/TextureLoader.h>
|
||||
#include <XCEngine/Resources/UI/UIDocumentCompiler.h>
|
||||
#include <XCEngine/Resources/Volume/VolumeField.h>
|
||||
#include <XCEngine/Resources/Volume/VolumeFieldLoader.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
@@ -366,6 +368,27 @@ bool WriteTextureArtifactFile(const fs::path& artifactPath, const Texture& textu
|
||||
return static_cast<bool>(output);
|
||||
}
|
||||
|
||||
bool WriteVolumeFieldArtifactFile(const fs::path& artifactPath, const VolumeField& volumeField) {
|
||||
std::ofstream output(artifactPath, std::ios::binary | std::ios::trunc);
|
||||
if (!output.is_open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VolumeFieldArtifactHeader header;
|
||||
header.storageKind = static_cast<Core::uint32>(volumeField.GetStorageKind());
|
||||
header.boundsMin = volumeField.GetBounds().GetMin();
|
||||
header.boundsMax = volumeField.GetBounds().GetMax();
|
||||
header.voxelSize = volumeField.GetVoxelSize();
|
||||
header.payloadSize = static_cast<Core::uint64>(volumeField.GetPayloadSize());
|
||||
|
||||
output.write(reinterpret_cast<const char*>(&header), sizeof(header));
|
||||
if (volumeField.GetPayloadSize() > 0) {
|
||||
output.write(static_cast<const char*>(volumeField.GetPayloadData()), volumeField.GetPayloadSize());
|
||||
}
|
||||
|
||||
return static_cast<bool>(output);
|
||||
}
|
||||
|
||||
std::vector<MaterialProperty> GatherMaterialProperties(const Material& material) {
|
||||
return material.GetProperties();
|
||||
}
|
||||
@@ -1258,6 +1281,7 @@ bool AssetDatabase::EnsureMetaForPath(const fs::path& sourcePath,
|
||||
|
||||
const fs::path metaPath(sourcePath.string() + ".meta");
|
||||
outRecord.metaPath = NormalizeRelativePath(metaPath);
|
||||
const Containers::String expectedImporterName = GetImporterNameForPath(relativePath, isFolder);
|
||||
|
||||
bool shouldRewriteMeta = false;
|
||||
if (!fs::exists(metaPath) || !ReadMetaFile(metaPath, outRecord) || !outRecord.guid.IsValid()) {
|
||||
@@ -1266,6 +1290,10 @@ bool AssetDatabase::EnsureMetaForPath(const fs::path& sourcePath,
|
||||
}
|
||||
shouldRewriteMeta = true;
|
||||
}
|
||||
if (outRecord.importerName != expectedImporterName) {
|
||||
outRecord.importerName = expectedImporterName;
|
||||
shouldRewriteMeta = true;
|
||||
}
|
||||
if (outRecord.importerVersion != kCurrentImporterVersion) {
|
||||
outRecord.importerVersion = kCurrentImporterVersion;
|
||||
shouldRewriteMeta = true;
|
||||
@@ -1409,6 +1437,9 @@ Containers::String AssetDatabase::GetImporterNameForPath(const Containers::Strin
|
||||
if (ext == ".shader") {
|
||||
return Containers::String("ShaderImporter");
|
||||
}
|
||||
if (ext == ".nvdb") {
|
||||
return Containers::String("VolumeFieldImporter");
|
||||
}
|
||||
if (ext == ".mat" || ext == ".material" || ext == ".json") {
|
||||
return Containers::String("MaterialImporter");
|
||||
}
|
||||
@@ -1437,6 +1468,9 @@ ResourceType AssetDatabase::GetPrimaryResourceTypeForImporter(const Containers::
|
||||
if (importerName == "ShaderImporter") {
|
||||
return ResourceType::Shader;
|
||||
}
|
||||
if (importerName == "VolumeFieldImporter") {
|
||||
return ResourceType::VolumeField;
|
||||
}
|
||||
return ResourceType::Unknown;
|
||||
}
|
||||
|
||||
@@ -1487,6 +1521,8 @@ bool AssetDatabase::ImportAsset(const SourceAssetRecord& sourceRecord,
|
||||
return ImportModelAsset(sourceRecord, outRecord);
|
||||
case ResourceType::Shader:
|
||||
return ImportShaderAsset(sourceRecord, outRecord);
|
||||
case ResourceType::VolumeField:
|
||||
return ImportVolumeFieldAsset(sourceRecord, outRecord);
|
||||
default:
|
||||
SetLastErrorMessage(Containers::String("No importer available for asset: ") + sourceRecord.relativePath);
|
||||
return false;
|
||||
@@ -1875,6 +1911,54 @@ bool AssetDatabase::ImportShaderAsset(const SourceAssetRecord& sourceRecord,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetDatabase::ImportVolumeFieldAsset(const SourceAssetRecord& sourceRecord,
|
||||
ArtifactRecord& outRecord) {
|
||||
VolumeFieldLoader loader;
|
||||
const Containers::String absolutePath =
|
||||
NormalizePathString(fs::path(m_projectRoot.CStr()) / sourceRecord.relativePath.CStr());
|
||||
LoadResult result = loader.Load(absolutePath);
|
||||
if (!result || result.resource == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VolumeField* volumeField = static_cast<VolumeField*>(result.resource);
|
||||
const Containers::String artifactKey = BuildArtifactKey(sourceRecord);
|
||||
const Containers::String artifactDir = BuildArtifactDirectory(artifactKey);
|
||||
const Containers::String mainArtifactPath =
|
||||
NormalizePathString(fs::path(artifactDir.CStr()) / "main.xcvol");
|
||||
|
||||
std::error_code ec;
|
||||
fs::remove_all(fs::path(m_projectRoot.CStr()) / artifactDir.CStr(), ec);
|
||||
ec.clear();
|
||||
fs::create_directories(fs::path(m_projectRoot.CStr()) / artifactDir.CStr(), ec);
|
||||
if (ec) {
|
||||
delete volumeField;
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool writeOk =
|
||||
WriteVolumeFieldArtifactFile(fs::path(m_projectRoot.CStr()) / mainArtifactPath.CStr(), *volumeField);
|
||||
delete volumeField;
|
||||
if (!writeOk) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outRecord.artifactKey = artifactKey;
|
||||
outRecord.assetGuid = sourceRecord.guid;
|
||||
outRecord.importerName = sourceRecord.importerName;
|
||||
outRecord.importerVersion = sourceRecord.importerVersion;
|
||||
outRecord.resourceType = ResourceType::VolumeField;
|
||||
outRecord.artifactDirectory = artifactDir;
|
||||
outRecord.mainArtifactPath = mainArtifactPath;
|
||||
outRecord.sourceHash = sourceRecord.sourceHash;
|
||||
outRecord.metaHash = sourceRecord.metaHash;
|
||||
outRecord.sourceFileSize = sourceRecord.sourceFileSize;
|
||||
outRecord.sourceWriteTime = sourceRecord.sourceWriteTime;
|
||||
outRecord.mainLocalID = kMainAssetLocalID;
|
||||
outRecord.dependencies.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AssetDatabase::ImportUIDocumentAsset(const SourceAssetRecord& sourceRecord,
|
||||
UIDocumentKind kind,
|
||||
const char* artifactFileName,
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <XCEngine/Resources/Shader/ShaderLoader.h>
|
||||
#include <XCEngine/Resources/Texture/TextureLoader.h>
|
||||
#include <XCEngine/Resources/UI/UIDocumentLoaders.h>
|
||||
#include <XCEngine/Resources/Volume/VolumeFieldLoader.h>
|
||||
#include <exception>
|
||||
|
||||
namespace XCEngine {
|
||||
@@ -49,6 +50,7 @@ TextureLoader g_textureLoader;
|
||||
UIViewLoader g_uiViewLoader;
|
||||
UIThemeLoader g_uiThemeLoader;
|
||||
UISchemaLoader g_uiSchemaLoader;
|
||||
VolumeFieldLoader g_volumeFieldLoader;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -92,6 +94,7 @@ void ResourceManager::EnsureInitialized() {
|
||||
RegisterBuiltinLoader(*this, g_uiViewLoader);
|
||||
RegisterBuiltinLoader(*this, g_uiThemeLoader);
|
||||
RegisterBuiltinLoader(*this, g_uiSchemaLoader);
|
||||
RegisterBuiltinLoader(*this, g_volumeFieldLoader);
|
||||
m_assetImportService.Initialize();
|
||||
|
||||
m_asyncLoader = std::move(asyncLoader);
|
||||
|
||||
Reference in New Issue
Block a user