Implemented KRMeshBinding, mesh lod functionality is now explicit in KRScene format and api

This commit is contained in:
2025-11-11 23:07:04 -08:00
parent 8c8aa1893c
commit 82019987e6
22 changed files with 268 additions and 180 deletions

View File

@@ -1556,7 +1556,7 @@ void LoadMesh(KRContext& context, FbxScene* pFbxScene, FbxGeometryConverter* pGe
KRMesh* new_mesh = new KRMesh(context, pMesh->GetNode()->GetName());
new_mesh->LoadData(mi, true, need_tangents);
context.getMeshManager()->addModel(new_mesh);
context.getMeshManager()->addMesh(new_mesh);
}
KRNode* LoadMesh(KRNode* parent_node, FbxScene* pFbxScene, FbxGeometryConverter* pGeometryConverter, FbxNode* pNode)

View File

@@ -67,31 +67,8 @@ KRMesh::KRMesh(KRContext& context, std::string name, Block* data) : KRResource(c
loadPack(data);
}
void KRMesh::parseName(const std::string& name, std::string& lodBaseName, int& lodCoverage)
{
lodCoverage = 100;
lodBaseName = name;
size_t last_underscore_pos = name.find_last_of('_');
if (last_underscore_pos != std::string::npos) {
// Found an underscore
std::string suffix = name.substr(last_underscore_pos + 1);
if (suffix.find("lod") == 0) {
std::string lod_level_string = suffix.substr(3);
char* end = NULL;
int c = (int)strtol(lod_level_string.c_str(), &end, 10);
if (c >= 0 && c <= 100 && *end == '\0') {
lodCoverage = c;
lodBaseName = name.substr(0, last_underscore_pos);
}
}
}
}
void KRMesh::setName(const std::string name)
{
parseName(name, m_lodBaseName, m_lodCoverage);
m_lodCoverage = 100;
m_lodBaseName = name;
}

View File

