From 2de749ff162a309a9f57792703ba53cf7dfbf6b6 Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Mon, 13 May 2013 13:16:25 -0700 Subject: [PATCH] Added ability to store position, normal, tangent, and uv vertex attributes using GL_SHORT to reduce memory consumption and bandwidth. Now taking advantage of GL_EXT_discard_framebuffer to reduce extraneous memory copy operations in the PowerVR driver Implemented native support for Maya's extended scene graph node attributes (pre-transform, post-transform, pivot sets, scale compensation) Debugging of broken skinned mesh renderer in progress --- KREngine/kraken/KRAudioManager.cpp | 2 +- KREngine/kraken/KRBone.cpp | 62 +-- KREngine/kraken/KRBone.h | 1 + KREngine/kraken/KRCamera.cpp | 48 +- KREngine/kraken/KRDirectionalLight.cpp | 7 +- KREngine/kraken/KREngine-common.h | 2 + KREngine/kraken/KRLODGroup.cpp | 1 - KREngine/kraken/KRLight.cpp | 6 +- KREngine/kraken/KRMat4.h | 2 +- KREngine/kraken/KRMaterial.cpp | 8 +- KREngine/kraken/KRMesh.cpp | 282 +++++++++--- KREngine/kraken/KRMesh.h | 27 +- KREngine/kraken/KRMeshManager.cpp | 90 ++-- KREngine/kraken/KRMeshManager.h | 6 +- KREngine/kraken/KRNode.cpp | 431 +++++++++++++++--- KREngine/kraken/KRNode.h | 47 +- KREngine/kraken/KRParticleSystemNewtonian.cpp | 4 +- KREngine/kraken/KRPointLight.cpp | 4 +- KREngine/kraken/KRRenderSettings.h | 1 + KREngine/kraken/KRResource+fbx.cpp | 39 +- KREngine/kraken/KRScene.cpp | 14 +- KREngine/kraken/KRStockGeometry.h | 4 + KREngine/kraken/KRTextureManager.cpp | 1 + KREngine/kraken/KRVector3.cpp | 24 + KREngine/kraken/KRVector3.h | 4 + .../Shaders/ObjectShader.fsh | 4 + .../Shaders/ObjectShader.vsh | 45 +- 27 files changed, 860 insertions(+), 306 deletions(-) diff --git a/KREngine/kraken/KRAudioManager.cpp b/KREngine/kraken/KRAudioManager.cpp index b87ebc2..6c2c860 100644 --- a/KREngine/kraken/KRAudioManager.cpp +++ b/KREngine/kraken/KRAudioManager.cpp @@ -1547,7 +1547,7 @@ void KRAudioManager::startFrame(float deltaTime) // apply minimum-cutoff so that we don't waste cycles processing very quiet / distant sound sources gain = KRMAX(gain - KRENGINE_AUDIO_CUTOFF, 0.0f) / (1.0f - KRENGINE_AUDIO_CUTOFF); - if(gain > 0.0f /*|| true*/) { // FINDME, HACK! "true" added to prevent squelching of audio sources that are contributing to reverb + if(gain > 0.0f) { KRVector3 source_listener_space = KRVector3( KRVector3::Dot(listener_right, diff), diff --git a/KREngine/kraken/KRBone.cpp b/KREngine/kraken/KRBone.cpp index 921273d..8783502 100644 --- a/KREngine/kraken/KRBone.cpp +++ b/KREngine/kraken/KRBone.cpp @@ -11,7 +11,7 @@ KRBone::KRBone(KRScene &scene, std::string name) : KRNode(scene, name) { - + setScaleCompensation(true); } KRBone::~KRBone() @@ -32,45 +32,55 @@ tinyxml2::XMLElement *KRBone::saveXML( tinyxml2::XMLNode *parent) void KRBone::loadXML(tinyxml2::XMLElement *e) { KRNode::loadXML(e); + setScaleCompensation(true); } +KRAABB KRBone::getBounds() { + return KRAABB(-KRVector3::One(), KRVector3::One(), getModelMatrix()); // Only required for bone debug visualization +} void KRBone::render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); - bool bVisualize = false; + bool bVisualize = pCamera->settings.debug_display == KRRenderSettings::KRENGINE_DEBUG_DISPLAY_BONES; if(renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) { KRMat4 sphereModelMatrix = getModelMatrix(); + + // Enable additive blending + GLDEBUG(glEnable(GL_BLEND)); + GLDEBUG(glBlendFunc(GL_ONE, GL_ONE)); + + + // Disable z-buffer write + GLDEBUG(glDepthMask(GL_FALSE)); + + // Disable z-buffer test + GLDEBUG(glDisable(GL_DEPTH_TEST)); - KRShader *pShader = getContext().getShaderManager()->getShader("visualize_overlay", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); - - if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass)) { - - // Enable additive blending - GLDEBUG(glEnable(GL_BLEND)); - GLDEBUG(glBlendFunc(GL_ONE, GL_ONE)); - - - // Disable z-buffer write - GLDEBUG(glDepthMask(GL_FALSE)); - - // Enable z-buffer test - GLDEBUG(glEnable(GL_DEPTH_TEST)); - GLDEBUG(glDepthFunc(GL_LEQUAL)); - GLDEBUG(glDepthRangef(0.0, 1.0)); - std::vector sphereModels = getContext().getModelManager()->getModel("__sphere"); - if(sphereModels.size()) { - for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) { - sphereModels[0]->renderSubmesh(i, renderPass, getName(), "visualize_overlay"); - } + KRShader *pShader = getContext().getShaderManager()->getShader("visualize_overlay", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); + + if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass)) { + std::vector sphereModels = getContext().getModelManager()->getModel("__sphere"); + if(sphereModels.size()) { + for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) { + sphereModels[0]->renderSubmesh(i, renderPass, getName(), "visualize_overlay"); } + } - // Enable alpha blending - GLDEBUG(glEnable(GL_BLEND)); - GLDEBUG(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); } + + // Enable alpha blending + GLDEBUG(glEnable(GL_BLEND)); + GLDEBUG(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); + + // Enable z-buffer test + GLDEBUG(glEnable(GL_DEPTH_TEST)); + GLDEBUG(glDepthFunc(GL_LEQUAL)); + GLDEBUG(glDepthRangef(0.0, 1.0)); + + } } diff --git a/KREngine/kraken/KRBone.h b/KREngine/kraken/KRBone.h index 5021c12..187b019 100644 --- a/KREngine/kraken/KRBone.h +++ b/KREngine/kraken/KRBone.h @@ -20,6 +20,7 @@ public: virtual std::string getElementName(); virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); virtual void loadXML(tinyxml2::XMLElement *e); + virtual KRAABB getBounds(); void render(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass); diff --git a/KREngine/kraken/KRCamera.cpp b/KREngine/kraken/KRCamera.cpp index 919fb13..197fa9d 100644 --- a/KREngine/kraken/KRCamera.cpp +++ b/KREngine/kraken/KRCamera.cpp @@ -114,6 +114,16 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende // Set render target GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, compositeFramebuffer)); + + +#if GL_EXT_discard_framebuffer + GLenum attachments[2] = {GL_DEPTH_ATTACHMENT, GL_COLOR_ATTACHMENT0}; + GLDEBUG(glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, attachments)); +#endif + + // Enable z-buffer write + GLDEBUG(glDepthMask(GL_TRUE)); + GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); GLDEBUG(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); @@ -121,9 +131,6 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende GLDEBUG(glCullFace(GL_BACK)); GLDEBUG(glEnable(GL_CULL_FACE)); - // Enable z-buffer write - GLDEBUG(glDepthMask(GL_TRUE)); - // Enable z-buffer test GLDEBUG(glEnable(GL_DEPTH_TEST)); GLDEBUG(glDepthFunc(GL_LEQUAL)); @@ -229,15 +236,23 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende GLDEBUG(glDisable(GL_BLEND)); GLDEBUG(glClearColor(0.0f, 0.0f, 0.0f, 1.0f)); + + // Enable z-buffer write + GLDEBUG(glDepthMask(GL_TRUE)); + + +#if GL_EXT_discard_framebuffer + GLenum attachments[2] = {GL_DEPTH_ATTACHMENT, GL_COLOR_ATTACHMENT0}; + GLDEBUG(glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, attachments)); + GLDEBUG(glClear(GL_DEPTH_BUFFER_BIT)); +#else GLDEBUG(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); - - +#endif // Enable backface culling GLDEBUG(glCullFace(GL_BACK)); GLDEBUG(glEnable(GL_CULL_FACE)); - // Enable z-buffer write - GLDEBUG(glDepthMask(GL_TRUE)); + // Enable z-buffer test GLDEBUG(glEnable(GL_DEPTH_TEST)); @@ -282,7 +297,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture); // Render a full screen quad - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, true, false, false, true, false, false, false, true); + m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } @@ -439,7 +454,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende KRShader *pVisShader = getContext().getShaderManager()->getShader("visualize_overlay", this, std::vector(), std::vector(), std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, true, false, false, false, false, false, false, true); + m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, KRENGINE_VBO_3D_CUBE_ATTRIBS, true); for(unordered_map::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) { KRMat4 matModel = KRMat4(); matModel.scale((*itr).first.size() * 0.5f); @@ -465,6 +480,12 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende m_pContext->getModelManager()->unbindVBO(); GL_POP_GROUP_MARKER; + + +#if GL_EXT_discard_framebuffer + GLenum attachments[2] = {GL_DEPTH_ATTACHMENT, GL_COLOR_ATTACHMENT0}; + GLDEBUG(glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, attachments)); +#endif } @@ -665,7 +686,7 @@ void KRCamera::renderPost() } // Update attribute values. - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, true, false, false, true, false, false, false, true); + m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); @@ -687,7 +708,7 @@ void KRCamera::renderPost() // viewMatrix.translate(-0.70, 0.70 - 0.45 * iShadow, 0.0); // getContext().getShaderManager()->selectShader(blitShader, KRViewport(getViewportSize(), viewMatrix, KRMat4()), shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); // m_pContext->getTextureManager()->selectTexture(1, NULL); -// m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, true, false, false, true, false, true); +// m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); // m_pContext->getTextureManager()->_setActiveTexture(0); // GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow])); //#if GL_EXT_shadow_samplers @@ -854,7 +875,7 @@ void KRCamera::renderPost() m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font")); - m_pContext->getModelManager()->bindVBO((void *)m_debug_text_vertices, vertex_count * sizeof(DebugTextVertexData), NULL, 0, true, false, false, true, false, false, false, true); + m_pContext->getModelManager()->bindVBO((void *)m_debug_text_vertices, vertex_count * sizeof(DebugTextVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, vertex_count)); @@ -1048,6 +1069,9 @@ std::string KRCamera::getDebugText() case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_COLLIDERS: stream << "Collider Visualization"; break; + case KRRenderSettings::KRENGINE_DEBUG_DISPLAY_BONES: + stream << "Bone Visualization"; + break; } return stream.str(); } diff --git a/KREngine/kraken/KRDirectionalLight.cpp b/KREngine/kraken/KRDirectionalLight.cpp index c070856..d5073df 100644 --- a/KREngine/kraken/KRDirectionalLight.cpp +++ b/KREngine/kraken/KRDirectionalLight.cpp @@ -30,9 +30,6 @@ std::string KRDirectionalLight::getElementName() { } KRVector3 KRDirectionalLight::getWorldLightDirection() { - const GLfloat PI = 3.14159265; - const GLfloat d2r = PI * 2 / 360; - KRVector3 world_rotation = getWorldRotation(); KRVector3 light_rotation = KRVector3(0.0, 0.0, 1.0); @@ -40,7 +37,7 @@ KRVector3 KRDirectionalLight::getWorldLightDirection() { m.rotate(world_rotation.x, X_AXIS); m.rotate(world_rotation.y, Y_AXIS); m.rotate(world_rotation.z, Z_AXIS); -// m.rotate(-90.0 * d2r, Y_AXIS); + KRVector3 light_direction = KRMat4::Dot(m, light_rotation); return light_direction; } @@ -130,7 +127,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector & GLDEBUG(glDisable(GL_DEPTH_TEST)); // Render a full screen quad - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, true, false, false, true, false, false, false, true); + m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } } diff --git a/KREngine/kraken/KREngine-common.h b/KREngine/kraken/KREngine-common.h index 327e8b9..a59bf8d 100644 --- a/KREngine/kraken/KREngine-common.h +++ b/KREngine/kraken/KREngine-common.h @@ -47,6 +47,8 @@ float const D2R = PI * 2 / 360; #include #include +#include "tinyxml2.h" + using std::vector; using std::string; diff --git a/KREngine/kraken/KRLODGroup.cpp b/KREngine/kraken/KRLODGroup.cpp index e8b5866..9df0a4f 100644 --- a/KREngine/kraken/KRLODGroup.cpp +++ b/KREngine/kraken/KRLODGroup.cpp @@ -106,7 +106,6 @@ bool KRLODGroup::getLODVisibility(const KRViewport &viewport) if(m_min_distance == 0 && m_max_distance == 0) { return true; } else { - // return (m_max_distance == 0); // FINDME, HACK - Test code to enable only the lowest LOD group float lod_bias = viewport.getLODBias(); lod_bias = pow(2.0f, -lod_bias); diff --git a/KREngine/kraken/KRLight.cpp b/KREngine/kraken/KRLight.cpp index 398c32c..7c96687 100644 --- a/KREngine/kraken/KRLight.cpp +++ b/KREngine/kraken/KRLight.cpp @@ -226,7 +226,7 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_PARTICLE_ORIGIN, KRMat4::DotWDiv(KRMat4::Invert(particleModelMatrix), KRVector3::Zero())); pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_dust_particle_size); - m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), KRMeshManager::KRENGINE_MAX_RANDOM_PARTICLES * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, true, false, false, true, false, false, false, true); + m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), KRMeshManager::KRENGINE_MAX_RANDOM_PARTICLES * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); } } @@ -266,7 +266,7 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE, KRVector2(slice_near, slice_spacing)); pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, (m_color * pCamera->settings.volumetric_environment_intensity * m_intensity * -slice_spacing / 1000.0f)); - m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getVolumetricLightingVertexes(), KRMeshManager::KRENGINE_MAX_VOLUMETRIC_PLANES * 6 * sizeof(KRMeshManager::VolumetricLightingVertexData), NULL, 0, true, false, false, false, false, false, false, true); + m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getVolumetricLightingVertexes(), KRMeshManager::KRENGINE_MAX_VOLUMETRIC_PLANES * 6 * sizeof(KRMeshManager::VolumetricLightingVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX), true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6)); } @@ -339,7 +339,7 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize); m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture); - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, true, false, false, true, false, false, false, true); + m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } } diff --git a/KREngine/kraken/KRMat4.h b/KREngine/kraken/KRMat4.h index 7a4c18c..e08a4e7 100644 --- a/KREngine/kraken/KRMat4.h +++ b/KREngine/kraken/KRMat4.h @@ -62,7 +62,7 @@ class KRMat4 { public: - float c[16]; + float c[16]; // Matrix components, in column-major order diff --git a/KREngine/kraken/KRMaterial.cpp b/KREngine/kraken/KRMaterial.cpp index 59414fb..141e177 100644 --- a/KREngine/kraken/KRMaterial.cpp +++ b/KREngine/kraken/KRMaterial.cpp @@ -240,6 +240,10 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str()); } + if(bones.size() > 0) { + bSameMaterial = false; // FINDME, HACK! - This is test code + } + if(!bSameMaterial) { KRVector2 default_scale = KRVector2(1.0f, 1.0f); KRVector2 default_offset = KRVector2(0.0f, 0.0f); @@ -283,7 +287,9 @@ bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC //printf("%s - delta translation: %.4f %.4f %.4f\n", bone->getName().c_str(), translation.x - initialTranslation.x, translation.y - initialTranslation.y, translation.z - initialTranslation.z); // printf("%s - delta scale: %.4f %.4f %.4f\n", bone->getName().c_str(), scale.x - initialScale.x, scale.y - initialScale.y, scale.z - initialScale.z); - KRMat4 t = bone->getInverseBindPoseMatrix() * bone->getModelMatrix(); + KRMat4 model_mat = bone->getActivePoseMatrix(); + KRMat4 inv_bind_mat = bone->getInverseBindPoseMatrix(); + KRMat4 t = /*KRMat4::Invert(matModel) * */(inv_bind_mat * model_mat); for(int i=0; i < 16; i++) { *bone_mat_component++ = t[i]; } diff --git a/KREngine/kraken/KRMesh.cpp b/KREngine/kraken/KRMesh.cpp index dfd3f80..875678e 100644 --- a/KREngine/kraken/KRMesh.cpp +++ b/KREngine/kraken/KRMesh.cpp @@ -271,7 +271,7 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st int start_index_offset, start_vertex_offset, index_count, vertex_count; getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size, index_data + start_index_offset, index_count * 2, has_vertex_attribute(KRENGINE_ATTRIB_VERTEX), has_vertex_attribute(KRENGINE_ATTRIB_NORMAL), has_vertex_attribute(KRENGINE_ATTRIB_TANGENT), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB), has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES), has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS), true); + m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size, index_data + start_index_offset, index_count * 2, pHeader->vertex_attrib_flags, true); int vertex_draw_count = cVertexes; if(vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset; @@ -297,7 +297,7 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st assert(cBufferVertexes <= 65535); - m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes, NULL, 0, has_vertex_attribute(KRENGINE_ATTRIB_VERTEX), has_vertex_attribute(KRENGINE_ATTRIB_NORMAL), has_vertex_attribute(KRENGINE_ATTRIB_TANGENT), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB), has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES), has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS), true); + m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes, NULL, 0, pHeader->vertex_attrib_flags, true); if(iVertex + cVertexes >= MAX_VBO_SIZE) { @@ -351,22 +351,84 @@ void KRMesh::LoadData(std::vector<__uint16_t> vertex_indexes, std::vector::iterator itr=vertices.begin(); itr != vertices.end(); itr++) { + if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f || fabsf((*itr).z) > 1.0f) { + use_short_vertexes = false; + } + } + } + + if(use_short_normals) { + for(std::vector::iterator itr=normals.begin(); itr != normals.end(); itr++) { + (*itr).normalize(); + } + } + + if(use_short_tangents) { + for(std::vector::iterator itr=tangents.begin(); itr != tangents.end(); itr++) { + (*itr).normalize(); + } + } + + if(use_short_uva) { + for(std::vector::iterator itr=uva.begin(); itr != uva.end(); itr++) { + if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) { + use_short_uva = false; + } + } + } + + if(use_short_uvb) { + for(std::vector::iterator itr=uvb.begin(); itr != uvb.end(); itr++) { + if(fabsf((*itr).x) > 1.0f || fabsf((*itr).y) > 1.0f) { + use_short_uvb = false; + } + } + } __int32_t vertex_attrib_flags = 0; if(vertices.size()) { - vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX); + if(use_short_vertexes) { + vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX_SHORT); + } else { + vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX); + } } if(normals.size() || calculate_normals) { - vertex_attrib_flags += (1 << KRENGINE_ATTRIB_NORMAL); + if(use_short_normals) { + vertex_attrib_flags += (1 << KRENGINE_ATTRIB_NORMAL_SHORT); + } else { + vertex_attrib_flags += (1 << KRENGINE_ATTRIB_NORMAL); + } } if(tangents.size() || calculate_tangents) { - vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TANGENT); + if(use_short_tangents) { + vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TANGENT_SHORT); + } else { + vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TANGENT); + } } if(uva.size()) { - vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA); + if(use_short_uva) { + vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA_SHORT); + } else { + vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA); + } } if(uvb.size()) { - vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB); + if(use_short_uvb) { + vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB_SHORT); + } else { + vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB); + } } if(bone_names.size()) { vertex_attrib_flags += (1 << KRENGINE_ATTRIB_BONEINDEXES) + (1 << KRENGINE_ATTRIB_BONEWEIGHTS); @@ -557,7 +619,13 @@ bool KRMesh::lod_sort_predicate(const KRMesh *m1, const KRMesh *m2) bool KRMesh::has_vertex_attribute(vertex_attrib_t attribute_type) const { - return (getHeader()->vertex_attrib_flags & (1 << attribute_type)) != 0; + //return (getHeader()->vertex_attrib_flags & (1 << attribute_type)) != 0; + return has_vertex_attribute(getHeader()->vertex_attrib_flags, attribute_type); +} + +bool KRMesh::has_vertex_attribute(int vertex_attrib_flags, vertex_attrib_t attribute_type) +{ + return (vertex_attrib_flags & (1 << attribute_type)) != 0; } KRMesh::pack_header *KRMesh::getHeader() const @@ -610,7 +678,10 @@ int KRMesh::getVertexCount(int submesh) const KRVector3 KRMesh::getVertexPosition(int index) const { - if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) { + short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX_SHORT]); + return KRVector3((float)v[0] / 32767.0f, (float)v[1] / 32767.0f, (float)v[2] / 32767.0f); + } else if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) { return KRVector3((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX])); } else { return KRVector3::Zero(); @@ -619,7 +690,10 @@ KRVector3 KRMesh::getVertexPosition(int index) const KRVector3 KRMesh::getVertexNormal(int index) const { - if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) { + short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL_SHORT]); + return KRVector3((float)v[0] / 32767.0f, (float)v[1] / 32767.0f, (float)v[2] / 32767.0f); + } else if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) { return KRVector3((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL])); } else { return KRVector3::Zero(); @@ -628,7 +702,10 @@ KRVector3 KRMesh::getVertexNormal(int index) const KRVector3 KRMesh::getVertexTangent(int index) const { - if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) { + short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT_SHORT]); + return KRVector3((float)v[0] / 32767.0f, (float)v[1] / 32767.0f, (float)v[2] / 32767.0f); + } else if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) { return KRVector3((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT])); } else { return KRVector3::Zero(); @@ -637,7 +714,10 @@ KRVector3 KRMesh::getVertexTangent(int index) const KRVector2 KRMesh::getVertexUVA(int index) const { - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) { + short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA_SHORT]); + return KRVector2((float)v[0] / 32767.0f, (float)v[1] / 32767.0f); + } else if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) { return KRVector2((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA])); } else { return KRVector2::Zero(); @@ -646,7 +726,10 @@ KRVector2 KRMesh::getVertexUVA(int index) const KRVector2 KRMesh::getVertexUVB(int index) const { - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) { + short *v = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB_SHORT]); + return KRVector2((float)v[0] / 32767.0f, (float)v[1] / 32767.0f); + } else if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) { return KRVector2((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB])); } else { return KRVector2::Zero(); @@ -655,40 +738,73 @@ KRVector2 KRMesh::getVertexUVB(int index) const void KRMesh::setVertexPosition(int index, const KRVector3 &v) { - float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX]); - vert[0] = v.x; - vert[1] = v.y; - vert[2] = v.z; + if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) { + short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX_SHORT]); + vert[0] = v.x * 32767.0f; + vert[1] = v.y * 32767.0f; + vert[2] = v.z * 32767.0f; + } else if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) { + float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX]); + vert[0] = v.x; + vert[1] = v.y; + vert[2] = v.z; + } } void KRMesh::setVertexNormal(int index, const KRVector3 &v) { - float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL]); - vert[0] = v.x; - vert[1] = v.y; - vert[2] = v.z; + if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) { + short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL_SHORT]); + vert[0] = v.x * 32767.0f; + vert[1] = v.y * 32767.0f; + vert[2] = v.z * 32767.0f; + } else if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) { + float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL]); + vert[0] = v.x; + vert[1] = v.y; + vert[2] = v.z; + } } void KRMesh::setVertexTangent(int index, const KRVector3 & v) { - float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT]); - vert[0] = v.x; - vert[1] = v.y; - vert[2] = v.z; + if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) { + short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT_SHORT]); + vert[0] = v.x * 32767.0f; + vert[1] = v.y * 32767.0f; + vert[2] = v.z * 32767.0f; + } else if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) { + float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT]); + vert[0] = v.x; + vert[1] = v.y; + vert[2] = v.z; + } } void KRMesh::setVertexUVA(int index, const KRVector2 &v) { - float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA]); - vert[0] = v.x; - vert[1] = v.y; + if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) { + short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA_SHORT]); + vert[0] = v.x * 32767.0f; + vert[1] = v.y * 32767.0f; + } else if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) { + float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA]); + vert[0] = v.x; + vert[1] = v.y; + } } void KRMesh::setVertexUVB(int index, const KRVector2 &v) { - float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB]); - vert[0] = v.x; - vert[1] = v.y; + if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) { + short *vert = (short *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB_SHORT]); + vert[0] = v.x * 32767.0f; + vert[1] = v.y * 32767.0f; + } else if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) { + float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB]); + vert[0] = v.x; + vert[1] = v.y; + } } @@ -719,27 +835,42 @@ void KRMesh::setBoneWeight(int index, int weight_index, float bone_weight) size_t KRMesh::VertexSizeForAttributes(__int32_t vertex_attrib_flags) { size_t data_size = 0; - if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_VERTEX)) { + if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_VERTEX)) { data_size += sizeof(float) * 3; } - if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_NORMAL)) { + if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_NORMAL)) { data_size += sizeof(float) * 3; } - if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_TANGENT)) { + if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TANGENT)) { data_size += sizeof(float) * 3; } - if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_TEXUVA)) { + if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVA)) { data_size += sizeof(float) * 2; } - if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_TEXUVB)) { + if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVB)) { data_size += sizeof(float) * 2; } - if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_BONEINDEXES)) { + if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_BONEINDEXES)) { data_size += 4; // 4 bytes } - if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_BONEWEIGHTS)) { + if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_BONEWEIGHTS)) { data_size += sizeof(float) * 4; } + if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_VERTEX_SHORT)) { + data_size += sizeof(short) * 4; // Extra short added in order to maintain 32-bit alignment. TODO, FINDME - Perhaps we can bind this as a vec4 and use the 4th component for another attribute... + } + if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_NORMAL_SHORT)) { + data_size += sizeof(short) * 4; // Extra short added in order to maintain 32-bit alignment. TODO, FINDME - Perhaps we can bind this as a vec4 and use the 4th component for another attribute... + } + if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TANGENT_SHORT)) { + data_size += sizeof(short) * 4; // Extra short added in order to maintain 32-bit alignment. TODO, FINDME - Perhaps we can bind this as a vec4 and use the 4th component for another attribute... + } + if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVA_SHORT)) { + data_size += sizeof(short) * 2; + } + if(has_vertex_attribute(vertex_attrib_flags, KRENGINE_ATTRIB_TEXUVB_SHORT)) { + data_size += sizeof(short) * 2; + } return data_size; } @@ -929,6 +1060,9 @@ bool KRMesh::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitin void KRMesh::convertToIndexed() { + + char *szKey = new char[m_vertex_size * 2 + 1]; + // Convert model to indexed vertices, identying vertexes with identical attributes and optimizing order of trianges for best usage post-vertex-transform cache on GPU std::vector<__uint16_t> vertex_indexes; std::vector > vertex_index_bases; @@ -975,12 +1109,13 @@ void KRMesh::convertToIndexed() while(vertexes_remaining) { - std::map, std::vector >, int> prev_indexes = std::map, std::vector >, int>(); + //typedef std::pair, std::vector > vertex_key_t; + typedef std::string vertex_key_t; + + unordered_map prev_indexes = unordered_map(); for(int i=0; i < vertex_count; i++) { - - KRVector3 vertex_position = getVertexPosition(source_index); KRVector2 vertex_uva = getVertexUVA(source_index); KRVector2 vertex_uvb = getVertexUVB(source_index); @@ -1001,26 +1136,40 @@ void KRMesh::convertToIndexed() vertex_bone_weights.push_back(getBoneWeight(source_index, 3)); } - std::pair, std::vector > vertex_key; // = std::make_pair(std::vector(), std::vector()); - if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) { + + + unsigned char *vertex_data = (unsigned char *)getVertexData(source_index); + for(int b=0; b < m_vertex_size; b++) { + const char *szHex = "0123456789ABCDEF"; + szKey[b*2] = szHex[vertex_data[b] & 0x0f]; + szKey[b*2+1] = szHex[((vertex_data[b] & 0xf0) >> 4)]; + } + szKey[m_vertex_size * 2] = '\0'; + + vertex_key_t vertex_key = szKey; + /* + + vertex_key_t vertex_key = std::make_pair(std::vector(), std::vector()); + + if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX) || has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) { vertex_key.first.push_back(vertex_position.x); vertex_key.first.push_back(vertex_position.y); vertex_key.first.push_back(vertex_position.z); } - if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL) || has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) { vertex_key.first.push_back(vertex_normal.x); vertex_key.first.push_back(vertex_normal.y); vertex_key.first.push_back(vertex_normal.z); } - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) { vertex_key.first.push_back(vertex_uva.x); vertex_key.first.push_back(vertex_uva.y); } - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) { vertex_key.first.push_back(vertex_uvb.x); vertex_key.first.push_back(vertex_uvb.y); } - if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT) || has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) { vertex_key.first.push_back(vertex_tangent.x); vertex_key.first.push_back(vertex_tangent.y); vertex_key.first.push_back(vertex_tangent.z); @@ -1037,23 +1186,23 @@ void KRMesh::convertToIndexed() vertex_key.first.push_back(vertex_bone_weights[2]); vertex_key.first.push_back(vertex_bone_weights[3]); } - + */ int found_index = -1; if(prev_indexes.count(vertex_key) == 0) { found_index = vertices.size() - vertex_index_base_start_vertex; - if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX) || has_vertex_attribute(KRENGINE_ATTRIB_VERTEX_SHORT)) { vertices.push_back(vertex_position); } - if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL) || has_vertex_attribute(KRENGINE_ATTRIB_NORMAL_SHORT)) { normals.push_back(vertex_normal); } - if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT) || has_vertex_attribute(KRENGINE_ATTRIB_TANGENT_SHORT)) { tangents.push_back(vertex_tangent); } - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA_SHORT)) { uva.push_back(vertex_uva); } - if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) { + if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB) || has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB_SHORT)) { uvb.push_back(vertex_uvb); } if(has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES)) { @@ -1091,8 +1240,12 @@ void KRMesh::convertToIndexed() } } + delete szKey; + fprintf(stderr, "Convert to indexed, before: %i after: %i \(%.2f%% saving)\n", getHeader()->vertex_count, vertices.size(), ((float)getHeader()->vertex_count - (float)vertices.size()) / (float)getHeader()->vertex_count * 100.0f); + + LoadData(vertex_indexes, vertex_index_bases, vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights, KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES, false, false); } @@ -1228,27 +1381,4 @@ void KRMesh::optimizeIndexes() free(new_indices); free(vertex_mapping); free(new_vertex_data); - - /* - - - if(getModelFormat() == KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) { - - int cVertexes = pSubmesh->vertex_count; - //fprintf(stderr, "start - object: %s material: %s vertices: %i\n", object_name.c_str(), material_name.c_str(), cVertexes); - - __uint16_t *index_data = getIndexData(); - int submesh_index_group = 0; - while(cVertexes > 0) { - - int start_index_offset, start_vertex_offset, index_count, vertex_count; - getIndexedRange(iSubmesh, submesh_index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - - m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, m_vertex_size * vertex_count, index_data + start_index_offset, index_count * 4, has_vertex_attribute(KRENGINE_ATTRIB_VERTEX), has_vertex_attribute(KRENGINE_ATTRIB_NORMAL), has_vertex_attribute(KRENGINE_ATTRIB_TANGENT), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB), has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES), has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS), true); - - glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_SHORT, 0); - cVertexes -= index_count; - } - - */ } diff --git a/KREngine/kraken/KRMesh.h b/KREngine/kraken/KRMesh.h index f6d07b1..bf5b9a1 100644 --- a/KREngine/kraken/KRMesh.h +++ b/KREngine/kraken/KRMesh.h @@ -72,6 +72,11 @@ public: KRENGINE_ATTRIB_TEXUVB, KRENGINE_ATTRIB_BONEINDEXES, KRENGINE_ATTRIB_BONEWEIGHTS, + KRENGINE_ATTRIB_VERTEX_SHORT, + KRENGINE_ATTRIB_NORMAL_SHORT, + KRENGINE_ATTRIB_TANGENT_SHORT, + KRENGINE_ATTRIB_TEXUVA_SHORT, + KRENGINE_ATTRIB_TEXUVB_SHORT, KRENGINE_NUM_ATTRIBUTES } vertex_attrib_t; @@ -112,26 +117,7 @@ public: GLsizei vertex_count; char szMaterialName[KRENGINE_MAX_NAME_LENGTH]; } Submesh; - - typedef struct { - GLfloat x; - GLfloat y; - GLfloat z; - } KRVector3D; - - typedef struct { - GLfloat u; - GLfloat v; - } TexCoord; - - typedef struct { - KRVector3D vertex; - KRVector3D normal; - KRVector3D tangent; - TexCoord uva; - TexCoord uvb; - } VertexData; - + typedef struct { union { struct { // For Indexed triangles / strips @@ -154,6 +140,7 @@ public: static bool lod_sort_predicate(const KRMesh *m1, const KRMesh *m2); bool has_vertex_attribute(vertex_attrib_t attribute_type) const; + static bool has_vertex_attribute(int vertex_attrib_flags, vertex_attrib_t attribute_type); int getSubmeshCount() const; int getVertexCount(int submesh) const; diff --git a/KREngine/kraken/KRMeshManager.cpp b/KREngine/kraken/KRMeshManager.cpp index fbb7b31..7f9b607 100644 --- a/KREngine/kraken/KRMeshManager.cpp +++ b/KREngine/kraken/KRMeshManager.cpp @@ -146,9 +146,8 @@ void KRMeshManager::releaseVBO(GLvoid *data) } } -void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights, bool static_vbo) { - - +void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, int vertex_attrib_flags, bool static_vbo) { + if(m_currentVBO.data != data || m_currentVBO.size != size + index_data_size) { if(m_vbosActive.find(data) != m_vbosActive.end()) { @@ -157,7 +156,7 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); #else GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle)); - configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb, enable_bone_indexes, enable_bone_weights); + configureAttribs(vertex_attrib_flags); if(m_currentVBO.vbo_handle_indexes == -1) { GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } else { @@ -172,7 +171,7 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); #else GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle)); - configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb, enable_bone_indexes, enable_bone_weights); + configureAttribs(vertex_attrib_flags); if(m_currentVBO.vbo_handle_indexes == -1) { GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } else { @@ -218,7 +217,7 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G GLDEBUG(glBufferData(GL_ARRAY_BUFFER, size, data, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); m_memoryTransferredThisFrame += size; m_vboMemUsed += size; - configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb, enable_bone_indexes, enable_bone_weights); + configureAttribs(vertex_attrib_flags); m_currentVBO.size = size; m_currentVBO.data = data; @@ -238,82 +237,73 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G } } -void KRMeshManager::configureAttribs(bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights) +void KRMeshManager::configureAttribs(__int32_t attributes) { - __int32_t attributes = 0; + GLsizei data_size = (GLsizei)KRMesh::VertexSizeForAttributes(attributes); - if(enable_vertex) { - attributes |= (1 << KRMesh::KRENGINE_ATTRIB_VERTEX); + if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_VERTEX_SHORT)) { GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_VERTEX)); + GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_VERTEX, 3, GL_SHORT, GL_TRUE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_VERTEX_SHORT, attributes)))); + } else if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_VERTEX)) { + GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_VERTEX)); + GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_VERTEX, attributes)))); } else { GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_VERTEX)); } - - if(enable_normal) { - attributes |= (1 << KRMesh::KRENGINE_ATTRIB_NORMAL); + + if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_NORMAL_SHORT)) { GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_NORMAL)); + GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_NORMAL, 3, GL_SHORT, GL_TRUE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_NORMAL_SHORT, attributes)))); + } else if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_NORMAL)) { + GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_NORMAL)); + GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_NORMAL, attributes)))); } else { GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_NORMAL)); } - - if(enable_tangent) { - attributes |= (1 << KRMesh::KRENGINE_ATTRIB_TANGENT); + + if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_TANGENT_SHORT)) { GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TANGENT)); + GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TANGENT, 3, GL_SHORT, GL_TRUE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TANGENT_SHORT, attributes)))); + } else if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_TANGENT)) { + GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TANGENT)); + GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TANGENT, attributes)))); } else { GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TANGENT)); } - - if(enable_uva) { - attributes |= (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); + + if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_TEXUVA_SHORT)) { GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVA)); + GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TEXUVA, 2, GL_SHORT, GL_TRUE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TEXUVA_SHORT, attributes)))); + } else if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_TEXUVA)) { + GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVA)); + GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TEXUVA, attributes)))); } else { GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVA)); } - - if(enable_uvb) { - attributes |= (1 << KRMesh::KRENGINE_ATTRIB_TEXUVB); + + if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_TEXUVB_SHORT)) { GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVB)); + GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TEXUVB, 2, GL_SHORT, GL_TRUE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TEXUVB_SHORT, attributes)))); + } else if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_TEXUVB)) { + GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVB)); + GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TEXUVB, 2, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TEXUVB, attributes)))); } else { GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_TEXUVB)); } - if(enable_bone_indexes) { - attributes |= (1 << KRMesh::KRENGINE_ATTRIB_BONEINDEXES); + if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_BONEINDEXES)) { GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_BONEINDEXES)); + GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_BONEINDEXES, 4, GL_UNSIGNED_BYTE, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_BONEINDEXES, attributes)))); } else { GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_BONEINDEXES)); } - if(enable_bone_weights) { - attributes |= (1 << KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS); + if(KRMesh::has_vertex_attribute(attributes, KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS)) { GLDEBUG(glEnableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS)); + GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS, 4, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS, attributes)))); } else { GLDEBUG(glDisableVertexAttribArray(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS)); } - - GLsizei data_size = (GLsizei)KRMesh::VertexSizeForAttributes(attributes); - - if(enable_vertex) { - GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_VERTEX, attributes)))); - } - if(enable_normal) { - GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_NORMAL, attributes)))); - } - if(enable_tangent) { - GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TANGENT, attributes)))); - } - if(enable_uva) { - GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TEXUVA, attributes)))); - } - if(enable_uvb) { - GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_TEXUVB, 2, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_TEXUVB, attributes)))); - } - if(enable_bone_indexes ) { - GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_BONEINDEXES, 4, GL_UNSIGNED_BYTE, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_BONEINDEXES, attributes)))); - } - if(enable_bone_weights) { - GLDEBUG(glVertexAttribPointer(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS, 4, GL_FLOAT, GL_FALSE, data_size, BUFFER_OFFSET(KRMesh::AttributeOffset(KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS, attributes)))); - } } long KRMeshManager::getMemUsed() diff --git a/KREngine/kraken/KRMeshManager.h b/KREngine/kraken/KRMeshManager.h index a5214ed..6e17df4 100644 --- a/KREngine/kraken/KRMeshManager.h +++ b/KREngine/kraken/KRMeshManager.h @@ -59,15 +59,13 @@ public: std::vector getModelNames(); unordered_multimap &getModels(); - - void bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights, bool static_vbo); + void bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, int vertex_attrib_flags, bool static_vbo); void releaseVBO(GLvoid *data); void unbindVBO(); long getMemUsed(); long getMemActive(); - void configureAttribs(bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights); - + void configureAttribs(__int32_t attributes); typedef struct { GLfloat x; diff --git a/KREngine/kraken/KRNode.cpp b/KREngine/kraken/KRNode.cpp index a2d53ec..32157c7 100644 --- a/KREngine/kraken/KRNode.cpp +++ b/KREngine/kraken/KRNode.cpp @@ -30,15 +30,22 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont m_localScale = KRVector3::One(); m_localRotation = KRVector3::Zero(); m_localTranslation = KRVector3::Zero(); + m_initialLocalTranslation = m_localTranslation; + m_initialLocalScale = m_localScale; + m_initialLocalRotation = m_localRotation; + m_parentNode = NULL; m_pScene = &scene; m_modelMatrixValid = false; m_inverseModelMatrixValid = false; m_bindPoseMatrixValid = false; + m_activePoseMatrixValid = false; m_inverseBindPoseMatrixValid = false; m_modelMatrix = KRMat4(); m_bindPoseMatrix = KRMat4(); + m_activePoseMatrix = KRMat4(); m_lod_visible = false; + m_scale_compensation = false; } KRNode::~KRNode() { @@ -53,6 +60,19 @@ KRNode::~KRNode() { } +void KRNode::setScaleCompensation(bool scale_compensation) +{ + if(m_scale_compensation != scale_compensation) { + m_scale_compensation = scale_compensation; + invalidateModelMatrix(); + invalidateBindPoseMatrix(); + } +} +bool KRNode::getScaleCompensation() +{ + return m_scale_compensation; +} + void KRNode::childDeleted(KRNode *child_node) { m_childNodes.erase(child_node); @@ -75,15 +95,18 @@ tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) { tinyxml2::XMLElement *e = doc->NewElement(getElementName().c_str()); tinyxml2::XMLNode *n = parent->InsertEndChild(e); e->SetAttribute("name", m_name.c_str()); - e->SetAttribute("translate_x", m_localTranslation.x); // TODO - Increase number of digits after the decimal in floating point format (6 -> 12?) - e->SetAttribute("translate_y", m_localTranslation.y); - e->SetAttribute("translate_z", m_localTranslation.z); - e->SetAttribute("scale_x", m_localScale.x); - e->SetAttribute("scale_y", m_localScale.y); - e->SetAttribute("scale_z", m_localScale.z); - e->SetAttribute("rotate_x", m_localRotation.x * 180 / M_PI); - e->SetAttribute("rotate_y", m_localRotation.y * 180 / M_PI); - e->SetAttribute("rotate_z", m_localRotation.z * 180 / M_PI); + m_localTranslation.setXMLAttribute("translate", e); + m_localScale.setXMLAttribute("scale", e); + (m_localRotation * (180.0f / M_PI)).setXMLAttribute("rotate", e); + + + m_rotationOffset.setXMLAttribute("rotate_offset", e); + m_scalingOffset.setXMLAttribute("scale_offset", e); + m_rotationPivot.setXMLAttribute("rotate_pivot", e); + m_scalingPivot.setXMLAttribute("scale_pivot", e); + (m_preRotation * (180.0f / M_PI)).setXMLAttribute("pre_rotate", e); + (m_postRotation * (180.0f / M_PI)).setXMLAttribute("post_rotate", e); + for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { KRNode *child = (*itr); child->saveXML(n); @@ -93,26 +116,35 @@ tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) { void KRNode::loadXML(tinyxml2::XMLElement *e) { m_name = e->Attribute("name"); - float x,y,z; - e->QueryFloatAttribute("translate_x", &x); - e->QueryFloatAttribute("translate_y", &y); - e->QueryFloatAttribute("translate_z", &z); - m_localTranslation = KRVector3(x,y,z); + m_localTranslation.getXMLAttribute("translate", e, KRVector3::Zero()); + m_localScale.getXMLAttribute("scale", e, KRVector3::One()); + m_localRotation.getXMLAttribute("rotate", e, KRVector3::Zero()); + m_localRotation *= M_PI / 180.0f; // Convert degrees to radians + m_preRotation.getXMLAttribute("pre_rotate", e, KRVector3::Zero()); + m_preRotation *= M_PI / 180.0f; // Convert degrees to radians + m_postRotation.getXMLAttribute("post_rotate", e, KRVector3::Zero()); + m_postRotation *= M_PI / 180.0f; // Convert degrees to radians + + + m_rotationOffset.getXMLAttribute("rotate_offset", e, KRVector3::Zero()); + m_scalingOffset.getXMLAttribute("scale_offset", e, KRVector3::Zero()); + m_rotationPivot.getXMLAttribute("rotate_pivot", e, KRVector3::Zero()); + m_scalingPivot.getXMLAttribute("scale_pivot", e, KRVector3::Zero()); + + m_initialLocalTranslation = m_localTranslation; - - e->QueryFloatAttribute("scale_x", &x); - e->QueryFloatAttribute("scale_y", &y); - e->QueryFloatAttribute("scale_z", &z); - m_localScale = KRVector3(x,y,z); m_initialLocalScale = m_localScale; - - e->QueryFloatAttribute("rotate_x", &x); - e->QueryFloatAttribute("rotate_y", &y); - e->QueryFloatAttribute("rotate_z", &z); - m_localRotation = KRVector3(x,y,z) / 180.0 * M_PI; // Convert degrees to radians m_initialLocalRotation = m_localRotation; + m_initialRotationOffset = m_rotationOffset; + m_initialScalingOffset = m_scalingOffset; + m_initialRotationPivot = m_rotationPivot; + m_initialScalingPivot = m_scalingPivot; + m_initialPreRotation = m_preRotation; + m_initialPostRotation = m_postRotation; + m_bindPoseMatrixValid = false; + m_activePoseMatrixValid = false; m_inverseBindPoseMatrixValid = false; m_modelMatrixValid = false; m_inverseModelMatrixValid = false; @@ -183,6 +215,113 @@ void KRNode::setLocalRotation(const KRVector3 &v, bool set_original) { invalidateModelMatrix(); } + +void KRNode::setRotationOffset(const KRVector3 &v, bool set_original) +{ + m_rotationOffset = v; + if(set_original) { + m_initialRotationOffset = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} + +void KRNode::setScalingOffset(const KRVector3 &v, bool set_original) +{ + m_scalingOffset = v; + if(set_original) { + m_initialScalingOffset = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} + +void KRNode::setRotationPivot(const KRVector3 &v, bool set_original) +{ + m_rotationPivot = v; + if(set_original) { + m_initialRotationPivot = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} +void KRNode::setScalingPivot(const KRVector3 &v, bool set_original) +{ + m_scalingPivot = v; + if(set_original) { + m_initialScalingPivot = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} +void KRNode::setPreRotation(const KRVector3 &v, bool set_original) +{ + m_preRotation = v; + if(set_original) { + m_initialPreRotation = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} +void KRNode::setPostRotation(const KRVector3 &v, bool set_original) +{ + m_postRotation = v; + if(set_original) { + m_initialPostRotation = v; + invalidateBindPoseMatrix(); + } + invalidateModelMatrix(); +} + +const KRVector3 &KRNode::getRotationOffset() +{ + return m_rotationOffset; +} +const KRVector3 &KRNode::getScalingOffset() +{ + return m_scalingOffset; +} +const KRVector3 &KRNode::getRotationPivot() +{ + return m_rotationPivot; +} +const KRVector3 &KRNode::getScalingPivot() +{ + return m_scalingPivot; +} +const KRVector3 &KRNode::getPreRotation() +{ + return m_preRotation; +} +const KRVector3 &KRNode::getPostRotation() +{ + return m_postRotation; +} +const KRVector3 &KRNode::getInitialRotationOffset() +{ + return m_initialRotationOffset; +} +const KRVector3 &KRNode::getInitialScalingOffset() +{ + return m_initialScalingOffset; +} +const KRVector3 &KRNode::getInitialRotationPivot() +{ + return m_initialRotationPivot; +} +const KRVector3 &KRNode::getInitialScalingPivot() +{ + return m_initialScalingPivot; +} +const KRVector3 &KRNode::getInitialPreRotation() +{ + return m_initialPreRotation; +} +const KRVector3 &KRNode::getInitialPostRotation() +{ + return m_initialPostRotation; +} + const KRVector3 &KRNode::getLocalTranslation() { return m_localTranslation; } @@ -211,7 +350,7 @@ const KRVector3 KRNode::getWorldScale() { return KRMat4::DotNoTranslate(getModelMatrix(), m_localScale); } const KRVector3 KRNode::getWorldRotation() { - KRVector3 world_rotation = m_localRotation; + KRVector3 world_rotation = (-KRQuaternion(m_postRotation) * KRQuaternion(m_localRotation) * KRQuaternion(m_preRotation)).eulerXYZ();; if(m_parentNode) { KRVector3 parent_rotation = m_parentNode->getWorldRotation(); world_rotation = (KRQuaternion(world_rotation) * KRQuaternion(parent_rotation)).eulerXYZ(); @@ -219,6 +358,24 @@ const KRVector3 KRNode::getWorldRotation() { return world_rotation; } +const KRVector3 KRNode::getBindPoseWorldRotation() { + KRVector3 world_rotation = (-KRQuaternion(m_initialPostRotation) * KRQuaternion(m_initialLocalRotation) * KRQuaternion(m_initialPreRotation)).eulerXYZ(); + if(dynamic_cast(m_parentNode)) { + KRVector3 parent_rotation = m_parentNode->getBindPoseWorldRotation(); + world_rotation = (KRQuaternion(world_rotation) * KRQuaternion(parent_rotation)).eulerXYZ(); + } + return world_rotation; +} + +const KRVector3 KRNode::getActivePoseWorldRotation() { + KRVector3 world_rotation = (KRQuaternion(m_preRotation) * KRQuaternion(m_localRotation) * -KRQuaternion(m_postRotation)).eulerXYZ(); + if(dynamic_cast(m_parentNode)) { + KRVector3 parent_rotation = m_parentNode->getActivePoseWorldRotation(); + world_rotation = (KRQuaternion(world_rotation) * KRQuaternion(parent_rotation)).eulerXYZ(); + } + return world_rotation; +} + std::string KRNode::getElementName() { return "node"; } @@ -310,6 +467,7 @@ KRAABB KRNode::getBounds() { void KRNode::invalidateModelMatrix() { m_modelMatrixValid = false; + m_activePoseMatrixValid = false; m_inverseModelMatrixValid = false; for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { KRNode *child = (*itr); @@ -335,15 +493,62 @@ const KRMat4 &KRNode::getModelMatrix() if(!m_modelMatrixValid) { m_modelMatrix = KRMat4(); - - m_modelMatrix.scale(m_localScale); - m_modelMatrix.rotate(m_localRotation.x, X_AXIS); - m_modelMatrix.rotate(m_localRotation.y, Y_AXIS); - m_modelMatrix.rotate(m_localRotation.z, Z_AXIS); - m_modelMatrix.translate(m_localTranslation); - if(m_parentNode) { - m_modelMatrix *= m_parentNode->getModelMatrix(); + bool parent_is_bone = false; + if(dynamic_cast(m_parentNode)) { + parent_is_bone = true; + } + + if(getScaleCompensation() && parent_is_bone) { + m_modelMatrix.translate(-m_scalingPivot); + m_modelMatrix.scale(m_localScale); + m_modelMatrix.translate(m_scalingPivot); + m_modelMatrix.translate(m_scalingOffset); + m_modelMatrix.translate(-m_rotationPivot); + m_modelMatrix.rotate(-m_postRotation.z, Z_AXIS); + m_modelMatrix.rotate(-m_postRotation.y, Y_AXIS); + m_modelMatrix.rotate(-m_postRotation.x, X_AXIS); + m_modelMatrix.rotate(m_localRotation.x, X_AXIS); + m_modelMatrix.rotate(m_localRotation.y, Y_AXIS); + m_modelMatrix.rotate(m_localRotation.z, Z_AXIS); + m_modelMatrix.rotate(m_preRotation.x, X_AXIS); + m_modelMatrix.rotate(m_preRotation.y, Y_AXIS); + m_modelMatrix.rotate(m_preRotation.z, Z_AXIS); + m_modelMatrix.translate(m_rotationPivot); + m_modelMatrix.translate(m_rotationOffset); + //m_modelMatrix.translate(m_localTranslation); + if(m_parentNode) { + + m_modelMatrix.rotate(m_parentNode->getWorldRotation()); + m_modelMatrix.translate(KRMat4::Dot(m_parentNode->getModelMatrix(), m_localTranslation)); + } else { + m_modelMatrix.translate(m_localTranslation); + } + } else { + + // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 + m_modelMatrix.translate(-m_scalingPivot); + m_modelMatrix.scale(m_localScale); + m_modelMatrix.translate(m_scalingPivot); + m_modelMatrix.translate(m_scalingOffset); + m_modelMatrix.translate(-m_rotationPivot); + m_modelMatrix.rotate(-m_postRotation.z, Z_AXIS); + m_modelMatrix.rotate(-m_postRotation.y, Y_AXIS); + m_modelMatrix.rotate(-m_postRotation.x, X_AXIS); + m_modelMatrix.rotate(m_localRotation.x, X_AXIS); + m_modelMatrix.rotate(m_localRotation.y, Y_AXIS); + m_modelMatrix.rotate(m_localRotation.z, Z_AXIS); + m_modelMatrix.rotate(m_preRotation.x, X_AXIS); + m_modelMatrix.rotate(m_preRotation.y, Y_AXIS); + m_modelMatrix.rotate(m_preRotation.z, Z_AXIS); + m_modelMatrix.translate(m_rotationPivot); + m_modelMatrix.translate(m_rotationOffset); + m_modelMatrix.translate(m_localTranslation); + + + if(m_parentNode) { + m_modelMatrix *= m_parentNode->getModelMatrix(); + } } m_modelMatrixValid = true; @@ -352,6 +557,143 @@ const KRMat4 &KRNode::getModelMatrix() return m_modelMatrix; } +const KRMat4 &KRNode::getBindPoseMatrix() +{ + if(!m_bindPoseMatrixValid) { + m_bindPoseMatrix = KRMat4(); + + bool parent_is_bone = false; + if(dynamic_cast(m_parentNode)) { + parent_is_bone = true; + } + + if(getScaleCompensation() && parent_is_bone) { + m_bindPoseMatrix.translate(-m_initialScalingPivot); + m_bindPoseMatrix.scale(m_initialLocalScale); + m_bindPoseMatrix.translate(m_initialScalingPivot); + m_bindPoseMatrix.translate(m_initialScalingOffset); + m_bindPoseMatrix.translate(-m_initialRotationPivot); + m_bindPoseMatrix.rotate(-m_initialPostRotation.z, Z_AXIS); + m_bindPoseMatrix.rotate(-m_initialPostRotation.y, Y_AXIS); + m_bindPoseMatrix.rotate(-m_initialPostRotation.x, X_AXIS); + m_bindPoseMatrix.rotate(m_initialLocalRotation.x, X_AXIS); + m_bindPoseMatrix.rotate(m_initialLocalRotation.y, Y_AXIS); + m_bindPoseMatrix.rotate(m_initialLocalRotation.z, Z_AXIS); + m_bindPoseMatrix.rotate(m_initialPreRotation.x, X_AXIS); + m_bindPoseMatrix.rotate(m_initialPreRotation.y, Y_AXIS); + m_bindPoseMatrix.rotate(m_initialPreRotation.z, Z_AXIS); + m_bindPoseMatrix.translate(m_initialRotationPivot); + m_bindPoseMatrix.translate(m_initialRotationOffset); + //m_bindPoseMatrix.translate(m_localTranslation); + if(m_parentNode) { + + m_bindPoseMatrix.rotate(m_parentNode->getBindPoseWorldRotation()); + m_bindPoseMatrix.translate(KRMat4::Dot(m_parentNode->getBindPoseMatrix(), m_localTranslation)); + } else { + m_bindPoseMatrix.translate(m_localTranslation); + } + } else { + + // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 + m_bindPoseMatrix.translate(-m_scalingPivot); + m_bindPoseMatrix.scale(m_localScale); + m_bindPoseMatrix.translate(m_scalingPivot); + m_bindPoseMatrix.translate(m_scalingOffset); + m_bindPoseMatrix.translate(-m_rotationPivot); + m_bindPoseMatrix.rotate(-m_postRotation.z, Z_AXIS); + m_bindPoseMatrix.rotate(-m_postRotation.y, Y_AXIS); + m_bindPoseMatrix.rotate(-m_postRotation.x, X_AXIS); + m_bindPoseMatrix.rotate(m_localRotation.x, X_AXIS); + m_bindPoseMatrix.rotate(m_localRotation.y, Y_AXIS); + m_bindPoseMatrix.rotate(m_localRotation.z, Z_AXIS); + m_bindPoseMatrix.rotate(m_preRotation.x, X_AXIS); + m_bindPoseMatrix.rotate(m_preRotation.y, Y_AXIS); + m_bindPoseMatrix.rotate(m_preRotation.z, Z_AXIS); + m_bindPoseMatrix.translate(m_rotationPivot); + m_bindPoseMatrix.translate(m_rotationOffset); + m_bindPoseMatrix.translate(m_localTranslation); + + + if(m_parentNode && parent_is_bone) { + m_bindPoseMatrix *= m_parentNode->getBindPoseMatrix(); + } + } + + m_bindPoseMatrixValid = true; + + } + return m_bindPoseMatrix; +} + +const KRMat4 &KRNode::getActivePoseMatrix() +{ + + if(!m_activePoseMatrixValid) { + m_activePoseMatrix = KRMat4(); + + bool parent_is_bone = false; + if(dynamic_cast(m_parentNode)) { + parent_is_bone = true; + } + + if(getScaleCompensation() && parent_is_bone) { + m_activePoseMatrix.translate(-m_scalingPivot); + m_activePoseMatrix.scale(m_localScale); + m_activePoseMatrix.translate(m_scalingPivot); + m_activePoseMatrix.translate(m_scalingOffset); + m_activePoseMatrix.translate(-m_rotationPivot); + m_activePoseMatrix.rotate(-m_postRotation.z, Z_AXIS); + m_activePoseMatrix.rotate(-m_postRotation.y, Y_AXIS); + m_activePoseMatrix.rotate(-m_postRotation.x, X_AXIS); + m_activePoseMatrix.rotate(m_localRotation.x, X_AXIS); + m_activePoseMatrix.rotate(m_localRotation.y, Y_AXIS); + m_activePoseMatrix.rotate(m_localRotation.z, Z_AXIS); + m_activePoseMatrix.rotate(m_preRotation.x, X_AXIS); + m_activePoseMatrix.rotate(m_preRotation.y, Y_AXIS); + m_activePoseMatrix.rotate(m_preRotation.z, Z_AXIS); + m_activePoseMatrix.translate(m_rotationPivot); + m_activePoseMatrix.translate(m_rotationOffset); + if(m_parentNode) { + + m_activePoseMatrix.rotate(m_parentNode->getWorldRotation()); + m_activePoseMatrix.translate(KRMat4::Dot(m_parentNode->getActivePoseMatrix(), m_localTranslation)); + } else { + m_activePoseMatrix.translate(m_localTranslation); + } + } else { + + // WorldTransform = ParentWorldTransform * T * Roff * Rp * Rpre * R * Rpost * Rp-1 * Soff * Sp * S * Sp-1 + m_activePoseMatrix.translate(-m_scalingPivot); + m_activePoseMatrix.scale(m_localScale); + m_activePoseMatrix.translate(m_scalingPivot); + m_activePoseMatrix.translate(m_scalingOffset); + m_activePoseMatrix.translate(-m_rotationPivot); + m_activePoseMatrix.rotate(-m_postRotation.z, Z_AXIS); + m_activePoseMatrix.rotate(-m_postRotation.y, Y_AXIS); + m_activePoseMatrix.rotate(-m_postRotation.x, X_AXIS); + m_activePoseMatrix.rotate(m_localRotation.x, X_AXIS); + m_activePoseMatrix.rotate(m_localRotation.y, Y_AXIS); + m_activePoseMatrix.rotate(m_localRotation.z, Z_AXIS); + m_activePoseMatrix.rotate(m_preRotation.x, X_AXIS); + m_activePoseMatrix.rotate(m_preRotation.y, Y_AXIS); + m_activePoseMatrix.rotate(m_preRotation.z, Z_AXIS); + m_activePoseMatrix.translate(m_rotationPivot); + m_activePoseMatrix.translate(m_rotationOffset); + m_activePoseMatrix.translate(m_localTranslation); + + + if(m_parentNode && parent_is_bone) { + m_activePoseMatrix *= m_parentNode->getActivePoseMatrix(); + } + } + + m_activePoseMatrixValid = true; + + } + return m_activePoseMatrix; + +} + const KRMat4 &KRNode::getInverseModelMatrix() { if(!m_inverseModelMatrixValid) { @@ -360,29 +702,6 @@ const KRMat4 &KRNode::getInverseModelMatrix() return m_inverseModelMatrix; } -const KRMat4 &KRNode::getBindPoseMatrix() -{ - if(!m_bindPoseMatrixValid) { - m_bindPoseMatrix = KRMat4(); - - - m_bindPoseMatrix.scale(m_initialLocalScale); - m_bindPoseMatrix.rotate(m_initialLocalRotation.x, X_AXIS); - m_bindPoseMatrix.rotate(m_initialLocalRotation.y, Y_AXIS); - m_bindPoseMatrix.rotate(m_initialLocalRotation.z, Z_AXIS); - m_bindPoseMatrix.translate(m_initialLocalTranslation); - - KRBone *parentBone = dynamic_cast(m_parentNode); - if(parentBone) { - - m_bindPoseMatrix *= parentBone->getBindPoseMatrix(); - } - - m_bindPoseMatrixValid = true; - } - return m_bindPoseMatrix; -} - const KRMat4 &KRNode::getInverseBindPoseMatrix() { if(!m_inverseBindPoseMatrixValid ) { diff --git a/KREngine/kraken/KRNode.h b/KREngine/kraken/KRNode.h index 3176699..e03f8f9 100644 --- a/KREngine/kraken/KRNode.h +++ b/KREngine/kraken/KRNode.h @@ -62,6 +62,29 @@ public: void setLocalScale(const KRVector3 &v, bool set_original = false); void setLocalRotation(const KRVector3 &v, bool set_original = false); + + void setRotationOffset(const KRVector3 &v, bool set_original = false); + void setScalingOffset(const KRVector3 &v, bool set_original = false); + void setRotationPivot(const KRVector3 &v, bool set_original = false); + void setScalingPivot(const KRVector3 &v, bool set_original = false); + void setPreRotation(const KRVector3 &v, bool set_original = false); + void setPostRotation(const KRVector3 &v, bool set_original = false); + + const KRVector3 &getRotationOffset(); + const KRVector3 &getScalingOffset(); + const KRVector3 &getRotationPivot(); + const KRVector3 &getScalingPivot(); + const KRVector3 &getPreRotation(); + const KRVector3 &getPostRotation(); + + const KRVector3 &getInitialRotationOffset(); + const KRVector3 &getInitialScalingOffset(); + const KRVector3 &getInitialRotationPivot(); + const KRVector3 &getInitialScalingPivot(); + const KRVector3 &getInitialPreRotation(); + const KRVector3 &getInitialPostRotation(); + + const KRVector3 &getLocalTranslation(); const KRVector3 &getLocalScale(); const KRVector3 &getLocalRotation(); @@ -74,6 +97,9 @@ public: const KRVector3 getWorldScale(); const KRVector3 getWorldRotation(); + const KRVector3 getBindPoseWorldRotation(); + const KRVector3 getActivePoseWorldRotation(); + const KRVector3 localToWorld(const KRVector3 &local_point); const KRVector3 worldToLocal(const KRVector3 &world_point); @@ -85,6 +111,7 @@ public: const KRMat4 &getModelMatrix(); const KRMat4 &getInverseModelMatrix(); const KRMat4 &getBindPoseMatrix(); + const KRMat4 &getActivePoseMatrix(); const KRMat4 &getInverseBindPoseMatrix(); enum node_attribute_type { @@ -112,16 +139,31 @@ public: virtual void updateLODVisibility(const KRViewport &viewport); bool lodIsVisible(); + void setScaleCompensation(bool scale_compensation); + bool getScaleCompensation(); + protected: KRVector3 m_localTranslation; KRVector3 m_localScale; KRVector3 m_localRotation; + KRVector3 m_rotationOffset; + KRVector3 m_scalingOffset; + KRVector3 m_rotationPivot; + KRVector3 m_scalingPivot; + KRVector3 m_preRotation; + KRVector3 m_postRotation; + KRVector3 m_initialLocalTranslation; KRVector3 m_initialLocalScale; KRVector3 m_initialLocalRotation; - + KRVector3 m_initialRotationOffset; + KRVector3 m_initialScalingOffset; + KRVector3 m_initialRotationPivot; + KRVector3 m_initialScalingPivot; + KRVector3 m_initialPreRotation; + KRVector3 m_initialPostRotation; bool m_lod_visible; void hideLOD(); @@ -138,10 +180,12 @@ private: KRMat4 m_modelMatrix; KRMat4 m_inverseModelMatrix; KRMat4 m_bindPoseMatrix; + KRMat4 m_activePoseMatrix; KRMat4 m_inverseBindPoseMatrix; bool m_modelMatrixValid; bool m_inverseModelMatrixValid; bool m_bindPoseMatrixValid; + bool m_activePoseMatrixValid; bool m_inverseBindPoseMatrixValid; std::string m_name; @@ -151,6 +195,7 @@ private: KRScene *m_pScene; std::set m_octree_nodes; + bool m_scale_compensation; public: diff --git a/KREngine/kraken/KRParticleSystemNewtonian.cpp b/KREngine/kraken/KRParticleSystemNewtonian.cpp index b36f499..81324cd 100644 --- a/KREngine/kraken/KRParticleSystemNewtonian.cpp +++ b/KREngine/kraken/KRParticleSystemNewtonian.cpp @@ -77,7 +77,7 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vectorselectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, 1.0f); - m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, true, false, false, true, false, false, false, false); + m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); } } @@ -105,7 +105,7 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vectorgetModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, true, false, false, true, false, false); +// m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); // GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); // } //// } diff --git a/KREngine/kraken/KRPointLight.cpp b/KREngine/kraken/KRPointLight.cpp index 7480a28..d18ddcb 100644 --- a/KREngine/kraken/KRPointLight.cpp +++ b/KREngine/kraken/KRPointLight.cpp @@ -96,13 +96,13 @@ void KRPointLight::render(KRCamera *pCamera, std::vector &point_ GLDEBUG(glDisable(GL_DEPTH_TEST)); // Render a full screen quad - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, true, false, false, true, false, false, false, true); + m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } else { #if GL_OES_vertex_array_object GLDEBUG(glBindVertexArrayOES(0)); #endif - m_pContext->getModelManager()->configureAttribs(true, false, false, false, false, false, false); + m_pContext->getModelManager()->configureAttribs(1 << KRMesh::KRENGINE_ATTRIB_VERTEX); // Render sphere of light's influence generateMesh(); diff --git a/KREngine/kraken/KRRenderSettings.h b/KREngine/kraken/KRRenderSettings.h index 1da08f2..0b8174e 100644 --- a/KREngine/kraken/KRRenderSettings.h +++ b/KREngine/kraken/KRRenderSettings.h @@ -95,6 +95,7 @@ public: KRENGINE_DEBUG_DISPLAY_DRAW_CALLS, KRENGINE_DEBUG_DISPLAY_OCTREE, KRENGINE_DEBUG_DISPLAY_COLLIDERS, + KRENGINE_DEBUG_DISPLAY_BONES, KRENGINE_DEBUG_DISPLAY_NUMBER } debug_display; diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index 56ef56f..9951d49 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -85,13 +85,16 @@ void KRResource::LoadFbx(KRContext &context, const std::string& path) // Load the scene. lResult = LoadScene(lSdkManager, pFbxScene, path.c_str()); - // ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====---- - - printf("Baking pivots...\n"); KFbxNode* pNode = pFbxScene->GetRootNode(); + + // ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====---- + /* + printf("Baking pivots...\n"); + if(pNode) { pNode->ResetPivotSetAndConvertAnimation(); } + */ // ----====---- Import Animation Layers ----====---- printf("\nLoading animations...\n"); @@ -660,12 +663,6 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p KFbxVector4 lZero(0.0, 0.0, 0.0); KFbxVector4 lOne(1.0, 1.0, 1.0); - assert(post_rotation == lZero); - assert(pre_rotation == lZero); - assert(rotation_offset == lZero); - assert(scaling_offset == lZero); - assert(rotation_pivot == lZero); - assert(scaling_pivot == lZero); assert(geometric_rotation == lZero); assert(geometric_translation == lZero); assert(geometric_scaling == lOne); @@ -675,6 +672,13 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p KRVector3 node_rotation = KRVector3(local_rotation[0], local_rotation[1], local_rotation[2]) / 180.0 * M_PI; KRVector3 node_scale = KRVector3(local_scale[0], local_scale[1], local_scale[2]); + KRVector3 node_rotation_offset = KRVector3(rotation_offset[0], rotation_offset[1], rotation_offset[2]); + KRVector3 node_scaling_offset = KRVector3(scaling_offset[0], scaling_offset[1], scaling_offset[2]); + KRVector3 node_rotation_pivot = KRVector3(rotation_pivot[0], rotation_pivot[1], rotation_pivot[2]); + KRVector3 node_scaling_pivot = KRVector3(scaling_pivot[0], scaling_pivot[1], scaling_pivot[2]); + KRVector3 node_pre_rotation = KRVector3(pre_rotation[0], pre_rotation[1], pre_rotation[2]) / 180.0 * M_PI; + KRVector3 node_post_rotation = KRVector3(post_rotation[0], post_rotation[1], post_rotation[2]) / 180.0 * M_PI; + // printf(" Local Translation: %f %f %f\n", local_translation[0], local_translation[1], local_translation[2]); // printf(" Local Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]); // printf(" Local Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]); @@ -740,6 +744,15 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p new_node->setLocalRotation(node_rotation); new_node->setLocalTranslation(node_translation); new_node->setLocalScale(node_scale); + + + new_node->setRotationOffset(node_rotation_offset); + new_node->setScalingOffset(node_scaling_offset); + new_node->setRotationPivot(node_rotation_pivot); + new_node->setScalingPivot(node_scaling_pivot); + new_node->setPreRotation(node_pre_rotation); + new_node->setPostRotation(node_post_rotation); + new_node->setUseWorldUnits(use_world_space_units); parent_node->addChild(new_node); @@ -822,6 +835,12 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p new_node->setLocalRotation(node_rotation); new_node->setLocalTranslation(node_translation); new_node->setLocalScale(node_scale); + new_node->setRotationOffset(node_rotation_offset); + new_node->setScalingOffset(node_scaling_offset); + new_node->setRotationPivot(node_rotation_pivot); + new_node->setScalingPivot(node_scaling_pivot); + new_node->setPreRotation(node_pre_rotation); + new_node->setPostRotation(node_post_rotation); parent_node->addChild(new_node); // Load child nodes @@ -1056,7 +1075,7 @@ void LoadMesh(KRContext &context, FbxGeometryConverter *pGeometryConverter, KFbx } weight_info.weights[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = bone_weight; weight_info.bone_indexes[KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1] = target_bone_index; - for(int bone_index=KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1; bone_index >=0; bone_index--) { + for(int bone_index=KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 2; bone_index >=0; bone_index--) { if(bone_weight > weight_info.weights[bone_index]) { weight_info.weights[bone_index+1] = weight_info.weights[bone_index]; weight_info.bone_indexes[bone_index+1] = weight_info.bone_indexes[bone_index]; diff --git a/KREngine/kraken/KRScene.cpp b/KREngine/kraken/KRScene.cpp index 14439ad..b5b815a 100644 --- a/KREngine/kraken/KRScene.cpp +++ b/KREngine/kraken/KRScene.cpp @@ -182,18 +182,6 @@ void KRScene::render(KROctreeNode *pOctreeNode, unordered_map &visi if(bOcclusionResultsPass) { // ----====---- Occlusion results pass ----====---- if(pOctreeNode->m_occlusionTested) { - /* - GLuint hasBeenTested = 0; - int c =0; - while(!hasBeenTested) { - GLDEBUG(glGetQueryObjectuivEXT(pOctreeNode->m_occlusionQuery, GL_QUERY_RESULT_AVAILABLE_EXT, &hasBeenTested)); // FINDME, HACK!! This needs to be replaced with asynchonous logic - c++; - } - if(c > 1) { - fprintf(stderr, "GL_QUERY_RESULT_AVAILABLE_EXT count = %i\n", c); - } - */ - GLuint params = 0; GLDEBUG(glGetQueryObjectuivEXT(pOctreeNode->m_occlusionQuery, GL_QUERY_RESULT_EXT, ¶ms)); @@ -283,7 +271,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, unordered_map &visi KRMat4 mvpmatrix = matModel * viewport.getViewProjectionMatrix(); - getContext().getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, true, false, false, false, false, false, false, true); + getContext().getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, KRENGINE_VBO_3D_CUBE_ATTRIBS, true); // Enable additive blending if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { diff --git a/KREngine/kraken/KRStockGeometry.h b/KREngine/kraken/KRStockGeometry.h index fdf73c3..4dc7e18 100644 --- a/KREngine/kraken/KRStockGeometry.h +++ b/KREngine/kraken/KRStockGeometry.h @@ -9,6 +9,8 @@ #ifndef KRSTOCKGEOMETRY_H #define KRSTOCKGEOMETRY_H +#include "KRMesh.h" + static const GLfloat KRENGINE_VBO_3D_CUBE[] = { 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, @@ -27,6 +29,7 @@ static const GLfloat KRENGINE_VBO_3D_CUBE[] = { }; static int KRENGINE_VBO_3D_CUBE_SIZE = sizeof(GLfloat) * 3 * 14; +static const __int32_t KRENGINE_VBO_3D_CUBE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX); static const GLfloat KRENGINE_VERTICES_2D_SQUARE[] = { -1.0f, -1.0f, @@ -50,6 +53,7 @@ static const GLfloat KRENGINE_VBO_2D_SQUARE[] = { }; static const int KRENGINE_VBO_2D_SQUARE_SIZE = sizeof(GLfloat) * 5 * 4; +static const __int32_t KRENGINE_VBO_2D_SQUARE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); #endif diff --git a/KREngine/kraken/KRTextureManager.cpp b/KREngine/kraken/KRTextureManager.cpp index 508e08d..e6fb8f5 100644 --- a/KREngine/kraken/KRTextureManager.cpp +++ b/KREngine/kraken/KRTextureManager.cpp @@ -151,6 +151,7 @@ KRTexture *KRTextureManager::getTextureCube(const char *szName) { } KRTexture *KRTextureManager::getTexture(const std::string &name) { + std::string lowerName = name; std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower); diff --git a/KREngine/kraken/KRVector3.cpp b/KREngine/kraken/KRVector3.cpp index a40111e..bdad05c 100644 --- a/KREngine/kraken/KRVector3.cpp +++ b/KREngine/kraken/KRVector3.cpp @@ -31,6 +31,7 @@ #include "KREngine-common.h" #include "KRVector3.h" +#include "tinyxml2.h" //default constructor KRVector3::KRVector3() @@ -315,3 +316,26 @@ void KRVector3::setUniform(GLint location) const { if(location != -1) GLDEBUG(glUniform3f(location, x, y, z)); } + +void KRVector3::setXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e) +{ + // TODO - Increase number of digits after the decimal in floating point format (6 -> 12?) + // FINDME, TODO - This needs optimization... + e->SetAttribute((base_name + "_x").c_str(), x); + e->SetAttribute((base_name + "_y").c_str(), y); + e->SetAttribute((base_name + "_z").c_str(), z); +} + +void KRVector3::getXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const KRVector3 &default_value) +{ + float new_x,new_y,new_z; + if(e->QueryFloatAttribute((base_name + "_x").c_str(), &new_x) == tinyxml2::XML_SUCCESS + && e->QueryFloatAttribute((base_name + "_y").c_str(), &new_y) == tinyxml2::XML_SUCCESS + && e->QueryFloatAttribute((base_name + "_z").c_str(), &new_z) == tinyxml2::XML_SUCCESS) { + x = new_x; + y = new_y; + z = new_z; + } else { + *this = default_value; + } +} diff --git a/KREngine/kraken/KRVector3.h b/KREngine/kraken/KRVector3.h index 6ef6630..81ea190 100644 --- a/KREngine/kraken/KRVector3.h +++ b/KREngine/kraken/KRVector3.h @@ -34,6 +34,7 @@ #include "KREngine-common.h" + class KRVector4; class KRVector3 { @@ -103,6 +104,9 @@ public: static void OrthoNormalize(KRVector3 &normal, KRVector3 &tangent); // Gram-Schmidt Orthonormalization void setUniform(GLint location) const; + + void setXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e); + void getXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const KRVector3 &default_value); }; namespace std { diff --git a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh index b476e5b..71acfbc 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.fsh @@ -393,4 +393,8 @@ void main() #endif + + #if BONE_COUNT > 0 + gl_FragColor.b = 1.0; + #endif } diff --git a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh index fd08cb2..4e379d3 100644 --- a/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh +++ b/KREngine/kraken_standard_assets_ios/Shaders/ObjectShader.vsh @@ -29,13 +29,16 @@ // or implied, of Kearwood Gilbert. // -attribute highp vec3 vertex_position, vertex_normal, vertex_tangent; +attribute highp vec3 vertex_position, vertex_normal; +#if HAS_NORMAL_MAP == 1 + attribute highp vec3 vertex_tangent; +#endif attribute mediump vec2 vertex_uv; uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices #if BONE_COUNT > 0 attribute highp vec4 bone_weights; - attribute mediump vec4 bone_indexes; + attribute highp vec4 bone_indexes; uniform highp mat4 bone_transforms[BONE_COUNT]; #else #define vertex_position_skinned vertex_position @@ -168,30 +171,28 @@ void main() mediump vec4 scaled_bone_indexes = bone_indexes; mediump vec4 scaled_bone_weights = bone_weights; - // scaled_bone_indexes = vec4(1.0, 0.0, 0.0, 0.0); - // scaled_bone_weights = vec4(1.0, 0.0, 0.0, 0.0); - highp vec3 vertex_position_skinned = - ((bone_transforms[ int(scaled_bone_indexes.x) ] * vec4(vertex_position, 1.0)).xyz * scaled_bone_weights.x) + - ((bone_transforms[ int(scaled_bone_indexes.y) ] * vec4(vertex_position, 1.0)).xyz * scaled_bone_weights.y) + - ((bone_transforms[ int(scaled_bone_indexes.z) ] * vec4(vertex_position, 1.0)).xyz * scaled_bone_weights.z) + - ((bone_transforms[ int(scaled_bone_indexes.w) ] * vec4(vertex_position, 1.0)).xyz * scaled_bone_weights.w); - - highp vec3 vertex_normal_skinned = normalize( - ((bone_transforms[ int(scaled_bone_indexes.x) ] * vec4(vertex_normal, 1.0)).xyz * scaled_bone_weights.x) + - ((bone_transforms[ int(scaled_bone_indexes.y) ] * vec4(vertex_normal, 1.0)).xyz * scaled_bone_weights.y) + - ((bone_transforms[ int(scaled_bone_indexes.z) ] * vec4(vertex_normal, 1.0)).xyz * scaled_bone_weights.z) + - ((bone_transforms[ int(scaled_bone_indexes.w) ] * vec4(vertex_normal, 1.0)).xyz * scaled_bone_weights.w)); - - highp vec3 vertex_tangent_skinned = normalize( - ((bone_transforms[ int(scaled_bone_indexes.x) ] * vec4(vertex_tangent, 1.0)).xyz * scaled_bone_weights.x) + - ((bone_transforms[ int(scaled_bone_indexes.y) ] * vec4(vertex_tangent, 1.0)).xyz * scaled_bone_weights.y) + - ((bone_transforms[ int(scaled_bone_indexes.z) ] * vec4(vertex_tangent, 1.0)).xyz * scaled_bone_weights.z) + - ((bone_transforms[ int(scaled_bone_indexes.w) ] * vec4(vertex_tangent, 1.0)).xyz * scaled_bone_weights.w)); -#endif + //scaled_bone_indexes = vec4(1.0, 0.0, 0.0, 0.0); + scaled_bone_weights = vec4(1.0, 0.0, 0.0, 0.0); + highp mat4 skin_matrix = + bone_transforms[ int(scaled_bone_indexes.x) ] * scaled_bone_weights.x + + bone_transforms[ int(scaled_bone_indexes.y) ] * scaled_bone_weights.y + + bone_transforms[ int(scaled_bone_indexes.z) ] * scaled_bone_weights.z + + bone_transforms[ int(scaled_bone_indexes.w) ] * scaled_bone_weights.w; + //skin_matrix = bone_transforms[0]; + highp vec3 vertex_position_skinned = (skin_matrix * vec4(vertex_position, 1)).xyz; + + highp vec3 vertex_normal_skinned = normalize(mat3(skin_matrix) * vertex_normal); + #if HAS_NORMAL_MAP == 1 + highp vec3 vertex_tangent_skinned = normalize(mat3(skin_matrix) * vertex_tangent); + #endif + +#endif // Transform position gl_Position = mvp_matrix * vec4(vertex_position_skinned,1.0); + + #if HAS_DIFFUSE_MAP == 1 || (HAS_NORMAL_MAP == 1 && ENABLE_PER_PIXEL == 1) || (HAS_SPEC_MAP == 1 && ENABLE_PER_PIXEL == 1) || (HAS_REFLECTION_MAP == 1 && ENABLE_PER_PIXEL == 1) // Pass UV co-ordinates