Explorar o código

fix overlap_test and raycast

mikymod %!s(int64=12) %!d(string=hai) anos
pai
achega
9212d675e9

+ 1 - 5
engine/lua/LuaPhysicsWorld.cpp

@@ -91,7 +91,7 @@ CE_EXPORT int physics_world_overlap_test(lua_State* L)
 	stack.push_table();
 	for (uint32_t i = 0; i < actors.size(); i++)
 	{
-		stack.push_key_begin(i);
+		stack.push_key_begin(i+1);
 		stack.push_actor(actors[i]);
 		stack.push_key_end();
 	}
@@ -119,10 +119,6 @@ void load_physics_world(LuaEnvironment& env)
 	env.load_module_enum("ShapeType", "PLANE",						ShapeType::PLANE);
 	env.load_module_enum("ShapeType", "CONVEX_MESH",				ShapeType::CONVEX_MESH);
 
-	// SceneQuery types
-	env.load_module_enum("SceneQueryType", "RAYCAST",				SceneQueryType::RAYCAST);
-	env.load_module_enum("SceneQueryType", "OVERLAP",				SceneQueryType::OVERLAP);
-
 	// SceneQuery modes
 	env.load_module_enum("CollisionMode", "CLOSEST",				CollisionMode::CLOSEST);
 	env.load_module_enum("CollisionMode", "ANY",					CollisionMode::ANY);

+ 42 - 17
engine/lua/LuaRaycast.cpp

@@ -27,6 +27,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "LuaStack.h"
 #include "LuaEnvironment.h"
 #include "Raycast.h"
+#include "Log.h"
 
 namespace crown
 {
@@ -41,25 +42,50 @@ CE_EXPORT int raycast_cast(lua_State* L)
 	Vector3 dir = stack.get_vector3(3);
 	float length = stack.get_float(4);
 	
-	raycast->cast(from, dir, length);
+	List<RaycastHit> hits(default_allocator());
 
-	return 0;
-}
-
-//-----------------------------------------------------------------------------
-CE_EXPORT int raycast_sync_cast(lua_State* L)
-{
-	LuaStack stack(L);
+	raycast->cast(from, dir, length, hits);
 
-	Raycast* raycast = stack.get_raycast(1);
-	Vector3 from = stack.get_vector3(2);
-	Vector3 dir = stack.get_vector3(3);
-	float length = stack.get_float(4);
-	
-	Actor* actor = raycast->sync_cast(from, dir, length);
+	switch(raycast->mode())
+	{
+		case CollisionMode::CLOSEST:
+		{
+			bool hit = hits.size() > 0 ? true : false;
+			stack.push_bool(hit);
+			break;
+		}
+		case CollisionMode::ANY:
+		{
+			bool hit = hits.size() > 0 ? true : false;
+			stack.push_bool(hit);
+			if (hit)
+			{
+				stack.push_vector3(hits[0].position);
+				stack.push_float(hits[0].distance);
+				stack.push_vector3(hits[0].normal);
+				stack.push_actor(hits[0].actor);
+				return 5;
+			}
+			break;
+		}
+		case CollisionMode::ALL:
+		{
+			stack.push_table();
+			for (uint32_t i = 0; i < hits.size(); i++)
+			{
+				stack.push_key_begin(i+1);
+				
+				stack.push_table();
+				stack.push_key_begin("position"); stack.push_vector3(hits[i].position);	stack.push_key_end();
+				stack.push_key_begin("distance"); stack.push_float(hits[i].distance); stack.push_key_end();
+				stack.push_key_begin("normal"); stack.push_vector3(hits[i].normal); stack.push_key_end();
+				stack.push_key_begin("actor"); stack.push_actor(hits[i].actor); stack.push_key_end();
 
-	if (actor) stack.push_actor(actor);
-	else stack.push_nil();
+				stack.push_key_end();
+			}
+			break;
+		}
+	}
 
 	return 1;
 }
@@ -68,7 +94,6 @@ CE_EXPORT int raycast_sync_cast(lua_State* L)
 void load_raycast(LuaEnvironment& env)
 {
 	env.load_module_function("Raycast", "cast",	raycast_cast);
-	env.load_module_function("Raycast", "sync_cast", raycast_sync_cast);
 }
 
 } // namespace crown

