Skip to content

Commit 8800896

Browse files
sapierPilzAdam
sapier
authored andcommittedMar 27, 2013
Closed add object <-> object collision handling
1 parent 880d9e5 commit 8800896

10 files changed

+157
-33
lines changed
 

‎src/activeobject.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class ActiveObject
6161
}
6262

6363
virtual u8 getType() const = 0;
64-
64+
virtual bool getCollisionBox(aabb3f *toset) = 0;
6565
protected:
6666
u16 m_id; // 0 is invalid, "no id"
6767
};

‎src/collision.cpp

+70-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2323
#include "nodedef.h"
2424
#include "gamedef.h"
2525
#include "log.h"
26+
#include "environment.h"
27+
#include "serverobject.h"
2628
#include <vector>
29+
#include <set>
2730
#include "util/timetaker.h"
2831
#include "main.h" // g_profiler
2932
#include "profiler.h"
@@ -186,11 +189,12 @@ bool wouldCollideWithCeiling(
186189
}
187190

188191

189-
collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
192+
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
190193
f32 pos_max_d, const aabb3f &box_0,
191194
f32 stepheight, f32 dtime,
192195
v3f &pos_f, v3f &speed_f, v3f &accel_f)
193196
{
197+
Map *map = &env->getMap();
194198
//TimeTaker tt("collisionMoveSimple");
195199
ScopeProfiler sp(g_profiler, "collisionMoveSimple avg", SPT_AVG);
196200

@@ -215,6 +219,7 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
215219
std::vector<aabb3f> cboxes;
216220
std::vector<bool> is_unloaded;
217221
std::vector<bool> is_step_up;
222+
std::vector<bool> is_object;
218223
std::vector<int> bouncy_values;
219224
std::vector<v3s16> node_positions;
220225
{
@@ -256,6 +261,7 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
256261
is_step_up.push_back(false);
257262
bouncy_values.push_back(n_bouncy_value);
258263
node_positions.push_back(p);
264+
is_object.push_back(false);
259265
}
260266
}
261267
catch(InvalidPositionException &e)
@@ -267,14 +273,72 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
267273
is_step_up.push_back(false);
268274
bouncy_values.push_back(0);
269275
node_positions.push_back(p);
276+
is_object.push_back(false);
270277
}
271278
}
272279
} // tt2
273280

281+
{
282+
ScopeProfiler sp(g_profiler, "collisionMoveSimple objects avg", SPT_AVG);
283+
//TimeTaker tt3("collisionMoveSimple collect object boxes");
284+
285+
/* add object boxes to cboxes */
286+
287+
288+
std::list<ActiveObject*> objects;
289+
#ifndef SERVER
290+
ClientEnvironment *c_env = dynamic_cast<ClientEnvironment*>(env);
291+
if (c_env != 0)
292+
{
293+
f32 distance = speed_f.getLength();
294+
std::vector<DistanceSortedActiveObject> clientobjects;
295+
c_env->getActiveObjects(pos_f,distance * 1.5,clientobjects);
296+
for (int i=0; i < clientobjects.size(); i++)
297+
{
298+
objects.push_back((ActiveObject*)clientobjects[i].obj);
299+
}
300+
}
301+
else
302+
#endif
303+
{
304+
ServerEnvironment *s_env = dynamic_cast<ServerEnvironment*>(env);
305+
if (s_env != 0)
306+
{
307+
f32 distance = speed_f.getLength();
308+
std::set<u16> s_objects = s_env->getObjectsInsideRadius(pos_f,distance * 1.5);
309+
for (std::set<u16>::iterator iter = s_objects.begin(); iter != s_objects.end(); iter++)
310+
{
311+
ServerActiveObject *current = s_env->getActiveObject(*iter);
312+
objects.push_back((ActiveObject*)current);
313+
}
314+
}
315+
}
316+
317+
for (std::list<ActiveObject*>::const_iterator iter = objects.begin();iter != objects.end(); ++iter)
318+
{
319+
ActiveObject *object = *iter;
320+
321+
if (object != NULL)
322+
{
323+
aabb3f object_collisionbox;
324+
if (object->getCollisionBox(&object_collisionbox))
325+
{
326+
cboxes.push_back(object_collisionbox);
327+
is_unloaded.push_back(false);
328+
is_step_up.push_back(false);
329+
bouncy_values.push_back(0);
330+
node_positions.push_back(v3s16(0,0,0));
331+
is_object.push_back(true);
332+
}
333+
}
334+
}
335+
} //tt3
336+
274337
assert(cboxes.size() == is_unloaded.size());
275338
assert(cboxes.size() == is_step_up.size());
276339
assert(cboxes.size() == bouncy_values.size());
277340
assert(cboxes.size() == node_positions.size());
341+
assert(cboxes.size() == is_object.size());
278342

