Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
DynamicTree.cpp
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#include "DynamicTree.h"
7//#include "QuadTree.h"
8//#include "RegularGrid.h"
10
11#include "Log.h"
12#include "RegularGrid.h"
13#include "Timer.h"
14#include "GameObjectModel.h"
15#include "ModelInstance.h"
16
17#include <G3D/AABox.h>
18#include <G3D/Ray.h>
19#include <G3D/Vector3.h>
20
22
23namespace {
24
25int CHECK_TREE_PERIOD = 200;
26
27} // namespace
28
29template<> struct HashTrait< GameObjectModel>{
30 static size_t hashCode(const GameObjectModel& g) { return (size_t)(void*)&g; }
31};
32
33template<> struct PositionTrait< GameObjectModel> {
34 static void getPosition(const GameObjectModel& g, G3D::Vector3& p) { p = g.getPosition(); }
35};
36
37template<> struct BoundsTrait< GameObjectModel> {
38 static void getBounds(const GameObjectModel& g, G3D::AABox& out) { out = g.getBounds();}
39 static void getBounds2(const GameObjectModel* g, G3D::AABox& out) { out = g->getBounds();}
40};
41
42/*
43static bool operator == (const GameObjectModel& mdl, const GameObjectModel& mdl2){
44 return &mdl == &mdl2;
45}
46*/
47
49
50struct DynTreeImpl : public ParentTree/*, public Intersectable*/
51{
54
56 rebalance_timer(CHECK_TREE_PERIOD),
58 {
59 }
60
61 void insert(const Model& mdl)
62 {
63 base::insert(mdl);
65 }
66
67 void remove(const Model& mdl)
68 {
69 base::remove(mdl);
71 }
72
73 void balance()
74 {
77 }
78
79 void update(uint32 difftime)
80 {
81 if (!size())
82 return;
83
84 rebalance_timer.Update(difftime);
85 if (rebalance_timer.Passed())
86 {
87 rebalance_timer.Reset(CHECK_TREE_PERIOD);
88 if (unbalanced_times > 0)
89 balance();
90 }
91 }
92
95};
96
98
100{
101 delete impl;
102}
103
105{
106 impl->insert(mdl);
107}
108
110{
111 impl->remove(mdl);
112}
113
115{
116 return impl->contains(mdl);
117}
118
120{
121 impl->balance();
122}
123
125{
126 return impl->size();
127}
128
130{
131 impl->update(t_diff);
132}
133
135{
138 explicit DynamicTreeIntersectionCallback(uint32 phasemask) : did_hit(false), phase_mask(phasemask) { }
139 bool operator()(const G3D::Ray& r, const GameObjectModel& obj, float& distance)
140 {
141 did_hit = obj.intersectRay(r, distance, true, phase_mask);
142 return did_hit;
143 }
144 bool didHit() const { return did_hit;}
145};
146
148{
152 {
153 SF_LOG_DEBUG("maps", "Dynamic Intersection log");
154 }
155 bool operator()(const G3D::Ray& r, const GameObjectModel& obj, float& distance)
156 {
157 SF_LOG_DEBUG("maps", "testing intersection with %s", obj.name.c_str());
158 bool hit = obj.intersectRay(r, distance, true, phase_mask);
159 if (hit)
160 {
161 did_hit = true;
162 SF_LOG_DEBUG("maps", "result: intersects");
163 }
164 return hit;
165 }
166 bool didHit() const { return did_hit;}
167};
168
169bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray& ray,
170 const G3D::Vector3& endPos, float& maxDist) const
171{
172 float distance = maxDist;
173 DynamicTreeIntersectionCallback callback(phasemask);
174 impl->intersectRay(ray, callback, distance, endPos);
175 if (callback.didHit())
176 maxDist = distance;
177 return callback.didHit();
178}
179
180bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const G3D::Vector3& startPos,
181 const G3D::Vector3& endPos, G3D::Vector3& resultHit,
182 float modifyDist) const
183{
184 bool result = false;
185 float maxDist = (endPos - startPos).magnitude();
186 // valid map coords should *never ever* produce float overflow, but this would produce NaNs too
187 ASSERT(maxDist < std::numeric_limits<float>::max());
188 // prevent NaN values which can cause BIH intersection to enter infinite loop
189 if (maxDist < 1e-10f)
190 {
191 resultHit = endPos;
192 return false;
193 }
194 G3D::Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1
195 G3D::Ray ray(startPos, dir);
196 float dist = maxDist;
197 if (getIntersectionTime(phasemask, ray, endPos, dist))
198 {
199 resultHit = startPos + dir * dist;
200 if (modifyDist < 0)
201 {
202 if ((resultHit - startPos).magnitude() > -modifyDist)
203 resultHit = resultHit + dir*modifyDist;
204 else
205 resultHit = startPos;
206 }
207 else
208 resultHit = resultHit + dir*modifyDist;
209
210 result = true;
211 }
212 else
213 {
214 resultHit = endPos;
215 result = false;
216 }
217 return result;
218}
219
220bool DynamicMapTree::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const
221{
222 G3D::Vector3 v1(x1, y1, z1), v2(x2, y2, z2);
223
224 float maxDist = (v2 - v1).magnitude();
225
226 if (!G3D::fuzzyGt(maxDist, 0) )
227 return true;
228
229 G3D::Ray r(v1, (v2-v1) / maxDist);
230 DynamicTreeIntersectionCallback callback(phasemask);
231 impl->intersectRay(r, callback, maxDist, v2);
232
233 return !callback.did_hit;
234}
235
236float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const
237{
238 G3D::Vector3 v(x, y, z);
239 G3D::Ray r(v, G3D::Vector3(0, 0, -1));
240 DynamicTreeIntersectionCallback callback(phasemask);
241 impl->intersectZAllignedRay(r, callback, maxSearchDist);
242
243 if (callback.didHit())
244 return v.z - maxSearchDist;
245 else
246 return -G3D::inf();
247}
std::uint32_t uint32
Definition Define.h:77
RegularGrid2D< GameObjectModel, BIHWrap< GameObjectModel > > ParentTree
#define ASSERT
Definition Errors.h:29
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
bool contains(const GameObjectModel &) const
void insert(const GameObjectModel &)
bool getIntersectionTime(uint32 phasemask, const G3D::Ray &ray, const G3D::Vector3 &endPos, float &maxDist) const
bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const
DynTreeImpl * impl
Definition DynamicTree.h:23
void update(uint32 diff)
int size() const
float getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const
bool getObjectHitPos(uint32 phasemask, const G3D::Vector3 &pPos1, const G3D::Vector3 &pPos2, G3D::Vector3 &pResultHitPos, float pModifyDist) const
void remove(const GameObjectModel &)
const G3D::AABox & getBounds() const
const G3D::Vector3 & getPosition() const
bool intersectRay(const G3D::Ray &Ray, float &MaxDist, bool StopAtFirstHit, uint32 ph_mask) const
static void getBounds(const GameObjectModel &g, G3D::AABox &out)
static void getBounds2(const GameObjectModel *g, G3D::AABox &out)
void remove(const Model &mdl)
TimeTrackerSmall rebalance_timer
ParentTree base
void insert(const Model &mdl)
void update(uint32 difftime)
GameObjectModel Model
bool operator()(const G3D::Ray &r, const GameObjectModel &obj, float &distance)
DynamicTreeIntersectionCallback_WithLogger(uint32 phasemask)
DynamicTreeIntersectionCallback(uint32 phasemask)
bool operator()(const G3D::Ray &r, const GameObjectModel &obj, float &distance)
static size_t hashCode(const GameObjectModel &g)
static void getPosition(const GameObjectModel &g, G3D::Vector3 &p)