feat(editor): added surface editing tools
This commit is contained in:
parent
980dc249e9
commit
3f44e38788
9 changed files with 145 additions and 37 deletions
|
@ -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;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "datatypes/cframe.h"
|
||||
#include "datatypes/color3.h"
|
||||
#include "datatypes/vector.h"
|
||||
#include "rendering/surface.h"
|
||||
#include <reactphysics3d/reactphysics3d.h>
|
||||
|
||||
namespace rp = reactphysics3d;
|
||||
|
@ -38,6 +39,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);
|
||||
~Part() override;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
23
core/src/rendering/surface.cpp
Normal file
23
core/src/rendering/surface.cpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include "surface.h"
|
||||
#include "datatypes/vector.h"
|
||||
|
||||
static std::array<Data::Vector3, 6> 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];
|
||||
}
|
|
@ -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,
|
||||
|
@ -8,3 +17,7 @@ enum SurfaceType {
|
|||
SurfaceInlets = 4,
|
||||
SurfaceUniversal = 5,
|
||||
};
|
||||
|
||||
namespace Data { class Vector3; }
|
||||
NormalId faceFromNormal(Data::Vector3);
|
||||
Data::Vector3 normalFromFace(NormalId);
|
|
@ -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<std::weak_ptr<Part>> draggingObject;
|
||||
std::optional<HandleFace> 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> 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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,10 +11,17 @@
|
|||
#include <qfiledialog.h>
|
||||
|
||||
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 {
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1612</width>
|
||||
<width>1027</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -545,6 +545,9 @@
|
|||
</property>
|
||||
</action>
|
||||
<action name="actionToolStuds">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="surface-studs"/>
|
||||
</property>
|
||||
|
@ -559,6 +562,9 @@
|
|||
</property>
|
||||
</action>
|
||||
<action name="actionToolInlets">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="surface-inlets"/>
|
||||
</property>
|
||||
|
@ -573,6 +579,9 @@
|
|||
</property>
|
||||
</action>
|
||||
<action name="actionToolUniversal">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="surface-universal"/>
|
||||
</property>
|
||||
|
@ -587,6 +596,9 @@
|
|||
</property>
|
||||
</action>
|
||||
<action name="actionToolSmooth">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="surface-smooth"/>
|
||||
</property>
|
||||
|
@ -601,6 +613,9 @@
|
|||
</property>
|
||||
</action>
|
||||
<action name="actionToolWeld">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="surface-weld"/>
|
||||
</property>
|
||||
|
@ -615,6 +630,9 @@
|
|||
</property>
|
||||
</action>
|
||||
<action name="actionToolGlue">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="surface-glue"/>
|
||||
</property>
|
||||
|
|
Loading…
Add table
Reference in a new issue