diff --git a/assets/shaders/phong.vs b/assets/shaders/phong.vs index 989d10d..aa529f3 100644 --- a/assets/shaders/phong.vs +++ b/assets/shaders/phong.vs @@ -42,8 +42,8 @@ void main() aNormal == vec3(0, -1, 0) ? FaceBottom : aNormal == vec3(1, 0, 0) ? FaceRight : aNormal == vec3(-1, 0, 0) ? FaceLeft : - aNormal == vec3(0, 0, 1) ? FaceFront : - aNormal == vec3(0, 0, -1) ? FaceBack : -1; + aNormal == vec3(0, 0, -1) ? FaceFront : + aNormal == vec3(0, 0, 1) ? FaceBack : -1; vSurfaceZ = surfaces[vFace]; // if (surfaces[vFace] > SurfaceUniversal) vSurfaceZ = 0; diff --git a/core/src/objects/part.h b/core/src/objects/part.h index 98b1618..73c63ed 100644 --- a/core/src/objects/part.h +++ b/core/src/objects/part.h @@ -8,6 +8,7 @@ #include "datatypes/cframe.h" #include "datatypes/color3.h" #include "datatypes/vector.h" +#include "rendering/surface.h" #include namespace rp = reactphysics3d; @@ -37,6 +38,13 @@ public: bool anchored = false; rp::RigidBody* rigidBody = nullptr; + + SurfaceType topSurface = SurfaceType::SurfaceStuds; + SurfaceType bottomSurface = SurfaceType::SurfaceInlets; + SurfaceType leftSurface = SurfaceType::SurfaceSmooth; + SurfaceType rightSurface = SurfaceType::SurfaceSmooth; + SurfaceType frontSurface = SurfaceType::SurfaceSmooth; + SurfaceType backSurface = SurfaceType::SurfaceSmooth; Part(); Part(PartConstructParams params); diff --git a/core/src/rendering/renderer.cpp b/core/src/rendering/renderer.cpp index f878abd..5da2c60 100644 --- a/core/src/rendering/renderer.cpp +++ b/core/src/rendering/renderer.cpp @@ -109,14 +109,6 @@ void renderParts() { // }); studsTexture->activate(0); shader->set("studs", 0); - // shader->set("surfaces[1]", SurfaceStuds); - shader->set("surfaces[1]", SurfaceStuds); - shader->set("surfaces[4]", SurfaceInlets); - - shader->set("surfaces[0]", SurfaceStuds); - shader->set("surfaces[2]", SurfaceStuds); - shader->set("surfaces[3]", SurfaceStuds); - shader->set("surfaces[5]", SurfaceStuds); // Pre-calculate the normal matrix for the shader @@ -147,6 +139,13 @@ void renderParts() { shader->set("texScale", part->size); shader->set("transparency", part->transparency); + shader->set("surfaces[" + std::to_string(NormalId::Right) + "]", part->rightSurface); + shader->set("surfaces[" + std::to_string(NormalId::Top) + "]", part->topSurface); + shader->set("surfaces[" + std::to_string(NormalId::Back) + "]", part->backSurface); + shader->set("surfaces[" + std::to_string(NormalId::Left) + "]", part->leftSurface); + shader->set("surfaces[" + std::to_string(NormalId::Bottom) + "]", part->bottomSurface); + shader->set("surfaces[" + std::to_string(NormalId::Front) + "]", part->frontSurface); + CUBE_MESH->bind(); glDrawArrays(GL_TRIANGLES, 0, CUBE_MESH->vertexCount); } @@ -170,6 +169,13 @@ void renderParts() { shader->set("texScale", part->size); shader->set("transparency", part->transparency); + shader->set("surfaces[" + std::to_string(NormalId::Right) + "]", part->rightSurface); + shader->set("surfaces[" + std::to_string(NormalId::Top) + "]", part->topSurface); + shader->set("surfaces[" + std::to_string(NormalId::Back) + "]", part->backSurface); + shader->set("surfaces[" + std::to_string(NormalId::Left) + "]", part->leftSurface); + shader->set("surfaces[" + std::to_string(NormalId::Bottom) + "]", part->bottomSurface); + shader->set("surfaces[" + std::to_string(NormalId::Front) + "]", part->frontSurface); + CUBE_MESH->bind(); glDrawArrays(GL_TRIANGLES, 0, CUBE_MESH->vertexCount); } diff --git a/core/src/rendering/surface.cpp b/core/src/rendering/surface.cpp new file mode 100644 index 0000000..dd3d873 --- /dev/null +++ b/core/src/rendering/surface.cpp @@ -0,0 +1,23 @@ +#include "surface.h" +#include "datatypes/vector.h" + +static std::array FACE_NORMALS = {{ + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 }, + { -1, 0, 0 }, + { 0, -1, 0 }, + { 0, 0, -1 }, +}}; + +NormalId faceFromNormal(Data::Vector3 normal) { + for (int face = 0; face < 6; face++) { + if (normal.Dot(FACE_NORMALS[face]) > 0.99) + return (NormalId)face; + } + return (NormalId)-1; +} + +Data::Vector3 normalFromFace(NormalId face) { + return FACE_NORMALS[face]; +} \ No newline at end of file diff --git a/core/src/rendering/surface.h b/core/src/rendering/surface.h index ae4f462..5cd7e81 100644 --- a/core/src/rendering/surface.h +++ b/core/src/rendering/surface.h @@ -1,5 +1,14 @@ #pragma once +enum NormalId { + Right = 0, + Top = 1, + Back = 2, + Left = 3, + Bottom = 4, + Front = 5 +}; + enum SurfaceType { SurfaceSmooth = 0, SurfaceGlue = 1, @@ -7,4 +16,8 @@ enum SurfaceType { SurfaceStuds = 3, SurfaceInlets = 4, SurfaceUniversal = 5, -}; \ No newline at end of file +}; + +namespace Data { class Vector3; } +NormalId faceFromNormal(Data::Vector3); +Data::Vector3 normalFromFace(NormalId); \ No newline at end of file diff --git a/editor/mainglwidget.cpp b/editor/mainglwidget.cpp index b7b5284..4528d2d 100644 --- a/editor/mainglwidget.cpp +++ b/editor/mainglwidget.cpp @@ -37,6 +37,7 @@ #include "mainglwidget.h" #include "math_helper.h" +#include "rendering/surface.h" static Data::CFrame XYZToZXY(glm::vec3(0, 0, 0), -glm::vec3(1, 0, 0), glm::vec3(0, 0, 1)); @@ -130,7 +131,7 @@ bool isMouseDragging = false; std::optional> draggingObject; std::optional draggingHandle; void MainGLWidget::handleObjectDrag(QMouseEvent* evt) { - if (!isMouseDragging || !draggingObject) return; + if (!isMouseDragging || !draggingObject || mainWindow()->selectedTool >= TOOL_SMOOTH) return; QPoint position = evt->pos(); @@ -214,12 +215,12 @@ void MainGLWidget::handleLinearTransform(QMouseEvent* evt) { // printf("Post-snap: (%f, %f, %f)\n", diff.x, diff.y, diff.z); switch (mainWindow()->selectedTool) { - case SelectedTool::MOVE: { + case TOOL_MOVE: { // Add difference editorToolHandles->adornee->lock()->cframe = editorToolHandles->adornee->lock()->cframe + diff; } break; - case SelectedTool::SCALE: { + case TOOL_SCALE: { // Find local difference glm::vec3 localDiff = frame.Inverse() * diff; // Find outwarwd difference @@ -316,11 +317,11 @@ void MainGLWidget::mouseMoveEvent(QMouseEvent* evt) { handleCursorChange(evt); switch (mainWindow()->selectedTool) { - case SelectedTool::MOVE: - case SelectedTool::SCALE: + case TOOL_MOVE: + case TOOL_SCALE: handleLinearTransform(evt); break; - case SelectedTool::ROTATE: + case TOOL_ROTATE: handleRotationalTransform(evt); break; default: @@ -356,6 +357,24 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) { std::shared_ptr part = partFromBody(rayHit->body); if (part->name == "Baseplate") return; + // Handle surface tool + if (mainWindow()->selectedTool >= TOOL_SMOOTH) { + Data::Vector3 localNormal = part->cframe.Inverse().Rotation() * rayHit->worldNormal; + NormalId face = faceFromNormal(localNormal); + SurfaceType surface = SurfaceType(mainWindow()->selectedTool - TOOL_SMOOTH); + + switch (face) { + case Right: part->rightSurface = surface; break; + case Top: part->topSurface = surface; break; + case Back: part->backSurface = surface; break; + case Left: part->leftSurface = surface; break; + case Bottom: part->bottomSurface = surface; break; + case Front: part->frontSurface = surface; break; + default: break; + } + return; + } + //part.selected = true; isMouseDragging = true; draggingObject = part; diff --git a/editor/mainwindow.cpp b/editor/mainwindow.cpp index 96226b1..72aa6b8 100644 --- a/editor/mainwindow.cpp +++ b/editor/mainwindow.cpp @@ -109,12 +109,19 @@ MainWindow::MainWindow(QWidget *parent) ui->explorerView->buildContextMenu(); - connect(ui->actionToolSelect, &QAction::triggered, this, [&]() { selectedTool = SelectedTool::SELECT; updateToolbars(); }); - connect(ui->actionToolMove, &QAction::triggered, this, [&](bool state) { selectedTool = state ? SelectedTool::MOVE : SelectedTool::SELECT; updateToolbars(); }); - connect(ui->actionToolScale, &QAction::triggered, this, [&](bool state) { selectedTool = state ? SelectedTool::SCALE : SelectedTool::SELECT; updateToolbars(); }); - connect(ui->actionToolRotate, &QAction::triggered, this, [&](bool state) { selectedTool = state ? SelectedTool::ROTATE : SelectedTool::SELECT; updateToolbars(); }); + connect(ui->actionToolSelect, &QAction::triggered, this, [&]() { selectedTool = TOOL_SELECT; updateToolbars(); }); + connect(ui->actionToolMove, &QAction::triggered, this, [&](bool state) { selectedTool = state ? TOOL_MOVE : TOOL_SELECT; updateToolbars(); }); + connect(ui->actionToolScale, &QAction::triggered, this, [&](bool state) { selectedTool = state ? TOOL_SCALE : TOOL_SELECT; updateToolbars(); }); + connect(ui->actionToolRotate, &QAction::triggered, this, [&](bool state) { selectedTool = state ? TOOL_ROTATE : TOOL_SELECT; updateToolbars(); }); + + connect(ui->actionToolSmooth, &QAction::triggered, this, [&](bool state) { selectedTool = state ? TOOL_SMOOTH : TOOL_SELECT; updateToolbars(); }); + connect(ui->actionToolGlue, &QAction::triggered, this, [&](bool state) { selectedTool = state ? TOOL_GLUE : TOOL_SELECT; updateToolbars(); }); + connect(ui->actionToolWeld, &QAction::triggered, this, [&](bool state) { selectedTool = state ? TOOL_WELD : TOOL_SELECT; updateToolbars(); }); + connect(ui->actionToolStuds, &QAction::triggered, this, [&](bool state) { selectedTool = state ? TOOL_STUDS : TOOL_SELECT; updateToolbars(); }); + connect(ui->actionToolInlets, &QAction::triggered, this, [&](bool state) { selectedTool = state ? TOOL_INLETS : TOOL_SELECT; updateToolbars(); }); + connect(ui->actionToolUniversal, &QAction::triggered, this, [&](bool state) { selectedTool = state ? TOOL_UNIVERSAL : TOOL_SELECT; updateToolbars(); }); ui->actionToolSelect->setChecked(true); - selectedTool = SelectedTool::SELECT; + selectedTool = TOOL_SELECT; connect(ui->actionGridSnap1, &QAction::triggered, this, [&]() { snappingMode = GridSnappingMode::SNAP_1_STUD; updateToolbars(); }); connect(ui->actionGridSnap05, &QAction::triggered, this, [&]() { snappingMode = GridSnappingMode::SNAP_05_STUDS; updateToolbars(); }); @@ -421,23 +428,30 @@ void MainWindow::timerEvent(QTimerEvent* evt) { } void MainWindow::updateToolbars() { - ui->actionToolSelect->setChecked(selectedTool == SelectedTool::SELECT); - ui->actionToolMove->setChecked(selectedTool == SelectedTool::MOVE); - ui->actionToolScale->setChecked(selectedTool == SelectedTool::SCALE); - ui->actionToolRotate->setChecked(selectedTool == SelectedTool::ROTATE); + ui->actionToolSelect->setChecked(selectedTool == TOOL_SELECT); + ui->actionToolMove->setChecked(selectedTool == TOOL_MOVE); + ui->actionToolScale->setChecked(selectedTool == TOOL_SCALE); + ui->actionToolRotate->setChecked(selectedTool == TOOL_ROTATE); + + ui->actionToolSmooth->setChecked(selectedTool == TOOL_SMOOTH); + ui->actionToolGlue->setChecked(selectedTool == TOOL_GLUE); + ui->actionToolWeld->setChecked(selectedTool == TOOL_WELD); + ui->actionToolStuds->setChecked(selectedTool == TOOL_STUDS); + ui->actionToolInlets->setChecked(selectedTool == TOOL_INLETS); + ui->actionToolUniversal->setChecked(selectedTool == TOOL_UNIVERSAL); ui->actionGridSnap1->setChecked(snappingMode == GridSnappingMode::SNAP_1_STUD); ui->actionGridSnap05->setChecked(snappingMode == GridSnappingMode::SNAP_05_STUDS); ui->actionGridSnapOff->setChecked(snappingMode == GridSnappingMode::SNAP_OFF); - editorToolHandles->worldMode = (selectedTool == SelectedTool::SCALE || selectedTool == SelectedTool::ROTATE) ? false : worldSpaceTransforms; - editorToolHandles->nixAxes = selectedTool == SelectedTool::ROTATE; + editorToolHandles->worldMode = (selectedTool == TOOL_SCALE || selectedTool == TOOL_ROTATE) ? false : worldSpaceTransforms; + editorToolHandles->nixAxes = selectedTool == TOOL_ROTATE; - editorToolHandles->active = selectedTool != SelectedTool::SELECT; + editorToolHandles->active = selectedTool > TOOL_SELECT && selectedTool < TOOL_SMOOTH; editorToolHandles->handlesType = - selectedTool == SelectedTool::MOVE ? HandlesType::MoveHandles - : selectedTool == SelectedTool::SCALE ? HandlesType::ScaleHandles - : selectedTool == SelectedTool::ROTATE ? HandlesType::RotateHandles + selectedTool == TOOL_MOVE ? HandlesType::MoveHandles + : selectedTool == TOOL_SCALE ? HandlesType::ScaleHandles + : selectedTool == TOOL_ROTATE ? HandlesType::RotateHandles : HandlesType::ScaleHandles; } diff --git a/editor/mainwindow.h b/editor/mainwindow.h index 57a35b6..3d21736 100644 --- a/editor/mainwindow.h +++ b/editor/mainwindow.h @@ -11,10 +11,17 @@ #include enum SelectedTool { - SELECT, - MOVE, - SCALE, - ROTATE, + TOOL_SELECT, + TOOL_MOVE, + TOOL_SCALE, + TOOL_ROTATE, + + TOOL_SMOOTH, + TOOL_GLUE, + TOOL_WELD, + TOOL_STUDS, + TOOL_INLETS, + TOOL_UNIVERSAL, }; enum GridSnappingMode { diff --git a/editor/mainwindow.ui b/editor/mainwindow.ui index 766da64..ce42c65 100644 --- a/editor/mainwindow.ui +++ b/editor/mainwindow.ui @@ -40,7 +40,7 @@ 0 0 - 1612 + 1027 30 @@ -545,6 +545,9 @@ + + true + @@ -559,6 +562,9 @@ + + true + @@ -573,6 +579,9 @@ + + true + @@ -587,6 +596,9 @@ + + true + @@ -601,6 +613,9 @@ + + true + @@ -615,6 +630,9 @@ + + true +