Skip to content

Commit

Permalink
Added more joint types
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardodoria committed Aug 28, 2023
1 parent aebb4f9 commit eb223b2
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 27 deletions.
10 changes: 8 additions & 2 deletions engine/core/component/Joint2DComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,14 @@ namespace Supernova{
Joint2DType type = Joint2DType::DISTANCE;
bool collideConnected = false;

Vector2 worldAnchorOnBodyA;
Vector2 worldAnchorOnBodyB;
Vector2 anchorA;
Vector2 anchorB;
Vector2 axis;
Vector2 groundAnchorA;
Vector2 groundAnchorB;
float ratio = 0;
Entity joint1 = NULL_ENTITY;
Entity joint2 = NULL_ENTITY;

bool needUpdate = true;
};
Expand Down
63 changes: 61 additions & 2 deletions engine/core/object/physics/Joint2D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,65 @@ void Joint2D::setDistanceJoint(Entity bodyA, Entity bodyB, Vector2 worldAnchorOn

joint.bodyA = bodyA;
joint.bodyB = bodyB;
joint.worldAnchorOnBodyA = worldAnchorOnBodyA;
joint.worldAnchorOnBodyB = worldAnchorOnBodyB;
joint.anchorA = worldAnchorOnBodyA;
joint.anchorB = worldAnchorOnBodyB;

joint.needUpdate = true;
}

void Joint2D::setRevoluteJoint(Entity bodyA, Entity bodyB, Vector2 worldAnchor){
Joint2DComponent& joint = getComponent<Joint2DComponent>();

joint.type = Joint2DType::REVOLUTE;

joint.bodyA = bodyA;
joint.bodyB = bodyB;
joint.anchorA = worldAnchor;
joint.anchorB = worldAnchor;

joint.needUpdate = true;
}

void Joint2D::setPrismaticJoint(Entity bodyA, Entity bodyB, Vector2 worldAnchor, Vector2 worldAxis){
Joint2DComponent& joint = getComponent<Joint2DComponent>();

joint.type = Joint2DType::PRISMATIC;

joint.bodyA = bodyA;
joint.bodyB = bodyB;
joint.anchorA = worldAnchor;
joint.anchorB = worldAnchor;
joint.axis = worldAxis;

joint.needUpdate = true;
}

void Joint2D::setPulleyJoint(Entity bodyA, Entity bodyB, Vector2 groundAnchorA, Vector2 groundAnchorB, Vector2 worldAnchorOnBodyA, Vector2 worldAnchorOnBodyB, Vector2 worldAxis, float ratio){
Joint2DComponent& joint = getComponent<Joint2DComponent>();

joint.type = Joint2DType::PULLEY;

joint.bodyA = bodyA;
joint.bodyB = bodyB;
joint.groundAnchorA = groundAnchorA;
joint.groundAnchorB = groundAnchorB;
joint.anchorA = worldAnchorOnBodyA;
joint.anchorB = worldAnchorOnBodyB;
joint.ratio = ratio;

joint.needUpdate = true;
}

void Joint2D::setGearJoint(Entity bodyA, Entity bodyB, Entity revoluteJoint, Entity prismaticJoint, float ratio){
Joint2DComponent& joint = getComponent<Joint2DComponent>();

joint.type = Joint2DType::PULLEY;

joint.bodyA = bodyA;
joint.bodyB = bodyB;
joint.joint1 = revoluteJoint;
joint.joint2 = prismaticJoint;
joint.ratio = ratio;

joint.needUpdate = true;
}
5 changes: 4 additions & 1 deletion engine/core/object/physics/Joint2D.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ namespace Supernova{
Joint2D& operator=(const Joint2D& rhs);

void setDistanceJoint(Entity bodyA, Entity bodyB, Vector2 worldAnchorOnBodyA, Vector2 worldAnchorOnBodyB);

void setRevoluteJoint(Entity bodyA, Entity bodyB, Vector2 worldAnchor);
void setPrismaticJoint(Entity bodyA, Entity bodyB, Vector2 worldAnchor, Vector2 worldAxis);
void setPulleyJoint(Entity bodyA, Entity bodyB, Vector2 groundAnchorA, Vector2 groundAnchorB, Vector2 worldAnchorOnBodyA, Vector2 worldAnchorOnBodyB, Vector2 worldAxis, float ratio);
void setGearJoint(Entity bodyA, Entity bodyB, Entity revoluteJoint, Entity prismaticJoint, float ratio);
};
}

