Add raycasting

This commit is contained in:
Dane Johnson 2021-04-21 18:27:30 -05:00
parent 84c4abbd94
commit fa20631e7b
5 changed files with 106 additions and 2 deletions

View File

@ -45,6 +45,7 @@ Rigidbody *Rigidbody::Instance() {
rigidbody->collisionShape = collisionShape;
rigidbody->btBody = new btRigidBody(rigidbody->mass, new RigidbodyMotionState(rigidbody), rigidbody->collisionShape);
rigidbody->btBody->setAngularFactor(character ? 0.0f : 1.0f);
rigidbody->btBody->setUserPointer(rigidbody);
World *world = World::GetWorld();
world->AddRigidbody(rigidbody);
@ -119,8 +120,8 @@ void RigidbodyMotionState::getWorldTransform(btTransform &worldTrans) const {
void RigidbodyMotionState::setWorldTransform(const btTransform &worldTrans) {
Transform transform = rigidbody->GetTransform();
transform.position = Vector3(worldTrans.getOrigin().getX(),
worldTrans.getOrigin().getY(),
worldTrans.getOrigin().getZ());
worldTrans.getOrigin().getY(),
worldTrans.getOrigin().getZ());
worldTrans.getRotation().getEulerZYX(transform.rotation.z,
transform.rotation.y,

View File

@ -37,6 +37,26 @@ void World::Step(float delta) {
btWorld->stepSimulation(delta);
}
RaycastResult World::Raycast(const Vector3 &from, const Vector3 &to) {
RaycastResult rcr;
btVector3 btFrom = btVector3(from.x, from.y, from.z);
btVector3 btTo = btVector3(to.x, to.y, to.z);
btCollisionWorld::ClosestRayResultCallback rayCallback(btFrom, btTo);
rayCallback.m_collisionFilterGroup = -1; // Everything
btWorld->rayTest(btFrom, btTo, rayCallback);
rcr.hit = rayCallback.hasHit();
if (rcr.hit) {
rcr.position = Vector3(rayCallback.m_hitPointWorld.getX(),
rayCallback.m_hitPointWorld.getY(),
rayCallback.m_hitPointWorld.getZ());
rcr.normal = Vector3(rayCallback.m_hitNormalWorld.getX(),
rayCallback.m_hitNormalWorld.getY(),
rayCallback.m_hitNormalWorld.getZ());
rcr.object = (Rigidbody*) rayCallback.m_collisionObject->getUserPointer();
}
return rcr;
}
World* World::world { new World() };
World::World() {

View File

@ -27,6 +27,13 @@
#include "Rigidbody.h"
struct RaycastResult {
bool hit;
Vector3 position;
Vector3 normal;
Rigidbody *object;
};
/**
World is the object that performs the rigidbody physics simulation. Presently there is only one world.
*/
@ -46,8 +53,11 @@ public:
@param delta the time that has passed since the last physics update
*/
void Step(float delta);
RaycastResult Raycast(const Vector3 &from, const Vector3 &to);
private:
static World* world;
// Some hocus pocus
btDiscreteDynamicsWorld *btWorld;
btDefaultCollisionConfiguration *collisionConfiguration;
btCollisionDispatcher *dispatcher;
@ -55,6 +65,7 @@ private:
btSequentialImpulseConstraintSolver *solver;
World();
~World();
};
#endif /* WORLD_H */

48
demo/shooter/main.lua Normal file
View File

@ -0,0 +1,48 @@
package.path = package.path .. ";../scripts/?.lua"
local freecam = require("freecam")
local Vector3 = couch.Vector3
function init()
freecam.init_camera()
local light = couch.DirectionalLight()
light:SetDirection(Vector3(1.0, -2.0, -1.0))
light:SetColor(Vector3(1.0, 1.0, 1.0))
light:SetAmbient(0.2)
light:SetDiffuse(1.0)
light:SetSpecular(0.1)
couch.Node.GetRoot():AddChild(light:Instance())
local box_mesh = couch.TexturedMesh("../resources/cube.obj", "../resources/paintedwood.jpg")
local box = couch.Rigidbody()
box:SetCollisionShape(couch.BoxCollisionShape(1, 1, 1))
box:AddChild(box_mesh)
couch.Node.GetRoot():AddChild(box:Instance())
local ground = couch.Rigidbody()
ground:SetCollisionShape(couch.BoxCollisionShape(100, 0.1, 100))
ground:Translate(Vector3(0.0, -1.0, 0.0))
ground:SetMass(0.0)
couch.Node.GetRoot():AddChild(ground:Instance())
end
function update(delta)
freecam.update_camera(delta)
end
function onkey(key, code, action, mod)
freecam.onkey(key, code, action, mod)
local camera_transform = freecam.camera:GetTransform()
if action == couch.ACTION_PRESS and key == couch.KEY_R then
local res = couch.World.GetWorld():Raycast(camera_transform.position,
camera_transform.position + camera_transform:Forward() * 100.0)
if (res.hit) then
res.object:ApplyImpulse(res.normal * -100.0)
end
end
end
function onmousemotion(_, _, relx, rely)
freecam.onmousemotion(relx, rely)
end

View File

@ -18,6 +18,17 @@
#include "Skybox.h"
#include "Rigidbody.h"
#include "CollisionShape.h"
struct RaycastResult {
bool hit;
Vector3 position;
Vector3 normal;
Rigidbody *object;
};
class World {
public:
static World* GetWorld();
RaycastResult Raycast(const Vector3 &from, const Vector3 &to);
};
%}
class Vector3 {
@ -37,6 +48,19 @@ public:
}
%ignore "Vector3";
struct RaycastResult {
bool hit;
Vector3 position;
Vector3 normal;
Rigidbody *object;
};
class World {
public:
static World* GetWorld();
RaycastResult Raycast(const Vector3 &from, const Vector3 &to);
};
%include "types.h"
%include "constants.h"
%include "Node.h"