Update the auto lod level generator

This commit is contained in:
samuncle 2019-02-28 01:01:44 +01:00
parent bf6e81b97d
commit d284b52368
3 changed files with 32 additions and 18 deletions

View File

@ -250,31 +250,39 @@ void LODNode::OnRegisterSceneNode()
scene::ISceneNode::OnRegisterSceneNode(); scene::ISceneNode::OnRegisterSceneNode();
} }
void LODNode::add(int level, scene::ISceneNode* node, bool reparent) void LODNode::autoComputeLevel()
{ {
// Dynamic auto computation of LoD level
printf("Autocomputation of LoD level: >%s<\n ---- \n", node->getName());
Box = node->getBoundingBox(); // This will be set based on the amount of objects in a scene.
float volume = Box.getVolume(); float agressivity = 1.0;
// First we try to estimate how far away we need to draw
float max_draw = 0.0; float max_draw = 0.0;
if (m_volume < 2.0)
if (volume < 2.0)
{ {
max_draw = (volume * 1.3) + 50.0; max_draw = (m_volume * 1.3) + 50.0;
} }
else else
{ {
max_draw = (volume * 0.05) + 100; max_draw = (m_volume * 0.05) + 100;
} }
max_draw *= agressivity;
int level2 = (int) max_draw * (m_detail.size() + 1) * 0.3; int step = (int) max_draw / m_detail.size();
// Then we recompute the level of detail culling distance
int cursor = 0;
while(cursor < m_detail.size())
{
m_detail[cursor] = step * step * (cursor + 1);
cursor++;
}
}
printf("Volume: %f\n", max_draw); void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
printf("Level: %d\n", level); {
Box = node->getBoundingBox();
printf("Level2: %d\n", level2); m_volume = Box.getVolume();
// samuncle suggested to put a slight randomisation in LOD // samuncle suggested to put a slight randomisation in LOD
// I'm not convinced (Auria) but he's the artist pro, so I listen ;P // I'm not convinced (Auria) but he's the artist pro, so I listen ;P
@ -282,7 +290,7 @@ void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
// and the location is disapparition needs to be deterministic // and the location is disapparition needs to be deterministic
if (m_detail.size() > 0) if (m_detail.size() > 0)
{ {
assert(m_detail.back()<level2*level2); assert(m_detail.back()<level*level);
m_detail[m_detail.size() - 1] += (int)(((rand()%1000)-500)/500.0f*(m_detail[m_detail.size() - 1]*0.2f)); m_detail[m_detail.size() - 1] += (int)(((rand()%1000)-500)/500.0f*(m_detail[m_detail.size() - 1]*0.2f));
} }
@ -291,7 +299,7 @@ void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
node->grab(); node->grab();
node->remove(); node->remove();
node->setPosition(core::vector3df(0,0,0)); node->setPosition(core::vector3df(0,0,0));
m_detail.push_back(level2*level2); m_detail.push_back(level*level);
m_nodes.push_back(node); m_nodes.push_back(node);
m_nodes_set.insert(node); m_nodes_set.insert(node);
node->setParent(this); node->setParent(this);

View File

@ -63,7 +63,7 @@ private:
int m_forced_lod; int m_forced_lod;
// Volume of the bounding box (for autoLOD computation) // Volume of the bounding box (for autoLOD computation)
int m_volume; float m_volume;
enum PreviousVisibility enum PreviousVisibility
{ {
@ -107,6 +107,11 @@ public:
*/ */
void add(int level, scene::ISceneNode* node, bool reparent); void add(int level, scene::ISceneNode* node, bool reparent);
/**
* This method can be used to automatically compute LoD level
*/
void autoComputeLevel();
void forceLevelOfDetail(int n); void forceLevelOfDetail(int n);
/** Get the highest level of detail node */ /** Get the highest level of detail node */

View File

@ -142,6 +142,7 @@ LODNode* ModelDefinitionLoader::instanciateAsLOD(const XMLNode* node, scene::ISc
lod_node->add(group[m].m_distance, scene_node, true); lod_node->add(group[m].m_distance, scene_node, true);
} }
} }
lod_node->autoComputeLevel();
#ifdef DEBUG #ifdef DEBUG
std::string debug_name = groupname+" (LOD track-object)"; std::string debug_name = groupname+" (LOD track-object)";