Compare commits

...

5 commits

6 changed files with 75 additions and 5 deletions

View file

@ -42,9 +42,9 @@ glm::mat3 lookAt(Data::Vector3 position, Data::Vector3 lookAt, Data::Vector3 up)
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(f);
u = s.Cross(f).Unit();
return { s, u, f };
return { s, u, -f };
}
Data::CFrame::CFrame(Data::Vector3 position, Data::Vector3 lookAt, Data::Vector3 up)

View file

@ -51,6 +51,10 @@ Data::Vector3 Data::Vector3::operator -() const {
return Data::Vector3(-this->X(), -this->Y(), -this->Z());
}
bool Data::Vector3::operator ==(Data::Vector3 other) const {
return this->X() == other.X() && this->Y() == other.Y() && this->Z() == other.Z();
}
Data::Vector3 Data::Vector3::Cross(Data::Vector3 other) const {
return glm::cross(this->vector, other.vector);
}

View file

@ -47,5 +47,7 @@ namespace Data {
Data::Vector3 operator +(Data::Vector3) const;
Data::Vector3 operator -(Data::Vector3) const;
Data::Vector3 operator -() const;
bool operator ==(Data::Vector3) const;
};
}

View file

@ -46,7 +46,7 @@ Data::CFrame Handles::GetCFrameOfHandle(HandleFace face) {
Data::Vector3 handleOffset = this->worldMode ? ((Data::Vector3::ONE * 2.f) + adornee->lock()->GetAABB() * 0.5f) : Data::Vector3(2.f + adornee->lock()->size * 0.5f);
Data::Vector3 handlePos = localFrame * (handleOffset * face.normal);
Data::CFrame cframe(handlePos, handlePos + localFrame.Rotation() * face.normal, upAxis);
Data::CFrame cframe(handlePos, handlePos + localFrame.Rotation() * -face.normal, upAxis);
return cframe;
}

View file

@ -193,6 +193,7 @@ void renderHandles() {
glDepthMask(GL_TRUE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW); // This is right... Probably.....
// Use shader
handleShader->use();

View file

@ -5,6 +5,7 @@
#include <glm/common.hpp>
#include <glm/ext/matrix_projection.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/scalar_constants.hpp>
#include <glm/ext/vector_float3.hpp>
#include <glm/geometric.hpp>
#include <glm/gtc/round.hpp>
@ -77,6 +78,50 @@ void MainGLWidget::handleCameraRotate(QMouseEvent* evt) {
// QCursor::setPos(lastMousePos);
}
static Data::Vector3 orthoVecs[6] {
{1, 0, 0},
{-1, 0, 0},
{0, 1, 0},
{0, -1, 0},
{0, 0, 1},
{0, 0, -1},
};
// Snaps CFrame to the neareest 90 degree angle
// https://gamedev.stackexchange.com/a/183342
Data::CFrame snapCFrame(Data::CFrame frame) {
Data::Vector3 closestVec1{0, 0, 0};
float closest1 = 0.f;
// Primary vector
for (Data::Vector3 vec : orthoVecs) {
float closeness = glm::dot((glm::vec3)frame.LookVector(), (glm::vec3)vec);
if (closeness > closest1) {
closest1 = closeness;
closestVec1 = vec;
}
}
Data::Vector3 closestVec2{0, 0, 0};
float closest2 = 0.f;
// Second vector
for (Data::Vector3 vec : orthoVecs) {
// Guard against accidental linear dependency
if (vec == closestVec1) continue;
float closeness = glm::dot((glm::vec3)frame.UpVector(), (glm::vec3)vec);
if (closeness > closest2) {
closest2 = closeness;
closestVec2 = vec;
}
}
// Data::Vector3 thirdVec = closestVec1.Cross(closestVec2);
return Data::CFrame(frame.Position(), frame.Position() + closestVec1, closestVec2);
}
bool isMouseDragging = false;
std::optional<std::weak_ptr<Part>> draggingObject;
std::optional<HandleFace> draggingHandle;
@ -91,9 +136,23 @@ void MainGLWidget::handleObjectDrag(QMouseEvent* evt) {
});
if (!rayHit) return;
Data::Vector3 vec = rayHit->worldPoint;
vec = vec + Data::Vector3(rpToGlm(rayHit->worldNormal) * draggingObject->lock()->size / 2.f);
draggingObject->lock()->cframe = draggingObject->lock()->cframe.Rotation() + vec;
Data::CFrame targetFrame = partFromBody(rayHit->body)->cframe;
Data::Vector3 surfaceNormal = targetFrame.Inverse().Rotation() * rayHit->worldNormal;
// The part being dragged's frame local to the hit target's frame, but without its position component
Data::CFrame localFrame = (targetFrame.Inverse() * draggingObject->lock()->cframe).Rotation();
// Snap axis
localFrame = snapCFrame(localFrame);
// Unsink the object
// Get the normal of the surface relative to the part's frame, and get the size along that vector
Data::Vector3 partOffset = localFrame * ((localFrame.Inverse() * rayHit->worldNormal) * draggingObject->lock()->size / 2);
Data::CFrame newFrame = targetFrame.Rotation() * localFrame;
draggingObject->lock()->cframe = newFrame + vec + partOffset;
syncPartPhysics(draggingObject->lock());
}
@ -156,6 +215,10 @@ void MainGLWidget::handleHandleDrag(QMouseEvent* evt) {
// Find outwarwd difference
localDiff = localDiff * glm::sign(draggingHandle->normal);
// Minimum size of 0.01f
localDiff = glm::max(part->size + localDiff, 0.01f) - part->size;
diff = frame * (localDiff * glm::sign(draggingHandle->normal));
// Add local difference to size
part->size += localDiff;