- Implemented methods for determining amount of scene that has streamed in. (KRScene::getStreamLevel, KRNode::getStreamLevel, KRModel::getStreamLevel, KRMaterial::getStreamLevel, and KRTexture::getStreamLevel

- Implemented connection between LOD groups and texture streaming, which delays the switch to a new LOD group until the required textures have completed streaming in.
- Corrected bug in KRMaterial that resulted in reflection cube texture names being formatted incorrectly in the mtl file
- Scene graph now requires that lod_group nodes only be contained within lod_set nodes.
- Scene graph  group nodes that do not have a LOD minimum or maximum distance are now stored as "node" rather than as "lod_group" nodes.
- IMPORTANT!  Scenes exported with this version will not be backwards compatible with earlier versions due to the requirement of lod_set nodes.

--HG--
branch : nfb
extra : rebase_source : 1ff640b85338a794841ebbb2bf0087306ff59143
This commit is contained in:
2014-03-10 22:32:49 -07:00
parent 64f1b70545
commit 8a1164c44f
23 changed files with 305 additions and 87 deletions

View File

@@ -1102,7 +1102,7 @@ std::string KRCamera::getDebugText()
} }
const KRViewport &KRCamera::getViewport() const KRViewport &KRCamera::getViewport() const
{ {
return m_viewport; return m_viewport;
} }

View File

@@ -59,7 +59,7 @@ public:
KRRenderSettings settings; KRRenderSettings settings;
const KRViewport &getViewport(); const KRViewport &getViewport() const;
virtual std::string getElementName(); virtual std::string getElementName();

View File

@@ -88,7 +88,6 @@ public:
static void SetLogCallback(log_callback *log_callback, void *user_data); static void SetLogCallback(log_callback *log_callback, void *user_data);
static void Log(log_level level, const std::string &message_format, ...); static void Log(log_level level, const std::string &message_format, ...);
private: private:
KRBundleManager *m_pBundleManager; KRBundleManager *m_pBundleManager;
KRSceneManager *m_pSceneManager; KRSceneManager *m_pSceneManager;

View File

@@ -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 KRCLAMP(x, min, max) (KRMAX(KRMIN(x, max), min))
#define KRALIGN(x) ((x + 3) & ~0x03) #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 "KRVector4.h"
#include "KRVector3.h" #include "KRVector3.h"
#include "KRVector2.h" #include "KRVector2.h"

View File

