forked from townforge/townforge
game: change flag extents to 3D markers
Works better for 3D terrain
This commit is contained in:
parent
6e04ee20dc
commit
bdfc76b151
@ -1,6 +1,6 @@
|
||||
<material>
|
||||
<technique name="Techniques/DiffUnlitAlpha.xml" />
|
||||
<texture unit="diffuse" name="Textures/selmask.png" />
|
||||
<texture unit="diffuse" name="Textures/blank.png" />
|
||||
<parameter name="MatDiffColor" value="1 1 1 1" />
|
||||
<parameter name="MatSpecColor" value="1 1 1 1" />
|
||||
</material>
|
||||
|
BIN
GameData/Textures/blank.png
Normal file
BIN
GameData/Textures/blank.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 69 B |
@ -67,7 +67,7 @@ static CustomModel *createModel(const std::vector<float> &vertex_data, const std
|
||||
// https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
|
||||
static Color GetRandomColor(size_t n, float alpha = 1.0f)
|
||||
{
|
||||
static constexpr float s = .7f;
|
||||
static constexpr float s = .9f;
|
||||
static constexpr float v = .95f;
|
||||
static constexpr float golden_ratio_conjugate = 0.618033988749895;
|
||||
float h = 0;
|
||||
@ -171,6 +171,8 @@ CityMeshResources::CityMeshResources(ResourceCache *cache)
|
||||
influenceModel = cache->GetResource<Model>("Models/Plane.mdl");
|
||||
cursorModel = cache->GetResource<Model>("Models/Box.mdl");
|
||||
|
||||
markerModel = cache->GetResource<Model>("Models/Pyramid.mdl");
|
||||
|
||||
VertexBuffer *vbuffer = blockModel->GetGeometry(0, 0)->GetVertexBuffer(0);
|
||||
const float *vertexData = (const float*)vbuffer->Lock(0, vbuffer->GetVertexCount());
|
||||
if (vertexData)
|
||||
@ -435,12 +437,14 @@ void CityMeshSection::setView(uint32_t vx0, uint32_t vy0, uint32_t vx1, uint32_t
|
||||
void CityMeshSection::setCameraPos(const Vector3 &pos)
|
||||
{
|
||||
height_scale = get_height_scale(pos);
|
||||
#if 0
|
||||
for (const auto &node: flagNodes)
|
||||
{
|
||||
Vector3 p = node.second->GetPosition();
|
||||
p.y_ = 0.01f * height_scale;
|
||||
node.second->SetPosition(p);
|
||||
}
|
||||
#endif
|
||||
if (selectionNode)
|
||||
selectionNode->SetPosition(Vector3(0.0f, 0.01f * height_scale, 0.0f));
|
||||
}
|
||||
@ -698,6 +702,47 @@ static CustomModel *create_area(Node *node, Material *material, uint32_t fx0, ui
|
||||
return model;
|
||||
}
|
||||
|
||||
static void add_marker(Node *node, Model *model, Material *material, uint32_t x, uint32_t y, uint32_t ox, uint32_t oy, float height)
|
||||
{
|
||||
Node *markerNode = node->CreateChild("marker");
|
||||
markerNode->SetPosition(Vector3((int32_t)(x - ox), height + 1.5f, (int32_t)(y - oy)));
|
||||
markerNode->SetScale(Vector3(0.5f, 3.0f, 0.5f));
|
||||
static const Quaternion upside_down(180.0f, Vector3(1.0f, 0.0f, 0.0f));
|
||||
markerNode->SetRotation(upside_down);
|
||||
auto object = markerNode->CreateComponent<StaticModel>();
|
||||
object->SetModel(model, true);
|
||||
object->SetMaterial(material);
|
||||
object->SetCastShadows(false);
|
||||
}
|
||||
|
||||
void CityMeshSection::CreateMarkerArea(Node *node, Material *material, uint32_t fx0, uint32_t fy0, uint32_t fx1, uint32_t fy1, float height)
|
||||
{
|
||||
const CityState *city = &game->cityState;
|
||||
const uint32_t ox = city->ox;
|
||||
const uint32_t oy = city->oy;
|
||||
const cc::cc_potential_state_t *state = cc::get_cc_potential_state(city->id, city->seed);
|
||||
|
||||
++fx1;
|
||||
++fy1;
|
||||
|
||||
add_marker(node, resources.markerModel, material, fx0, fy0, ox, oy, height + cc::get_cc_height(state, fx0, fy0) / (float)HEIGHT_UNITS_PER_BLOCK);
|
||||
add_marker(node, resources.markerModel, material, fx0, fy1, ox, oy, height + cc::get_cc_height(state, fx0, fy1) / (float)HEIGHT_UNITS_PER_BLOCK);
|
||||
add_marker(node, resources.markerModel, material, fx1, fy0, ox, oy, height + cc::get_cc_height(state, fx1, fy0) / (float)HEIGHT_UNITS_PER_BLOCK);
|
||||
add_marker(node, resources.markerModel, material, fx1, fy1, ox, oy, height + cc::get_cc_height(state, fx1, fy1) / (float)HEIGHT_UNITS_PER_BLOCK);
|
||||
|
||||
static const uint32_t delta = 4;
|
||||
for (uint32_t y = fy0 + delta; y <= fy1 - (delta - 1); y += delta)
|
||||
{
|
||||
add_marker(node, resources.markerModel, material, fx0, y, ox, oy, height + cc::get_cc_height(state, fx0, y) / (float)HEIGHT_UNITS_PER_BLOCK);
|
||||
add_marker(node, resources.markerModel, material, fx1, y, ox, oy, height + cc::get_cc_height(state, fx1, y) / (float)HEIGHT_UNITS_PER_BLOCK);
|
||||
}
|
||||
for (uint32_t x = fx0 + delta; x <= fx1 - (delta - 1); x += delta)
|
||||
{
|
||||
add_marker(node, resources.markerModel, material, x, fy0, ox, oy, height + cc::get_cc_height(state, x, fy0) / (float)HEIGHT_UNITS_PER_BLOCK);
|
||||
add_marker(node, resources.markerModel, material, x, fy1, ox, oy, height + cc::get_cc_height(state, x, fy1) / (float)HEIGHT_UNITS_PER_BLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
void CityMeshSection::GetFlags(std::set<uint32_t> &flags) const
|
||||
{
|
||||
for (const auto &e: blockNodes)
|
||||
@ -1283,14 +1328,12 @@ void CityMeshSection::RebuildFlags(const C &flags, const Selection &selection, b
|
||||
if (!material)
|
||||
{
|
||||
material = resources.ownershipMaterial->Clone();
|
||||
material->SetShaderParameter("MatDiffColor", GetRandomColor(flag->owner, .6f));
|
||||
material->SetShaderParameter("MatDiffColor", GetRandomColor(flag->owner, 1.0f));
|
||||
resources.ownership_materials[flag->id] = material;
|
||||
}
|
||||
|
||||
create_area(flagNode, material, flag->x0, flag->y0, flag->x1, flag->y1, ox, oy, 0.0f);
|
||||
CreateMarkerArea(flagNode, material, flag->x0, flag->y0, flag->x1, flag->y1, 0.0f);
|
||||
}
|
||||
|
||||
flagNode->SetPosition(Vector3(U2Fd(flag->, x), 0.01f * height_scale, U2Fd(flag->, y)));
|
||||
}
|
||||
|
||||
if (has_new)
|
||||
@ -1394,13 +1437,10 @@ void CityMeshUrho3D::CreateGroundTiles()
|
||||
ResourceCache* cache = node->GetSubsystem<ResourceCache>();
|
||||
|
||||
influenceNode = node->CreateChild("influence");
|
||||
influenceNode->SetPosition(Vector3(0.0f, 0.02f * height_scale, 0.0f));
|
||||
|
||||
generatorExtentsNode = node->CreateChild("generator_extents");
|
||||
generatorExtentsNode->SetPosition(Vector3(0.0f, 0.0175f * height_scale, 0.0f));
|
||||
|
||||
maxGeneratorExtentsNode = node->CreateChild("max_generator_extents");
|
||||
maxGeneratorExtentsNode->SetPosition(Vector3(0.0f, 0.0175f * height_scale, 0.0f));
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
@ -1474,10 +1514,9 @@ void CityMeshUrho3D::setHighlight(const Selection &selection, const std::shared_
|
||||
uint32_t iy0 = flag->y0 - influence;
|
||||
uint32_t ix1 = flag->x1 + influence;
|
||||
uint32_t iy1 = flag->y1 + influence;
|
||||
influenceNode->SetPosition(Vector3(U2F(i, x), 0.315f * height_scale, U2F(i, y)));
|
||||
node->AddChild(influenceNode); // does not double add and removes from existing parent if needed
|
||||
influenceNode->RemoveComponents<CustomModel>();
|
||||
create_area(influenceNode, resources.influenceMaterial, ix0, iy0, ix1, iy1, ox, oy, 0.0f);
|
||||
influenceNode->RemoveAllChildren();
|
||||
CreateMarkerArea(influenceNode, resources.influenceMaterial, ix0, iy0, ix1, iy1, 0.0f);
|
||||
if (cc::is_generator(flag->role))
|
||||
{
|
||||
uint32_t generator_extents = RESOURCE_AVAILABILITY_SCALE(influence);
|
||||
@ -1485,17 +1524,15 @@ void CityMeshUrho3D::setHighlight(const Selection &selection, const std::shared_
|
||||
uint32_t gy0 = flag->y0 - generator_extents;
|
||||
uint32_t gx1 = flag->x1 + generator_extents;
|
||||
uint32_t gy1 = flag->y1 + generator_extents;
|
||||
generatorExtentsNode->RemoveComponents<CustomModel>();
|
||||
generatorExtentsNode->SetPosition(Vector3(U2F(g, x), 0.3175f * height_scale, U2F(g, y)));
|
||||
create_area(generatorExtentsNode, resources.influenceMaterial, gx0, gy0, gx1, gy1, ox, oy, 0.0f);
|
||||
generatorExtentsNode->RemoveAllChildren();
|
||||
CreateMarkerArea(generatorExtentsNode, resources.influenceMaterial, gx0, gy0, gx1, gy1, 0.0f);
|
||||
|
||||
uint32_t mgx0 = flag->x0 - generator_extents * MAX_DISTANCE_PERCENTAGE / 100;
|
||||
uint32_t mgy0 = flag->y0 - generator_extents * MAX_DISTANCE_PERCENTAGE / 100;
|
||||
uint32_t mgx1 = flag->x1 - generator_extents * MAX_DISTANCE_PERCENTAGE / 100;
|
||||
uint32_t mgy1 = flag->y1 - generator_extents * MAX_DISTANCE_PERCENTAGE / 100;
|
||||
maxGeneratorExtentsNode->RemoveComponents<CustomModel>();
|
||||
maxGeneratorExtentsNode->SetPosition(Vector3(U2F(mg, x), 0.3175f * height_scale, U2F(mg, y)));
|
||||
create_area(maxGeneratorExtentsNode, resources.influenceMaterial, mgx0, mgy0, mgx1, mgy1, ox, oy, 0.0f);
|
||||
maxGeneratorExtentsNode->RemoveAllChildren();
|
||||
CreateMarkerArea(maxGeneratorExtentsNode, resources.influenceMaterial, mgx0, mgy0, mgx1, mgy1, 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1572,18 +1609,6 @@ void CityMeshSection::updateHeightMap()
|
||||
printf("Height map changed in %f seconds, geometry rebuilt in %f seconds\n", (t1-t0)/1e6, (t2-t1)/1e6);
|
||||
}
|
||||
|
||||
bool CityMeshSection::IsIn(uint32_t x, uint32_t y) const
|
||||
{
|
||||
return (x >= vx0 && x <= vx1 && y >= vy0 && y <= vy1);
|
||||
}
|
||||
|
||||
uint16_t CityMeshSection::GetTerrainHeight(uint32_t x, uint32_t y) const
|
||||
{
|
||||
uint16_t h = terrainHeightMap->GetPixelInt(x - vx0, terrainHeightMap->GetHeight() - 1 - (y - vy0));
|
||||
h = SWAP16(h);
|
||||
return h / HEIGHT_UNITS_PER_BLOCK;
|
||||
}
|
||||
|
||||
void CityMeshSection::SetNorth(const Urho3D::SharedPtr<CityMeshSection> §ion)
|
||||
{
|
||||
terrain->SetNorthNeighbor(section ? section->terrain : NULL);
|
||||
@ -1610,7 +1635,7 @@ void CityMeshUrho3D::Update(float timeStep, const Selection &selection, bool mar
|
||||
float pulseIntensity = (sinf(time * 10) + 1) / 2;
|
||||
Color color(pulseIntensity / 2, pulseIntensity / 2 + .75f, pulseIntensity / 2 + .75f, 0.5);
|
||||
resources.selectedMaterial->SetShaderParameter("MatDiffColor", color);
|
||||
color.a_ = 0.3;
|
||||
color.a_ = 1.0f;
|
||||
resources.influenceMaterial->SetShaderParameter("MatDiffColor", color);
|
||||
if (mark_new_block)
|
||||
empower_t0 = time;
|
||||
@ -1765,19 +1790,32 @@ void CityMeshUrho3D::ClearFlags(const std::set<uint32_t> &flags)
|
||||
sections[x][y]->ClearFlags(flags);
|
||||
}
|
||||
|
||||
uint16_t CityMeshUrho3D::GetTerrainHeight(uint32_t tx, uint32_t ty) const
|
||||
uint16_t CityMeshUrho3D::GetTerrainHeight(uint32_t x, uint32_t y) const
|
||||
{
|
||||
for (int y = 0; y < NUM_CITY_SECTIONS; ++y)
|
||||
for (int x = 0; x < NUM_CITY_SECTIONS; ++x)
|
||||
if (sections[x][y] && sections[x][y]->IsIn(tx, ty))
|
||||
return sections[x][y]->GetTerrainHeight(tx, ty);
|
||||
|
||||
const CityState *city = &game->cityState;
|
||||
const cc::cc_potential_state_t *state = cc::get_cc_potential_state(city->id, city->seed);
|
||||
const uint16_t raw_height = cc::get_cc_height(state, tx, ty);
|
||||
const uint16_t raw_height = cc::get_cc_height(state, x, y);
|
||||
return raw_height / HEIGHT_UNITS_PER_BLOCK;
|
||||
}
|
||||
|
||||
void CityMeshUrho3D::CreateMarkerArea(Node *node, Material *material, uint32_t fx0, uint32_t fy0, uint32_t fx1, uint32_t fy1, float height)
|
||||
{
|
||||
const CityState *city = &game->cityState;
|
||||
const uint32_t ox = city->ox;
|
||||
const uint32_t oy = city->oy;
|
||||
const cc::cc_potential_state_t *state = cc::get_cc_potential_state(city->id, city->seed);
|
||||
for (uint32_t y = fy0; y <= fy1; y += 4)
|
||||
{
|
||||
add_marker(node, resources.markerModel, material, fx0, y, ox, oy, height + cc::get_cc_height(state, fx0, y) / (float)HEIGHT_UNITS_PER_BLOCK);
|
||||
add_marker(node, resources.markerModel, material, fx1, y, ox, oy, height + cc::get_cc_height(state, fx1, y) / (float)HEIGHT_UNITS_PER_BLOCK);
|
||||
}
|
||||
for (uint32_t x = fx0 + 4; x <= fx1 - 4; x += 4)
|
||||
{
|
||||
add_marker(node, resources.markerModel, material, x, fy0, ox, oy, height + cc::get_cc_height(state, x, fy0) / (float)HEIGHT_UNITS_PER_BLOCK);
|
||||
add_marker(node, resources.markerModel, material, x, fy1, ox, oy, height + cc::get_cc_height(state, x, fy1) / (float)HEIGHT_UNITS_PER_BLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
void CityMeshUrho3D::RebuildFlags(const C &flags, const Selection &selection, bool highlight_new)
|
||||
{
|
||||
|
@ -68,6 +68,7 @@ struct CityMeshResources
|
||||
Urho3D::SharedPtr<Urho3D::Model> selectionModel;
|
||||
Urho3D::SharedPtr<Urho3D::Model> influenceModel;
|
||||
Urho3D::SharedPtr<Urho3D::Model> cursorModel;
|
||||
Urho3D::SharedPtr<Urho3D::Model> markerModel;
|
||||
|
||||
Urho3D::Quaternion FrontRotation;
|
||||
Urho3D::Quaternion BackRotation;
|
||||
@ -96,8 +97,6 @@ public:
|
||||
void ClearFlags(const std::set<uint32_t> &flags);
|
||||
template<typename C> void RebuildFlags(const C &flags, const Selection &selection, bool highlight_new);
|
||||
bool hasFlagsWithNew() const { return !flagsWithNew.empty(); }
|
||||
bool IsIn(uint32_t x, uint32_t y) const;
|
||||
uint16_t GetTerrainHeight(uint32_t x, uint32_t y) const;
|
||||
|
||||
void SetNorth(const Urho3D::SharedPtr<CityMeshSection> §ion);
|
||||
void SetSouth(const Urho3D::SharedPtr<CityMeshSection> §ion);
|
||||
@ -107,6 +106,7 @@ public:
|
||||
private:
|
||||
void CreateTerrain();
|
||||
void updateHeightMap();
|
||||
void CreateMarkerArea(Urho3D::Node *node, Urho3D::Material *material, uint32_t fx0, uint32_t fy0, uint32_t fx1, uint32_t fy1, float height = 0.0f);
|
||||
|
||||
private:
|
||||
const GameState *game;
|
||||
@ -179,6 +179,7 @@ private:
|
||||
void CreateGroundTiles();
|
||||
void CreateTerrain();
|
||||
void SetupMaterials();
|
||||
void CreateMarkerArea(Urho3D::Node *node, Urho3D::Material *material, uint32_t fx0, uint32_t fy0, uint32_t fx1, uint32_t fy1, float height = 0.0f);
|
||||
|
||||
private:
|
||||
Urho3D::SharedPtr<Urho3D::Node> node;
|
||||
|
Loading…
Reference in New Issue
Block a user