Giter Club home page Giter Club logo

impulseengine's People

Contributors

randygaul avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

impulseengine's Issues

order of selection of vertices and order of calculating face normal in CircleToPolygon() do not match

in Shape.h

void SetBox( real hw, real hh )
  {
    m_vertexCount = 4;
    m_vertices[0].Set( -hw, -hh );
    m_vertices[1].Set(  hw, -hh );
    m_vertices[2].Set(  hw,  hh );
    m_vertices[3].Set( -hw,  hh );
    m_normals[0].Set(  0.0f,  -1.0f );
    m_normals[1].Set(  1.0f,   0.0f );
    m_normals[2].Set(  0.0f,   1.0f );
    m_normals[3].Set( -1.0f,   0.0f );
  }
    for (;;)
    {
      hull[outCount] = indexHull;

      // Search for next index that wraps around the hull
      // by computing cross products to find the most counter-clockwise
      // vertex in the set, given the previos hull index
      int32 nextHullIndex = 0;
      for(int32 i = 1; i < (int32)count; ++i)
      {
        // Skip if same coordinate as we need three unique
        // points in the set to perform a cross product
        if(nextHullIndex == indexHull)
        {
          nextHullIndex = i;
          continue;
        }

        // Cross every set of three unique vertices
        // Record each counter clockwise third vertex and add
        // to the output hull
        // See : http://www.oocities.org/pcgpe/math2d.html
        Vec2 e1 = vertices[nextHullIndex] - vertices[hull[outCount]];
        Vec2 e2 = vertices[i] - vertices[hull[outCount]];
        real c = Cross( e1, e2 );
        if(c > 0.0f)
          nextHullIndex = i;

        // Cross product is zero then e vectors are on same line
        // therefor want to record vertex farthest along that line
        if(c == 0.0f && e2.LenSqr( ) > e1.LenSqr( ))
          nextHullIndex = i;
      }
      
      ++outCount;
      indexHull = nextHullIndex;

      // Conclude algorithm upon wrap-around
      if(nextHullIndex == rightMost)
      {
        m_vertexCount = outCount;
        break;
      }
    }

    // Copy vertices into shape's vertices
    for(uint32 i = 0; i < m_vertexCount; ++i)
      m_vertices[i] = vertices[hull[i]];

    // Compute face normals
    for(uint32 i1 = 0; i1 < m_vertexCount; ++i1)
    {
      uint32 i2 = i1 + 1 < m_vertexCount ? i1 + 1 : 0;
      Vec2 face = m_vertices[i2] - m_vertices[i1];

      // Ensure no zero-length edges, because that's bad
      assert( face.LenSqr( ) > EPSILON * EPSILON );

      // Calculate normal with 2D cross product between vector and scalar
      m_normals[i1] = Vec2( face.y, -face.x );
      m_normals[i1].Normalize( );
    }
  }

in Collision.cpp

void CircletoPolygon( Manifold *m, Body *a, Body *b )
{
  Circle *A       = reinterpret_cast<Circle *>      (a->shape);
  PolygonShape *B = reinterpret_cast<PolygonShape *>(b->shape);

  m->contact_count = 0;

  // Transform circle center to Polygon model space
  Vec2 center = a->position;
  center = B->u.Transpose( ) * (center - b->position);

  // Find edge with minimum penetration
  // Exact concept as using support points in Polygon vs Polygon
  real separation = -FLT_MAX;
  uint32 faceNormal = 0;
  for(uint32 i = 0; i < B->m_vertexCount; ++i)
  {
    real s = Dot( B->m_normals[i], center - B->m_vertices[i] );

    if(s > A->radius)
      return;

    if(s > separation)
    {
      separation = s;
      faceNormal = i;
    }
  }

  // Grab face's vertices
  Vec2 v1 = B->m_vertices[faceNormal];
  uint32 i2 = faceNormal + 1 < B->m_vertexCount ? faceNormal + 1 : 0;
  Vec2 v2 = B->m_vertices[i2];

  // Check to see if center is within polygon
  if(separation < EPSILON)
  {
    m->contact_count = 1;
    m->normal = -(B->u * B->m_normals[faceNormal]);
    m->contacts[0] = m->normal * A->radius + a->position;
    m->penetration = A->radius;
    return;
  }

  // Determine which voronoi region of the edge center of circle lies within
  real dot1 = Dot( center - v1, v2 - v1 );
  real dot2 = Dot( center - v2, v1 - v2 );
  m->penetration = A->radius - separation;

  // Closest to v1
  if(dot1 <= 0.0f)
  {
    if(DistSqr( center, v1 ) > A->radius * A->radius)
      return;

    m->contact_count = 1;
    Vec2 n = v1 - center;
    n = B->u * n;
    n.Normalize( );
    m->normal = n;
    v1 = B->u * v1 + b->position;
    m->contacts[0] = v1;
  }

  // Closest to v2
  else if(dot2 <= 0.0f)
  {
    if(DistSqr( center, v2 ) > A->radius * A->radius)
      return;

    m->contact_count = 1;
    Vec2 n = v2 - center;
    v2 = B->u * v2 + b->position;
    m->contacts[0] = v2;
    n = B->u * n;
    n.Normalize( );
    m->normal = n;
  }

  // Closest to face
  else
  {
    Vec2 n = B->m_normals[faceNormal];
    if(Dot( center - v1, n ) > A->radius)
      return;

    n = B->u * n;
    m->normal = -n;
    m->contacts[0] = m->normal * A->radius + a->position;
    m->contact_count = 1;
  }
}