Expand Down
77 changes: 55 additions & 22 deletions engine/core/subsystem/PhysicsSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,6 @@ b2BodyType getBodyType(Body2DType type){
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<Body2DComponent>());
Expand Down Expand Up @@ -174,29 +164,72 @@ bool PhysicsSystem::loadJoint2D(Joint2DComponent& joint){
Signature signatureB = scene->getSignature(joint.bodyB);

if (signatureA.test(scene->getComponentType<Body2DComponent>()) && signatureB.test(scene->getComponentType<Body2DComponent>())){
b2JointDef* jointDef;
b2JointDef* jointDef = NULL;

Body2DComponent myBodyA = scene->getComponent<Body2DComponent>(joint.bodyA);
Body2DComponent myBodyB = scene->getComponent<Body2DComponent>(joint.bodyB);

if (joint.type == Joint2DType::DISTANCE){
b2Vec2 anchorA(joint.worldAnchorOnBodyA.x / pointsToMeterScale, joint.worldAnchorOnBodyA.y / pointsToMeterScale);
b2Vec2 anchorb(joint.worldAnchorOnBodyB.x / pointsToMeterScale, joint.worldAnchorOnBodyB.y / pointsToMeterScale);
b2Vec2 anchorA(joint.anchorA.x / pointsToMeterScale, joint.anchorA.y / pointsToMeterScale);
b2Vec2 anchorB(joint.anchorB.x / pointsToMeterScale, joint.anchorB.y / pointsToMeterScale);

jointDef = new b2DistanceJointDef();
((b2DistanceJointDef*)jointDef)->Initialize(myBodyA.body, myBodyB.body, anchorA, anchorb);
}

jointDef->collideConnected = joint.collideConnected;
jointDef->type = getJointType(joint.type);
((b2DistanceJointDef*)jointDef)->Initialize(myBodyA.body, myBodyB.body, anchorA, anchorB);
}else if(joint.type == Joint2DType::REVOLUTE){
b2Vec2 anchor(joint.anchorA.x / pointsToMeterScale, joint.anchorA.y / pointsToMeterScale);

jointDef = new b2RevoluteJointDef();
((b2RevoluteJointDef*)jointDef)->Initialize(myBodyA.body, myBodyB.body, anchor);
}else if(joint.type == Joint2DType::PRISMATIC){
b2Vec2 anchor(joint.anchorA.x / pointsToMeterScale, joint.anchorA.y / pointsToMeterScale);
b2Vec2 axis(joint.axis.x, joint.axis.y);

jointDef = new b2PrismaticJointDef();
((b2PrismaticJointDef*)jointDef)->Initialize(myBodyA.body, myBodyB.body, anchor, axis);
}else if(joint.type == Joint2DType::PULLEY){
b2Vec2 anchorA(joint.anchorA.x / pointsToMeterScale, joint.anchorA.y / pointsToMeterScale);
b2Vec2 anchorB(joint.anchorB.x / pointsToMeterScale, joint.anchorB.y / pointsToMeterScale);
b2Vec2 groundA(joint.groundAnchorA.x / pointsToMeterScale, joint.groundAnchorA.y / pointsToMeterScale);
b2Vec2 groundB(joint.groundAnchorB.x / pointsToMeterScale, joint.groundAnchorB.y / pointsToMeterScale);

jointDef = new b2PulleyJointDef();
((b2PulleyJointDef*)jointDef)->Initialize(myBodyA.body, myBodyB.body, groundA, groundB, anchorA, anchorB, joint.ratio);
}else if(joint.type == Joint2DType::GEAR){

Signature signatureJ1 = scene->getSignature(joint.joint1);
Signature signatureJ2 = scene->getSignature(joint.joint2);

if (signatureJ1.test(scene->getComponentType<Joint2DComponent>()) && signatureJ2.test(scene->getComponentType<Joint2DComponent>())){
Joint2DComponent myJoint1 = scene->getComponent<Joint2DComponent>(joint.joint1);
Joint2DComponent myJoint2 = scene->getComponent<Joint2DComponent>(joint.joint2);

if (myJoint1.joint && myJoint2.joint){
jointDef = new b2GearJointDef();
((b2GearJointDef*)jointDef)->joint1 = myJoint1.joint;
((b2GearJointDef*)jointDef)->joint2 = myJoint2.joint;
((b2GearJointDef*)jointDef)->bodyA = myBodyA.body;
((b2GearJointDef*)jointDef)->bodyB = myBodyB.body;
((b2GearJointDef*)jointDef)->ratio = joint.ratio;
}else{
Log::error("Cannot create joint, joint1 or joint2 not created");
}
}else{
Log::error("Cannot create joint, error in joint1 or joint2");
}

joint.needUpdate = false;
}
if (jointDef){
jointDef->collideConnected = joint.collideConnected;
joint.joint = world2D->CreateJoint(jointDef);

joint.joint = world2D->CreateJoint(jointDef);
joint.needUpdate = false;

delete jointDef;
delete jointDef;

return true;
return true;
}else{
Log::error("Cannot create joint");
}
}else{
Log::error("Cannot create joint, error in bodyA or bodyB");
}
Expand Down

0 comments on commit eb223b2

Please sign in to comment.