Implementing basic physics
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
#include "Math/Vector.h"
|
||||
#include "Math/Matrix.h"
|
||||
#include "Containers/Array.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());
|
||||
float surfaceArea() const
|
||||
{
|
||||
Math::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
|
||||
{
|
||||
if (min.x > other.max.x
|
||||
|| max.x < other.min.x)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (min.y > other.max.y
|
||||
|| max.y < other.min.y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (min.z > other.max.z
|
||||
|| max.z < other.min.z)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool contains(const AABB& other) const
|
||||
{
|
||||
if (min.x > other.min.x
|
||||
|| max.x < other.max.x)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (min.y > other.min.y
|
||||
|| max.y < other.max.y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (min.z > other.min.z
|
||||
|| max.z < other.max.z)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
AABB getTransformedBox(const Math::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();
|
||||
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));
|
||||
}
|
||||
return AABB {
|
||||
.min = tmin,
|
||||
.max = tmax,
|
||||
};
|
||||
}
|
||||
void adjust(const Math::Vector vertex)
|
||||
{
|
||||
min.x = std::min(min.x, vertex.x);
|
||||
min.y = std::min(min.y, vertex.y);
|
||||
min.z = std::min(min.z, vertex.z);
|
||||
|
||||
max.x = std::max(max.x, vertex.x);
|
||||
max.y = std::max(max.y, vertex.y);
|
||||
max.z = std::max(max.z, vertex.z);
|
||||
}
|
||||
AABB combine(const AABB& other) const
|
||||
{
|
||||
return AABB {
|
||||
.min = Math::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 (
|
||||
std::max(max.x, other.max.x),
|
||||
std::max(max.y, other.max.y),
|
||||
std::max(max.z, other.max.z)
|
||||
),
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -1,8 +1,17 @@
|
||||
target_sources(Engine
|
||||
PRIVATE
|
||||
AABB.h
|
||||
BoxCollider.h
|
||||
Camera.h
|
||||
Camera.cpp
|
||||
Component.h
|
||||
Collider.h
|
||||
Collider.cpp
|
||||
MeshCollider.h
|
||||
RigidBody.h
|
||||
ShapeBase.h
|
||||
ShapeBase.cpp
|
||||
SphereCollider.h
|
||||
StaticMesh.h
|
||||
Transform.h
|
||||
Transform.cpp)
|
||||
@@ -10,7 +19,14 @@ target_sources(Engine
|
||||
target_sources(Engine
|
||||
PUBLIC FILE_SET HEADERS
|
||||
FILES
|
||||
AABB.h
|
||||
BoxCollider.h
|
||||
Camera.h
|
||||
Component.h
|
||||
Collider.h
|
||||
MeshCollider.h
|
||||
RigidBody.h
|
||||
ShapeBase.h
|
||||
SphereCollider.h
|
||||
StaticMesh.h
|
||||
Transform.h)
|
||||
@@ -40,15 +40,15 @@ struct Camera
|
||||
void buildProjectionMatrix();
|
||||
Math::Matrix4 viewMatrix;
|
||||
Math::Matrix4 projectionMatrix;
|
||||
//Transforms relative to actor
|
||||
float yaw;
|
||||
float pitch;
|
||||
private:
|
||||
bool bNeedsViewBuild;
|
||||
bool bNeedsProjectionBuild;
|
||||
|
||||
Gfx::PViewport viewport;
|
||||
|
||||
//Transforms relative to actor
|
||||
float yaw;
|
||||
float pitch;
|
||||
};
|
||||
} // namespace Component
|
||||
} // namespace Seele
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "Collider.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Component;
|
||||
|
||||
Collider Collider::transform(const Transform& transform) const
|
||||
{
|
||||
return Collider{
|
||||
.type = this->type,
|
||||
.boundingbox = this->boundingbox.getTransformedBox(transform.toMatrix()),
|
||||
.physicsMesh = this->physicsMesh.transform(transform),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "AABB.h"
|
||||
#include "ShapeBase.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
enum class ColliderType
|
||||
{
|
||||
STATIC,
|
||||
DYNAMIC,
|
||||
};
|
||||
struct Collider
|
||||
{
|
||||
ColliderType type;
|
||||
AABB boundingbox;
|
||||
ShapeBase physicsMesh;
|
||||
Collider transform(const Transform& transform) const;
|
||||
};
|
||||
} // namespace Component
|
||||
} // namespace Seele
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "AABB.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
struct RigidBody
|
||||
{
|
||||
float mass = 1.0f;
|
||||
Math::Vector force;
|
||||
Math::Vector torque;
|
||||
Math::Vector linearMomentum;
|
||||
Math::Vector angularMomentum;
|
||||
};
|
||||
} // namespace Component
|
||||
} // namespace Seele
|
||||
@@ -0,0 +1,226 @@
|
||||
#include "ShapeBase.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Component;
|
||||
|
||||
|
||||
//https://people.eecs.berkeley.edu/~jfc/mirtich/massProps.html
|
||||
struct ComputationState
|
||||
{
|
||||
// compute physics properties
|
||||
int A; /* alpha */
|
||||
int B; /* beta */
|
||||
int C; /* gamma */
|
||||
|
||||
/* projection integrals */
|
||||
float P1, Pa, Pb, Paa, Pab, Pbb, Paaa, Paab, Pabb, Pbbb;
|
||||
|
||||
/* face integrals */
|
||||
float Fa, Fb, Fc, Faa, Fbb, Fcc, Faaa, Fbbb, Fccc, Faab, Fbbc, Fcca;
|
||||
|
||||
/* volume integrals */
|
||||
float T0;
|
||||
Math::Vector T1, T2, TP;
|
||||
};
|
||||
|
||||
struct Face
|
||||
{
|
||||
StaticArray<Math::Vector, 3> vertices;
|
||||
Math::Vector normal;
|
||||
float w;
|
||||
};
|
||||
|
||||
void computeProjectionIntegrals(Face& f, ComputationState& state)
|
||||
{
|
||||
state.P1 = state.Pa = state.Pb = state.Paa = state.Pab = state.Pbb = state.Paaa = state.Paab = state.Pabb = state.Pbbb = 0.0;
|
||||
for(uint32_t i = 0; i < 3; ++i)
|
||||
{
|
||||
float a0 = f.vertices[i][state.A];
|
||||
float b0 = f.vertices[i][state.B];
|
||||
float a1 = f.vertices[(i+1)%3][state.A];
|
||||
float b1 = f.vertices[(i+1)%3][state.B];
|
||||
|
||||
float da = a1 - a0;
|
||||
float db = b1 - b0;
|
||||
|
||||
float a0_2 = a0 * a0, a0_3 = a0_2 * a0, a0_4 = a0_3 * a0;
|
||||
float b0_2 = b0 * b0, b0_3 = b0_2 * b0, b0_4 = b0_3 * b0;
|
||||
float a1_2 = a1 * a1, a1_3 = a1_2 * a1;
|
||||
float b1_2 = b1 * b1, b1_3 = b1_2 * b1;
|
||||
|
||||
float C1 = a1 + a0;
|
||||
float Ca = a1 * C1 + a0_2;
|
||||
float Caa = a1 * Ca + a0_3;
|
||||
float Caaa = a1 * Caa + a0_4;
|
||||
float Cb = b1 * (b1 + b0) + b0_2;
|
||||
float Cbb = b1 * Cb + b0_3;
|
||||
float Cbbb = b1 * Cbb + b0_4;
|
||||
float Cab = 3 * a1_2 + 2 * a1 * a0 + a0_2;
|
||||
float Kab = a1_2 + 2 * a1 * a0 + 3 * a0_2;
|
||||
float Caab = a0 * Cab + 4 * a1_3;
|
||||
float Kaab = a1 * Kab + 4 * a0_3;
|
||||
float Cabb = 4 * b1_3 + 3 * b1_2 * b0 + 2 * b1 * b0_2 + b0_3;
|
||||
float Kabb = b1_3 + 2 * b1_2 * b0 + 3 * b1 * b0_2 + 4 * b0_3;
|
||||
|
||||
state.P1 += db * C1;
|
||||
state.Pa += db * Ca;
|
||||
state.Paa += db * Caa;
|
||||
state.Paaa += db * Caaa;
|
||||
state.Pb += da * Cb;
|
||||
state.Pbb += da * Cbb;
|
||||
state.Pbbb += da * Cbbb;
|
||||
state.Pab += db * (b1 * Cab + b0 * Kab);
|
||||
state.Paab += db * (b1 * Caab + b0 * Kaab);
|
||||
state.Pabb += da * (a1 * Cabb + a0 * Kabb);
|
||||
}
|
||||
|
||||
state.P1 /= 2.0;
|
||||
state.Pa /= 6.0;
|
||||
state.Paa /= 12.0;
|
||||
state.Paaa /= 20.0;
|
||||
state.Pb /= -6.0;
|
||||
state.Pbb /= -12.0;
|
||||
state.Pbbb /= -20.0;
|
||||
state.Pab /= 24.0;
|
||||
state.Paab /= 60.0;
|
||||
state.Pabb /= -60.0;
|
||||
}
|
||||
|
||||
void computeFaceIntegrals(Face& f, ComputationState& state)
|
||||
{
|
||||
computeProjectionIntegrals(f, state);
|
||||
float k1 = 1.0f/f.normal[state.C];
|
||||
float k2 = k1 * k1;
|
||||
float k3 = k2 * k1;
|
||||
float k4 = k3 * k1;
|
||||
|
||||
glm::vec3 n = f.normal;
|
||||
float w = f.w;
|
||||
|
||||
state.Fa = k1 * state.Pa;
|
||||
state.Fb = k1 * state.Pb;
|
||||
state.Fc = -k2 * (n[state.A] * state.Pa + n[state.B] * state.Pb + f.w * state.P1);
|
||||
|
||||
state.Faa = k1 * state.Paa;
|
||||
state.Fbb = k1 * state.Pbb;
|
||||
state.Fcc = k3 * (n[state.A] * n[state.A] * state.Paa
|
||||
+ 2 * n[state.A] * n[state.B] * state.Pab
|
||||
+ n[state.B] * n[state.B] * state.Pbb
|
||||
+ w * (2 * (n[state.A] * state.Pa + n[state.B] * state.Pb) + w * state.P1));
|
||||
|
||||
state.Faaa = k1 * state.Paaa;
|
||||
state.Fbbb = k1 * state.Pbbb;
|
||||
state.Fccc = -k4 * (n[state.A] * n[state.A] * n[state.A] * state.Paaa
|
||||
+ 3 * n[state.A] * n[state.A] * n[state.B] * state.Paab
|
||||
+ 3 * n[state.A] * n[state.B] * n[state.B] * state.Pabb
|
||||
+ 3 * n[state.B] * n[state.B] * n[state.B] * state.Pbbb
|
||||
+ 3 * w * (n[state.A] * n[state.A] * state.Paa
|
||||
+ 2 * n[state.A] * n[state.B] * state.Pa
|
||||
+ n[state.B] * n[state.B] * state.Pbb)
|
||||
+ w * w *(3 * (n[state.A]*state.Pa + n[state.B]*state.Pb) + w * state.P1)
|
||||
);
|
||||
|
||||
state.Faab = k1 * state.Paab;
|
||||
state.Fbbc = -k2 * (n[state.A] * state.Paab + n[state.B] * state.Pbbb + w * state.Pbb);
|
||||
state.Fcca = k3 * (n[state.A] * n[state.A] * state.Paa + 2 * n[state.A] * n[state.B] * state.Paab + n[state.B] * n[state.B] * state.Pabb
|
||||
+ 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)
|
||||
{
|
||||
std::memset(&state, 0, sizeof(ComputationState));
|
||||
for (size_t i = 0; i < indices.size(); i+=3)
|
||||
{
|
||||
Face f;
|
||||
f.vertices = {
|
||||
vertices[indices[i]],
|
||||
vertices[indices[i+1]],
|
||||
vertices[indices[i+2]],
|
||||
};
|
||||
|
||||
Math::Vector e1 = f.vertices[2] - f.vertices[0];
|
||||
Math::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
|
||||
- f.normal.z * f.vertices[0].z;
|
||||
|
||||
float nx = std::abs(f.normal.x);
|
||||
float ny = std::abs(f.normal.y);
|
||||
float nz = std::abs(f.normal.z);
|
||||
if (nx > ny && nx > nz) state.C = 0;
|
||||
else state.C = (ny > nz) ? 1 : 2;
|
||||
state.A = (state.C + 1) % 3;
|
||||
state.B = (state.A + 1) % 3;
|
||||
|
||||
computeFaceIntegrals(f, state);
|
||||
|
||||
state.T0 += f.normal.x * ((state.A == 0) ? state.Fa : ((state.B == 0) ? state.Fb : state.Fc));
|
||||
state.T1[state.A] += f.normal[state.A] * state.Faa;
|
||||
state.T1[state.B] += f.normal[state.B] * state.Fbb;
|
||||
state.T1[state.C] += f.normal[state.C] * state.Fcc;
|
||||
state.T2[state.A] += f.normal[state.A] * state.Faaa;
|
||||
state.T2[state.B] += f.normal[state.B] * state.Fbbb;
|
||||
state.T2[state.C] += f.normal[state.C] * state.Fccc;
|
||||
state.TP[state.A] += f.normal[state.A] * state.Faab;
|
||||
state.TP[state.B] += f.normal[state.B] * state.Fbbc;
|
||||
state.TP[state.C] += f.normal[state.C] * state.Fcca;
|
||||
}
|
||||
state.T1 /= 2.0f;
|
||||
state.T2 /= 3.0f;
|
||||
state.TP /= 2.0f;
|
||||
}
|
||||
|
||||
void computePhysicsParamsForMesh(Array<Math::Vector>& vertices, const Array<uint32_t>& indices, Math::Matrix3& bodyInertia, Math::Vector& centerOfMass, float& mass)
|
||||
{
|
||||
ComputationState state;
|
||||
computeVolumeIntegrals(vertices, indices, state);
|
||||
float density = 1;
|
||||
mass = density * state.T0;
|
||||
Math::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);
|
||||
bodyInertia[2][2] = density * (state.T2.x + state.T2.y);
|
||||
bodyInertia[0][1] = bodyInertia[1][0] = - density * state.TP.x;
|
||||
bodyInertia[1][2] = bodyInertia[2][1] = - density * state.TP.y;
|
||||
bodyInertia[2][1] = bodyInertia[1][2] = - density * state.TP.z;
|
||||
|
||||
bodyInertia[0][0] -= mass * (r.y * r.y + r.z * r.z);
|
||||
bodyInertia[1][1] -= mass * (r.z * r.z + r.x * r.x);
|
||||
bodyInertia[2][2] -= mass * (r.x * r.x + r.y * r.y);
|
||||
bodyInertia[0][1] = bodyInertia[1][0] += mass * r.x * r.y;
|
||||
bodyInertia[1][2] = bodyInertia[2][1] += mass * r.y * r.z;
|
||||
bodyInertia[2][1] = bodyInertia[1][2] += mass * r.z * r.x;
|
||||
}
|
||||
|
||||
ShapeBase::ShapeBase(Array<Math::Vector> vertices, Array<uint32> indices)
|
||||
: vertices(vertices)
|
||||
, indices(indices)
|
||||
{
|
||||
computePhysicsParamsForMesh(vertices, indices, bodyInertia, centerOfMass, mass);
|
||||
}
|
||||
|
||||
ShapeBase ShapeBase::transform(const Component::Transform& transform) const
|
||||
{
|
||||
ShapeBase result = *this;
|
||||
for(auto& vert : result.vertices)
|
||||
{
|
||||
vert = transform.toMatrix() * Math::Vector4(vert, 1.0f);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ShapeBase::addCollider(Array<Math::Vector> verts, Array<uint32> inds, Math::Matrix4 matrix)
|
||||
{
|
||||
size_t indOffset = vertices.size();
|
||||
for(auto vert : verts)
|
||||
{
|
||||
vertices.add(Math::Vector(matrix * Math::Vector4(vert, 1.0f)));
|
||||
}
|
||||
for(auto ind : inds)
|
||||
{
|
||||
indices.add(ind + static_cast<uint32>(indOffset));
|
||||
}
|
||||
computePhysicsParamsForMesh(vertices, indices, bodyInertia, centerOfMass, mass);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "Containers/Array.h"
|
||||
#include "Transform.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Component
|
||||
{
|
||||
struct ShapeBase
|
||||
{
|
||||
ShapeBase(Array<Math::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;
|
||||
float mass;
|
||||
Math::Matrix3 bodyInertia;
|
||||
Array<Math::Vector> vertices;
|
||||
Array<uint32> indices;
|
||||
};
|
||||
} // namespace Component
|
||||
} // namespace Seele
|
||||
@@ -4,31 +4,57 @@ using namespace Seele::Component;
|
||||
|
||||
DEFINE_COMPONENT(Transform)
|
||||
|
||||
|
||||
void Transform::setPosition(Math::Vector pos)
|
||||
{
|
||||
transform.setPosition(pos);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void Transform::setRotation(Math::Quaternion quat)
|
||||
{
|
||||
transform.setRotation(quat);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void Transform::setScale(Math::Vector scale)
|
||||
{
|
||||
transform.setScale(scale);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void Transform::setRelativeLocation(Math::Vector location)
|
||||
{
|
||||
transform = Math::Transform(location, transform.getRotation(), transform.getScale());
|
||||
dirty = true;
|
||||
}
|
||||
void Transform::setRelativeRotation(Math::Vector rotation)
|
||||
{
|
||||
transform = Math::Transform(transform.getPosition(), Math::Quaternion(rotation), transform.getScale());
|
||||
dirty = true;
|
||||
}
|
||||
void Transform::setRelativeRotation(Math::Quaternion rotation)
|
||||
{
|
||||
transform = Math::Transform(transform.getPosition(), rotation, transform.getScale());
|
||||
dirty = true;
|
||||
}
|
||||
void Transform::setRelativeScale(Math::Vector scale)
|
||||
{
|
||||
transform = Math::Transform(transform.getPosition(), transform.getRotation(), scale);
|
||||
dirty = true;
|
||||
}
|
||||
void Transform::addRelativeLocation(Math::Vector translation)
|
||||
{
|
||||
transform = Math::Transform(transform.getPosition() + translation, transform.getRotation(), transform.getScale());
|
||||
dirty = true;
|
||||
}
|
||||
void Transform::addRelativeRotation(Math::Vector rotation)
|
||||
{
|
||||
transform = Math::Transform(transform.getPosition(), transform.getRotation() * Math::Quaternion(rotation), transform.getScale());
|
||||
dirty = true;
|
||||
}
|
||||
void Transform::addRelativeRotation(Math::Quaternion rotation)
|
||||
{
|
||||
transform = Math::Transform(transform.getPosition(), transform.getRotation() * rotation, transform.getScale());
|
||||
dirty = true;
|
||||
}
|
||||
@@ -8,23 +8,6 @@ namespace Component
|
||||
{
|
||||
struct Transform
|
||||
{
|
||||
Transform() {}
|
||||
Transform(const Transform& other) : transform(other.transform) {}
|
||||
Transform(Transform&& other) : transform(other.transform) {}
|
||||
Transform& operator=(const Transform& other) {
|
||||
if (&other != this)
|
||||
{
|
||||
transform = other.transform;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Transform& operator=(Transform&& other) {
|
||||
if(&other != this)
|
||||
{
|
||||
transform = std::move(other.transform);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Math::Vector getPosition() const { return transform.getPosition(); }
|
||||
Math::Quaternion getRotation() const { return transform.getRotation(); }
|
||||
Math::Vector getScale() const { return transform.getScale(); }
|
||||
@@ -35,6 +18,13 @@ struct Transform
|
||||
|
||||
Math::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 setRelativeLocation(Math::Vector location);
|
||||
void setRelativeRotation(Math::Quaternion rotation);
|
||||
void setRelativeRotation(Math::Vector rotation);
|
||||
@@ -44,6 +34,7 @@ struct Transform
|
||||
void addRelativeRotation(Math::Quaternion rotation);
|
||||
void addRelativeRotation(Math::Vector rotation);
|
||||
private:
|
||||
bool dirty = true;
|
||||
Math::Transform transform;
|
||||
};
|
||||
DECLARE_COMPONENT(Transform)
|
||||
|
||||
Reference in New Issue
Block a user