diff --git a/kraken/KRPipeline.cpp b/kraken/KRPipeline.cpp index 5cd61e2..cc4791d 100644 --- a/kraken/KRPipeline.cpp +++ b/kraken/KRPipeline.cpp @@ -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& 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& 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; diff --git a/kraken/KRPipeline.h b/kraken/KRPipeline.h index 307e3e4..6d35a73 100644 --- a/kraken/KRPipeline.h +++ b/kraken/KRPipeline.h @@ -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& 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& shaders, uint32_t vertexAttributes, Topology topology); virtual ~KRPipeline(); const char* getKey() const; diff --git a/kraken/nodes/KRCamera.cpp b/kraken/nodes/KRCamera.cpp index 313a56c..1589dea 100755 --- a/kraken/nodes/KRCamera.cpp +++ b/kraken/nodes/KRCamera.cpp @@ -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())) { diff --git a/kraken/nodes/KRDirectionalLight.cpp b/kraken/nodes/KRDirectionalLight.cpp index b0d29b0..84d5b69 100755 --- a/kraken/nodes/KRDirectionalLight.cpp +++ b/kraken/nodes/KRDirectionalLight.cpp @@ -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 diff --git a/kraken/nodes/KRLight.cpp b/kraken/nodes/KRLight.cpp index 3595e38..3f44ff2 100755 --- a/kraken/nodes/KRLight.cpp +++ b/kraken/nodes/KRLight.cpp @@ -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); diff --git a/kraken/nodes/KRParticleSystemNewtonian.cpp b/kraken/nodes/KRParticleSystemNewtonian.cpp index 999b0e9..12b70a2 100755 --- a/kraken/nodes/KRParticleSystemNewtonian.cpp +++ b/kraken/nodes/KRParticleSystemNewtonian.cpp @@ -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())) { diff --git a/kraken/nodes/KRPointLight.cpp b/kraken/nodes/KRPointLight.cpp index 6de7e27..c712f27 100755 --- a/kraken/nodes/KRPointLight.cpp +++ b/kraken/nodes/KRPointLight.cpp @@ -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 diff --git a/kraken/nodes/KRSprite.cpp b/kraken/nodes/KRSprite.cpp index 239ba1c..7c7ead9 100755 --- a/kraken/nodes/KRSprite.cpp +++ b/kraken/nodes/KRSprite.cpp @@ -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())) { diff --git a/kraken/resources/KRResource+fbx.cpp b/kraken/resources/KRResource+fbx.cpp index 7563524..a3bb509 100755 --- a/kraken/resources/KRResource+fbx.cpp +++ b/kraken/resources/KRResource+fbx.cpp @@ -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 { diff --git a/kraken/resources/KRResource+obj.cpp b/kraken/resources/KRResource+obj.cpp index e69ab7a..dcf44bf 100755 --- a/kraken/resources/KRResource+obj.cpp +++ b/kraken/resources/KRResource+obj.cpp @@ -354,7 +354,7 @@ KRMesh* KRResource::LoadObj(KRContext& context, const std::string& path) // std::vector<__uint16_t> vertex_indexes; // std::vector > vertex_index_bases; - mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_TRIANGLES; + mi.format = Topology::Triangles; new_mesh->LoadData(mi, true, false); } diff --git a/kraken/resources/material/KRMaterial.cpp b/kraken/resources/material/KRMaterial.cpp index 55f07da..6bb4aa3 100755 --- a/kraken/resources/material/KRMaterial.cpp +++ b/kraken/resources/material/KRMaterial.cpp @@ -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& bones, const std::vector& 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& bones, const std::vector& bind_poses, const Matrix4& matModel, KRTexture* pLightMap, float lod_coverage) { bool bLightMap = pLightMap && ri.camera->settings.bEnableLightMap; diff --git a/kraken/resources/material/KRMaterial.h b/kraken/resources/material/KRMaterial.h index 01a7698..2e27275 100755 --- a/kraken/resources/material/KRMaterial.h +++ b/kraken/resources/material/KRMaterial.h @@ -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& bones, const std::vector& 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& bones, const std::vector& bind_poses, const hydra::Matrix4& matModel, KRTexture* pLightMap, float lod_coverage = 0.0f); bool needsVertexTangents(); diff --git a/kraken/resources/mesh/KRMesh.cpp b/kraken/resources/mesh/KRMesh.cpp index 875935f..76e48ce 100755 --- a/kraken/resources/mesh/KRMesh.cpp +++ b/kraken/resources/mesh/KRMesh.cpp @@ -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>::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::const_iterator itr = mi.vertices.begin(); itr != mi.vertices.end(); itr++) { @@ -677,60 +664,84 @@ 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); - Vector3 v1 = p2 - p1; - Vector3 v2 = p3 - p1; + 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(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); - // -- Calculate normal if missing -- - if (calculate_normals) { - Vector3 first_normal = getVertexNormal(iVertex); - 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); - } - } - - // -- Calculate tangent vector for normal mapping -- - if (calculate_tangents) { - Vector3 first_tangent = getVertexTangent(iVertex); - 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 st1 = Vector2::Create(uv1.x - uv0.x, uv1.y - uv0.y); - Vector2 st2 = Vector2::Create(uv2.x - uv0.x, uv2.y - uv0.y); - float coef = 1 / (st1.x * st2.y - st2.x * st1.y); - - Vector3 tangent = Vector3::Create( - coef * ((v1.x * st2.y) + (v2.x * -st1.y)), - coef * ((v1.y * st2.y) + (v2.y * -st1.y)), - coef * ((v1.z * st2.y) + (v2.z * -st1.y)) - ); - - tangent.normalize(); - setVertexTangent(iVertex, tangent); - setVertexTangent(iVertex + 1, tangent); - setVertexTangent(iVertex + 2, tangent); - } - } + normal.normalize(); + setVertexNormal(i0, normal); + setVertexNormal(i1, normal); + setVertexNormal(i2, normal); } } + + // -- Calculate tangent vector for normal mapping -- + if (calculate_tangents) { + 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, 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); + float coef = 1 / (st1.x * st2.y - st2.x * st1.y); + + Vector3 tangent = Vector3::Create( + coef * ((v1.x * st2.y) + (v2.x * -st1.y)), + coef * ((v1.y * st2.y) + (v2.y * -st1.y)), + coef * ((v1.z * st2.y) + (v2.z * -st1.y)) + ); + + tangent.normalize(); + 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 +int KRMesh::getVertexIndex(int submesh, int index) const { - switch (getModelFormat()) { - case ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: - { + 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(); } diff --git a/kraken/resources/mesh/KRMesh.h b/kraken/resources/mesh/KRMesh.h index 2e97229..e01455b 100755 --- a/kraken/resources/mesh/KRMesh.h +++ b/kraken/resources/mesh/KRMesh.h @@ -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 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 vertices; std::vector<__uint16_t> vertex_indexes; std::vector > 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; diff --git a/kraken/resources/mesh/KRMeshCube.cpp b/kraken/resources/mesh/KRMeshCube.cpp index 95e69fb..48e7c8f 100755 --- a/kraken/resources/mesh/KRMeshCube.cpp +++ b/kraken/resources/mesh/KRMeshCube.cpp @@ -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(0, 0)); mi.material_names.push_back("__white"); - mi.format = ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES; + mi.format = Topology::Triangles; LoadData(mi, true, true); } diff --git a/kraken/resources/mesh/KRMeshQuad.cpp b/kraken/resources/mesh/KRMeshQuad.cpp index 38f81e0..3d08c1f 100755 --- a/kraken/resources/mesh/KRMeshQuad.cpp +++ b/kraken/resources/mesh/KRMeshQuad.cpp @@ -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); } diff --git a/kraken/resources/mesh/KRMeshSphere.cpp b/kraken/resources/mesh/KRMeshSphere.cpp index 8b71d10..3117998 100755 --- a/kraken/resources/mesh/KRMeshSphere.cpp +++ b/kraken/resources/mesh/KRMeshSphere.cpp @@ -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++) {