#ifndef CITY_GRID_H #define CITY_GRID_H #include #include class TownGridData { protected: struct shape_data { Ref shape; Transform shape_xform; }; struct cell_item { String name; AABB aabb; Transform xform; Dictionary data; }; Vector items; HashMap 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