Files
academy2/modules/meshops/city_grid.h
2021-07-31 03:37:28 +03:00

101 lines
2.6 KiB
C++

#ifndef CITY_GRID_H
#define CITY_GRID_H
#include <core/hash_map.h>
#include <modules/voxel/util/math/vector3i.h>
class TownGridData {
protected:
struct shape_data {
Ref<Shape> shape;
Transform shape_xform;
};
struct cell_item {
String name;
AABB aabb;
Transform xform;
Dictionary data;
};
Vector<cell_item> items;
HashMap<Vector3i, int, Vector3iHasher> grid;
Vector3 origin;
Vector3 scale;
public:
void set_origin(const Vector3 &pos)
{
origin = pos;
}
void set_scale(const Vector3 &pos)
{
scale = pos;
}
Vector3i pos_to_grid(const Vector3 &pos)
{
Vector3i ret;
ret.x = (int)(((pos.x - origin.x) / + scale.x * 0.5f) / scale.x);
ret.y = (int)(((pos.y - origin.y) / + scale.y * 0.5f) / scale.y);
ret.z = (int)(((pos.z - origin.z) / + scale.z * 0.5f) / scale.z);
return ret;
}
Vector3 grid_to_pos(int x, int y, int z)
{
Vector3 ret;
ret.x = (float)x * scale.x - scale.x * 0.5f + origin.x;
ret.y = (float)y * scale.y - scale.y * 0.5f + origin.y;
ret.z = (float)z * scale.z - scale.z * 0.5f + origin.z;
return ret;
}
bool grid_can_place(const AABB &place, const Transform &xform)
{
Transform xform_inv = xform.affine_inverse();
AABB xplace = xform.xform(place);
int i, j, k, x1, y1, z1, x2, y2, z2;
Vector3i a = pos_to_grid(xplace.position);
Vector3i b = pos_to_grid(xplace.position + xplace.size);
x1 = MIN(a.x, b.x);
y1 = MIN(a.y, b.y);
z1 = MIN(a.z, b.z);
x2 = MAX(a.x, b.x);
y2 = MAX(a.y, b.y);
z2 = MAX(a.z, b.z);
for (i = x1; i < x2; i++)
for (j = y1; j < y2; j++)
for (k = z1; k < z2; k++) {
Vector3 key(i, j, k);
Vector3 pos = grid_to_pos(i, j, k);
Vector3 pos_inv = xform_inv.xform(pos);
if (place.has_point(pos_inv) && grid.has(key))
return false;
}
return true;
}
void grid_place(const StringName &name, const AABB &place, const Transform &xform)
{
int id = items.size();
struct cell_item it;
it.name = name;
it.aabb = place;
it.xform = xform;
items.push_back(it);
Transform xform_inv = xform.affine_inverse();
AABB xplace = xform.xform(place);
int i, j, k, x1, y1, z1, x2, y2, z2;
Vector3i a = pos_to_grid(xplace.position);
Vector3i b = pos_to_grid(xplace.position + xplace.size);
x1 = MIN(a.x, b.x);
y1 = MIN(a.y, b.y);
z1 = MIN(a.z, b.z);
x2 = MAX(a.x, b.x);
y2 = MAX(a.y, b.y);
z2 = MAX(a.z, b.z);
for (i = x1; i < x2; i++)
for (j = y1; j < y2; j++)
for (k = z1; k < z2; k++) {
Vector3 key(i, j, k);
Vector3 pos = grid_to_pos(i, j, k);
Vector3 pos_inv = xform_inv.xform(pos);
if (place.has_point(pos_inv))
grid[key] = id;
}
}
};
#endif