+ 0 - 10
engine/physics/PhysicsTypes.h

@@ -128,16 +128,6 @@ struct CollisionType
 	};
 };
 
-//-----------------------------------------------------------------------------
-struct SceneQueryType
-{
-	enum Enum
-	{
-		RAYCAST,
-		OVERLAP
-	};
-};
-
 //-----------------------------------------------------------------------------
 struct CollisionMode
 {

+ 1 - 1
engine/physics/PhysicsWorld.cpp

@@ -387,7 +387,7 @@ void PhysicsWorld::clear_kinematic(ActorId id)
 
 //-----------------------------------------------------------------------------
 void PhysicsWorld::overlap_test(const char* callback, CollisionType::Enum filter, ShapeType::Enum type,
-								const Vector3& pos, const Quaternion& rot, const Vector3& size, List<Actor*> actors)
+								const Vector3& pos, const Quaternion& rot, const Vector3& size, List<Actor*>& actors)
 {
 	PxTransform transform(PxVec3(pos.x, pos.y, pos.z), PxQuat(rot.v.x, rot.v.y, rot.v.z, rot.w));
 

+ 1 - 1
engine/physics/PhysicsWorld.h

@@ -108,7 +108,7 @@ public:
 
 	/// Finds all actors in the physics world that are in a particular shape (supported: spheres, capsules and boxes)
 	void						overlap_test(const char* callback, CollisionType::Enum filter, ShapeType::Enum type,
-											const Vector3& pos, const Quaternion& rot, const Vector3& size, List<Actor*> actors);
+											const Vector3& pos, const Quaternion& rot, const Vector3& size, List<Actor*>& actors);
 
 	void						update(float dt);
 

+ 24 - 42
engine/physics/Raycast.cpp

