Skip to content

Commit

Permalink
gh-36: impl scene transform & add node setup and common nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorOrachyov committed Aug 1, 2023
1 parent c1e03ea commit ede17b8
Show file tree
Hide file tree
Showing 16 changed files with 578 additions and 52 deletions.
2 changes: 2 additions & 0 deletions engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,8 @@ add_library(wmoge STATIC
scene/scene_manager.hpp
scene/scene_node.cpp
scene/scene_node.hpp
scene/scene_nodes.cpp
scene/scene_nodes.hpp
scene/scene_transform.cpp
scene/scene_transform.hpp
scene/scene_tree.cpp
Expand Down
10 changes: 7 additions & 3 deletions engine/core/array_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,14 @@ namespace wmoge {
class ArrayView {
public:
ArrayView() = default;
explicit ArrayView(T* data, std::size_t size) : m_data(data), m_size(size) {}
explicit ArrayView(std::vector<T>& vector) : m_data(vector.data()), m_size(vector.size()) {}
ArrayView(T* data, std::size_t size) : m_data(data), m_size(size) {}
ArrayView(std::vector<T>& vector) : m_data(vector.data()), m_size(vector.size()) {}
template<typename M>
ArrayView(const std::vector<M>& vector) : m_data(vector.data()), m_size(vector.size()) {}
template<std::size_t MinCapacity>
explicit ArrayView(ankerl::svector<T, MinCapacity>& vector) : m_data(vector.data()), m_size(vector.size()) {}
ArrayView(ankerl::svector<T, MinCapacity>& vector) : m_data(vector.data()), m_size(vector.size()) {}
template<typename M, std::size_t MinCapacity>
ArrayView(const ankerl::svector<M, MinCapacity>& vector) : m_data(vector.data()), m_size(vector.size()) {}

T& operator[](const int i) {
assert(i < size());
Expand Down
1 change: 1 addition & 0 deletions engine/core/object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ namespace wmoge {
#define WG_OBJECT(name, super) \
public: \
friend class Class; \
name() = default; \
~name() override = default; \
static void register_class(); \
const class Class* class_ptr() const override { return class_ptr_static(); } \
Expand Down
1 change: 1 addition & 0 deletions engine/engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
#include "scene/scene_components.hpp"
#include "scene/scene_manager.hpp"
#include "scene/scene_node.hpp"
#include "scene/scene_nodes.hpp"
#include "scene/scene_transform.hpp"
#include "scene/scene_tree.hpp"

Expand Down
40 changes: 38 additions & 2 deletions engine/math/quat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@
#ifndef WMOGE_QUAT_HPP
#define WMOGE_QUAT_HPP

#include <math/mat.hpp>
#include <math/vec.hpp>
#include "io/yaml.hpp"
#include "math/mat.hpp"
#include "math/vec.hpp"

namespace wmoge {

Expand Down Expand Up @@ -260,6 +261,27 @@ namespace wmoge {
return r;
}

Vec as_euler() const {
Vec angles;

// roll (x-axis rotation)
const T sinr_cosp = T(2) * (scalar * vec.x() + vec.y() * vec.z());
const T cosr_cosp = T(1) - T(2) * (vec.x() * vec.x() + vec.y() * vec.y());
angles[0] = Math::atan2(sinr_cosp, cosr_cosp);

// yaw (y-axis rotation)
const T sinp = Math::sqrt(T(1) + T(2) * (scalar * vec.y() - vec.x() * vec.z()));
const T cosp = Math::sqrt(T(1) - T(2) * (scalar * vec.y() - vec.x() * vec.z()));
angles[1] = T(2) * Math::atan2(sinp, cosp) - T(Math::HALF_PI) / T(2);

// pitch (z-axis rotation)
const T siny_cosp = T(2) * (scalar * vec.z() + vec.x() * vec.y());
const T cosy_cosp = T(1) - T(2) * (vec.y() * vec.y() + vec.z() * vec.z());
angles[2] = Math::atan2(siny_cosp, cosy_cosp);

return angles;
}

void axis_angle(Vec& axis, T& angle) const {
angle = (T) 2 * Math::acos(scalar);
T s = Math::max((T) (1.0 - scalar * scalar), (T) 0.0);
Expand Down Expand Up @@ -416,6 +438,20 @@ namespace wmoge {
return ostream;
}

template<typename T>
bool yaml_read(const YamlConstNodeRef& node, TQuat<T>& quat) {
WG_YAML_READ_AS(node, "scalar", quat.scalar);
WG_YAML_READ_AS(node, "vec", quat.vec);
return true;
}
template<typename T>
bool yaml_write(YamlNodeRef node, const TQuat<T>& quat) {
WG_YAML_MAP(node);
WG_YAML_WRITE_AS(node, "scalar", quat.scalar);
WG_YAML_WRITE_AS(node, "vec", quat.vec);
return true;
}

}// namespace wmoge

namespace std {
Expand Down
89 changes: 84 additions & 5 deletions engine/math/transform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#ifndef WMOGE_TRANSFORM_HPP
#define WMOGE_TRANSFORM_HPP

#include "io/yaml.hpp"
#include "math/mat.hpp"
#include "math/math_utils2d.hpp"
#include "math/math_utils3d.hpp"
Expand Down Expand Up @@ -71,6 +72,20 @@ namespace wmoge {
Math2d::translate(-m_translation);
}

friend bool yaml_read(const YamlConstNodeRef& node, Transform2d& transform) {
WG_YAML_READ_AS_OPT(node, "rotation", transform.m_rotation);
WG_YAML_READ_AS_OPT(node, "translation", transform.m_translation);
WG_YAML_READ_AS_OPT(node, "scale", transform.m_scale);
return true;
}
friend bool yaml_write(YamlNodeRef node, const Transform2d& transform) {
WG_YAML_MAP(node);
WG_YAML_WRITE_AS(node, "rotation", transform.m_rotation);
WG_YAML_WRITE_AS(node, "translation", transform.m_translation);
WG_YAML_WRITE_AS(node, "scale", transform.m_scale);
return true;
}

private:
Vec2f m_translation;
Vec2f m_scale;
Expand All @@ -96,28 +111,92 @@ namespace wmoge {
void rotate_z(float rad) { m_rotation = Quatf(Vec3f::axis_z(), rad) * m_rotation; }
void scale(const Vec3f& scale) { m_scale *= scale; }

Mat4x4f get_transform() {
[[nodiscard]] Mat4x4f get_transform() const {
return Math3d::translate(m_translation) *
m_rotation.as_matrix() *
Math3d::scale(m_scale);
}

Mat4x4f get_inverse_transform() {
[[nodiscard]] Mat4x4f get_inverse_transform() const {
return Math3d::scale(Vec3f(1.0f, 1.0f, 1.0f) / m_scale) *
m_rotation.inverse().as_matrix() *
Math3d::translate(-m_translation);
}

const Quatf& get_rotation() const { return m_rotation; }
const Vec3f& get_translation() const { return m_translation; }
const Vec3f& get_scale() const { return m_scale; }
[[nodiscard]] const Quatf& get_rotation() const { return m_rotation; }
[[nodiscard]] const Vec3f& get_translation() const { return m_translation; }
[[nodiscard]] const Vec3f& get_scale() const { return m_scale; }

friend bool yaml_read(const YamlConstNodeRef& node, Transform3d& transform) {
WG_YAML_READ_AS_OPT(node, "rotation", transform.m_rotation);
WG_YAML_READ_AS_OPT(node, "translation", transform.m_translation);
WG_YAML_READ_AS_OPT(node, "scale", transform.m_scale);
return true;
}
friend bool yaml_write(YamlNodeRef node, const Transform3d& transform) {
WG_YAML_MAP(node);
WG_YAML_WRITE_AS(node, "rotation", transform.m_rotation);
WG_YAML_WRITE_AS(node, "translation", transform.m_translation);
WG_YAML_WRITE_AS(node, "scale", transform.m_scale);
return true;
}

private:
Quatf m_rotation;
Vec3f m_translation;
Vec3f m_scale;
};

/**
* @class TransformEdt
* @brief Utility to manage 3d space transformations with euler angles
*/
class TransformEdt {
public:
TransformEdt() {
m_scale = Vec3f(1, 1, 1);
}

void translate(const Vec3f& offset) { m_translation += offset; }
void rotate(const Vec3f& angles) { m_rotation += angles; }
void scale(const Vec3f& scale) { m_scale *= scale; }

[[nodiscard]] Mat4x4f get_transform() const {
return Math3d::translate(m_translation) *
Quatf(m_rotation[0], m_rotation[1], m_rotation[2]).as_matrix() *
Math3d::scale(m_scale);
}

[[nodiscard]] Mat4x4f get_inverse_transform() const {
return Math3d::scale(Vec3f(1.0f, 1.0f, 1.0f) / m_scale) *
Quatf(m_rotation[0], m_rotation[1], m_rotation[2]).inverse().as_matrix() *
Math3d::translate(-m_translation);
}

[[nodiscard]] const Vec3f& get_rotation() const { return m_rotation; }
[[nodiscard]] const Vec3f& get_translation() const { return m_translation; }
[[nodiscard]] const Vec3f& get_scale() const { return m_scale; }

friend bool yaml_read(const YamlConstNodeRef& node, TransformEdt& transform) {
WG_YAML_READ_AS_OPT(node, "rotation", transform.m_rotation);
WG_YAML_READ_AS_OPT(node, "translation", transform.m_translation);
WG_YAML_READ_AS_OPT(node, "scale", transform.m_scale);
return true;
}
friend bool yaml_write(YamlNodeRef node, const TransformEdt& transform) {
WG_YAML_MAP(node);
WG_YAML_WRITE_AS(node, "rotation", transform.m_rotation);
WG_YAML_WRITE_AS(node, "translation", transform.m_translation);
WG_YAML_WRITE_AS(node, "scale", transform.m_scale);
return true;
}

private:
Vec3f m_rotation;
Vec3f m_translation;
Vec3f m_scale;
};

}// namespace wmoge

#endif//WMOGE_TRANSFORM_HPP
8 changes: 7 additions & 1 deletion engine/scene/register_classes_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,18 @@

#include "register_classes_scene.hpp"

#include "scene_node.hpp"
#include "scene/scene_node.hpp"
#include "scene/scene_nodes.hpp"

namespace wmoge {

void register_classes_scene() {
SceneNode::register_class();
SceneNodeFolder::register_class();
SceneNodeTransform::register_class();
SceneNodePrefab::register_class();
SceneNodeEntity::register_class();
SceneNodeCamera::register_class();
}

}// namespace wmoge
13 changes: 7 additions & 6 deletions engine/scene/scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,13 @@

#include "scene.hpp"

#include "debug/profiler.hpp"
#include "scene/scene_manager.hpp"

namespace wmoge {

Scene::Scene(StringId name) {
m_name = name;
m_tree = std::make_unique<SceneTree>();
m_ecs_world = std::make_unique<EcsWorld>();
m_name = name;
m_tree = std::make_unique<SceneTree>();
m_transforms = std::make_unique<SceneTransformManager>();
m_ecs_world = std::make_unique<EcsWorld>();
}

const StringId& Scene::get_name() {
Expand All @@ -44,6 +42,9 @@ namespace wmoge {
SceneTree* Scene::get_tree() {
return m_tree.get();
}
SceneTransformManager* Scene::get_transforms() {
return m_transforms.get();
}
EcsWorld* Scene::get_ecs_world() {
return m_ecs_world.get();
}
Expand Down
15 changes: 9 additions & 6 deletions engine/scene/scene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "core/ref.hpp"
#include "ecs/ecs_world.hpp"
#include "platform/window.hpp"
#include "scene/scene_transform.hpp"
#include "scene/scene_tree.hpp"

#include <memory>
Expand All @@ -48,14 +49,16 @@ namespace wmoge {
Scene(StringId name = StringId());
~Scene() override = default;

[[nodiscard]] const StringId& get_name();
[[nodiscard]] SceneTree* get_tree();
[[nodiscard]] EcsWorld* get_ecs_world();
[[nodiscard]] const StringId& get_name();
[[nodiscard]] SceneTree* get_tree();
[[nodiscard]] SceneTransformManager* get_transforms();
[[nodiscard]] EcsWorld* get_ecs_world();

private:
StringId m_name;
std::unique_ptr<SceneTree> m_tree;
std::unique_ptr<EcsWorld> m_ecs_world;
StringId m_name;
std::unique_ptr<SceneTree> m_tree;
std::unique_ptr<SceneTransformManager> m_transforms;
std::unique_ptr<EcsWorld> m_ecs_world;
};

}// namespace wmoge
Expand Down
24 changes: 12 additions & 12 deletions engine/scene/scene_components.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,22 @@ namespace wmoge {
fast_vector<EcsEntity> children;
};

/**
* @class EcsComponentParent
* @brief Parent entity, for complex objects
*/
struct EcsComponentParent {
WG_ECS_COMPONENT(EcsComponentParent, 1);

EcsEntity parent;
};

/**
* @class EcsComponentSceneTransform
* @brief Node in a relative transform hierarchy of objects
*/
struct EcsComponentSceneTransform {
WG_ECS_COMPONENT(EcsComponentSceneTransform, 1);
WG_ECS_COMPONENT(EcsComponentSceneTransform, 2);

Ref<SceneTransform> transform;
};
Expand All @@ -65,21 +75,11 @@ namespace wmoge {
* @brief Matrix to convert local to world coordinates of an object
*/
struct EcsComponentLocalToWorld {
WG_ECS_COMPONENT(EcsComponentLocalToWorld, 2);
WG_ECS_COMPONENT(EcsComponentLocalToWorld, 3);

Mat4x4f matrix;
};

/**
* @class EcsComponentBox
* @brief Bounding volume of an object which can be used for culling
*/
struct EcsComponentBox {
WG_ECS_COMPONENT(EcsComponentBox, 3);

Aabbf box;
};

/**
* @class EcsComponentSceneNode
* @brief Node for bidirectional mapping of runtime and static game object representation
Expand Down
Loading

0 comments on commit ede17b8

Please sign in to comment.