Added more collision shapes and rigidbody driving

This commit is contained in:
Dane Johnson 2021-01-25 15:17:32 -06:00
parent f27cf4bd88
commit cd20bc490d
10 changed files with 2499 additions and 29 deletions

17
core/CollisionShape.cpp Normal file
View File

@ -0,0 +1,17 @@
#include "CollisionShape.h"
CollisionShape::CollisionShape() {
shape = nullptr;
}
SphereCollisionShape::SphereCollisionShape(cfloat radius) {
shape = new btSphereShape(radius);
}
BoxCollisionShape::BoxCollisionShape(cfloat width, cfloat height, cfloat depth) {
shape = new btBoxShape(btVector3(width / 2.0f, height / 2.0f, depth / 2.0f));
}
CapsuleCollisionShape::CapsuleCollisionShape(cfloat radius, cfloat height) {
shape = new btCapsuleShape(radius, height);
}

32
core/CollisionShape.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef COLLISIONSHAPE_H
#define COLLISIONSHAPE_H
#include <btBulletDynamicsCommon.h>
#include "types.h"
class CollisionShape {
public:
CollisionShape();
protected:
btCollisionShape *shape;
private:
friend class Rigidbody;
};
class SphereCollisionShape : public CollisionShape {
public:
SphereCollisionShape(cfloat radius);
};
class BoxCollisionShape : public CollisionShape {
public:
BoxCollisionShape(cfloat width, cfloat height, cfloat depth);
};
class CapsuleCollisionShape: public CollisionShape {
public:
CapsuleCollisionShape(cfloat radius, cfloat height);
};
#endif /* COLLISIONSHAPE_H */

View File

