Skip to content

Commit

Permalink
Added Joint2DComponent
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardodoria committed Aug 18, 2023
1 parent f907e82 commit 7caa1d7
Show file tree
Hide file tree
Showing 11 changed files with 208 additions and 18 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ include_directories (${SUPERNOVA_ROOT}/engine/core/object)
include_directories (${SUPERNOVA_ROOT}/engine/core/object/audio)
include_directories (${SUPERNOVA_ROOT}/engine/core/object/ui)
include_directories (${SUPERNOVA_ROOT}/engine/core/object/environment)
include_directories (${SUPERNOVA_ROOT}/engine/core/object/physics)
include_directories (${SUPERNOVA_ROOT}/engine/core/script)
include_directories (${SUPERNOVA_ROOT}/engine/core/subsystem)
include_directories (${SUPERNOVA_ROOT}/engine/core/texture)
Expand Down
1 change: 1 addition & 0 deletions engine/core/Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Scene::Scene(){
registerComponent<AudioComponent>();
registerComponent<TilemapComponent>();
registerComponent<Body2DComponent>();
registerComponent<Joint2DComponent>();

registerSystem<PhysicsSystem>();
registerSystem<ActionSystem>();
Expand Down
1 change: 1 addition & 0 deletions engine/core/Scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "component/AudioComponent.h"
#include "component/TilemapComponent.h"
#include "component/Body2DComponent.h"
#include "component/Joint2DComponent.h"

namespace Supernova{

Expand Down
2 changes: 1 addition & 1 deletion engine/core/component/Body2DComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace Supernova{
bool fixedRotation = false;
bool bullet = false;
Body2DType type = Body2DType::STATIC;
bool enable = true;
bool enabled = true;
float gravityScale = 1.0f;

CollisionShape2D shapes[MAX_SHAPES];
Expand Down
38 changes: 38 additions & 0 deletions engine/core/component/Joint2DComponent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef JOINT2D_COMPONENT_H
#define JOINT2D_COMPONENT_H

#include "Supernova.h"

class b2Joint;

namespace Supernova{

enum class Joint2DType{
DISTANCE,
REVOLUTE
};

struct Joint2DComponent{
b2Joint* joint = NULL;

Entity bodyA;
Entity bodyB;
Joint2DType type = Joint2DType::DISTANCE;
bool collideConnected = false;

Vector2 localAnchorA = Vector2(0.0f, 0.0f);
Vector2 localAnchorB = Vector2(0.0f, 0.0f);
float referenceAngle = 0.0f;
float lowerAngle = 0.0f;
float upperAngle = 0.0f;
float maxMotorTorque = 0.0f;
float motorSpeed = 0.0f;
float enableLimit = false;
float enableMotor = false;

bool needUpdate = true;
};

}

#endif //JOINT2D_COMPONENT_H
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,11 @@ void Body2D::setType(Body2DType type){
}
}

void Body2D::setEnabled(bool enable){
void Body2D::setEnabled(bool enabled){
Body2DComponent& body = getComponent<Body2DComponent>();

if (body.enable != enable){
body.enable = enable;
if (body.enabled != enabled){
body.enabled = enabled;

body.needUpdate = true;
}
Expand Down Expand Up @@ -301,7 +301,7 @@ Body2DType Body2D::getType() const{
bool Body2D::isEnabled() const{
Body2DComponent& body = getComponent<Body2DComponent>();

return body.enable;
return body.enabled;
}

float Body2D::getGravityScale() const{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace Supernova{
void setFixedRotation(bool fixedRotation);
void setBullet(bool bullet);
void setType(Body2DType type);
void setEnabled(bool enable);
void setEnabled(bool enabled);
void setGravityScale(float gravityScale);

Vector2 getLinearVelocity() const;
Expand Down
27 changes: 27 additions & 0 deletions engine/core/object/physics/Joint2D.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// (c) 2023 Eduardo Doria.
//

#include "Joint2D.h"

#include "subsystem/PhysicsSystem.h"
#include "component/Body2DComponent.h"

using namespace Supernova;

Joint2D::Joint2D(Scene* scene, Entity entity): EntityHandle(scene, entity){

}

Joint2D::~Joint2D(){

}

Joint2D::Joint2D(const Joint2D& rhs): EntityHandle(rhs){

}

Joint2D& Joint2D::operator=(const Joint2D& rhs){

return *this;
}
23 changes: 23 additions & 0 deletions engine/core/object/physics/Joint2D.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// (c) 2023 Eduardo Doria.
//

#ifndef JOINT2D_H
#define JOINT2D_H

#include "EntityHandle.h"

namespace Supernova{

class Joint2D: public EntityHandle{
public:
Joint2D(Scene* scene, Entity entity);
virtual ~Joint2D();

Joint2D(const Joint2D& rhs);
Joint2D& operator=(const Joint2D& rhs);

};
}

#endif //BODY2D_H
116 changes: 104 additions & 12 deletions engine/core/subsystem/PhysicsSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,31 @@

using namespace Supernova;

b2BodyType getBodyType(Body2DType type){
if (type == Body2DType::STATIC){
return b2_staticBody;
}else if (type == Body2DType::kINEMATIC){
return b2_kinematicBody;
}else if (type == Body2DType::DYNAMIC){
return b2_dynamicBody;
}

return b2_staticBody;
}

b2JointType getJointType(Joint2DType type){
if (type == Joint2DType::DISTANCE){
return e_distanceJoint;
}else if (type == Joint2DType::REVOLUTE){
return e_revoluteJoint;
}

return e_unknownJoint;
}


PhysicsSystem::PhysicsSystem(Scene* scene): SubSystem(scene){
signature.set(scene->getComponentType<Transform>());
signature.set(scene->getComponentType<Body2DComponent>());

this->scene = scene;

Expand Down Expand Up @@ -66,16 +88,47 @@ int PhysicsSystem::addRectShape2D(Entity entity, float width, float height){
return -1;
}

b2Body* PhysicsSystem::getBody(Entity entity){
Body2DComponent* body = scene->findComponent<Body2DComponent>(entity);

if (body){
return body->body;
}

return NULL;
}

bool PhysicsSystem::loadBody2D(Body2DComponent& body){
if (world2D && !body.body){
b2BodyDef bodyDef;
bodyDef.position.Set(0.0f, 0.0f);
bodyDef.angle = 0.0f;
bodyDef.type = b2_dynamicBody;
bodyDef.linearVelocity = b2Vec2(body.linearVelocity.x, body.linearVelocity.y);
bodyDef.angularVelocity = body.angularVelocity;
bodyDef.linearDamping = body.linearDamping;
bodyDef.angularDamping = body.angularDamping;
bodyDef.allowSleep = body.allowSleep;
bodyDef.awake = body.awake;
bodyDef.fixedRotation = body.fixedRotation;
bodyDef.bullet = body.bullet;
bodyDef.enabled = body.enabled;
bodyDef.gravityScale = body.gravityScale;
bodyDef.type = getBodyType(body.type);

body.needUpdate = false;

body.body = world2D->CreateBody(&bodyDef);

for (int i = 0; i < body.numShapes; i++){
b2FixtureDef fixtureDef;

fixtureDef.density = body.shapes[i].density;
fixtureDef.friction = body.shapes[i].friction;
fixtureDef.restitution = body.shapes[i].restitution;
fixtureDef.isSensor = body.shapes[i].sensor;

body.shapes[i].needUpdate = false;

body.shapes[i].fixture = body.body->CreateFixture(body.shapes[i].shape, 1.0f);
}

Expand All @@ -102,6 +155,33 @@ void PhysicsSystem::destroyBody2D(Body2DComponent& body){
}
}

bool PhysicsSystem::loadJoint2D(Joint2DComponent& joint){
if (world2D && !joint.joint){
b2JointDef jointDef;
jointDef.bodyA = getBody(joint.bodyA);
jointDef.bodyB = getBody(joint.bodyB);
jointDef.collideConnected = joint.collideConnected;
jointDef.type = getJointType(joint.type);

joint.needUpdate = false;

joint.joint = world2D->CreateJoint(&jointDef);

return true;
}

return false;
}

void PhysicsSystem::destroyJoint2D(Joint2DComponent& joint){
if (world2D && joint.joint){
world2D->DestroyJoint(joint.joint);

joint.joint = NULL;
}
}


void PhysicsSystem::load(){
if (!world2D){
b2Vec2 gravity(0.0f, 10.0f);
Expand All @@ -118,6 +198,8 @@ void PhysicsSystem::destroy(){

void PhysicsSystem::update(double dt){
auto bodies2d = scene->getComponentArray<Body2DComponent>();
auto joints2d = scene->getComponentArray<Joint2DComponent>();

for (int i = 0; i < bodies2d->size(); i++){
Body2DComponent& body = bodies2d->getComponentFromIndex(i);
Entity entity = bodies2d->getEntity(i);
Expand All @@ -134,16 +216,9 @@ void PhysicsSystem::update(double dt){
body.body->SetAwake(body.awake);
body.body->SetFixedRotation(body.fixedRotation);
body.body->SetBullet(body.bullet);
body.body->SetEnabled(body.enable);
body.body->SetEnabled(body.enabled);
body.body->SetGravityScale(body.gravityScale);

if (body.type == Body2DType::STATIC){
body.body->SetType(b2_staticBody);
}else if (body.type == Body2DType::kINEMATIC){
body.body->SetType(b2_kinematicBody);
}else if (body.type == Body2DType::DYNAMIC){
body.body->SetType(b2_dynamicBody);
}
body.body->SetType(getBodyType(body.type));

body.needUpdate = false;
}
Expand Down Expand Up @@ -175,6 +250,23 @@ void PhysicsSystem::update(double dt){
}
}

for (int i = 0; i < joints2d->size(); i++){
Joint2DComponent& joint = joints2d->getComponentFromIndex(i);
Entity entity = joints2d->getEntity(i);
Signature signature = scene->getSignature(entity);

loadJoint2D(joint);

if (joint.needUpdate){
if (joint.type == Joint2DType::DISTANCE){
b2DistanceJoint* distJoint = (b2DistanceJoint*)joint.joint;
//distJoint.se
}

joint.needUpdate = false;
}
}

if (bodies2d->size() > 0){
int32 velocityIterations = 6;
int32 positionIterations = 2;
Expand Down Expand Up @@ -211,7 +303,7 @@ void PhysicsSystem::update(double dt){
body.linearVelocity = Vector2(body.body->GetLinearVelocity().x, body.body->GetLinearVelocity().y);
body.angularVelocity = body.body->GetAngularVelocity();
body.awake = body.body->IsAwake();
body.enable = body.body->IsEnabled();
body.enabled = body.body->IsEnabled();
}
}

Expand Down
7 changes: 7 additions & 0 deletions engine/core/subsystem/PhysicsSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@

#include "SubSystem.h"
#include "component/Body2DComponent.h"
#include "component/Joint2DComponent.h"

class b2World;
class b2Body;

namespace Supernova{

Expand All @@ -26,9 +28,14 @@ namespace Supernova{
void removeBody2D(Entity entity);
int addRectShape2D(Entity entity, float width, float height);

b2Body* getBody(Entity entity);

bool loadBody2D(Body2DComponent& body);
void destroyBody2D(Body2DComponent& body);

bool loadJoint2D(Joint2DComponent& joint);
void destroyJoint2D(Joint2DComponent& joint);

virtual void load();
virtual void destroy();
virtual void update(double dt);
Expand Down

0 comments on commit 7caa1d7

Please sign in to comment.