101 lines
2.6 KiB
C++
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
|