@@ -7,6 +7,7 @@
// //
#include "KRLODGroup.h" #include "KRLODGroup.h"
#include "KRLODSet.h"
#include "KRContext.h" #include "KRContext.h"
KRLODGroup::KRLODGroup(KRScene &scene, std::string name) : KRNode(scene, name) 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<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
(*itr)->updateLODVisibility(viewport);
}
}
}
float KRLODGroup::getMinDistance() float KRLODGroup::getMinDistance()
{ {
return m_min_distance; return m_min_distance;

View File

@@ -20,8 +20,6 @@ public:
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
virtual void loadXML(tinyxml2::XMLElement *e); virtual void loadXML(tinyxml2::XMLElement *e);
virtual void updateLODVisibility(const KRViewport &viewport);
float getMinDistance(); float getMinDistance();
float getMaxDistance(); float getMaxDistance();
void setMinDistance(float min_distance); void setMinDistance(float min_distance);
@@ -32,8 +30,9 @@ public:
void setUseWorldUnits(bool use_world_units); void setUseWorldUnits(bool use_world_units);
bool getUseWorldUnits() const; bool getUseWorldUnits() const;
private:
bool getLODVisibility(const KRViewport &viewport); bool getLODVisibility(const KRViewport &viewport);
private:
float m_min_distance; float m_min_distance;
float m_max_distance; float m_max_distance;
KRAABB m_reference; // Point of reference, used for distance calculation. Usually set to the bounding box center KRAABB m_reference; // Point of reference, used for distance calculation. Usually set to the bounding box center

View File

@@ -7,11 +7,12 @@
// //
#include "KRLODSet.h" #include "KRLODSet.h"
#include "KRLODGroup.h"
#include "KRContext.h" #include "KRContext.h"
KRLODSet::KRLODSet(KRScene &scene, std::string name) : KRNode(scene, name) KRLODSet::KRLODSet(KRScene &scene, std::string name) : KRNode(scene, name)
{ {
m_activeLODGroup = NULL;
} }
KRLODSet::~KRLODSet() KRLODSet::~KRLODSet()
@@ -33,3 +34,82 @@ void KRLODSet::loadXML(tinyxml2::XMLElement *e)
{ {
KRNode::loadXML(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<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRLODGroup *lod_group = dynamic_cast<KRLODGroup *>(*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<KRNode *>::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;
}
}

View File

@@ -12,6 +12,8 @@
#include "KRResource.h" #include "KRResource.h"
#include "KRNode.h" #include "KRNode.h"
class KRLODGroup;
class KRLODSet : public KRNode { class KRLODSet : public KRNode {
public: public:
KRLODSet(KRScene &scene, std::string name); KRLODSet(KRScene &scene, std::string name);
@@ -20,6 +22,18 @@ public:
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
virtual void loadXML(tinyxml2::XMLElement *e); 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;
}; };

View File

@@ -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"; stream << "\n# map_Reflection filename.pvr -s 1.0 1.0 -o 0.0 0.0";
} }
if(m_reflectionCube.size()) { if(m_reflectionCube.size()) {
stream << "map_ReflectionCube " << m_reflectionCube << ".pvr"; stream << "\nmap_ReflectionCube " << m_reflectionCube << ".pvr";
} else { } else {
stream << "\n# map_ReflectionCube cubemapname"; 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; 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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const std::vector<KRBone *> &bones, const std::vector<KRMat4> &bind_poses, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const KRVector3 &rim_color, float rim_power) { kraken_stream_level KRMaterial::getStreamLevel(bool prime)
bool bLightMap = pLightMap && pCamera->settings.bEnableLightMap; {
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()) { if(!m_pAmbientMap && m_ambientMap.size()) {
m_pAmbientMap = getContext().getTextureManager()->getTexture(m_ambientMap); m_pAmbientMap = getContext().getTextureManager()->getTexture(m_ambientMap);
} }
@@ -238,6 +270,12 @@ bool KRMaterial::bind(KRCamera *pCamera, std::vector<KRPointLight *> &point_ligh
if(!m_pReflectionCube && m_reflectionCube.size()) { if(!m_pReflectionCube && m_reflectionCube.size()) {
m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str()); m_pReflectionCube = getContext().getTextureManager()->getTextureCube(m_reflectionCube.c_str());
} }
}
bool KRMaterial::bind(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const std::vector<KRBone *> &bones, const std::vector<KRMat4> &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_scale = KRVector2::One();
KRVector2 default_offset = KRVector2::Zero(); KRVector2 default_offset = KRVector2::Zero();

View File

@@ -88,6 +88,8 @@ public:
bool needsVertexTangents(); bool needsVertexTangents();
kraken_stream_level getStreamLevel(bool prime = true);
private: private:
std::string m_name; std::string m_name;
@@ -129,6 +131,8 @@ private:
GLfloat m_ns; // Shininess GLfloat m_ns; // Shininess
alpha_mode_type m_alpha_mode; alpha_mode_type m_alpha_mode;
void getTextures();
}; };
#endif #endif

View File

@@ -161,33 +161,51 @@ void KRMesh::loadPack(KRDataBlock *data) {
updateAttributeOffsets(); updateAttributeOffsets();
} }
void KRMesh::getMaterials()
{
if(m_materials.size() == 0) {
for(std::vector<KRMesh::Submesh *>::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<KRMaterial *>::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<KRMaterial *>::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<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones, const KRVector3 &rim_color, float rim_power) { void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones, const KRVector3 &rim_color, float rim_power) {
//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 && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
getSubmeshes(); getSubmeshes();
if(m_materials.size() == 0) { getMaterials();
for(std::vector<KRMesh::Submesh *>::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<KRMaterial *>::iterator mat_itr = m_uniqueMaterials.begin(); mat_itr != m_uniqueMaterials.end(); mat_itr++) {
if((*mat_itr)->isTransparent()) {
m_hasTransparency = true;
break;
}
}
}
int cSubmeshes = m_submeshes.size(); int cSubmeshes = m_submeshes.size();
if(renderPass == KRNode::RENDER_PASS_SHADOWMAP) { if(renderPass == KRNode::RENDER_PASS_SHADOWMAP) {

View File

@@ -67,6 +67,8 @@ public:
KRMesh(KRContext &context, std::string name); KRMesh(KRContext &context, std::string name);
virtual ~KRMesh(); virtual ~KRMesh();
kraken_stream_level getStreamLevel(bool prime = true);
bool hasTransparency(); bool hasTransparency();
typedef enum { typedef enum {
@@ -218,6 +220,7 @@ private:
KRDataBlock *m_pIndexBaseData; KRDataBlock *m_pIndexBaseData;
void getSubmeshes(); 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 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); static bool sphereCast(const KRMat4 &model_to_world, const KRVector3 &v0, const KRVector3 &v1, float radius, const KRTriangle3 &tri, KRHitInfo &hitinfo);

View File

@@ -80,7 +80,7 @@ tinyxml2::XMLElement *KRModel::saveXML( tinyxml2::XMLNode *parent)
e->SetAttribute("lod_min_coverage", m_min_lod_coverage); e->SetAttribute("lod_min_coverage", m_min_lod_coverage);
e->SetAttribute("receives_shadow", m_receivesShadow ? "true" : "false"); e->SetAttribute("receives_shadow", m_receivesShadow ? "true" : "false");
e->SetAttribute("faces_camera", m_faces_camera ? "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); e->SetAttribute("rim_power", m_rim_power);
return e; return e;
} }
@@ -199,6 +199,20 @@ void KRModel::render(KRCamera *pCamera, std::vector<KRPointLight *> &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() { KRAABB KRModel::getBounds() {
loadModel(); loadModel();
if(m_models.size() > 0) { if(m_models.size() > 0) {

View File

@@ -69,6 +69,8 @@ public:
void setLightMap(const std::string &name); void setLightMap(const std::string &name);
std::string getLightMap(); std::string getLightMap();
virtual kraken_stream_level getStreamLevel(bool prime = true);
private: private:
std::vector<KRMesh *> m_models; std::vector<KRMesh *> m_models;
unordered_map<KRMesh *, std::vector<KRBone *> > m_bones; // Outer std::map connects model to set of bones unordered_map<KRMesh *, std::vector<KRBone *> > m_bones; // Outer std::map connects model to set of bones

View File

@@ -10,6 +10,7 @@
#include "KRNode.h" #include "KRNode.h"
#include "KRLODGroup.h" #include "KRLODGroup.h"
#include "KRLODSet.h"
#include "KRPointLight.h" #include "KRPointLight.h"
#include "KRSpotLight.h" #include "KRSpotLight.h"
#include "KRDirectionalLight.h" #include "KRDirectionalLight.h"
@@ -126,17 +127,17 @@ tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) {
tinyxml2::XMLElement *e = doc->NewElement(getElementName().c_str()); tinyxml2::XMLElement *e = doc->NewElement(getElementName().c_str());
tinyxml2::XMLNode *n = parent->InsertEndChild(e); tinyxml2::XMLNode *n = parent->InsertEndChild(e);
e->SetAttribute("name", m_name.c_str()); e->SetAttribute("name", m_name.c_str());
m_localTranslation.setXMLAttribute("translate", e); m_localTranslation.setXMLAttribute("translate", e, KRVector3::Zero());
m_localScale.setXMLAttribute("scale", e); m_localScale.setXMLAttribute("scale", e, KRVector3::One());
(m_localRotation * (180.0f / M_PI)).setXMLAttribute("rotate", e); (m_localRotation * (180.0f / M_PI)).setXMLAttribute("rotate", e, KRVector3::Zero());
m_rotationOffset.setXMLAttribute("rotate_offset", e); m_rotationOffset.setXMLAttribute("rotate_offset", e, KRVector3::Zero());
m_scalingOffset.setXMLAttribute("scale_offset", e); m_scalingOffset.setXMLAttribute("scale_offset", e, KRVector3::Zero());
m_rotationPivot.setXMLAttribute("rotate_pivot", e); m_rotationPivot.setXMLAttribute("rotate_pivot", e, KRVector3::Zero());
m_scalingPivot.setXMLAttribute("scale_pivot", e); m_scalingPivot.setXMLAttribute("scale_pivot", e, KRVector3::Zero());
(m_preRotation * (180.0f / M_PI)).setXMLAttribute("pre_rotate", e); (m_preRotation * (180.0f / M_PI)).setXMLAttribute("pre_rotate", e, KRVector3::Zero());
(m_postRotation * (180.0f / M_PI)).setXMLAttribute("post_rotate", e); (m_postRotation * (180.0f / M_PI)).setXMLAttribute("post_rotate", e, KRVector3::Zero());
for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) { for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
KRNode *child = (*itr); KRNode *child = (*itr);
@@ -395,6 +396,8 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) {
const char *szName = e->Attribute("name"); const char *szName = e->Attribute("name");
if(strcmp(szElementName, "node") == 0) { if(strcmp(szElementName, "node") == 0) {
new_node = new KRNode(scene, szName); new_node = new KRNode(scene, szName);
} if(strcmp(szElementName, "lod_set") == 0) {
new_node = new KRLODSet(scene, szName);
} if(strcmp(szElementName, "lod_group") == 0) { } if(strcmp(szElementName, "lod_group") == 0) {
new_node = new KRLODGroup(scene, szName); new_node = new KRLODGroup(scene, szName);
} else if(strcmp(szElementName, "point_light") == 0) { } else if(strcmp(szElementName, "point_light") == 0) {
@@ -879,8 +882,11 @@ void KRNode::addToOctreeNode(KROctreeNode *octree_node)
void KRNode::updateLODVisibility(const KRViewport &viewport) 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 if(m_lod_visible) {
showLOD(); for(std::set<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
(*itr)->updateLODVisibility(viewport);
}
}
} }
void KRNode::hideLOD() void KRNode::hideLOD()
@@ -932,3 +938,14 @@ std::set<KRBehavior *> &KRNode::getBehaviors()
{ {
return m_behaviors; 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<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(prime));
}
return stream_level;
}

View File

@@ -165,6 +165,12 @@ public:
void setAnimationEnabled(node_attribute_type attrib, bool enable); void setAnimationEnabled(node_attribute_type attrib, bool enable);
bool getAnimationEnabled(node_attribute_type attrib) const; bool getAnimationEnabled(node_attribute_type attrib) const;
virtual kraken_stream_level getStreamLevel(bool prime = true);
virtual void hideLOD();
virtual void showLOD();
protected: protected:
KRVector3 m_localTranslation; KRVector3 m_localTranslation;
KRVector3 m_localScale; KRVector3 m_localScale;
@@ -189,10 +195,6 @@ protected:
KRVector3 m_initialPostRotation; KRVector3 m_initialPostRotation;
bool m_lod_visible; bool m_lod_visible;
void hideLOD();
void showLOD();
float m_lod_min_coverage;
float m_lod_max_coverage;
KRNode *m_parentNode; KRNode *m_parentNode;
std::set<KRNode *> m_childNodes; std::set<KRNode *> m_childNodes;
@@ -240,7 +242,7 @@ public:
} }
void removeFromOctreeNodes(); void removeFromOctreeNodes();
void addToOctreeNode(KROctreeNode *octree_node); void addToOctreeNode(KROctreeNode *octree_node);
void childDeleted(KRNode *child_node); virtual void childDeleted(KRNode *child_node);
template <class T> T *find() template <class T> T *find()
{ {

View File

@@ -28,6 +28,7 @@
#include "KRBundle.h" #include "KRBundle.h"
#include "KRModel.h" #include "KRModel.h"
#include "KRLODGroup.h" #include "KRLODGroup.h"
#include "KRLODSet.h"
#include "KRCollider.h" #include "KRCollider.h"
#ifdef IOS_REF #ifdef IOS_REF
@@ -947,6 +948,9 @@ void LoadNode(FbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *pG
group_max_distance = fbx_lod_group->MinDistance.Get(); 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; KRAABB reference_bounds;
// Create a lod_group node for each fbx child node // Create a lod_group node for each fbx child node
int child_count = pNode->GetChildCount(); 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->setPostRotation(node_post_rotation);
new_node->setUseWorldUnits(use_world_space_units); 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)); 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) { if(pNode->GetChildCount() > 0) {
// Create an empty node, for inheritence of transforms // Create an empty node, for inheritence of transforms
std::string name = GetFbxObjectName(pNode); std::string name = GetFbxObjectName(pNode);
new_node = new KRNode(parent_node->getScene(), name);
/*
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;
} }
} }
} }

View File

@@ -38,7 +38,6 @@
#include "KRScene.h" #include "KRScene.h"
#include "KRNode.h" #include "KRNode.h"
#include "KRLODGroup.h"
#include "KRStockGeometry.h" #include "KRStockGeometry.h"
#include "KRDirectionalLight.h" #include "KRDirectionalLight.h"
#include "KRSpotLight.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) { KRScene::KRScene(KRContext &context, std::string name) : KRResource(context, name) {
m_pFirstLight = NULL; m_pFirstLight = NULL;
m_pRootNode = new KRLODGroup(*this, "scene_root"); m_pRootNode = new KRNode(*this, "scene_root");
notify_sceneGraphCreate(m_pRootNode); notify_sceneGraphCreate(m_pRootNode);
m_skyBoxName = name + "_skybox"; m_skyBoxName = name + "_skybox";
@@ -98,6 +97,11 @@ std::set<KRLocator *> &KRScene::getLocators()
return m_locatorNodes; return m_locatorNodes;
} }
std::set<KRLight *> &KRScene::getLights()
{
return m_lights;
}
void KRScene::render(KRCamera *pCamera, unordered_map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame) { void KRScene::render(KRCamera *pCamera, unordered_map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame) {
if(new_frame) { if(new_frame) {
// Expire cached occlusion test results. // Expire cached occlusion test results.
@@ -469,6 +473,10 @@ void KRScene::notify_sceneGraphDelete(KRNode *pNode)
if(locator) { if(locator) {
m_locatorNodes.erase(locator); m_locatorNodes.erase(locator);
} }
KRLight *light = dynamic_cast<KRLight *>(pNode);
if(light) {
m_lights.erase(light);
}
m_modifiedNodes.erase(pNode); m_modifiedNodes.erase(pNode);
if(!m_newNodes.erase(pNode)) { if(!m_newNodes.erase(pNode)) {
m_nodeTree.remove(pNode); m_nodeTree.remove(pNode);
@@ -477,6 +485,7 @@ void KRScene::notify_sceneGraphDelete(KRNode *pNode)
void KRScene::updateOctree(const KRViewport &viewport) void KRScene::updateOctree(const KRViewport &viewport)
{ {
m_pRootNode->showLOD();
m_pRootNode->updateLODVisibility(viewport); m_pRootNode->updateLODVisibility(viewport);
std::set<KRNode *> newNodes = std::move(m_newNodes); std::set<KRNode *> newNodes = std::move(m_newNodes);
@@ -502,6 +511,10 @@ void KRScene::updateOctree(const KRViewport &viewport)
if(locatorNode) { if(locatorNode) {
m_locatorNodes.insert(locatorNode); m_locatorNodes.insert(locatorNode);
} }
KRLight *light = dynamic_cast<KRLight *>(node);
if(light) {
m_lights.insert(light);
}
} }
for(std::set<KRNode *>::iterator itr=modifiedNodes.begin(); itr != modifiedNodes.end(); itr++) { for(std::set<KRNode *>::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;
}

View File

@@ -64,6 +64,8 @@ public:
KRNode *getRootNode(); KRNode *getRootNode();
KRLight *getFirstLight(); KRLight *getFirstLight();
kraken_stream_level getStreamLevel(bool prime = true);
bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo, unsigned int layer_mask); 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 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); bool sphereCast(const KRVector3 &v0, const KRVector3 &v1, float radius, KRHitInfo &hitinfo, unsigned int layer_mask);
@@ -87,6 +89,7 @@ public:
std::set<KRAmbientZone *> &getAmbientZones(); std::set<KRAmbientZone *> &getAmbientZones();
std::set<KRReverbZone *> &getReverbZones(); std::set<KRReverbZone *> &getReverbZones();
std::set<KRLocator *> &getLocators(); std::set<KRLocator *> &getLocators();
std::set<KRLight *> &getLights();
private: private:
@@ -102,6 +105,7 @@ private:
std::set<KRAmbientZone *> m_ambientZoneNodes; std::set<KRAmbientZone *> m_ambientZoneNodes;
std::set<KRReverbZone *> m_reverbZoneNodes; std::set<KRReverbZone *> m_reverbZoneNodes;
std::set<KRLocator *> m_locatorNodes; std::set<KRLocator *> m_locatorNodes;
std::set<KRLight *> m_lights;
KROctree m_nodeTree; KROctree m_nodeTree;

View File

@@ -99,11 +99,26 @@ void KRTexture::resetPoolExpiry()
m_last_frame_used = getContext().getCurrentFrame(); 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() long KRTexture::getLastFrameUsed()
{ {
return m_last_frame_used; return m_last_frame_used;
} }
bool KRTexture::isAnimated() bool KRTexture::isAnimated()
{ {
return false; return false;

View File

@@ -38,8 +38,8 @@
#include "KRContextObject.h" #include "KRContextObject.h"
#include "KRResource.h" #include "KRResource.h"
class KRDataBlock; class KRDataBlock;
class KRCamera;
class KRTexture : public KRResource { class KRTexture : public KRResource {
public: public:
@@ -66,6 +66,7 @@ public:
bool hasMipmaps(); bool hasMipmaps();
bool canStreamOut() const; bool canStreamOut() const;
kraken_stream_level getStreamLevel(bool prime = true);
void _swapHandles(); void _swapHandles();
protected: protected:

View File

@@ -417,13 +417,15 @@ void KRVector3::setUniform(GLint location) const
if(location != -1) GLDEBUG(glUniform3f(location, x, y, z)); 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?) // TODO - Increase number of digits after the decimal in floating point format (6 -> 12?)
// FINDME, TODO - This needs optimization... // FINDME, TODO - This needs optimization...
e->SetAttribute((base_name + "_x").c_str(), x); if(*this != default_value) {
e->SetAttribute((base_name + "_y").c_str(), y); e->SetAttribute((base_name + "_x").c_str(), x);
e->SetAttribute((base_name + "_z").c_str(), z); 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) void KRVector3::getXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const KRVector3 &default_value)

View File

@@ -126,7 +126,7 @@ public:
void setUniform(GLint location) const; 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); void getXMLAttribute(const std::string &base_name, tinyxml2::XMLElement *e, const KRVector3 &default_value);
}; };