overhauled physics engine

This commit is contained in:
Dynamitos
2023-01-21 18:43:21 +01:00
parent 3c7346cf7b
commit 2208ab438a
164 changed files with 22606 additions and 928 deletions
+70 -22
View File
@@ -2,16 +2,64 @@
#include "Math/Vector.h"
#include "Math/Matrix.h"
#include "Containers/Array.h"
#include "Graphics/DebugVertex.h"
namespace Seele
{
struct AABB
{
Math::Vector min = Math::Vector(std::numeric_limits<float>::max());
Math::Vector max = Math::Vector(std::numeric_limits<float>::min());
Vector min = Vector(std::numeric_limits<float>::max());
Vector max = Vector(std::numeric_limits<float>::lowest());// cause of reasons
void visualize(Array<DebugVertex>& vertices) const
{
StaticArray<DebugVertex, 8> corners;
corners[0] = DebugVertex { .position = Vector(min.x, min.y, min.z), .color = Vector(0, 1, 0) };
corners[1] = DebugVertex { .position = Vector(min.x, min.y, max.z), .color = Vector(0, 1, 0) };
corners[2] = DebugVertex { .position = Vector(min.x, max.y, min.z), .color = Vector(0, 1, 0) };
corners[3] = DebugVertex { .position = Vector(min.x, max.y, max.z), .color = Vector(0, 1, 0) };
corners[4] = DebugVertex { .position = Vector(max.x, min.y, min.z), .color = Vector(0, 1, 0) };
corners[5] = DebugVertex { .position = Vector(max.x, min.y, max.z), .color = Vector(0, 1, 0) };
corners[6] = DebugVertex { .position = Vector(max.x, max.y, min.z), .color = Vector(0, 1, 0) };
corners[7] = DebugVertex { .position = Vector(max.x, max.y, max.z), .color = Vector(0, 1, 0) };
vertices.add(corners[0]);
vertices.add(corners[1]);
vertices.add(corners[1]);
vertices.add(corners[3]);
vertices.add(corners[2]);
vertices.add(corners[3]);
vertices.add(corners[0]);
vertices.add(corners[2]);
vertices.add(corners[0]);
vertices.add(corners[4]);
vertices.add(corners[1]);
vertices.add(corners[5]);
vertices.add(corners[2]);
vertices.add(corners[6]);
vertices.add(corners[3]);
vertices.add(corners[7]);
vertices.add(corners[4]);
vertices.add(corners[5]);
vertices.add(corners[5]);
vertices.add(corners[7]);
vertices.add(corners[6]);
vertices.add(corners[7]);
vertices.add(corners[4]);
vertices.add(corners[6]);
}
float surfaceArea() const
{
Math::Vector d = max - min;
Vector d = max - min;
return 2.0f * (d.x * d.y + d.y * d.z + d.z * d.x);
}
bool intersects(const AABB& other) const
@@ -52,31 +100,31 @@ struct AABB
}
return true;
}
AABB getTransformedBox(const Math::Matrix4& matrix) const
AABB getTransformedBox(const Matrix4& matrix) const
{
StaticArray<Math::Vector, 8> corners;
corners[0] = Math::Vector(min.x, min.y, min.z);
corners[1] = Math::Vector(min.x, min.y, max.z);
corners[2] = Math::Vector(min.x, max.y, min.z);
corners[3] = Math::Vector(min.x, max.y, max.z);
corners[4] = Math::Vector(max.x, min.y, min.z);
corners[5] = Math::Vector(max.x, min.y, max.z);
corners[6] = Math::Vector(max.x, max.y, min.z);
corners[7] = Math::Vector(max.x, max.y, max.z);
Math::Vector tmin = Math::Vector(1, 1, 1) * std::numeric_limits<float>::max();
Math::Vector tmax = Math::Vector(1, 1, 1) * std::numeric_limits<float>::min();
StaticArray<Vector, 8> corners;
corners[0] = Vector(min.x, min.y, min.z);
corners[1] = Vector(min.x, min.y, max.z);
corners[2] = Vector(min.x, max.y, min.z);
corners[3] = Vector(min.x, max.y, max.z);
corners[4] = Vector(max.x, min.y, min.z);
corners[5] = Vector(max.x, min.y, max.z);
corners[6] = Vector(max.x, max.y, min.z);
corners[7] = Vector(max.x, max.y, max.z);
Vector tmin = Vector(1, 1, 1) * std::numeric_limits<float>::max();
Vector tmax = Vector(1, 1, 1) * std::numeric_limits<float>::lowest();
for(int i = 0; i < 8; ++i)
{
Math::Vector transformed = matrix * Math::Vector4(corners[i], 1.0f);
tmin = Math::Vector(std::min(tmin.x, transformed.x), std::min(tmin.y, transformed.y), std::min(tmin.z, transformed.z));
tmax = Math::Vector(std::max(tmax.x, transformed.x), std::max(tmax.y, transformed.y), std::max(tmax.z, transformed.z));
Vector transformed = matrix * Vector4(corners[i], 1.0f);
tmin = Vector(std::min(tmin.x, transformed.x), std::min(tmin.y, transformed.y), std::min(tmin.z, transformed.z));
tmax = Vector(std::max(tmax.x, transformed.x), std::max(tmax.y, transformed.y), std::max(tmax.z, transformed.z));
}
return AABB {
.min = tmin,
.max = tmax,
};
}
void adjust(const Math::Vector vertex)
void adjust(const Vector vertex)
{
min.x = std::min(min.x, vertex.x);
min.y = std::min(min.y, vertex.y);
@@ -89,12 +137,12 @@ struct AABB
AABB combine(const AABB& other) const
{
return AABB {
.min = Math::Vector(
.min = Vector(
std::min(min.x, other.min.x),
std::min(min.y, other.min.y),
std::min(min.z, other.min.z)
),
.max = Math::Vector (
.max = Vector (
std::max(max.x, other.max.x),
std::max(max.y, other.max.y),
std::max(max.z, other.max.z)
+4 -4
View File
@@ -15,14 +15,14 @@ struct Camera
Camera();
~Camera();
Math::Matrix4 getViewMatrix() const
Matrix4 getViewMatrix() const
{
assert (!bNeedsViewBuild);
return viewMatrix;
}
Math::Vector getCameraPosition() const
Vector getCameraPosition() const
{
return Math::Vector(viewMatrix[3]);
return Vector(viewMatrix[3]);
}
void setViewport(Gfx::PViewport viewport);
void mouseMove(float deltaX, float deltaY);
@@ -30,7 +30,7 @@ struct Camera
void moveX(float amount);
void moveY(float amount);
void buildViewMatrix();
Math::Matrix4 viewMatrix;
Matrix4 viewMatrix;
//Transforms relative to actor
float yaw;
float pitch;
+1 -1
View File
@@ -13,7 +13,7 @@ enum class ColliderType
};
struct Collider
{
ColliderType type;
ColliderType type = ColliderType::STATIC;
AABB boundingbox;
ShapeBase physicsMesh;
Collider transform(const Transform& transform) const;
+4 -4
View File
@@ -8,10 +8,10 @@ namespace Component
struct RigidBody
{
float mass = 1.0f;
Math::Vector force;
Math::Vector torque;
Math::Vector linearMomentum;
Math::Vector angularMomentum;
Vector force;
Vector torque;
Vector linearMomentum;
Vector angularMomentum;
};
} // namespace Component
} // namespace Seele
+54 -12
View File
@@ -1,4 +1,5 @@
#include "ShapeBase.h"
#include "AABB.h"
using namespace Seele;
using namespace Seele::Component;
@@ -20,13 +21,13 @@ struct ComputationState
/* volume integrals */
float T0;
Math::Vector T1, T2, TP;
Vector T1, T2, TP;
};
struct Face
{
StaticArray<Math::Vector, 3> vertices;
Math::Vector normal;
StaticArray<Vector, 3> vertices;
Vector normal;
float w;
};
@@ -126,7 +127,7 @@ void computeFaceIntegrals(Face& f, ComputationState& state)
+ w * (2 * (n[state.A] * state.Paa + n[state.B] * state.Pab) + w * state.Pa));
}
void computeVolumeIntegrals(const Array<Math::Vector> vertices, const Array<uint32>& indices, ComputationState& state)
void computeVolumeIntegrals(const Array<Vector> vertices, const Array<uint32>& indices, ComputationState& state)
{
std::memset(&state, 0, sizeof(ComputationState));
for (size_t i = 0; i < indices.size(); i+=3)
@@ -138,8 +139,8 @@ void computeVolumeIntegrals(const Array<Math::Vector> vertices, const Array<uint
vertices[indices[i+2]],
};
Math::Vector e1 = f.vertices[2] - f.vertices[0];
Math::Vector e2 = f.vertices[1] - f.vertices[0];
Vector e1 = f.vertices[2] - f.vertices[0];
Vector e2 = f.vertices[1] - f.vertices[0];
f.normal = glm::normalize(glm::cross(e1, e2));
f.w = - f.normal.x * f.vertices[0].x
- f.normal.y * f.vertices[0].y
@@ -171,13 +172,13 @@ void computeVolumeIntegrals(const Array<Math::Vector> vertices, const Array<uint
state.TP /= 2.0f;
}
void computePhysicsParamsForMesh(Array<Math::Vector>& vertices, const Array<uint32_t>& indices, Math::Matrix3& bodyInertia, Math::Vector& centerOfMass, float& mass)
void computePhysicsParamsForMesh(Array<Vector>& vertices, const Array<uint32_t>& indices, Matrix3& bodyInertia, Vector& centerOfMass, float& mass)
{
ComputationState state;
computeVolumeIntegrals(vertices, indices, state);
float density = 1;
mass = density * state.T0;
Math::Vector r = state.T1 / state.T0;
Vector r = state.T1 / state.T0;
centerOfMass = r;
bodyInertia[0][0] = density * (state.T2.y + state.T2.z);
bodyInertia[1][1] = density * (state.T2.z + state.T2.x);
@@ -194,7 +195,12 @@ void computePhysicsParamsForMesh(Array<Math::Vector>& vertices, const Array<uint
bodyInertia[2][1] = bodyInertia[1][2] += mass * r.z * r.x;
}
ShapeBase::ShapeBase(Array<Math::Vector> vertices, Array<uint32> indices)
ShapeBase::ShapeBase()
{
}
ShapeBase::ShapeBase(Array<Vector> vertices, Array<uint32> indices)
: vertices(vertices)
, indices(indices)
{
@@ -206,17 +212,17 @@ ShapeBase ShapeBase::transform(const Component::Transform& transform) const
ShapeBase result = *this;
for(auto& vert : result.vertices)
{
vert = transform.toMatrix() * Math::Vector4(vert, 1.0f);
vert = transform.toMatrix() * Vector4(vert, 1.0f);
}
return result;
}
void ShapeBase::addCollider(Array<Math::Vector> verts, Array<uint32> inds, Math::Matrix4 matrix)
void ShapeBase::addCollider(Array<Vector> verts, Array<uint32> inds, Matrix4 matrix)
{
size_t indOffset = vertices.size();
for(auto vert : verts)
{
vertices.add(Math::Vector(matrix * Math::Vector4(vert, 1.0f)));
vertices.add(Vector(matrix * Vector4(vert, 1.0f)));
}
for(auto ind : inds)
{
@@ -224,3 +230,39 @@ void ShapeBase::addCollider(Array<Math::Vector> verts, Array<uint32> inds, Math:
}
computePhysicsParamsForMesh(vertices, indices, bodyInertia, centerOfMass, mass);
}
void ShapeBase::visualize() const
{
for(uint32 i = 0; i < indices.size(); i+=3)
{
gDebugVertices.add(DebugVertex{
.position = Vector(vertices[indices[i+0]]),
.color = Vector(1, 0, 0),
});
gDebugVertices.add(DebugVertex{
.position = Vector(vertices[indices[i+1]]),
.color = Vector(1, 0, 0),
});
gDebugVertices.add(DebugVertex{
.position = Vector(vertices[indices[i+1]]),
.color = Vector(1, 0, 0),
});
gDebugVertices.add(DebugVertex{
.position = Vector(vertices[indices[i+2]]),
.color = Vector(1, 0, 0),
});
gDebugVertices.add(DebugVertex{
.position = Vector(vertices[indices[i+2]]),
.color = Vector(1, 0, 0),
});
gDebugVertices.add(DebugVertex{
.position = Vector(vertices[indices[i+0]]),
.color = Vector(1, 0, 0),
});
}
}
+8 -5
View File
@@ -1,6 +1,7 @@
#pragma once
#include "Containers/Array.h"
#include "Transform.h"
#include "Graphics/DebugVertex.h"
namespace Seele
{
@@ -8,13 +9,15 @@ namespace Component
{
struct ShapeBase
{
ShapeBase(Array<Math::Vector> vertices, Array<uint32> indices);
ShapeBase();
ShapeBase(Array<Vector> vertices, Array<uint32> indices);
ShapeBase transform(const Component::Transform& transform) const;
void addCollider(Array<Math::Vector> vertices, Array<uint32> indices, Math::Matrix4 matrix);
Math::Vector centerOfMass;
void addCollider(Array<Vector> vertices, Array<uint32> indices, Matrix4 matrix);
void visualize() const;
Vector centerOfMass;
float mass;
Math::Matrix3 bodyInertia;
Array<Math::Vector> vertices;
Matrix3 bodyInertia;
Array<Vector> vertices;
Array<uint32> indices;
};
} // namespace Component
+2
View File
@@ -7,6 +7,8 @@ namespace Component
{
struct StaticMesh
{
StaticMesh() {}
StaticMesh(PMeshAsset mesh) : mesh(mesh) {}
PMeshAsset mesh;
};
} // namespace Component
+12 -12
View File
@@ -5,55 +5,55 @@ using namespace Seele::Component;
DEFINE_COMPONENT(Transform)
void Transform::setPosition(Math::Vector pos)
void Transform::setPosition(Vector pos)
{
transform.setPosition(pos);
dirty = true;
}
void Transform::setRotation(Math::Quaternion quat)
void Transform::setRotation(Quaternion quat)
{
transform.setRotation(quat);
dirty = true;
}
void Transform::setScale(Math::Vector scale)
void Transform::setScale(Vector scale)
{
transform.setScale(scale);
dirty = true;
}
void Transform::setRelativeLocation(Math::Vector location)
void Transform::setRelativeLocation(Vector location)
{
transform = Math::Transform(location, transform.getRotation(), transform.getScale());
dirty = true;
}
void Transform::setRelativeRotation(Math::Vector rotation)
void Transform::setRelativeRotation(Vector rotation)
{
transform = Math::Transform(transform.getPosition(), Math::Quaternion(rotation), transform.getScale());
transform = Math::Transform(transform.getPosition(), Quaternion(rotation), transform.getScale());
dirty = true;
}
void Transform::setRelativeRotation(Math::Quaternion rotation)
void Transform::setRelativeRotation(Quaternion rotation)
{
transform = Math::Transform(transform.getPosition(), rotation, transform.getScale());
dirty = true;
}
void Transform::setRelativeScale(Math::Vector scale)
void Transform::setRelativeScale(Vector scale)
{
transform = Math::Transform(transform.getPosition(), transform.getRotation(), scale);
dirty = true;
}
void Transform::addRelativeLocation(Math::Vector translation)
void Transform::addRelativeLocation(Vector translation)
{
transform = Math::Transform(transform.getPosition() + translation, transform.getRotation(), transform.getScale());
dirty = true;
}
void Transform::addRelativeRotation(Math::Vector rotation)
void Transform::addRelativeRotation(Vector rotation)
{
transform = Math::Transform(transform.getPosition(), transform.getRotation() * Math::Quaternion(rotation), transform.getScale());
transform = Math::Transform(transform.getPosition(), transform.getRotation() * Quaternion(rotation), transform.getScale());
dirty = true;
}
void Transform::addRelativeRotation(Math::Quaternion rotation)
void Transform::addRelativeRotation(Quaternion rotation)
{
transform = Math::Transform(transform.getPosition(), transform.getRotation() * rotation, transform.getScale());
dirty = true;
+17 -17
View File
@@ -8,31 +8,31 @@ namespace Component
{
struct Transform
{
Math::Vector getPosition() const { return transform.getPosition(); }
Math::Quaternion getRotation() const { return transform.getRotation(); }
Math::Vector getScale() const { return transform.getScale(); }
Vector getPosition() const { return transform.getPosition(); }
Quaternion getRotation() const { return transform.getRotation(); }
Vector getScale() const { return transform.getScale(); }
Math::Vector getForward() const { return transform.getForward(); }
Math::Vector getUp() const { return transform.getUp(); }
Math::Vector getRight() const { return transform.getRight(); }
Vector getForward() const { return transform.getForward(); }
Vector getUp() const { return transform.getUp(); }
Vector getRight() const { return transform.getRight(); }
Math::Matrix4 toMatrix() const { return transform.toMatrix(); }
Matrix4 toMatrix() const { return transform.toMatrix(); }
bool isDirty() const { return dirty; }
void clean() { dirty = false; }
void setPosition(Math::Vector pos);
void setRotation(Math::Quaternion quat);
void setScale(Math::Vector scale);
void setPosition(Vector pos);
void setRotation(Quaternion quat);
void setScale(Vector scale);
void setRelativeLocation(Math::Vector location);
void setRelativeRotation(Math::Quaternion rotation);
void setRelativeRotation(Math::Vector rotation);
void setRelativeScale(Math::Vector scale);
void setRelativeLocation(Vector location);
void setRelativeRotation(Quaternion rotation);
void setRelativeRotation(Vector rotation);
void setRelativeScale(Vector scale);
void addRelativeLocation(Math::Vector translation);
void addRelativeRotation(Math::Quaternion rotation);
void addRelativeRotation(Math::Vector rotation);
void addRelativeLocation(Vector translation);
void addRelativeRotation(Quaternion rotation);
void addRelativeRotation(Vector rotation);
private:
bool dirty = true;
Math::Transform transform;