@ -20,6 +20,7 @@
# include <renderer/frame_buffer.h>
# include <renderer/frame_buffer.h>
# include <renderer/orthographic_camera.h>
# include <renderer/orthographic_camera.h>
# include <renderer/texture.h>
# include <renderer/texture.h>
# include <box2d/box2d.h>
# include "entity.h"
# include "entity.h"
//#define LOAD_ASSETS_FROM_EDITOR true
//#define LOAD_ASSETS_FROM_EDITOR true
@ -38,19 +39,113 @@ namespace lunarium
// }
// }
World : : World ( std : : string name )
World : : World ( std : : string name )
: mUUID ( UUID : : GetNewID ( ) ) , mName ( name ) , mpActiveCamera ( nullptr ) , mFrameBuffer ( nullptr )
: mUUID ( UUID : : GetNewID ( ) ) , mName ( name ) , mpActiveCamera ( nullptr ) , mFrameBuffer ( nullptr ) , mpPhysicsWorld ( nullptr ) , mDrawDebugObjects ( false )
//mGetAssetsFromEditor(EDITOR_MODE)
//mGetAssetsFromEditor(EDITOR_MODE)
{
{
WorldSettings . Physics . PhysicsScaleFactor = 16.0f ;
}
}
std : : string World : : GetName ( ) const
{
return mName ;
}
void World : : OnLoad ( )
void World : : SetName ( std : : string name )
{
mName = name ;
}
glm : : vec2 World : : GetGravity ( ) const
{
return { WorldSettings . Physics . Gravity . x , WorldSettings . Physics . Gravity . y } ;
}
void World : : SetGravity ( glm : : vec2 gravity )
{
{
WorldSettings . Physics . Gravity . x = gravity . x ;
WorldSettings . Physics . Gravity . y = gravity . y ;
}
float World : : GetPhysicsScaleFactor ( ) const
{
return WorldSettings . Physics . PhysicsScaleFactor ;
}
void World : : SetPhysicsScaleFactor ( float factor )
{
WorldSettings . Physics . PhysicsScaleFactor = factor ;
}
void World : : OnLoad ( )
{
// INITIALIZE SCRIPTS
WorldAPI : : Initialize ( this ) . LogIfFailed ( LogCategory : : GAME_SYSTEM , " Failed to initialized the world scripting api " ) ;
WorldAPI : : Initialize ( this ) . LogIfFailed ( LogCategory : : GAME_SYSTEM , " Failed to initialized the world scripting api " ) ;
// Initialize Physics
mpPhysicsWorld = new b2World ( { WorldSettings . Physics . Gravity . x , WorldSettings . Physics . Gravity . y } ) ;
// Iterate all entities with physics components and initialize them
// Only checking for RigidBody because any physics object needs at least that
auto group_phys = mECSRegistry . view < RigidBodyComponent , TransformComponent > ( ) ;
for ( auto entity : group_phys )
{
auto & transform = group_phys . get < TransformComponent > ( entity ) ;
auto & rigid_body = group_phys . get < RigidBodyComponent > ( entity ) ;
float scale_factor = WorldSettings . Physics . PhysicsScaleFactor ;
rigid_body . Defintion . position . Set ( transform . Position . x / scale_factor , transform . Position . y / scale_factor ) ;
rigid_body . Defintion . angle = transform . Rotation . z ;
if ( ! rigid_body . IsStatic )
{
rigid_body . Defintion . type = b2_dynamicBody ;
}
rigid_body . pBody = mpPhysicsWorld - > CreateBody ( & rigid_body . Defintion ) ;
// Handle collision components
if ( mECSRegistry . all_of < CollisionComponent > ( entity ) )
{
auto & comp = mECSRegistry . get < CollisionComponent > ( entity ) ;
switch ( comp . Type )
{
case CollisionComponent : : ShapeType : : Box :
{
b2PolygonShape Shape ;
Shape . SetAsBox ( comp . Width / scale_factor , comp . Height / scale_factor ) ;
b2FixtureDef fixtureDef ;
fixtureDef . shape = & Shape ;
fixtureDef . isSensor = comp . IsSensor ;
fixtureDef . density = comp . Density ;
fixtureDef . friction = comp . Friction ;
fixtureDef . restitution = comp . Restitution ;
rigid_body . pBody - > CreateFixture ( & fixtureDef ) ;
} break ;
case CollisionComponent : : ShapeType : : Circle :
{
b2CircleShape Shape ;
Shape . m_radius = comp . Radius / scale_factor ;
b2FixtureDef fixtureDef ;
fixtureDef . shape = & Shape ;
fixtureDef . isSensor = comp . IsSensor ;
fixtureDef . density = comp . Density ;
fixtureDef . friction = comp . Friction ;
fixtureDef . restitution = comp . Restitution ;
rigid_body . pBody - > CreateFixture ( & fixtureDef ) ;
} break ;
}
}
}
// Load scripts from all ScriptComponents in the world
// Load scripts from all ScriptComponents in the world
auto group_scripts = mECSRegistry . view < ScriptComponent > ( ) ;
auto group_scripts = mECSRegistry . view < ScriptComponent > ( ) ;
for ( auto entity : group_scripts )
for ( auto entity : group_scripts )
{
{
auto & script_comp = group_scripts . get < ScriptComponent > ( entity ) ;
auto & script_comp = group_scripts . get < ScriptComponent > ( entity ) ;
@ -62,6 +157,8 @@ namespace lunarium
WrenScript script ( pScript - > GetScriptFile ( ) . filename ( ) . string ( ) . c_str ( ) , pScript - > GetScript ( ) ) ;
WrenScript script ( pScript - > GetScriptFile ( ) . filename ( ) . string ( ) . c_str ( ) , pScript - > GetScript ( ) ) ;
// mScriptState.RunScript(&script);
// mScriptState.RunScript(&script);
WorldAPI : : RunScript ( script ) ;
WorldAPI : : RunScript ( script ) ;
# else
// Get Binary assets
# endif
# endif
}
}
@ -74,6 +171,9 @@ namespace lunarium
// Call OnUnLoad for each registered EntityBehavior class object
// Call OnUnLoad for each registered EntityBehavior class object
WorldAPI : : InvokeEvent ( WorldAPI : : Event : : ON_UNLOAD ) ;
WorldAPI : : InvokeEvent ( WorldAPI : : Event : : ON_UNLOAD ) ;
WorldAPI : : Shutdown ( ) ;
WorldAPI : : Shutdown ( ) ;
delete mpPhysicsWorld ;
mpPhysicsWorld = nullptr ;
}
}
void World : : SetRunMode ( RunMode mode )
void World : : SetRunMode ( RunMode mode )
@ -94,21 +194,50 @@ namespace lunarium
// Update Transforms for any enity with a velocity
// Update Transforms for any enity with a velocity
// NOTE: Might remove the VelocityComponent in favor of using the physics system
auto group = mECSRegistry . group < > ( entt : : get < VelocityComponent , TransformComponent > ) ;
auto group = mECSRegistry . group < > ( entt : : get < VelocityComponent , TransformComponent > ) ;
for ( auto entity : group )
for ( auto entity : group )
{
{
// Skip any entity that has a physics component
if ( mECSRegistry . any_of < RigidBodyComponent , CollisionComponent > ( entity ) )
{
continue ;
}
auto & transform = group . get < TransformComponent > ( entity ) ;
auto & transform = group . get < TransformComponent > ( entity ) ;
auto & velocity = group . get < VelocityComponent > ( entity ) ;
auto & velocity = group . get < VelocityComponent > ( entity ) ;
transform . Position + = velocity . Velocity * dt ;
transform . Position + = velocity . Velocity * dt ;
}
}
// Update the physics sim and then use the results to update objects Transforms
float timeStep = 1.0f / 60.0f ;
int32 velocityIterations = 6 ;
int32 positionIterations = 2 ;
mpPhysicsWorld - > Step ( timeStep , velocityIterations , positionIterations ) ;
auto group_phys = mECSRegistry . view < TransformComponent , RigidBodyComponent > ( ) ;
for ( auto entity : group_phys )
{
auto & transform = group_phys . get < TransformComponent > ( entity ) ;
auto & rigid_body = group_phys . get < RigidBodyComponent > ( entity ) ;
float scale_factor = WorldSettings . Physics . PhysicsScaleFactor ;
transform . Position = glm : : vec3 ( rigid_body . pBody - > GetPosition ( ) . x * scale_factor , rigid_body . pBody - > GetPosition ( ) . y * scale_factor , 0.0f ) ;
transform . Rotation . z = rigid_body . pBody - > GetAngle ( ) ;
}
}
}
void World : : Render ( lunarium : : Renderer2D * pGraphics )
void World : : Render ( lunarium : : Renderer2D * pGraphics )
{
{
RenderBlockouts ( pGraphics ) ;
RenderBlockouts ( pGraphics ) ;
RenderSprites ( pGraphics ) ;
RenderSprites ( pGraphics ) ;
if ( mDrawDebugObjects )
{
RenderDebugObjects ( pGraphics ) ;
}
}
}
@ -271,40 +400,36 @@ namespace lunarium
// pGraphics->DrawQuad(rect, color, nullptr, transform.Rotation.z, Rectangle(-1, -1, -1, -1), parent_transform);
// pGraphics->DrawQuad(rect, color, nullptr, transform.Rotation.z, Rectangle(-1, -1, -1, -1), parent_transform);
}
}
}
}
// void World::DrawHeirarchy(lunarium::Renderer2D* g, entt::entity& entity, TransformComponent& my_trans, BlockOutComponent& bo_comp, glm::mat4 current_transform)
// {
// // Draw current entity
// Rectangle rect(my_trans.Position.x, my_trans.Position.y, bo_comp.Size.x, bo_comp.Size.y);
// Color color(bo_comp.Color.x, bo_comp.Color.y, bo_comp.Color.z, bo_comp.Color.w);
// g->DrawQuad(rect, color, nullptr, -my_trans.Rotation.z, Rectangle(-1, -1, -1, -1), current_transform);
// // Apply transform to children's transforms
// current_transform *= my_trans.GetTransform();
// // Iterate and draw children
// if (mECSRegistry.all_of<ChildrenComponent>(entity))
// {
// ChildrenComponent& children_comp = mECSRegistry.get<ChildrenComponent>(entity);
// for (int i = 0; i < children_comp.Children.size(); i++)
// {
// Entity* pEnt = GetEntity(children_comp.Children[i]);
// entt::entity handle = pEnt->GetEnttHandle();
// if (pEnt->HasComponent<TransformComponent>() && pEnt->HasComponent<BlockOutComponent>())
// {
// TransformComponent& trans_comp = pEnt->GetComponent<TransformComponent>();
// BlockOutComponent& bo_comp = pEnt->GetComponent<BlockOutComponent>();
// DrawHeirarchy(g, handle, trans_comp, bo_comp, current_transform);
// }
// }
// }
// }
void World : : RenderDebugObjects ( lunarium : : Renderer2D * pGraphics )
{
auto group_phys = mECSRegistry . view < TransformComponent , RigidBodyComponent , CollisionComponent > ( ) ;
for ( auto entity : group_phys )
{
auto & rigid_body = group_phys . get < RigidBodyComponent > ( entity ) ;
auto & collision = group_phys . get < CollisionComponent > ( entity ) ;
if ( ! rigid_body . pBody )
continue ;
if ( collision . Type = = CollisionComponent : : ShapeType : : Box )
{
b2AABB box ;
b2Transform transform = { rigid_body . pBody - > GetTransform ( ) . p , b2Rot ( 0.0f ) } ;
rigid_body . pBody - > GetFixtureList ( ) - > GetShape ( ) - > ComputeAABB ( & box , transform , 0 ) ;
float scale_factor = WorldSettings . Physics . PhysicsScaleFactor ;
float angle = rigid_body . pBody - > GetAngle ( ) ;
Rectangle rect ( box ) ;
rect . Scale ( scale_factor , scale_factor ) ;
rect . X * = scale_factor ;
rect . Y * = scale_factor ;
pGraphics - > DrawBox ( rect , Color ( 0.1f , 0.2f , 1.0f , 1.0f ) , 1.5f , angle ) ;
}
}
}
glm : : mat4 World : : GetParentTransform ( LUUID parent )
glm : : mat4 World : : GetParentTransform ( LUUID parent )
{
{
glm : : mat4 transform ( 1.0f ) ;
glm : : mat4 transform ( 1.0f ) ;
@ -360,8 +485,11 @@ namespace lunarium
{
{
# if !BUILD_NO_EDITOR // Only does this when this is an editor build
# if !BUILD_NO_EDITOR // Only does this when this is an editor build
// General data
node [ " UUID " ] = mUUID ;
node [ " UUID " ] = mUUID ;
node [ " Name " ] = mName ;
// Game entities
node [ " NumberOfEntities " ] = mEntities . size ( ) ;
node [ " NumberOfEntities " ] = mEntities . size ( ) ;
auto & ents = node [ " Entities " ] ;
auto & ents = node [ " Entities " ] ;
for ( int i = 0 ; i < mEntities . size ( ) ; i + + )
for ( int i = 0 ; i < mEntities . size ( ) ; i + + )
@ -371,6 +499,17 @@ namespace lunarium
ents . emplace_back ( e ) ;
ents . emplace_back ( e ) ;
}
}
// World settings
auto & settings = node [ " Settings " ] ;
auto & physics = settings [ " Physics " ] ;
physics [ " scale_factor " ] = WorldSettings . Physics . PhysicsScaleFactor ;
auto & gravity = physics [ " gravity " ] ;
gravity [ " x " ] = WorldSettings . Physics . Gravity . x ;
gravity [ " y " ] = WorldSettings . Physics . Gravity . y ;
gravity [ " z " ] = WorldSettings . Physics . Gravity . z ;
# endif
# endif
return OpRes : : OK ( ) ;
return OpRes : : OK ( ) ;
}
}
@ -379,7 +518,11 @@ namespace lunarium
{
{
# if !BUILD_NO_EDITOR // Only does this when this is an editor build
# if !BUILD_NO_EDITOR // Only does this when this is an editor build
// General Data
mUUID = node [ " UUID " ] . get < u64 > ( ) ;
mUUID = node [ " UUID " ] . get < u64 > ( ) ;
mName = node [ " Name " ] . get < std : : string > ( ) ;
// Game entities
int num_entities = node [ " NumberOfEntities " ] . get < int > ( ) ;
int num_entities = node [ " NumberOfEntities " ] . get < int > ( ) ;
auto & ents = node [ " Entities " ] ;
auto & ents = node [ " Entities " ] ;
for ( auto it = ents . begin ( ) ; it ! = ents . end ( ) ; + + it )
for ( auto it = ents . begin ( ) ; it ! = ents . end ( ) ; + + it )
@ -398,6 +541,18 @@ namespace lunarium
mEntitiesByUUID [ new_ent - > GetUUID ( ) ] = new_ent ;
mEntitiesByUUID [ new_ent - > GetUUID ( ) ] = new_ent ;
}
}
// World Settings
if ( ! node [ " Settings " ] . is_null ( ) )
{
auto & settings = node [ " Settings " ] ;
auto & physics = settings [ " Physics " ] ;
WorldSettings . Physics . PhysicsScaleFactor = physics [ " scale_factor " ] . get < float > ( ) ;
auto & gravity = physics [ " gravity " ] ;
WorldSettings . Physics . Gravity = { gravity [ " x " ] . get < float > ( ) , gravity [ " y " ] . get < float > ( ) , gravity [ " z " ] . get < float > ( ) } ;
}
# endif
# endif
return OpRes : : OK ( ) ;
return OpRes : : OK ( ) ;
}
}