engine/ext/scenes/map/scene.cpp
2020-09-27 00:00:00 -05:00

101 lines
3.3 KiB
C++

#include "scene.h"
#include <uf/utils/time/time.h>
#include <uf/utils/io/iostream.h>
#include <uf/utils/math/vector.h>
#include <uf/utils/math/transform.h>
#include <uf/utils/window/window.h>
#include <uf/utils/audio/audio.h>
#include <uf/utils/thread/thread.h>
#include <uf/utils/camera/camera.h>
#include <uf/engine/asset/asset.h>
#include <uf/engine/asset/masterdata.h>
#include <uf/utils/renderer/renderer.h>
#include <uf/ext/gltf/gltf.h>
#include <uf/utils/math/collision.h>
#include "../../ext.h"
#include "../../gui/gui.h"
#include "behavior_test.h"
EXT_OBJECT_REGISTER_CPP(TestScene_Map)
void ext::TestScene_Map::initialize() {
ext::Scene::initialize();
{
uf::Object* object = new uf::Object;
this->addChild(*object);
ext::TestBehavior::attach( *object );
object->initialize();
}
}
void ext::TestScene_Map::render() {
ext::Scene::render();
}
void ext::TestScene_Map::tick() {
ext::Scene::tick();
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
uf::Asset& assetLoader = this->getComponent<uf::Asset>();
/* Collision */ {
bool local = false;
bool sort = false;
bool useStrongest = false;
// pod::Thread& thread = uf::thread::fetchWorker();
pod::Thread& thread = uf::thread::has("Physics") ? uf::thread::get("Physics") : uf::thread::create( "Physics", true, false );
auto function = [&]() -> int {
std::vector<uf::Object*> entities;
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
auto& metadata = entity->getComponent<uf::Serializer>();
if ( !metadata["system"]["physics"]["collision"].isNull() && !metadata["system"]["physics"]["collision"].asBool() ) return;
if ( entity->hasComponent<uf::Collider>() )
entities.push_back((uf::Object*) entity);
};
this->process(filter);
auto onCollision = []( pod::Collider::Manifold& manifold, uf::Object* a, uf::Object* b ){
uf::Serializer payload;
payload["normal"][0] = manifold.normal.x;
payload["normal"][1] = manifold.normal.y;
payload["normal"][2] = manifold.normal.z;
payload["entity"] = b->getUid();
payload["depth"] = -manifold.depth;
a->callHook("world:Collision.%UID%", payload);
payload["entity"] = a->getUid();
payload["depth"] = manifold.depth;
b->callHook("world:Collision.%UID%", payload);
};
auto testColliders = [&]( uf::Collider& colliderA, uf::Collider& colliderB, uf::Object* a, uf::Object* b, bool useStrongest ){
pod::Collider::Manifold strongest;
auto manifolds = colliderA.intersects(colliderB);
for ( auto manifold : manifolds ) {
if ( manifold.colliding && manifold.depth > 0 ) {
if ( !useStrongest ) onCollision(manifold, a, b);
else if ( strongest.depth < manifold.depth ) strongest = manifold;
}
}
if ( useStrongest && strongest.colliding ) onCollision(strongest, a, b);
};
// collide with others
for ( auto* _a : entities ) {
uf::Object& entityA = *_a;
for ( auto* _b : entities ) { if ( _a == _b ) continue;
uf::Object& entityB = *_b;
testColliders( entityA.getComponent<uf::Collider>(), entityB.getComponent<uf::Collider>(), &entityA, &entityB, useStrongest );
}
}
return 0;
};
if ( local ) function(); else uf::thread::add( thread, function, true );
}
}