Skip to content

Commit

Permalink
Merge branch 'examples' of github.com:tmayoff/wren into examples
Browse files Browse the repository at this point in the history
  • Loading branch information
tmayoff committed Nov 28, 2024
2 parents 70670e9 + 20054df commit 5407f41
Show file tree
Hide file tree
Showing 16 changed files with 220 additions and 68 deletions.
4 changes: 4 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
coverage:
status:
project: false
ignore:
- "examples"
- "tools"
- "subprojects"
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ subdir('wren_vk')
# subdir('wren_gltf')
# subdir('wren_gui')
subdir('wren')
subdir('wren_physics')
# subdir('wren_ecs')
subdir('editor')

Expand Down
17 changes: 13 additions & 4 deletions wren/include/wren/scene/components.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
#pragma once

#include <functional>
#include <flecs.h>

#include "scene.hpp"
namespace wren::scene::components {

namespace wren::scene {
struct Base {
Base() = default;
Base(const Base &) = default;
Base(Base &&) = delete;
auto operator=(const Base &) -> Base & = default;
auto operator=(Base &&) -> Base & = delete;
virtual ~Base() = default;

// virtual void init(const flecs::world &world) = 0;
};

// void iterate_known_components(const Scene& scene, entt::entity entity,
// std::function<void()>);

}
} // namespace wren::scene::components
40 changes: 40 additions & 0 deletions wren/include/wren/scene/components/collider.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#include <flecs.h>

#include <memory>
#include <optional>
#include <wren/math/vector.hpp>
#include <wren/scene/components/transform.hpp>

#include "../components.hpp"

namespace wren::scene::components {

struct Collider : public Base {
using Ptr = std::shared_ptr<Collider>;

[[nodiscard]] virtual auto raycast(const Transform& transform,
const math::Vec3f& origin,
const math::Vec3f& direction) const
-> std::optional<math::Vec3f> = 0;
};

struct BoxCollider2D : public Collider {
static void init(const flecs::world& world) {
static bool inited = false;
if (!inited) {
inited = true;
world.component<BoxCollider2D::Ptr>().is_a<Collider>();
}
}

[[nodiscard]] auto raycast(const Transform& transform,
const math::Vec3f& origin,
const math::Vec3f& direction) const
-> std::optional<math::Vec3f> override;

math::Vec2f size;
};

} // namespace wren::scene::components
17 changes: 14 additions & 3 deletions wren/include/wren/scene/entity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <flecs.h>

#include "components.hpp"
#include "scene.hpp"

