feat: replace position and rotation with cframe
This commit is contained in:
parent
c7ea5c5563
commit
5ee493dc97
12 changed files with 207 additions and 23 deletions
|
@ -118,15 +118,15 @@ void processInput(GLFWwindow* window) {
|
|||
float shiftFactor = (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) ? -0.5 : 0.5;
|
||||
shiftFactor *= deltaTime;
|
||||
if (glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS) {
|
||||
lastPart->rotation *= glm::angleAxis(shiftFactor, glm::vec3(1, 0, 0));
|
||||
// lastPart->rotation *= glm::angleAxis(shiftFactor, glm::vec3(1, 0, 0));
|
||||
syncPartPhysics(lastPart);
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_Y) == GLFW_PRESS) {
|
||||
lastPart->rotation *= glm::angleAxis(shiftFactor, glm::vec3(0, 1, 0));
|
||||
// lastPart->rotation *= glm::angleAxis(shiftFactor, glm::vec3(0, 1, 0));
|
||||
syncPartPhysics(lastPart);
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS) {
|
||||
lastPart->rotation *= glm::angleAxis(shiftFactor, glm::vec3(0, 0, 1));
|
||||
// lastPart->rotation *= glm::angleAxis(shiftFactor, glm::vec3(0, 0, 1));
|
||||
syncPartPhysics(lastPart);
|
||||
}
|
||||
}
|
||||
|
@ -178,15 +178,15 @@ void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods
|
|||
float shiftFactor = (mods & GLFW_MOD_SHIFT) ? -0.2 : 0.2;
|
||||
if (mode == 0) {
|
||||
if (key == GLFW_KEY_X && action == GLFW_PRESS) {
|
||||
lastPart->position.x += shiftFactor;
|
||||
// lastPart->position.x += shiftFactor;
|
||||
syncPartPhysics(lastPart);
|
||||
}
|
||||
if (key == GLFW_KEY_Y && action == GLFW_PRESS) {
|
||||
lastPart->position.y += shiftFactor;
|
||||
// lastPart->position.y += shiftFactor;
|
||||
syncPartPhysics(lastPart);
|
||||
}
|
||||
if (key == GLFW_KEY_Z && action == GLFW_PRESS) {
|
||||
lastPart->position.z += shiftFactor;
|
||||
// lastPart->position.z += shiftFactor;
|
||||
syncPartPhysics(lastPart);
|
||||
}
|
||||
} else if (mode == 1) {
|
||||
|
|
|
@ -74,8 +74,9 @@ void MainGLWidget::handleObjectDrag(QMouseEvent* evt) {
|
|||
});
|
||||
|
||||
if (!rayHit) return;
|
||||
draggingObject->lock()->position = rpToGlm(rayHit->worldPoint);
|
||||
draggingObject->lock()->position += rpToGlm(rayHit->worldNormal) * draggingObject->lock()->scale / 2.f;
|
||||
Data::Vector3 vec = rayHit->worldPoint;
|
||||
vec = vec + Data::Vector3(rpToGlm(rayHit->worldNormal) * draggingObject->lock()->scale / 2.f);
|
||||
draggingObject->lock()->cframe = draggingObject->lock()->cframe.Rotation() + vec;
|
||||
syncPartPhysics(draggingObject->lock());
|
||||
}
|
||||
|
||||
|
|
82
src/datatypes/cframe.cpp
Normal file
82
src/datatypes/cframe.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
#include "cframe.h"
|
||||
#include "datatypes/vector.h"
|
||||
#include "physics/util.h"
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <reactphysics3d/mathematics/Transform.h>
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/gtx/euler_angles.hpp>
|
||||
|
||||
Data::CFrame::CFrame(glm::vec3 translation, glm::mat3 rotation)
|
||||
: translation(translation)
|
||||
, rotation(rotation) {
|
||||
}
|
||||
|
||||
Data::CFrame::CFrame(Data::Vector3 position, glm::quat quat)
|
||||
: translation(position)
|
||||
, rotation(quat) {
|
||||
}
|
||||
|
||||
Data::CFrame::CFrame(const rp::Transform& transform) : Data::CFrame::CFrame(rpToGlm(transform.getPosition()), rpToGlm(transform.getOrientation())) {
|
||||
}
|
||||
|
||||
glm::mat3 lookAt(Data::Vector3 position, Data::Vector3 lookAt, Data::Vector3 up) {
|
||||
// https://github.com/sgorsten/glm/issues/29#issuecomment-743989030
|
||||
Data::Vector3 f = (lookAt - position).Unit(); // Forward/Look
|
||||
Data::Vector3 u = up.Unit(); // Up
|
||||
Data::Vector3 s = f.Cross(u).Unit(); // Right
|
||||
u = s.Cross(u);
|
||||
|
||||
return {
|
||||
{ s.X(), u.X(), -f.X() },
|
||||
{ s.Y(), u.Y(), -f.Y() },
|
||||
{ s.Z(), u.Z(), -f.Z() },
|
||||
};
|
||||
}
|
||||
|
||||
Data::CFrame::CFrame(Data::Vector3 position, Data::Vector3 lookAt, Data::Vector3 up)
|
||||
: translation(position)
|
||||
, rotation(::lookAt(position, lookAt, up)) {
|
||||
}
|
||||
|
||||
Data::CFrame::~CFrame() = default;
|
||||
const Data::TypeInfo Data::CFrame::TYPE = {
|
||||
.name = "CFrame",
|
||||
};
|
||||
|
||||
const Data::TypeInfo& Data::CFrame::GetType() const { return Data::Vector3::TYPE; };
|
||||
|
||||
const Data::String Data::CFrame::ToString() const {
|
||||
return std::to_string(X()) + ", " + std::to_string(Y()) + ", " + std::to_string(Z());
|
||||
}
|
||||
|
||||
Data::CFrame::operator glm::mat4() const {
|
||||
// Always make sure to translate the position first, then rotate. Matrices work backwards
|
||||
return glm::translate(glm::mat4(1.0f), this->translation) * glm::mat4(this->rotation);
|
||||
}
|
||||
|
||||
Data::CFrame::operator rp::Transform() const {
|
||||
return rp::Transform(glmToRp(translation), glmToRp(rotation));
|
||||
}
|
||||
|
||||
Data::Vector3 Data::CFrame::ToEulerAnglesXYZ() {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
glm::extractEulerAngleXYZ(glm::mat4(this->rotation), x, y, z);
|
||||
return Data::Vector3(x, y, z);
|
||||
}
|
||||
|
||||
Data::CFrame Data::CFrame::FromEulerAnglesXYZ(Data::Vector3 vector) {
|
||||
glm::mat3 mat = glm::eulerAngleXYZ(vector.X(), vector.Y(), vector.Z());
|
||||
return Data::CFrame(Data::Vector3::ZERO, glm::column(mat, 2), (Data::Vector3)glm::column(mat, 1)); // Getting LookAt (3rd) and Up (2nd) vectors
|
||||
}
|
||||
|
||||
// Operators
|
||||
|
||||
Data::CFrame Data::CFrame::operator +(Data::Vector3 vector) const {
|
||||
return CFrame { this->translation + glm::vec3(vector), this->rotation };
|
||||
}
|
||||
|
||||
Data::CFrame Data::CFrame::operator -(Data::Vector3 vector) const {
|
||||
return *this + -vector;
|
||||
}
|
56
src/datatypes/cframe.h
Normal file
56
src/datatypes/cframe.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
#include "base.h"
|
||||
#include "datatypes/vector.h"
|
||||
#include <glm/ext/matrix_float3x3.hpp>
|
||||
#include <glm/ext/quaternion_geometric.hpp>
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
#include <glm/fwd.hpp>
|
||||
#include <glm/gtc/matrix_access.hpp>
|
||||
#include <reactphysics3d/mathematics/Transform.h>
|
||||
#include <reactphysics3d/reactphysics3d.h>
|
||||
|
||||
namespace rp = reactphysics3d;
|
||||
|
||||
namespace Data {
|
||||
class CFrame : Base {
|
||||
glm::vec3 translation;
|
||||
glm::mat3 rotation;
|
||||
|
||||
CFrame(glm::vec3, glm::mat3);
|
||||
public:
|
||||
// CFrame(float x, float y, float z);
|
||||
// CFrame(const glm::vec3&);
|
||||
// CFrame(const rp::Vector3&);
|
||||
CFrame(const rp::Transform&);
|
||||
CFrame(Data::Vector3 position, glm::quat quat);
|
||||
CFrame(Data::Vector3 position, Data::Vector3 lookAt, Data::Vector3 up = Data::Vector3(0, 1, 0));
|
||||
~CFrame();
|
||||
|
||||
virtual const TypeInfo& GetType() const override;
|
||||
static const TypeInfo TYPE;
|
||||
|
||||
virtual const Data::String ToString() const override;
|
||||
|
||||
operator glm::mat4() const;
|
||||
operator rp::Transform() const;
|
||||
|
||||
//inline static CFrame identity() { }
|
||||
inline Vector3 Position() const { return translation; }
|
||||
inline CFrame Rotation() const { return CFrame { glm::vec3(0, 0, 0), rotation }; }
|
||||
inline float X() const { return translation.x; }
|
||||
inline float Y() const { return translation.y; }
|
||||
inline float Z() const { return translation.z; }
|
||||
|
||||
inline Vector3 RightVector() { return glm::column(rotation, 0); }
|
||||
inline Vector3 UpVector() { return glm::column(rotation, 1); }
|
||||
inline Vector3 LookVector() { return glm::column(rotation, 2); }
|
||||
|
||||
Vector3 ToEulerAnglesXYZ();
|
||||
static CFrame FromEulerAnglesXYZ(Data::Vector3);
|
||||
|
||||
// Operators
|
||||
Data::CFrame operator +(Data::Vector3) const;
|
||||
Data::CFrame operator -(Data::Vector3) const;
|
||||
};
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <variant>
|
||||
#include "base.h"
|
||||
#include "vector.h"
|
||||
#include <variant>
|
||||
#include "cframe.h"
|
||||
|
||||
// #define __VARIANT_TYPE std::variant< \
|
||||
// Null, \
|
||||
|
@ -19,7 +20,8 @@ namespace Data {
|
|||
Int,
|
||||
Float,
|
||||
String,
|
||||
Vector3
|
||||
Vector3,
|
||||
CFrame
|
||||
> __VARIANT_TYPE;
|
||||
|
||||
class Variant {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "vector.h"
|
||||
#include <glm/ext/quaternion_geometric.hpp>
|
||||
|
||||
Data::Vector3::Vector3(const glm::vec3& src) : vector(src) {};
|
||||
Data::Vector3::Vector3(const rp::Vector3& src) : vector(glm::vec3(src.x, src.y, src.z)) {};
|
||||
|
@ -11,9 +12,33 @@ const Data::TypeInfo Data::Vector3::TYPE = {
|
|||
|
||||
const Data::TypeInfo& Data::Vector3::GetType() const { return Data::Vector3::TYPE; };
|
||||
|
||||
Data::Vector3 Data::Vector3::ZERO(0, 0, 0);
|
||||
Data::Vector3 Data::Vector3::ONE(1, 1, 1);
|
||||
|
||||
const Data::String Data::Vector3::ToString() const {
|
||||
return std::to_string(X()) + ", " + std::to_string(Y()) + ", " + std::to_string(Z());
|
||||
}
|
||||
|
||||
Data::Vector3::operator glm::vec3() const { return vector; };
|
||||
Data::Vector3::operator rp::Vector3() const { return rp::Vector3(X(), Y(), Z()); };
|
||||
Data::Vector3::operator rp::Vector3() const { return rp::Vector3(X(), Y(), Z()); };
|
||||
|
||||
// Operators
|
||||
Data::Vector3 Data::Vector3::operator +(Data::Vector3 other) const {
|
||||
return Data::Vector3(this->X() + other.X(), this->Y() + other.Y(), this->Z() + other.Z());
|
||||
}
|
||||
|
||||
Data::Vector3 Data::Vector3::operator -(Data::Vector3 other) const {
|
||||
return Data::Vector3(this->X() - other.X(), this->Y() - other.Y(), this->Z() - other.Z());
|
||||
}
|
||||
|
||||
Data::Vector3 Data::Vector3::operator -() const {
|
||||
return Data::Vector3(-this->X(), -this->Y(), -this->Z());
|
||||
}
|
||||
|
||||
Data::Vector3 Data::Vector3::Cross(Data::Vector3 other) const {
|
||||
return glm::cross(this->vector, other.vector);
|
||||
}
|
||||
|
||||
float Data::Vector3::Dot(Data::Vector3 other) const {
|
||||
return glm::dot(this->vector, other.vector);
|
||||
}
|
|
@ -9,7 +9,7 @@ namespace rp = reactphysics3d;
|
|||
|
||||
namespace Data {
|
||||
class Vector3 : Base {
|
||||
const glm::vec3 vector;
|
||||
glm::vec3 vector;
|
||||
|
||||
public:
|
||||
Vector3(float x, float y, float z);
|
||||
|
@ -20,6 +20,9 @@ namespace Data {
|
|||
virtual const TypeInfo& GetType() const override;
|
||||
static const TypeInfo TYPE;
|
||||
|
||||
static Data::Vector3 ZERO;
|
||||
static Data::Vector3 ONE;
|
||||
|
||||
virtual const Data::String ToString() const override;
|
||||
|
||||
operator glm::vec3() const;
|
||||
|
@ -29,5 +32,14 @@ namespace Data {
|
|||
inline float Y() const { return vector.y; }
|
||||
inline float Z() const { return vector.z; }
|
||||
inline float Magnitude() const { return glm::length(vector); }
|
||||
inline Data::Vector3 Unit() const { return glm::normalize(vector); }
|
||||
|
||||
Data::Vector3 Cross(Data::Vector3) const;
|
||||
float Dot(Data::Vector3) const;
|
||||
|
||||
// Operators
|
||||
Data::Vector3 operator +(Data::Vector3) const;
|
||||
Data::Vector3 operator -(Data::Vector3) const;
|
||||
Data::Vector3 operator -() const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "part.h"
|
||||
#include "base/instance.h"
|
||||
#include "datatypes/base.h"
|
||||
#include "datatypes/cframe.h"
|
||||
#include "datatypes/vector.h"
|
||||
#include "objects/base/member.h"
|
||||
#include <memory>
|
||||
|
@ -21,13 +22,13 @@ const InstanceType* Part::GetClass() {
|
|||
Part::Part(): Part(PartConstructParams {}) {
|
||||
}
|
||||
|
||||
Part::Part(PartConstructParams params): Instance(&TYPE), position(params.position), rotation(params.rotation),
|
||||
Part::Part(PartConstructParams params): Instance(&TYPE), cframe(Data::CFrame(params.position, params.rotation)),
|
||||
scale(params.scale), material(params.material), anchored(params.anchored) {
|
||||
this->memberMap = std::make_unique<MemberMap>(MemberMap {
|
||||
.super = std::move(this->memberMap),
|
||||
.members = {
|
||||
{ "Anchored", { .backingField = &anchored, .type = &Data::Bool::TYPE, .codec = fieldCodecOf<Data::Bool, bool>(), .updateCallback = memberFunctionOf(&Part::onUpdated, this) } },
|
||||
{ "Position", { .backingField = &position, .type = &Data::Vector3::TYPE, .codec = fieldCodecOf<Data::Vector3, glm::vec3>(), .updateCallback = memberFunctionOf(&Part::onUpdated, this) } }
|
||||
// { "Position", { .backingField = &position, .type = &Data::Vector3::TYPE, .codec = fieldCodecOf<Data::Vector3, glm::vec3>(), .updateCallback = memberFunctionOf(&Part::onUpdated, this) } }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/ext.hpp>
|
||||
#include "../rendering/material.h"
|
||||
#include "datatypes/cframe.h"
|
||||
#include "datatypes/vector.h"
|
||||
#include <reactphysics3d/reactphysics3d.h>
|
||||
|
||||
|
@ -28,8 +29,7 @@ public:
|
|||
const static InstanceType TYPE;
|
||||
|
||||
// TODO: Switch these over to our dedicated datatypes
|
||||
glm::vec3 position;
|
||||
glm::quat rotation = glm::identity<glm::quat>();
|
||||
Data::CFrame cframe;
|
||||
glm::vec3 scale;
|
||||
Material material;
|
||||
bool selected = false;
|
||||
|
@ -45,4 +45,6 @@ public:
|
|||
static inline std::shared_ptr<Part> New(PartConstructParams params) { return std::make_shared<Part>(params); };
|
||||
static inline InstanceRef CreateGeneric() { return std::make_shared<Part>(); };
|
||||
virtual const InstanceType* GetClass() override;
|
||||
|
||||
inline Data::Vector3 position() { return cframe.Position(); }
|
||||
};
|
|
@ -17,6 +17,7 @@
|
|||
#include <reactphysics3d/reactphysics3d.h>
|
||||
#include "../common.h"
|
||||
#include "../objects/part.h"
|
||||
#include "datatypes/cframe.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "simulation.h"
|
||||
|
@ -45,7 +46,7 @@ void simulationInit() {
|
|||
void syncPartPhysics(std::shared_ptr<Part> part) {
|
||||
glm::mat4 rotMat = glm::mat4(1.0f);
|
||||
|
||||
rp::Transform transform(glmToRp(part->position), glmToRp(part->rotation));
|
||||
rp::Transform transform = part->cframe;
|
||||
if (!part->rigidBody) {
|
||||
part->rigidBody = world->createRigidBody(transform);
|
||||
} else {
|
||||
|
@ -76,9 +77,7 @@ void physicsStep(float deltaTime) {
|
|||
if (obj->GetClass()->className != "Part") continue; // TODO: Replace this with a .IsA call instead of comparing the class name directly
|
||||
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(obj);
|
||||
const rp::Transform& transform = part->rigidBody->getTransform();
|
||||
part->position = rpToGlm(transform.getPosition());
|
||||
// part.rotation = glm::eulerAngles(rpToGlm(transform.getOrientation()));
|
||||
part->rotation = rpToGlm(transform.getOrientation());
|
||||
part->cframe = Data::CFrame(transform);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <glm/ext/vector_float3.hpp>
|
||||
#include <memory>
|
||||
#include <reactphysics3d/body/Body.h>
|
||||
#include <reactphysics3d/mathematics/Matrix3x3.h>
|
||||
#include <reactphysics3d/mathematics/Quaternion.h>
|
||||
#include <reactphysics3d/mathematics/Vector3.h>
|
||||
#include <reactphysics3d/mathematics/mathematics.h>
|
||||
|
@ -18,6 +19,10 @@ inline rp::Quaternion glmToRp(glm::quat quat) {
|
|||
return rp::Quaternion(quat.w, rp::Vector3(quat.x, quat.y, quat.z));
|
||||
}
|
||||
|
||||
// inline rp::Matrix3x3 glmToRp(glm::mat3 mat) {
|
||||
// return (rp::Quaternion)glmToRp((glm::quat)mat);
|
||||
// }
|
||||
|
||||
inline glm::vec3 rpToGlm(rp::Vector3 vec) {
|
||||
return glm::vec3(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "physics/util.h"
|
||||
#include "shader.h"
|
||||
#include "mesh.h"
|
||||
#include "defaultmeshes.h"
|
||||
|
@ -109,9 +110,7 @@ void renderParts() {
|
|||
if (inst->GetClass()->className != "Part") continue;
|
||||
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst);
|
||||
|
||||
glm::mat4 model = glm::mat4(1.0f);
|
||||
model = glm::translate(model, part->position);
|
||||
model = model * glm::mat4_cast(part->rotation);
|
||||
glm::mat4 model = part->cframe;
|
||||
model = glm::scale(model, part->scale);
|
||||
shader->set("model", model);
|
||||
shader->set("material", part->material);
|
||||
|
|
Loading…
Add table
Reference in a new issue