@@ -35,15 +35,15 @@ namespace crown
 {
 
 //-------------------------------------------------------------------------
-Raycast::Raycast(PxScene* scene, EventStream& events, const char* callback, CollisionMode::Enum mode, CollisionType::Enum filter)
+Raycast::Raycast(PxScene* scene, EventStream& events, const char* callback, CollisionMode::Enum mode, CollisionType::Enum type)
 	: m_scene(scene)
 	, m_buffer(m_hits, CE_MAX_RAY_INTERSECTIONS)
 	, m_events(events)
 	, m_callback(callback)
 	, m_mode(mode)
-	, m_filter(filter)
+	, m_type(type)
 {
-	switch (m_filter)
+	switch (m_type)
 	{
 		case CollisionType::BOTH: break;
 		case CollisionType::STATIC: m_fd.flags = PxQueryFlag::eSTATIC; break;
@@ -59,57 +59,39 @@ Raycast::Raycast(PxScene* scene, EventStream& events, const char* callback, Coll
 }
 
 //-------------------------------------------------------------------------
-void Raycast::cast(const Vector3& from, const Vector3& dir, const float length)
+void Raycast::cast(const Vector3& from, const Vector3& dir, const float length, List<RaycastHit>& hits)
 {
-	bool hit = m_scene->raycast(PxVec3(from.x, from.y, from.z), PxVec3(dir.x, dir.y, dir.z), length,
-								m_buffer, PxHitFlags(PxHitFlag::eDEFAULT), m_fd);
+	m_scene->raycast(PxVec3(from.x, from.y, from.z), PxVec3(dir.x, dir.y, dir.z), length, m_buffer, PxHitFlags(PxHitFlag::eDEFAULT), m_fd);
 
 	for (uint32_t i = 0; i < m_buffer.getNbAnyHits(); i++)
 	{
 		PxRaycastHit rh = m_buffer.getAnyHit(i);
 
-		physics_world::SceneQueryEvent ev;
-
-		ev.type = SceneQueryType::RAYCAST;
-		ev.mode = m_mode;	
-		ev.hit = hit;
-		ev.callback = m_callback;
-		ev.position.x = rh.position.x;
-		ev.position.y = rh.position.y;
-		ev.position.z = rh.position.z;
-		ev.distance = rh.distance;
-		ev.normal.x = rh.normal.x;
-		ev.normal.y = rh.normal.y;
-		ev.normal.z = rh.normal.z;
-		ev.actor = (Actor*)(rh.actor->userData);
-
-		event_stream::write(m_events, physics_world::EventType::SCENE_QUERY, ev);
-
-		Log::i("callback: %s", ev.callback);
-		Log::i("position: (%f, %f, %f)", ev.position.x, ev.position.y, ev.position.z);
-		Log::i("normal: (%f, %f, %f)", ev.normal.x, ev.normal.y, ev.normal.z);
-		Log::i("distance: %f", ev.distance);
+		RaycastHit hit;
+
+		hit.position.x = rh.position.x;
+		hit.position.y = rh.position.y;
+		hit.position.z = rh.position.z;
+		hit.distance = rh.distance;
+		hit.normal.x = rh.normal.x;
+		hit.normal.y = rh.normal.y;
+		hit.normal.z = rh.normal.z;
+		hit.actor = (Actor*)(rh.actor->userData);
+
+		hits.push_back(hit);
 	}
 }
 
 //-------------------------------------------------------------------------
-Actor* Raycast::sync_cast(const Vector3& from, const Vector3& dir, const float length)
+CollisionMode::Enum Raycast::mode() const
 {
-	bool hit = m_scene->raycast(PxVec3(from.x, from.y, from.z), PxVec3(dir.x, dir.y, dir.z), length,
-								m_buffer, PxHitFlags(PxHitFlag::eDEFAULT), m_fd);
-
-	if (hit)
-	{
-		PxRaycastHit rh = m_buffer.getAnyHit(0);
-
-		Log::i("callback: %s", m_callback);
-		Log::i("position: (%f, %f, %f)", rh.position.x, rh.position.y, rh.position.z);
-		Log::i("distance: %f", rh.distance);
-
-		return (Actor*)(rh.actor->userData);
-	}
-	else return NULL;
+	return m_mode;
 }
 
+//-------------------------------------------------------------------------
+CollisionType::Enum Raycast::type() const
+{
+	return m_type;
+}
 
 } // namespace crown

+ 16 - 4
engine/physics/Raycast.h

@@ -46,10 +46,20 @@ namespace crown
 struct Vector3;
 struct Actor;
 
+//-----------------------------------------------------------------------------
+struct RaycastHit
+{
+	Vector3					position;
+	float					distance;
+	Vector3					normal;
+	Actor*					actor;
+};
+
+//-----------------------------------------------------------------------------
 struct Raycast
 {
 	/// Constructor
-			Raycast(PxScene* scene, EventStream& events, const char* callback, CollisionMode::Enum mode, CollisionType::Enum filter);
+	Raycast(PxScene* scene, EventStream& events, const char* callback, CollisionMode::Enum mode, CollisionType::Enum type);
 
 	/// Performs a raycast against objects in the scene. The ray is casted from position @a from, has direction @a dir and is long @a length
 	/// If any actor is hit along the ray, @a EventStream is filled according to @a mode previously specified and callback will be called for processing.
@@ -58,9 +68,11 @@ struct Raycast
 	/// If there was a hit, the callback will also be called with the position of the hit, the distance from the origin, the normal of the surface that 
 	/// was hit and the actor that was hit.
 	/// @a CollisionMode::ALL: as @a CollisionMode::CLOSEST, with more tuples
-	void	cast(const Vector3& from, const Vector3& dir, const float length);
+	void					cast(const Vector3& from, const Vector3& dir, const float length, List<RaycastHit>& hits);
+
+	CollisionMode::Enum 	mode() const;
 
-	Actor*	sync_cast(const Vector3& from, const Vector3& dir, const float length);
+	CollisionType::Enum 	type() const;
 
 private:
 
@@ -73,7 +85,7 @@ private:
 	const char*				m_callback;
 
 	CollisionMode::Enum		m_mode;
-	CollisionType::Enum		m_filter;
+	CollisionType::Enum		m_type;
 };
 
 } // namespace crown