4#include <glm/gtc/matrix_transform.hpp>
5#include <glm/gtc/type_ptr.hpp>
11#include <QOpenGLVersionFunctionsFactory>
12#include <QOpenGLFunctions_4_5_Core>
18 : shader(sdr), ownerScene(sceneMgr->scene), sceneManager(sceneMgr), objectID(sceneMgr->scene->allocateObjectID()), parent(objectParent), meshName(nameOfMesh) {
20 shader->
setBool(
"isHovered",
false);
24 creationOptions = options;
25 std::visit([&](
auto&& o) {
26 using T = std::decay_t<
decltype(o)>;
28 if constexpr (std::is_same_v<T, ObjectOptions>) {
29 position = o.position;
31 rotation = o.rotation;
32 }
else if constexpr (std::is_same_v<T, PointMassOptions>) {
33 position = o.base.position;
35 rotation = o.base.rotation;
36 physicsBody = std::make_unique<Physics::PointMass>(objectID, o.mass, o.base.position, o.isStatic);
40 }
else if constexpr (std::is_same_v<T, RigidBodyOptions>) {
41 position = o.base.position;
43 rotation = o.base.rotation;
44 physicsBody = std::make_unique<Physics::RigidBody>(objectID, o.mass, o.createCollider(o.base), o.base.position, o.isStatic);
47 std::span<const Vertex> meshVerts = mesh->
getVertices();
48 std::vector<glm::vec3> verts(meshVerts.size());
49 for (
size_t i = 0; i < meshVerts.size(); ++i) {
50 verts[i] = meshVerts[i].pos;
53 std::span<const unsigned int> meshInds = mesh->
getIndices();
54 std::vector<unsigned int> inds(meshInds.data(), meshInds.data() + meshInds.size());
56 rb->setGeometry(verts, inds);
57 rb->setScale(o.base.scale);
61 std::cout <<
"Problem with CreationOptions on SceneObject construction!" << std::endl;
65 orientation = glm::quat(rotation);
79 return buildModelMatrix(
false);
82glm::mat4 SceneObject::getRenderModelMatrix()
const {
83 return buildModelMatrix(
true);
86glm::mat4 SceneObject::buildModelMatrix(
bool relativeToRenderOrigin)
const{
87 glm::vec3 currentPosition = position;
88 glm::vec3 origin(0.0f);
89 bool hasMappedPhysicsPosition =
false;
92 std::lock_guard<std::mutex> lk(posMapMutex);
93 origin = renderOrigin;
95 auto it = posMap.find(physicsBody.get());
96 if (it != posMap.end()) {
97 currentPosition = it->second;
98 hasMappedPhysicsPosition =
true;
104 if (!hasMappedPhysicsPosition) {
109 if (relativeToRenderOrigin) {
110 currentPosition -= origin;
113 glm::mat4 model(1.0f);
114 model = glm::translate(model, currentPosition);
115 model = model * glm::mat4_cast(orientation);
116 model = glm::scale(model, scale);
120std::optional<float> SceneObject::intersectsAABB(
const Math::Ray& ray)
const {
124 if (
auto t = worldAABB->intersectRay(ray)) {
131std::optional<float> SceneObject::intersectsMesh(
const Math::Ray& ray)
const {
132 std::span<const Vertex> verts = mesh->
getVertices();
133 std::vector<glm::vec3> vertPositions;
134 vertPositions.reserve(verts.size());
135 for (
const auto& vert : verts) {
136 vertPositions.push_back({vert.pos});
138 const size_t triCount = verts.size() / 3;
140 std::span<const unsigned int> indices = mesh->
getIndices();
141 auto *glFuncs = QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_4_5_Core>(QOpenGLContext::currentContext());
142 ComputeShader compute(
"assets/shaders/meshIntersection.comp", glFuncs);
143 (void) compute.createSSBO(vertPositions.data(), vertPositions.size() *
sizeof(glm::vec3), 0);
144 (void) compute.createSSBO(indices.data(), indices.size() *
sizeof(
unsigned int), 1);
145 std::vector<float> initDists(triCount, -1.0f);
146 unsigned int distancesSSBO = compute.createSSBO(initDists.data(), initDists.size() *
sizeof(
float), 2);
148 compute.setVec3(
"rayOrig", ray.
origin);
149 compute.setVec3(
"rayDir", ray.
dir);
152 constexpr unsigned int groupSize = 64;
153 unsigned int groups = (triCount + groupSize - 1) / groupSize;
154 compute.dispatch(groups);
156 auto distances = compute.readSSBO<
float>(distancesSSBO, triCount);
157 auto minIt = std::min_element(distances.begin(), distances.end());
158 if (minIt == distances.end()) {
167 auto tAABB = intersectsAABB(ray);
171 auto tTri = intersectsMesh(ray);
187 std::lock_guard<std::mutex> lk(posMapMutex);
188 posMap[physicsBody.get()] = pos;
197 orientation = glm::quat(euler);
220 return glm::eulerAngles(orientation);
253 return {getRenderModelMatrix(),
getObjectID(), glm::vec3(1.0f, 1.0f, 0.0f)};
std::variant< ObjectOptions, PointMassOptions, RigidBodyOptions > CreationOptions
std::span< const Vertex > getVertices() const
Provides read-only view of vertex data without copying.
const Physics::Bounding::AABB & getLocalAABB() const
Gets the local-space axis-aligned bounding box.
std::span< const unsigned int > getIndices() const
Provides read-only view of index data without copying.
std::unique_ptr< ICollider > getTransformed(const glm::mat4 &modelMatrix) const override
Creates a transformed copy of this collider in world space.
void setScale(const glm::vec3 &newScale)
static Mesh * getMesh(const std::string &name)
void setGizmoFor(SceneObject *newTarget, bool redraw=false)
void removeFromPhysicsSystem(Physics::PhysicsBody *body) const
void addToPhysicsSystem(Physics::PhysicsBody *body) const
void setHovered(bool hovered) override
Sets the hover state of this object.
glm::mat4 getModelMatrix() const override
Gets the model transformation matrix for this instance.
glm::vec3 getRotation() const
void setScale(const glm::vec3 &scl)
glm::vec3 getPosition() const
glm::vec3 getScale() const
void handleClick(const Math::Ray &ray, float distance) override
Handles a mouse click on this object.
Rendering::InstanceData getInstanceData() const override
Gets the complete per-instance data for GPU upload.
void setRotation(const glm::vec3 &rot)
void setRotationQuat(const glm::quat &q)
SceneObject(SceneManager *sceneManager, const std::string &meshName, Shader *sdr, const CreationOptions &options, QObject *parent=nullptr)
glm::quat getRotationQuat() const
Shader * getShader() const override
Gets the shader used to render this object.
uint32_t getObjectID() const override
Gets the unique identifier for this object.
Mesh * getMesh() const override
Gets the mesh geometry for this object.
void setPosition(const glm::vec3 &pos)
std::optional< float > intersectsRay(const Math::Ray &ray) const override
Tests if a ray intersects this object's geometry.
bool getHovered() const override
Gets the current hover state of this object.
void freeObjectID(uint32_t objID)
void setBool(const std::string &name, bool value) const
glm::vec3 origin
Starting point of the ray in world space.
glm::vec3 dir
Direction vector (should be normalized)
Represents a ray in 3D space.
Per-instance data for instanced rendering.