@@ -25,15 +25,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
25
25
26
26
static constexpr float granularity = 16.0 * BS;
27
27
28
+ static v3s16 getChunkPos (const v3f &pos)
Has conversations. Original line has conversations.
29
+ {
30
+ return v3s16 (
31
+ std::floor (pos.X / granularity),
32
+ std::floor (pos.Y / granularity),
33
+ std::floor (pos.Z / granularity));
34
+ }
35
+
28
36
static aabb3s16 calcBox (const aabb3f &cb)
29
37
{
30
- return aabb3s16 (
31
- std::floor (cb.MinEdge .X / granularity),
32
- std::floor (cb.MinEdge .Y / granularity),
33
- std::floor (cb.MinEdge .Z / granularity),
34
- std::ceil (cb.MaxEdge .X / granularity),
35
- std::ceil (cb.MaxEdge .Y / granularity),
36
- std::ceil (cb.MaxEdge .Z / granularity));
38
+ return { getChunkPos (cb.MinEdge ), getChunkPos (cb.MaxEdge ) };
37
39
}
38
40
39
41
void ServerActiveObjectMap::addObject (ServerActiveObject *object)
@@ -46,10 +48,12 @@ void ServerActiveObjectMap::addObject(ServerActiveObject *object)
46
48
" object ID in use: " + std::to_string (id));
47
49
w.object = object;
48
50
w.has_box = w.object ->getCollisionBox (&cb);
51
+ w.pos = getChunkPos (w.object ->getBasePosition ());
49
52
if (w.has_box ) {
50
53
w.box = calcBox (cb);
51
54
addObjectRefs (id, w.box );
52
55
}
56
+ addObjectRef (id, w.pos );
53
57
objects.emplace (id, w);
54
58
}
55
59
@@ -61,6 +65,7 @@ ServerActiveObject *ServerActiveObjectMap::removeObject(u16 id)
61
65
Wrapper w = pw->second ;
62
66
if (w.has_box )
63
67
removeObjectRefs (id, w.box );
68
+ removeObjectRef (id, w.pos );
64
69
objects.erase (pw);
65
70
return w.object ;
66
71
}
@@ -79,19 +84,22 @@ void ServerActiveObjectMap::updateObject(u16 id)
79
84
return ;
80
85
}
81
86
Wrapper &w = pw->second ;
87
+ v3s16 pos = getChunkPos (w.object ->getBasePosition ());
82
88
aabb3f cb;
83
89
aabb3s16 box;
84
90
bool has_box = w.object ->getCollisionBox (&cb);
85
91
if (has_box)
86
92
box = calcBox (cb);
87
- if (w.has_box && has_box && w.box == box)
93
+ if (w.has_box && has_box && w.box == box && pos == w. pos )
88
94
return ;
89
95
if (w.has_box )
90
96
removeObjectRefs (id, w.box );
97
+ removeObjectRef (id, w.pos );
91
98
w.box = box;
92
99
w.has_box = has_box;
93
100
if (w.has_box )
94
101
addObjectRefs (id, w.box );
102
+ addObjectRef (id, w.pos );
95
103
}
96
104
97
105
void ServerActiveObjectMap::updateObject (ServerActiveObject *object)
@@ -151,28 +159,38 @@ std::unordered_set<u16> ServerActiveObjectMap::getObjectsNearBox(const aabb3s16
151
159
return result;
152
160
}
153
161
162
+ void ServerActiveObjectMap::addObjectRef (u16 id, v3s16 pos)
163
+ {
164
+ refmap.emplace (pos, id);
165
+ }
166
+
167
+ void ServerActiveObjectMap::removeObjectRef (u16 id, v3s16 pos)
168
+ {
169
+ auto bounds = refmap.equal_range (pos);
170
+ for (auto iter = bounds.first ; iter != bounds.second ;) {
171
+ if (iter->second == id)
172
+ iter = refmap.erase (iter);
173
+ else
174
+ ++iter;
175
+ }
176
+ }
177
+
154
178
void ServerActiveObjectMap::addObjectRefs (u16 id, const aabb3s16 &box)
155
179
{
156
180
v3s16 p;
157
181
for (p.Z = box.MinEdge .Z ; p.Z <= box.MaxEdge .Z ; p.Z ++)
158
182
for (p.Y = box.MinEdge .Y ; p.Y <= box.MaxEdge .Y ; p.Y ++)
159
183
for (p.X = box.MinEdge .X ; p.X <= box.MaxEdge .X ; p.X ++)
160
- refmap. emplace (p, id );
184
+ addObjectRef (id, p );
161
185
}
162
186
163
187
void ServerActiveObjectMap::removeObjectRefs (u16 id, const aabb3s16 &box)
164
188
{
165
189
v3s16 p;
166
190
for (p.Z = box.MinEdge .Z ; p.Z <= box.MaxEdge .Z ; p.Z ++)
167
191
for (p.Y = box.MinEdge .Y ; p.Y <= box.MaxEdge .Y ; p.Y ++)
168
- for (p.X = box.MinEdge .X ; p.X <= box.MaxEdge .X ; p.X ++) {
169
- auto bounds = refmap.equal_range (p);
170
- for (auto iter = bounds.first ; iter != bounds.second ;)
171
- if (iter->second == id)
172
- refmap.erase (iter++);
173
- else
174
- ++iter;
175
- }
192
+ for (p.X = box.MinEdge .X ; p.X <= box.MaxEdge .X ; p.X ++)
193
+ removeObjectRef (id, p);
176
194
}
177
195
178
196
bool ServerActiveObjectMap::isFreeId (u16 id)