From 78073bac4594020057f846fab1d75d193cc3c661 Mon Sep 17 00:00:00 2001 From: Anselme Date: Wed, 29 Nov 2017 19:41:44 +0100 Subject: [PATCH] adding generic scriptable scene node class --- src/editor.cpp | 2 +- src/scene/gibgeneratornode.cpp | 1 + src/scene/meshnode.cpp | 1 + src/scene/objectnode.cpp | 51 +++++++++++++++++++++++++++ src/scene/objectnode.h | 64 ++++++++++++++++++++++++++++++++++ src/tools/scenepicker.cpp | 29 ++++++++++++--- src/tools/scenepicker.h | 29 +++++++++++++++ 7 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 src/scene/objectnode.cpp create mode 100644 src/scene/objectnode.h diff --git a/src/editor.cpp b/src/editor.cpp index c173d65..a929b46 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -28,7 +28,7 @@ Editor::Editor() : m_editorEnabled(false) { m_objectEditor = new ObjectEditor(); - addChild(m_pickerNode); + m_children.push_back(m_pickerNode); m_pickerNode->setVisible(false); } diff --git a/src/scene/gibgeneratornode.cpp b/src/scene/gibgeneratornode.cpp index 28f3185..3139335 100644 --- a/src/scene/gibgeneratornode.cpp +++ b/src/scene/gibgeneratornode.cpp @@ -21,6 +21,7 @@ void GibGeneratorNode::createGib(GraphicalNode* graphicalPart, physicsShape->calculateLocalInertia(mass, localInertia); btRigidBody *body = new btRigidBody(mass, motionState, physicsShape, localInertia); body->setLinearVelocity(btVector3(velocity.x, velocity.y, velocity.z)); + body->setUserPointer(graphicalPart); getEngine().getScene()->getPhysics()->addRigidBody(body); diff --git a/src/scene/meshnode.cpp b/src/scene/meshnode.cpp index 2444888..d27fbfd 100644 --- a/src/scene/meshnode.cpp +++ b/src/scene/meshnode.cpp @@ -56,5 +56,6 @@ btRigidBody* MeshNode::buildStaticCollider() // IMPORTANT ! collisions on static meshes does not work if the transform is modified after the rigidbody construction m_rigidBody = new btRigidBody(0., nullptr, shape); m_rigidBody->setWorldTransform(transform); + m_rigidBody->setUserPointer(this); return m_rigidBody; } diff --git a/src/scene/objectnode.cpp b/src/scene/objectnode.cpp new file mode 100644 index 0000000..be7d236 --- /dev/null +++ b/src/scene/objectnode.cpp @@ -0,0 +1,51 @@ +#include "objectnode.h" + +glm::mat4 Transform::getMatrix() const +{ + return glm::toMat4(m_rotation) * glm::translate(glm::mat4(), m_position); +} + +void Transform::setFromMatrix(const glm::mat4& mat) +{ + m_position = glm::vec3(mat[3]); + m_rotation = glm::conjugate(glm::toQuat(mat)); +} + +ObjectNode::ObjectNode() +{ + +} + +void ObjectNode::init() +{ + // TODO : lua init +} + +void ObjectNode::update() +{ + // TODO : lua update + + // children update + m_graphics.update(); + ContainerNode::update(); +} + +void ObjectNode::gui() +{ + // imgui editor +} + +void ObjectNode::luaBind() +{ + // TODO do lua bindings +} + +void ObjectNode::getTransform(Transform& t) +{ + t.setFromMatrix(m_graphics.getTransform()); +} + +void ObjectNode::setTransform(const Transform& t) +{ + m_graphics.setTransform(t.getMatrix()); +} diff --git a/src/scene/objectnode.h b/src/scene/objectnode.h new file mode 100644 index 0000000..e03bd95 --- /dev/null +++ b/src/scene/objectnode.h @@ -0,0 +1,64 @@ +#ifndef OBJECTNODE_H +#define OBJECTNODE_H + +#include "containernode.h" +#include "graphicalcontainernode.h" +#include +#include +#include + +class GraphicalContainerNode; + +struct Transform +{ + glm::vec3 m_position; + glm::quat m_rotation; + + void getPosition(float* pos) { memcpy(pos, glm::value_ptr(m_position), sizeof(float)*3); } + void setPosition(const float* pos) { memcpy(glm::value_ptr(m_position), pos, sizeof(float)*3); } + void getRotation(float* rot) { memcpy(rot, glm::value_ptr(m_rotation), sizeof(float)*4); } + void setRotation(const float* rot) { memcpy(glm::value_ptr(m_rotation), rot, sizeof(float)*4); } + + glm::mat4 getMatrix() const; + void setFromMatrix(const glm::mat4& mat); +}; + +class ObjectNode : public ContainerNode +{ + GraphicalContainerNode m_graphics; + + std::string name; + + std::string initScript; + std::string updateScript; + +public: + ObjectNode(); + + void init(); + + void update(); + + void gui(); + + static void luaBind(); + + // LUA accessible methods + + // instanciation + //static ObjectNode* create() { return new ObjectNode(); } + ObjectNode* clone(); + + // positionning + void getTransform(Transform& t); + void setTransform(const Transform& t); + + // physics + + + // graphics + + +}; + +#endif // OBJECTNODE_H diff --git a/src/tools/scenepicker.cpp b/src/tools/scenepicker.cpp index 5f458d8..2b672da 100644 --- a/src/tools/scenepicker.cpp +++ b/src/tools/scenepicker.cpp @@ -76,16 +76,18 @@ void ScenePicker::pick() btVector3 start(cam->getEyePosition().x, cam->getEyePosition().y, cam->getEyePosition().z); btVector3 end = start; end += btVector3(start.x() + dir_cam.x, start.y() + dir_cam.y, start.z() + dir_cam.z); - btCollisionWorld::ClosestRayResultCallback RayCallback(start, end); + btCollisionWorld::ClosestRayResultCallback rayCallback(start, end); PhysicsDebugNode* pdnode= getEngine().getPhysicsDebug(); if (pdnode != nullptr) pdnode->drawLine(start,end,btVector3(1,0,1)); - getEngine().getScene()->getPhysics()->rayTest(start,end,RayCallback); + getEngine().getScene()->getPhysics()->rayTest(start, end, rayCallback); - m_pickSucceeded = RayCallback.hasHit(); + m_pickSucceeded = rayCallback.hasHit(); + m_pickedNode = nullptr; if(m_pickSucceeded) { - btVector3 target = RayCallback.m_hitPointWorld; + m_pickedNode = static_cast(rayCallback.m_collisionObject->getUserPointer()); + btVector3 target = rayCallback.m_hitPointWorld; m_pickedPos = glm::vec3(target.x(), target.y(), target.z()); m_geometry.modelMatrix = glm::translate(glm::mat4(), m_pickedPos); } @@ -94,3 +96,22 @@ void ScenePicker::pick() m_pickSucceeded = false; } +btCollisionWorld::ClosestRayResultCallback ScenePicker::pickFromCamera(glm::ivec2 pickPos) +{ + +} + +btCollisionWorld::ClosestRayResultCallback ScenePicker::pickFromCamera() +{ + +} + +btCollisionWorld::ClosestRayResultCallback ScenePicker::pick(glm::vec3 start, glm::vec3 end) +{ + +} + +glm::vec3 ScenePicker::pickPixel(glm::ivec2 pixelPos) +{ + +} diff --git a/src/tools/scenepicker.h b/src/tools/scenepicker.h index 41ab04d..33489ca 100644 --- a/src/tools/scenepicker.h +++ b/src/tools/scenepicker.h @@ -2,12 +2,14 @@ #define SCENEPICKER_H #include "scene/meshnode.h" +#include class ScenePicker : public MeshNode { static Mesh* generateMesh(); glm::vec3 m_pickedPos; + SceneNode* m_pickedNode; bool m_pickSucceeded; public: @@ -21,6 +23,33 @@ public: glm::vec3 getIntersection() { return m_pickedPos; } bool getTraceSucceeded() { m_pickSucceeded; } + + /** + * @brief pickFromCamera performs picking in the physic world + * @param pickPos is the coordinates to pick on the screen (in pixels) + */ + btCollisionWorld::ClosestRayResultCallback pickFromCamera(glm::ivec2 pickPos); + + /** + * @brief pickFromCamera performs picking in the physic world + * this will trace a ray from the center of the screen in the direction of the view + */ + btCollisionWorld::ClosestRayResultCallback pickFromCamera(); + + /** + * @brief pickPhysicsFromCamera performs picking in the physic world + * this will trace a ray from the center of the screen in the direction of the view + */ + btCollisionWorld::ClosestRayResultCallback pick(glm::vec3 start, glm::vec3 end); + + /** + * @brief pickPixel picks a pixel directly in the last frame's positions texture + * @warning accessing the GPU's buffers is a heavy operation, do not overuse it + * + * @param pixelPos the position of the picked pixel + * @return the coordinates of the pixel + */ + glm::vec3 pickPixel(glm::ivec2 pixelPos); }; #endif // SCENEPICKER_H