OpenGothic
Open source reimplementation of Gothic I and II
Loading...
Searching...
No Matches
spaceindex.cpp
Go to the documentation of this file.
1#include "spaceindex.h"
2
3#include "world/objects/vob.h"
4
6 arr.clear();
7 index.clear();
8 dynamic.clear();
9 }
10
12 index.clear();
13 dynamic.clear();
14 }
15
17 arr.push_back(v);
18 index.reserve(arr.size());
19 index.clear();
20 dynamic.clear();
21 }
22
24 for(size_t i=0;i<arr.size();++i) {
25 if(arr[i]==v) {
26 arr[i] = arr.back();
27 arr.pop_back();
28 index.clear();
29 dynamic.clear();
30 return;
31 }
32 }
33 }
34
35bool BaseSpaceIndex::hasObject(const Vob* v) const {
36 if(v==nullptr)
37 return false;
38 for(size_t i=0;i<arr.size();++i)
39 if(arr[i]==v)
40 return true;
41 return false;
42 }
43
44void BaseSpaceIndex::find(const Tempest::Vec3& p, float R, const void* ctx, void (*func)(const void*, Vob*)) {
45 if(index.size()==0)
46 buildIndex();
47 for(auto& i:dynamic)
48 (*func)(ctx,i);
49 implFind(index.data(),index.size(),0,p,R,ctx,func);
50 }
51
52void BaseSpaceIndex::buildIndex() {
53 size_t cnt = 0;
54 index.resize(arr.size());
55 dynamic.clear();
56 for(size_t i=0; i<arr.size(); ++i) {
57 if(arr[i]->isDynamic()) {
58 dynamic.push_back(arr[i]);
59 } else {
60 index[cnt] = arr[i];
61 ++cnt;
62 }
63 }
64 index.resize(cnt);
65 buildIndex(index.data(),index.size(),0);
66 }
67
68void BaseSpaceIndex::buildIndex(Vob** v, size_t cnt, uint8_t depth) {
69 depth%=3;
70 sort(v,cnt,depth);
71 size_t mid = cnt/2;
72 if(mid>0) {
73 // [0..mid)
74 buildIndex(v,mid,uint8_t(depth+1u));
75 }
76 if(mid+1<cnt) {
77 // (mid..cnt)
78 buildIndex(v+mid+1,cnt-mid-1,uint8_t(depth+1u));
79 }
80 }
81
82void BaseSpaceIndex::sort(Vob** v, size_t cnt, uint8_t component) {
83 bool (*predicate)(const Vob* a, const Vob* b) = nullptr;
84 switch(component) {
85 case 0:
86 predicate = [](const Vob* a, const Vob* b){ return a->position().x < b->position().x; };
87 break;
88 case 1:
89 predicate = [](const Vob* a, const Vob* b){ return a->position().y < b->position().y; };
90 break;
91 case 2:
92 predicate = [](const Vob* a, const Vob* b){ return a->position().z < b->position().z; };
93 break;
94 }
95 std::sort(v,v+cnt,predicate);
96 }
97
98void BaseSpaceIndex::implFind(Vob** v, size_t cnt, uint8_t depth,
99 const Tempest::Vec3& p, float R, const void* ctx, void (*func)(const void*, Vob*)) {
100 if(cnt==0)
101 return;
102
103 auto mid = cnt/2;
104 auto pos = v[mid]->position();
105 auto qR = (R+675.0);//v[mid]->extendedSearchRadius());
106
107 if((pos-p).quadLength()<=qR*qR) {
108 func(ctx,v[mid]);
109 }
110
111 depth%=3;
112 switch(depth) {
113 case 0:
114 if(p.x-qR<=pos.x)
115 implFind(v,mid,uint8_t(depth+1u),p,R, ctx,func);
116 if(p.x+qR>=pos.x)
117 implFind(v+mid+1,cnt-mid-1,uint8_t(depth+1u),p,R, ctx,func);
118 break;
119 case 1:
120 if(p.y-qR<=pos.y)
121 implFind(v,mid,uint8_t(depth+1u),p,R, ctx,func);
122 if(p.y+qR>=pos.y)
123 implFind(v+mid+1,cnt-mid-1,uint8_t(depth+1u),p,R, ctx,func);
124 break;
125 case 2:
126 if(p.z-qR<=pos.z)
127 implFind(v,mid,uint8_t(depth+1u),p,R, ctx,func);
128 if(p.z+qR>=pos.z)
129 implFind(v+mid+1,cnt-mid-1,uint8_t(depth+1u),p,R, ctx,func);
130 break;
131 }
132 }
void del(Vob *v)
void find(const Tempest::Vec3 &p, float R, const void *ctx, void(*func)(const void *, Vob *))
bool hasObject(const Vob *v) const
void add(Vob *v)
Definition vob.h:11
Tempest::Vec3 position() const
Definition vob.cpp:57