diff --git a/KREngine/kraken/KRCamera.cpp b/KREngine/kraken/KRCamera.cpp index 03c0845..7a4abf1 100644 --- a/KREngine/kraken/KRCamera.cpp +++ b/KREngine/kraken/KRCamera.cpp @@ -1102,7 +1102,7 @@ std::string KRCamera::getDebugText() } -const KRViewport &KRCamera::getViewport() +const KRViewport &KRCamera::getViewport() const { return m_viewport; } diff --git a/KREngine/kraken/KRCamera.h b/KREngine/kraken/KRCamera.h index 560dd4e..4978c00 100644 --- a/KREngine/kraken/KRCamera.h +++ b/KREngine/kraken/KRCamera.h @@ -59,7 +59,7 @@ public: KRRenderSettings settings; - const KRViewport &getViewport(); + const KRViewport &getViewport() const; virtual std::string getElementName(); diff --git a/KREngine/kraken/KRContext.h b/KREngine/kraken/KRContext.h index 4f91d40..06402e2 100644 --- a/KREngine/kraken/KRContext.h +++ b/KREngine/kraken/KRContext.h @@ -88,7 +88,6 @@ public: static void SetLogCallback(log_callback *log_callback, void *user_data); static void Log(log_level level, const std::string &message_format, ...); - private: KRBundleManager *m_pBundleManager; KRSceneManager *m_pSceneManager; diff --git a/KREngine/kraken/KREngine-common.h b/KREngine/kraken/KREngine-common.h index 5dcf36b..c02b537 100644 --- a/KREngine/kraken/KREngine-common.h +++ b/KREngine/kraken/KREngine-common.h @@ -183,6 +183,12 @@ fprintf(stderr, "Error at line number %d, in file %s. Returned %d for call %s\n" #define KRCLAMP(x, min, max) (KRMAX(KRMIN(x, max), min)) #define KRALIGN(x) ((x + 3) & ~0x03) +typedef enum { + STREAM_LEVEL_OUT, + STREAM_LEVEL_IN_LQ, + STREAM_LEVEL_IN_HQ +} kraken_stream_level; + #include "KRVector4.h" #include "KRVector3.h" #include "KRVector2.h" diff --git a/KREngine/kraken/KRLODGroup.cpp b/KREngine/kraken/KRLODGroup.cpp index 9df0a4f..907427a 100644 --- a/KREngine/kraken/KRLODGroup.cpp +++ b/KREngine/kraken/KRLODGroup.cpp @@ -7,6 +7,7 @@ // #include "KRLODGroup.h" +#include "KRLODSet.h" #include "KRContext.h" KRLODGroup::KRLODGroup(KRScene &scene, std::string name) : KRNode(scene, name) @@ -128,22 +129,6 @@ bool KRLODGroup::getLODVisibility(const KRViewport &viewport) } } -void KRLODGroup::updateLODVisibility(const KRViewport &viewport) -{ - bool new_visibility = getLODVisibility(viewport); - if(!new_visibility) { - hideLOD(); - } else { - if(!m_lod_visible) { - getScene().notify_sceneGraphCreate(this); - m_lod_visible = true; - } - for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { - (*itr)->updateLODVisibility(viewport); - } - } -} - float KRLODGroup::getMinDistance() { return m_min_distance; diff --git a/KREngine/kraken/KRLODGroup.h b/KREngine/kraken/KRLODGroup.h index c394fb4..e86a9c8 100644 --- a/KREngine/kraken/KRLODGroup.h +++ b/KREngine/kraken/KRLODGroup.h @@ -20,8 +20,6 @@ public: virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); virtual void loadXML(tinyxml2::XMLElement *e); - virtual void updateLODVisibility(const KRViewport &viewport); - float getMinDistance(); float getMaxDistance(); void setMinDistance(float min_distance); @@ -32,8 +30,9 @@ public: void setUseWorldUnits(bool use_world_units); bool getUseWorldUnits() const; -private: bool getLODVisibility(const KRViewport &viewport); + +private: float m_min_distance; float m_max_distance; KRAABB m_reference; // Point of reference, used for distance calculation. Usually set to the bounding box center diff --git a/KREngine/kraken/KRLODSet.cpp b/KREngine/kraken/KRLODSet.cpp index 93fe90d..5b3a10b 100644 --- a/KREngine/kraken/KRLODSet.cpp +++ b/KREngine/kraken/KRLODSet.cpp @@ -7,11 +7,12 @@ // #include "KRLODSet.h" +#include "KRLODGroup.h" #include "KRContext.h" KRLODSet::KRLODSet(KRScene &scene, std::string name) : KRNode(scene, name) { - + m_activeLODGroup = NULL; } KRLODSet::~KRLODSet() @@ -33,3 +34,82 @@ void KRLODSet::loadXML(tinyxml2::XMLElement *e) { KRNode::loadXML(e); } + + +void KRLODSet::updateLODVisibility(const KRViewport &viewport) +{ + if(m_lod_visible) { + KRLODGroup *new_active_lod_group = NULL; + + // Upgrade and downgrade LOD groups as needed + for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + KRLODGroup *lod_group = dynamic_cast(*itr); + assert(lod_group != NULL); + if(lod_group->getLODVisibility(viewport)) { + new_active_lod_group = lod_group; + } + } + + if(new_active_lod_group == NULL) { + m_activeLODGroup = NULL; + } else if(m_activeLODGroup == NULL) { + m_activeLODGroup = new_active_lod_group; + } else if(new_active_lod_group != m_activeLODGroup) { + if(new_active_lod_group->getStreamLevel(true) >= kraken_stream_level::STREAM_LEVEL_IN_LQ) { + fprintf(stderr, "LOD %s -> %s\n", m_activeLODGroup->getName().c_str(), new_active_lod_group->getName().c_str()); + m_activeLODGroup = new_active_lod_group; + } else { + fprintf(stderr, "LOD %s -> %s - waiting for streaming...\n", m_activeLODGroup->getName().c_str(), new_active_lod_group->getName().c_str()); + } + } + + for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + KRNode *child = *itr; + if(child == m_activeLODGroup) { + child->showLOD(); + } else { + child->hideLOD(); + } + } + + KRNode::updateLODVisibility(viewport); + } +} + +KRLODGroup *KRLODSet::getActiveLODGroup() const +{ + return m_activeLODGroup; +} + +void KRLODSet::childDeleted(KRNode *child_node) +{ + KRNode::childDeleted(child_node); + if(m_activeLODGroup == child_node) { + m_activeLODGroup = NULL; + } +} + +void KRLODSet::hideLOD() +{ + KRNode::hideLOD(); + m_activeLODGroup = NULL; // Ensure that the streamer will wait for the group to load in next time +} + +void KRLODSet::showLOD() +{ + // Don't automatically recurse into our children, as only one of those will be activated, by updateLODVisibility + if(!m_lod_visible) { + getScene().notify_sceneGraphCreate(this); + m_lod_visible = true; + } +} + +kraken_stream_level KRLODSet::getStreamLevel(bool prime) +{ + if(m_activeLODGroup) { + return m_activeLODGroup->getStreamLevel(prime); + } else { + return kraken_stream_level::STREAM_LEVEL_IN_HQ; + } +} + diff --git a/KREngine/kraken/KRLODSet.h b/KREngine/kraken/KRLODSet.h index cbb5337..a66544f 100644 --- a/KREngine/kraken/KRLODSet.h +++ b/KREngine/kraken/KRLODSet.h @@ -12,6 +12,8 @@ #include "KRResource.h" #include "KRNode.h" +class KRLODGroup; + class KRLODSet : public KRNode { public: KRLODSet(KRScene &scene, std::string name); @@ -20,6 +22,18 @@ public: virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); virtual void loadXML(tinyxml2::XMLElement *e); + virtual void updateLODVisibility(const KRViewport &viewport); + + KRLODGroup *getActiveLODGroup() const; + + virtual void showLOD(); + virtual void hideLOD(); + virtual void childDeleted(KRNode *child_node); + + virtual kraken_stream_level getStreamLevel(bool prime = true); + +private: + KRLODGroup *m_activeLODGroup; }; diff --git a/KREngine/kraken/KRMaterial.cpp b/KREngine/kraken/KRMaterial.cpp index 141f648..bbe4730 100644 --- a/KREngine/kraken/KRMaterial.cpp +++ b/KREngine/kraken/KRMaterial.cpp @@ -118,7 +118,7 @@ bool KRMaterial::save(KRDataBlock &data) { stream << "\n# map_Reflection filename.pvr -s 1.0 1.0 -o 0.0 0.0"; } if(m_reflectionCube.size()) { - stream << "map_ReflectionCube " << m_reflectionCube << ".pvr"; + stream << "\nmap_ReflectionCube " << m_reflectionCube << ".pvr"; } else { stream << "\n# map_ReflectionCube cubemapname"; } @@ -217,9 +217,41 @@ bool KRMaterial::isTransparent() { return m_tr < 1.0 || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDONESIDE || m_alpha_mode == KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE; } -bool KRMaterial::bind(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const std::vector &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const KRVector3 &rim_color, float rim_power) { - bool bLightMap = pLightMap && pCamera->settings.bEnableLightMap; +kraken_stream_level KRMaterial::getStreamLevel(bool prime) +{ + kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; + getTextures(); + + if(m_pAmbientMap) { + stream_level = KRMIN(stream_level, m_pNormalMap->getStreamLevel(prime)); + } + + if(m_pDiffuseMap) { + stream_level = KRMIN(stream_level, m_pDiffuseMap->getStreamLevel(prime)); + } + + if(m_pNormalMap) { + stream_level = KRMIN(stream_level, m_pNormalMap->getStreamLevel(prime)); + } + + if(m_pSpecularMap) { + stream_level = KRMIN(stream_level, m_pSpecularMap->getStreamLevel(prime)); + } + + if(m_pReflectionMap) { + stream_level = KRMIN(stream_level, m_pReflectionMap->getStreamLevel(prime)); + } + + if(m_pReflectionCube) { + stream_level = KRMIN(stream_level, m_pReflectionCube->getStreamLevel(prime)); + } + + return stream_level; +} + +void KRMaterial::getTextures() +{ if(!m_pAmbientMap && m_ambientMap.size()) { m_pAmbientMap = getContext().getTextureManager()->getTexture(m_ambientMap); } @@ -238,6 +270,12 @@ bool KRMaterial::bind(KRCamera *pCamera, std::vector &point_ligh if(!m_pReflectionCube && m_reflectionCube.size()) { m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str()); } +} + +bool KRMaterial::bind(KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const std::vector &bones, const std::vector &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const KRVector3 &rim_color, float rim_power) { + bool bLightMap = pLightMap && pCamera->settings.bEnableLightMap; + + getTextures(); KRVector2 default_scale = KRVector2::One(); KRVector2 default_offset = KRVector2::Zero(); diff --git a/KREngine/kraken/KRMaterial.h b/KREngine/kraken/KRMaterial.h index ef6d9ee..503a045 100644 --- a/KREngine/kraken/KRMaterial.h +++ b/KREngine/kraken/KRMaterial.h @@ -88,6 +88,8 @@ public: bool needsVertexTangents(); + kraken_stream_level getStreamLevel(bool prime = true); + private: std::string m_name; @@ -129,6 +131,8 @@ private: GLfloat m_ns; // Shininess alpha_mode_type m_alpha_mode; + + void getTextures(); }; #endif diff --git a/KREngine/kraken/KRMesh.cpp b/KREngine/kraken/KRMesh.cpp index 4be1af1..36acf44 100644 --- a/KREngine/kraken/KRMesh.cpp +++ b/KREngine/kraken/KRMesh.cpp @@ -161,33 +161,51 @@ void KRMesh::loadPack(KRDataBlock *data) { updateAttributeOffsets(); } +void KRMesh::getMaterials() +{ + if(m_materials.size() == 0) { + + for(std::vector::iterator itr = m_submeshes.begin(); itr != m_submeshes.end(); itr++) { + const char *szMaterialName = (*itr)->szMaterialName; + KRMaterial *pMaterial = getContext().getMaterialManager()->getMaterial(szMaterialName); + m_materials.push_back(pMaterial); + if(pMaterial) { + m_uniqueMaterials.insert(pMaterial); + } else { + KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Missing material: %s", szMaterialName); + } + } + + m_hasTransparency = false; + for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { + if((*mat_itr)->isTransparent()) { + m_hasTransparency = true; + break; + } + } + } +} + +kraken_stream_level KRMesh::getStreamLevel(bool prime) +{ + kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; + getSubmeshes(); + getMaterials(); + + for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { + stream_level = KRMIN(stream_level, (*mat_itr)->getStreamLevel(prime)); + } + + return stream_level; +} + void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones, const KRVector3 &rim_color, float rim_power) { //fprintf(stderr, "Rendering model: %s\n", m_name.c_str()); if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { getSubmeshes(); - if(m_materials.size() == 0) { - - for(std::vector::iterator itr = m_submeshes.begin(); itr != m_submeshes.end(); itr++) { - const char *szMaterialName = (*itr)->szMaterialName; - KRMaterial *pMaterial = getContext().getMaterialManager()->getMaterial(szMaterialName); - m_materials.push_back(pMaterial); - if(pMaterial) { - m_uniqueMaterials.insert(pMaterial); - } else { - KRContext::Log(KRContext::LOG_LEVEL_WARNING, "Missing material: %s", szMaterialName); - } - } - - m_hasTransparency = false; - for(std::set::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) { - if((*mat_itr)->isTransparent()) { - m_hasTransparency = true; - break; - } - } - } + getMaterials(); int cSubmeshes = m_submeshes.size(); if(renderPass == KRNode::RENDER_PASS_SHADOWMAP) { diff --git a/KREngine/kraken/KRMesh.h b/KREngine/kraken/KRMesh.h index b5217a8..891ddeb 100644 --- a/KREngine/kraken/KRMesh.h +++ b/KREngine/kraken/KRMesh.h @@ -67,6 +67,8 @@ public: KRMesh(KRContext &context, std::string name); virtual ~KRMesh(); + kraken_stream_level getStreamLevel(bool prime = true); + bool hasTransparency(); typedef enum { @@ -218,6 +220,7 @@ private: KRDataBlock *m_pIndexBaseData; void getSubmeshes(); + void getMaterials(); static bool rayCast(const KRVector3 &start, const KRVector3 &dir, const KRTriangle3 &tri, const KRVector3 &tri_n0, const KRVector3 &tri_n1, const KRVector3 &tri_n2, KRHitInfo &hitinfo); static bool sphereCast(const KRMat4 &model_to_world, const KRVector3 &v0, const KRVector3 &v1, float radius, const KRTriangle3 &tri, KRHitInfo &hitinfo); diff --git a/KREngine/kraken/KRModel.cpp b/KREngine/kraken/KRModel.cpp index f337aba..aa931b1 100644 --- a/KREngine/kraken/KRModel.cpp +++ b/KREngine/kraken/KRModel.cpp @@ -80,7 +80,7 @@ tinyxml2::XMLElement *KRModel::saveXML( tinyxml2::XMLNode *parent) e->SetAttribute("lod_min_coverage", m_min_lod_coverage); e->SetAttribute("receives_shadow", m_receivesShadow ? "true" : "false"); e->SetAttribute("faces_camera", m_faces_camera ? "true" : "false"); - m_rim_color.setXMLAttribute("rim_color", e); + m_rim_color.setXMLAttribute("rim_color", e, KRVector3::Zero()); e->SetAttribute("rim_power", m_rim_power); return e; } @@ -199,6 +199,20 @@ void KRModel::render(KRCamera *pCamera, std::vector &point_light } } + +kraken_stream_level KRModel::getStreamLevel(bool prime) +{ + kraken_stream_level stream_level = KRNode::getStreamLevel(prime); + + loadModel(); + + for(auto itr = m_models.begin(); itr != m_models.end(); itr++) { + stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(prime)); + } + + return stream_level; +} + KRAABB KRModel::getBounds() { loadModel(); if(m_models.size() > 0) { diff --git a/KREngine/kraken/KRModel.h b/KREngine/kraken/KRModel.h index c688f70..a048071 100644 --- a/KREngine/kraken/KRModel.h +++ b/KREngine/kraken/KRModel.h @@ -69,6 +69,8 @@ public: void setLightMap(const std::string &name); std::string getLightMap(); + virtual kraken_stream_level getStreamLevel(bool prime = true); + private: std::vector m_models; unordered_map > m_bones; // Outer std::map connects model to set of bones diff --git a/KREngine/kraken/KRNode.cpp b/KREngine/kraken/KRNode.cpp index ebbbeb2..1cd4eda 100644 --- a/KREngine/kraken/KRNode.cpp +++ b/KREngine/kraken/KRNode.cpp @@ -10,6 +10,7 @@ #include "KRNode.h" #include "KRLODGroup.h" +#include "KRLODSet.h" #include "KRPointLight.h" #include "KRSpotLight.h" #include "KRDirectionalLight.h" @@ -126,17 +127,17 @@ 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()); - m_localTranslation.setXMLAttribute("translate", e); - m_localScale.setXMLAttribute("scale", e); - (m_localRotation * (180.0f / M_PI)).setXMLAttribute("rotate", e); + m_localTranslation.setXMLAttribute("translate", e, KRVector3::Zero()); + m_localScale.setXMLAttribute("scale", e, KRVector3::One()); + (m_localRotation * (180.0f / M_PI)).setXMLAttribute("rotate", e, KRVector3::Zero()); - 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); + m_rotationOffset.setXMLAttribute("rotate_offset", e, KRVector3::Zero()); + m_scalingOffset.setXMLAttribute("scale_offset", e, KRVector3::Zero()); + m_rotationPivot.setXMLAttribute("rotate_pivot", e, KRVector3::Zero()); + m_scalingPivot.setXMLAttribute("scale_pivot", e, KRVector3::Zero()); + (m_preRotation * (180.0f / M_PI)).setXMLAttribute("pre_rotate", e, KRVector3::Zero()); + (m_postRotation * (180.0f / M_PI)).setXMLAttribute("post_rotate", e, KRVector3::Zero()); for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { KRNode *child = (*itr); @@ -395,6 +396,8 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) { const char *szName = e->Attribute("name"); if(strcmp(szElementName, "node") == 0) { new_node = new KRNode(scene, szName); + } if(strcmp(szElementName, "lod_set") == 0) { + new_node = new KRLODSet(scene, szName); } if(strcmp(szElementName, "lod_group") == 0) { new_node = new KRLODGroup(scene, szName); } else if(strcmp(szElementName, "point_light") == 0) { @@ -879,8 +882,11 @@ void KRNode::addToOctreeNode(KROctreeNode *octree_node) void KRNode::updateLODVisibility(const KRViewport &viewport) { - // If we aren't an LOD group node, then we just add ourselves and all our children to the octree - showLOD(); + if(m_lod_visible) { + for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + (*itr)->updateLODVisibility(viewport); + } + } } void KRNode::hideLOD() @@ -932,3 +938,14 @@ std::set &KRNode::getBehaviors() { return m_behaviors; } + +kraken_stream_level KRNode::getStreamLevel(bool prime) +{ + kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; + + for(std::set::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { + stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(prime)); + } + + return stream_level; +} diff --git a/KREngine/kraken/KRNode.h b/KREngine/kraken/KRNode.h index eb074fa..e4bb849 100644 --- a/KREngine/kraken/KRNode.h +++ b/KREngine/kraken/KRNode.h @@ -165,6 +165,12 @@ public: void setAnimationEnabled(node_attribute_type attrib, bool enable); bool getAnimationEnabled(node_attribute_type attrib) const; + + virtual kraken_stream_level getStreamLevel(bool prime = true); + + virtual void hideLOD(); + virtual void showLOD(); + protected: KRVector3 m_localTranslation; KRVector3 m_localScale; @@ -189,10 +195,6 @@ protected: KRVector3 m_initialPostRotation; bool m_lod_visible; - void hideLOD(); - void showLOD(); - float m_lod_min_coverage; - float m_lod_max_coverage; KRNode *m_parentNode; std::set m_childNodes; @@ -240,7 +242,7 @@ public: } void removeFromOctreeNodes(); void addToOctreeNode(KROctreeNode *octree_node); - void childDeleted(KRNode *child_node); + virtual void childDeleted(KRNode *child_node); template T *find() { diff --git a/KREngine/kraken/KRResource+fbx.cpp b/KREngine/kraken/KRResource+fbx.cpp index 697da3e..0c87e14 100644 --- a/KREngine/kraken/KRResource+fbx.cpp +++ b/KREngine/kraken/KRResource+fbx.cpp @@ -28,6 +28,7 @@ #include "KRBundle.h" #include "KRModel.h" #include "KRLODGroup.h" +#include "KRLODSet.h" #include "KRCollider.h" #ifdef IOS_REF @@ -947,6 +948,9 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG group_max_distance = fbx_lod_group->MinDistance.Get(); } + KRLODSet *lod_set = new KRLODSet(parent_node->getScene(), name); + parent_node->addChild(lod_set); + KRAABB reference_bounds; // Create a lod_group node for each fbx child node int child_count = pNode->GetChildCount(); @@ -1006,7 +1010,7 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG new_node->setPostRotation(node_post_rotation); new_node->setUseWorldUnits(use_world_space_units); - parent_node->addChild(new_node); + lod_set->addChild(new_node); LoadNode(pFbxScene, new_node, pGeometryConverter, pNode->GetChild(i)); @@ -1049,19 +1053,7 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG if(pNode->GetChildCount() > 0) { // Create an empty node, for inheritence of transforms std::string name = GetFbxObjectName(pNode); - - - /* - if(min_distance == 0.0f && max_distance == 0.0f) { - // Regular node for grouping children together under one transform - new_node = new KRNode(parent_node->getScene(), name); - } else { - */ - // LOD Enabled group node - KRLODGroup *lod_group = new KRLODGroup(parent_node->getScene(), name); - lod_group->setMinDistance(0.0f); - lod_group->setMaxDistance(0.0f); - new_node = lod_group; + new_node = new KRNode(parent_node->getScene(), name); } } } diff --git a/KREngine/kraken/KRScene.cpp b/KREngine/kraken/KRScene.cpp index 1f07bc7..816a4ca 100644 --- a/KREngine/kraken/KRScene.cpp +++ b/KREngine/kraken/KRScene.cpp @@ -38,7 +38,6 @@ #include "KRScene.h" #include "KRNode.h" -#include "KRLODGroup.h" #include "KRStockGeometry.h" #include "KRDirectionalLight.h" #include "KRSpotLight.h" @@ -49,7 +48,7 @@ const long KRENGINE_OCCLUSION_TEST_EXPIRY = 10; KRScene::KRScene(KRContext &context, std::string name) : KRResource(context, name) { m_pFirstLight = NULL; - m_pRootNode = new KRLODGroup(*this, "scene_root"); + m_pRootNode = new KRNode(*this, "scene_root"); notify_sceneGraphCreate(m_pRootNode); m_skyBoxName = name + "_skybox"; @@ -98,6 +97,11 @@ std::set &KRScene::getLocators() return m_locatorNodes; } +std::set &KRScene::getLights() +{ + return m_lights; +} + void KRScene::render(KRCamera *pCamera, unordered_map &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame) { if(new_frame) { // Expire cached occlusion test results. @@ -469,6 +473,10 @@ void KRScene::notify_sceneGraphDelete(KRNode *pNode) if(locator) { m_locatorNodes.erase(locator); } + KRLight *light = dynamic_cast(pNode); + if(light) { + m_lights.erase(light); + } m_modifiedNodes.erase(pNode); if(!m_newNodes.erase(pNode)) { m_nodeTree.remove(pNode); @@ -477,6 +485,7 @@ void KRScene::notify_sceneGraphDelete(KRNode *pNode) void KRScene::updateOctree(const KRViewport &viewport) { + m_pRootNode->showLOD(); m_pRootNode->updateLODVisibility(viewport); std::set newNodes = std::move(m_newNodes); @@ -502,6 +511,10 @@ void KRScene::updateOctree(const KRViewport &viewport) if(locatorNode) { m_locatorNodes.insert(locatorNode); } + KRLight *light = dynamic_cast(node); + if(light) { + m_lights.insert(light); + } } for(std::set::iterator itr=modifiedNodes.begin(); itr != modifiedNodes.end(); itr++) { @@ -558,3 +571,13 @@ bool KRScene::sphereCast(const KRVector3 &v0, const KRVector3 &v1, float radius, } +kraken_stream_level KRScene::getStreamLevel(bool prime) +{ + kraken_stream_level stream_level = kraken_stream_level::STREAM_LEVEL_IN_HQ; + + if(m_pRootNode) { + stream_level = KRMIN(stream_level, m_pRootNode->getStreamLevel(prime)); + } + + return stream_level; +} diff --git a/KREngine/kraken/KRScene.h b/KREngine/kraken/KRScene.h index 90ef75c..7050dd4 100644 --- a/KREngine/kraken/KRScene.h +++ b/KREngine/kraken/KRScene.h @@ -64,6 +64,8 @@ public: KRNode *getRootNode(); KRLight *getFirstLight(); + kraken_stream_level getStreamLevel(bool prime = true); + bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo, unsigned int layer_mask); bool rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo, unsigned int layer_mask); bool sphereCast(const KRVector3 &v0, const KRVector3 &v1, float radius, KRHitInfo &hitinfo, unsigned int layer_mask); @@ -87,6 +89,7 @@ public: std::set &getAmbientZones(); std::set &getReverbZones(); std::set &getLocators(); + std::set &getLights(); private: @@ -102,6 +105,7 @@ private: std::set m_ambientZoneNodes; std::set m_reverbZoneNodes; std::set m_locatorNodes; + std::set m_lights; KROctree m_nodeTree; diff --git a/KREngine/kraken/KRTexture.cpp b/KREngine/kraken/KRTexture.cpp index 4bc425f..f0207aa 100644 --- a/KREngine/kraken/KRTexture.cpp +++ b/KREngine/kraken/KRTexture.cpp @@ -99,11 +99,26 @@ void KRTexture::resetPoolExpiry() m_last_frame_used = getContext().getCurrentFrame(); } + +kraken_stream_level KRTexture::getStreamLevel(bool prime) +{ + if(prime) { + resetPoolExpiry(); + } + + if(m_current_lod_max_dim == 0) { + return kraken_stream_level::STREAM_LEVEL_OUT; + } else if(m_current_lod_max_dim == m_max_lod_max_dim) { + return kraken_stream_level::STREAM_LEVEL_IN_HQ; + } else { + return kraken_stream_level::STREAM_LEVEL_IN_LQ; + } +} + long KRTexture::getLastFrameUsed() { return m_last_frame_used; } - bool KRTexture::isAnimated() { return false; diff --git a/KREngine/kraken/KRTexture.h b/KREngine/kraken/KRTexture.h index dccdd72..dde342f 100644 --- a/KREngine/kraken/KRTexture.h +++ b/KREngine/kraken/KRTexture.h @@ -38,8 +38,8 @@ #include "KRContextObject.h" #include "KRResource.h" - class KRDataBlock; +class KRCamera; class KRTexture : public KRResource { public: @@ -66,6 +66,7 @@ public: bool hasMipmaps(); bool canStreamOut() const; + kraken_stream_level getStreamLevel(bool prime = true); void _swapHandles(); protected: diff --git a/KREngine/kraken/KRVector3.cpp b/KREngine/kraken/KRVector3.cpp index 1a6b55d..9074b68 100644 --- a/KREngine/kraken/KRVector3.cpp +++ b/KREngine/kraken/KRVector3.cpp @@ -417,13 +417,15 @@ 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) +void KRVector3::setXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const KRVector3 &default_value) { // 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); + if(*this != default_value) { + 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) diff --git a/KREngine/kraken/KRVector3.h b/KREngine/kraken/KRVector3.h index 82aa60f..072843e 100644 --- a/KREngine/kraken/KRVector3.h +++ b/KREngine/kraken/KRVector3.h @@ -126,7 +126,7 @@ public: void setUniform(GLint location) const; - void setXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e); + void setXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const KRVector3 &default_value); void getXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const KRVector3 &default_value); };