c++ – 3D Impulse primarily based collision decision not behaving accurately, what may very well be mistaken?

c++ – 3D Impulse primarily based collision decision not behaving accurately, what may very well be mistaken?

[ad_1]

I’ve applied a collision decision system primarily based on Ian Mellingtons system Cyclone and afterwards primarily based on the GamePhysicsCookBook. Presently the final one is applied.

For some purpose the system behaves oddly. If I arrange a take a look at, the place the dice drops from a bit up the Y-axis and with 45degree rotation over the x axis it simply stays on that edge, then it begins shifting round weirdly. That final half is because of friction.

A video pattern right here

It is best to be capable of see the contactpoints and their regular (up the Y axis)

If I transfer the article and slam it right into a wall, it would find yourself rotating eternally.

It isn’t the dampening, since that works fantastic – apply a drive with out gravity as an illustration and all the things stops ultimately.

It isn’t the intertia tensor.

The contactnormal is pointing in the direction of “B”, which means that it must be detrimental for the article to be handled as “A”

The code is as follows:

whereas (currentiteration < 8) {
                for (int cidx = 0; cidx < contactDataFrame.dimension(); cidx++) {
                    //apply impulse, frictionless
                    {
                        GVECTOR relativeContactPoint = Math::VectorSubtract(contactDataFrame[cidx].contactpoint, mPhysicsOBJData[0].place);
                        GVECTOR closingVelocity = Math::VectorNegate(Math::VectorAdd(mPhysicsOBJData[0].velocity, Math::Vector3Cross(mPhysicsOBJData[0].rotation, relativeContactPoint)));

                        float dp = Math::Vector3Dot(closingVelocity, Math::VectorNegate(contactDataFrame[cidx].contactnormal)).m128_f32[0];

                        if (dp > 0.0f) {
                            proceed;
                        }

                        float numerator = (-(1.0f + restitution)) * dp;
                        
                        GMATRIX tensor = transformedTensors[0];; 
                        GVECTOR torque = Math::Vector3Cross(Math::Vec3MultiplyMatrixRHS(Math::Vector3Cross(relativeContactPoint, Math::VectorNegate(contactDataFrame[cidx].contactnormal)), tensor), relativeContactPoint);

                        float denominator = mPhysicsOBJData[0].inverseMass + Math::Vector3Dot(Math::VectorNegate(contactDataFrame[cidx].contactnormal), torque).m128_f32[0];
                        if (denominator == 0.0f) {
                            PRINT_N("ERROR - denominator J == 0");
                            proceed;
                        }

                        float j = numerator / denominator;
                        j /= contactDataFrame[cidx].contactcount;

                        GVECTOR impulse = Math::VecMultiplyScalar(Math::VectorNegate(contactDataFrame[cidx].contactnormal), j);
                
                        mPhysicsOBJData[0].velocity = Math::VectorSubtract(mPhysicsOBJData[0].velocity, Math::VecMultiplyScalar(impulse, mPhysicsOBJData[0].inverseMass));
                        mPhysicsOBJData[0].rotation = Math::VectorSubtract(mPhysicsOBJData[0].rotation, Math::Vec3MultiplyMatrixRHS(Math::Vector3Cross(relativeContactPoint, impulse), tensor));

                        GVECTOR tangentNormal = Math::VectorSubtract(closingVelocity, Math::VecMultiplyScalar(Math::VectorNegate(contactDataFrame[cidx].contactnormal), Math::Vector3Dot(closingVelocity, Math::VectorNegate(contactDataFrame[cidx].contactnormal)).m128_f32[0]));

                        if (sqrt(Math::Vector3Dot(tangentNormal, tangentNormal).m128_f32[0]) == 0.0f) {
                            PRINT_N("ERROR - NO TAGENT VECTOR");
                            proceed;
                        }
                        tangentNormal = Math::Vec3Normalize(tangentNormal);

                        numerator = -Math::Vector3Dot(closingVelocity, tangentNormal).m128_f32[0];
                        denominator = mPhysicsOBJData[0].inverseMass + Math::Vector3Dot(tangentNormal, Math::Vector3Cross(Math::Vec3MultiplyMatrixRHS(Math::Vector3Cross(relativeContactPoint, tangentNormal), tensor), relativeContactPoint)).m128_f32[0];
                        if (denominator == 0.0f) {
                            PRINT_N("ERROR - DENOMINATOR TANGET == 0");
                            proceed;
                        }
                        float jt = numerator / denominator;
                        jt /= contactDataFrame[cidx].contactcount;

                        if (jt == 0.0f) {
                            PRINT_N("ERROR - NO JT IMPULSE");
                            proceed;
                        }

                        float friction = 3.75f;
                        if (jt > j * friction) {
                            jt = j * friction;

                        }
                        else if (jt < -j * friction) {
                            jt = -j * friction;
                        }

                        GVECTOR tagentImpulse = Math::VecMultiplyScalar(tangentNormal, jt);
                        mPhysicsOBJData[0].velocity = Math::VectorSubtract(mPhysicsOBJData[0].velocity, tagentImpulse);
                        mPhysicsOBJData[0].rotation = Math::VectorSubtract(mPhysicsOBJData[0].rotation, Math::Vec3MultiplyMatrixRHS(Math::Vector3Cross(relativeContactPoint, tagentImpulse), tensor));
                    }
                }
                currentiteration++;
}

[ad_2]

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply