Commit 13afaf79 authored by Leon's avatar Leon

Init CMakeLists; complete engine base

parent 68aaed47
......@@ -8,6 +8,7 @@ namespace duodim
public:
static Bounds fromCenterAndExtents(Vector2D<float> center, const Vector2D<float> extents);
static Bounds asUnion(Bounds a, Bounds b);
Bounds();
Bounds(const Vector2D<float> min, const Vector2D<float> max);
Vector2D<float> getMin();
Vector2D<float> getMax();
......
......@@ -10,6 +10,8 @@ namespace duodim
public:
static Vector2D<T> min(const Vector2D<T> a, const Vector2D<T> b);
static Vector2D<T> max(const Vector2D<T> a, const Vector2D<T> b);
static Vector2D<T> one();
static Vector2D<T> gravity();
Vector2D(const T x, const T y);
Vector2D(const Vector2D<T>& a);
......
......@@ -13,9 +13,8 @@ namespace duodim
Circle(float radius);
~Circle();
Bounds getBounds();
float getMass();
Bounds getBounds(const Vector2D<float> position);
MassAndInertia getMassAndInertia(const float density);
float getRadius();
void setRadius(float r);
protected:
......
......@@ -2,7 +2,9 @@
#define INCLUDE_CONVEX_POLYGON_HPP
#include <list>
#include <optional>
#include "Shape.hpp"
#include "Transform.hpp"
using namespace std;
......@@ -12,14 +14,15 @@ namespace duodim
{
public:
ConvexPolygon();
ConvexPolygon(list<Vector2D<float>> vertices, list<Vector2D<float>> normals);
ConvexPolygon(list<Vector2D<float>> vertices);
~ConvexPolygon();
Bounds getBounds(const optional<Transform> transformOpt);
MassAndInertia getMassAndInertia(const float density);
list<Vector2D<float>> getVertices();
list<Vector2D<float>> getNormals();
float getMass();
void setVertices(list<Vector2D<float>> v);
void setNormals(list<Vector2D<float>> n);
protected:
......
#ifndef INCLUDE_RECTANGLE_HPP
#define INCLUDE_RECTANGLE_HPP
#include <optional>
#include "Shape.hpp"
#include "Transform.hpp"
namespace duodim
{
......@@ -13,9 +15,14 @@ namespace duodim
Rectangle(float dim);
~Rectangle();
Bounds getBounds(const optional<Transform> transformOpt);
MassAndInertia getMassAndInertia(const float density);
float getHeight();
float getWidth();
float getMass();
float getInertia();
bool isQuadratic();
void setHeight(float h);
void setWidth(float w);
......
#ifndef INCLUDE_SHAPE_HPP
#define INCLUDE_SHAPE_HPP
#include <optional>
#include <string>
#include "Bounds.hpp"
#include "Transform.hpp"
using namespace std;
namespace duodim
{
struct MassAndInertia {
float mass;
float inertia;
};
class Shape
{
public:
virtual Bounds getBounds();
virtual float getMass();
virtual Bounds getBounds(optional<Transform> transformOpt);
virtual MassAndInertia getMassAndInertia(const float density);
string getName();
void setName(string n);
......
......@@ -10,46 +10,54 @@ namespace duodim
class Body
{
public:
Body();
Body(Vector2D<float> position, Shape shape);
Body(float posX, float posY, Shape shape);
Vector2D<float> getPosition();
Body(Material material, Shape shape);
Body(Material material, Shape shape, float density);
Body(Vector2D<float> position, Material material, Shape shape);
Body(Vector2D<float> position, Material material, Shape shape, float density);
Body(float posX, float posY, Material material, Shape shape);
Body(float posX, float posY, Material material, Shape shape, float density);
Shape getShape();
float getRotation();
Transform getTransform();
float getDensity();
bool isStatic();
void addForce(Vector2D<float> f);
void addForce(Vector2D<float> f, Vector2D<float> pos);
void addImpulse(Vector2D<float> i, Vector2D<float> pos);
void addTorque(float t);
void setPosition(Vector2D<float> p);
void setPosition(float posX, float posY);
void setRotation(float r);
void setShape(Shape s);
void setDensity(const float d);
void update(float deltaTime);
void transformLocalToWorldSpace();
void transformWorldToLocalSpace();
void update();
void integrateForce(const float deltaTime);
void integrateVelocity(const float deltaTime);
void setStatic();
void unsetStatic();
private:
Transform transform;
Vector2D<float> velocity;
Vector2D<float> force;
Vector2D<float> velocity = Vector2D<float>();
Vector2D<float> force = Vector2D<float>();
Shape shape;
Bounds bounds;
Material material;
float rotation = 0.f;
float angularVelocity = 0.f;
float torque = 0.f;
float mass = 1.f;
float inertia = 1.f;
float inv_mass = 1.f;
float inv_inertia = 1.f;
float coeffFriction = 1.f;
float coeffRestitution = 1.f;
float mass;
float inertia;
float inv_mass;
float inv_inertia;
float density;
void initialize();
};
}
#endif
\ No newline at end of file
......@@ -15,6 +15,7 @@ Bounds Bounds::asUnion(Bounds a, Bounds b)
);
}
Bounds::Bounds() : min(Vector2D<float>()), max(Vector2D<float>()) {}
Bounds::Bounds(const Vector2D<float> min, const Vector2D<float> max) : min(min), max(max) {}
Vector2D<float> Bounds::getMin()
......
......@@ -15,6 +15,18 @@ Vector2D<T> Vector2D<T>::max(const Vector2D<T> a, const Vector2D<T> b)
return Vector2D<T>(T(max(a.getX(), b.getX())), T(max(a.getY(), b.getY())));
}
template <typename T>
Vector2D<T> Vector2D<T>::one()
{
return Vector2D<T>(T(1), T(1));
}
template <typename T>
Vector2D<T> Vector2D<T>::gravity()
{
return Vector2D<T>(T(0), T(-9.81));
}
template <typename T>
Vector2D<T>::Vector2D(const T x, const T y) : x(x), y(y) {}
......
......@@ -15,19 +15,22 @@ Circle::Circle(float radius) : radius(radius) {
}
Circle::~Circle() {}
Bounds Circle::getBounds()
Bounds Circle::getBounds(const Vector2D<float> position)
{
return Bounds::fromCenterAndExtents(position, (Vector2D<float>::one() * radius));
}
float Circle::getRadius()
MassAndInertia Circle::getMassAndInertia(const float density)
{
return radius;
float sqRad = pow(radius, 2);
float mass = density * M_PI * sqRad;
float inertia = .5f * mass * sqRad;
return {mass, inertia};
}
float Circle::getMass()
float Circle::getRadius()
{
return M_PI * pow(radius, 2);
return radius;
}
void Circle::setRadius(float r)
......
#include <math.h>
#include <list>
#include <string>
#include "Transform.hpp"
#include "ConvexPolygon.hpp"
#include "Vector2D.hpp"
using namespace duodim;
using namespace std;
ConvexPolygon::ConvexPolygon() : vertices({}), normals({}) {
ConvexPolygon::ConvexPolygon() : vertices({}), normals({})
{
updateName();
}
ConvexPolygon::ConvexPolygon(list<Vector2D<float>> vertices, list<Vector2D<float>> normals) : vertices(vertices), normals(normals) {
ConvexPolygon::ConvexPolygon(list<Vector2D<float>> vertices) : vertices(vertices)
{
Vector2D<float> centroid = Vector2D<float>();
float area = 0.f;
auto i = 0u;
for (auto v : vertices)
{
auto j = (i + 1) % vertices.size();
auto it = vertices.begin();
advance(it, j);
centroid = centroid + ((v + *it) * v.crossMult(*it) / 6.f * area);
i++;
}
for (auto v : vertices)
{
v = v - centroid;
}
auto anormals = list<Vector2D<float>>();
i = 0u;
for (auto v : vertices)
{
auto j = (i + 1) % vertices.size();
auto it = vertices.begin();
advance(it, j);
anormals.push_back((v - *it).normalized().crossMult(1.f));
i++;
}
normals = anormals;
updateName();
}
ConvexPolygon::~ConvexPolygon() {}
list<Vector2D<float>> ConvexPolygon::getVertices()
Bounds ConvexPolygon::getBounds(const optional<Transform> transformOpt)
{
return vertices;
Vector2D<float> min = Vector2D<float>::one() * INFINITY;
Vector2D<float> max = Vector2D<float>::one() * (-1.f) * INFINITY;
for (auto v : vertices)
{
Vector2D<float> vertex;
if (transformOpt.has_value())
{
Transform t = transformOpt.value();
vertex = t.getWorldPosition(v);
}
else
{
vertex = v;
}
min = Vector2D<float>::min(min, vertex);
max = Vector2D<float>::max(max, vertex);
}
return Bounds(min, max);
}
list<Vector2D<float>> ConvexPolygon::getNormals()
MassAndInertia ConvexPolygon::getMassAndInertia(const float density)
{
return normals;
float area = 0.f, densityInertia = 0.f;
auto i = 0u;
for (auto v : vertices)
{
auto j = (i + 1) % vertices.size();
auto it = vertices.begin();
advance(it, j);
Vector2D<float> atJ = *it;
float tri_area = .5f * abs(v.crossMult(atJ));
float tri_inertia = tri_area * (v.squaredMagnitude() + atJ.squaredMagnitude() + (v * atJ)) / 6.f;
area += tri_area;
densityInertia = tri_inertia;
i++;
}
return {(area * density), (densityInertia * density)};
}
float ConvexPolygon::getMass()
list<Vector2D<float>> ConvexPolygon::getVertices()
{
Vector2D<float> centroid = Vector2D<float>();
for
return vertices;
}
list<Vector2D<float>> ConvexPolygon::getNormals()
{
return normals;
}
void ConvexPolygon::setVertices(list<Vector2D<float>> v)
......
#include <math.h>
#include <optional>
#include <string>
#include "Bounds.hpp"
#include "Rectangle.hpp"
#include "Shape.hpp"
#include "Transform.hpp"
using namespace duodim;
using namespace std;
......@@ -15,6 +20,34 @@ Rectangle::Rectangle(float dim) : height(dim), width(dim) {
}
Rectangle::~Rectangle() {}
Bounds Rectangle::getBounds(const optional<Transform> transformOpt)
{
Vector2D<float> center;
if(transformOpt)
{
Transform t = transformOpt.value();
center = t.getPosition();
}
else
{
center = Vector2D<float>();
}
Vector2D<float> extents = Vector2D<float>((.5f * width), (.5f * height));
return Bounds::fromCenterAndExtents(center, extents);
}
/**
* Mass = Volume (in 2D: Area) * density.
* Moment of inertia = 1/12 * mass * (height^2 + width^2)
*/
MassAndInertia Rectangle::getMassAndInertia(const float density)
{
float area = height * width;
float mass = area * density;
return {mass, ((1.f / 12.f) * mass * (pow(height, 2) + pow(width, 2)))};
}
float Rectangle::getHeight()
{
return height;
......
#include <optional>
#include <string>
#include "Shape.hpp"
#include "Bounds.hpp"
#include "Shape.hpp"
#include "Transform.hpp"
using namespace duodim;
using namespace std;
Bounds Shape::getBounds()
Bounds Shape::getBounds(const optional<Transform> transformOpt)
{
return Bounds(Vector2D<float>(), Vector2D<float>());
}
float Shape::getMass()
MassAndInertia Shape::getMassAndInertia(const float density)
{
return 1.f;
return {1.f, 1.f};
}
string Shape::getName()
......
#include <optional>
#include "Body.hpp"
#include "Vector2D.hpp"
#include "Bounds.hpp"
#include "Shape.hpp"
#include "Transform.hpp"
#include "Vector2D.hpp"
#include "World.hpp"
using namespace duodim;
Body::Body() : transform(Transform()) {}
Body::Body(Vector2D<float> position, Shape shape) : transform(Transform(position)), shape(shape) {}
Body::Body(float posX, float posY, Shape shape) : transform(Transform(Vector2D<float>(posX, posY))), shape(shape) {}
Body::Body(Material material, Shape shape)
: transform(Transform()), material(material), shape(shape), density(1.f)
{
initialize();
}
Body::Body(Material material, Shape shape, float density)
: transform(Transform()), material(material), shape(shape), density(density)
{
initialize();
}
Body::Body(Vector2D<float> position, Material material, Shape shape)
: transform(Transform(position, 0.f)), material(material), shape(shape), density(1.f)
{
initialize();
}
Body::Body(Vector2D<float> position, Material material, Shape shape, float density)
: transform(Transform(position, 0.f)), material(material), shape(shape), density(density)
{
initialize();
}
Body::Body(float posX, float posY, Material material, Shape shape)
: transform(Transform(Vector2D<float>(posX, posY))), material(material), shape(shape), density(1.f)
{
initialize();
}
Vector2D<float> Body::getPosition()
Body::Body(float posX, float posY, Material material, Shape shape, float density)
: transform(Transform(Vector2D<float>(posX, posY))), material(material), shape(shape), density(density)
{
return transform.getPosition();
initialize();
}
Shape Body::getShape()
......@@ -19,30 +49,46 @@ Shape Body::getShape()
return shape;
}
float Body::getRotation()
Transform Body::getTransform()
{
return transform;
}
float Body::getDensity()
{
return density;
}
bool Body::isStatic()
{
return rotation;
return inv_mass == 0.f && inv_inertia == 0.f;
}
void Body::addForce(Vector2D<float> f)
{
Vector2D<float> nf = force + f;
force = nf;
force = force + f;
}
void Body::setPosition(Vector2D<float> p)
void Body::addForce(Vector2D<float> f, Vector2D<float> pos)
{
transform.setPosition(p);
addForce(f);
addTorque(pos.crossMult(f));
}
void Body::setPosition(float posX, float posY)
void Body::addImpulse(Vector2D<float> i, Vector2D<float> pos)
{
transform.setPosition(Vector2D<float>(posX, posY));
velocity = velocity + i * inv_mass;
angularVelocity = pos.crossMult(i) * inv_inertia;
}
void Body::setRotation(float r)
void Body::addTorque(float t)
{
rotation = r;
torque += t;
}
void Body::setPosition(Vector2D<float> p)
{
transform.setPosition(p);
}
void Body::setShape(Shape s)
......@@ -50,30 +96,60 @@ void Body::setShape(Shape s)
shape = s;
}
void Body::update(float deltaTime)
void Body::setDensity(const float d)
{
if (mass == 0.f) {
throw "Mass can't be zero";
}
// Apply motion
velocity = velocity + Vector2D<float>((force.getX() / shape.getMass()), ((force.getY() / shape.getMass()) + (World::gravityConst * -1))) * deltaTime;
transform.setPosition(transform.getPosition() + velocity * deltaTime);
density = d;
unsetStatic();
}
void Body::update()
{
bounds = shape.getBounds(optional<Transform>{transform});
}
// Apply rotation
angularVelocity += (torque / inertia) * deltaTime;
rotation += angularVelocity * deltaTime;
void Body::integrateForce(const float deltaTime)
{
if (isStatic())
{
return;
}
auto g = Vector2D<float>::gravity();
velocity = (g + force * inv_mass) * deltaTime;
angularVelocity = torque * inv_inertia * deltaTime;
// Reset force and torque
force = Vector2D<float>();
torque = 0.f;
}
void Body::transformLocalToWorldSpace()
void Body::integrateVelocity(const float deltaTime)
{
if (isStatic())
{
return;
}
transform.setPosition(transform.getPosition() + velocity * deltaTime);
transform.setRotation(transform.getRotation() + angularVelocity * deltaTime);
}
void Body::setStatic()
{
mass = 0.f;
inertia = 0.f;
inv_mass = 0.f;
inertia = 0.f;
}
void Body::unsetStatic()
{
MassAndInertia mai = shape.getMassAndInertia(density);
mass = mai.mass;
inertia = mai.inertia;
inv_mass = mass != 0.f ? 1.f / mass : 0.f;
inv_inertia = inertia != 0.f ? 1.f / inertia : 0.f;
}
void Body::transformWorldToLocalSpace()
void Body::initialize()
{
update();
unsetStatic();
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment