ParticleSpawner: Fix crash when attaching to invisible entity
[oweals/minetest.git] / src / collision.h
index a4eca0dd821a6a9ce948c6019f1dc1c4f7730f13..87a50282870c11cb5075bce68a99a50f7c496a95 100644 (file)
@@ -1,6 +1,6 @@
 /*
-Minetest-c55
-Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
@@ -17,45 +17,72 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#ifndef COLLISION_HEADER
-#define COLLISION_HEADER
+#pragma once
 
 #include "irrlichttypes_bloated.h"
+#include <vector>
 
 class Map;
 class IGameDef;
+class Environment;
+class ActiveObject;
 
-struct collisionMoveResult
+enum CollisionType
 {
-       bool touching_ground;
-       bool collides;
-
-       collisionMoveResult():
-               touching_ground(false),
-               collides(false)
-       {}
+       COLLISION_NODE,
+       COLLISION_OBJECT,
 };
 
-// Moves using a single iteration; speed should not exceed pos_max_d/dtime
-collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
-               f32 pos_max_d, const core::aabbox3d<f32> &box_0,
-               f32 dtime, v3f &pos_f, v3f &speed_f);
-
-// Moves using as many iterations as needed
-collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
-               f32 pos_max_d, const core::aabbox3d<f32> &box_0,
-               f32 dtime, v3f &pos_f, v3f &speed_f);
-
-enum CollisionType
+enum CollisionAxis
 {
-       COLLISION_FALL
+       COLLISION_AXIS_NONE = -1,
+       COLLISION_AXIS_X,
+       COLLISION_AXIS_Y,
+       COLLISION_AXIS_Z,
 };
 
 struct CollisionInfo
 {
-       CollisionType t;
-       f32 speed;
+       CollisionInfo() = default;
+
+       CollisionType type = COLLISION_NODE;
+       CollisionAxis axis = COLLISION_AXIS_NONE;
+       v3s16 node_p = v3s16(-32768,-32768,-32768); // COLLISION_NODE
+       ActiveObject *object = nullptr; // COLLISION_OBJECT
+       v3f old_speed;
+       v3f new_speed;
+       int plane = -1;
 };
 
-#endif
+struct collisionMoveResult
+{
+       collisionMoveResult() = default;
+
+       bool touching_ground = false;
+       bool collides = false;
+       bool standing_on_object = false;
+       std::vector<CollisionInfo> collisions;
+};
+
+// Moves using a single iteration; speed should not exceed pos_max_d/dtime
+collisionMoveResult collisionMoveSimple(Environment *env,IGameDef *gamedef,
+               f32 pos_max_d, const aabb3f &box_0,
+               f32 stepheight, f32 dtime,
+               v3f *pos_f, v3f *speed_f,
+               v3f accel_f, ActiveObject *self=NULL,
+               bool collideWithObjects=true);
+
+// Helper function:
+// Checks for collision of a moving aabbox with a static aabbox
+// Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision
+// dtime receives time until first collision, invalid if -1 is returned
+CollisionAxis axisAlignedCollision(
+               const aabb3f &staticbox, const aabb3f &movingbox,
+               const v3f &speed, f32 *dtime);
 
+// Helper function:
+// Checks if moving the movingbox up by the given distance would hit a ceiling.
+bool wouldCollideWithCeiling(
+               const std::vector<aabb3f> &staticboxes,
+               const aabb3f &movingbox,
+               f32 y_increase, f32 d);