From 9125e7a3cce37ab13104d2849b4fe6a090721bec Mon Sep 17 00:00:00 2001 From: karl Date: Tue, 29 Sep 2020 21:04:25 +0200 Subject: [PATCH] Add origin vector to Transform We need this in addition to the Matrix (which includes translation) - mainly for rotation, which should be around the translation, but not around the origin. There may be some places left which need changes due to this - the line between the origin and translation isn't as clear yet as it should be. --- ECS/Components/Transform.h | 16 +++++++++------- ECS/Systems/PathMoveSystem.h | 5 +---- ECS/Systems/PositionDebugSystem.h | 6 +++--- ECS/Systems/RenderSystem.h | 31 +++++++++++++++++++------------ main.cpp | 29 ++++++++++++++--------------- 5 files changed, 46 insertions(+), 41 deletions(-) diff --git a/ECS/Components/Transform.h b/ECS/Components/Transform.h index 71a0902..4b837be 100644 --- a/ECS/Components/Transform.h +++ b/ECS/Components/Transform.h @@ -15,11 +15,16 @@ struct Transform { Transform() = default; glm::mat4 matrix = glm::mat4(1.0f); // Initialize as identity + glm::vec3 origin = glm::vec3(0.0f, 0.0f, 0.0f); void translate(glm::vec3 offset) { matrix = glm::translate(matrix, offset); } + glm::vec3 get_translation() { + return glm::vec3(matrix[3]); + } + void uniform_scale(float factor) { scale(glm::vec3(factor, factor, factor)); } @@ -32,9 +37,8 @@ struct Transform { matrix = glm::rotate(matrix, glm::radians(degrees), axis); } - void set_position(glm::vec3 position) { - glm::vec3 difference = getPosition() - position; - translate(-difference); + void set_origin(glm::vec3 position) { + origin = position; } void set_rotation_from_quat(glm::quat quaternion) { @@ -43,12 +47,10 @@ struct Transform { matrix = glm::mat4_cast(quaternion); matrix[3] = save; - - std::cout << glm::to_string(matrix) << std::endl; } - glm::vec3 getPosition() const { - return matrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + glm::vec3 get_origin() const { + return origin; } glm::vec3 forward() const { diff --git a/ECS/Systems/PathMoveSystem.h b/ECS/Systems/PathMoveSystem.h index 8f66bf6..6870a8e 100644 --- a/ECS/Systems/PathMoveSystem.h +++ b/ECS/Systems/PathMoveSystem.h @@ -135,15 +135,12 @@ class PathMoveSystem : public EntitySystem, public EventSubscriber { pathmove->time_passed); // Apply - transform->set_position(point); + transform->set_origin(point); // Rotation // https://www.3dgep.com/understanding-quaternions/#SQUAD PathMove::Views views = pathmove->views; transform->set_rotation_from_quat(views.views[pathmove->current_point_index]); - - // FIXME: Debugging output - std::cout << point.x << ", " << point.y << ", " << point.z << std::endl; }); } diff --git a/ECS/Systems/PositionDebugSystem.h b/ECS/Systems/PositionDebugSystem.h index e2fb8d3..ee4a8ba 100644 --- a/ECS/Systems/PositionDebugSystem.h +++ b/ECS/Systems/PositionDebugSystem.h @@ -17,9 +17,9 @@ public: void tick(World *pWorld, float deltaTime) override { pWorld->each([&](Entity *ent, ComponentHandle transform) { std::cout << ent->getEntityId() << ": " - << transform->getPosition().x << ", " - << transform->getPosition().y << ", " - << transform->getPosition().z + << transform->get_origin().x << ", " + << transform->get_origin().y << ", " + << transform->get_origin().z << std::endl; }); } diff --git a/ECS/Systems/RenderSystem.h b/ECS/Systems/RenderSystem.h index 616409c..24581d1 100644 --- a/ECS/Systems/RenderSystem.h +++ b/ECS/Systems/RenderSystem.h @@ -34,9 +34,14 @@ public: shader.setVec3("lightDirection", light->direction); }); + glm::vec3 cameraPos = cameraTransform->get_origin(); + + glm::mat4 view = cameraTransform->matrix; + view[3] = glm::vec4(cameraPos, 1.0); + shader.setMat4("projection", camera->projection); - shader.setMat4("view", glm::inverse(cameraTransform->matrix)); - shader.setVec3("cameraPosition", cameraTransform->getPosition()); + shader.setMat4("view", glm::inverse(view)); + shader.setVec3("cameraPosition", cameraTransform->get_origin()); std::vector renderObjects; std::vector transparentRenderObjects; @@ -45,8 +50,6 @@ public: renderObjects.emplace_back(RenderObject(transform->matrix, 0, mesh.get(), 0)); });*/ - glm::vec3 cameraPos = cameraTransform->getPosition(); - /*// TODO: Is it possible to do get ObjMeshes in the Mesh loop above implicitly via polymorphism? * // TODO: Commented out because of double rendering - we only want to get objects that explicitly DON'T have a texture here! pWorld->each([&](Entity *ent, ComponentHandle mesh, ComponentHandle transform) { @@ -61,7 +64,7 @@ public: // ObjMesh with textures pWorld->each([&](Entity *ent, ComponentHandle mesh, ComponentHandle transform, ComponentHandle texture) { // Add the object to the renderObjects to draw if the distance is within the min and max distance of the mesh - float distance = glm::distance(cameraPos, transform->getPosition()); + float distance = glm::distance(cameraPos, transform->get_origin()); if (distance > mesh->minDistance && distance < mesh->maxDistance) { // Get optional components @@ -73,16 +76,16 @@ public: // Put it into the list of transparent render objects if the texture wants to be rendered transparently if (textureComponent.isValid() && textureComponent->render_transparent) { - transparentRenderObjects.emplace_back(RenderObject(transform->matrix, textureID, mesh.get(), distance, material)); + transparentRenderObjects.emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh.get(), distance, material)); } else { - renderObjects.emplace_back(RenderObject(transform->matrix, textureID, mesh.get(), distance, material)); + renderObjects.emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh.get(), distance, material)); } } }); // LODObjMesh with Texture pWorld->each([&](Entity *ent, ComponentHandle lodMesh, ComponentHandle transform) { - float distance = glm::distance(cameraPos, transform->getPosition()); + float distance = glm::distance(cameraPos, transform->get_origin()); for (const auto &mesh : lodMesh->meshes) { if (distance > mesh.minDistance && distance < mesh.maxDistance) { @@ -95,9 +98,9 @@ public: // Put it into the list of transparent render objects if the texture wants to be rendered transparently if (textureComponent.isValid() && textureComponent->render_transparent) { - transparentRenderObjects.emplace_back(RenderObject(transform->matrix, textureID, mesh, distance, material)); + transparentRenderObjects.emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh, distance, material)); } else { - renderObjects.emplace_back(RenderObject(transform->matrix, textureID, mesh, distance, material)); + renderObjects.emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh, distance, material)); } } } @@ -118,15 +121,18 @@ public: } struct RenderObject { - RenderObject(const glm::mat4 &matrix, unsigned int textureId, const Mesh &mesh, float distance, const Material &material) + RenderObject(const glm::mat4 &matrix, const glm::vec3 &origin, unsigned int textureId, const Mesh &mesh, float distance, const Material &material) : matrix(matrix), + origin(origin), texture_id(textureId), mesh(mesh), distance(distance), material(material) {} void render(Shader shader) const { - shader.setMat4("model", matrix); + glm::mat4 model_matrix = matrix; + model_matrix[3] = glm::vec4(origin, 1.0); + shader.setMat4("model", model_matrix); // 0 can't be a valid texture name, so we use it for meshes without textures here if (texture_id != 0) { @@ -140,6 +146,7 @@ public: } glm::mat4 matrix; + glm::vec3 origin; unsigned int texture_id; Mesh mesh; float distance; diff --git a/main.cpp b/main.cpp index f58d332..c430998 100644 --- a/main.cpp +++ b/main.cpp @@ -93,24 +93,23 @@ int main() { player->assign(70.0f, 1280, 720, 0.1f, 100.0f); player->assign(10.0, PathMove::Path(std::vector{ glm::vec3(0.0, 2.0, 0.0), - glm::vec3(0.0, 2.0, -1.0), - glm::vec3(2.0, 2.0, -2.0), - glm::vec3(1.0, 3.0, -3.0), - glm::vec3(-2.0, 2.0, -4.0), + glm::vec3(-2.0, 2.0, -1.0), + glm::vec3(-1.0, 2.0, -2.0), + glm::vec3(4.0, 3.0, -3.0), glm::vec3(2.0, 2.0, -4.0), + glm::vec3(1.0, 2.0, -4.0), glm::vec3(0.0, 2.0, -10.0) }), PathMove::Views(std::vector{ glm::quat(0.0, 0.0, 0.0, 0.0), + glm::angleAxis(glm::radians(-10.f), glm::vec3(0.f, 1.f, 0.f)), glm::angleAxis(glm::radians(10.f), glm::vec3(0.f, 1.f, 0.f)), - glm::angleAxis(glm::radians(30.f), glm::vec3(0.f, 1.f, 0.f)), glm::angleAxis(glm::radians(40.f), glm::vec3(0.f, 1.f, 0.f)), - glm::angleAxis(glm::radians(50.f), glm::vec3(0.f, 1.f, 0.f)), - glm::angleAxis(glm::radians(70.f), glm::vec3(0.f, 1.f, 0.f)), - glm::angleAxis(glm::radians(80.f), glm::vec3(0.f, 1.f, 0.f)) + glm::angleAxis(glm::radians(90.f), glm::vec3(0.f, 1.f, 0.f)), + glm::angleAxis(glm::radians(95.f), glm::vec3(0.f, 1.f, 0.f)), + glm::angleAxis(glm::radians(180.f), glm::vec3(0.f, 1.f, 0.f)) }) ); - player->get()->translate(glm::vec3(0.0f, 1.0f, 2.0f)); Entity *monkey = world->create(); monkey->assign(); @@ -119,28 +118,28 @@ int main() { monkey->assign("Resources/Marble.jpg", Texture::Settings(true, false)); monkey->assign(glm::vec3(0.0, 0.3, 0.0), 0.5); monkey->assign(0.6, 0.6); - monkey->get()->translate(glm::vec3(0.0f, 2.0f, -6.0f)); + monkey->get()->set_origin(glm::vec3(0.0f, 2.0f, -6.0f)); Entity *wall1 = world->create(); wall1->assign(); wall1->assign(ObjMesh("Resources/Wall.obj", ObjMesh::Settings())); wall1->assign("Resources/Glass.png", Texture::Settings(true, true)); wall1->assign(0.2, 0.8); - wall1->get()->translate(glm::vec3(0.0f, 0.0f, -2.0f)); + wall1->get()->set_origin(glm::vec3(0.0f, 0.0f, -2.0f)); Entity *wall2 = world->create(); wall2->assign(); wall2->assign(ObjMesh("Resources/Wall.obj", ObjMesh::Settings())); wall2->assign("Resources/Glass.png", Texture::Settings(true, true)); wall2->assign(0.2, 0.8); - wall2->get()->translate(glm::vec3(0.0f, 0.0f, -10.0f)); + wall2->get()->set_origin(glm::vec3(0.0f, 0.0f, -10.0f)); Entity *wall3 = world->create(); wall3->assign(); wall3->assign(ObjMesh("Resources/Wall.obj", ObjMesh::Settings())); wall3->assign("Resources/Glass.png", Texture::Settings(true, true)); wall3->assign(0.2, 0.8); - wall3->get()->translate(glm::vec3(4.0f, 0.0f, -6.0f)); + wall3->get()->set_origin(glm::vec3(4.0f, 0.0f, -6.0f)); wall3->get()->rotate(90.0, glm::vec3(0.0, 1.0, 0.0)); Entity *wall4 = world->create(); @@ -148,7 +147,7 @@ int main() { wall4->assign(ObjMesh("Resources/Wall.obj", ObjMesh::Settings())); wall4->assign("Resources/Glass.png", Texture::Settings(true, true)); wall4->assign(0.2, 0.8); - wall4->get()->translate(glm::vec3(-4.0f, 0.0f, -6.0f)); + wall4->get()->set_origin(glm::vec3(-4.0f, 0.0f, -6.0f)); wall4->get()->rotate(90.0, glm::vec3(0.0, 1.0, 0.0)); Entity *ground = world->create(); @@ -156,7 +155,7 @@ int main() { ground->assign(ObjMesh("Resources/Ground.obj", ObjMesh::Settings())); ground->assign("Resources/Grass.jpg", Texture::Settings(true, false)); ground->assign(1.0, 0.0); - ground->get()->translate(glm::vec3(0.0f, 0.0f, 0.0f)); + ground->get()->set_origin(glm::vec3(0.0f, 0.0f, 0.0f)); Entity *sun = world->create(); sun->assign(glm::normalize(glm::vec3(1.0, 1.0, 1.0)));