Replace KRMesh::ModelFormat enum with Topology. Topology merges indexed and non-indexed options.
Some checks failed
CMake on multiple platforms / build (Release, cl, cl, windows-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, clang, clang++, macos-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, clang, clang++, ubuntu-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, gcc, g++, ubuntu-latest) (push) Has been cancelled

This commit is contained in:
2026-06-05 01:18:57 -07:00
parent 5b79142471
commit 763a448a6c
17 changed files with 176 additions and 198 deletions

View File

@@ -41,7 +41,7 @@
using namespace hydra;
KRPipeline::KRPipeline(KRContext& context, KrDeviceHandle deviceHandle, const KRRenderPass* renderPass, Vector2i viewport_size, Vector2i scissor_size, const PipelineInfo& info, const char* szKey, const std::vector<KRShader*>& shaders, uint32_t vertexAttributes, ModelFormat modelFormat)
KRPipeline::KRPipeline(KRContext& context, KrDeviceHandle deviceHandle, const KRRenderPass* renderPass, Vector2i viewport_size, Vector2i scissor_size, const PipelineInfo& info, const char* szKey, const std::vector<KRShader*>& shaders, uint32_t vertexAttributes, Topology topology)
: KRContextObject(context)
, m_deviceHandle(deviceHandle)
{
@@ -225,15 +225,25 @@ KRPipeline::KRPipeline(KRContext& context, KrDeviceHandle deviceHandle, const KR
VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
switch (modelFormat) {
case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES:
case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES:
switch (topology) {
case Topology::Points:
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
break;
case Topology::LineStrips:
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
break;
case Topology::Lines:
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
break;
case Topology::Triangles:
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
break;
case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP:
case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP:
case Topology::TriangleStrips:
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
break;
case Topology::TriangleFans:
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
break;
}
inputAssembly.primitiveRestartEnable = VK_FALSE;

View File

@@ -45,9 +45,10 @@ class KRRenderPass;
class KRUniformBuffer;
class KRTexture;
enum class ModelFormat : __uint8_t;
struct SpvReflectShaderModule;
enum class Topology : uint8_t;
enum class CullMode : uint32_t
{
kCullBack = 0,
@@ -205,7 +206,7 @@ public:
RasterMode rasterMode;
CullMode cullMode;
uint32_t vertexAttributes;
ModelFormat modelFormat;
Topology modelFormat;
const KRRenderPass* renderPass;
};
@@ -213,7 +214,7 @@ class KRPipeline : public KRContextObject
{
public:
KRPipeline(KRContext& context, KrDeviceHandle deviceHandle, const KRRenderPass* renderPass, hydra::Vector2i viewport_size, hydra::Vector2i scissor_size, const PipelineInfo& info, const char* szKey, const std::vector<KRShader*>& shaders, uint32_t vertexAttributes, ModelFormat modelFormat);
KRPipeline(KRContext& context, KrDeviceHandle deviceHandle, const KRRenderPass* renderPass, hydra::Vector2i viewport_size, hydra::Vector2i scissor_size, const PipelineInfo& info, const char* szKey, const std::vector<KRShader*>& shaders, uint32_t vertexAttributes, Topology topology);
virtual ~KRPipeline();
const char* getKey() const;

View File

@@ -188,7 +188,7 @@ void KRCamera::render(KRNode::RenderInfo& ri)
info.renderPass = ri.renderPass;
info.rasterMode = RasterMode::kAdditive;
info.vertexAttributes = vertices.getVertexAttributes();
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP;
info.modelFormat = Topology::TriangleStrips;
KRPipeline* pVisShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info);
}
*/
@@ -425,7 +425,7 @@ void KRCamera::renderPost(RenderInfo& ri)
info.pCamera = this;
info.renderPass = compositeSurface.getRenderPass(RenderPassType::RENDER_PASS_FORWARD_TRANSPARENT);
info.rasterMode = RasterMode::kOpaqueNoTest;
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP;
info.modelFormat = Topology::TriangleStrips;
info.vertexAttributes = vertices.getVertexAttributes();
KRPipeline *postShader = m_pContext->getPipelineManager()->getPipeline(surface, info);
@@ -617,7 +617,7 @@ void KRCamera::renderDebug(RenderInfo& ri)
info.rasterMode = RasterMode::kAlphaBlendNoTest;
info.cullMode = CullMode::kCullNone;
info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_POSITION) | (1 << KRMesh::KRENGINE_ATTRIB_TEXCOORD0);
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES;
info.modelFormat = Topology::Triangles;
KRPipeline* fontShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info);
if (fontShader && fontShader->bind(ri, Matrix4())) {

View File

@@ -161,7 +161,7 @@ void KRDirectionalLight::render(RenderInfo& ri)
info.rasterMode = RasterMode::kAdditiveNoTest;
info.vertexAttributes = vertices.getVertexAttributes();
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP;
info.modelFormat = Topology::TriangleStrips;
KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info);
if (pShader && pShader->bind(ri, getModelMatrix())) { // TODO: Need to pass in the light index to the shader

View File

@@ -239,7 +239,7 @@ void KRLight::render(RenderInfo& ri)
info.rasterMode = RasterMode::kAdditive;
info.cullMode = CullMode::kCullNone;
info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_POSITION) | (1 << KRMesh::KRENGINE_ATTRIB_TEXCOORD0);
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES;
info.modelFormat = Topology::Triangles;
KRPipeline* pParticleShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info);
if (pParticleShader && pParticleShader->bind(ri, getParticleModelMatrix(*ri.viewport))) { // TODO: Pass light index to shader
m_pContext->getMeshManager()->bindVBO(ri.commandBuffer, &m_pContext->getMeshManager()->KRENGINE_VBO_DATA_RANDOM_PARTICLES, 1.0f);
@@ -279,7 +279,7 @@ void KRLight::render(RenderInfo& ri)
info.rasterMode = RasterMode::kAdditive;
info.cullMode = CullMode::kCullNone;
info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_POSITION);
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES;
info.modelFormat = Topology::Triangles;
KRPipeline* pFogShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info);
if (pFogShader) {
@@ -364,7 +364,7 @@ void KRLight::render(RenderInfo& ri)
info.rasterMode = RasterMode::kAdditiveNoTest;
info.cullMode = CullMode::kCullNone;
info.vertexAttributes = vertices.getVertexAttributes();
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP;
info.modelFormat = Topology::TriangleStrips;
KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info);

