Add raycasting
This commit is contained in:
parent
84c4abbd94
commit
fa20631e7b
@ -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,
|
||||
|
@ -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() {
|
||||
|
11
core/World.h
11
core/World.h
@ -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
48
demo/shooter/main.lua
Normal 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
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user