intersting

This commit is contained in:
maelstrom 2025-02-01 21:15:53 +01:00
parent eb6436d683
commit 4caa65a437
3 changed files with 79 additions and 6 deletions

View file

@ -2,11 +2,17 @@
#include <chrono>
#include <QMouseEvent>
#include <glm/ext/matrix_projection.hpp>
#include <glm/ext/vector_float3.hpp>
#include <glm/geometric.hpp>
#include <glm/matrix.hpp>
#include <reactphysics3d/collision/RaycastInfo.h>
#include "GLFW/glfw3.h"
#include "qcursor.h"
#include "qevent.h"
#include "qnamespace.h"
#include "qwindowdefs.h"
#include "rendering/renderer.h"
#include "physics/simulation.h"
#include "camera.h"
@ -50,11 +56,66 @@ void MainGLWidget::mouseMoveEvent(QMouseEvent* evt) {
// QCursor::setPos(lastMousePos);
}
void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
if (evt->button() != Qt::RightButton) return;
class FirstRayHit : public rp::RaycastCallback {
rp::Body** target;
lastMousePos = evt->pos();
isMouseDragging = true;
virtual rp::decimal notifyRaycastHit(const rp::RaycastInfo& raycastInfo) override {
if (reinterpret_cast<Part*>(raycastInfo.body->getUserData())->name == "Baseplate") return 1;
*target = raycastInfo.body;
return 0;
}
public:
FirstRayHit(rp::Body** target) : target(target) {}
};
void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
switch(evt->button()) {
// Camera drag
case Qt::RightButton: {
lastMousePos = evt->pos();
isMouseDragging = true;
return;
// Clicking on objects
} case Qt::LeftButton: {
QPoint position = evt->pos();
rp::Body* rayHitTarget = NULL;
// VVV Thank goodness for this person's answer
// https://stackoverflow.com/a/30005258/16255372
// glm::vec3 worldPos = camera.cameraPos + glm::vec3(glm::vec4(float(position.x()) / width() - 0.5f, float(position.y()) / height() - 0.5f, 0, 0) * camera.getLookAt());
glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)width() / (float)height(), 0.1f, 100.0f);
glm::mat4 view = glm::lookAt(glm::vec3(0), camera.cameraFront, camera.cameraUp);
glm::mat4 inverseViewport = glm::inverse(projection * view);
glm::vec2 ndc = glm::vec2(float(position.x()) / width() * 2.f - 1.f, -float(position.y()) / height() * 2.f + 1.f);
glm::vec4 world = glm::normalize(inverseViewport * glm::vec4(ndc, 1, 1));
glm::vec3 flat = glm::vec3(world) / world.w; // https://stackoverflow.com/a/68870587/16255372
printf("At: %f; %f; %f\n", world.x, world.y, world.z);
workspace->AddChild(lastPart = Part::New({
.position = camera.cameraPos + glm::vec3(world) * 10.f,
.rotation = glm::vec3(0),
.scale = glm::vec3(1, 1, 1),
.material = Material {
.diffuse = glm::vec3(1.0f, 0.5f, 0.31f),
.specular = glm::vec3(0.5f, 0.5f, 0.5f),
.shininess = 32.0f,
},
.anchored = true,
}));
syncPartPhysics(lastPart);
castRay(camera.cameraPos, world, 500, new FirstRayHit(&rayHitTarget));
if (!rayHitTarget) return;
printf("Hit: %s\n", reinterpret_cast<Part*>(rayHitTarget->getUserData())->name.c_str());
return;
} default:
return;
}
}
void MainGLWidget::mouseReleaseEvent(QMouseEvent* evt) {

View file

@ -2,12 +2,14 @@
#include <glm/ext/matrix_float3x3.hpp>
#include <glm/gtc/quaternion.hpp>
#include <memory>
#include <reactphysics3d/collision/RaycastInfo.h>
#include <reactphysics3d/collision/shapes/BoxShape.h>
#include <reactphysics3d/collision/shapes/CollisionShape.h>
#include <reactphysics3d/components/RigidBodyComponents.h>
#include <reactphysics3d/engine/EventListener.h>
#include <reactphysics3d/engine/PhysicsCommon.h>
#include <reactphysics3d/mathematics/Quaternion.h>
#include <reactphysics3d/mathematics/Ray.h>
#include <reactphysics3d/mathematics/Transform.h>
#include <reactphysics3d/mathematics/Vector3.h>
#include <reactphysics3d/memory/DefaultAllocator.h>
@ -36,6 +38,8 @@ void simulationInit() {
world = physicsCommon->createPhysicsWorld();
world->setGravity(rp::Vector3(0, -196.2, 0));
world->setEventListener(&eventListener);
}
void syncPartPhysics(std::shared_ptr<Part> part) {
@ -58,7 +62,7 @@ void syncPartPhysics(std::shared_ptr<Part> part) {
part->rigidBody->addCollider(shape, rp::Transform());
part->rigidBody->setType(part->anchored ? rp::BodyType::STATIC : rp::BodyType::DYNAMIC);
world->setEventListener(&eventListener);
part->rigidBody->setUserData(&*part);
}
void physicsStep(float deltaTime) {
@ -75,4 +79,9 @@ void physicsStep(float deltaTime) {
// part.rotation = glm::eulerAngles(rpToGlm(transform.getOrientation()));
part->rotation = rpToGlm(transform.getOrientation());
}
}
void castRay(glm::vec3 point, glm::vec3 rotation, float maxLength, rp::RaycastCallback* callback) {
rp::Ray ray(glmToRp(point), glmToRp(glm::normalize(rotation)) * maxLength);
world->raycast(ray, callback);
}

View file

@ -1,8 +1,11 @@
#pragma once
#include "../objects/part.h"
#include <glm/ext/vector_float3.hpp>
#include <memory>
#include <reactphysics3d/collision/RaycastInfo.h>
void simulationInit();
void syncPartPhysics(std::shared_ptr<Part> part);
void physicsStep(float deltaTime);
void physicsStep(float deltaTime);
void castRay(glm::vec3 point, glm::vec3 rotation, float maxLength, rp::RaycastCallback* callback);