예제 #1
0
        /// <summary>
        /// Checks a ray against a circle with a given origin and square radius.
        /// </summary>
        internal static bool CircleRayCast(
      VoltShape shape,
      Vector2 shapeOrigin,
      float sqrRadius,
      ref VoltRayCast ray,
      ref VoltRayResult result)
        {
            Vector2 toOrigin = shapeOrigin - ray.origin;

              if (toOrigin.sqrMagnitude < sqrRadius)
              {
            result.SetContained(shape);
            return true;
              }

              float slope = Vector2.Dot(toOrigin, ray.direction);
              if (slope < 0)
            return false;

              float sqrSlope = slope * slope;
              float d = sqrRadius + sqrSlope - Vector2.Dot(toOrigin, toOrigin);
              if (d < 0)
            return false;

              float dist = slope - Mathf.Sqrt(d);
              if (dist < 0 || dist > ray.distance)
            return false;

              // N.B.: For historical raycasts this normal will be wrong!
              // Must be either transformed back to world or invalidated later.
              Vector2 normal = (dist * ray.direction - toOrigin).normalized;
              result.Set(shape, dist, normal);
              return true;
        }
예제 #2
0
 private VoltBody CreateBody(
     bool isStatic,
     Common.Core.Numerics.Vector2 originWS,
     float rotation,
     VoltShape shape)
 {
     if (isStatic)
     {
         return(this._world.CreateStaticBody(ToVolt(originWS), rotation, new VoltShape[] { shape }));
     }
     else
     {
         return(this._world.CreateDynamicBody(ToVolt(originWS), rotation, new VoltShape[] { shape }));
     }
 }
예제 #3
0
        /// <summary>
        /// Creates a manifold for two shapes if they collide.
        /// </summary>
        private void NarrowPhase(
      VoltShape sa,
      VoltShape sb)
        {
            if (sa.AABB.Intersect(sb.AABB) == false)
            return;

              VoltShape.OrderShapes(ref sa, ref sb);
              Manifold manifold = Collision.Dispatch(this, sa, sb);
              if (manifold != null)
            this.manifolds.Add(manifold);
        }
예제 #4
0
        internal void FreeShape(VoltShape shape)
        {
            switch (shape.Type)
              {
            case VoltShape.ShapeType.Circle:
              this.circlePool.Deallocate(shape);
              break;

            case VoltShape.ShapeType.Polygon:
              this.polygonPool.Deallocate(shape);
              break;

            default:
              VoltDebug.LogError("Unknown shape for deallocation");
              break;
              }
        }
예제 #5
0
   internal void Set(
 VoltShape shape,
 float distance,
 Vector2 normal)
   {
       if (this.IsValid == false || distance < this.distance)
         {
       this.shape = shape;
       this.distance = distance;
       this.normal = normal;
         }
   }
예제 #6
0
 internal void Reset()
 {
     this.shape = null;
 }
예제 #7
0
 internal void SetContained(VoltShape shape)
 {
     this.shape = shape;
       this.distance = 0.0f;
       this.normal = Vector2.zero;
 }
예제 #8
0
   internal static Manifold Dispatch(
 VoltWorld world,
 VoltShape sa, 
 VoltShape sb)
   {
       Test test = Collision.tests[(int)sa.Type, (int)sb.Type];
         return test(world, sa, sb);
   }
예제 #9
0
   private static Manifold __Polygon_Polygon(
 VoltWorld world,
 VoltShape sa, 
 VoltShape sb)
   {
       return Polygon_Polygon(world, (VoltPolygon)sa, (VoltPolygon)sb);
   }
예제 #10
0
   private static Manifold __Polygon_Circle(
 VoltWorld world,
 VoltShape sa, 
 VoltShape sb)
   {
       return Circle_Polygon(world, (VoltCircle)sb, (VoltPolygon)sa);
   }
예제 #11
0
   private static Manifold __Circle_Circle(
 VoltWorld world,
 VoltShape sa, 
 VoltShape sb)
   {
       return Circle_Circle(world, (VoltCircle)sa, (VoltCircle)sb);
   }
예제 #12
0
        /// <summary>
        /// Workhorse for circle-circle collisions, compares origin distance
        /// to the sum of the two circles' radii, returns a Manifold.
        /// </summary>
        /// 
        private static Manifold TestCircles(
      VoltWorld world,
      VoltCircle shapeA,
      VoltShape shapeB,
      Vector2 overrideBCenter, // For testing vertices in circles
      float overrideBRadius)
        {
            Vector2 r = overrideBCenter - shapeA.worldSpaceOrigin;
              float min = shapeA.radius + overrideBRadius;
              float distSq = r.sqrMagnitude;

              if (distSq >= min * min)
            return null;

              float dist = Mathf.Sqrt(distSq);
              float distInv = 1.0f / dist;

              Vector2 pos =
            shapeA.worldSpaceOrigin +
            (0.5f + distInv * (shapeA.radius - min / 2.0f)) * r;

              // Build the collision Manifold
              Manifold manifold =
            world.AllocateManifold().Assign(world, shapeA, shapeB);
              manifold.AddContact(pos, distInv * r, dist - min);
              return manifold;
        }