Implemented Hierarchical LOD system and associated FBX Importer functionality.

This commit is contained in:
2013-04-04 12:50:53 -07:00
parent fb23c8ef78
commit 16c8523a40
11 changed files with 366 additions and 49 deletions

View File

@@ -9,7 +9,6 @@
/* Begin PBXBuildFile section */
104A335E1672D31C001C8BA6 /* KRCollider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 104A335C1672D31B001C8BA6 /* KRCollider.cpp */; };
104A335F1672D31C001C8BA6 /* KRCollider.h in Headers */ = {isa = PBXBuildFile; fileRef = 104A335D1672D31C001C8BA6 /* KRCollider.h */; settings = {ATTRIBUTES = (Public, ); }; };
10CC33A4168530A300BB9846 /* libPVRTexLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 10CC33A3168530A300BB9846 /* libPVRTexLib.a */; };
10CC33A5168534F000BB9846 /* KRCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E48B3CBF14393E2F000C50E2 /* KRCamera.cpp */; };
E4030E4C160A3CF000592648 /* KRStockGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = E4030E4B160A3CF000592648 /* KRStockGeometry.h */; settings = {ATTRIBUTES = (Public, ); }; };
E4030E4D160A3CF000592648 /* KRStockGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = E4030E4B160A3CF000592648 /* KRStockGeometry.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -197,6 +196,10 @@
E499BF2216AE760F007FCDBE /* krengine_osx.h in Headers */ = {isa = PBXBuildFile; fileRef = E4BBBB8C1512A40300F43B5B /* krengine_osx.h */; settings = {ATTRIBUTES = (Public, ); }; };
E499BF2316AE7636007FCDBE /* kraken-prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = E4BBBB8B1512A40300F43B5B /* kraken-prefix.pch */; };
E499BF2516AE8C20007FCDBE /* KREngine.mm in Sources */ = {isa = PBXBuildFile; fileRef = E491016F13C99BDC0098455B /* KREngine.mm */; };
E4AE635D1704FB0A00B460CD /* KRLODGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4AE635B1704FB0A00B460CD /* KRLODGroup.cpp */; };
E4AE635E1704FB0A00B460CD /* KRLODGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4AE635B1704FB0A00B460CD /* KRLODGroup.cpp */; };
E4AE635F1704FB0A00B460CD /* KRLODGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AE635C1704FB0A00B460CD /* KRLODGroup.h */; };
E4AE63601704FB0A00B460CD /* KRLODGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AE635C1704FB0A00B460CD /* KRLODGroup.h */; };
E4AFC6B615F7C46800DDB4C8 /* KRAABB.cpp in Headers */ = {isa = PBXBuildFile; fileRef = E40BA45215EFF79500D7C3DD /* KRAABB.cpp */; settings = {ATTRIBUTES = (Public, ); }; };
E4AFC6B915F7C7B200DDB4C8 /* KROctree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4924C2415EE95E700B965C6 /* KROctree.cpp */; settings = {ATTRIBUTES = (Public, ); }; };
E4AFC6BB15F7C7D600DDB4C8 /* KROctreeNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4924C2915EE96AA00B965C6 /* KROctreeNode.cpp */; };
@@ -483,6 +486,8 @@
E497B952151BEDA600D3DC67 /* KRResource+fbx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = "KRResource+fbx.cpp"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
E497B95C151BF05F00D3DC67 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = ../../../../MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
E497B95E151BF09600D3DC67 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = ../../../../MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
E4AE635B1704FB0A00B460CD /* KRLODGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRLODGroup.cpp; sourceTree = "<group>"; };
E4AE635C1704FB0A00B460CD /* KRLODGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLODGroup.h; sourceTree = "<group>"; };
E4B175AA161F5A1000B8FB80 /* KRTexture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRTexture.cpp; sourceTree = "<group>"; };
E4B175AB161F5A1000B8FB80 /* KRTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRTexture.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
E4B175B0161F5FAE00B8FB80 /* KRTextureCube.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRTextureCube.cpp; sourceTree = "<group>"; };
@@ -624,7 +629,6 @@
E497B95D151BF05F00D3DC67 /* CoreServices.framework in Frameworks */,
E497B95F151BF09600D3DC67 /* SystemConfiguration.framework in Frameworks */,
E460292B16682BF700261BB9 /* libfbxsdk-2013.3-static.a in Frameworks */,
10CC33A4168530A300BB9846 /* libPVRTexLib.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -802,7 +806,7 @@
E428C2EF166960ED00A16EDF /* Animation */,
E48839AB15F930E200BD66D5 /* Bundle */,
E48839AA15F9309E00BD66D5 /* Material */,
E48839A915F9307E00BD66D5 /* Model */,
E48839A915F9307E00BD66D5 /* Mesh */,
E48839A815F9304C00BD66D5 /* Texture */,
E48839A715F9302E00BD66D5 /* Shader */,
E48839A615F92FC300BD66D5 /* Scene */,
@@ -855,7 +859,7 @@
name = Texture;
sourceTree = "<group>";
};
E48839A915F9307E00BD66D5 /* Model */ = {
E48839A915F9307E00BD66D5 /* Mesh */ = {
isa = PBXGroup;
children = (
E491018313C99BDC0098455B /* KRMeshManager.h */,
@@ -867,7 +871,7 @@
E4C454B1167BC04B003586CD /* KRMeshSphere.h */,
E4C454B4167BC05C003586CD /* KRMeshSphere.cpp */,
);
name = Model;
name = Mesh;
sourceTree = "<group>";
};
E48839AA15F9309E00BD66D5 /* Material */ = {
@@ -942,6 +946,8 @@
E4F975351536221C00FD60B2 /* KRNode.cpp */,
E480BE671671C641004EC8AD /* KRBone.h */,
E480BE6B1671C653004EC8AD /* KRBone.cpp */,
E4AE635B1704FB0A00B460CD /* KRLODGroup.cpp */,
E4AE635C1704FB0A00B460CD /* KRLODGroup.h */,
);
name = "Scene Graph Nodes";
sourceTree = "<group>";
@@ -1212,6 +1218,7 @@
E499BF2116AE75A7007FCDBE /* KREngine-common.h in Headers */,
E450273B16E0491D00FDEC5C /* KRReverbZone.h in Headers */,
E4FE6AA816B21D660058B8CE /* forsyth.h in Headers */,
E4AE635F1704FB0A00B460CD /* KRLODGroup.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1287,6 +1294,7 @@
E499BF1D16AE74FF007FCDBE /* KRTextureAnimated.h in Headers */,
E499BF1F16AE753E007FCDBE /* KRCollider.h in Headers */,
E499BF2316AE7636007FCDBE /* kraken-prefix.pch in Headers */,
E4AE63601704FB0A00B460CD /* KRLODGroup.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1548,6 +1556,7 @@
E4943231169E08D200BCB891 /* KRAmbientZone.cpp in Sources */,
E4FE6AAB16B21D7E0058B8CE /* forsyth.cpp in Sources */,
E450273916E0491D00FDEC5C /* KRReverbZone.cpp in Sources */,
E4AE635D1704FB0A00B460CD /* KRLODGroup.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1619,6 +1628,7 @@
E4F027DF1697BFFF00D4427D /* KRAudioBuffer.cpp in Sources */,
E4943232169E08D200BCB891 /* KRAmbientZone.cpp in Sources */,
E450273A16E0491D00FDEC5C /* KRReverbZone.cpp in Sources */,
E4AE635E1704FB0A00B460CD /* KRLODGroup.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1748,6 +1758,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_CXX_LIBRARY = "libstdc++";
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -1780,8 +1791,9 @@
"\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"",
"\"$(SYSTEM_APPS_DIR)/Imagination/PowerVR/GraphicsSDK/PVRTexTool/Library/OSX_x86/Static\"",
);
MACOSX_DEPLOYMENT_TARGET = 10.6;
MACOSX_DEPLOYMENT_TARGET = 10.7;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = kraken;
SDKROOT = macosx;
SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders_osx";
@@ -1794,6 +1806,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_CXX_LIBRARY = "libstdc++";
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
@@ -1822,7 +1835,8 @@
"\"$(SYSTEM_APPS_DIR)/Autodesk/FBX SDK/2013.3/lib/gcc4/ub\"",
"\"$(SYSTEM_APPS_DIR)/Imagination/PowerVR/GraphicsSDK/PVRTexTool/Library/OSX_x86/Static\"",
);
MACOSX_DEPLOYMENT_TARGET = 10.6;
MACOSX_DEPLOYMENT_TARGET = 10.7;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = kraken;
SDKROOT = macosx;
SHARED_PRECOMPS_DIR = "$(CACHE_ROOT)/SharedPrecompiledHeaders_osx";

View File

@@ -83,6 +83,7 @@ KRAudioManager::KRAudioManager(KRContext &context) : KRContextObject(context)
m_reverb_impulse_responses[i] = NULL;
m_reverb_impulse_responses_weight[i] = 0.0f;
}
m_output_accumulation = NULL;
}
void KRAudioManager::initAudio()

View File

@@ -95,6 +95,9 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
KRVector3 vecCameraDirection = m_viewport.getCameraDirection();
scene.updateOctree(m_viewport);
if(settings.bEnableDeferredLighting) {
// ----====---- Opaque Geometry, Deferred rendering Pass 1 ----====----

View File

@@ -0,0 +1,91 @@
//
// KRLODGroup.cpp
// KREngine
//
// Created by Kearwood Gilbert on 2012-12-06.
// Copyright (c) 2012 Kearwood Software. All rights reserved.
//
#include "KRLODGroup.h"
#include "KRContext.h"
KRLODGroup::KRLODGroup(KRScene &scene, std::string name) : KRNode(scene, name)
{
m_min_distance = 0.0f;
m_max_distance = 0.0f;
}
KRLODGroup::~KRLODGroup()
{
}
std::string KRLODGroup::getElementName() {
return "lod_group";
}
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);
return e;
}
void KRLODGroup::loadXML(tinyxml2::XMLElement *e)
{
KRNode::loadXML(e);
m_min_distance = 0.0f;
if(e->QueryFloatAttribute("min_distance", &m_min_distance) != tinyxml2::XML_SUCCESS) {
m_min_distance = 0.0f;
}
m_max_distance = 0.0f;
if(e->QueryFloatAttribute("max_distance", &m_max_distance) != tinyxml2::XML_SUCCESS) {
m_max_distance = 0.0f;
}
}
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));
}
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::vector<KRNode *>::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) {
(*itr)->updateLODVisibility(viewport);
}
}
}
float KRLODGroup::getMinDistance()
{
return m_min_distance;
}
float KRLODGroup::getMaxDistance()
{
return m_max_distance;
}
void KRLODGroup::setMinDistance(float min_distance)
{
m_min_distance = min_distance;
}
void KRLODGroup::setMaxDistance(float max_distance)
{
m_max_distance = max_distance;
}

View File

@@ -0,0 +1,38 @@
//
// KRLODGroup.h
// KREngine
//
// Created by Kearwood Gilbert on 2012-12-06.
// Copyright (c) 2012 Kearwood Software. All rights reserved.
//
#ifndef KRLODGROUP_H
#define KRLODGROUP_H
#include "KRResource.h"
#include "KRNode.h"
#include "KRTexture.h"
class KRLODGroup : public KRNode {
public:
KRLODGroup(KRScene &scene, std::string name);
virtual ~KRLODGroup();
virtual std::string getElementName();
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);
void setMaxDistance(float max_distance);
private:
bool getLODVisibility(const KRViewport &viewport);
float m_min_distance;
float m_max_distance;
};
#endif

View File

@@ -9,6 +9,7 @@
#include "KREngine-common.h"
#include "KRNode.h"
#include "KRLODGroup.h"
#include "KRPointLight.h"
#include "KRSpotLight.h"
#include "KRDirectionalLight.h"
@@ -37,6 +38,7 @@ KRNode::KRNode(KRScene &scene, std::string name) : KRContextObject(scene.getCont
m_inverseBindPoseMatrixValid = false;
m_modelMatrix = KRMat4();
m_bindPoseMatrix = KRMat4();
m_lod_visible = false;
}
KRNode::~KRNode() {
@@ -51,7 +53,10 @@ void KRNode::addChild(KRNode *child) {
assert(child->m_parentNode == NULL);
child->m_parentNode = this;
m_childNodes.push_back(child);
getScene().notify_sceneGraphCreate(child);
if(m_lod_visible) {
// Child node inherits LOD visibility status from parent
child->showLOD();
}
}
tinyxml2::XMLElement *KRNode::saveXML(tinyxml2::XMLNode *parent) {
@@ -213,6 +218,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_group") == 0) {
new_node = new KRLODGroup(scene, szName);
} else if(strcmp(szElementName, "point_light") == 0) {
new_node = new KRPointLight(scene, szName);
} else if(strcmp(szElementName, "directional_light") == 0) {
@@ -434,3 +441,37 @@ void KRNode::addToOctreeNode(KROctreeNode *octree_node)
{
m_octree_nodes.insert(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();
}
void KRNode::hideLOD()
{
if(m_lod_visible) {
m_lod_visible = false;
getScene().notify_sceneGraphDelete(this);
for(std::vector<KRNode *>::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) {
(*itr)->hideLOD();
}
}
}
void KRNode::showLOD()
{
if(!m_lod_visible) {
getScene().notify_sceneGraphCreate(this);
m_lod_visible = true;
for(std::vector<KRNode *>::iterator itr=m_childNodes.begin(); itr < m_childNodes.end(); ++itr) {
(*itr)->showLOD();
}
}
}
bool KRNode::lodIsVisible()
{
return m_lod_visible;
}

View File

@@ -103,6 +103,9 @@ public:
virtual void physicsUpdate(float deltaTime);
virtual bool hasPhysics();
virtual void updateLODVisibility(const KRViewport &viewport);
bool lodIsVisible();
protected:
KRVector3 m_localTranslation;
KRVector3 m_localScale;
@@ -112,7 +115,16 @@ protected:
KRVector3 m_initialLocalScale;
KRVector3 m_initialLocalRotation;
bool m_lod_visible;
void hideLOD();
void showLOD();
float m_lod_min_coverage;
float m_lod_max_coverage;
KRNode *m_parentNode;
std::vector<KRNode *> m_childNodes;
private:
void invalidateModelMatrix();
@@ -128,7 +140,7 @@ private:
std::string m_name;
std::vector<KRNode *> m_childNodes;
KRScene *m_pScene;

View File

@@ -79,6 +79,7 @@ void KROctree::shrink()
KROctreeNode *newRoot = m_pRootNode->stripChild();
delete m_pRootNode;
m_pRootNode = newRoot;
if(m_pRootNode == NULL) return;
}
}
}

View File

@@ -7,7 +7,8 @@
//
#include "KREngine-common.h"
#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>
#include <fbxsdk.h>
@@ -24,6 +25,7 @@
#include "KRBone.h"
#include "KRBundle.h"
#include "KRModel.h"
#include "KRLODGroup.h"
#include "KRCollider.h"
#ifdef IOS_REF
@@ -45,6 +47,7 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
KRNode *LoadLight(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxNode* pNode);
KRNode *LoadSkeleton(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxNode* pNode);
KRNode *LoadCamera(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxNode* pNode);
void LoadLOD(KRContext &context, std::vector<KRResource *> &resources, FbxGeometryConverter *pGeometryConverter, FbxLODGroup* pSourceLodGroup);
std::string GetFbxObjectName(FbxObject *obj);
const float KRAKEN_FBX_ANIMATION_FRAMERATE = 30.0f; // FINDME - This should be configurable
@@ -724,46 +727,157 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vector<KRResource
// printf(" Local Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]);
// printf(" Local Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]);
KRNode *new_node = NULL;
KFbxNodeAttribute::EType attribute_type = (pNode->GetNodeAttribute()->GetAttributeType());
switch(attribute_type) {
case KFbxNodeAttribute::eMesh:
new_node = LoadMesh(parent_node, resources, pGeometryConverter, pNode);
break;
case KFbxNodeAttribute::eLight:
new_node = LoadLight(parent_node, resources, pNode);
break;
case KFbxNodeAttribute::eSkeleton:
new_node = LoadSkeleton(parent_node, resources, pNode);
break;
case KFbxNodeAttribute::eCamera:
new_node = LoadCamera(parent_node, resources, pNode);
break;
default:
{
if(pNode->GetChildCount() > 0) {
// Create an empty node, for inheritence of transforms
new_node = new KRNode(parent_node->getScene(), GetFbxObjectName(pNode));
if(attribute_type == KFbxNodeAttribute::eLODGroup) {
std::string name = GetFbxObjectName(pNode);
FbxLODGroup *fbx_lod_group = (FbxLODGroup*) pNode->GetNodeAttribute(); // FbxCast<FbxLODGroup>(pNode);
if(!fbx_lod_group->WorldSpace.Get()) {
printf("WARNING - LOD Groups only supported with world space distance thresholds.\n");
}
float group_min_distance = 0.0f;
float group_max_distance = 0.0f;
if(fbx_lod_group->MinMaxDistance.Get()) {
group_min_distance = fbx_lod_group->MinDistance.Get();
group_max_distance = fbx_lod_group->MinDistance.Get();
}
// Create a lod_group node for each fbx child node
int child_count = pNode->GetChildCount();
for(int i = 0; i < child_count; i++)
{
float min_distance = 0;
float max_distance = 0; // 0 for max_distance means infinity
FbxLODGroup::EDisplayLevel display_level;
fbx_lod_group->GetDisplayLevel(i, display_level);
switch(display_level) {
case FbxLODGroup::eUseLOD:
if(i > 0 ) {
FbxDistance d;
fbx_lod_group->GetThreshold(i - 1, d);
min_distance = d.value();
}
if(i < child_count - 1) {
FbxDistance d;
fbx_lod_group->GetThreshold(i, d);
max_distance = d.value();
}
break;
case FbxLODGroup::eShow:
// We leave min_distance and max_distance as 0's, which effectively makes the LOD group always visible
break;
case FbxLODGroup::eHide:
min_distance = -1;
max_distance = -1;
// LOD Groups with -1 for both min_distance and max_distance will never be displayed; import in case that the distance values are to be modified by scripting at runtime
break;
}
if(group_min_distance != 0.0f && min_distance != -1) {
if(min_distance < group_min_distance) min_distance = group_min_distance;
}
if(group_max_distance != 0.0f && max_distance != -1) {
if(max_distance == 0.0f) {
max_distance = group_max_distance;
} else if(max_distance > group_max_distance) {
max_distance = group_max_distance;
}
}
break;
}
KRLODGroup *new_node = new KRLODGroup(parent_node->getScene(), name + "_lodlevel" + boost::lexical_cast<string>(i + 1));
new_node->setMinDistance(min_distance);
new_node->setMaxDistance(max_distance);
new_node->setLocalRotation(node_rotation);
new_node->setLocalTranslation(node_translation);
new_node->setLocalScale(node_scale);
parent_node->addChild(new_node);
if(new_node != NULL) {
new_node->setLocalRotation(node_rotation);
new_node->setLocalTranslation(node_translation);
new_node->setLocalScale(node_scale);
parent_node->addChild(new_node);
// Load child nodes
for(int i = 0; i < pNode->GetChildCount(); i++)
{
LoadNode(pFbxScene, new_node, resources, pGeometryConverter, pNode->GetChild(i));
}
} else {
KRNode *new_node = NULL;
switch(attribute_type) {
case KFbxNodeAttribute::eMesh:
new_node = LoadMesh(parent_node, resources, pGeometryConverter, pNode);
break;
case KFbxNodeAttribute::eLight:
new_node = LoadLight(parent_node, resources, pNode);
break;
case KFbxNodeAttribute::eSkeleton:
new_node = LoadSkeleton(parent_node, resources, pNode);
break;
case KFbxNodeAttribute::eCamera:
new_node = LoadCamera(parent_node, resources, pNode);
break;
default:
{
if(pNode->GetChildCount() > 0) {
// Create an empty node, for inheritence of transforms
std::string name = GetFbxObjectName(pNode);
float min_distance = 0.0f;
float max_distance = 0.0f;
typedef boost::tokenizer<boost::char_separator<char> > char_tokenizer;
int step = 0;
char_tokenizer name_components(name, boost::char_separator<char>("_"));
for(char_tokenizer::iterator itr=name_components.begin(); itr != name_components.end(); itr++) {
std::string component = *itr;
std::transform(component.begin(), component.end(),
component.begin(), ::tolower);
if(component.compare("lod") == 0) {
step = 1;
} else if(step == 1) {
min_distance = boost::lexical_cast<float>(component);
step++;
} else if(step == 2) {
max_distance = boost::lexical_cast<float>(component);
step++;
}
}
/*
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(min_distance);
lod_group->setMaxDistance(max_distance);
new_node = lod_group;
/*
}
*/
}
}
break;
}
if(new_node != NULL) {
new_node->setLocalRotation(node_rotation);
new_node->setLocalTranslation(node_translation);
new_node->setLocalScale(node_scale);
parent_node->addChild(new_node);
// Load child nodes
for(int i = 0; i < pNode->GetChildCount(); i++)
{
LoadNode(pFbxScene, new_node, resources, pGeometryConverter, pNode->GetChild(i));
}
}
}
}
void LoadLOD(KRContext &context, std::vector<KRResource *> &resources, FbxLODGroup* pSourceLodGroup) {
}
void LoadMaterial(KRContext &context, std::vector<KRResource *> &resources, FbxSurfaceMaterial *pMaterial) {
//printf(" %s: %i - %i\n", pMaterial->GetName(), mat_vertex_start, mat_vertex_count + mat_vertex_start - 1);

View File

@@ -38,6 +38,7 @@
#include "KRScene.h"
#include "KRNode.h"
#include "KRLODGroup.h"
#include "KRStockGeometry.h"
#include "KRDirectionalLight.h"
#include "KRSpotLight.h"
@@ -48,7 +49,7 @@ const long KRENGINE_OCCLUSION_TEST_EXPIRY = 60;
KRScene::KRScene(KRContext &context, std::string name) : KRResource(context, name) {
m_pFirstLight = NULL;
m_pRootNode = new KRNode(*this, "scene_root");
m_pRootNode = new KRLODGroup(*this, "scene_root");
notify_sceneGraphCreate(m_pRootNode);
m_skyBoxName = name + "_skybox";
@@ -85,9 +86,6 @@ std::set<KRReverbZone *> &KRScene::getReverbZones()
}
void KRScene::render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame) {
updateOctree();
if(new_frame) {
// Expire cached occlusion test results.
// Cached "failed" results are expired on the next frame (marked with .second of -1)
@@ -425,8 +423,10 @@ void KRScene::notify_sceneGraphDelete(KRNode *pNode)
}
}
void KRScene::updateOctree()
void KRScene::updateOctree(const KRViewport &viewport)
{
m_pRootNode->updateLODVisibility(viewport);
std::set<KRNode *> newNodes = m_newNodes;
std::set<KRNode *> modifiedNodes = m_modifiedNodes;
m_newNodes.clear();
@@ -449,7 +449,9 @@ void KRScene::updateOctree()
}
for(std::set<KRNode *>::iterator itr=modifiedNodes.begin(); itr != modifiedNodes.end(); itr++) {
KRNode *node = *itr;
m_nodeTree.update(node);
if(node->lodIsVisible()) {
m_nodeTree.update(node);
}
}
}

View File

@@ -71,6 +71,7 @@ public:
void render(KROctreeNode *pOctreeNode, std::map<KRAABB, int> &visibleBounds, KRCamera *pCamera, std::vector<KRLight *> &lights, const KRViewport &viewport, KRNode::RenderPass renderPass, std::vector<KROctreeNode *> &remainingOctrees, std::vector<KROctreeNode *> &remainingOctreesTestResults, std::vector<KROctreeNode *> &remainingOctreesTestResultsOnly, bool bOcclusionResultsPass, bool bOcclusionTestResultsOnly);
void updateOctree(const KRViewport &viewport);
void notify_sceneGraphCreate(KRNode *pNode);
void notify_sceneGraphDelete(KRNode *pNode);
@@ -99,7 +100,6 @@ private:
std::set<KRReverbZone *> m_reverbZoneNodes;
KROctree m_nodeTree;
void updateOctree();
std::string m_skyBoxName;