]> git.lizzy.rs Git - dragonfireclient.git/blob - src/server/serveractiveobjectmap.h
Add online content repository
[dragonfireclient.git] / src / server / serveractiveobjectmap.h
1 /*
2 Minetest
3 Copyright (C) 2018 numZero, Lobachevsky Vitaly <numzer0@yandex.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #pragma once
21 #include <unordered_set>
22 #include <unordered_map>
23 #include <vector>
24 #include "irr_v3d.h"
25 #include "irr_aabb3d.h"
26
27 class ServerActiveObject;
28
29 /*!
30  * The class to speed up collision tests.
31  *
32  * @note It stores any objects but only those that has valid collision box
33  * (`physical` Lua entities) are actually processed.
34  * @note It uses world coordinate units, i.e. node size is always BS.
35  */
36 struct ServerActiveObjectMap
37 {
38         struct Wrapper
39         {
40                 ServerActiveObject *object;
41                 aabb3s16 box;
42                 v3s16 pos;
43                 bool has_box;
44         };
45
46         /*!
47          * Adds object to the map. It must have valid ID.
48          *
49          * If an object with the same ID already exists in the map,
50          * std::logic_error is thrown.
51          */
52         void addObject(ServerActiveObject *object);
53
54         /*!
55          * Removes object from the map. The pointer must be valid.
56          * See `removeObject(u16)` for details.
57          */
58         void removeObject(ServerActiveObject *object);
59
60         /*!
61          * Removes object from the map.
62          *
63          * If the object is not found, the call is ignored.
64          * The function never throws, unless the underlying container throws.
65          */
66         ServerActiveObject *removeObject(u16 id);
67
68         /*!
69          * Updates object metadata stored in the map.
70          * See `updateObject(u16)` for details.
71          */
72         void updateObject(ServerActiveObject *object);
73
74         /*!
75          * Updates object metadata stored in the map.
76          *
77          * The metadata includes (approximate) absolute collision box and
78          * its existence (`physical` property for Lua entities).
79          * This function must be called after each change of these properties,
80          * including each object movement.
81          */
82         void updateObject(u16 id);
83
84         /*!
85          * Returns the object with given ID, if any.
86          * Returns NULL otherwise.
87          */
88         ServerActiveObject *getObject(u16 id) const;
89
90         /*!
91          * Checks if the given ID is free and valid (i.e. non-zero).
92          */
93         bool isFreeId(u16 id);
94
95         /*!
96          * Returns a free ID, if any. Returns 0 in the case of failure.
97          *
98          * @note This function doesn't reserve the ID; it remains free until
99          * an object with that ID is added.
100          * @note This function tries to reclaim freed IDs as late as possible.
101          * However, there is no guarantee.
102          */
103         u16 getFreeId();
104
105         /*!
106          * Returns a list of objects whose base position is at distance less
107          * than @p radius from @p pos.
108          *
109          * @note Due to inexact nature of floating-point computations, it is
110          * undefined whether an object lying exactly at the boundary is included
111          * in the list or not.
112          */
113         std::vector<u16> getObjectsInsideRadius(v3f pos, float radius);
114
115         /*!
116          * Returns a list of objects whose collision box intersects with @p box
117          *
118          * @note Due to inexact nature of floating-point computations, it is
119          * undefined whether an object lying exactly at the boundary is included
120          * in the list or not.
121          */
122         std::vector<u16> getObjectsTouchingBox(const aabb3f &box);
123
124         /*!
125          * Returns count of objects in the map.
126          */
127         std::size_t size() const { return objects.size(); }
128
129         /*!
130          * Returns reference to the underlying container.
131          */
132         const std::unordered_map<u16, Wrapper> &getObjects() const { return objects; }
133
134 private:
135         void addObjectRef(u16 id, v3s16 pos);
136         void removeObjectRef(u16 id, v3s16 pos);
137         void addObjectRefs(u16 id, const aabb3s16 &box);
138         void removeObjectRefs(u16 id, const aabb3s16 &box);
139         std::unordered_set<u16> getObjectsNearBox(const aabb3s16 &box);
140
141         std::unordered_map<u16, Wrapper> objects;
142         std::unordered_multimap<v3s16, u16> refmap;
143 };