View File

@@ -99,7 +99,7 @@ void KRParticleSystemNewtonian::render(RenderInfo& ri)
info.rasterMode = RasterMode::kAdditive;
info.cullMode = CullMode::kCullNone;
info.vertexAttributes = (1 << KRMesh::KRENGINE_ATTRIB_POSITION) | (1 << KRMesh::KRENGINE_ATTRIB_TEXCOORD0);
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES;
info.modelFormat = Topology::Triangles;
KRPipeline* pParticleShader = m_pContext->getPipelineManager()->getPipeline(*ri.surface, info);
if (pParticleShader && pParticleShader->bind(ri, getModelMatrix())) {

View File

@@ -113,7 +113,7 @@ void KRPointLight::render(RenderInfo& ri)
info.rasterMode = bVisualize ? RasterMode::kAdditive : RasterMode::kAlphaBlend;
}
info.vertexAttributes = bInsideLight ? m_pContext->getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES.getVertexAttributes() : 1 << KRMesh::KRENGINE_ATTRIB_POSITION;
info.modelFormat = bInsideLight ? ModelFormat::KRENGINE_MODEL_FORMAT_STRIP : ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES;
info.modelFormat = bInsideLight ? Topology::TriangleStrips : Topology::Triangles;
KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info);
if (pShader && pShader->bind(ri, sphereModelMatrix)) { // TODO: Pass light index to shader

View File

@@ -133,7 +133,7 @@ void KRSprite::render(RenderInfo& ri)
info.rasterMode = RasterMode::kAdditive;
info.cullMode = CullMode::kCullNone;
info.vertexAttributes = vertices.getVertexAttributes();
info.modelFormat = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP;
info.modelFormat = Topology::TriangleStrips;
KRPipeline* pShader = getContext().getPipelineManager()->getPipeline(*ri.surface, info);
if (pShader && pShader->bind(ri, getModelMatrix())) {

View File

@@ -1276,7 +1276,7 @@ void LoadMaterial(KRContext& context, FbxSurfaceMaterial* pMaterial)
void LoadMesh(KRContext& context, FbxScene* pFbxScene, FbxGeometryConverter* pGeometryConverter, FbxMesh* pMesh)
{
KRMesh::mesh_info mi;
mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES;
mi.format = Topology::Triangles;
typedef struct
{

View File

@@ -354,7 +354,7 @@ KRMesh* KRResource::LoadObj(KRContext& context, const std::string& path)
// std::vector<__uint16_t> vertex_indexes;
// std::vector<std::pair<int, int> > vertex_index_bases;
mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES;
mi.format = Topology::Triangles;
new_mesh->LoadData(mi, true, false);
}

View File

@@ -743,7 +743,7 @@ kraken_stream_level KRMaterial::getStreamLevel()
return stream_level;
}
bool KRMaterial::bind(KRNode::RenderInfo& ri, ModelFormat modelFormat, __uint32_t vertexAttributes, CullMode cullMode, const std::vector<KRBone*>& bones, const std::vector<Matrix4>& bind_poses, const Matrix4& matModel, KRTexture* pLightMap, float lod_coverage)
bool KRMaterial::bind(KRNode::RenderInfo& ri, Topology modelFormat, __uint32_t vertexAttributes, CullMode cullMode, const std::vector<KRBone*>& bones, const std::vector<Matrix4>& bind_poses, const Matrix4& matModel, KRTexture* pLightMap, float lod_coverage)
{
bool bLightMap = pLightMap && ri.camera->settings.bEnableLightMap;

View File

@@ -47,6 +47,7 @@
enum class CullMode : __uint32_t;
enum class ModelFormat : __uint8_t;
enum class Topology : __uint8_t;
class KRTextureManager;
class KRContext;
@@ -130,7 +131,7 @@ public:
bool isTransparent();
bool bind(KRNode::RenderInfo& ri, ModelFormat modelFormat, __uint32_t vertexAttributes, CullMode cullMode, const std::vector<KRBone*>& bones, const std::vector<hydra::Matrix4>& bind_poses, const hydra::Matrix4& matModel, KRTexture* pLightMap, float lod_coverage = 0.0f);
bool bind(KRNode::RenderInfo& ri, Topology modelFormat, __uint32_t vertexAttributes, CullMode cullMode, const std::vector<KRBone*>& bones, const std::vector<hydra::Matrix4>& bind_poses, const hydra::Matrix4& matModel, KRTexture* pLightMap, float lod_coverage = 0.0f);
bool needsVertexTangents();

View File

@@ -344,8 +344,7 @@ void KRMesh::createDataBlocks(KRMeshManager::KRVBOData::vbo_type t)
int32_t vertex_count = pHeader->vertex_count;
int vbo_index = 0;
if (getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES
|| getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP) {
if (getIndexCount(iSubmesh) > 0) {
int index_group = getSubmesh(iSubmesh)->index_group;
int index_group_offset = getSubmesh(iSubmesh)->index_group_offset;
@@ -442,7 +441,7 @@ void KRMesh::renderSubmesh(VkCommandBuffer& commandBuffer, int iSubmesh, const K
vector<shared_ptr<KRMeshManager::KRVBOData>>::iterator vbo_itr = mesh.vbo_data_blocks.begin();
int vbo_index = 0;
if (getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) {
if (getIndexCount(0) > 0) {
int index_group = getSubmesh(iSubmesh)->index_group;
int index_group_offset = getSubmesh(iSubmesh)->index_group_offset;
@@ -480,15 +479,10 @@ void KRMesh::renderSubmesh(VkCommandBuffer& commandBuffer, int iSubmesh, const K
if (iVertex + cVertexes >= MAX_VBO_SIZE) {
assert(iVertex + (MAX_VBO_SIZE - iVertex) <= cBufferVertexes);
switch (getModelFormat()) {
case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES:
case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP:
if (getIndexCount(0) == 0) {
vkCmdDraw(commandBuffer, (MAX_VBO_SIZE - iVertex), 1, iVertex, 0);
break;
case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES:
case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP:
} else {
vkCmdDrawIndexed(commandBuffer, (MAX_VBO_SIZE - iVertex), 1, iVertex, 0, 0);
break;
}
m_pContext->getMeshManager()->log_draw_call(renderPass->getType(), object_name, material_name, (MAX_VBO_SIZE - iVertex));
@@ -498,17 +492,10 @@ void KRMesh::renderSubmesh(VkCommandBuffer& commandBuffer, int iSubmesh, const K
} else {
assert(iVertex + cVertexes <= cBufferVertexes);
switch (getModelFormat()) {
case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES:
case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP:
if (getIndexCount(0) == 0) {
vkCmdDraw(commandBuffer, cVertexes, 1, iVertex, 0);
break;
case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES:
case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP:
} else {
vkCmdDrawIndexed(commandBuffer, cVertexes, 1, iVertex, 0, 0);
break;
default:
break;
}
m_pContext->getMeshManager()->log_draw_call(renderPass->getType(), object_name, material_name, cVertexes);
@@ -528,7 +515,7 @@ void KRMesh::LoadData(const KRMesh::mesh_info& mi, bool calculate_normals, bool
bool use_short_vertexes = false;
bool use_short_normals = true;
bool use_short_tangents = true;
bool use_short_texcoord[8] = { true, true, true, true, true, true, true, true };
bool use_short_texcoord[8] = { false, false, false, false, false, false, false, false };
if (use_short_vertexes) {
for (std::vector<Vector3>::const_iterator itr = mi.vertices.begin(); itr != mi.vertices.end(); itr++) {
@@ -677,41 +664,35 @@ void KRMesh::LoadData(const KRMesh::mesh_info& mi, bool calculate_normals, bool
*index_base_data++ = (*itr).second;
}
if (getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES) {
// Calculate missing surface normals and tangents
//cout << " Calculate surface normals and tangents\n";
if (calculate_normals || calculate_tangents) {
// NOTE: This will not work properly if the vertices are already indexed
for (int iVertex = 0; iVertex < (int)mi.vertices.size(); iVertex += 3) {
Vector3 p1 = getVertexPosition(iVertex);
Vector3 p2 = getVertexPosition(iVertex + 1);
Vector3 p3 = getVertexPosition(iVertex + 2);
auto calculateTriangleAttributes = [this, calculate_normals, calculate_tangents](int i0, int i1, int i2) {
Vector3 p1 = getVertexPosition(i0);
Vector3 p2 = getVertexPosition(i1);
Vector3 p3 = getVertexPosition(i2);
Vector3 v1 = p2 - p1;
Vector3 v2 = p3 - p1;
// -- Calculate normal if missing --
if (calculate_normals) {
Vector3 first_normal = getVertexNormal(iVertex);
Vector3 first_normal = getVertexNormal(i0);
if (first_normal.x == 0.0f && first_normal.y == 0.0f && first_normal.z == 0.0f) {
// Note - We don't take into consideration smoothing groups or smoothing angles when generating normals; all generated normals represent flat shaded polygons
Vector3 normal = Vector3::Cross(v1, v2);
normal.normalize();
setVertexNormal(iVertex, normal);
setVertexNormal(iVertex + 1, normal);
setVertexNormal(iVertex + 2, normal);
setVertexNormal(i0, normal);
setVertexNormal(i1, normal);
setVertexNormal(i2, normal);
}
}
// -- Calculate tangent vector for normal mapping --
if (calculate_tangents) {
Vector3 first_tangent = getVertexTangent(iVertex);
Vector3 first_tangent = getVertexTangent(i0);
if (first_tangent.x == 0.0f && first_tangent.y == 0.0f && first_tangent.z == 0.0f) {
Vector2 uv0 = getVertexTexCoord(0, iVertex);
Vector2 uv1 = getVertexTexCoord(0, iVertex + 1);
Vector2 uv2 = getVertexTexCoord(0, iVertex + 2);
Vector2 uv0 = getVertexTexCoord(0, i0);
Vector2 uv1 = getVertexTexCoord(0, i1);
Vector2 uv2 = getVertexTexCoord(0, i2);
Vector2 st1 = Vector2::Create(uv1.x - uv0.x, uv1.y - uv0.y);
Vector2 st2 = Vector2::Create(uv2.x - uv0.x, uv2.y - uv0.y);
@@ -724,13 +705,43 @@ void KRMesh::LoadData(const KRMesh::mesh_info& mi, bool calculate_normals, bool
);
tangent.normalize();
setVertexTangent(iVertex, tangent);
setVertexTangent(iVertex + 1, tangent);
setVertexTangent(iVertex + 2, tangent);
setVertexTangent(i0, tangent);
setVertexTangent(i1, tangent);
setVertexTangent(i2, tangent);
}
}
};
// Calculate missing surface normals and tangents
if (calculate_normals || calculate_tangents) {
switch (getModelFormat()) {
case Topology::Triangles:
{
// NOTE: This will not work properly if the vertices are already indexed
for (int iVertex = 0; iVertex + 2 < (int)mi.vertices.size(); iVertex += 3) {
calculateTriangleAttributes(iVertex, iVertex + 1, iVertex + 2);
}
break;
}
case Topology::TriangleStrips:
{
// NOTE: This will not work properly if the vertices are already indexed
for (int iVertex = 0; iVertex + 2 < (int)mi.vertices.size(); iVertex++) {
calculateTriangleAttributes(iVertex, iVertex + 1, iVertex + 2);
}
break;
}
case Topology::TriangleFans:
{
// NOTE: This will not work properly if the vertices are already indexed
for (int iVertex = 1; iVertex + 1 < (int)mi.vertices.size(); iVertex++) {
calculateTriangleAttributes(0, iVertex, iVertex + 1);
}
break;
}
default:
assert(false); // Not Supported
} // switch
}
m_pData->unlock();
@@ -853,6 +864,20 @@ int KRMesh::getVertexCount(int submesh) const
return getSubmesh(submesh)->vertex_count;
}
int KRMesh::getIndexCount(int submesh) const
{
pack_header* pHeader = getHeader();
if (pHeader->index_count == 0) {
return 0;
}
int index_group = getSubmesh(submesh)->index_group;
int start_index_offset, start_vertex_offset, index_count, vertex_count;
getIndexedRange(index_group, start_index_offset, start_vertex_offset, index_count, vertex_count);
return index_count;
}
__uint32_t KRMesh::getVertexAttributes() const
{
pack_header* header = getHeader();
@@ -1202,10 +1227,9 @@ Matrix4 KRMesh::getBoneBindPose(int bone_index)
return Matrix4::Create(getBone(bone_index)->bind_pose);
}
ModelFormat KRMesh::getModelFormat() const
Topology KRMesh::getModelFormat() const
{
ModelFormat f = (ModelFormat)getHeader()->model_format;
return f;
return (Topology)getHeader()->model_format;
}
bool KRMesh::rayCast(const Vector3& start, const Vector3& dir, const Triangle3& tri, const Vector3& tri_n0, const Vector3& tri_n1, const Vector3& tri_n2, HitInfo& hitinfo)
@@ -1247,39 +1271,22 @@ bool KRMesh::rayCast(const Vector3& start, const Vector3& dir, HitInfo& hitinfo)
m_pData->lock();
bool hit_found = false;
for (int submesh_index = 0; submesh_index < getSubmeshCount(); submesh_index++) {
// int vertex_start = getSubmesh(submesh_index)->start_vertex;
int vertex_count = getVertexCount(submesh_index);
switch (getModelFormat()) {
case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES:
case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES:
case Topology::Triangles:
for (int triangle_index = 0; triangle_index < vertex_count / 3; triangle_index++) {
int tri_vert_index[3]; // FINDME, HACK! This is not very efficient for indexed collider meshes...
tri_vert_index[0] = getTriangleVertexIndex(submesh_index, triangle_index * 3);
tri_vert_index[1] = getTriangleVertexIndex(submesh_index, triangle_index * 3 + 1);
tri_vert_index[2] = getTriangleVertexIndex(submesh_index, triangle_index * 3 + 2);
tri_vert_index[0] = getVertexIndex(submesh_index, triangle_index * 3);
tri_vert_index[1] = getVertexIndex(submesh_index, triangle_index * 3 + 1);
tri_vert_index[2] = getVertexIndex(submesh_index, triangle_index * 3 + 2);
Triangle3 tri = Triangle3::Create(getVertexPosition(tri_vert_index[0]), getVertexPosition(tri_vert_index[1]), getVertexPosition(tri_vert_index[2]));
if (rayCast(start, dir, tri, getVertexNormal(tri_vert_index[0]), getVertexNormal(tri_vert_index[1]), getVertexNormal(tri_vert_index[2]), hitinfo)) hit_found = true;
}
break;
/*
NOTE: Not yet supported:
case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP:
case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP:
for(int triangle_index=0; triangle_index < vertex_count - 2; triangle_index++) {
int tri_vert_index[3];
tri_vert_index[0] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3);
tri_vert_index[1] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 1);
tri_vert_index[2] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 2);
if(rayCast(v0, dir, getVertexPosition(vertex_start + triangle_index), getVertexPosition(vertex_start + triangle_index+1), getVertexPosition(vertex_start + triangle_index+2), getVertexNormal(vertex_start + triangle_index), getVertexNormal(vertex_start + triangle_index+1), getVertexNormal(vertex_start + triangle_index+2), hitinfo)) hit_found = true;
}
break;
*/
default:
assert(false); // Not yet implemented
break;
}
}
@@ -1296,42 +1303,20 @@ bool KRMesh::sphereCast(const Matrix4& model_to_world, const Vector3& v0, const
for (int submesh_index = 0; submesh_index < getSubmeshCount(); submesh_index++) {
int vertex_count = getVertexCount(submesh_index);
switch (getModelFormat()) {
case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES:
case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES:
case Topology::Triangles:
for (int triangle_index = 0; triangle_index < vertex_count / 3; triangle_index++) {
int tri_vert_index[3]; // FINDME, HACK! This is not very efficient for indexed collider meshes...
tri_vert_index[0] = getTriangleVertexIndex(submesh_index, triangle_index * 3);
tri_vert_index[1] = getTriangleVertexIndex(submesh_index, triangle_index * 3 + 1);
tri_vert_index[2] = getTriangleVertexIndex(submesh_index, triangle_index * 3 + 2);
tri_vert_index[0] = getVertexIndex(submesh_index, triangle_index * 3);
tri_vert_index[1] = getVertexIndex(submesh_index, triangle_index * 3 + 1);
tri_vert_index[2] = getVertexIndex(submesh_index, triangle_index * 3 + 2);
Triangle3 tri = Triangle3::Create(getVertexPosition(tri_vert_index[0]), getVertexPosition(tri_vert_index[1]), getVertexPosition(tri_vert_index[2]));
if (sphereCast(model_to_world, v0, v1, radius, tri, hitinfo)) hit_found = true;
/*
Triangle3 tri2 = Triangle3(getVertexPosition(tri_vert_index[1]), getVertexPosition(tri_vert_index[0]), getVertexPosition(tri_vert_index[2]));
if(sphereCast(model_to_world, v0, v1, radius, tri2, new_hitinfo)) hit_found = true;
*/
}
break;
/*
NOTE: Not yet supported:
case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP:
case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP:
for(int triangle_index=0; triangle_index < vertex_count - 2; triangle_index++) {
int tri_vert_index[3];
tri_vert_index[0] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3);
tri_vert_index[1] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 1);
tri_vert_index[2] = getTriangleVertexIndex(submesh_index, vertex_start + triangle_index*3 + 2);
if(sphereCast(model_to_world, v0, v1, getVertexPosition(vertex_start + triangle_index), getVertexPosition(vertex_start + triangle_index+1), getVertexPosition(vertex_start + triangle_index+2), getVertexNormal(vertex_start + triangle_index), getVertexNormal(vertex_start + triangle_index+1), getVertexNormal(vertex_start + triangle_index+2), new_hitinfo)) hit_found = true;
}
break;
*/
default:
assert(false); // Not yet implemented
break;
}
}
@@ -1400,6 +1385,7 @@ void KRMesh::convertToIndexed()
int vertex_index_base_start_vertex = 0;
mesh_info mi;
mi.format = getModelFormat();
int bone_count = getBoneCount();
for (int bone_index = 0; bone_index < bone_count; bone_index++) {
@@ -1533,32 +1519,16 @@ void KRMesh::convertToIndexed()
KRContext::Log(KRContext::LOG_LEVEL_INFORMATION, "Convert to indexed, before: %i after: %i (%.2f%% saving)", getHeader()->vertex_count, mi.vertices.size(), ((float)getHeader()->vertex_count - (float)mi.vertices.size()) / (float)getHeader()->vertex_count * 100.0f);
switch (getModelFormat()) {
case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES:
mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES;
break;
case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP:
mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP;
break;
default:
assert(false);
}
m_pData->unlock();
LoadData(mi, false, false);
}
void KRMesh::optimize()
{
switch (getModelFormat()) {
case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES:
case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_STRIP:
if (getIndexCount(0) > 0) {
optimizeIndexes();
break;
case ModelFormat::KRENGINE_MODEL_FORMAT_STRIP:
case ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES:
} else {
convertToIndexed(); // HACK, FINDME, TODO - This may not be ideal in every case and should be exposed through the API independently
break;
}
}
@@ -1577,14 +1547,11 @@ void KRMesh::getIndexedRange(int index_group, int& start_index_offset, int& star
}
}
int KRMesh::getTriangleVertexIndex(int submesh, int index) const
{
switch (getModelFormat()) {
case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES:
int KRMesh::getVertexIndex(int submesh, int index) const
{
if (getIndexCount(submesh) > 0) {
__uint16_t* index_data = getIndexData();
int start_index_offset, start_vertex_offset, index_count, vertex_count;
int index_group = getSubmesh(submesh)->index_group;
int index_group_offset = getSubmesh(submesh)->index_group_offset;
@@ -1595,11 +1562,8 @@ int KRMesh::getTriangleVertexIndex(int submesh, int index) const
getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count);
}
return index_data[start_index_offset + remaining_vertices] + start_vertex_offset;
}
break;
default:
} else {
return getSubmesh(submesh)->start_vertex + index;
break;
}
}
@@ -1610,7 +1574,7 @@ void KRMesh::optimizeIndexes()
m_pData->lock();
// TODO - Implement optimization for indexed strips
if (getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) {
if (getModelFormat() == Topology::Triangles && getIndexCount(0) > 0) {
__uint16_t* new_indices = (__uint16_t*)malloc(0x10000 * sizeof(__uint16_t));
__uint16_t* vertex_mapping = (__uint16_t*)malloc(0x10000 * sizeof(__uint16_t));
@@ -1691,7 +1655,7 @@ void KRMesh::optimizeIndexes()
free(new_indices);
free(vertex_mapping);
free(new_vertex_data);
} // if(getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES)
} // getModelFormat() == Topology::Triangles && getIndexCount(0) > 0
m_pData->unlock();
}

View File

@@ -59,12 +59,14 @@ class KRMaterial;
class KRNode;
class KRRenderPass;
enum class ModelFormat : __uint8_t
enum class Topology : uint8_t
{
KRENGINE_MODEL_FORMAT_TRIANGLES = 0,
KRENGINE_MODEL_FORMAT_STRIP,
KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES,
KRENGINE_MODEL_FORMAT_INDEXED_STRIP
Points = 0,
LineStrips,
Lines,
Triangles,
TriangleStrips,
TriangleFans
};
class KRMesh : public KRResource
@@ -120,6 +122,17 @@ public:
weights
};
static constexpr const std::initializer_list<VertexAttribute> VertexAttributeList
{
VertexAttribute::position,
VertexAttribute::normal,
VertexAttribute::tangent,
VertexAttribute::texcoord,
VertexAttribute::color,
VertexAttribute::joints,
VertexAttribute::weights
};
typedef struct
{
ComponentType component;
@@ -129,17 +142,6 @@ public:
} AttributeInfo;
static_assert(sizeof(AttributeInfo) == 4);
enum class Topology : uint8_t
{
Points = 0,
LineStrips,
LineLoops,
Lines,
Triangles,
TriangleStrips,
TriangleFans
};
static const int kMaxAttributes = 32;
typedef struct
{
@@ -188,7 +190,7 @@ public:
typedef struct
{
ModelFormat format;
Topology format;
std::vector<hydra::Vector3> vertices;
std::vector<__uint16_t> vertex_indexes;
std::vector<std::pair<int, int> > vertex_index_bases;
@@ -285,9 +287,10 @@ public:
int getSubmeshCount() const;
int getVertexCount(int submesh) const;
int getIndexCount(int submesh) const;
__uint32_t getVertexAttributes() const;
int getTriangleVertexIndex(int submesh, int index) const;
int getVertexIndex(int submesh, int index) const;
hydra::Vector3 getVertexPosition(int index) const;
hydra::Vector3 getVertexNormal(int index) const;
hydra::Vector3 getVertexTangent(int index) const;
@@ -313,7 +316,7 @@ public:
hydra::Matrix4 getBoneBindPose(int bone_index);
ModelFormat getModelFormat() const;
Topology getModelFormat() const;
bool lineCast(const hydra::Vector3& v0, const hydra::Vector3& v1, hydra::HitInfo& hitinfo) const;
bool rayCast(const hydra::Vector3& v0, const hydra::Vector3& dir, hydra::HitInfo& hitinfo) const;

View File

@@ -60,7 +60,7 @@ KRMeshCube::KRMeshCube(KRContext& context) : KRMesh(context, "__cube")
mi.submesh_starts.push_back(0);
mi.submesh_lengths.push_back((int)mi.vertices.size());
mi.material_names.push_back("__white");
mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP;
mi.format = Topology::TriangleStrips;
*/
// Cube with normals
@@ -172,7 +172,7 @@ KRMeshCube::KRMeshCube(KRContext& context) : KRMesh(context, "__cube")
mi.submesh_lengths.push_back((int)mi.vertex_indexes.size());
mi.vertex_index_bases.push_back(std::make_pair<int, int>(0, 0));
mi.material_names.push_back("__white");
mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES;
mi.format = Topology::Triangles;
LoadData(mi, true, true);
}

View File

@@ -53,7 +53,7 @@ KRMeshQuad::KRMeshQuad(KRContext& context) : KRMesh(context, "__quad")
mi.submesh_starts.push_back(0);
mi.submesh_lengths.push_back((int)mi.vertices.size());
mi.material_names.push_back("__white");
mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_STRIP;
mi.format = Topology::TriangleStrips;
LoadData(mi, true, true);
}

View File

@@ -112,8 +112,7 @@ KRMeshSphere::KRMeshSphere(KRContext& context) : KRMesh(context, "__sphere")
mi.submesh_lengths.push_back((int)mi.vertices.size());
mi.material_names.push_back("__white");
mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES;
mi.format = Topology::Triangles;
// Generate normals pointing away from center of sphere.
for (int vertex_index = 0; vertex_index < mi.vertices.size(); vertex_index++) {