The order of finding the vertices in void Set() in Shape.h is anti-clockwise. in void SetBox() as well the order in which the vertices of the rectangle are declared and the normals are calculated is anti-clockwise, but in Collision.cpp, when visualizing the function CircleToPolygon(), it works only when the vertices are arranged in a clockwise manner. I changed the order in which the vertices are declared in SetBox() but that broke the program. can you please explain why this is happening?

Circle friction not working as intended? Circle never gets any slower.

I'm currently stuck with friction and wanted to check out this repo to see how it works. It seems though that circles never stop. I tried to debug it and it seems that friction attempts to slow the circle down but it always gets overshadowed by other forces making it faster. So even when colliding with the flat ground the circle will wander off. I tried cranking up dynamic and static friction but that also didnt help. Am I missing something?

P.S. Thank you for your great tutorial series.

Wrong friction calculation?

In Manifold.cpp, friction is initialized like this

sf = std::sqrt( A->staticFriction * A->staticFriction );
df = std::sqrt( A->dynamicFriction * A->dynamicFriction );

shouldn't it be

sf = std::sqrt( A->staticFriction * B->staticFriction );
df = std::sqrt( A->dynamicFriction * B->dynamicFriction );

?

Square inside polygon results in no collision because of BiasGreaterThan.

I'm finding that the BiasGreaterThan function results in cases where a square can get stuck in a polygon at certain positions. This seems to be because the wrong reference/incidence face gets picked. It appears to be fixed by simply changing BiasGreaterThan to a naive

inline bool BiasGreaterThan( real a, real b )
{
  return a >= b;
}

Or doing what box2d does also works i.e.

...
const float k_tol = 0.1f * b2_linearSlop; 
if (separationB > separationA + k_tol)
...

This can happen if you spawn a square inside a polygon (with gravity off so the square doesn't move).

Here is an example case, but it's pretty noticeable if you spawn a square inside of any random convex polygon of appropriate size.

PolygonShape poly;
    Vec2 vertices[] = {Vec2(-0.5, -0.5), Vec2(0.5,-0.5), Vec2(0.5, 0.5), Vec2(-0.5,0.5)};
    poly.Set( vertices, 4 );
    Body *b1 = new Body(&poly,-1.6,0);
    b1->SetOrient(0);
    
    PolygonShape poly2;
    Vec2 vertices2[] = {Vec2( -3.740512982560686,  -0.5735584769983424), Vec2( -3.719614114679503,  -1.7226350555144725), Vec2( -2.4932647260279026,  -2.7316117009988794), Vec2( -0.8201915887684166,  -3.339520273224558), Vec2( 0.8485318324075104,  -3.768661315482074), Vec2( 1.4125001862587832,  -3.877552867283213), Vec2( 3.7734708786741002,  -2.3132118400651835), Vec2( 3.9056625143223886,  -2.053720640728945), Vec2( 3.9608941922040817,  -0.21303954202834152), Vec2( 3.4524715186551624,  1.0169073997947553), Vec2( 1.9124525889738742,  2.634607801080719), Vec2( 0.24731544222635193,  3.825379925658064), Vec2( -1.1199503300054676,  4.6035871781070306), Vec2( -3.0722506887204464,  2.6117852157357326)};
    poly2.Set( vertices2, 14);
    Body *b2 = new Body(&poly2,0,0);
    
    b2->SetOrient(0);

PolygontoPolygon(b2, b1); Will return false even though they do clearly intersect.
PolygontoPolygon(b1, b2); Will return true however.

But with the fixes mentioned above they both will return true.

Multiple Contact Point Bug

Hey,

There is are issues in the Manifold Resolution portion when there are two contact points in the collision.

For one, an impulse is applied to the Body after the first contact point is processed and then the velocity and angularVelocity are used in the for loop for the next contact point but those values have already been modified.

Secondly the impulse algorithm doesn't work correctly when two contact points are made. Box2D seems to have some sort of Box Solver algorithm to handle this. For example, send a rectangle at a larger rectangle with infinite mass and the moving rectangle will not bounce correctly. It will start to rotate when it shouldn't and more often than not get stuck. The impulses of the two points need to be combined somehow and not applied separately.

About Compilation on Windows

Hi. Unfortunately, I am stuck on compiling the project. I am using VS 2019 and eventually getting this problem. Any ideas for opening the project in VS 2019 ?

image

Repeat simulation with different dt

If a simulation (using forces) is repeated with a lower deltatime (for example 1/120 instead of 1/60), the resulting state will be different even after the 1/120-simulation processed twice as many frames

Is it possible to repeat a simulation with a different framerate and come up with the same result?

I think setting the force to 0 after it has been applied causes the differences, maybe it should be lowered depending on dt? Or the force has to be applied without using dt?

b->force.Set( 0, 0 );

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.