feat: spherical handles + rendering limit increase

This commit is contained in:
maelstrom 2025-02-25 15:20:53 +01:00
parent e082428314
commit e22bb74850
8 changed files with 1142 additions and 95 deletions

View file

@ -38,8 +38,8 @@ Data::CFrame Handles::GetCFrameOfHandle(HandleFace face) {
// return adornee->lock()->cframe + face.normal * 5.f;
if (worldMode)
return adornee->lock()->cframe + (adornee->lock()->size * 0.5f * face.normal) + face.normal * 5.f;
return adornee->lock()->cframe + glm::vec3(glm::mat4(adornee->lock()->cframe.Rotation()) * glm::vec4((adornee->lock()->size * 0.5f * face.normal) + face.normal * 5.f, 0));
return adornee->lock()->cframe + (adornee->lock()->size * 0.5f * face.normal) + face.normal * 2.f;
return adornee->lock()->cframe + glm::vec3(glm::mat4(adornee->lock()->cframe.Rotation()) * glm::vec4((adornee->lock()->size * 0.5f * face.normal) + face.normal * 2.f, 0));
}
Data::CFrame Handles::PartCFrameFromHandlePos(HandleFace face, Data::Vector3 newPos) {
@ -47,8 +47,8 @@ Data::CFrame Handles::PartCFrameFromHandlePos(HandleFace face, Data::Vector3 new
// return adornee->lock()->cframe + face.normal * 5.f;
if (worldMode)
return adornee->lock()->cframe.Rotation() + newPos - (adornee->lock()->size * 0.5f * face.normal) - face.normal * 5.f;
return adornee->lock()->cframe.Rotation() + newPos - glm::vec3(glm::mat4(adornee->lock()->cframe.Rotation()) * glm::vec4((adornee->lock()->size * 0.5f * face.normal) + face.normal * 5.f, 0));
return adornee->lock()->cframe.Rotation() + newPos - (adornee->lock()->size * 0.5f * face.normal) - face.normal * 2.f;
return adornee->lock()->cframe.Rotation() + newPos - glm::vec3(glm::mat4(adornee->lock()->cframe.Rotation()) * glm::vec4((adornee->lock()->size * 0.5f * face.normal) + face.normal * 2.f, 0));
}
std::optional<HandleFace> Handles::RaycastHandle(rp3d::Ray ray) {

File diff suppressed because it is too large Load diff

View file

@ -2,5 +2,6 @@
#include "mesh.h"
extern Mesh* CUBE_MESH;
extern Mesh* SPHERE_MESH;
void initMeshes();

View file

@ -3,7 +3,7 @@
#include "mesh.h"
Mesh::Mesh(int vertexCount, float *vertices) {
Mesh::Mesh(int vertexCount, float *vertices) : vertexCount(vertexCount) {
// Generate buffers
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);

View file

@ -4,6 +4,8 @@ class Mesh {
unsigned int VBO, VAO;
public:
int vertexCount;
Mesh(int vertexCount, float* vertices);
~Mesh();
void bind();

View file

@ -27,7 +27,8 @@
Shader* shader = NULL;
Shader* skyboxShader = NULL;
Shader* handleShader;
Shader* handleShader = NULL;
Shader* identityShader = NULL;
extern Camera camera;
Skybox* skyboxTexture = NULL;
Texture3D* studsTexture = NULL;
@ -61,6 +62,7 @@ void renderInit(GLFWwindow* window, int width, int height) {
shader = new Shader("assets/shaders/phong.vs", "assets/shaders/phong.fs");
skyboxShader = new Shader("assets/shaders/skybox.vs", "assets/shaders/skybox.fs");
handleShader = new Shader("assets/shaders/handle.vs", "assets/shaders/handle.fs");
identityShader = new Shader("assets/shaders/identity.vs", "assets/shaders/identity.fs");
}
void renderParts() {
@ -72,7 +74,7 @@ void renderParts() {
// shader->set("lightColor", 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, 100.0f);
glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)viewportWidth / (float)viewportHeight, 0.1f, 1000.0f);
glm::mat4 view = camera.getLookAt();
shader->set("projection", projection);
shader->set("view", view);
@ -136,7 +138,7 @@ void renderSkyBox() {
skyboxShader->use();
glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)viewportWidth / (float)viewportHeight, 0.1f, 100.0f);
glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)viewportWidth / (float)viewportHeight, 0.1f, 1000.0f);
// Remove translation component of view, making us always at (0, 0, 0)
glm::mat4 view = glm::mat4(glm::mat3(camera.getLookAt()));
@ -150,8 +152,6 @@ void renderSkyBox() {
}
void renderHandles() {
// if (getSelection().size() == 0) return;
// if (getSelection()[0].lock()->GetClass() != &Part::TYPE) return;
if (!editorToolHandles->adornee.has_value() || !editorToolHandles->active) return;
glDepthMask(GL_TRUE);
@ -160,7 +160,7 @@ void renderHandles() {
handleShader->use();
// view/projection transformations
glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)viewportWidth / (float)viewportHeight, 0.1f, 100.0f);
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);
@ -187,8 +187,29 @@ void renderHandles() {
glm::mat3 normalMatrix = glm::mat3(glm::transpose(glm::inverse(model)));
handleShader->set("normalMatrix", normalMatrix);
CUBE_MESH->bind();
glDrawArrays(GL_TRIANGLES, 0, 36);
SPHERE_MESH->bind();
glDrawArrays(GL_TRIANGLES, 0, SPHERE_MESH->vertexCount);
}
// 2d square overlay
identityShader->use();
identityShader->set("aColor", glm::vec3(0.f, 1.f, 1.f));
for (auto face : HandleFace::Faces) {
Data::CFrame cframe = editorToolHandles->GetCFrameOfHandle(face);
glm::vec4 screenPos = projection * view * glm::vec4((glm::vec3)cframe.Position(), 1.0f);
glm::vec3 ndcCoords = screenPos / screenPos.w;
float rad = 5;
float xRad = rad * 1/viewportWidth;
float yRad = rad * 1/viewportHeight;
glBegin(GL_QUADS);
glVertex3f(ndcCoords.x - xRad, ndcCoords.y - yRad, 0);
glVertex3f(ndcCoords.x + xRad, ndcCoords.y - yRad, 0);
glVertex3f(ndcCoords.x + xRad, ndcCoords.y + yRad, 0);
glVertex3f(ndcCoords.x - xRad, ndcCoords.y + yRad, 0);
glEnd();
}
}

