feat(editor): circle around rotation handles
This commit is contained in:
parent
1bdb9f146c
commit
452c61ef90
5 changed files with 120 additions and 2 deletions
|
@ -2,6 +2,7 @@
|
|||
#include "common.h"
|
||||
#include "datatypes/cframe.h"
|
||||
#include "datatypes/vector.h"
|
||||
#include <glm/ext/scalar_common.hpp>
|
||||
#include <optional>
|
||||
#include <reactphysics3d/collision/RaycastInfo.h>
|
||||
#include <reactphysics3d/engine/PhysicsCommon.h>
|
||||
|
@ -50,7 +51,8 @@ Data::CFrame Handles::GetCFrameOfHandle(HandleFace face) {
|
|||
if (glm::abs(glm::dot(glm::vec3(localFrame.Rotation() * handleNormal), upAxis)) > 0.9999f)
|
||||
upAxis = glm::vec3(0, 1, 0);
|
||||
|
||||
Data::Vector3 handleOffset = this->worldMode ? ((Data::Vector3::ONE * 2.f) + adornee.lock()->GetAABB() * 0.5f) : Data::Vector3(2.f + adornee.lock()->size * 0.5f);
|
||||
glm::vec3 partSize = handlesType == HandlesType::RotateHandles ? glm::vec3(glm::max(adornee.lock()->size.x, adornee.lock()->size.y, adornee.lock()->size.z)) : adornee.lock()->size;
|
||||
Data::Vector3 handleOffset = this->worldMode ? ((Data::Vector3::ONE * 2.f) + adornee.lock()->GetAABB() * 0.5f) : Data::Vector3(2.f + partSize * 0.5f);
|
||||
Data::Vector3 handlePos = localFrame * (handleOffset * handleNormal);
|
||||
Data::CFrame cframe(handlePos, handlePos + localFrame.Rotation() * -handleNormal, upAxis);
|
||||
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <GL/gl.h>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/ext/matrix_float4x4.hpp>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/trigonometric.hpp>
|
||||
#include <memory>
|
||||
|
||||
#include "datatypes/cframe.h"
|
||||
#include "objects/handles.h"
|
||||
#include "rendering/torus.h"
|
||||
#include "shader.h"
|
||||
#include "mesh.h"
|
||||
#include "defaultmeshes.h"
|
||||
|
@ -42,6 +46,8 @@ void renderInit(GLFWwindow* window, int width, int height) {
|
|||
viewportWidth = width, viewportHeight = height;
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
int argc = 1;
|
||||
char* argv = const_cast<char*>("");
|
||||
initMeshes();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
@ -396,6 +402,57 @@ void renderOutlines() {
|
|||
}
|
||||
}
|
||||
|
||||
void renderRotationArcs() {
|
||||
if (editorToolHandles->adornee.expired() || editorToolHandles->handlesType != HandlesType::RotateHandles) return;
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
glFrontFace(GL_CW);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// Use shader
|
||||
handleShader->use();
|
||||
|
||||
handleShader->set("sunLight", DirLight {
|
||||
.direction = glm::vec3(-0.2f, -1.0f, -0.3f),
|
||||
.ambient = glm::vec3(0.2f, 0.2f, 0.2f),
|
||||
.diffuse = glm::vec3(0.5f, 0.5f, 0.5f),
|
||||
.specular = glm::vec3(1.0f, 1.0f, 1.0f),
|
||||
});
|
||||
|
||||
// view/projection transformations
|
||||
glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)viewportWidth / (float)viewportHeight, 0.1f, 1000.0f);
|
||||
glm::mat4 view = camera.getLookAt();
|
||||
handleShader->set("projection", projection);
|
||||
handleShader->set("view", view);
|
||||
|
||||
// Pass in the camera position
|
||||
handleShader->set("viewPos", camera.cameraPos);
|
||||
|
||||
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(getSelection()[0].lock());
|
||||
|
||||
for (HandleFace face : HandleFace::Faces) {
|
||||
if (glm::any(glm::lessThan(face.normal, glm::vec3(0)))) continue;
|
||||
glm::mat4 model = part->cframe * Data::CFrame(glm::vec3(0), face.normal, glm::vec3(0, 1.01, 0.1));
|
||||
handleShader->set("model", model);
|
||||
|
||||
float radius = glm::max(part->size.x, part->size.y, part->size.z) / 2.f + 2.f;
|
||||
|
||||
handleShader->set("material", Material {
|
||||
.diffuse = glm::abs(face.normal),
|
||||
.specular = glm::vec3(0.5f, 0.5f, 0.5f),
|
||||
.shininess = 16.0f,
|
||||
});
|
||||
glm::mat3 normalMatrix = glm::mat3(glm::transpose(glm::inverse(model)));
|
||||
handleShader->set("normalMatrix", normalMatrix);
|
||||
|
||||
genTorus(radius, 0.05f, 20, 20);
|
||||
}
|
||||
}
|
||||
|
||||
void render(GLFWwindow* window) {
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
@ -404,6 +461,7 @@ void render(GLFWwindow* window) {
|
|||
renderHandles();
|
||||
renderParts();
|
||||
renderOutlines();
|
||||
renderRotationArcs();
|
||||
if (wireframeRendering)
|
||||
renderWireframe();
|
||||
// TODO: Make this a debug flag
|
||||
|
|
47
core/src/rendering/torus.cpp
Normal file
47
core/src/rendering/torus.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include "torus.h"
|
||||
#include <cmath>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#define PI 3.1415926535f
|
||||
|
||||
struct vec { float x; float y; float z; };
|
||||
|
||||
void genTorusPoint(float outerRadius, float innerRadius, float tubeSides, float ringSides, int tube, int ring) {
|
||||
float angle = float(tube) / tubeSides * 2 * PI;
|
||||
float xL = innerRadius * cos(angle);
|
||||
float yL = innerRadius * sin(angle);
|
||||
|
||||
float outerAngle = float(ring) / ringSides * 2 * PI;
|
||||
float x = (outerRadius + xL) * cos(outerAngle);
|
||||
float y = (outerRadius + xL) * sin(outerAngle);
|
||||
float z = yL;
|
||||
|
||||
// return vec { x, y, z };
|
||||
glVertex3f(x, y, z);
|
||||
}
|
||||
|
||||
// made by yours truly
|
||||
void genTorus(float outerRadius, float innerRadius, int tubeSides, int ringSides) {
|
||||
glBegin(GL_TRIANGLES);
|
||||
|
||||
for (int i = 0; i < tubeSides; i++) {
|
||||
float tube = float(i) / tubeSides;
|
||||
for (int j = 0; j < ringSides; j++) {
|
||||
float ring = float(j) / ringSides;
|
||||
|
||||
int in = (i+1) % tubeSides;
|
||||
int jn = (j+1) % tubeSides;
|
||||
|
||||
genTorusPoint(outerRadius, innerRadius, tubeSides, ringSides, i, j);
|
||||
genTorusPoint(outerRadius, innerRadius, tubeSides, ringSides, in, j);
|
||||
genTorusPoint(outerRadius, innerRadius, tubeSides, ringSides, in, jn);
|
||||
|
||||
genTorusPoint(outerRadius, innerRadius, tubeSides, ringSides, in, jn);
|
||||
genTorusPoint(outerRadius, innerRadius, tubeSides, ringSides, i, jn);
|
||||
genTorusPoint(outerRadius, innerRadius, tubeSides, ringSides, i, j);
|
||||
}
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
11
core/src/rendering/torus.h
Normal file
11
core/src/rendering/torus.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
Generates a torus made of circles extruded into cylinders and spun around the origin
|
||||
|
||||
float outerRadius - The radius of the "circle" from the origin at which the center of the cylinders lie
|
||||
float innerRadius - The radius of the cylinders
|
||||
int tubeSides - Number of vertices in each circle
|
||||
int ringSides - How many cylinder circles to draw around the torus
|
||||
*/
|
||||
void genTorus(float outerRadius, float innerRadius, int tubeSides, int ringSides);
|
|
@ -285,7 +285,7 @@ void MainGLWidget::handleRotationalTransform(QMouseEvent* evt) {
|
|||
part->cframe = initialFrame * Data::CFrame::FromEulerAnglesXYZ(-angles);
|
||||
|
||||
gWorkspace()->SyncPartPhysics(part);
|
||||
sendPropertyUpdatedSignal(draggingObject.lock(), "Rotation", draggingObject.lock()->cframe.ToEulerAnglesXYZ());
|
||||
sendPropertyUpdatedSignal(part, "Rotation", part->cframe.ToEulerAnglesXYZ());
|
||||
}
|
||||
|
||||
std::optional<HandleFace> MainGLWidget::raycastHandle(glm::vec3 pointDir) {
|
||||
|
|
Loading…
Add table
Reference in a new issue