279343
/*
280344
Collision detection
@@ -386,7 +450,11 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
386450
is_collision = false;
387451

388452
CollisionInfo info;
389-
info.type = COLLISION_NODE;
453+
if (is_object[nearest_boxindex]) {
454+
info.type = COLLISION_OBJECT;
455+
}
456+
else
457+
info.type = COLLISION_NODE;
390458
info.node_p = node_positions[nearest_boxindex];
391459
info.bouncy = bouncy;
392460
info.old_speed = speed_f;

‎src/collision.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2525

2626
class Map;
2727
class IGameDef;
28+
class Environment;
2829

2930
enum CollisionType
3031
{
31-
COLLISION_NODE
32+
COLLISION_NODE,
33+
COLLISION_OBJECT,
3234
};
3335

3436
struct CollisionInfo
@@ -65,7 +67,7 @@ struct collisionMoveResult
6567
};
6668

6769
// Moves using a single iteration; speed should not exceed pos_max_d/dtime
68-
collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
70+
collisionMoveResult collisionMoveSimple(Environment *env,IGameDef *gamedef,
6971
f32 pos_max_d, const aabb3f &box_0,
7072
f32 stepheight, f32 dtime,
7173
v3f &pos_f, v3f &speed_f, v3f &accel_f);

‎src/content_cao.cpp

+19-2
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class TestCAO : public ClientActiveObject
174174

175175
void processMessage(const std::string &data);
176176

177+
bool getCollisionBox(aabb3f *toset) { return false; }
177178
private:
178179
scene::IMeshSceneNode *m_node;
179180
v3f m_position;
@@ -329,6 +330,7 @@ class ItemCAO : public ClientActiveObject
329330
std::string infoText()
330331
{return m_infotext;}
331332

333+
bool getCollisionBox(aabb3f *toset) { return false; }
332334
private:
333335
core::aabbox3d<f32> m_selection_box;
334336
scene::IMeshSceneNode *m_node;
@@ -643,6 +645,22 @@ class GenericCAO : public ClientActiveObject
643645
ClientActiveObject::registerType(getType(), create);
644646
}
645647

648+
bool getCollisionBox(aabb3f *toset) {
649+
if (m_prop.physical) {
650+
aabb3f retval;
651+
//update collision box
652+
toset->MinEdge = m_prop.collisionbox.MinEdge * BS;
653+
toset->MaxEdge = m_prop.collisionbox.MaxEdge * BS;
654+
655+
toset->MinEdge += m_position;
656+
toset->MaxEdge += m_position;
657+
658+
return true;
659+
}
660+
661+
return false;
662+
}
663+
646664
void initialize(const std::string &data)
647665
{
648666
infostream<<"GenericCAO: Got init data"<<std::endl;
@@ -1127,8 +1145,7 @@ class GenericCAO : public ClientActiveObject
11271145
v3f p_pos = m_position;
11281146
v3f p_velocity = m_velocity;
11291147
v3f p_acceleration = m_acceleration;
1130-
IGameDef *gamedef = env->getGameDef();
1131-
moveresult = collisionMoveSimple(&env->getMap(), gamedef,
1148+
moveresult = collisionMoveSimple(env,env->getGameDef(),
11321149
pos_max_d, box, stepheight, dtime,
11331150
p_pos, p_velocity, p_acceleration);
11341151
// Apply results

‎src/content_sao.cpp

+34-4
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ class DummyLoadSAO : public ServerActiveObject
6464
infostream<<"DummyLoadSAO step"<<std::endl;
6565
}
6666

67+
bool getCollisionBox(aabb3f *toset) {
68+
return false;
69+
}
70+
6771
private:
6872
};
6973

@@ -132,6 +136,10 @@ class TestSAO : public ServerActiveObject
132136
}
133137
}
134138

139+
bool getCollisionBox(aabb3f *toset) {
140+
return false;
141+
}
142+
135143
private:
136144
float m_timer1;
137145
float m_age;
@@ -208,8 +216,7 @@ class ItemSAO : public ServerActiveObject
208216
v3f pos_f_old = pos_f;
209217
v3f accel_f = v3f(0,0,0);
210218
f32 stepheight = 0;
211-
IGameDef *gamedef = m_env->getGameDef();
212-
moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
219+
moveresult = collisionMoveSimple(m_env,m_env->getGameDef(),
213220
pos_max_d, box, stepheight, dtime,
214221
pos_f, m_speed_f, accel_f);
215222

@@ -314,6 +321,10 @@ class ItemSAO : public ServerActiveObject
314321
return 0;
315322
}
316323

324+
bool getCollisionBox(aabb3f *toset) {
325+
return false;
326+
}
327+
317328

318329
private:
319330
std::string m_itemstring;
@@ -490,8 +501,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
490501
v3f p_pos = m_base_position;
491502
v3f p_velocity = m_velocity;
492503
v3f p_acceleration = m_acceleration;
493-
IGameDef *gamedef = m_env->getGameDef();
494-
moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
504+
moveresult = collisionMoveSimple(m_env,m_env->getGameDef(),
495505
pos_max_d, box, stepheight, dtime,
496506
p_pos, p_velocity, p_acceleration);
497507
// Apply results
@@ -880,6 +890,22 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
880890
m_messages_out.push_back(aom);
881891
}
882892

893+
bool LuaEntitySAO::getCollisionBox(aabb3f *toset) {
894+
if (m_prop.physical)
895+
{
896+
//update collision box
897+
toset->MinEdge = m_prop.collisionbox.MinEdge * BS;
898+
toset->MaxEdge = m_prop.collisionbox.MaxEdge * BS;
899+
900+
toset->MinEdge += m_base_position;
901+
toset->MaxEdge += m_base_position;
902+
903+
return true;
904+
}
905+
906+
return false;
907+
}
908+
883909
/*
884910
PlayerSAO
885911
*/
@@ -1434,3 +1460,7 @@ std::string PlayerSAO::getPropertyPacket()
14341460
return gob_cmd_set_properties(m_prop);
14351461
}
14361462

