diff --git a/core/src/objects/handles.cpp b/core/src/objects/handles.cpp index b98130d..ef56d0b 100644 --- a/core/src/objects/handles.cpp +++ b/core/src/objects/handles.cpp @@ -2,6 +2,7 @@ #include "common.h" #include "datatypes/cframe.h" #include "datatypes/vector.h" +#include #include #include #include @@ -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); diff --git a/core/src/rendering/renderer.cpp b/core/src/rendering/renderer.cpp index b778b89..4128741 100644 --- a/core/src/rendering/renderer.cpp +++ b/core/src/rendering/renderer.cpp @@ -1,16 +1,20 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #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(""); 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 = std::dynamic_pointer_cast(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 diff --git a/core/src/rendering/torus.cpp b/core/src/rendering/torus.cpp new file mode 100644 index 0000000..f83b21c --- /dev/null +++ b/core/src/rendering/torus.cpp @@ -0,0 +1,47 @@ +#include "torus.h" +#include + +#include + +#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(); +} \ No newline at end of file diff --git a/core/src/rendering/torus.h b/core/src/rendering/torus.h new file mode 100644 index 0000000..465d3cd --- /dev/null +++ b/core/src/rendering/torus.h @@ -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); \ No newline at end of file diff --git a/editor/mainglwidget.cpp b/editor/mainglwidget.cpp index c136ca2..509d610 100644 --- a/editor/mainglwidget.cpp +++ b/editor/mainglwidget.cpp @@ -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 MainGLWidget::raycastHandle(glm::vec3 pointDir) {