gjtiquia / headless-game-engine

A minimalistic, framework-agnostic JavaScript game engine.
https://www.npmjs.com/package/headless-game-engine
MIT License
0 stars 0 forks source link

@headless-game-engine/physics-2d #25

Open gjtiquia opened 1 year ago

gjtiquia commented 1 year ago

include Rigidbody2D and Collider2D

static box colliders first

stretch goals

gjtiquia commented 1 year ago

for now really just implement AABB (Axis-aligned bounding boxes), detection and resolution

https://www.youtube.com/watch?v=wPKzwSxyhTI&ab_channel=DigiPenGameEngineArchitectureClub

https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection#aabb_vs._aabb

gjtiquia commented 1 year ago

Planning:

add abstract class System in the core package

Each Scene has a list of game objects and a list of systems

System has access to the lifecycle

Execution order will be game object components first, then system

The design is so that the components can do "whatever they want" and the system will do the "correction"

For a "clean" way to handle things, components should really just hold data and leave all the data manipulation to the system, following the ECS architecture

But it's nice to allow regular components without thinking about systems

Unity event execution reference:

https://docs.unity3d.com/Manual/ExecutionOrder.html

FixedUpdate in Unity is for scripts to do stuff like Rigidbody.AddForce, then the Internal Physics Update will take these into account, move the rigidbodies and do collision handling.

Add class Physics2DSystem extends System in physics-2d package

Most of the work would can be done in fixedUpdate, since System.fixedUpdate comes after Component.fixedUpdate, like how Unity's internal physics update comes after FixedUpdate in components.

Not doing it in lateUpdate, to reserve some flexibility for other components to make use of the information done in fixedUpdate, if ever needed.

There are 3 steps

  1. Integration
  2. Detection
  3. Resolution

Stretch goal:

Add class Rigidbody2D extends Component

Rigidbodies can operate without colliders. they will move with the physics system during the integration step.

gjtiquia commented 1 year ago

Planning:

add abstract class System in the core package

Each Scene has a list of game objects and a list of systems

System has access to the lifecycle

Execution order will be game object components first, then system

The design is so that the components can do "whatever they want" and the system will do the "correction"

For a "clean" way to handle things, components should really just hold data and leave all the data manipulation to the system, following the ECS architecture

But it's nice to allow regular components without thinking about systems

Add class Physics2DSystem extends System in physics-2d package

Most of the work would be done in lateUpdate, with 3 steps

  1. Integration
  2. Detection
  3. Resolution

Stretch goal:

gjtiquia commented 1 year ago

Integration

Goal: move all the Rigidbodies

In Component.fixedUpdate, whenever Rigidbody.AddForce is called, the resultant acceleration is calculated (with fixedDeltaTime) and added to the net acceleration

Unity Rigidbody.AddForce reference

https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html

In the reference, change in velocity means the acceleration.

Stretch Goals

in PhysicsSystem2D, the velocity is updated by the net acceleration. NO NEED to multiply by fixedDeltaTime, as this should have been done in the AddForce calculation

save the current position for use during the detection and resolution step

const previousPosition = {...position}

the position is then updated by the velocity * dt

velocity += netAcceleration
position += velocity * dt

then reset netAcceleration to zero

netAcceleration = {x: 0, y: 0}
gjtiquia commented 1 year ago

Detection

straight into narrow phase detection, broad phase is a stretch goal

slow O(n^2) but, it works, dun do premature optimization until needed

Unity Collision Detection Mode reference

https://docs.unity3d.com/ScriptReference/CollisionDetectionMode2D.html

for each Collider2D, check against other Collider2D and see if they are colliding

Collider2D does discrete detection by default and just checks the current position. Tunneling may occur.

for rigidbodies, should (optionally) do continous detection, checks in the path from the previous position to the current position and see if there were any collisions during that time. this prevents tunneling.

note that not all rigidbodies hv colliders. or the other way around, not all colliders have rigidbodies.

the continuous detection can be done by.... sweeping using line segments maybe?

stretch goal

add all the collisions into a hashmap, for use in resolution phase, and potentially OnCollisionEnter2D and OnCollisionExit2D calls

gjtiquia commented 1 year ago

Resolution

correctly displace the game object

https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/swept-aabb-collision-detection-and-response-r3084/

just need to do resolution for rigidbodies? technically no need to resolve those game objects with just colliders, they are not expected to be moving anyways?

// TODO