1463+
bool PlayerSAO::getCollisionBox(aabb3f *toset) {
1464+
//player collision handling is already done clientside no need to do it twice
1465+
return false;
1466+
}

‎src/content_sao.h

+3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class LuaEntitySAO : public ServerActiveObject
7878
void setSprite(v2s16 p, int num_frames, float framelength,
7979
bool select_horiz_by_yawpitch);
8080
std::string getName();
81+
bool getCollisionBox(aabb3f *toset);
8182
private:
8283
std::string getPropertyPacket();
8384
void sendPosition(bool do_interpolate, bool is_movement_end);
@@ -235,6 +236,8 @@ class PlayerSAO : public ServerActiveObject
235236
m_is_singleplayer = is_singleplayer;
236237
}
237238

239+
bool getCollisionBox(aabb3f *toset);
240+
238241
private:
239242
std::string getPropertyPacket();
240243

‎src/environment.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2096,7 +2096,7 @@ void ClientEnvironment::step(float dtime)
20962096
Move the lplayer.
20972097
This also does collision detection.
20982098
*/
2099-
lplayer->move(dtime_part, *m_map, position_max_increment,
2099+
lplayer->move(dtime_part, this, position_max_increment,
21002100
&player_collisions);
21012101
}
21022102
}

‎src/localplayer.cpp

