Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • gamedev/fggl
  • onuralpsezer/fggl
2 results
Show changes
Showing
with 67458 additions and 34 deletions
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 31/07/22.
//
#include "fggl/phys/bullet/module.hpp"
#include "fggl/phys/bullet/service.hpp"
namespace fggl::phys::bullet {
bool Bullet::factory(modules::ModuleService service, modules::Services& services) {
if ( service == phys::PhysicsProvider::service ) {
services.bind<phys::PhysicsProvider, BulletProvider>();
}
return false;
}
} // namespace fggl::phys::bullet
\ No newline at end of file
/*
* ${license.title}
* Copyright (C) 2022 ${license.owner}
* ${license.mailto}
* This file is part of FGGL.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 30/05/22.
//
#include "fggl/phys/bullet/phys_draw.hpp"
#include "../include/fggl/phys/bullet/phys_draw.hpp"
#include "fggl/debug/draw.hpp"
#include <iostream>
......
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 01/08/22.
//
#include "fggl/phys/bullet/service.hpp"
#include "fggl/phys/bullet/types.hpp"
#include "fggl/phys/bullet/motion.hpp"
namespace fggl::phys::bullet {
constexpr float UNIT_EXTENT = 0.5F;
btCollisionShape* create_bullet_shape(const YAML::Node& node) {
auto type = node["type"].as<std::string>("MISSING");
if ( type == "sphere" ) {
auto radius = node["radius"].as<float>(UNIT_EXTENT);
return new btSphereShape(radius);
} else if ( type == "box" ) {
auto extents = node["extents"].as<math::vec3>(math::vec3(UNIT_EXTENT));
return new btBoxShape(btVector3(extents.x, extents.y, extents.z));
} else {
debug::warning("unknown shape type: {}, assuming unit sphere", type);
return new btSphereShape(0.5F);
}
}
void setup_body(BodyType type, btRigidBody& body) {
if ( type != BodyType::STATIC ) {
body.setRestitution(0.5F);
body.setRollingFriction(0.0F);
// kinematic bodies cannot sleep
if (type == BodyType::KINEMATIC) {
auto flags = (body.getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
body.setCollisionFlags(flags);
body.setActivationState(DISABLE_DEACTIVATION);
}
}
}
void add_bt_body(const entity::ComponentSpec& spec, entity::EntityManager& manager, const entity::EntityID& id) {
auto& body = manager.add<BulletBody>(id);
body.motion = new FgglMotionState(&manager, id);
auto type = spec.get<BodyType>("type", BodyType::DYNAMIC);
auto mass = 0.0F;
// non-static objects can have mass
if ( type != BodyType::STATIC ) {
mass = spec.get<float>("mass", 1.0F);
}
// calculate inertia
btCollisionShape* shape = create_bullet_shape(spec.config["shape"]);
btVector3 inertia(0, 0, 0);
if ( type != BodyType::STATIC ) {
shape->calculateLocalInertia(mass, inertia);
}
// construction information for the simulation
btRigidBody::btRigidBodyConstructionInfo constructionInfo {
mass,
body.motion,
shape,
inertia
};
body.body = new btRigidBody(constructionInfo);
setup_body(type, *body.body);
// add the body to the simulation
if ( type == BodyType::DYNAMIC ) {
manager.add<phys::Dynamics>(id);
}
}
PhysicsEngine* BulletProvider::create(entity::EntityManager* entityManager, entity::EntityFactory* factory) {
auto* engine = new BulletPhysicsEngine(entityManager);
// FIXME: this won't work across multiple scenes - reactive approach might be better...
factory->bind(util::make_guid("phys::Body"), add_bt_body, [engine](auto& manager, const auto& entity) {
debug::trace("adding entity {} to physics scene...", (uint64_t)entity);
auto& physComp = manager.template get<BulletBody>(entity);
engine->addBody(entity, physComp);
});
return engine;
}
} // namespace fggl::phys::bullet
\ No newline at end of file
/*
* ${license.title}
* Copyright (C) 2022 ${license.owner}
* ${license.mailto}
* This file is part of FGGL.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
#include "fggl/phys/bullet/types.hpp"
#include "fggl/phys/bullet/motion.hpp"
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
#include "../include/fggl/phys/bullet/types.hpp"
#include "../include/fggl/phys/bullet/motion.hpp"
namespace fggl::phys::bullet {
......@@ -27,7 +35,7 @@ namespace fggl::phys::bullet {
return {fgglVec.x, fgglVec.y, fgglVec.z};
}
BulletPhysicsEngine::BulletPhysicsEngine(ecs3::World* world) : m_ecs(world), m_config(), m_world(nullptr) {
BulletPhysicsEngine::BulletPhysicsEngine(entity::EntityManager* world) : m_ecs(world), m_config(), m_world(nullptr), m_debug(nullptr) {
m_config.broadphase = new btDbvtBroadphase();
m_config.collisionConfiguration = new btDefaultCollisionConfiguration();
m_config.dispatcher = new btCollisionDispatcher(m_config.collisionConfiguration);
......@@ -39,153 +47,101 @@ namespace fggl::phys::bullet {
m_config.solver,
m_config.collisionConfiguration);
m_debug = std::make_unique<debug::BulletDebugDrawList>();
m_world->setDebugDrawer( m_debug.get() );
m_debug->setDebugMode(1);
// callbacks (for handling bullet -> ecs)
// ensure we deal with ecs -> bullet changes
m_ecs->addDeathListener( [this](auto entity) { this->onEntityDeath(entity);} );
//m_ecs->addDeathListener( [this](auto entity) { this->onEntityDeath(entity);} );
}
void BulletPhysicsEngine::step() {
checkForPhys();
// this is now handled on creation
//checkForPhys();
auto dynamicEnts = m_ecs->findMatching<phys::Dynamics>();
auto dynamicEnts = m_ecs->find<phys::Dynamics, phys::bullet::BulletBody>();
for (auto& ent : dynamicEnts) {
auto* dynamicComp = m_ecs->get<phys::Dynamics>(ent);
auto* bulletProxy = m_ecs->get<phys::bullet::BulletBody>(ent);
if ( bulletProxy == nullptr ) {
std::cerr << "entity has dynamics but isn't a physics object!" << std::endl;
continue;
}
auto& dynamicComp = m_ecs->get<phys::Dynamics>(ent);
auto& bulletProxy = m_ecs->get<phys::bullet::BulletBody>(ent);
const auto forceVec = dynamicComp->force;
const auto forceVec = dynamicComp.force;
if ( glm::length(forceVec) != 0.F ) {
bulletProxy->body->applyCentralForce({forceVec.x, forceVec.y, forceVec.z});
bulletProxy->body->activate();
dynamicComp->force = math::VEC3_ZERO;
bulletProxy.body->applyCentralForce({forceVec.x, forceVec.y, forceVec.z});
bulletProxy.body->activate();
dynamicComp.force = math::VEC3_ZERO;
}
}
m_world->stepSimulation(60.0f);
m_world->stepSimulation(60.0F);
//syncToECS();
pollCollisions();
if ( debugDraw ) {
// if debug draw is enabled, trigger a draw call
if ( m_debug != nullptr ) {
m_world->debugDrawWorld();
}
}
inline btCollisionShape* shape_to_bullet(const phys::RigidBody* fgglBody) {
if ( fgglBody->shape == nullptr ) {
// they forgot to put a shape, we'll assume a unit sphere to avoid crashes...
return new btSphereShape(0.5f);
}
void BulletPhysicsEngine::addBody(entity::EntityID /*entity*/, BulletBody &body) {
// ensure static objects are placed correctly by setting their transforms to the correct value
btTransform transform;
body.body->getMotionState()->getWorldTransform(transform);
body.body->setWorldTransform(transform);
switch (fgglBody->shape->type) {
case phys::ShapeType::BOX: {
auto extents = ((phys::Box*)fgglBody->shape)->extents;
return new btBoxShape({extents.x, extents.y, extents.z});
}
case phys::ShapeType::SPHERE: {
float radius = ((phys::Sphere*)fgglBody->shape)->radius;
return new btSphereShape(radius);
}
default:
return new btSphereShape(0.5f);
}
m_world->addRigidBody(body.body);
}
void BulletPhysicsEngine::checkForPhys() {
// FIXME without reactive-based approaches this is very slow
auto entsWantPhys = m_ecs->findMatching<phys::RigidBody>();
for (auto ent : entsWantPhys) {
auto* btComp = m_ecs->tryGet<BulletBody>(ent);
if ( btComp != nullptr ) {
// they are already in the simulation
continue;
}
// set up the bullet proxy for our object
btComp = m_ecs->add<BulletBody>(ent);
const auto* fgBody = m_ecs->get<phys::RigidBody>(ent);
btComp->motion = new FgglMotionState(m_ecs, ent);
// collisions
btCollisionShape* colShape = shape_to_bullet(fgBody);
btVector3 localInt(0, 0, 0);
if ( !fgBody->isStatic() ) {
colShape->calculateLocalInertia(fgBody->mass, localInt);
}
// setup the construction information
btRigidBody::btRigidBodyConstructionInfo bodyCI(
fgBody->mass,
btComp->motion,
colShape,
localInt
);
btComp->body = new btRigidBody(bodyCI);
btComp->body->setUserIndex( static_cast<int>(ent) );
if (!fgBody->isStatic()) {
btComp->body->setRestitution(0.5f);
btComp->body->setRollingFriction(0.0f);
}
if ( fgBody->type == BodyType::KINEMATIC ) {
auto flags = btComp->body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT;
btComp->body->setCollisionFlags( flags );
// we don't have a clean way of saying a kinematic object moved, so just prevent sleeping.
// if this turns out to be an issue, we'll need to revisit this.
btComp->body->setActivationState( DISABLE_DEACTIVATION );
}
m_world->addRigidBody( btComp->body );
void BulletPhysicsEngine::setDebugDraw(bool active) {
if ( active ) {
m_debug = std::make_unique<debug::BulletDebugDrawList>();
m_world->setDebugDrawer(m_debug.get());
m_debug->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
} else {
m_debug = nullptr;
}
}
void BulletPhysicsEngine::forceSyncToECS() {
const auto physEnts = m_ecs->findMatching<BulletBody>();
void BulletPhysicsEngine::syncTransformToECS() {
const auto physEnts = m_ecs->find<math::Transform, BulletBody>();
for (const auto& ent : physEnts) {
auto* transform = m_ecs->get<math::Transform>(ent);
auto* physBody = m_ecs->get<BulletBody>(ent);
auto& physBody = m_ecs->get<BulletBody>(ent);
// don't bother syncing things with motion states, it's not necessary
if ( physBody.motion != nullptr ) {
continue;
}
if ( physBody->body->isKinematicObject() ) {
auto& transform = m_ecs->get<math::Transform>(ent);
if ( physBody.body->isKinematicObject() ) {
continue;
}
btTransform bTransform;
physBody->motion->getWorldTransform(bTransform);
physBody.motion->getWorldTransform(bTransform);
// set calculate and set ecs position
auto& btPos = bTransform.getOrigin();
math::vec3 pos{btPos.x(), btPos.y(), btPos.z()};
transform->origin( pos );
transform.origin( pos );
// set the rotation
const auto& btRot = bTransform.getRotation();
math::vec3 rot;
btRot.getEulerZYX(rot.x, rot.y, rot.z);
transform->euler(rot);
transform.euler(rot);
}
}
BulletPhysicsEngine::~BulletPhysicsEngine() {
// clean up the rigid bodies
auto entRB = m_ecs->findMatching<BulletBody>();
for (auto& ent : entRB) {
auto* bulletBody = m_ecs->get<BulletBody>(ent);
m_world->removeCollisionObject(bulletBody->body);
auto entRB = m_ecs->find<BulletBody>();
for (const auto& ent : entRB) {
auto& bulletBody = m_ecs->get<BulletBody>(ent);
if ( bulletBody.body != nullptr ) {
m_world->removeCollisionObject(bulletBody.body);
}
// release resources and delete
bulletBody->release();
m_ecs->remove<BulletBody>(ent);
bulletBody.release();
}
// delete the world
......@@ -198,7 +154,7 @@ namespace fggl::phys::bullet {
delete m_config.collisionConfiguration;
}
static void handleCollisionCallbacks(ecs3::World* world, ecs3::entity_t owner, ecs3::entity_t other) {
static void handleCollisionCallbacks(entity::EntityManager* world, entity::EntityID owner, entity::EntityID other) {
if ( !world->has<CollisionCallbacks>(owner) ) {
return;
}
......@@ -222,11 +178,11 @@ namespace fggl::phys::bullet {
void BulletPhysicsEngine::pollCollisions() {
// flush collision caches
auto caches = m_ecs->findMatching<CollisionCache>();
for( auto& ent : caches) {
auto* cache = m_ecs->get<CollisionCache>(ent);
std::swap(cache->collisions, cache->lastFrame);
cache->collisions.clear();
auto caches = m_ecs->find<CollisionCache>();
for( const auto& ent : caches) {
auto& cache = m_ecs->get<CollisionCache>(ent);
std::swap(cache.collisions, cache.lastFrame);
cache.collisions.clear();
}
// deal with the number of manifolds
......@@ -237,15 +193,6 @@ namespace fggl::phys::bullet {
const auto* body0 = contactManifold->getBody0();
const auto* body1 = contactManifold->getBody1();
// FIXME rigid body didn't die according to plan!
if ( body0->getUserIndex() == ecs::NULL_ENTITY || body1->getUserIndex() == ecs::NULL_ENTITY) {
continue;
}
if ( !m_ecs->alive( body0->getUserIndex()) || !m_ecs->alive(body1->getUserIndex()) ) {
continue;
}
int numContacts = contactManifold->getNumContacts();
for ( auto contactIdx = 0; contactIdx < numContacts; ++contactIdx ) {
auto& point = contactManifold->getContactPoint(contactIdx);
......@@ -256,14 +203,14 @@ namespace fggl::phys::bullet {
}
}
handleCollisionCallbacks(m_ecs, body0->getUserIndex(), body1->getUserIndex());
handleCollisionCallbacks(m_ecs, body1->getUserIndex(), body0->getUserIndex());
//handleCollisionCallbacks(m_ecs, body0->getUserIndex(), body1->getUserIndex());
//handleCollisionCallbacks(m_ecs, body1->getUserIndex(), body0->getUserIndex());
}
// note contacts that have ended
caches = m_ecs->findMatching<CollisionCache>(); // re-fetch, entities can (and probably do) die in handlers.
for( auto& ent : caches) {
auto* cache = m_ecs->get<CollisionCache>(ent);
caches = m_ecs->find<CollisionCache>(); // re-fetch, entities can (and probably do) die in handlers.
for( const auto& ent : caches) {
auto& cache = m_ecs->get<CollisionCache>(ent);
// if we don't have an exit callback, it's pointless checking the cache
auto* callbacks = m_ecs->tryGet<CollisionCallbacks>(ent);
......@@ -272,20 +219,20 @@ namespace fggl::phys::bullet {
}
// check if a collision has ended
for (const auto& other : cache->lastFrame) {
auto itr = cache->collisions.find(other);
if (itr == cache->collisions.end()) {
for (const auto& other : cache.lastFrame) {
auto itr = cache.collisions.find(other);
if (itr == cache.collisions.end()) {
callbacks->onExit( ent,other);
}
}
}
}
void BulletPhysicsEngine::onEntityDeath(ecs::entity_t entity) {
void BulletPhysicsEngine::onEntityDeath(entity::EntityID entity) {
auto* btPhysics = m_ecs->tryGet<BulletBody>(entity);
if ( btPhysics != nullptr) {
// decouple physics from entity
btPhysics->body->setUserIndex( ecs::NULL_ENTITY );
//btPhysics->body->setUserIndex( entity::INVALID );
m_world->removeRigidBody( btPhysics->body );
btPhysics->release();
}
......@@ -303,7 +250,7 @@ namespace fggl::phys::bullet {
m_contactCache.removed.push_back(point);
}
ecs3::entity_t BulletPhysicsEngine::raycast(math::vec3 from, math::vec3 to) {
entity::EntityID BulletPhysicsEngine::raycast(math::vec3 from, math::vec3 to) {
const auto btFrom = to_bullet(from);
const auto btTo = to_bullet(to);
......@@ -311,18 +258,19 @@ namespace fggl::phys::bullet {
m_world->rayTest(btFrom, btTo, rayTestResult);
if ( !rayTestResult.hasHit() ) {
return ecs3::NULL_ENTITY;
return entity::INVALID;
}
// tell the user what it hit
return rayTestResult.m_collisionObject->getUserIndex();
return entity::INVALID;
// return rayTestResult.m_collisionObject->getUserIndex();
}
std::vector<ContactPoint> BulletPhysicsEngine::scanCollisions(ecs3::entity_t entity) {
std::vector<ContactPoint> BulletPhysicsEngine::scanCollisions(entity::EntityID entity) {
return std::vector<ContactPoint>();
}
std::vector<ecs3::entity_t> BulletPhysicsEngine::raycastAll(math::vec3 fromPos, math::vec3 toPos) {
std::vector<entity::EntityID> BulletPhysicsEngine::raycastAll(math::vec3 fromPos, math::vec3 toPos) {
const auto btFrom = to_bullet(fromPos);
const auto btTo = to_bullet(toPos);
......@@ -337,21 +285,21 @@ namespace fggl::phys::bullet {
// hit processing
const auto hits = rayTestResult.m_collisionObjects.size();
std::vector<ecs3::entity_t> hitVec;
std::vector<entity::EntityID> hitVec;
hitVec.reserve(hits);
for ( auto i = 0; i < hits; ++i) {
ecs3::entity_t entity = rayTestResult.m_collisionObjects[i]->getUserIndex();
hitVec.push_back(entity);
auto entity = rayTestResult.m_collisionObjects[i]->getUserIndex();
//hitVec.push_back(entity);
}
return hitVec;
}
std::vector<ecs3::entity_t> BulletPhysicsEngine::sweep(PhyShape &shape,
std::vector<entity::EntityID> BulletPhysicsEngine::sweep(PhyShape &shape,
math::Transform &from,
math::Transform &to) {
return std::vector<ecs3::entity_t>();
return std::vector<entity::EntityID>();
}
} // namespace fggl::phys::bullet
\ No newline at end of file
add_library(fggl-lua)
find_package(Lua REQUIRED)
target_link_libraries(fggl-lua PUBLIC ${LUA_LIBRARIES})
target_include_directories(fggl-lua INTERFACE ${LUA_INCLUDE_DIR})
# Link to FGGL
target_link_libraries(fggl-lua PUBLIC fggl)
# sources and include directories
target_sources(fggl-lua
PRIVATE
src/engine.cpp
src/module.cpp
)
target_include_directories(fggl-lua
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
$<INSTALL_INTERFACE:include>
)
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 15/10/22.
//
#ifndef FGGL_INTEGRATIONS_LUA_SCRIPT_LUA_ENGINE_HPP
#define FGGL_INTEGRATIONS_LUA_SCRIPT_LUA_ENGINE_HPP
#include "fggl/script/engine.hpp"
#include "fggl/data/storage.hpp"
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
};
namespace fggl::script::lua {
class LuaScriptEngine : public ScriptEngine {
public:
LuaScriptEngine(data::Storage* storage);
virtual ~LuaScriptEngine();
void onActivate() override;
void onDeactivate() override;
void onUpdate() override;
void onEvent(const std::string& name) override;
// running scripts
bool run(const char* script) override;
bool load(const char* filename) override;
// variables
void setGlobal(const char* name, void* ptr) override;
private:
data::Storage* m_storage;
lua_State* m_state;
void release();
};
class LuaScriptProvider : public ScriptProvider {
public:
LuaScriptProvider(data::Storage* storage);
virtual ~LuaScriptProvider() = default;
LuaScriptEngine* create() override;
private:
data::Storage* m_storage;
};
}
#endif //FGGL_INTEGRATIONS_LUA_SCRIPT_LUA_ENGINE_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 15/10/22.
//
#ifndef FGGL_INTEGRATIONS_LUA_SCRIPT_LUA_MODULE_HPP
#define FGGL_INTEGRATIONS_LUA_SCRIPT_LUA_MODULE_HPP
#define FGGL_HAS_LUA
#include "fggl/modules/module.hpp"
#include "fggl/entity/module.hpp"
#include "fggl/script/engine.hpp"
#include "fggl/data/module.hpp"
#include "fggl/assets/packed/adapter.hpp"
namespace fggl::script::lua {
constexpr auto MIME_LUA = assets::from_mime("text/lua");
constexpr auto SCRIPT_LUA = assets::make_asset_type("script/lua");
struct Lua {
constexpr static const char* name = "fggl::script::lua";
constexpr static const std::array<modules::ServiceName, 1> provides = {
script::ScriptProvider::service
};
constexpr static const std::array<modules::ServiceName, 2> depends = {
data::SERVICE_STORAGE,
assets::CheckinAdapted::service
};
static bool factory(modules::ServiceName name, modules::Services& serviceManager);
};
} // namespace fggl::script::lua
namespace fggl::script {
using Lua = lua::Lua;
} // namespace fggl::script
#endif //FGGL_INTEGRATIONS_LUA_SCRIPT_LUA_MODULE_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 15/10/22.
//
#include "fggl/script/lua/engine.hpp"
#include "fggl/debug/logging.hpp"
#include "fggl/scenes/game.hpp"
#include "fggl/entity/loader/loader.hpp"
#include <cassert>
extern "C" {
int lua_switch_scene(lua_State *L) {
auto *scene = lua_tostring(L, -1);
auto *statePtr = (fggl::AppState *) (lua_topointer(L, -2));
statePtr->owner().change_state(scene);
return 0;
}
int lua_create_entity(lua_State *L) {
/*auto *prototype = lua_tostring(L, -1);
auto *statePtr = (fggl::scenes::Game*) (lua_topointer(L, -2));
auto *factory = statePtr->owner().service<fggl::entity::EntityFactory>();
//factory->create( statePtr->world(), , [](){} );
*/
return 0;
}
static void open_lua_fggl(lua_State *L) {
// switch scene
lua_pushcfunction(L, lua_switch_scene);
lua_setglobal(L, "switch_scene");
}
}
namespace fggl::script::lua {
LuaScriptProvider::LuaScriptProvider(data::Storage *storage) : m_storage(storage) {
}
LuaScriptEngine *LuaScriptProvider::create() {
return new LuaScriptEngine(m_storage);
}
LuaScriptEngine::LuaScriptEngine(data::Storage* storage) : m_state(luaL_newstate()), m_storage(storage) {
luaL_openlibs(m_state);
open_lua_fggl(m_state);
}
LuaScriptEngine::~LuaScriptEngine() {
release();
}
void LuaScriptEngine::release() {
if ( m_state != nullptr ) {
lua_close(m_state);
m_state = nullptr;
}
}
void LuaScriptEngine::onActivate() {
lua_getglobal(m_state, "print");
lua_pushstring(m_state, "LUA activate triggered");
lua_call(m_state, 1, 0);
}
void LuaScriptEngine::onDeactivate() {
lua_getglobal(m_state, "print");
lua_pushstring(m_state, "LUA deactivate triggered");
lua_call(m_state, 1, 0);
}
void LuaScriptEngine::onUpdate() {
lua_getglobal(m_state, "print");
lua_pushstring(m_state, "LUA update triggered");
lua_call(m_state, 1, 0);
}
void LuaScriptEngine::onEvent(const std::string &name) {
lua_getglobal(m_state, "print");
lua_pushstring(m_state, "LUA event triggered");
lua_call(m_state, 1, 0);
}
bool LuaScriptEngine::run(const char *script) {
auto result = luaL_dostring(m_state, script);
if ( !result ) {
fggl::debug::warning("lua error: {}", lua_tostring(m_state, -1));
}
return result;
}
bool LuaScriptEngine::load(const char *filename) {
assert( filename != nullptr);
auto path = m_storage->resolvePath(data::StorageType::Data, filename);
if ( !std::filesystem::exists(path) ) {
fggl::debug::warning("lua error: file does not exist: {}", path.c_str());
return false;
}
// load the file ( OK = 0 = false because reasons...)
auto result = !luaL_dofile(m_state, path.c_str());
if ( !result ) {
fggl::debug::warning("lua error: {}", lua_tostring(m_state, -1));
return false;
}
return true;
}
void LuaScriptEngine::setGlobal(const char *name, void *ptr) {
lua_pushlightuserdata(m_state, ptr);
lua_setglobal(m_state, name);
}
}
\ No newline at end of file
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 15/10/22.
//
#include "fggl/script/lua/module.hpp"
#include "fggl/script/lua/engine.hpp"
namespace fggl::script::lua {
static assets::AssetTypeID is_lua(std::filesystem::path path) {
if ( path.extension() == ".lua" ) {
return SCRIPT_LUA;
}
return assets::INVALID_ASSET_TYPE;
}
bool Lua::factory(modules::ServiceName service, modules::Services &serviceManager) {
if ( service == ScriptProvider::service ) {
auto *storageService = serviceManager.get<data::Storage>();
serviceManager.bind<ScriptProvider,LuaScriptProvider>(storageService);
auto *assetPacker = serviceManager.get<assets::CheckinAdapted>();
assetPacker->setLoader(MIME_LUA, assets::NEEDS_CHECKIN, is_lua);
return true;
}
return false;
}
}
\ No newline at end of file
find_package(Threads REQUIRED)
# GTest Dependency
find_package(GTest)
find_package( GTest REQUIRED )
if ( NOT GTest_FOUND )
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/refs/tags/release-1.11.0.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
message(NOTICE "GTest not found, installing...")
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/refs/tags/release-1.11.0.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
endif ()
add_subdirectory(testfggl)
enable_testing()
add_executable( fggl_test
# TestFggl.cpp
ecs/ecs.cpp
ecs3/ecs.cpp
math/types.cpp
ecs3/easing.cpp
# TestFggl.cpp
# ecs/ecs.cpp
# ecs3/ecs.cpp
# ecs3/easing.cpp
# math/types.cpp
util/guid.cpp
util/safety.cpp
)
target_include_directories(fggl_test
PUBLIC
......@@ -14,14 +16,10 @@ target_include_directories(fggl_test
target_link_libraries(fggl_test
fggl
gtest
gtest_main
gmock
)
include(GoogleTest)
gtest_discover_tests(fggl_test)
add_test(
NAME gtest
COMMAND $<TARGET_FILE:fggl_test>
)
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 23/07/22.
//
#include <gtest/gtest.h>
#include "fggl/util/guid.hpp"
namespace {
// expect blank (0-width) strings to be the offset basis
TEST(UtilHash32, Empty) {
auto value = fggl::util::hash_fnv1a_32("");
EXPECT_EQ( fggl::util::FNV_OFFSET_BASIS_32, value );
}
TEST(UtilHash64, Empty) {
auto value = fggl::util::hash_fnv1a_64("");
EXPECT_EQ( fggl::util::FNV_OFFSET_BASIS_64, value );
}
// expect single characters to work correctly
TEST(UtilHash32, SingleChar) {
auto value = fggl::util::hash_fnv1a_32("a");
EXPECT_EQ( 0xe40c292c, value );
}
TEST(UtilHash64, SingleChar) {
auto value = fggl::util::hash_fnv1a_64("a");
EXPECT_EQ( 0xaf63dc4c8601ec8c, value );
}
// expect hello world to known values
TEST(UtilHash32, HelloWorld) {
auto value = fggl::util::hash_fnv1a_32("Hello World");
EXPECT_EQ( 0xb3902527, value );
}
TEST(UtilHash64, HelloWorld) {
auto value = fggl::util::hash_fnv1a_64("Hello World");
EXPECT_EQ( 0x3d58dee72d4e0c27, value );
}
// expect scoped (::) notation to work correctly
TEST(UtilHash32, Scoped) {
auto value = fggl::util::hash_fnv1a_32("fggl::test::scoped");
EXPECT_EQ( 0x27fd4589, value );
}
TEST(UtilHash64, Scoped) {
auto value = fggl::util::hash_fnv1a_64("fggl::test::scoped");
EXPECT_EQ( 0xd2929655f3b0cf49, value );
}
// sanity checks
TEST(UtilHash32, RepeatsAreEqual) {
auto value = fggl::util::hash_fnv1a_32("fggl::test::scoped");
auto value2 = fggl::util::hash_fnv1a_32("fggl::test::scoped");
EXPECT_EQ( value, value2 );
EXPECT_EQ( false, value < value2);
EXPECT_EQ( false, value2 < value);
}
TEST(UtilHash64, RepeatsAreEqual) {
auto value = fggl::util::hash_fnv1a_64("fggl::test::scoped");
auto value2 = fggl::util::hash_fnv1a_64("fggl::test::scoped");
EXPECT_EQ( value, value2 );
EXPECT_EQ( false, value < value2);
EXPECT_EQ( false, value2 < value);
}
// GUID tests
TEST(GuidTest, GuidSuffix) {
auto guid = fggl::util::make_guid("test");
auto guidSuffix = "test"_fid;
EXPECT_EQ(guid, guidSuffix);
EXPECT_EQ( false, guid < guidSuffix);
EXPECT_EQ( false, guidSuffix < guid);
}
TEST(GuidTest, OrderingLE) {
auto guid1 = fggl::util::GUID::make(0);
auto guid2 = fggl::util::GUID::make(1);
EXPECT_NE(guid1, guid2);
EXPECT_EQ( true, guid1 < guid2);
EXPECT_EQ( false, guid2 < guid1);
}
TEST(GuidTest, OrderingGE) {
auto guid1 = fggl::util::GUID::make(15);
auto guid2 = fggl::util::GUID::make(36);
EXPECT_NE(guid1, guid2);
EXPECT_EQ( true, guid1 < guid2);
EXPECT_EQ( false, guid2 < guid1);
}
#ifdef DEBUG
TEST(GuidTest, GuidToString) {
fggl::util::GUID guid = fggl::util::internString("test");
EXPECT_EQ("test", fggl::util::guidToString(guid));
}
#endif
}
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 23/07/22.
//
#include <gtest/gtest.h>
#include "fggl/util/safety.hpp"
namespace {
using TestType = fggl::util::OpaqueName<unsigned int, struct TestTag>;
TEST(SafetyHandle, CheckZero) {
auto v1 = TestType::make(0);
auto v2 = TestType::make(0);
EXPECT_EQ(v1, v2);
}
TEST(SafetyHandle, CheckValue) {
auto v1 = TestType::make(0x12345678);
auto v2 = TestType::make(0x12345678);
EXPECT_EQ(v1, v2);
}
TEST(SafetyHandle, CheckValueNE) {
auto v1 = TestType::make(0x12345678);
auto v2 = TestType::make(0x87654321);
EXPECT_NE(v1, v2);
}
}
\ No newline at end of file
add_executable(fgpak)
target_link_libraries(fgpak fggl)
target_sources(fgpak
PRIVATE
src/main.cpp
)
\ No newline at end of file
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 11/09/22.
//
#ifndef FGGL_TOOLS_PACK_SRC_BINARY_HPP
#define FGGL_TOOLS_PACK_SRC_BINARY_HPP
#include <cstdint>
#include <iostream>
#include <cstdio>
#include "fggl/data/model.hpp"
namespace fggl::data {
enum class ModelType {
OPENGL
};
struct ModelHeader {
unsigned long guid;
std::size_t size;
ModelType type;
};
void write_mesh(FILE* file, const Mesh& mesh) {
static_assert( std::is_standard_layout_v<Vertex> );
static_assert( std::is_standard_layout_v<Mesh::IndexType> );
// write vertex data
std::size_t vertexCount = mesh.vertexCount();
fwrite( &vertexCount, sizeof(vertexCount), 1, file );
fwrite( mesh.vertexList().data(), sizeof(Vertex), vertexCount, file );
std::size_t indexCount = mesh.indexCount();
fwrite( &indexCount, sizeof(indexCount), 1, file);
fwrite( mesh.indexList().data(), sizeof(Mesh::IndexType), indexCount, file);
}
void write_model(FILE* file, const ModelHeader& header, const Mesh& mesh) {
assert( header.type == ModelType::OPENGL );
fwrite( &header , sizeof(ModelHeader), 1, file);
write_mesh(file, mesh);
}
void read_mesh(FILE* fin, data::Mesh& mesh) {
static_assert( std::is_standard_layout_v<Vertex> );
static_assert( std::is_standard_layout_v<Mesh::IndexType> );
std::size_t readCount;
// vertex data
std::size_t vertexCount = 0;
readCount = fread( &vertexCount, sizeof(vertexCount), 1, fin );
assert(ferror(fin) == 0);
if (readCount != 1) {
std::cerr << "failed to read vertex count" << std::endl;
return;
}
// push vertex data into mesh
auto* vertexData = new data::Vertex[vertexCount];
readCount = fread( vertexData, sizeof(Vertex), vertexCount, fin );
assert(ferror(fin) == 0);
if ( readCount != vertexCount ) {
std::cerr << "failed to read vertex data" << std::endl;
return;
}
for ( std::size_t i = 0; i < vertexCount; ++i) {
mesh.pushVertex(vertexData[i]);
}
delete[] vertexData;
// read index size
std::size_t indexCount = 0;
readCount = fread( &indexCount, sizeof(indexCount), 1, fin);
assert(ferror(fin) == 0);
if (readCount != 1 ) {
std::cerr << "failed to read index count" << std::endl;
return;
}
// read index data
auto* idxData = new Mesh::IndexType[indexCount];
readCount = fread( idxData, sizeof(Mesh::IndexType), indexCount, fin);
assert(ferror(fin) == 0);
if (readCount != indexCount) {
std::cerr << "failed to read index data, expected: " << indexCount << ", got: " << readCount << std::endl;
return;
}
for (int i=0; i < indexCount; ++i) {
mesh.pushIndex( idxData[i] );
}
delete[] idxData;
}
void read_model(FILE* file, ModelHeader& header, Mesh& mesh) {
fread( &header, sizeof(ModelHeader), 1, file);
if ( header.type == ModelType::OPENGL ) {
read_mesh(file, mesh);
}
}
}
#endif //FGGL_TOOLS_PACK_SRC_BINARY_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 11/09/22.
//
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <filesystem>
#include <map>
#include <yaml-cpp/yaml.h>
#include "fggl/data/model.hpp"
#include "fggl/data/procedural.hpp"
#include "fggl/entity/loader/loader.hpp"
#include "binary.hpp"
constexpr const char* YAML_PREFAB = "prefabs";
constexpr const char* YAML_COMPONENT = "components";
constexpr uint32_t DEFAULT_STACKS = 16;
constexpr uint32_t DEFAULT_SLICES = 16;
constexpr const char *SHAPE_SPHERE{"sphere"};
constexpr const char *SHAPE_BOX{"box"};
namespace fggl {
static void process_shape(const YAML::Node &node, data::Mesh &mesh) {
auto transform = data::OFFSET_NONE;
auto offset = node["offset"].as<math::vec3>(math::VEC3_ZERO);
transform = glm::translate(transform, offset);
auto scale = node["scale"].as<math::vec3>(math::VEC3_ONES);
transform = glm::scale(transform, scale);
debug::debug("scale: {}, {}, {}", scale.x, scale.y, scale.z);
// now the shape itself
auto type = node["type"].as<std::string>();
if (type == SHAPE_BOX) {
data::make_cube(mesh, transform);
} else if (type == SHAPE_SPHERE) {
auto stacks = node["stacks"].as<uint32_t>(DEFAULT_STACKS);
auto slices = node["slices"].as<uint32_t>(DEFAULT_SLICES);
data::make_sphere(mesh, transform, stacks, slices);
} else {
debug::log(debug::Level::warning, "unknown shape type requested: {}", type);
}
}
static void process_mesh(const YAML::Node& spec, fggl::data::Mesh& mesh) {
// process shape structure
if (spec["shape"].IsSequence()) {
for (const auto &node : spec["shape"]) {
process_shape(node, mesh);
}
} else {
process_shape(spec["shape"], mesh);
}
mesh.removeDups();
}
}
void write_comp_static_model(FILE* fout, const YAML::Node& config) {
// calculate mesh
fggl::data::Mesh mesh;
fggl::process_mesh( config, mesh);
// calculate correct name
auto meshName = config["shape_id"];
auto meshNameStr = meshName.as<std::string>();
auto meshGuid = fggl::util::make_guid_rt(meshNameStr);
// header data
fggl::data::ModelHeader header{
.guid = meshGuid.get(),
.type = fggl::data::ModelType::OPENGL,
};
// write the mesh to disk
fggl::data::write_model( fout, header, mesh );
}
int main(int argc, char* argv[]) {
auto* packName = argv[1];
std::cout << "generating " << packName << std::endl;
std::map< fggl::util::GUID, std::string > guids;
// rollball
auto rollPath = std::filesystem::current_path() / "rollball.yml";
std::cout << rollPath << std::endl;
YAML::Node root = YAML::LoadFile(rollPath);
if ( !root ){
return EXIT_FAILURE;
}
//std::cout << root[ YAML_PREFAB ] << std::endl;
std::map<std::string, std::function<void(FILE* fout, const YAML::Node&)>> converters;
converters["StaticMesh"] = write_comp_static_model;
std::string meshFile = "rollball_models.bin";
FILE* fout = fopen(meshFile.c_str(), "w");
// pack prefabs
for (const auto& prefab : root[YAML_PREFAB]) {
// name
auto name = prefab["name"].as<std::string>();
auto nameRef = fggl::util::make_guid(name.c_str());
guids[nameRef] = name;
std::cout << name << std::endl;
// parent
//auto parentName = prefab["parent"].as<std::string>();
//auto parentGuid = fggl::util::make_guid(parentName.c_str());
// components
for( const auto& key : prefab[YAML_COMPONENT] ) {
auto compStr = key.first.as<std::string>();
auto compGuid = fggl::util::make_guid_rt(compStr);
guids[compGuid] = compStr;
// figure out the type
auto compWrite = converters.find(compStr);
if ( compWrite != converters.end()) {
compWrite->second(fout, key.second);
}
}
}
fclose(fout);
// guid table
std::cerr << "GUID Table" << std::endl;
std::cerr << "guid,str" << std::endl;
for (auto& [guid,str] : guids) {
std::cerr << guid.get() << "," << str << std::endl;
}
return EXIT_SUCCESS;
}
\ No newline at end of file
# Vendor Libraries
This folder contains 3rd party code we need to ship with our build.
Compile-time only dependencies, or dependencies which can be included using cmake directly will not be included within this folder.
| Library | Purpose | Licence |
|------------|--------------------------------------------------|---------|
| GLAD | Allow loading of OpenGL libraries and extentions | MIT |
| Dear IMGUI | Debugging UI/Editor windows | MIT |
\ No newline at end of file
add_library( entt INTERFACE )
target_include_directories( entt
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
$<INSTALL_INTERFACE:include>
)
install(
FILES
include/fggl/vendor/entt.hpp
DESTINATION
${CMAKE_INSTALL_INCLUDEDIR}/fggl/vendor/entt.hpp
)
install(TARGETS entt
EXPORT fgglTargets
DESTINATION
${CMAKE_INSTALL_LIBDIR}/fggl/entt
)
source diff could not be displayed: it is too large. Options to address this: view the blob.
add_library(fggl-glad)
target_include_directories( fggl-glad
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/debug/include>
$<INSTALL_INTERFACE:include/fggl>
)
target_compile_options( fggl-glad PRIVATE -Wall -Wno-pedantic -Wodr -fno-strict-aliasing -fno-strict-overflow )
target_sources( fggl-glad
PRIVATE
debug/glad.c
)
# FIXME should be a cleaner way to do this...
install(
FILES
debug/include/glad/glad.h
DESTINATION
${CMAKE_INSTALL_INCLUDEDIR}/fggl/glad
)
install(
FILES
public/KHR/khrplatform.h
DESTINATION
${CMAKE_INSTALL_INCLUDEDIR}/fggl/KHR
)
install(TARGETS fggl-glad
EXPORT fgglTargets
DESTINATION
${CMAKE_INSTALL_LIBDIR}/fggl/glad
)
\ No newline at end of file