Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

lukabratzi

Member Since 04 Feb 2011
Offline Last Active May 13 2013 03:06 PM
-----

Posts I've Made

In Topic: Collision resolution between multiple AABB objects

04 February 2013 - 12:27 PM

In the first loop you clear the velocity change when you first encounter a sprite, but it may have already been in a collision by that point.

For example if the first rectangle hits the second, the second will receive a velocity change, which will be cleared before it is applied.

You may also need to run through the whole list multiple times to resolve all intersections.

Good god, I feel ridiculously foolish for missing that.  I'll test that out later today and see if it fixes it, but it would explain a lot.  Sometimes its the simple things I guess.

 

I had tried running through the process multiple times and that lessened the problem.  Is this an actual approach that some physics engines take?  It seems so inefficient.


In Topic: Collision resolution between multiple AABB objects

04 February 2013 - 11:38 AM

if(aPhysicsComponent->m_mass > 0 && bPhysicsComponent->m_mass > 0)
{
Vector2D impulse = hitNormalA;
float restitutionCoefficient = -0.5f;

impulse *= (-(1.0f + restitutionCoefficient));
impulse /= (1/spriteAMass + 1/spriteBMass);

aPhysicsComponent->m_velocityChangesToApply += (hitNormalA);
bPhysicsComponent->m_velocityChangesToApply += (hitNormalB);
}

 

 

Would this work?

 

    aPhysicsComponent->m_velocityChangesToApply += (hitNormalA) * impulse / spriteAMass;
    bPhysicsComponent->m_velocityChangesToApply += (hitNormalB* impulse / spriteBMass;

Well both hitNormalA/B and impulse are both vectors.  Ideally impulse should be some force and direction applied on collision to both objects for a bounce effect, but I'm not even using that right now.  currently I'm just trying to move the objects apart by the penetration amount (hitNormalA = hitNormal * penetrationDepth) to separate them.

 

What's happening is that my method breaks when any one object is colliding with more than one other object.  I think that the middle object is being acted upon by both sides and can't resolve either collision as its always blocked by one of the other two objects.

 

So that makes me think that it may not necessarily be a problem with my collision resolution code but is instead more of a fundamental, conceptual problem with how I'm conducting my collision tests?


In Topic: SSE Branching Question

07 April 2012 - 05:18 PM

That line is a comment. It's just explaining what the branchless code is up to.

A branch means moving the program counter forwards (beyond the next instruction, typically) or backwards. There's no branching going on. _mm_cmplt_ps is an instruction that can be viewed as taking two inputs and generating a single output. Once that instruction has finished, the program counter advances to the next instruction. No branch.

The same holds for the other instructions/intrinsics used in the example.

Here's the same algorithm for scalar variables in regular C:

const unsigned choice_masks[2] = { 0, (unsigned)-1 };

unsigned mask = choice_masks[lhs < rhs];
unsigned result = (mask & option1) | ((~mask) & option2); // assuming option1 and option2 are also of type unsigned

No conditionals, no branching.

Fantastic, that really clears things up for me and will let me eliminate a lot of gross bit manipulations I had to do. Thanks for clearing this up for me guys!

In Topic: SSE Branching Question

07 April 2012 - 04:03 PM

There are a number of SSE instructions that generate bit masks (all ones or all zeros) depending on the result of a comparison. These masks are then used to choose between two options.

An example using intrinsics:

// result = (lhs < rhs) ? option1 : option2;
__m128 mask = _mm_cmplt_ps(lhs, rhs);
__m128 result = _mm_or_ps(_mm_and_ps(mask, option1), _mm_andnot_ps(mask, option2));

Right, I saw that. But here's what concerns me:
// result = (lhs < rhs) ? option 1 : option2

How is that not a branch? Does SSE do some special bit algorithm? Otherwise I can't see how that's not the same as:

if ( lhs < rhs )
result = option1
else
result = option 2

PARTNERS