View file

@ -39,13 +39,9 @@ MainGLWidget::MainGLWidget(QWidget* parent): QOpenGLWidget(parent) {
setMouseTracking(true);
}
Shader* identityShader;
void MainGLWidget::initializeGL() {
glewInit();
renderInit(NULL, width(), height());
identityShader = new Shader("assets/shaders/identity.vs", "assets/shaders/identity.fs");
}
extern int vpx, vpy;
@ -67,43 +63,6 @@ extern std::optional<HandleFace> draggingHandle;
extern Shader* shader;
void MainGLWidget::paintGL() {
::render(NULL);
if (!editorToolHandles->adornee) return;
for (HandleFace face : HandleFace::Faces) {
// Ignore negatives (for now)
if (face.normal != glm::abs(face.normal)) continue;
glm::vec3 axisNormal = face.normal;
// // glm::vec3 planeNormal = camera.cameraFront;
glm::vec3 planeRight = glm::cross(axisNormal, glm::normalize(camera.cameraFront));
glm::vec3 planeNormal = glm::cross(glm::normalize(planeRight), axisNormal);
auto a = axisNormal;
auto b = planeRight;
auto c = planeNormal;
glm::mat3 matrix = {
axisNormal,
planeRight,
-planeNormal,
};
glm::mat4 model = glm::translate(glm::mat4(1.0f), (glm::vec3)editorToolHandles->adornee->lock()->position()) * glm::mat4(matrix);
model = glm::scale(model, glm::vec3(5, 5, 0.2));
shader->set("model", model);
shader->set("material", Material {
.diffuse = glm::vec3(0.5, 1.f, 0.5),
.specular = glm::vec3(0.5f, 0.5f, 0.5f),
.shininess = 16.0f,
});
glm::mat3 normalMatrix = glm::mat3(glm::transpose(glm::inverse(model)));
shader->set("normalMatrix", normalMatrix);
CUBE_MESH->bind();
// glDrawArrays(GL_TRIANGLES, 0, 36);
}
}
bool isMouseRightDragging = false;

64
tools/genmesh.py Executable file
View file

@ -0,0 +1,64 @@
#!/usr/bin/python3
# Default mesh generator
# Input from wavefront obj file
# Usage: ./genmesh.py mesh.obj > mesh.cpp
import sys
HEADER = """
static float CUBE_VERTICES[] = {
// positions // normals // texture coords
"""
FOOTER = """
};"""
file = open(sys.argv[1], "r")
vert_coords = []
vert_norms = []
vert_uvs = []
out_vertices = []
# greatest_coord = 0
# least_coord = 0
def normalize(x, y, z):
return (x/2, y/2, z/2)
for line in file:
if line.startswith('v '):
coords = line.split(' ')[1:]
vert_coords.append((float(coords[0]), float(coords[1]), float(coords[2])))
if line.startswith('vn '):
coords = line.split(' ')[1:]
vert_norms.append((float(coords[0]), float(coords[1]), float(coords[2])))
if line.startswith('vt '):
coords = line.split(' ')[1:]
vert_uvs.append((float(coords[0]), float(coords[1])))
if line.startswith('f '):
verts = line.split(' ')[1:]
for vert in verts:
coords, uv, normal = vert.split('/')
coords, uv, normal = int(coords), int(uv), int(normal)
coords, uv, normal = vert_coords[coords-1], vert_uvs[uv-1], vert_norms[normal-1]
coords = normalize(*coords)
# for coord in [*normal]:
# if coord > greatest_coord: greatest_coord = coord
# if coord < least_coord: least_coord = coord
out_vertices.append((coords, normal, uv))
print(HEADER)
for coords, normal, uv in out_vertices:
print(f"\t{coords[0]}, {coords[1]}, {coords[2]},\t{normal[0]}, {normal[1]}, {normal[2]},\t{uv[0]}, {uv[1]},")
print(FOOTER)