Demos big update

-Added some more math functions
-fixed many memory leaks
-added AABB and BVHTree support to collision.d
 *BVHTree has only incrementally adding entities implemented by now (and bad BottomUp algorithm)
 *ECS Systems use two trees, one for static and one for dynamic entities, dynamic BVH is builded every frame from scratch by now
-BrickBreaker now uses BVHTree to collision detection
 *balls only use tree for checks (they aren't adding to tree)
-fixed bug leading to crash
This commit is contained in:
Mergul 2020-07-17 13:38:41 +02:00
parent 96bbcb9956
commit 64dc099e0a
9 changed files with 973 additions and 70 deletions

View file

@ -54,6 +54,15 @@ struct CBall
ubyte radius;
}
struct CHitPoints
{
mixin ECS.Component;
alias value this;
short value;
}
// struct CVelocityFactor
// {
// mixin ECS.Component;
@ -72,6 +81,13 @@ struct CBall
// vec2 value = vec2(0);
// }
struct EDamage
{
mixin ECS.Event;
ubyte damage = 1;
}
/*#######################################################################################################################
------------------------------------------------ Systems ------------------------------------------------------------------
#######################################################################################################################*/
@ -152,7 +168,7 @@ struct BallCollisionSystem
{
mixin ECS.System!64;
mixin ECS.ReadOnlyDependencies!(ShootGridDependency);
mixin ECS.ReadOnlyDependencies!(ShootGridDependency, BVHDependency);
struct EntitiesData
{
@ -165,72 +181,136 @@ struct BallCollisionSystem
@readonly CBall[] ball_flag;
}
struct State
{
bool test(EntityID id)
{
Entity* entity = launcher.manager.getEntity(id);
if(entity)
{
CLocation* location = entity.getComponent!CLocation;
CScale* scale = entity.getComponent!CScale;
if(location && scale)
{
float radius = data.scale[i].x;
vec2 rel_pos = *location - data.location[i];
vec2 abs_rel_pos = rel_pos;
if(abs_rel_pos.x < 0)abs_rel_pos.x = -abs_rel_pos.x;
if(abs_rel_pos.y < 0)abs_rel_pos.y = -abs_rel_pos.y;
vec2 half_scale = *scale * 0.25f;
if(abs_rel_pos.x < half_scale.x + radius &&
abs_rel_pos.y < half_scale.y + radius)
{
if(abs_rel_pos.x < half_scale.x)
{
if(rel_pos.y * data.velocity[i].y > 0)
{
data.velocity[i].y = -data.velocity[i].y;
launcher.manager.sendEvent(id,EDamage(1));
return false;
}
}
else if(abs_rel_pos.y < half_scale.y)
{
if(rel_pos.x * data.velocity[i].x > 0)
{
data.velocity[i].x = -data.velocity[i].x;
launcher.manager.sendEvent(id,EDamage(1));
return false;
}
}
else
{
vec2 vector = abs_rel_pos - half_scale;
if(rel_pos.x > 0)vector.x = -vector.x;
if(rel_pos.y > 0)vector.y = -vector.y;
float pow_dist = vector.length2();
if(pow_dist < radius*radius)
{
vector = vector / sqrtf(pow_dist);
data.velocity[i] = data.velocity[i] - vector * (2 * dot(vector, data.velocity[i]));
launcher.manager.sendEvent(id,EDamage(1));
return false;
}
}
}
}
}
return true;
}
EntitiesData data;
uint i;
}
ShootGrid* grid;
BVHTree* tree;
BVHTree* static_tree;
bool onBegin()
{
grid = launcher.manager.getSystem!ShootGridManager().grid;
if(grid is null)return false;
//grid = launcher.manager.getSystem!ShootGridManager().grid;
tree = launcher.manager.getSystem!BVHBuilder().tree;
static_tree = launcher.manager.getSystem!StaticBVHBuilder().tree;
//if(grid is null)return false;
if(tree is null || static_tree is null)return false;
else return true;
}
void onUpdate(EntitiesData data)
{
EntityID id;
// State state;
// state.data = data;
// EntityID id;
// foreach(i; 0..data.length)
// {
// state.i = i;
// float radius = data.scale[i].x;
// if(grid.test(id, data.location[i] - radius, data.location[i] + radius, ubyte.max))
// {
// state.test(id);
// }
// }
State state;
state.data = data;
foreach(i; 0..data.length)
{
float radius = data.scale[i].x;
//if(grid.test(id, data.location[i], ubyte.max))
if(grid.test(id, data.location[i] - radius, data.location[i] + radius, ubyte.max))
{
Entity* entity = launcher.manager.getEntity(id);
if(entity)
{
CLocation* location = entity.getComponent!CLocation;
CScale* scale = entity.getComponent!CScale;
if(location && scale)
{
vec2 rel_pos = *location - data.location[i];
vec2 abs_rel_pos = rel_pos;
if(abs_rel_pos.x < 0)abs_rel_pos.x = -abs_rel_pos.x;
if(abs_rel_pos.y < 0)abs_rel_pos.y = -abs_rel_pos.y;
vec2 half_scale = *scale * 0.25f;
if(abs_rel_pos.x < half_scale.x + radius &&
abs_rel_pos.y < half_scale.y + radius)
{
if(abs_rel_pos.x < half_scale.x)
{
if(rel_pos.y * data.velocity[i].y > 0)data.velocity[i].y = -data.velocity[i].y;
}
else if(abs_rel_pos.y < half_scale.y)
{
if(rel_pos.x * data.velocity[i].x > 0)data.velocity[i].x = -data.velocity[i].x;
}
else
{
vec2 vector = abs_rel_pos - half_scale;
if(rel_pos.x > 0)vector.x = -vector.x;
if(rel_pos.y > 0)vector.y = -vector.y;
float pow_dist = vector.length2();
if(pow_dist < radius*radius)
{
vector = vector / sqrtf(pow_dist);
data.velocity[i] = data.velocity[i] - vector * (2 * dot(vector, data.velocity[i]));
}
}
}
}
}
//launcher.manager.sendEvent(id, EBulletHit(data.entity[i].id,data.bullet[i].damage));
//launcher.manager.removeEntity(data.entity[i].id);
}
state.i = i;
//float radius = data.scale[i].x;
AABB bounding = AABB(data.location[i]-data.scale[i], data.location[i]+data.scale[i]);
tree.test(bounding, cast(bool delegate(EntityID id))&state.test);
static_tree.test(bounding, cast(bool delegate(EntityID id))&state.test);
}
}
}
struct DamageSystem
{
mixin ECS.System!64;
mixin ECS.ReadOnlyDependencies!(ShootGridDependency);
struct EntitiesData
{
///variable named "length" contain entites count
uint length;
const (Entity)[] entity;
CHitPoints[] hit_points;
}
void handleEvent(Entity* entity, EDamage event)
{
EntityMeta meta = entity.getMeta();
CHitPoints* hp = meta.getComponent!CHitPoints;
hp.value -= event.damage;
if(hp.value < 0)launcher.manager.removeEntity(entity.id);
}
}
/*#######################################################################################################################
------------------------------------------------ Functions ------------------------------------------------------------------
#######################################################################################################################*/
@ -239,7 +319,7 @@ struct BrickBreakerDemo
{
__gshared const (char)* tips = "Brick breaker demo. It's a game about destroying evil bricks.";
EntityTemplate* tmpl;
//EntityTemplate* tmpl;
Texture texture;
}
@ -268,12 +348,16 @@ void brickBreakerRegister()
launcher.manager.registerComponent!CDamping;
launcher.manager.registerComponent!CVelocityFactor;
launcher.manager.registerComponent!CBall;
launcher.manager.registerComponent!CHitPoints;
launcher.manager.registerEvent!EDamage;
launcher.manager.registerSystem!MoveSystem(-100);
launcher.manager.registerSystem!EdgeCollisionSystem(-99);
launcher.manager.registerSystem!BallCollisionSystem(-79);
launcher.manager.registerSystem!InputMovementSystem(-120);
launcher.manager.registerSystem!DampingSystem(-120);
launcher.manager.registerSystem!DamageSystem(-120);
launcher.manager.endRegister();
}
@ -289,11 +373,14 @@ void brickBreakerStart()
EntityTemplate* brick_tmpl = launcher.manager.allocateTemplate(
[CLocation.component_id, CScale.component_id, CColor.component_id,
CTexCoordsIndex.component_id, CShootGrid.component_id].staticArray
CTexCoordsIndex.component_id, CBVH.component_id, CHitPoints.component_id,
CAABB.component_id, CStatic.component_id].staticArray
);
brick_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(304,40,16,8)*px);
brick_tmpl.getComponent!CColor().value = 0x80206020;
brick_tmpl.getComponent!CScale().value = vec2(16,8);
brick_tmpl.getComponent!CHitPoints().value = 2;
//brick_tmpl.getComponent!CAABB().bounding = AABB(vec2(),vec2());
EntityTemplate* big_brick_tmpl = launcher.manager.allocateTemplate(brick_tmpl);
big_brick_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(320,32,16,16)*px);
@ -302,7 +389,8 @@ void brickBreakerStart()
EntityTemplate* paddle_tmpl = launcher.manager.allocateTemplate(
[CLocation.component_id, CScale.component_id, CInput.component_id,
CTexCoordsIndex.component_id, CPaddle.component_id, CVelocity.component_id,
CDamping.component_id, CVelocityFactor.component_id, CShootGrid.component_id].staticArray
CDamping.component_id, CVelocityFactor.component_id, CBVH.component_id,
CAABB.component_id].staticArray
);
paddle_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(272,48,64,10)*px);
paddle_tmpl.getComponent!CScale().value = vec2(64,10);
@ -330,7 +418,11 @@ void brickBreakerStart()
launcher.gui_manager.addComponent(CBall(), "Ball");
launcher.gui_manager.addSystem(MoveSystem.system_id, "Move System");
launcher.gui_manager.addSystem(EdgeCollisionSystem.system_id, "Edge Collision System");
launcher.gui_manager.addSystem(BallCollisionSystem.system_id, "Ball Collision System");
launcher.gui_manager.addSystem(InputMovementSystem.system_id, "Input Movement System");
launcher.gui_manager.addSystem(DampingSystem.system_id, "Damping System");
launcher.gui_manager.addSystem(DamageSystem.system_id, "Damage System");
launcher.gui_manager.addTemplate(brick_tmpl, "Brick");
launcher.gui_manager.addTemplate(big_brick_tmpl, "Big Brick");

