forked from townforge/townforge
game: allow ellipsoid selection on land without flags
This commit is contained in:
parent
ba37b600e1
commit
e28cd0c4ce
@ -653,6 +653,35 @@ void CityMeshSection::ClearFlags(const std::set<uint32_t> &flags)
|
||||
}
|
||||
}
|
||||
|
||||
static void add_span(std::vector<std::vector<uint8_t>> &spans, uint32_t dx, uint32_t dy, uint32_t dh, uint32_t span_width, uint32_t span_height, uint8_t material_type)
|
||||
{
|
||||
const uint32_t idx = dy;
|
||||
if (idx >= spans.size())
|
||||
printf("add_span: overlow: %u vs %zu from dx %u dy %u dh %u\n", idx, spans.size(), dx, dy, dh);
|
||||
if (spans[idx].empty())
|
||||
spans[idx].resize(span_width * span_height, 0);
|
||||
spans[idx][dx + dh * span_width] = material_type;
|
||||
};
|
||||
|
||||
static void add_face_span(std::vector<float> &vdata, std::vector<uint32_t> &idata, int face, float dx, float dy, float h, float x_span, float y_span, float h_span, uint32_t u, uint32_t v, float u_mul, float v_mul, uint32_t material_scale)
|
||||
{
|
||||
const uint32_t idx_base = vdata.size() / 8;
|
||||
u %= material_scale;
|
||||
v %= material_scale;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
vdata.push_back(vertex_data_template[(face * 4 + i) * 8 + 0] * x_span + (x_span - 1) / 2.0f + dx);
|
||||
vdata.push_back(vertex_data_template[(face * 4 + i) * 8 + 1] * h_span + (h_span - 1) / 2.0f + h + 0.5f);
|
||||
vdata.push_back(vertex_data_template[(face * 4 + i) * 8 + 2] * y_span + (y_span - 1) / 2.0f + dy);
|
||||
vdata.push_back(vertex_data_template[(face * 4 + i) * 8 + 3]);
|
||||
vdata.push_back(vertex_data_template[(face * 4 + i) * 8 + 4]);
|
||||
vdata.push_back(vertex_data_template[(face * 4 + i) * 8 + 5]);
|
||||
vdata.push_back((vertex_data_template[(face * 4 + i) * 8 + 6] * u_mul + u) / material_scale);
|
||||
vdata.push_back((vertex_data_template[(face * 4 + i) * 8 + 7] * v_mul + v) / material_scale);
|
||||
}
|
||||
for (auto i = 0; i < 6; ++i) idata.push_back(index_data_template[i+face*6] + idx_base - face*4);
|
||||
};
|
||||
|
||||
template<typename C>
|
||||
void CityMeshSection::RebuildFlags(const C &flags, const Selection &selection, bool highlight_new)
|
||||
{
|
||||
@ -690,25 +719,6 @@ void CityMeshSection::RebuildFlags(const C &flags, const Selection &selection, b
|
||||
idx_base += 4;
|
||||
};
|
||||
|
||||
auto add_face_span = [](std::vector<float> &vdata, std::vector<uint32_t> &idata, int face, float dx, float dy, float h, float x_span, float y_span, float h_span, uint32_t u, uint32_t v, float u_mul, float v_mul, uint32_t material_scale)
|
||||
{
|
||||
const uint32_t idx_base = vdata.size() / 8;
|
||||
u %= material_scale;
|
||||
v %= material_scale;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
vdata.push_back(vertex_data_template[(face * 4 + i) * 8 + 0] * x_span + (x_span - 1) / 2.0f + dx);
|
||||
vdata.push_back(vertex_data_template[(face * 4 + i) * 8 + 1] * h_span + (h_span - 1) / 2.0f + h + 0.5f);
|
||||
vdata.push_back(vertex_data_template[(face * 4 + i) * 8 + 2] * y_span + (y_span - 1) / 2.0f + dy);
|
||||
vdata.push_back(vertex_data_template[(face * 4 + i) * 8 + 3]);
|
||||
vdata.push_back(vertex_data_template[(face * 4 + i) * 8 + 4]);
|
||||
vdata.push_back(vertex_data_template[(face * 4 + i) * 8 + 5]);
|
||||
vdata.push_back((vertex_data_template[(face * 4 + i) * 8 + 6] * u_mul + u) / material_scale);
|
||||
vdata.push_back((vertex_data_template[(face * 4 + i) * 8 + 7] * v_mul + v) / material_scale);
|
||||
}
|
||||
for (auto i = 0; i < 6; ++i) idata.push_back(index_data_template[i+face*6] + idx_base - face*4);
|
||||
};
|
||||
|
||||
auto add_quad_instance = [](StaticModelGroup *group, Node *node, const Vector3 &position, const Quaternion &rotation)
|
||||
{
|
||||
Node *instance = node->CreateChild("instance");
|
||||
@ -717,16 +727,6 @@ void CityMeshSection::RebuildFlags(const C &flags, const Selection &selection, b
|
||||
group->AddInstanceNode(instance);
|
||||
};
|
||||
|
||||
auto add_span = [](std::vector<std::vector<uint8_t>> &spans, uint32_t dx, uint32_t dy, uint32_t dh, uint32_t span_width, uint32_t span_height, uint8_t material_type)
|
||||
{
|
||||
const uint32_t idx = dy;
|
||||
if (idx >= spans.size())
|
||||
printf("add_span: overlow: %u vs %zu from dx %u dy %u dh %u\n", idx, spans.size(), dx, dy, dh);
|
||||
if (spans[idx].empty())
|
||||
spans[idx].resize(span_width * span_height, 0);
|
||||
spans[idx][dx + dh * span_width] = material_type;
|
||||
};
|
||||
|
||||
ResourceCache* cache = node->GetSubsystem<ResourceCache>();
|
||||
|
||||
updateHeightMap();
|
||||
@ -1041,7 +1041,7 @@ void CityMeshSection::RebuildFlags(const C &flags, const Selection &selection, b
|
||||
const uint32_t span_height = max_height;
|
||||
return cc::rectanglizer(span_width, span_height, span, rectangles, vertical_only);
|
||||
},
|
||||
[&add_face_span](std::vector<float> &vdata, std::vector<uint32_t> &idata,
|
||||
[](std::vector<float> &vdata, std::vector<uint32_t> &idata,
|
||||
uint32_t rx0, uint32_t ry0, uint32_t i, uint32_t rx_span, uint32_t ry_span, uint32_t fx0, uint32_t fy0,
|
||||
uint32_t ox, uint32_t oy, uint32_t material_scale) {
|
||||
add_face_span(vdata, idata, 0,
|
||||
@ -1061,7 +1061,7 @@ void CityMeshSection::RebuildFlags(const C &flags, const Selection &selection, b
|
||||
const uint32_t span_height = max_height;
|
||||
return cc::rectanglizer(span_width, span_height, span, rectangles, vertical_only);
|
||||
},
|
||||
[&add_face_span](std::vector<float> &vdata, std::vector<uint32_t> &idata,
|
||||
[](std::vector<float> &vdata, std::vector<uint32_t> &idata,
|
||||
uint32_t rx0, uint32_t ry0, uint32_t i, uint32_t rx_span, uint32_t ry_span, uint32_t fx0, uint32_t fy0,
|
||||
uint32_t ox, uint32_t oy, uint32_t material_scale) {
|
||||
add_face_span(vdata, idata, 1,
|
||||
@ -1081,7 +1081,7 @@ void CityMeshSection::RebuildFlags(const C &flags, const Selection &selection, b
|
||||
const uint32_t span_height = max_height;
|
||||
return cc::rectanglizer(span_width, span_height, span, rectangles, vertical_only);
|
||||
},
|
||||
[&add_face_span](std::vector<float> &vdata, std::vector<uint32_t> &idata,
|
||||
[](std::vector<float> &vdata, std::vector<uint32_t> &idata,
|
||||
uint32_t rx0, uint32_t ry0, uint32_t i, uint32_t rx_span, uint32_t ry_span, uint32_t fx0, uint32_t fy0,
|
||||
uint32_t ox, uint32_t oy, uint32_t material_scale) {
|
||||
add_face_span(vdata, idata, 2,
|
||||
@ -1101,7 +1101,7 @@ void CityMeshSection::RebuildFlags(const C &flags, const Selection &selection, b
|
||||
const uint32_t span_height = max_height;
|
||||
return cc::rectanglizer(span_width, span_height, span, rectangles, vertical_only);
|
||||
},
|
||||
[&add_face_span](std::vector<float> &vdata, std::vector<uint32_t> &idata,
|
||||
[](std::vector<float> &vdata, std::vector<uint32_t> &idata,
|
||||
uint32_t rx0, uint32_t ry0, uint32_t i, uint32_t rx_span, uint32_t ry_span, uint32_t fx0, uint32_t fy0,
|
||||
uint32_t ox, uint32_t oy, uint32_t material_scale) {
|
||||
add_face_span(vdata, idata, 3,
|
||||
@ -1121,7 +1121,7 @@ void CityMeshSection::RebuildFlags(const C &flags, const Selection &selection, b
|
||||
const uint32_t span_height = fx1 - fx0 + 1;
|
||||
return cc::rectanglizer(span_width, span_height, span, rectangles, vertical_only);
|
||||
},
|
||||
[&add_face_span](std::vector<float> &vdata, std::vector<uint32_t> &idata,
|
||||
[](std::vector<float> &vdata, std::vector<uint32_t> &idata,
|
||||
uint32_t rx0, uint32_t ry0, uint32_t i, uint32_t rx_span, uint32_t ry_span, uint32_t fx0, uint32_t fy0,
|
||||
uint32_t ox, uint32_t oy, uint32_t material_scale) {
|
||||
add_face_span(vdata, idata, 4,
|
||||
@ -1141,7 +1141,7 @@ void CityMeshSection::RebuildFlags(const C &flags, const Selection &selection, b
|
||||
const uint32_t span_height = fx1 - fx0 + 1;
|
||||
return cc::rectanglizer(span_width, span_height, span, rectangles, vertical_only);
|
||||
},
|
||||
[&add_face_span](std::vector<float> &vdata, std::vector<uint32_t> &idata,
|
||||
[](std::vector<float> &vdata, std::vector<uint32_t> &idata,
|
||||
uint32_t rx0, uint32_t ry0, uint32_t i, uint32_t rx_span, uint32_t ry_span, uint32_t fx0, uint32_t fy0,
|
||||
uint32_t ox, uint32_t oy, uint32_t material_scale) {
|
||||
add_face_span(vdata, idata, 5,
|
||||
@ -1325,14 +1325,6 @@ void CityMeshUrho3D::CreateGroundTiles()
|
||||
{
|
||||
ResourceCache* cache = node->GetSubsystem<ResourceCache>();
|
||||
|
||||
selectionNode = node->CreateChild("selection");
|
||||
selectionNode->SetPosition(Vector3(0.0f, 0.02f * height_scale, 0.0f));
|
||||
selectionNode->SetScale(Vector3(0.0f, 0.01f, 0.0f));
|
||||
auto* selectionObject = selectionNode->CreateComponent<StaticModel>();
|
||||
selectionObject->SetModel(resources.selectionModel, true);
|
||||
selectionObject->SetMaterial(resources.selectedMaterial);
|
||||
selectionObject->SetCastShadows(false);
|
||||
|
||||
influenceNode = node->CreateChild("influence");
|
||||
influenceNode->SetPosition(Vector3(0.0f, 0.02f * height_scale, 0.0f));
|
||||
|
||||
@ -1428,8 +1420,6 @@ void CityMeshUrho3D::setHighlight(const Selection &selection, const std::shared_
|
||||
const CityState *city = &game->cityState;
|
||||
const uint32_t ox = city->ox;
|
||||
const uint32_t oy = city->oy;
|
||||
selectionNode->SetPosition(Vector3(U2Fd(selection., x), 0.02f * height_scale, U2Fd(selection., y)));
|
||||
selectionNode->SetScale(Vector3(selection.x1 - selection.x0 + 1, 0.01f, selection.y1 - selection.y0 + 1));
|
||||
|
||||
if (selected_flag || hover_flag)
|
||||
{
|
||||
@ -1494,6 +1484,57 @@ void CityMeshUrho3D::setHighlight(const Selection &selection, const std::shared_
|
||||
node->RemoveChild(cursorNode[CURSOR_NEW]);
|
||||
node->RemoveChild(cursorNode[CURSOR_SEL]);
|
||||
}
|
||||
|
||||
// selection
|
||||
if (selectionNode)
|
||||
{
|
||||
selectionNode->Remove();
|
||||
selectionNode = NULL;
|
||||
}
|
||||
|
||||
std::vector<std::vector<uint8_t>> base_spans(1);
|
||||
|
||||
bool has_selection = false;
|
||||
for (uint32_t y = selection.y0; y <= selection.y1; ++y)
|
||||
{
|
||||
for (uint32_t x = selection.x0; x <= selection.x1; ++x)
|
||||
{
|
||||
if (selection.is_selected(x, y))
|
||||
{
|
||||
add_span(base_spans, y - selection.y0, 0, x - selection.x0, selection.y1-selection.y0+1, selection.x1-selection.x0+1, 1);
|
||||
has_selection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_selection)
|
||||
{
|
||||
selectionNode = node->CreateChild("selection");
|
||||
|
||||
std::vector<float> vertex_data;
|
||||
std::vector<uint32_t> index_data;
|
||||
bool indices_fit_in_16_bits = true;
|
||||
std::vector<std::tuple<uint32_t, uint32_t, uint32_t, uint32_t, uint8_t>> rectangles;
|
||||
if (!cc::rectanglizer(selection.y1 - selection.y0 + 1, selection.x1 - selection.x0 + 1, base_spans[0], rectangles, false))
|
||||
printf("Rectanglizer failure !!!\n");
|
||||
for (const auto &r: rectangles)
|
||||
{
|
||||
const uint8_t material_type = std::get<4>(r);
|
||||
const uint32_t rx0 = std::get<0>(r);
|
||||
const uint32_t ry0 = std::get<1>(r);
|
||||
const uint32_t rx_span = std::get<2>(r);
|
||||
const uint32_t ry_span = std::get<3>(r);
|
||||
add_face_span(vertex_data, index_data, 5,
|
||||
(int32_t)(selection.x0 + ry0 - ox) + 0.5f, (int32_t)(selection.y0 + rx0 - oy) + 0.5f, 0,
|
||||
ry_span, rx_span, 1,
|
||||
selection.y0 + rx0, selection.x0 + ry0, rx_span, ry_span, 1);
|
||||
if (vertex_data.size() > 65535)
|
||||
indices_fit_in_16_bits = false;
|
||||
}
|
||||
StaticModel *model = createModel(vertex_data, index_data, indices_fit_in_16_bits, selectionNode, resources.selectedMaterial);
|
||||
if (model)
|
||||
model->SetCastShadows(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CityMeshSection::updateHeightMap()
|
||||
@ -1613,8 +1654,12 @@ void CityMeshUrho3D::SetView(const Vector3 &pos)
|
||||
|
||||
height_scale = get_height_scale(pos);
|
||||
|
||||
selectionNode->SetPosition(Vector3(U2Fd(selection., x), 0.02f * height_scale, U2Fd(selection., y)));
|
||||
selectionNode->SetScale(Vector3(selection.x1 - selection.x0 + 1, 0.01f, selection.y1 - selection.y0 + 1));
|
||||
if (selectionNode)
|
||||
{
|
||||
Vector3 p = selectionNode->GetPosition();
|
||||
p.y_ = 0.02f * height_scale;
|
||||
selectionNode->SetPosition(p);
|
||||
}
|
||||
|
||||
for (int y = 0; y < NUM_CITY_SECTIONS; ++y)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user