FBX Import now creates empty nodes in the scene graph for transform and rotation inheritance.

Model matrix inheritance implemented
No longer have to freeze transform and rotations before importing to Kraken.

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40151
This commit is contained in:
kearwood
2012-11-03 02:57:35 +00:00
parent e5febf7e60
commit 19a6689245
18 changed files with 131 additions and 138 deletions

View File

@@ -16,6 +16,30 @@ KRAABB::KRAABB(const KRVector3 &minPoint, const KRVector3 &maxPoint)
min = minPoint; min = minPoint;
max = maxPoint; max = maxPoint;
} }
KRAABB::KRAABB(const KRVector3 &corner1, const KRVector3 &corner2, const KRMat4 &modelMatrix)
{
for(int iCorner=0; iCorner<8; iCorner++) {
KRVector3 sourceCornerVertex = KRMat4::Dot(modelMatrix, KRVector3(
(iCorner & 1) == 0 ? corner1.x : corner2.x,
(iCorner & 2) == 0 ? corner1.y : corner2.y,
(iCorner & 4) == 0 ? corner1.z : corner2.z));
if(iCorner == 0) {
min = sourceCornerVertex;
max = sourceCornerVertex;
} else {
if(sourceCornerVertex.x < min.x) min.x = sourceCornerVertex.x;
if(sourceCornerVertex.y < min.y) min.y = sourceCornerVertex.y;
if(sourceCornerVertex.z < min.z) min.z = sourceCornerVertex.z;
if(sourceCornerVertex.x > max.x) max.x = sourceCornerVertex.x;
if(sourceCornerVertex.y > max.y) max.y = sourceCornerVertex.y;
if(sourceCornerVertex.z > max.z) max.z = sourceCornerVertex.z;
}
}
}
KRAABB::~KRAABB() KRAABB::~KRAABB()
{ {
@@ -153,16 +177,16 @@ bool KRAABB::visible(const KRMat4 &matViewProjection) const
} }
float KRAABB::coverage(const KRMat4 &matMVP, const KRVector2 viewportSize) const float KRAABB::coverage(const KRMat4 &matVP, const KRVector2 viewportSize) const
{ {
if(!visible(matMVP)) { if(!visible(matVP)) {
return 0.0f; // Culled out by view frustrum return 0.0f; // Culled out by view frustrum
} else { } else {
KRVector2 screen_min; KRVector2 screen_min;
KRVector2 screen_max; KRVector2 screen_max;
// Loop through all corners and transform them to screen space // Loop through all corners and transform them to screen space
for(int i=0; i<8; i++) { for(int i=0; i<8; i++) {
KRVector3 screen_pos = KRMat4::DotWDiv(matMVP, KRVector3(i & 1 ? min.x : max.x, i & 2 ? min.y : max.y, i & 4 ? min.z : max.z)); KRVector3 screen_pos = KRMat4::DotWDiv(matVP, KRVector3(i & 1 ? min.x : max.x, i & 2 ? min.y : max.y, i & 4 ? min.z : max.z));
if(i==0) { if(i==0) {
screen_min.x = screen_pos.x; screen_min.x = screen_pos.x;
screen_min.y = screen_pos.y; screen_min.y = screen_pos.y;

View File

@@ -19,6 +19,7 @@ class KRVector2;
class KRAABB { class KRAABB {
public: public:
KRAABB(const KRVector3 &minPoint, const KRVector3 &maxPoint); KRAABB(const KRVector3 &minPoint, const KRVector3 &maxPoint);
KRAABB(const KRVector3 &corner1, const KRVector3 &corner2, const KRMat4 &modelMatrix);
~KRAABB(); ~KRAABB();
KRVector3 center() const; KRVector3 center() const;
@@ -40,7 +41,7 @@ public:
KRVector3 max; KRVector3 max;
static KRAABB Infinite(); static KRAABB Infinite();
float coverage(const KRMat4 &matMVP, const KRVector2 viewportSize) const; float coverage(const KRMat4 &matVP, const KRVector2 viewportSize) const;
}; };

View File

@@ -57,7 +57,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, const KR
if(renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS) { if(renderPass == KRNode::RENDER_PASS_DEFERRED_LIGHTS) {
// Lights are rendered on the second pass of the deferred renderer // Lights are rendered on the second pass of the deferred renderer
KRMat4 matModelViewInverseTranspose = viewport.getViewMatrix() * m_modelMatrix; KRMat4 matModelViewInverseTranspose = viewport.getViewMatrix() * getModelMatrix();
matModelViewInverseTranspose.transpose(); matModelViewInverseTranspose.transpose();
matModelViewInverseTranspose.invert(); matModelViewInverseTranspose.invert();
@@ -66,7 +66,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, const KR
light_direction_view_space.normalize(); light_direction_view_space.normalize();
KRShader *pShader = pContext->getShaderManager()->getShader("light_directional", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); KRShader *pShader = pContext->getShaderManager()->getShader("light_directional", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
if(pShader->bind(viewport, m_modelMatrix, lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass)) { if(pShader->bind(viewport, getModelMatrix(), lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass)) {
light_direction_view_space.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE]); light_direction_view_space.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE]);
m_color.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]); m_color.setUniform(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]);

View File

@@ -28,8 +28,6 @@ public:
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass); virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
#endif #endif
private:
KRMat4 m_modelMatrix;
}; };

View File

@@ -59,12 +59,6 @@ tinyxml2::XMLElement *KRInstance::saveXML( tinyxml2::XMLNode *parent)
return e; return e;
} }
KRMat4 &KRInstance::getModelMatrix() {
calcModelMatrix();
return m_modelMatrix;
}
void KRInstance::loadModel() { void KRInstance::loadModel() {
if(m_models.size() == 0) { if(m_models.size() == 0) {
m_models = m_pContext->getModelManager()->getModel(m_model_name.c_str()); // The model manager returns the LOD levels in sorted order, with the highest detail first m_models = m_pContext->getModelManager()->getModel(m_model_name.c_str()); // The model manager returns the LOD levels in sorted order, with the highest detail first
@@ -81,7 +75,6 @@ void KRInstance::loadModel() {
void KRInstance::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) { void KRInstance::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
calcModelMatrix();
KRNode::render(pCamera, pContext, viewport, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass); KRNode::render(pCamera, pContext, viewport, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, renderPass);
@@ -91,8 +84,7 @@ void KRInstance::render(KRCamera *pCamera, KRContext *pContext, const KRViewport
loadModel(); loadModel();
if(m_models.size() > 0) { if(m_models.size() > 0) {
KRMat4 matMVP = m_modelMatrix * viewport.getViewProjectionMatrix(); float lod_coverage = getBounds().coverage(viewport.getViewProjectionMatrix(), viewport.getSize()); // This also checks the view frustrum culling
float lod_coverage = getBounds().coverage(matMVP, viewport.getSize()); // This also checks the view frustrum culling
if(lod_coverage > m_min_lod_coverage) { if(lod_coverage > m_min_lod_coverage) {
// ---===--- Select the best LOD model based on screen coverage ---===--- // ---===--- Select the best LOD model based on screen coverage ---===---
@@ -116,7 +108,7 @@ void KRInstance::render(KRCamera *pCamera, KRContext *pContext, const KRViewport
m_pContext->getTextureManager()->selectTexture(5, m_pLightMap, 2048); m_pContext->getTextureManager()->selectTexture(5, m_pLightMap, 2048);
} }
pModel->render(pCamera, pContext, viewport, m_modelMatrix, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, m_pLightMap, renderPass); pModel->render(pCamera, pContext, viewport, getModelMatrix(), lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, m_pLightMap, renderPass);
} }
} }
} }
@@ -133,62 +125,11 @@ bool KRInstance::hasTransparency() {
} }
KRAABB KRInstance::getBounds() { KRAABB KRInstance::getBounds() {
calcModelMatrix();
loadModel(); loadModel();
KRVector3 meshMin, meshMax;
if(m_models.size() > 0) { if(m_models.size() > 0) {
meshMin = m_models[0]->getMinPoint(); return KRAABB(m_models[0]->getMinPoint(), m_models[0]->getMaxPoint(), getModelMatrix());
meshMax = m_models[0]->getMaxPoint();
} else { } else {
meshMin = -KRVector3::Max(); return KRAABB::Infinite();
meshMax = KRVector3::Max();
}
KRVector3 min, max;
for(int iCorner=0; iCorner < 8; iCorner++) {
KRVector3 cornerVertex = KRVector3(
(iCorner & 1) == 0 ? meshMin.x : meshMax.x,
(iCorner & 2) == 0 ? meshMin.y : meshMax.y,
(iCorner & 4) == 0 ? meshMin.z : meshMax.z);
cornerVertex = KRMat4::Dot(m_modelMatrix, cornerVertex);
if(iCorner == 0) {
// Prime with first point
min = cornerVertex;
max = cornerVertex;
} else {
if(cornerVertex.x < min.x) {
min.x = cornerVertex.x;
}
if(cornerVertex.y < min.y) {
min.y = cornerVertex.y;
}
if(cornerVertex.z < min.z) {
min.z = cornerVertex.z;
}
if(cornerVertex.x > max.x) {
max.x = cornerVertex.x;
}
if(cornerVertex.y > max.y) {
max.y = cornerVertex.y;
}
if(cornerVertex.z > max.z) {
max.z = cornerVertex.z;
}
} }
} }
return KRAABB(min, max);
}
void KRInstance::calcModelMatrix()
{
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);
}

View File

@@ -61,17 +61,13 @@ public:
virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass); virtual void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass);
#endif #endif
KRMat4 &getModelMatrix();
bool hasTransparency(); bool hasTransparency();
virtual KRAABB getBounds(); virtual KRAABB getBounds();
void calcModelMatrix();
private: private:
std::vector<KRModel *> m_models; std::vector<KRModel *> m_models;
KRMat4 m_modelMatrix;
KRTexture *m_pLightMap; KRTexture *m_pLightMap;
std::string m_lightMap; std::string m_lightMap;
std::string m_model_name; std::string m_model_name;

