#if 0 #include "behavior.h" #include "terrain.h" #include "generator.h" #include "../../../ext.h" #include #include "generator.h" #include "region.h" #include #include #include #include #include #include #include #include #include namespace { std::unordered_map region_table; } UF_OBJECT_REGISTER_BEGIN(ext::Terrain) UF_OBJECT_REGISTER_BEHAVIOR(uf::EntityBehavior) UF_OBJECT_REGISTER_BEHAVIOR(uf::ObjectBehavior) UF_OBJECT_REGISTER_BEHAVIOR(ext::TerrainBehavior) UF_OBJECT_REGISTER_END() void ext::Terrain::relocateChildren() { uf::Scene& scene = uf::scene::getCurrentScene(); std::vector entities; scene.process( [&]( uf::Entity* entity ) { if ( !entity || entity->getUid() == 0 ) return; uf::Serializer& metadata = entity->getComponent(); if ( ext::json::isObject( metadata["region"] ) && metadata["region"]["track"].as() ) { if ( std::find( entities.begin(), entities.end(), entity ) == entities.end() ) { entities.push_back(entity); } } } ); uf::Serializer& metadata = this->getComponent(); pod::Vector3ui size = { metadata["region"]["size"][0].as(), metadata["region"]["size"][1].as(), metadata["region"]["size"][2].as(), }; for ( uf::Entity* e : entities ) { uf::Entity& entity = *e; const pod::Transform<>& transform = entity.getComponent>(); pod::Vector3 pointf = uf::vector::divide(transform.position, {size.x, size.y, size.z}); pod::Vector3i point = { (int) (pointf.x + (pointf.x > 0 ? 0.5 : -0.5)), (int) (pointf.y + (pointf.y > 0 ? 0.5 : -0.5)), (int) (pointf.z + (pointf.z > 0 ? 0.5 : -0.5)), }; if ( !this->exists(point) ) continue; // oops uf::Object& region = *this->at(point); bool should = false; if ( entity.getParent().getName() != "Region" ) should = true; else { auto& current = entity.getParent(); const pod::Transform<>& t = current.getComponent>(); pod::Vector3i location = { (int) (t.position.x / size.x), (int) (t.position.y / size.y), (int) (t.position.z / size.z), }; if ( !uf::vector::equals( point, location ) ) should = true; } if ( should ) { region.moveChild(entity); // uf::iostream << "Relocating " << &entity << ": " << entity.getName() << " to (" << point.x << ", " << point.y << ", " << point.z << ")" << "\n"; } } } bool ext::Terrain::exists( const pod::Vector3i& position ) const { const uf::Serializer& metadata = this->getComponent(); pod::Vector3i size = { metadata["region"]["size"][0].as(), metadata["region"]["size"][1].as(), metadata["region"]["size"][2].as(), }; if ( this->getChildren().empty() ) return false; for ( auto it = this->getChildren().begin(); it != this->getChildren().end(); ++it ) { uf::Entity* kv = *it; const pod::Transform<>& transform = kv->getComponent>(); pod::Vector3i location = { (int) (transform.position.x / size.x), (int) (transform.position.y / size.y), (int) (transform.position.z / size.z), }; if ( uf::vector::equals( location, position ) ) return true; } return false; } bool ext::Terrain::inBounds( const pod::Vector3i& position ) const { const uf::Scene& scene = uf::scene::getCurrentScene(); const pod::Transform<>& player = scene.getController().getComponent>(); const uf::Serializer& metadata = this->getComponent(); pod::Vector3ui size = { metadata["region"]["size"][0].as(), metadata["region"]["size"][1].as(), metadata["region"]["size"][2].as(), }; pod::Vector3ui threshold = { metadata["terrain"]["radius"][0].as(), metadata["terrain"]["radius"][1].as(), metadata["terrain"]["radius"][2].as(), }; pod::Vector3i point = { (int) (player.position.x / size.x), (int) (player.position.y / size.y), (int) (player.position.z / size.z), }; pod::Vector3i difference = uf::vector::subtract( point, position ); return !(abs(difference.x) >= threshold.x || abs(difference.y) >= threshold.y || abs(difference.z) >= threshold.z); } void ext::Terrain::generate( bool single ) { uf::Serializer& metadata = this->getComponent(); pod::Vector3i radius = { metadata["terrain"]["radius"][0].as(), metadata["terrain"]["radius"][1].as(), metadata["terrain"]["radius"][2].as(), }; pod::Vector3i size = { metadata["region"]["size"][0].as(), metadata["region"]["size"][1].as(), metadata["region"]["size"][2].as(), }; uf::Scene& scene = uf::scene::getCurrentScene(); const pod::Transform<>& player = scene.getController().getComponent>(); pod::Vector3i location = { (int) player.position.x / size.x, (int) player.position.y / size.y, (int) player.position.z / size.z, }; if ( single ) this->generate( {location.x, location.y, location.z} ); else for ( int y = 0; y < radius.y; ++y ) { for ( int z = 0; z < radius.z; ++z ) { for ( int x = 0; x < radius.x; ++x ) { this->generate( {location.x + x, location.y + y, location.z + z} ); this->generate( {location.x - x, location.y - y, location.z - z} ); this->generate( {location.x + x, location.y + y, location.z - z} ); this->generate( {location.x - x, location.y + y, location.z + z} ); this->generate( {location.x - x, location.y + y, location.z - z} ); this->generate( {location.x + x, location.y - y, location.z + z} ); this->generate( {location.x + x, location.y - y, location.z - z} ); this->generate( {location.x - x, location.y - y, location.z + z} ); } } } } uf::Object* ext::Terrain::at( const pod::Vector3i& position ) const { if ( ::region_table.count(position) > 0 ) return ::region_table.at(position); const uf::Serializer& metadata = this->getComponent(); pod::Vector3i size = { metadata["region"]["size"][0].as(), metadata["region"]["size"][1].as(), metadata["region"]["size"][2].as(), }; if ( this->getChildren().empty() ) return NULL; for ( auto it = this->getChildren().begin(); it != this->getChildren().end(); ++it ) { uf::Entity* kv = *it; const pod::Transform<>& transform = kv->getComponent>(); pod::Vector3i location = { (int) (transform.position.x / size.x), (int) (transform.position.y / size.y), (int) (transform.position.z / size.z), }; if ( uf::vector::equals( location, position ) ) return (uf::Object*) kv; } return NULL; } void ext::Terrain::generate( const pod::Vector3i& position ) { uf::Serializer& metadata = this->getComponent(); pod::Vector3i size = { metadata["region"]["size"][0].as(), metadata["region"]["size"][1].as(), metadata["region"]["size"][2].as(), }; if ( this->exists(position) ) return; if ( !this->inBounds(position) ) return; /* auto& region = uf::instantiator::instantiate(); uf::instantiator::bind("RegionBehavior", region); this->addChild(region); */ auto& region = this->loadChild("./region.json", false); { uf::Serializer& m = region.getComponent(); // = metadata; m["system"]["type"] = "Region"; m["system"]["root"] = metadata["system"]["root"]; m["system"]["source"] = metadata["system"]["source"]; m["region"] = metadata["region"]; m["terrain"] = metadata["terrain"]; pod::Transform<>& transform = region.getComponent>(); transform.position.x = position.x * size.x; transform.position.y = position.y * size.y; transform.position.z = position.z * size.z; m["region"]["location"][0] = position.x; m["region"]["location"][1] = position.y; m["region"]["location"][2] = position.z; ::region_table[position] = ®ion; } } void ext::Terrain::degenerate( const pod::Vector3i& position ) { if ( !this->exists( position ) ) return; uf::Object* region = this->at( position ); if ( !region ) return; this->removeChild( *region ); region->destroy(); delete region; ::region_table.erase( position ); } #endif