View file

@ -72,7 +72,7 @@ struct Snake
bool move_system = true;
bool draw_system = true;
const int map_size = 18;
enum int map_size = 18;
MapElement[map_size * map_size] map;
@ -83,7 +83,7 @@ struct Snake
if(apple_tmpl)launcher.manager.freeTemplate(apple_tmpl);
if(snake_tmpl)launcher.manager.freeTemplate(snake_tmpl);
if(snake_destroy_particle)launcher.manager.freeTemplate(snake_destroy_particle);
texture.destory();
texture.destroy();
}
MapElement element(ivec2 pos)

View file

@ -64,7 +64,7 @@ struct SpaceInvaders
{
if(tmpl)launcher.manager.freeTemplate(tmpl);
}
texture.destory();
texture.destroy();
}
}
@ -90,7 +90,7 @@ struct SceneGrid
cells = Mallocator.makeArray!Cell(cells_count.x * cells_count.y);
}
void destory()
void destroy()
{
if(cells)
{
@ -707,6 +707,7 @@ struct ShipWeaponSystem
void onDestroy()
{
__xdtor();
/*launcher.manager.freeTemplate(laser1_tmpl);
launcher.manager.freeTemplate(laser2_tmpl);
launcher.manager.freeTemplate(main_weapon_tmpl);*/