@@ -70,8 +70,6 @@ class KRMesh : public KRResource
{
public:
static void parseName(const std::string& name, std::string& lodBaseName, int& lodCoverage);
KRMesh(KRContext& context, std::string name, mimir::Block* data);
KRMesh(KRContext& context, std::string name);
virtual ~KRMesh();

View File

@@ -0,0 +1,53 @@
//
// KRMeshBinding.cpp
// Kraken Engine
//
// Copyright 2025 Kearwood Gilbert. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The views and conclusions contained in the software and documentation are those of the
// authors and should not be interpreted as representing official policies, either expressed
// or implied, of Kearwood Gilbert.
//
#include "KREngine-common.h"
#include "KRContext.h"
#include "KRMesh.h"
#include "KRMeshBinding.h"
KRMesh* KRMeshBinding::get()
{
return static_cast<KRMesh*>(m_resource);
}
bool KRMeshBinding::load(KRContext* context)
{
if (m_name.size() == 0) {
return true;
}
if (m_resource != nullptr) {
return true;
}
m_resource = context->getMeshManager()->getMesh(m_name.c_str());
return (m_resource != nullptr);
}

View File

@@ -0,0 +1,46 @@
//
// KRMeshBinding.h
// Kraken Engine
//
// Copyright 2025 Kearwood Gilbert. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The views and conclusions contained in the software and documentation are those of the
// authors and should not be interpreted as representing official policies, either expressed
// or implied, of Kearwood Gilbert.
//
#pragma once
#include "KREngine-common.h"
#include "resources/KRResourceBinding.h"
class KRMesh;
class KRMeshBinding : public KRResourceBinding
{
public:
KRMesh* get();
bool load(KRContext* context) override final;
private:
};

View File

@@ -55,9 +55,9 @@ KRMeshManager::KRMeshManager(KRContext& context)
void KRMeshManager::init()
{
addModel(new KRMeshCube(*m_pContext));
addModel(new KRMeshQuad(*m_pContext));
addModel(new KRMeshSphere(*m_pContext));
addMesh(new KRMeshCube(*m_pContext));
addMesh(new KRMeshQuad(*m_pContext));
addMesh(new KRMeshSphere(*m_pContext));
// ---- Initialize stock models ----
static const float _KRENGINE_VBO_3D_CUBE_VERTEX_DATA[] = {
@@ -114,87 +114,59 @@ void KRMeshManager::init()
KRMeshManager::~KRMeshManager()
{
for (unordered_multimap<std::string, KRMesh*>::iterator itr = m_models.begin(); itr != m_models.end(); ++itr) {
for (unordered_map<std::string, KRMesh*>::iterator itr = m_meshes.begin(); itr != m_meshes.end(); ++itr) {
delete (*itr).second;
}
m_models.clear();
m_meshes.clear();
}
KRResource* KRMeshManager::loadResource(const std::string& name, const std::string& extension, Block* data)
{
if (extension.compare("krmesh") == 0) {
return loadModel(name.c_str(), data);
return loadMesh(name.c_str(), data);
}
return nullptr;
}
KRResource* KRMeshManager::getResource(const std::string& name, const std::string& extension)
{
if (extension.compare("krmesh") == 0) {
std::string lodBaseName;
int lodCoverage;
KRMesh::parseName(name, lodBaseName, lodCoverage);
std::vector<KRMesh*> models = getModel(lodBaseName.c_str());
for (KRMesh* mesh : models) {
if (mesh->getLODCoverage() == lodCoverage) {
return mesh;
}
}
return getMesh(name.c_str());
}
return nullptr;
}
KRMesh* KRMeshManager::loadModel(const char* szName, Block* pData)
KRMesh* KRMeshManager::loadMesh(const char* szName, Block* pData)
{
KRMesh* pModel = new KRMesh(*m_pContext, szName, pData);
addModel(pModel);
return pModel;
KRMesh* mesh = new KRMesh(*m_pContext, szName, pData);
addMesh(mesh);
return mesh;
}
void KRMeshManager::addModel(KRMesh* model)
void KRMeshManager::addMesh(KRMesh* mesh)
{
std::string lowerName = model->getLODBaseName();
std::string lowerName = mesh->getLODBaseName();
std::transform(lowerName.begin(), lowerName.end(),
lowerName.begin(), ::tolower);
m_models.insert(std::pair<std::string, KRMesh*>(lowerName, model));
m_meshes[lowerName] = mesh;
}
KRMesh* KRMeshManager::getMaxLODModel(const char* szName)
KRMesh* KRMeshManager::getMesh(const char* szName)
{
std::vector<KRMesh*> models = getModel(szName);
// models are always in order of highest LOD first
if (models.size()) {
return models[0];
std::string lower_name = szName;
std::transform(lower_name.begin(), lower_name.end(), lower_name.begin(), ::tolower);
unordered_map<std::string, KRMesh*>::iterator itr = m_meshes.find(lower_name);
if (itr == m_meshes.end()) {
KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Model not found: %s", lower_name.c_str());
return nullptr;
}
return nullptr;
return itr->second;
}
std::vector<KRMesh*> KRMeshManager::getModel(const char* szName)
unordered_map<std::string, KRMesh*>& KRMeshManager::getMeshes()
{
std::string lowerName = szName;
std::transform(lowerName.begin(), lowerName.end(),
lowerName.begin(), ::tolower);
std::vector<KRMesh*> matching_models;
std::pair<unordered_multimap<std::string, KRMesh*>::iterator, unordered_multimap<std::string, KRMesh*>::iterator> range = m_models.equal_range(lowerName);
for (unordered_multimap<std::string, KRMesh*>::iterator itr_match = range.first; itr_match != range.second; itr_match++) {
matching_models.push_back(itr_match->second);
}
std::sort(matching_models.begin(), matching_models.end(), KRMesh::lod_sort_predicate);
if (matching_models.size() == 0) {
KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Model not found: %s", lowerName.c_str());
}
return matching_models;
}
unordered_multimap<std::string, KRMesh*>& KRMeshManager::getModels()
{
return m_models;
return m_meshes;
}
void KRMeshManager::bindVBO(VkCommandBuffer& commandBuffer, KRVBOData* vbo_data, float lodCoverage)

View File

@@ -58,13 +58,12 @@ public:
void startFrame(float deltaTime);
void endFrame(float deltaTime);
KRMesh* loadModel(const char* szName, mimir::Block* pData);
std::vector<KRMesh*> getModel(const char* szName);
KRMesh* getMaxLODModel(const char* szName);
void addModel(KRMesh* model);
KRMesh* loadMesh(const char* szName, mimir::Block* pData);
KRMesh* getMesh(const char* szName);
void addMesh(KRMesh* mesh);
std::vector<std::string> getModelNames();
unordered_multimap<std::string, KRMesh*>& getModels();
std::vector<std::string> getMeshNames();
unordered_map<std::string, KRMesh*>& getMeshes();
class KRVBOData
{
@@ -217,7 +216,7 @@ private:
mimir::Block KRENGINE_VBO_2D_SQUARE_VERTICES;
__int32_t KRENGINE_VBO_2D_SQUARE_ATTRIBS;
unordered_multimap<std::string, KRMesh*> m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model
unordered_map<std::string, KRMesh*> m_meshes;
long m_vboMemUsed;
KRVBOData* m_currentVBO;

View File

@@ -107,7 +107,7 @@ void KRScene::render(KRNode::RenderInfo& ri)
// ---------- Start: Vulkan Debug Code ----------
/*
if (ri.renderPass->getType() == RenderPassType::RENDER_PASS_FORWARD_OPAQUE) {
KRMesh* sphereMesh = getContext().getMeshManager()->getMaxLODModel("__sphere");
KRMesh* sphereMesh = getContext().getMeshManager()->getMesh("__sphere");
if (sphereMesh && sphereMesh->isReady()) {
PipelineInfo info{};
std::string shader_name("vulkan_test");