@ -1,17 +1,5 @@
#include "Material.h"
Color::Color() {
this->r = 0.0f;
this->g = 0.0f;
this->b = 0.0f;
}
Color::Color(cfloat r, cfloat g, cfloat b) {
this->r = r;
this->g = g;
this->b = b;
}
Texture::Texture() {}
Texture Texture::FromFile(const char *filename) {

View File

@ -7,11 +7,7 @@
#include "types.h"
#include "Util.h"
struct Color {
cfloat r, g, b;
Color();
Color(cfloat r, cfloat g, cfloat b);
};
typedef Vector3 Color;
class Texture {
public:

View File

@ -1,7 +1,9 @@
#include "Rigidbody.h"
#include "World.h"
Rigidbody::Rigidbody() {}
Rigidbody::Rigidbody() {
collisionShape = new btSphereShape(1.0f);
}
Rigidbody *Rigidbody::Create() {
return new Rigidbody;
@ -19,9 +21,9 @@ Rigidbody *Rigidbody::Duplicate() {
Rigidbody *Rigidbody::Instance() {
Rigidbody *rigidbody = static_cast<Rigidbody*>(Node::Instance());
rigidbody->collisionShape = new btSphereShape(1.0f);
rigidbody->collisionShape = collisionShape;
rigidbody->btBody = new btRigidBody(rigidbody->mass, new RigidbodyMotionState(rigidbody), rigidbody->collisionShape);
assert(rigidbody);
rigidbody->btBody->setAngularFactor(character ? 0.0f : 1.0f);
World *world = World::GetWorld();
world->AddRigidbody(rigidbody);
@ -29,6 +31,26 @@ Rigidbody *Rigidbody::Instance() {
return rigidbody;
}
void Rigidbody::SetCollisionShape(CollisionShape collisionShape) {
if (this->collisionShape) {
delete this->collisionShape;
}
this->collisionShape = collisionShape.shape;
}
void Rigidbody::ApplyImpulse(Vector3 impulse) {
btBody->applyCentralImpulse(btVector3(impulse.x, impulse.y, impulse.z));
}
void Rigidbody::ApplyForce(Vector3 force) {
btBody->applyCentralForce(btVector3(force.x, force.y, force.z));
}
void Rigidbody::SetCharacter(bool character) {
this->character = character;
}
RigidbodyMotionState::RigidbodyMotionState(Rigidbody *rigidbody) {
this->rigidbody = rigidbody;
}

View File

@ -5,6 +5,7 @@
#include "types.h"
#include "Spatial.h"
#include "CollisionShape.h"
class Rigidbody : public Spatial {
public:
@ -12,8 +13,16 @@ public:
virtual Rigidbody *Create();
virtual Rigidbody *Duplicate();
virtual Rigidbody *Instance();
void SetCollisionShape(CollisionShape collisionShape);
cfloat mass = 1.0f;
void ApplyImpulse(Vector3 impulse);
void ApplyForce(Vector3 force);
void SetCharacter(bool character);
private:
bool character = false;
btRigidBody *btBody;
btCollisionShape *collisionShape;
friend class World;

10
demo/capsule.mtl Normal file
View File

@ -0,0 +1,10 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl None
Ns 500
Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2

2365
demo/capsule.obj Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,8 @@
local min = math.min
local max = math.max
local cube
local physics_ball
local character
local ball
local camera
@ -8,6 +10,8 @@ local vx = 0.0
local vy = 0.0
local vz = 0.0
local character_move_vec = couch.Vector3(0.0, 0.0, 0.0)
local ballvy = -1.0
local cam_rot_x = 0.0
@ -15,9 +19,9 @@ local cam_rot_y = 0.0
local SPEED = 30
local WHITE = couch.Color(1.0, 1.0, 1.0)
local RED = couch.Color(1.0, 0.0, 0.0)
local BLUE = couch.Color(0.0, 0.0, 1.0)
local WHITE = couch.Vector3(1.0, 1.0, 1.0)
local RED = couch.Vector3(1.0, 0.0, 0.0)
local BLUE = couch.Vector3(0.0, 0.0, 1.0)
local light
@ -54,11 +58,26 @@ function init()
physics_ball_mesh:SetMaterial(0, material)
physics_ball_prefab.children:Append(physics_ball_mesh);
physics_ball_prefab.transform.position = couch.Vector3(0.0, 30.0, -10.0)
local physics_ball = physics_ball_prefab:Instance()
physics_ball = physics_ball_prefab:Instance()
couch.Node.GetRoot().children:Append(physics_ball)
make_ground()
local character_prefab = couch.Mesh.FromFile("capsule.obj")
material = character_prefab:GetMaterial(0)
material.ambient = BLUE
material.diffuse = BLUE
material.specular = WHITE * 0.1
character_prefab:SetMaterial(0, material)
local character_body = couch.Rigidbody()
character_body.mass = 1.0
character_body:SetCollisionShape(couch.CapsuleCollisionShape(1.0, 1.0))
character_body:SetCharacter(true)
character_body.children:Append(character_prefab)
character_body.transform.position = couch.Vector3(0.0, 3.0, 0.0)
character = character_body:Instance()
couch.Node.GetRoot().children:Append(character)
local cube_prefab = couch.Mesh.FromFile("cube.obj")
material = cube_prefab:GetMaterial(0)
material.ambient = RED
@ -133,6 +152,9 @@ function update(delta)
cube.transform.rotation.y = cube.transform.rotation.y + 2.0 * delta;
cube.transform.rotation.z = cube.transform.rotation.z + 1.0 * delta;
character:ApplyForce(character_move_vec * 10.0)
print(character_move_vec.z)
end
function action_dir(key, action, pos, neg, curr)
@ -151,12 +173,12 @@ function onkey(key, code, action, mod)
vz = action_dir(key, action, couch.KEY_W, couch.KEY_S, vz)
vx = action_dir(key, action, couch.KEY_D, couch.KEY_A, vx)
vy = action_dir(key, action, couch.KEY_SPACE, couch.KEY_LEFT_CONTROL, vy)
if key == couch.KEY_DOWN and action == couch.ACTION_PRESS then
light.ambient = max(light.ambient - 0.1, 0.0)
elseif key == couch.KEY_UP and action == couch.ACTION_PRESS then
light.ambient = light.ambient + 0.1
print(light.ambient)
if key == couch.KEY_J and action == couch.ACTION_PRESS then
physics_ball:ApplyImpulse(couch.Vector3(0.0, 1.0, 0.0) * 10)
end
character_move_vec.z = action_dir(key, action, couch.KEY_DOWN, couch.KEY_UP, character_move_vec.z)
end
function onmousemotion(_, _, relx, rely)
@ -172,6 +194,13 @@ function make_ground()
ground = couch.Spatial():Instance()
couch.Node.GetRoot().children:Append(ground)
-- Add a collisionshape
local ground_shape_prefab = couch.Rigidbody()
ground_shape_prefab.mass = 0.0
ground_shape_prefab:SetCollisionShape(couch.BoxCollisionShape(180.0, 1.0, 180.0))
ground_shape_prefab.transform:Translate(0.0, -2.5, 0.0)
ground.children:Append(ground_shape_prefab:Instance())
for x = -20, 20, 1 do
for z = -20, 20, 1 do
local piece = ground_prefab:Instance()

View File

@ -17,6 +17,7 @@
#include "Light.h"
#include "Skybox.h"
#include "Rigidbody.h"
#include "CollisionShape.h"
%}
typedef float cfloat;
@ -50,3 +51,4 @@ public:
%include "Light.h"
%include "Skybox.h"
%include "Rigidbody.h"
%include "CollisionShape.h"