diff --git a/KREngine/kraken/KRAABB.cpp b/KREngine/kraken/KRAABB.cpp index 319fe63..e28aced 100644 --- a/KREngine/kraken/KRAABB.cpp +++ b/KREngine/kraken/KRAABB.cpp @@ -279,3 +279,14 @@ bool KRAABB::intersectsRay(const KRVector3 &v1, const KRVector3 &dir) const { return true; } + +void KRAABB::encapsulate(const KRAABB & b) +{ + if(b.min.x < min.x) min.x = b.min.x; + if(b.min.y < min.y) min.y = b.min.y; + if(b.min.z < min.z) min.z = b.min.z; + + if(b.max.x > max.x) max.x = b.max.x; + if(b.max.y > max.y) max.y = b.max.y; + if(b.max.z > max.z) max.z = b.max.z; +} \ No newline at end of file diff --git a/KREngine/kraken/KRAABB.h b/KREngine/kraken/KRAABB.h index ca4e7b6..802dd6e 100644 --- a/KREngine/kraken/KRAABB.h +++ b/KREngine/kraken/KRAABB.h @@ -34,6 +34,7 @@ public: bool visible(const KRMat4 &matViewProjection) const; bool intersectsLine(const KRVector3 &v1, const KRVector3 &v2) const; bool intersectsRay(const KRVector3 &v1, const KRVector3 &dir) const; + void encapsulate(const KRAABB & b); KRAABB& operator =(const KRAABB& b); bool operator ==(const KRAABB& b) const; diff --git a/KREngine/kraken/KRLODGroup.cpp b/KREngine/kraken/KRLODGroup.cpp index a892aa7..b2fcbc7 100644 --- a/KREngine/kraken/KRLODGroup.cpp +++ b/KREngine/kraken/KRLODGroup.cpp @@ -13,6 +13,7 @@ KRLODGroup::KRLODGroup(KRScene &scene, std::string name) : KRNode(scene, name) { m_min_distance = 0.0f; m_max_distance = 0.0f; + m_referencePoint = KRVector3::Zero(); } KRLODGroup::~KRLODGroup() @@ -28,6 +29,10 @@ tinyxml2::XMLElement *KRLODGroup::saveXML( tinyxml2::XMLNode *parent) tinyxml2::XMLElement *e = KRNode::saveXML(parent); e->SetAttribute("min_distance", m_min_distance); e->SetAttribute("max_distance", m_max_distance); + + e->SetAttribute("reference_x", m_referencePoint.x); + e->SetAttribute("reference_y", m_referencePoint.y); + e->SetAttribute("reference_z", m_referencePoint.z); return e; } @@ -44,13 +49,49 @@ void KRLODGroup::loadXML(tinyxml2::XMLElement *e) if(e->QueryFloatAttribute("max_distance", &m_max_distance) != tinyxml2::XML_SUCCESS) { m_max_distance = 0.0f; } + + + float x=0.0f, y=0.0f, z=0.0f; + if(e->QueryFloatAttribute("reference_x", &x) != tinyxml2::XML_SUCCESS) { + x = 0.0f; + } + if(e->QueryFloatAttribute("reference_y", &y) != tinyxml2::XML_SUCCESS) { + y = 0.0f; + } + if(e->QueryFloatAttribute("reference_z", &z) != tinyxml2::XML_SUCCESS) { + z = 0.0f; + } + m_referencePoint = KRVector3(x,y,z); +} + + +const KRVector3 KRLODGroup::getReferencePoint() +{ + return m_referencePoint; +} + +void KRLODGroup::setReferencePoint(const KRVector3 &referencePoint) +{ + m_referencePoint = referencePoint; +} + +const KRVector3 KRLODGroup::getWorldReferencePoint() +{ + return localToWorld(m_referencePoint); } bool KRLODGroup::getLODVisibility(const KRViewport &viewport) { - // Compare square distances as sqrt is expensive - float sqr_distance = (viewport.getCameraPosition() - getWorldTranslation()).sqrMagnitude(); - return ((sqr_distance >= m_min_distance * m_min_distance || m_min_distance == 0) && (sqr_distance < m_max_distance * m_max_distance || m_max_distance == 0)); + 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 = 1.0f; + + // Compare square distances as sqrt is expensive + float sqr_distance = (viewport.getCameraPosition() - getWorldReferencePoint()).sqrMagnitude() * (lod_bias * lod_bias); + return ((sqr_distance >= m_min_distance * m_min_distance || m_min_distance == 0) && (sqr_distance < m_max_distance * m_max_distance || m_max_distance == 0)); + } } void KRLODGroup::updateLODVisibility(const KRViewport &viewport) diff --git a/KREngine/kraken/KRLODGroup.h b/KREngine/kraken/KRLODGroup.h index f27395b..815daa8 100644 --- a/KREngine/kraken/KRLODGroup.h +++ b/KREngine/kraken/KRLODGroup.h @@ -28,10 +28,16 @@ public: void setMinDistance(float min_distance); void setMaxDistance(float max_distance); + const KRVector3 getReferencePoint(); + void setReferencePoint(const KRVector3 &referencePoint); + + const KRVector3 getWorldReferencePoint(); + private: bool getLODVisibility(const KRViewport &viewport); float m_min_distance; float m_max_distance; + KRVector3 m_referencePoint; // Point of reference, used for distance calculation. Usually set to the bounding box center }; diff --git a/KREngine/kraken/KRMeshManager.cpp b/KREngine/kraken/KRMeshManager.cpp index 5b553c9..40cb606 100644 --- a/KREngine/kraken/KRMeshManager.cpp +++ b/KREngine/kraken/KRMeshManager.cpp @@ -64,19 +64,17 @@ KRMeshManager::~KRMeshManager() { } KRMesh *KRMeshManager::loadModel(const char *szName, KRDataBlock *pData) { - - std::string lowerName = szName; - std::transform(lowerName.begin(), lowerName.end(), - lowerName.begin(), ::tolower); - - - KRMesh *pModel = new KRMesh(*m_pContext, lowerName, pData); + KRMesh *pModel = new KRMesh(*m_pContext, szName, pData); addModel(pModel); return pModel; } void KRMeshManager::addModel(KRMesh *model) { - m_models.insert(std::pair(model->getLODBaseName(), model)); + std::string lowerName = model->getLODBaseName(); + std::transform(lowerName.begin(), lowerName.end(), + lowerName.begin(), ::tolower); + + m_models.insert(std::pair(lowerName, model)); } std::vector KRMeshManager::getModel(const char *szName) { @@ -101,7 +99,7 @@ std::vector KRMeshManager::getModel(const char *szName) { return matching_models; } -std::multimap KRMeshManager::getModels() { +std::multimap &KRMeshManager::getModels() { return m_models; } diff --git a/KREngine/kraken/KRMeshManager.h b/KREngine/kraken/KRMeshManager.h index dbea338..22b31d8 100644 --- a/KREngine/kraken/KRMeshManager.h +++ b/KREngine/kraken/KRMeshManager.h @@ -57,7 +57,7 @@ public: void addModel(KRMesh *model); std::vector getModelNames(); - std::multimap getModels(); + std::multimap &getModels(); void bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights, bool static_vbo); diff --git a/KREngine/kraken/KRNode.cpp b/KREngine/kraken/KRNode.cpp index f7d51f3..7c83aee 100644 --- a/KREngine/kraken/KRNode.cpp +++ b/KREngine/kraken/KRNode.cpp @@ -193,7 +193,7 @@ const KRVector3 &KRNode::getInitialLocalRotation() { } const KRVector3 KRNode::getWorldTranslation() { - return KRMat4::Dot(getModelMatrix(), KRVector3::Zero()); + return localToWorld(KRVector3::Zero()); } const KRVector3 KRNode::getWorldScale() { @@ -278,7 +278,20 @@ KRScene &KRNode::getScene() { } KRAABB KRNode::getBounds() { - return KRAABB::Infinite(); + KRAABB bounds = KRAABB::Infinite(); + + bool first_child = true; + for(std::vector::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) { + KRNode *child = (*itr); + if(first_child) { + first_child = false; + bounds = child->getBounds(); + } else { + bounds.encapsulate(child->getBounds()); + } + } + + return bounds; } void KRNode::invalidateModelMatrix() @@ -475,3 +488,13 @@ bool KRNode::lodIsVisible() { return m_lod_visible; } + +const KRVector3 KRNode::localToWorld(const KRVector3 &local_point) +{ + return KRMat4::Dot(getModelMatrix(), local_point); +} + +const KRVector3 KRNode::worldToLocal(const KRVector3 &world_point) +{ + return KRMat4::Dot(getInverseModelMatrix(), world_point); +} diff --git a/KREngine/kraken/KRNode.h b/KREngine/kraken/KRNode.h index de40593..9787f81 100644 --- a/KREngine/kraken/KRNode.h +++ b/KREngine/kraken/KRNode.h @@ -71,6 +71,9 @@ public: const KRVector3 getWorldScale(); const KRVector3 getWorldRotation(); + const KRVector3 localToWorld(const KRVector3 &local_point); + const KRVector3 worldToLocal(const KRVector3 &world_point); + void setWorldTranslation(const KRVector3 &v); void setWorldScale(const KRVector3 &v); void setWorldRotation(const KRVector3 &v); diff --git a/KREngine/kraken/KRRenderSettings.cpp b/KREngine/kraken/KRRenderSettings.cpp index a619387..6d7f93d 100644 --- a/KREngine/kraken/KRRenderSettings.cpp +++ b/KREngine/kraken/KRRenderSettings.cpp @@ -26,7 +26,7 @@ KRRenderSettings::KRRenderSettings() bEnableSpecular = true; bEnableLightMap = true; bDebugSuperShiny = false; - bEnableDeferredLighting = true; + bEnableDeferredLighting = false; ambient_intensity = KRVector3::Zero(); light_intensity = KRVector3::One(); diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index 94fcbbd..97f0d26 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -95,17 +95,7 @@ std::vector KRResource::LoadFbx(KRContext &context, const std::str if(pNode) { pNode->ResetPivotSetAndConvertAnimation(); } - - // ----====---- Import Scene Graph Nodes ----====---- - printf("\nLoading scene graph...\n"); - if(pNode) - { - for(int i = 0; i < pNode->GetChildCount(); i++) - { - LoadNode(pFbxScene, pScene->getRootNode(), resources, pGeometryConverter, pNode->GetChild(i)); - } - } - + // ----====---- Import Animation Layers ----====---- printf("\nLoading animations...\n"); int animation_count = pFbxScene->GetSrcObjectCount(); @@ -162,10 +152,24 @@ std::vector KRResource::LoadFbx(KRContext &context, const std::str context.loadResource(file_name); } + // ----====---- Import Scene Graph Nodes ----====---- + printf("\nLoading scene graph...\n"); + if(pNode) + { + for(int i = 0; i < pNode->GetChildCount(); i++) + { + LoadNode(pFbxScene, pScene->getRootNode(), resources, pGeometryConverter, pNode->GetChild(i)); + } + } + for(std::map::iterator texture_itr = context.getTextureManager()->getTextures().begin(); texture_itr != context.getTextureManager()->getTextures().end(); texture_itr++) { resources.push_back((*texture_itr).second); } + for(std::map::iterator mesh_itr = context.getModelManager()->getModels().begin(); mesh_itr != context.getModelManager()->getModels().end(); mesh_itr++) { + resources.push_back((*mesh_itr).second); + } + DestroySdkObjects(lSdkManager); // Compress textures to PVR format @@ -727,7 +731,6 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vectorGetNodeAttribute()->GetAttributeType()); if(attribute_type == KFbxNodeAttribute::eLODGroup) { std::string name = GetFbxObjectName(pNode); @@ -741,6 +744,8 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vectorMinDistance.Get(); group_max_distance = fbx_lod_group->MinDistance.Get(); } + + KRVector3 reference_point; // Create a lod_group node for each fbx child node int child_count = pNode->GetChildCount(); for(int i = 0; i < child_count; i++) @@ -792,6 +797,13 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vectoraddChild(new_node); LoadNode(pFbxScene, new_node, resources, pGeometryConverter, pNode->GetChild(i)); + + if(i == 0) { + // Calculate reference point using the bounding box center from the highest quality LOD level + reference_point = new_node->getBounds().center(); + } + + new_node->setReferencePoint(new_node->worldToLocal(reference_point)); } } else { KRNode *new_node = NULL; @@ -1279,7 +1291,8 @@ void LoadMesh(KRContext &context, std::vector &resources, FbxGeome KRMesh *new_mesh = new KRMesh(context, pSourceMesh->GetNode()->GetName()); new_mesh->LoadData(vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights,KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES); - resources.push_back(new_mesh); + + context.getModelManager()->addModel(new_mesh); } KRNode *LoadMesh(KRNode *parent_node, std::vector &resources, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) { diff --git a/KREngine/kraken/KRScene.cpp b/KREngine/kraken/KRScene.cpp index 87aec87..9dfea53 100644 --- a/KREngine/kraken/KRScene.cpp +++ b/KREngine/kraken/KRScene.cpp @@ -489,3 +489,4 @@ bool KRScene::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hiti { return m_nodeTree.rayCast(v0, dir, hitinfo, layer_mask); } +