diff --git a/modules/world/spawner.cpp b/modules/world/spawner.cpp index 02f7806..2d1fd5e 100644 --- a/modules/world/spawner.cpp +++ b/modules/world/spawner.cpp @@ -60,6 +60,7 @@ void Spawner::place_scene(const StringName &name, const Transform &place) struct spawn_object obj; obj.xform = place; obj.active = false; + obj.pooled = false; obj.instance = -1; PoolVector pos = positions[name]; pos.resize(pos.size() + 1); @@ -106,15 +107,39 @@ void Spawner::update_view(Node *node, float distance) if (!pos[i].active) { Transform x = pos[i].xform; float d = org.distance_squared_to(x.origin); - if (d < distance * distance) { - Node *pn = scenes[*key]->instance(); + if (d < distance * distance && pos[i].instance < 0) { + int j; + Node *pn = NULL; + bool pooling = false; + for (j = 0; j < pos.size(); j++) { + if (j == i) + continue; + if (!pos[j].active && pos[j].instance >= 0 && pos[j].pooled) { + pos.write()[i].instance = pos[j].instance; + pos.write()[j].instance = -1; + pos.write()[j].pooled = false; + Object *po = ObjectDB::get_instance(pos[i].instance); + if (po) { + pn = Object::cast_to(po); + if (pn) { + pooling = true; + break; + } + } + } + } + if (!pn) + pn = scenes[*key]->instance(); if (pn) { Spatial *sp = Object::cast_to(pn); if (sp) { - view->add_child(sp); + if (!pooling) + view->add_child(sp); sp->set_global_transform(x); pos.write()[i].instance = sp->get_instance_id(); pos.write()[i].active = true; + pos.write()[i].pooled = false; + sp->show(); } else memfree(pn); } @@ -122,7 +147,7 @@ void Spawner::update_view(Node *node, float distance) } else { Transform x = pos[i].xform; float d = org.distance_squared_to(x.origin); - if (d > distance * distance + 600.0f) { + if (d > distance * distance + 2500.0f) { Object *po = ObjectDB::get_instance(pos[i].instance); if (po) { Node *pn = Object::cast_to(po); @@ -130,6 +155,16 @@ void Spawner::update_view(Node *node, float distance) pn->queue_delete(); } pos.write()[i].active = false; + pos.write()[i].instance = -1; + pos.write()[i].pooled = false; + } else if (d > distance * distance + 600.0f) { + Object *po = ObjectDB::get_instance(pos[i].instance); + if (po) { + Spatial *pn = Object::cast_to(po); + pn->hide(); + } + pos.write()[i].active = false; + pos.write()[i].pooled = true; } } diff --git a/modules/world/spawner.h b/modules/world/spawner.h index f7e15eb..a5353a9 100644 --- a/modules/world/spawner.h +++ b/modules/world/spawner.h @@ -9,6 +9,7 @@ protected: struct spawn_object { Transform xform; bool active; + bool pooled; int instance; }; HashMap > positions;