Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
RegularGrid.h
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#ifndef _REGULAR_GRID_H
7#define _REGULAR_GRID_H
8
9
10#include <G3D/Ray.h>
11#include <G3D/Table.h>
12#include <G3D/BoundsTrait.h>
13#include <G3D/PositionTrait.h>
14
15#include "Errors.h"
16
17template<class Node>
19 static Node * makeNode(int /*x*/, int /*y*/) { return new Node();}
20};
21
22template<class T,
23class Node,
24class NodeCreatorFunc = NodeCreator<Node>,
25 /*class BoundsFunc = BoundsTrait<T>,*/
26class PositionFunc = PositionTrait<T>
27>
29{
30public:
31 enum{
33 };
34
35 #define HGRID_MAP_SIZE (533.33333f * 64.f) // shouldn't be changed
36 #define CELL_SIZE float(HGRID_MAP_SIZE/(float)CELL_NUMBER)
37
38 typedef G3D::Table<const T*, Node*> MemberTable;
39
42
44 memset(nodes, 0, sizeof(nodes));
45 }
46
48 for (int x = 0; x < CELL_NUMBER; ++x)
49 for (int y = 0; y < CELL_NUMBER; ++y)
50 delete nodes[x][y];
51 }
52
53 void insert(const T& value)
54 {
55 G3D::Vector3 pos;
56 PositionFunc::getPosition(value, pos);
57 Node& node = getGridFor(pos.x, pos.y);
58 node.insert(value);
59 memberTable.set(&value, &node);
60 }
61
62 void remove(const T& value)
63 {
64 memberTable[&value]->remove(value);
65 // Remove the member
66 memberTable.remove(&value);
67 }
68
69 void balance()
70 {
71 for (int x = 0; x < CELL_NUMBER; ++x)
72 for (int y = 0; y < CELL_NUMBER; ++y)
73 if (Node* n = nodes[x][y])
74 n->balance();
75 }
76
77 bool contains(const T& value) const { return memberTable.containsKey(&value); }
78 int size() const { return memberTable.size(); }
79
80 struct Cell
81 {
82 int x, y;
83 bool operator == (const Cell& c2) const { return x == c2.x && y == c2.y;}
84
85 static Cell ComputeCell(float fx, float fy)
86 {
87 Cell c = { int(fx * (1.f/CELL_SIZE) + (CELL_NUMBER/2)), int(fy * (1.f/CELL_SIZE) + (CELL_NUMBER/2)) };
88 return c;
89 }
90
91 bool isValid() const { return x >= 0 && x < CELL_NUMBER && y >= 0 && y < CELL_NUMBER;}
92 };
93
94
95 Node& getGridFor(float fx, float fy)
96 {
97 Cell c = Cell::ComputeCell(fx, fy);
98 return getGrid(c.x, c.y);
99 }
100
101 Node& getGrid(int x, int y)
102 {
103 ASSERT(x < CELL_NUMBER && y < CELL_NUMBER);
104 if (!nodes[x][y])
105 nodes[x][y] = NodeCreatorFunc::makeNode(x, y);
106 return *nodes[x][y];
107 }
108
109 template<typename RayCallback>
110 void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float max_dist)
111 {
112 intersectRay(ray, intersectCallback, max_dist, ray.origin() + ray.direction() * max_dist);
113 }
114
115 template<typename RayCallback>
116 void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& max_dist, const G3D::Vector3& end)
117 {
118 Cell cell = Cell::ComputeCell(ray.origin().x, ray.origin().y);
119 if (!cell.isValid())
120 return;
121
122 Cell last_cell = Cell::ComputeCell(end.x, end.y);
123
124 if (cell == last_cell)
125 {
126 if (Node* node = nodes[cell.x][cell.y])
127 node->intersectRay(ray, intersectCallback, max_dist);
128 return;
129 }
130
131 float voxel = (float)CELL_SIZE;
132 float kx_inv = ray.invDirection().x, bx = ray.origin().x;
133 float ky_inv = ray.invDirection().y, by = ray.origin().y;
134
135 int stepX, stepY;
136 float tMaxX, tMaxY;
137 if (kx_inv >= 0)
138 {
139 stepX = 1;
140 float x_border = (cell.x+1) * voxel;
141 tMaxX = (x_border - bx) * kx_inv;
142 }
143 else
144 {
145 stepX = -1;
146 float x_border = (cell.x-1) * voxel;
147 tMaxX = (x_border - bx) * kx_inv;
148 }
149
150 if (ky_inv >= 0)
151 {
152 stepY = 1;
153 float y_border = (cell.y+1) * voxel;
154 tMaxY = (y_border - by) * ky_inv;
155 }
156 else
157 {
158 stepY = -1;
159 float y_border = (cell.y-1) * voxel;
160 tMaxY = (y_border - by) * ky_inv;
161 }
162
163 //int Cycles = std::max((int)ceilf(max_dist/tMaxX),(int)ceilf(max_dist/tMaxY));
164 //int i = 0;
165
166 float tDeltaX = voxel * fabs(kx_inv);
167 float tDeltaY = voxel * fabs(ky_inv);
168 do
169 {
170 if (Node* node = nodes[cell.x][cell.y])
171 {
172 //float enterdist = max_dist;
173 node->intersectRay(ray, intersectCallback, max_dist);
174 }
175 if (cell == last_cell)
176 break;
177 if (tMaxX < tMaxY)
178 {
179 tMaxX += tDeltaX;
180 cell.x += stepX;
181 }
182 else
183 {
184 tMaxY += tDeltaY;
185 cell.y += stepY;
186 }
187 //++i;
188 } while (cell.isValid());
189 }
190
191 template<typename IsectCallback>
192 void intersectPoint(const G3D::Vector3& point, IsectCallback& intersectCallback)
193 {
194 Cell cell = Cell::ComputeCell(point.x, point.y);
195 if (!cell.isValid())
196 return;
197 if (Node* node = nodes[cell.x][cell.y])
198 node->intersectPoint(point, intersectCallback);
199 }
200
201 // Optimized verson of intersectRay function for rays with vertical directions
202 template<typename RayCallback>
203 void intersectZAllignedRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& max_dist)
204 {
205 Cell cell = Cell::ComputeCell(ray.origin().x, ray.origin().y);
206 if (!cell.isValid())
207 return;
208 if (Node* node = nodes[cell.x][cell.y])
209 node->intersectRay(ray, intersectCallback, max_dist);
210 }
211};
212
213#undef CELL_SIZE
214#undef HGRID_MAP_SIZE
215
216#endif
#define ASSERT
Definition Errors.h:29
#define CELL_SIZE
Definition RegularGrid.h:36
Node & getGridFor(float fx, float fy)
Definition RegularGrid.h:95
bool contains(const T &value) const
Definition RegularGrid.h:77
void intersectRay(const G3D::Ray &ray, RayCallback &intersectCallback, float max_dist)
Node & getGrid(int x, int y)
void intersectZAllignedRay(const G3D::Ray &ray, RayCallback &intersectCallback, float &max_dist)
BIHWrap< GameObjectModel > * nodes[CELL_NUMBER][CELL_NUMBER]
Definition RegularGrid.h:41
void intersectRay(const G3D::Ray &ray, RayCallback &intersectCallback, float &max_dist, const G3D::Vector3 &end)
void intersectPoint(const G3D::Vector3 &point, IsectCallback &intersectCallback)
int size() const
Definition RegularGrid.h:78
void remove(const T &value)
Definition RegularGrid.h:62
G3D::Table< const GameObjectModel *, BIHWrap< GameObjectModel > * > MemberTable
Definition RegularGrid.h:38
void insert(const T &value)
Definition RegularGrid.h:53
static Node * makeNode(int, int)
Definition RegularGrid.h:19
bool operator==(const Cell &c2) const
Definition RegularGrid.h:83
static Cell ComputeCell(float fx, float fy)
Definition RegularGrid.h:85
bool isValid() const
Definition RegularGrid.h:91