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
This commit is contained in:
2013-05-13 13:16:25 -07:00
parent 6fe549b3ba
commit 2de749ff16
27 changed files with 860 additions and 306 deletions

View File

@@ -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),

View File

@@ -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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&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();
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));
// Enable additive blending
GLDEBUG(glEnable(GL_BLEND));
GLDEBUG(glBlendFunc(GL_ONE, GL_ONE));
// Disable z-buffer write
GLDEBUG(glDepthMask(GL_FALSE));
// 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<KRMesh *> 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");
}
// 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)) {
std::vector<KRMesh *> 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));
}
}

View File

@@ -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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass);

View File

@@ -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<KRPointLight *>(), std::vector<KRDirectionalLight *>(), std::vector<KRSpotLight *>(), 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<KRAABB, int>::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();
}

View File

@@ -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<KRPointLight *> &
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));
}
}

View File

@@ -47,6 +47,8 @@ float const D2R = PI * 2 / 360;
#include <boost/algorithm/string/predicate.hpp>
#include <boost/signals2/mutex.hpp>
#include "tinyxml2.h"
using std::vector;
using std::string;

View File

@@ -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);

View File

@@ -226,7 +226,7 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &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<KRPointLight *> &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<KRPointLight *> &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));
}
}

View File

@@ -62,7 +62,7 @@ class KRMat4 {
public:
float c[16];
float c[16]; // Matrix components, in column-major order

View File

@@ -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];
}

View File

@@ -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<std::p
clearData();
// TODO, FINDME - These values should be passed as a parameter and set by GUI flags
bool use_short_vertexes = false;
bool use_short_normals = true;
bool use_short_tangents = true;
bool use_short_uva = true;
bool use_short_uvb = true;
if(use_short_vertexes) {
for(std::vector<KRVector3>::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<KRVector3>::iterator itr=normals.begin(); itr != normals.end(); itr++) {
(*itr).normalize();
}
}
if(use_short_tangents) {
for(std::vector<KRVector3>::iterator itr=tangents.begin(); itr != tangents.end(); itr++) {
(*itr).normalize();
}
}
if(use_short_uva) {
for(std::vector<KRVector2>::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<KRVector2>::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<std::pair<int, int> > vertex_index_bases;
@@ -975,12 +1109,13 @@ void KRMesh::convertToIndexed()
while(vertexes_remaining) {
std::map<std::pair<std::vector<float>, std::vector<int> >, int> prev_indexes = std::map<std::pair<std::vector<float>, std::vector<int> >, int>();
//typedef std::pair<std::vector<float>, std::vector<int> > vertex_key_t;
typedef std::string vertex_key_t;
unordered_map<vertex_key_t, int> prev_indexes = unordered_map<vertex_key_t, int>();
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<float>, std::vector<int> > vertex_key; // = std::make_pair(std::vector<float>(), std::vector<int>());
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<float>(), std::vector<int>());
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;
}
*/
}

View File

@@ -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;
@@ -113,25 +118,6 @@ public:
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;

View File

@@ -146,8 +146,7 @@ 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) {
@@ -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()

View File

@@ -59,15 +59,13 @@ public:
std::vector<std::string> getModelNames();
unordered_multimap<std::string, KRMesh *> &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;

View File

@@ -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<KRNode *>::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<KRBone *>(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<KRBone *>(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<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRNode *child = (*itr);
@@ -336,14 +494,61 @@ 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);
bool parent_is_bone = false;
if(dynamic_cast<KRBone *>(m_parentNode)) {
parent_is_bone = true;
}
if(m_parentNode) {
m_modelMatrix *= m_parentNode->getModelMatrix();
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<KRBone *>(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<KRBone *>(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<KRBone *>(m_parentNode);
if(parentBone) {
m_bindPoseMatrix *= parentBone->getBindPoseMatrix();
}
m_bindPoseMatrixValid = true;
}
return m_bindPoseMatrix;
}
const KRMat4 &KRNode::getInverseBindPoseMatrix()
{
if(!m_inverseBindPoseMatrixValid ) {

View File

@@ -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<KROctreeNode *> m_octree_nodes;
bool m_scale_compensation;
public:

View File

@@ -77,7 +77,7 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vector<KRPointLig
if(getContext().getShaderManager()->selectShader(*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::vector<KRPointLig
// 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);
// 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));
// }
//// }

View File

@@ -96,13 +96,13 @@ void KRPointLight::render(KRCamera *pCamera, std::vector<KRPointLight *> &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();

View File

@@ -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;

View File

@@ -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];

View File

@@ -182,18 +182,6 @@ void KRScene::render(KROctreeNode *pOctreeNode, unordered_map<KRAABB, int> &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, &params));
@@ -283,7 +271,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, unordered_map<KRAABB, int> &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) {

View File

@@ -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

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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 {

View File

@@ -393,4 +393,8 @@ void main()
#endif
#if BONE_COUNT > 0
gl_FragColor.b = 1.0;
#endif
}

View File

@@ -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,31 +171,29 @@ 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);
//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_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 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
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
// 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
texCoord = vertex_uv.st;