namespace wren::scene {
Expand Down Expand Up @@ -30,18 +31,28 @@ class Entity {

template <typename T>
auto Entity::has_component() const -> bool {
// return scene_->world().all_of<T>();
return entity_.has<T>();
}

template <typename T>
auto Entity::get_component() -> T& {
return scene_->world().get<T>(entity_);
return *entity_.get_mut<T>();
}

template <typename T>
concept HasInit = requires() { T::init(); };

template <typename T, typename... Args>
void Entity::add_component(Args&&... args) {
entity_.add<T>();
entity_.set<T>(T(std::forward<Args>(args)...));
if (sizeof...(args) > 0) {
T t(std::forward<Args...>(args)...);
entity_.set<T>(t);
}

if constexpr (HasInit<T>) {
T::init(scene_->world());
}
}

} // namespace wren::scene
2 changes: 1 addition & 1 deletion wren/include/wren/scene/scene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Scene : public std::enable_shared_from_this<Scene> {
public:
static auto create() { return std::shared_ptr<Scene>(new Scene()); }

auto create_entity(const std::string& name = "entity") -> flecs::entity;
auto create_entity(const std::string& name = "entity") -> Entity;

auto world() const -> const flecs::world& { return ecs_; }
auto world() -> flecs::world& { return ecs_; }
Expand Down
1 change: 1 addition & 0 deletions wren/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ wren = library(
'src/render_pass.cpp',
'src/render_target.cpp',
'src/renderer.cpp',
'src/scene/components/collider.cpp',
'src/scene/deserialization.cpp',
'src/scene/scene.cpp',
'src/scene/serialization.cpp',
Expand Down
26 changes: 26 additions & 0 deletions wren/src/scene/components/collider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "scene/components/collider.hpp"

namespace wren::scene::components {

auto BoxCollider2D::raycast(const Transform& transform,
const math::Vec3f& origin,
const math::Vec3f& direction) const
-> std::optional<math::Vec3f> {
math::Vec3f normal =
math::Quaternionf{transform.rotation}.to_mat() * math::Vec3f{0, 0, 1};

float denominator = normal.dot(direction);
if (std::abs(denominator) < 0.0001) {
return {};
}

float t = normal.dot(transform.position - origin) / denominator;
if (t < 0) {
// Intersection points is behind the ray's origin
return {};
}

return origin + direction * t;
}

} // namespace wren::scene::components
4 changes: 2 additions & 2 deletions wren/src/scene/deserialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ auto deserialize(const std::filesystem::path& project_root,

for (const auto& [key, val] : entity_table) {
if (key.str() == "transform") {
auto& t = *entity.get_mut<components::Transform>();
auto& t = entity.get_component<components::Transform>();
deserialize(*val.as_table(), t);
} else if (key.str() == "mesh_renderer") {
components::MeshRenderer mesh_renderer{};
deserialize(*val.as_table(), project_root, mesh_renderer);
entity.emplace<components::MeshRenderer>(mesh_renderer);
entity.add_component<components::MeshRenderer>(mesh_renderer);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions wren/src/scene/scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

namespace wren::scene {

auto Scene::create_entity(const std::string& name) -> flecs::entity {
auto Scene::create_entity(const std::string& name) -> Entity {
auto entity = ecs_.entity(name.c_str());

// entity.add_component<components::Tag>(name);
entity.add<components::Transform>();

return entity;
return {entity, shared_from_this()};
}

} // namespace wren::scene
21 changes: 21 additions & 0 deletions wren_physics/include/wren/physics/ray.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include <flecs.h>

#include <wren/math/vector.hpp>

namespace wren::physics {

struct RayHit {
bool hit = false;
math::Vec3f point;
};

struct Ray {
math::Vec3f origin;
math::Vec3f direction;
};

auto raycast(const flecs::world& world, const Ray& ray, RayHit& hit) -> bool;

} // namespace wren::physics
12 changes: 12 additions & 0 deletions wren_physics/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
wren_physics = static_library(
'wren_physics',
'src/ray.cpp',
dependencies: [wren_dep, flecs],
include_directories: ['include/wren', 'include/wren/physics'],
)
wren_physics_dep = declare_dependency(
include_directories: 'include',
link_with: wren_physics,
)

subdir('tests')
28 changes: 28 additions & 0 deletions wren_physics/src/ray.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "physics/ray.hpp"

#include <wren/scene/components/collider.hpp>
#include <wren/scene/components/transform.hpp>

namespace wren::physics {

auto raycast(const flecs::world& world, const Ray& ray, RayHit& hit) -> bool {
const auto q = world.query<const scene::components::Transform,
const scene::components::Collider::Ptr>();

q.each([ray, &hit](const scene::components::Transform& transform,
const scene::components::Collider::Ptr& collider) {
if (hit.hit) {
return;
}

auto pos = collider->raycast(transform, ray.origin, ray.direction);
if (pos.has_value()) {
hit.hit = true;
hit.point = pos.value();
}
});

return hit.hit;
}

} // namespace wren::physics
12 changes: 12 additions & 0 deletions wren_physics/tests/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
tests = ['raycast']
foreach test : tests
test(
'wren_physics_@0@'.format(test),
executable(
'wren_physics_@0@_test'.format(test),
'@[email protected]'.format(test),
dependencies: [wren_physics_dep, wren_dep, boost_test],
cpp_args: ['-DBOOST_TEST_MODULE=@0@'.format(test)],
),
)
endforeach
43 changes: 43 additions & 0 deletions wren_physics/tests/raycast.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <boost/test/unit_test.hpp>
#include <wren/physics/ray.hpp>
#include <wren/scene/components.hpp>
#include <wren/scene/components/collider.hpp>
#include <wren/scene/components/transform.hpp>
#include <wren/scene/entity.hpp>
#include <wren/scene/scene.hpp>

namespace physics = wren::physics;
namespace components = wren::scene::components;
namespace math = wren::math;

BOOST_AUTO_TEST_SUITE(raycasting)

BOOST_AUTO_TEST_CASE(RaycastBoxCollider) {
const auto scene = wren::scene::Scene::create();

auto box = scene->create_entity("box");

box.add_component<components::BoxCollider2D::Ptr>(
new components::BoxCollider2D());
auto& transform = box.get_component<components::Transform>();
transform.position.z(-10);
// transform.position.x(1000);

BOOST_TEST(box.has_component<components::BoxCollider2D::Ptr>());

const auto q = scene->world().query<const components::Collider::Ptr>();
BOOST_TEST(q.count() == 1);

physics::Ray ray;
ray.direction = (transform.position - math::Vec3f(0));

physics::RayHit hit{};
physics::raycast(scene->world(), ray, hit);

BOOST_TEST(hit.hit);

const float length = (hit.point - math::Vec3f{0, 0, -10}).length();
BOOST_TEST(length <= 0.001);
}

BOOST_AUTO_TEST_SUITE_END()
56 changes: 0 additions & 56 deletions xmake.lua

This file was deleted.

0 comments on commit 5407f41

Please sign in to comment.