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
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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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())) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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())) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())) {
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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,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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
Reference in New Issue
Block a user