View File

@@ -129,19 +129,13 @@ void KRLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &v
} }
if(m_pFlareTexture) { if(m_pFlareTexture) {
KRVector3 light_position = getLocalTranslation();
KRMat4 m_modelMatrix = KRMat4();
m_modelMatrix.translate(light_position.x, light_position.y, light_position.z);
// Disable z-buffer test // Disable z-buffer test
GLDEBUG(glDisable(GL_DEPTH_TEST)); GLDEBUG(glDisable(GL_DEPTH_TEST));
GLDEBUG(glDepthRangef(0.0, 1.0)); GLDEBUG(glDepthRangef(0.0, 1.0));
// Render light flare on transparency pass // Render light flare on transparency pass
KRShader *pShader = pContext->getShaderManager()->getShader("flare", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); KRShader *pShader = pContext->getShaderManager()->getShader("flare", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
if(pShader->bind(viewport, m_modelMatrix, lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass)) { if(pShader->bind(viewport, getModelMatrix(), lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass)) {
GLDEBUG(glUniform1f( GLDEBUG(glUniform1f(
pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE], pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE],
m_flareSize m_flareSize

View File

@@ -201,7 +201,7 @@ bool KRMaterial::isTransparent() {
} }
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, const KRViewport &viewport, KRMat4 &matModel, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRContext *pContext, KRTexture *pLightMap, KRNode::RenderPass renderPass) { bool KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, const KRViewport &viewport, const KRMat4 &matModel, const KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRContext *pContext, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
bool bSameMaterial = *prevBoundMaterial == this; bool bSameMaterial = *prevBoundMaterial == this;
bool bLightMap = pLightMap && pCamera->bEnableLightMap; bool bLightMap = pLightMap && pCamera->bEnableLightMap;

View File

@@ -89,7 +89,7 @@ public:
char *getName(); char *getName();
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRCamera *pCamera, const KRViewport &viewport, KRMat4 &matModel, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRContext *pContext, KRTexture *pLightMap, KRNode::RenderPass renderPass); bool bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, const KRCamera *pCamera, const KRViewport &viewport, const KRMat4 &matModel, const KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRContext *pContext, KRTexture *pLightMap, KRNode::RenderPass renderPass);
#endif #endif

View File

@@ -111,7 +111,7 @@ void KRModel::loadPack(KRDataBlock *data) {
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
void KRModel::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRMat4 &matModel, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRTexture *pLightMap, KRNode::RenderPass renderPass) { void KRModel::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRMat4 &matModel, const KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRTexture *pLightMap, KRNode::RenderPass renderPass) {
//fprintf(stderr, "Rendering model: %s\n", m_name.c_str()); //fprintf(stderr, "Rendering model: %s\n", m_name.c_str());
if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES) { if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES) {
@@ -164,7 +164,6 @@ void KRModel::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &v
if(pMaterial != NULL && pMaterial == (*mat_itr)) { if(pMaterial != NULL && pMaterial == (*mat_itr)) {
if((!pMaterial->isTransparent() && renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) || (pMaterial->isTransparent() && renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) { if((!pMaterial->isTransparent() && renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT) || (pMaterial->isTransparent() && renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT)) {
KRMat4 matModel; // FINDME - HACK - Model matrices are all currently identity matrices
if(pMaterial->bind(&pPrevBoundMaterial, szPrevShaderKey, pCamera, viewport, matModel, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, pContext, pLightMap, renderPass)) { if(pMaterial->bind(&pPrevBoundMaterial, szPrevShaderKey, pCamera, viewport, matModel, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, pContext, pLightMap, renderPass)) {
switch(pMaterial->getAlphaMode()) { switch(pMaterial->getAlphaMode()) {

View File

@@ -69,7 +69,7 @@ public:
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRMat4 &matModel, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRTexture *pLightMap, KRNode::RenderPass renderPass); void render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, const KRMat4 &matModel, const KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRTexture *pLightMap, KRNode::RenderPass renderPass);
#endif #endif

View File

@@ -18,6 +18,7 @@
#import "KRParticleSystem.h" #import "KRParticleSystem.h"
#import "KRParticleSystemBrownian.h" #import "KRParticleSystemBrownian.h"
#import "KRAABB.h" #import "KRAABB.h"
#import "KRQuaternion.h"
KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getContext()) KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getContext())
@@ -29,6 +30,8 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont
m_parentNode = NULL; m_parentNode = NULL;
m_pScene = &scene; m_pScene = &scene;
getScene().notify_sceneGraphCreate(this); getScene().notify_sceneGraphCreate(this);
m_modelMatrixValid = false;
m_modelMatrix = KRMat4();
} }
KRNode::~KRNode() { KRNode::~KRNode() {
@@ -56,9 +59,9 @@ tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) {
e->SetAttribute("scale_x", m_localScale.x); e->SetAttribute("scale_x", m_localScale.x);
e->SetAttribute("scale_y", m_localScale.y); e->SetAttribute("scale_y", m_localScale.y);
e->SetAttribute("scale_z", m_localScale.z); e->SetAttribute("scale_z", m_localScale.z);
e->SetAttribute("rotate_x", m_localRotation.x); e->SetAttribute("rotate_x", m_localRotation.x * 180 / M_PI);
e->SetAttribute("rotate_y", m_localRotation.y); e->SetAttribute("rotate_y", m_localRotation.y * 180 / M_PI);
e->SetAttribute("rotate_z", m_localRotation.z); e->SetAttribute("rotate_z", m_localRotation.z * 180 / M_PI);
for(std::vector<KRNode *>::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) { for(std::vector<KRNode *>::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) {
KRNode *child = (*itr); KRNode *child = (*itr);
child->saveXML(n); child->saveXML(n);
@@ -82,7 +85,7 @@ void KRNode::loadXML(tinyxml2::XMLElement *e) {
e->QueryFloatAttribute("rotate_x", &x); e->QueryFloatAttribute("rotate_x", &x);
e->QueryFloatAttribute("rotate_y", &y); e->QueryFloatAttribute("rotate_y", &y);
e->QueryFloatAttribute("rotate_z", &z); e->QueryFloatAttribute("rotate_z", &z);
m_localRotation = KRVector3(x,y,z); m_localRotation = KRVector3(x,y,z) / 180.0 * M_PI; // Convert degrees to radians
for(tinyxml2::XMLElement *child_element=e->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) { for(tinyxml2::XMLElement *child_element=e->FirstChildElement(); child_element != NULL; child_element = child_element->NextSiblingElement()) {
KRNode *child_node = KRNode::LoadXML(getScene(), child_element); KRNode *child_node = KRNode::LoadXML(getScene(), child_element);
@@ -94,12 +97,16 @@ void KRNode::loadXML(tinyxml2::XMLElement *e) {
void KRNode::setLocalTranslation(const KRVector3 &v) { void KRNode::setLocalTranslation(const KRVector3 &v) {
m_localTranslation = v; m_localTranslation = v;
invalidateModelMatrix();
} }
void KRNode::setLocalScale(const KRVector3 &v) { void KRNode::setLocalScale(const KRVector3 &v) {
m_localScale = v; m_localScale = v;
invalidateModelMatrix();
} }
void KRNode::setLocalRotation(const KRVector3 &v) { void KRNode::setLocalRotation(const KRVector3 &v) {
m_localRotation = v; m_localRotation = v;
invalidateModelMatrix();
} }
const KRVector3 &KRNode::getLocalTranslation() { const KRVector3 &KRNode::getLocalTranslation() {
@@ -177,3 +184,30 @@ KRScene &KRNode::getScene() {
KRAABB KRNode::getBounds() { KRAABB KRNode::getBounds() {
return KRAABB::Infinite(); return KRAABB::Infinite();
} }
void KRNode::invalidateModelMatrix()
{
m_modelMatrixValid = false;
for(std::vector<KRNode *>::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) {
KRNode *child = (*itr);
child->invalidateModelMatrix();
}
}
const KRMat4 &KRNode::getModelMatrix()
{
if(!m_modelMatrixValid) {
if(m_parentNode) {
m_modelMatrix = m_parentNode->getModelMatrix();
} else {
m_modelMatrix = KRMat4();
}
m_modelMatrix.scale(m_localScale);
m_modelMatrix.rotate(KRQuaternion(m_localRotation));
m_modelMatrix.translate(m_localTranslation);
m_modelMatrixValid = true;
}
return m_modelMatrix;
}

View File

@@ -63,6 +63,7 @@ public:
const KRVector3 &getWorldRotation(); const KRVector3 &getWorldRotation();
virtual KRAABB getBounds(); virtual KRAABB getBounds();
const KRMat4 &getModelMatrix();
KRScene &getScene(); KRScene &getScene();
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
@@ -77,6 +78,9 @@ protected:
KRVector3 m_localRotation; KRVector3 m_localRotation;
private: private:
void invalidateModelMatrix();
KRMat4 m_modelMatrix;
bool m_modelMatrixValid;
std::string m_name; std::string m_name;

View File

@@ -36,6 +36,11 @@ std::string KRPointLight::getElementName() {
return "point_light"; return "point_light";
} }
KRAABB KRPointLight::getBounds() {
float influence_radius = sqrt((m_intensity / 100.0) / KRLIGHT_MIN_INFLUENCE - 1.0) + m_decayStart;
return KRAABB(KRVector3(-influence_radius), KRVector3(influence_radius), getModelMatrix());
}
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) { void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewport &viewport, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, KRNode::RenderPass renderPass) {
@@ -51,23 +56,20 @@ void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewpo
float influence_radius = sqrt((m_intensity / 100.0) / KRLIGHT_MIN_INFLUENCE - 1.0) + m_decayStart; float influence_radius = sqrt((m_intensity / 100.0) / KRLIGHT_MIN_INFLUENCE - 1.0) + m_decayStart;
m_modelMatrix = KRMat4(); KRMat4 sphereModelMatrix = KRMat4();
m_modelMatrix.scale(influence_radius); sphereModelMatrix.scale(influence_radius);
m_modelMatrix.translate(light_position.x, light_position.y, light_position.z); sphereModelMatrix.translate(light_position.x, light_position.y, light_position.z);
KRBoundingVolume influence_extents = KRBoundingVolume(KRVector3(-1.0), KRVector3(1.0), m_modelMatrix);
KRBoundingVolume frustrumVolumeNoNearClip = KRBoundingVolume(viewport.getViewMatrix(), pCamera->perspective_fov, viewport.getSize().x / viewport.getSize().y, 0.0, pCamera->getPerspectiveFarZ()); float lod_coverage = getBounds().coverage(viewport.getViewProjectionMatrix(), viewport.getSize()); // This also checks the view frustrum culling
if(lod_coverage > 0) { // Cull out any lights not within the view frustrum
if(influence_extents.test_intersect(frustrumVolumeNoNearClip)) {
// Cull out any lights not within the view frustrum
KRVector3 view_light_position = KRMat4::Dot(viewport.getViewMatrix(), light_position); KRVector3 view_light_position = KRMat4::Dot(viewport.getViewMatrix(), light_position);
bool bInsideLight = view_light_position.sqrMagnitude() <= (influence_radius + pCamera->getPerspectiveNearZ()) * (influence_radius + pCamera->getPerspectiveNearZ()); bool bInsideLight = view_light_position.sqrMagnitude() <= (influence_radius + pCamera->getPerspectiveNearZ()) * (influence_radius + pCamera->getPerspectiveNearZ());
KRShader *pShader = pContext->getShaderManager()->getShader(bVisualize ? "visualize_overlay" : (bInsideLight ? "light_point_inside" : "light_point"), pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); KRShader *pShader = pContext->getShaderManager()->getShader(bVisualize ? "visualize_overlay" : (bInsideLight ? "light_point_inside" : "light_point"), pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
if(pShader->bind(viewport, m_modelMatrix, lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass)) { if(pShader->bind(viewport, sphereModelMatrix, lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass)) {
@@ -100,7 +102,6 @@ void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, const KRViewpo
GLDEBUG(glDepthMask(GL_FALSE)); GLDEBUG(glDepthMask(GL_FALSE));
if(bInsideLight) { if(bInsideLight) {
// Disable z-buffer test // Disable z-buffer test

View File

@@ -20,6 +20,7 @@ public:
virtual ~KRPointLight(); virtual ~KRPointLight();
virtual std::string getElementName(); virtual std::string getElementName();
virtual KRAABB getBounds();
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
@@ -27,8 +28,6 @@ public:
#endif #endif
private: private:
KRMat4 m_modelMatrix;
void generateMesh(); void generateMesh();
GLfloat *m_sphereVertices; GLfloat *m_sphereVertices;

View File

@@ -40,8 +40,8 @@ void InitializeSdkObjects(KFbxSdkManager*& pSdkManager, KFbxScene*& pScene);
void DestroySdkObjects(KFbxSdkManager* pSdkManager); void DestroySdkObjects(KFbxSdkManager* pSdkManager);
bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pFilename); bool LoadScene(KFbxSdkManager* pSdkManager, KFbxDocument* pScene, const char* pFilename);
void LoadNode(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); void LoadNode(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxGeometryConverter *pGeometryConverter, KFbxNode* pNode);
void LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxGeometryConverter *pGeometryConverter, KFbxNode* pNode);
void LoadLight(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxNode* pNode); KRNode *LoadLight(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxNode* pNode);
std::vector<KRResource *> KRResource::LoadFbx(KRContext &context, const std::string& path) std::vector<KRResource *> KRResource::LoadFbx(KRContext &context, const std::string& path)
{ {
@@ -248,25 +248,43 @@ void LoadNode(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxGeo
printf(" Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]); printf(" Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]);
printf(" Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]); printf(" Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]);
KRNode *new_node = NULL;
KFbxNodeAttribute::EAttributeType attribute_type = (pNode->GetNodeAttribute()->GetAttributeType()); KFbxNodeAttribute::EAttributeType attribute_type = (pNode->GetNodeAttribute()->GetAttributeType());
switch(attribute_type) { switch(attribute_type) {
case KFbxNodeAttribute::eMESH: case KFbxNodeAttribute::eMESH:
LoadMesh(parent_node, resources, pGeometryConverter, pNode); new_node = LoadMesh(parent_node, resources, pGeometryConverter, pNode);
break; break;
case KFbxNodeAttribute::eLIGHT: case KFbxNodeAttribute::eLIGHT:
LoadLight(parent_node, resources, pNode); new_node = LoadLight(parent_node, resources, pNode);
break;
default:
{
if(pNode->GetChildCount() > 0) {
// Create an empty node, for inheritence of transforms
new_node = new KRNode(parent_node->getScene(), pNode->GetName());
}
}
break; break;
} }
if(new_node != NULL) {
new_node->setLocalRotation(KRVector3(local_rotation[0], local_rotation[1], local_rotation[2]) / 180.0 * M_PI);
new_node->setLocalTranslation(KRVector3(local_translation[0], local_translation[1], local_translation[2]));
new_node->setLocalScale(KRVector3(local_scale[0], local_scale[1], local_scale[2]));
parent_node->addChild(new_node);
// Load child nodes // Load child nodes
for(int i = 0; i < pNode->GetChildCount(); i++) for(int i = 0; i < pNode->GetChildCount(); i++)
{ {
LoadNode(parent_node, resources, pGeometryConverter, pNode->GetChild(i)); LoadNode(new_node, resources, pGeometryConverter, pNode->GetChild(i));
}
} }
} }
void LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) { KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) {
printf("Mesh: %s\n", pNode->GetName()); printf("Mesh: %s\n", pNode->GetName());
KFbxMesh* pSourceMesh = (KFbxMesh*) pNode->GetNodeAttribute(); KFbxMesh* pSourceMesh = (KFbxMesh*) pNode->GetNodeAttribute();
@@ -572,23 +590,14 @@ void LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxGeo
light_map.append("_lightmap"); light_map.append("_lightmap");
KRInstance *new_instance = new KRInstance(parent_node->getScene(), pNode->GetName(), pNode->GetName(), light_map, 0.0f); KRInstance *new_instance = new KRInstance(parent_node->getScene(), pNode->GetName(), pNode->GetName(), light_map, 0.0f);
fbxDouble3 local_rotation = pNode->LclRotation.Get(); // pNode->GetGeometricRotation(KFbxNode::eSOURCE_SET); return new_instance;
fbxDouble3 local_translation = pNode->LclTranslation.Get(); // pNode->GetGeometricTranslation(KFbxNode::eSOURCE_SET); } else {
fbxDouble3 local_scale = pNode->LclScaling.Get(); // pNode->GetGeometricScaling(KFbxNode::eSOURCE_SET); return NULL;
/*
fbxDouble3 local_rotation = pNode->GetGeometricRotation(KFbxNode::eDESTINATION_SET);
fbxDouble3 local_translation = pNode->GetGeometricTranslation(KFbxNode::eDESTINATION_SET);
fbxDouble3 local_scale = pNode->GetGeometricScaling(KFbxNode::eDESTINATION_SET);
*/
new_instance->setLocalRotation(KRVector3(local_rotation[0], local_rotation[1], local_rotation[2]));
new_instance->setLocalTranslation(KRVector3(local_translation[0], local_translation[1], local_translation[2]));
new_instance->setLocalScale(KRVector3(local_scale[0], local_scale[1], local_scale[2]));
parent_node->addChild(new_instance);
} }
} }
void LoadLight(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxNode* pNode) { KRNode *LoadLight(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxNode* pNode) {
const GLfloat PI = 3.14159265; const GLfloat PI = 3.14159265;
const GLfloat d2r = PI * 2 / 360; const GLfloat d2r = PI * 2 / 360;
@@ -648,17 +657,10 @@ void LoadLight(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxNo
} }
if(new_light) { if(new_light) {
fbxDouble3 local_rotation = pNode->LclRotation.Get(); // pNode->GetGeometricRotation(KFbxNode::eSOURCE_SET);
fbxDouble3 local_translation = pNode->LclTranslation.Get(); // pNode->GetGeometricTranslation(KFbxNode::eSOURCE_SET);
fbxDouble3 local_scale = pNode->LclScaling.Get(); // pNode->GetGeometricScaling(KFbxNode::eSOURCE_SET);
new_light->setLocalRotation(KRVector3(local_rotation[0], local_rotation[1], local_rotation[2]));
new_light->setLocalTranslation(KRVector3(local_translation[0], local_translation[1], local_translation[2]));
new_light->setLocalScale(KRVector3(local_scale[0], local_scale[1], local_scale[2]));
new_light->setColor(KRVector3(light_color[0], light_color[1], light_color[2])); new_light->setColor(KRVector3(light_color[0], light_color[1], light_color[2]));
new_light->setIntensity(light_intensity); new_light->setIntensity(light_intensity);
new_light->setDecayStart(light_decaystart); new_light->setDecayStart(light_decaystart);
parent_node->addChild(new_light);
} }
return new_light;
} }

View File

@@ -45,7 +45,7 @@ KRShaderManager::~KRShaderManager() {
} }
KRShader *KRShaderManager::getShader(std::string shader_name, KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass) { KRShader *KRShaderManager::getShader(const std::string &shader_name, const KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass) {
char szKey[256]; char szKey[256];
sprintf(szKey, "%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%i_%s_%i_%d_%d_%f_%f_%f_%f_%f_%f_%f", pCamera->bEnablePerPixel, bAlphaTest, bAlphaBlend, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, pCamera->bDebugPSSM, iShadowQuality, pCamera->bEnableAmbient, pCamera->bEnableDiffuse, pCamera->bEnableSpecular, bLightMap, bDiffuseMapScale, bSpecMapScale, bReflectionMapScale, bNormalMapScale, bDiffuseMapOffset, bSpecMapOffset, bReflectionMapOffset, bNormalMapOffset, renderPass, shader_name.c_str(),pCamera->dof_quality,pCamera->bEnableFlash,pCamera->bEnableVignette,pCamera->dof_depth,pCamera->dof_falloff,pCamera->flash_depth,pCamera->flash_falloff,pCamera->flash_intensity,pCamera->vignette_radius,pCamera->vignette_falloff); sprintf(szKey, "%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%i_%s_%i_%d_%d_%f_%f_%f_%f_%f_%f_%f", pCamera->bEnablePerPixel, bAlphaTest, bAlphaBlend, bDiffuseMap, bNormalMap, bSpecMap, bReflectionMap, bReflectionCubeMap, pCamera->bDebugPSSM, iShadowQuality, pCamera->bEnableAmbient, pCamera->bEnableDiffuse, pCamera->bEnableSpecular, bLightMap, bDiffuseMapScale, bSpecMapScale, bReflectionMapScale, bNormalMapScale, bDiffuseMapOffset, bSpecMapOffset, bReflectionMapOffset, bNormalMapOffset, renderPass, shader_name.c_str(),pCamera->dof_quality,pCamera->bEnableFlash,pCamera->bEnableVignette,pCamera->dof_depth,pCamera->dof_falloff,pCamera->flash_depth,pCamera->flash_falloff,pCamera->flash_intensity,pCamera->vignette_radius,pCamera->vignette_falloff);

View File

@@ -59,7 +59,7 @@ public:
const std::string &getVertShaderSource(const std::string &name); const std::string &getVertShaderSource(const std::string &name);
KRShader *getShader(std::string shader_name, KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass); KRShader *getShader(const std::string &shader_name, const KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass);
long getShaderHandlesUsed(); long getShaderHandlesUsed();