Skip to content

Commit

Permalink
Added all 3D joints
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardodoria committed Oct 16, 2023
1 parent 9bd2c7d commit ba66785
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 1 deletion.
5 changes: 4 additions & 1 deletion engine/core/component/Joint3DComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ namespace Supernova{
PRISMATIC, // slider in Jolt
SWINGTWIST,
SIXDOF,
PATH
PATH,
GEAR,
RACKANDPINON,
PULLEY
};

struct Joint3DComponent{
Expand Down
12 changes: 12 additions & 0 deletions engine/core/object/physics/Joint3D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@ void Joint3D::setPathJoint(Entity bodyA, Entity bodyB, std::vector<Vector3> posi
scene->getSystem<PhysicsSystem>()->loadPathJoint3D(getComponent<Joint3DComponent>(), bodyA, bodyB, positions, tangents, normals, pathPosition, isLooping);
}

void Joint3D::setGearJoint(Entity bodyA, Entity bodyB, Entity hingeA, Entity hingeB, int numTeethGearA, int numTeethGearB){
scene->getSystem<PhysicsSystem>()->loadGearJoint3D(getComponent<Joint3DComponent>(), bodyA, bodyB, hingeA, hingeB, numTeethGearA, numTeethGearB);
}

void Joint3D::setRackAndPinionJoint(Entity bodyA, Entity bodyB, Entity hinge, Entity slider, int numTeethRack, int numTeethGear, int rackLength){
scene->getSystem<PhysicsSystem>()->loadRackAndPinionJoint3D(getComponent<Joint3DComponent>(), bodyA, bodyB, hinge, slider, numTeethRack, numTeethGear, rackLength);
}

void Joint3D::setPulleyJoint(Joint3DComponent& joint, Entity bodyA, Entity bodyB, Vector3 worldAnchorOnBodyA, Vector3 worldAnchorOnBodyB, Vector3 fixedPointA, Vector3 fixedPointB){
scene->getSystem<PhysicsSystem>()->loadPulleyJoint3D(getComponent<Joint3DComponent>(), bodyA, bodyB, worldAnchorOnBodyA, worldAnchorOnBodyB, fixedPointA, fixedPointB);
}

Joint3DType Joint3D::getType(){
Joint3DComponent& joint = getComponent<Joint3DComponent>();

Expand Down
3 changes: 3 additions & 0 deletions engine/core/object/physics/Joint3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ namespace Supernova{
void setSwingTwistJoint(Entity bodyA, Entity bodyB, Vector3 worldAnchor, Vector3 twistAxis, Vector3 planeAxis, float normalHalfConeAngle, float planeHalfConeAngle, float twistMinAngle, float twistMaxAngle);
void setSixDOFJoint(Entity bodyA, Entity bodyB, Vector3 worldAnchorOnBodyA, Vector3 worldAnchorOnBodyB, Vector3 axisX, Vector3 axisY);
void setPathJoint(Entity bodyA, Entity bodyB, std::vector<Vector3> positions, std::vector<Vector3> tangents, std::vector<Vector3> normals, Vector3 pathPosition, bool isLooping);
void setGearJoint(Entity bodyA, Entity bodyB, Entity hingeA, Entity hingeB, int numTeethGearA, int numTeethGearB);
void setRackAndPinionJoint(Entity bodyA, Entity bodyB, Entity hinge, Entity slider, int numTeethRack, int numTeethGear, int rackLength);
void setPulleyJoint(Joint3DComponent& joint, Entity bodyA, Entity bodyB, Vector3 worldAnchorOnBodyA, Vector3 worldAnchorOnBodyB, Vector3 fixedPointA, Vector3 fixedPointB);

Joint3DType getType();
};
Expand Down
143 changes: 143 additions & 0 deletions engine/core/subsystem/PhysicsSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,149 @@ bool PhysicsSystem::loadPathJoint3D(Joint3DComponent& joint, Entity bodyA, Entit
return true;
}

bool PhysicsSystem::loadGearJoint3D(Joint3DComponent& joint, Entity bodyA, Entity bodyB, Entity hingeA, Entity hingeB, int numTeethGearA, int numTeethGearB){
Signature signatureA = scene->getSignature(bodyA);
Signature signatureB = scene->getSignature(bodyB);
Signature signatureHingeA = scene->getSignature(hingeA);
Signature signatureHingeB = scene->getSignature(hingeB);

if (signatureA.test(scene->getComponentType<Body3DComponent>()) && signatureB.test(scene->getComponentType<Body3DComponent>())){

Body3DComponent myBodyA = scene->getComponent<Body3DComponent>(bodyA);
Body3DComponent myBodyB = scene->getComponent<Body3DComponent>(bodyB);

updateBody3DPosition(signatureA, bodyA, myBodyA, true);
updateBody3DPosition(signatureB, bodyB, myBodyB, true);

if (signatureHingeA.test(scene->getComponentType<Joint3DComponent>()) && signatureHingeB.test(scene->getComponentType<Joint3DComponent>())){

Joint3DComponent myHingeA = scene->getComponent<Joint3DComponent>(hingeA);
Joint3DComponent myHingeB = scene->getComponent<Joint3DComponent>(hingeB);

if ((myHingeA.type != Joint3DType::HINGE) || (myHingeB.type != Joint3DType::HINGE)){
Log::error("Cannot create joint, hingeA or hingeB is not hinge type");
return false;
}

// Disable collision between gears
JPH::Ref<JPH::GroupFilterTable> group_filter = new JPH::GroupFilterTable(2);
group_filter->DisableCollision(0, 1);
myBodyA.body->SetCollisionGroup(JPH::CollisionGroup(group_filter, 0, 0));
myBodyB.body->SetCollisionGroup(JPH::CollisionGroup(group_filter, 0, 1));

JPH::HingeConstraintSettings* hingeSetA = (JPH::HingeConstraintSettings*)((JPH::HingeConstraint*)myHingeA.joint)->GetConstraintSettings().GetPtr();
JPH::HingeConstraintSettings* hingeSetB = (JPH::HingeConstraintSettings*)((JPH::HingeConstraint*)myHingeB.joint)->GetConstraintSettings().GetPtr();

JPH::GearConstraintSettings settings;
settings.mHingeAxis1 = hingeSetA->mHingeAxis1;
settings.mHingeAxis2 = hingeSetB->mHingeAxis1;
settings.SetRatio(numTeethGearA, numTeethGearB);

joint.joint = settings.Create(*myBodyA.body, *myBodyB.body);

((JPH::GearConstraint *)joint.joint)->SetConstraints(myHingeA.joint, myHingeB.joint);
world3D->AddConstraint(joint.joint);
joint.type = Joint3DType::GEAR;
}else{
Log::error("Cannot create joint, error in hingeA or hingeB");
return false;
}

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

return true;
}

bool PhysicsSystem::loadRackAndPinionJoint3D(Joint3DComponent& joint, Entity bodyA, Entity bodyB, Entity hinge, Entity slider, int numTeethRack, int numTeethGear, int rackLength){
Signature signatureA = scene->getSignature(bodyA);
Signature signatureB = scene->getSignature(bodyB);
Signature signatureHinge = scene->getSignature(hinge);
Signature signatureSlider = scene->getSignature(slider);

if (signatureA.test(scene->getComponentType<Body3DComponent>()) && signatureB.test(scene->getComponentType<Body3DComponent>())){

Body3DComponent myBodyA = scene->getComponent<Body3DComponent>(bodyA);
Body3DComponent myBodyB = scene->getComponent<Body3DComponent>(bodyB);

updateBody3DPosition(signatureA, bodyA, myBodyA, true);
updateBody3DPosition(signatureB, bodyB, myBodyB, true);

if (signatureHinge.test(scene->getComponentType<Joint3DComponent>()) && signatureSlider.test(scene->getComponentType<Joint3DComponent>())){

Joint3DComponent myHinge = scene->getComponent<Joint3DComponent>(hinge);
Joint3DComponent mySlider = scene->getComponent<Joint3DComponent>(slider);

if ((myHinge.type != Joint3DType::HINGE) || (mySlider.type != Joint3DType::PRISMATIC)){
Log::error("Cannot create joint, hinge or slider is not hinge and prismatic (slider) types");
return false;
}

// Disable collision between gears
JPH::Ref<JPH::GroupFilterTable> group_filter = new JPH::GroupFilterTable(2);
group_filter->DisableCollision(0, 1);
myBodyA.body->SetCollisionGroup(JPH::CollisionGroup(group_filter, 0, 0));
myBodyB.body->SetCollisionGroup(JPH::CollisionGroup(group_filter, 0, 1));

JPH::HingeConstraintSettings* hingeSetA = (JPH::HingeConstraintSettings*)((JPH::HingeConstraint*)myHinge.joint)->GetConstraintSettings().GetPtr();
JPH::SliderConstraintSettings* sliderSetB = (JPH::SliderConstraintSettings*)((JPH::SliderConstraint*)mySlider.joint)->GetConstraintSettings().GetPtr();

JPH::RackAndPinionConstraintSettings settings;
settings.mHingeAxis = hingeSetA->mHingeAxis1;
settings.mSliderAxis = sliderSetB->mSliderAxis2;
settings.SetRatio(numTeethRack, rackLength, numTeethGear);

joint.joint = settings.Create(*myBodyA.body, *myBodyB.body);

((JPH::GearConstraint *)joint.joint)->SetConstraints(myHinge.joint, mySlider.joint);
world3D->AddConstraint(joint.joint);
joint.type = Joint3DType::RACKANDPINON;
}else{
Log::error("Cannot create joint, error in hinge or slider");
return false;
}

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

return true;
}

bool PhysicsSystem::loadPulleyJoint3D(Joint3DComponent& joint, Entity bodyA, Entity bodyB, Vector3 anchorA, Vector3 anchorB, Vector3 fixedPointA, Vector3 fixedPointB){
Signature signatureA = scene->getSignature(bodyA);
Signature signatureB = scene->getSignature(bodyB);

if (signatureA.test(scene->getComponentType<Body3DComponent>()) && signatureB.test(scene->getComponentType<Body3DComponent>())){

Body3DComponent myBodyA = scene->getComponent<Body3DComponent>(bodyA);
Body3DComponent myBodyB = scene->getComponent<Body3DComponent>(bodyB);

updateBody3DPosition(signatureA, bodyA, myBodyA, true);
updateBody3DPosition(signatureB, bodyB, myBodyB, true);

JPH::PulleyConstraintSettings settings;
settings.mBodyPoint1 = JPH::Vec3(anchorA.x, anchorA.y, anchorA.z);
settings.mBodyPoint2 = JPH::Vec3(anchorB.x, anchorB.y, anchorB.z);
settings.mFixedPoint1 = JPH::Vec3(fixedPointA.x, fixedPointA.y, fixedPointA.z);
settings.mFixedPoint2 = JPH::Vec3(fixedPointB.x, fixedPointB.y, fixedPointB.z);

joint.joint = settings.Create(*myBodyA.body, *myBodyB.body);

world3D->AddConstraint(joint.joint);
joint.type = Joint3DType::PULLEY;

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

return true;
}

void PhysicsSystem::load(){
}

Expand Down
3 changes: 3 additions & 0 deletions engine/core/subsystem/PhysicsSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ namespace Supernova{
bool loadSwingTwistJoint3D(Joint3DComponent& joint, Entity bodyA, Entity bodyB, Vector3 anchor, Vector3 twistAxis, Vector3 planeAxis, float normalHalfConeAngle, float planeHalfConeAngle, float twistMinAngle, float twistMaxAngle);
bool loadSixDOFJoint3D(Joint3DComponent& joint, Entity bodyA, Entity bodyB, Vector3 anchorA, Vector3 anchorB, Vector3 axisX, Vector3 axisY);
bool loadPathJoint3D(Joint3DComponent& joint, Entity bodyA, Entity bodyB, std::vector<Vector3> positions, std::vector<Vector3> tangents, std::vector<Vector3> normals, Vector3 pathPosition, bool isLooping);
bool loadGearJoint3D(Joint3DComponent& joint, Entity bodyA, Entity bodyB, Entity hingeA, Entity hingeB, int numTeethGearA, int numTeethGearB);
bool loadRackAndPinionJoint3D(Joint3DComponent& joint, Entity bodyA, Entity bodyB, Entity hinge, Entity slider, int numTeethRack, int numTeethGear, int rackLength);
bool loadPulleyJoint3D(Joint3DComponent& joint, Entity bodyA, Entity bodyB, Vector3 anchorA, Vector3 anchorB, Vector3 fixedPointA, Vector3 fixedPointB);

virtual void load();
virtual void destroy();
Expand Down
4 changes: 4 additions & 0 deletions engine/core/util/JoltPhysicsAux.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "Jolt/Physics/Collision/Shape/SphereShape.h"
#include "Jolt/Physics/Body/BodyCreationSettings.h"
#include "Jolt/Physics/Body/BodyActivationListener.h"
#include "Jolt/Physics/Collision/GroupFilterTable.h"

#include "Jolt/Physics/Constraints/FixedConstraint.h"
#include "Jolt/Physics/Constraints/DistanceConstraint.h"
Expand All @@ -28,6 +29,9 @@
#include "Jolt/Physics/Constraints/SixDOFConstraint.h"
#include "Jolt/Physics/Constraints/PathConstraint.h"
#include "Jolt/Physics/Constraints/PathConstraintPathHermite.h"
#include "Jolt/Physics/Constraints/GearConstraint.h"
#include "Jolt/Physics/Constraints/RackAndPinionConstraint.h"
#include "Jolt/Physics/Constraints/PulleyConstraint.h"


// Based on: https://github.com/jrouwe/JoltPhysics/blob/master/HelloWorld/HelloWorld.cpp
Expand Down

0 comments on commit ba66785

Please sign in to comment.