+20-18
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2525
#include "gamedef.h"
2626
#include "nodedef.h"
2727
#include "settings.h"
28+
#include "environment.h"
2829
#include "map.h"
2930
#include "util/numeric.h"
3031

@@ -57,9 +58,10 @@ LocalPlayer::~LocalPlayer()
5758
{
5859
}
5960

60-
void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
61+
void LocalPlayer::move(f32 dtime, ClientEnvironment *env, f32 pos_max_d,
6162
std::list<CollisionInfo> *collision_info)
6263
{
64+
Map *map = &env->getMap();
6365
INodeDefManager *nodemgr = m_gamedef->ndef();
6466

6567
v3f position = getPosition();
@@ -97,15 +99,15 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
9799
if(in_liquid)
98100
{
99101
v3s16 pp = floatToInt(position + v3f(0,BS*0.1,0), BS);
100-
in_liquid = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
101-
liquid_viscosity = nodemgr->get(map.getNode(pp).getContent()).liquid_viscosity;
102+
in_liquid = nodemgr->get(map->getNode(pp).getContent()).isLiquid();
103+
liquid_viscosity = nodemgr->get(map->getNode(pp).getContent()).liquid_viscosity;
102104
}
103105
// If not in liquid, the threshold of going in is at lower y
104106
else
105107
{
106108
v3s16 pp = floatToInt(position + v3f(0,BS*0.5,0), BS);
107-
in_liquid = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
108-
liquid_viscosity = nodemgr->get(map.getNode(pp).getContent()).liquid_viscosity;
109+
in_liquid = nodemgr->get(map->getNode(pp).getContent()).isLiquid();
110+
liquid_viscosity = nodemgr->get(map->getNode(pp).getContent()).liquid_viscosity;
109111
}
110112
}
111113
catch(InvalidPositionException &e)
@@ -118,7 +120,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
118120
*/
119121
try{
120122
v3s16 pp = floatToInt(position + v3f(0,0,0), BS);
121-
in_liquid_stable = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
123+
in_liquid_stable = nodemgr->get(map->getNode(pp).getContent()).isLiquid();
122124
}
123125
catch(InvalidPositionException &e)
124126
{
@@ -132,8 +134,8 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
132134
try {
133135
v3s16 pp = floatToInt(position + v3f(0,0.5*BS,0), BS);
134136
v3s16 pp2 = floatToInt(position + v3f(0,-0.2*BS,0), BS);
135-
is_climbing = ((nodemgr->get(map.getNode(pp).getContent()).climbable ||
136-
nodemgr->get(map.getNode(pp2).getContent()).climbable) && !free_move);
137+
is_climbing = ((nodemgr->get(map->getNode(pp).getContent()).climbable ||
138+
nodemgr->get(map->getNode(pp2).getContent()).climbable) && !free_move);
137139
}
138140
catch(InvalidPositionException &e)
139141
{
@@ -197,7 +199,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
197199

198200
v3f accel_f = v3f(0,0,0);
199201

200-
collisionMoveResult result = collisionMoveSimple(&map, m_gamedef,
202+
collisionMoveResult result = collisionMoveSimple(env, m_gamedef,
201203
pos_max_d, playerbox, player_stepheight, dtime,
202204
position, m_speed, accel_f);
203205

@@ -219,15 +221,15 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
219221
*/
220222
v3s16 current_node = floatToInt(position - v3f(0,BS/2,0), BS);
221223
if(m_sneak_node_exists &&
222-
nodemgr->get(map.getNodeNoEx(m_old_node_below)).name == "air" &&
224+
nodemgr->get(map->getNodeNoEx(m_old_node_below)).name == "air" &&
223225
m_old_node_below_type != "air")
224226
{
225227
// Old node appears to have been removed; that is,
226228
// it wasn't air before but now it is
227229
m_need_to_get_new_sneak_node = false;
228230
m_sneak_node_exists = false;
229231
}
230-
else if(nodemgr->get(map.getNodeNoEx(current_node)).name != "air")
232+
else if(nodemgr->get(map->getNodeNoEx(current_node)).name != "air")
231233
{
232234
// We are on something, so make sure to recalculate the sneak
233235
// node.
@@ -267,10 +269,10 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
267269

268270
try{
269271
// The node to be sneaked on has to be walkable
270-
if(nodemgr->get(map.getNode(p)).walkable == false)
272+
if(nodemgr->get(map->getNode(p)).walkable == false)
271273
continue;
272274
// And the node above it has to be nonwalkable
273-
if(nodemgr->get(map.getNode(p+v3s16(0,1,0))).walkable == true)
275+
if(nodemgr->get(map->getNode(p+v3s16(0,1,0))).walkable == true)
274276
continue;
275277
}
276278
catch(InvalidPositionException &e)
@@ -331,7 +333,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
331333
{
332334
camera_barely_in_ceiling = false;
333335
v3s16 camera_np = floatToInt(getEyePosition(), BS);
334-
MapNode n = map.getNodeNoEx(camera_np);
336+
MapNode n = map->getNodeNoEx(camera_np);
335337
if(n.getContent() != CONTENT_IGNORE){
336338
if(nodemgr->get(n).walkable && nodemgr->get(n).solidness == 2){
337339
camera_barely_in_ceiling = true;
@@ -343,21 +345,21 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
343345
Update the node last under the player
344346
*/
345347
m_old_node_below = floatToInt(position - v3f(0,BS/2,0), BS);
346-
m_old_node_below_type = nodemgr->get(map.getNodeNoEx(m_old_node_below)).name;
348+
m_old_node_below_type = nodemgr->get(map->getNodeNoEx(m_old_node_below)).name;
347349

348350
/*
349351
Check properties of the node on which the player is standing
350352
*/
351-
const ContentFeatures &f = nodemgr->get(map.getNodeNoEx(getStandingNodePos()));
353+
const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(getStandingNodePos()));
352354
// Determine if jumping is possible
353355
m_can_jump = touching_ground && !in_liquid;
354356
if(itemgroup_get(f.groups, "disable_jump"))
355357
m_can_jump = false;
356358
}
357359

358-
void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d)
360+
void LocalPlayer::move(f32 dtime, ClientEnvironment *env, f32 pos_max_d)
359361
{
360-
move(dtime, map, pos_max_d, NULL);
362+
move(dtime, env, pos_max_d, NULL);
361363
}
362364

363365
void LocalPlayer::applyControl(float dtime)

‎src/localplayer.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2323
#include "player.h"
2424
#include <list>
2525

26+
class ClientEnvironment;
27+
2628
class LocalPlayer : public Player
2729
{
2830
public:
@@ -38,9 +40,9 @@ class LocalPlayer : public Player
3840

3941
v3f overridePosition;
4042

41-
void move(f32 dtime, Map &map, f32 pos_max_d,
43+
void move(f32 dtime, ClientEnvironment *env, f32 pos_max_d,
4244
std::list<CollisionInfo> *collision_info);
43-
void move(f32 dtime, Map &map, f32 pos_max_d);
45+
void move(f32 dtime, ClientEnvironment *env, f32 pos_max_d);
4446

4547
void applyControl(float dtime);
4648

‎src/particles.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ void Particle::step(float dtime, ClientEnvironment &env)
138138
v3f p_pos = m_pos*BS;
139139
v3f p_velocity = m_velocity*BS;
140140
v3f p_acceleration = m_acceleration*BS;
141-
collisionMoveSimple(&env.getClientMap(), m_gamedef,
141+
collisionMoveSimple(&env, m_gamedef,
142142
BS*0.5, box,
143143
0, dtime,
144144
p_pos, p_velocity, p_acceleration);

0 commit comments

Comments
 (0)
Please sign in to comment.