- 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:
@@ -1102,7 +1102,7 @@ std::string KRCamera::getDebugText()
|
||||
}
|
||||
|
||||
|
||||
const KRViewport &KRCamera::getViewport()
|
||||
const KRViewport &KRCamera::getViewport() const
|
||||
{
|
||||
return m_viewport;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
|
||||
KRRenderSettings settings;
|
||||
|
||||
const KRViewport &getViewport();
|
||||
const KRViewport &getViewport() const;
|
||||
|
||||
|
||||
virtual std::string getElementName();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
|
||||
(*itr)->updateLODVisibility(viewport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float KRLODGroup::getMinDistance()
|
||||
{
|
||||
return m_min_distance;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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<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;
|
||||
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<KRPointLight *> &point_ligh
|
||||
if(!m_pReflectionCube && m_reflectionCube.size()) {
|
||||
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_offset = KRVector2::Zero();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -161,12 +161,8 @@ void KRMesh::loadPack(KRDataBlock *data) {
|
||||
updateAttributeOffsets();
|
||||
}
|
||||
|
||||
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());
|
||||
if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
|
||||
getSubmeshes();
|
||||
void KRMesh::getMaterials()
|
||||
{
|
||||
if(m_materials.size() == 0) {
|
||||
|
||||
for(std::vector<KRMesh::Submesh *>::iterator itr = m_submeshes.begin(); itr != m_submeshes.end(); itr++) {
|
||||
@@ -188,6 +184,28 @@ void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vect
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
|
||||
//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();
|
||||
getMaterials();
|
||||
|
||||
int cSubmeshes = m_submeshes.size();
|
||||
if(renderPass == KRNode::RENDER_PASS_SHADOWMAP) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<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() {
|
||||
loadModel();
|
||||
if(m_models.size() > 0) {
|
||||
|
||||
@@ -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<KRMesh *> m_models;
|
||||
unordered_map<KRMesh *, std::vector<KRBone *> > m_bones; // Outer std::map connects model to set of bones
|
||||
|
||||
@@ -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<KRNode *>::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<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
|
||||
(*itr)->updateLODVisibility(viewport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KRNode::hideLOD()
|
||||
@@ -932,3 +938,14 @@ std::set<KRBehavior *> &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<KRNode *>::iterator itr=m_childNodes.begin(); itr != m_childNodes.end(); ++itr) {
|
||||
stream_level = KRMIN(stream_level, (*itr)->getStreamLevel(prime));
|
||||
}
|
||||
|
||||
return stream_level;
|
||||
}
|
||||
|
||||
@@ -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<KRNode *> 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 <class T> T *find()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<KRLocator *> &KRScene::getLocators()
|
||||
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) {
|
||||
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<KRLight *>(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<KRNode *> 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<KRLight *>(node);
|
||||
if(light) {
|
||||
m_lights.insert(light);
|
||||
}
|
||||
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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<KRAmbientZone *> &getAmbientZones();
|
||||
std::set<KRReverbZone *> &getReverbZones();
|
||||
std::set<KRLocator *> &getLocators();
|
||||
std::set<KRLight *> &getLights();
|
||||
|
||||
private:
|
||||
|
||||
@@ -102,6 +105,7 @@ private:
|
||||
std::set<KRAmbientZone *> m_ambientZoneNodes;
|
||||
std::set<KRReverbZone *> m_reverbZoneNodes;
|
||||
std::set<KRLocator *> m_locatorNodes;
|
||||
std::set<KRLight *> m_lights;
|
||||
|
||||
KROctree m_nodeTree;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -417,14 +417,16 @@ 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...
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user