Customise Consent Preferences

We use cookies to help you navigate efficiently and perform certain functions. You will find detailed information about all cookies under each consent category below.

The cookies that are categorised as "Necessary" are stored on your browser as they are essential for enabling the basic functionalities of the site. ... 

Always Active

Necessary cookies are required to enable the basic features of this site, such as providing secure log-in or adjusting your consent preferences. These cookies do not store any personally identifiable data.

No cookies to display.

Functional cookies help perform certain functionalities like sharing the content of the website on social media platforms, collecting feedback, and other third-party features.

No cookies to display.

Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc.

No cookies to display.

Performance cookies are used to understand and analyse the key performance indexes of the website which helps in delivering a better user experience for the visitors.

No cookies to display.

Advertisement cookies are used to provide visitors with customised advertisements based on the pages you visited previously and to analyse the effectiveness of the ad campaigns.

No cookies to display.

[ad_1]

I’m trying to make cut up axis theorem for 2nd collision physics. It does works, however is inaccurate. It’s primarily based off of: https://www.gamedev.web/tutorials/programming/math-and-physics/a-verlet-based-approach-for-2nd-game-physics-r2714/

A video for reference: https://www.youtube.com/watch?v=edSN3_Xkkls

Right here is the physics class:

class Physics {
int pointCount = 0;
Level* vertices[MAX_VERTICES];
int edgeCount = 0;
Edge* edges[MAX_EDGES];
PhysicsBody* PhysicsBodies[MAX_BODIES];
int bodyCount = 0;

float timestep = 1.0;
// The 'Depth' is the size of the vector, the 'Regular' is the course of the vector mentioned above. 
struct {
    float Depth;
    sf::Vector2f Regular;

    Edge* E;
    Level* V;
} CollisionInfo;
public:

void Replace();
void UpdateForces();
void updateVerlet();
void updateEdges();
void ProcessCollision();
void IterateCollisions();
void renderPoints(sf::RenderWindow& window);
void MakeShape(std::vector<sf::Vector2f> factors, bool anchored);
bool DetectCollision(PhysicsBody* B1, PhysicsBody* B2);
float IntervalDistance(float MinA, float MaxA, float MinB, float MaxB);
};

Right here is the purpose class:

struct Level {
sf::Vector2f Place;
sf::Vector2f OldPosition;
sf::Vector2f Acceleration;
};

Right here is the sting class:

struct Edge {
Level* v1;
Level* v2;

float OriginalLength; // The size of the sting when it was created

PhysicsBody* Guardian; // The physics physique that it belongs to
};

Right here is the detect collision perform:

bool Physics::DetectCollision(PhysicsBody* B1, PhysicsBody* B2) {

float MinDistance = 10000.0f;
// Iterates via all edges of each our bodies directly
for (int i = 0; i < B1->EdgeCount + B2->EdgeCount; i++) {
    Edge* E;
    if (i < B1->EdgeCount) {
        E = B1->edges[i];
        E->v1 = B1->edges[i]->v1;
        E->v2 = B1->edges[i]->v2;
    }
    else {
        E = B2->edges[i - B1->EdgeCount];
    }

    // Calculate the axis perpendicular to this edge and normalize
    //printPosition(E->v1->Place.x, E->v1->Place.y);
    //printPosition(E->v2->Place.x, E->v2->Place.y);
    sf::Vector2f Axis(E->v1->Place.y - E->v2->Place.y, E->v2->Place.x - E->v1->Place.y);
    float AxisN = Normalize(Axis);
    
    float MinA, MinB, MaxA, MaxB;
    B1->ProjectToAxis(Axis, MinA, MaxA);
    B2->ProjectToAxis(Axis, MinB, MaxB);

    float Distance = IntervalDistance(MinA, MaxA, MinB, MaxB);

    if (Distance > 0.0f) {
        return false; //If the intervals do not overlap, return false, since there is no such thing as a collision
    }
    // If the intervals overlap, test, whether or not the vector size on this
    //edge is smaller than the smallest size that has been reported to date
    else if (abs(Distance) < MinDistance) {
        MinDistance = abs(Distance);

        CollisionInfo.Regular = Axis; //Save collision data for later
        CollisionInfo.E = E; //Retailer the sting, as it's the collision edge
    }
}

CollisionInfo.Depth = MinDistance;

// Be certain that the physique containing the collision edge lies in
//B2 and the one containing the collision vertex in B1
// would not have an edge set to it 
if (CollisionInfo.E->Guardian != B2) {
    PhysicsBody* Temp = B2;
    B2 = B1;
    B1 = Temp;
}

//That is wanted to make it possible for the collision regular is pointing at B1
int Signal = SGN(CollisionInfo.Regular.x * (B1->Heart.x - B2->Heart.x));

//Do not forget that the road equation is N*( R - R0 ). We select B2->Heart
//as R0; the traditional N is given by the collision regular

if (Signal != 1)
    CollisionInfo.Regular = -CollisionInfo.Regular; //Revert the collision regular if it factors away from B1


float SmallestD = 100000.0f; //Initialize the smallest distance to a excessive worth
for (int I = 0; I < B1->VertexCount; I++) {
    //Measure the space of the vertex from the road utilizing the road equation
    float Distance = distanceBetweenPoints(CollisionInfo.Regular, (B1->vertices[I]->Place - B2->Heart));
    //If the measured distance is smaller than the smallest distance reported
    //to date, set the smallest distance and the collision vertex
    if (Distance < SmallestD) {
        SmallestD = Distance;
        CollisionInfo.V = B1->vertices[I];
    }
}

return true; //There isn't any separating axis. Report a collision!
}

I attempted altering the Min = std::min(DotP, Min); & Min = std::min(DotP, Min); to Min = FLT_MAX, Max = FLT_MIN; however this solely made the issue worse.

Right here is the venture to axis perform:

void PhysicsBody::ProjectToAxis(sf::Vector2f& Axis, float& Min, float& Max) {

float DotP = dotProduct(Axis, vertices[0]->Place);
// set min and max to the venture of the primary vertex
Min = Max = DotP;

for (int i = 1; i < VertexCount; i++) {
    // Mission the remainder of the vertices onto the axis and lengthen
    // The interval to left and proper if obligatory
    float DotP = dotProduct(Axis, vertices[1]->Place);

    //Min = FLT_MAX, Max = FLT_MIN;

    Min = std::min(DotP, Min);
    Max = std::max(DotP, Max);
}
/*
As you may see, projection in 2D is just a dot product of the projection axis and the purpose we wish to venture.
*/
}

Right here is the SGN perform:

inline bool SGN(float x) {
if (x > 0) return 1;
if (x < 0) return -1;
return 0;
}

[ad_2]

Leave a Reply

Your email address will not be published. Required fields are marked *