예제 #1
0
        bool IRaySegmentsCollidable.TryGetRayCollision(Body thisBody, Body raysBody, RaySegmentsShape raySegments, out RaySegmentIntersectionInfo info)
        {
            bool intersects = false;

            RaySegment[] segments = raySegments.Segments;
            Scalar[]     result   = new Scalar[segments.Length];
            Scalar       temp;

            Vector2D[][] polygons = this.Polygons;
            for (int index = 0; index < segments.Length; ++index)
            {
                result[index] = -1;
            }
            Matrix2x3 matrix = raysBody.Matrices.ToBody * thisBody.Matrices.ToWorld;

            for (int polyIndex = 0; polyIndex < polygons.Length; ++polyIndex)
            {
                Vector2D[] unTrans = polygons[polyIndex];
                Vector2D[] polygon = new Vector2D[unTrans.Length];
                for (int index = 0; index < unTrans.Length; ++index)
                {
                    Vector2D.Transform(ref matrix, ref unTrans[index], out polygon[index]);
                }
                BoundingRectangle rect;
                BoundingRectangle.FromVectors(polygon, out rect);
                BoundingPolygon poly = new BoundingPolygon(polygon);
                for (int index = 0; index < segments.Length; ++index)
                {
                    RaySegment segment = segments[index];
                    rect.Intersects(ref segment.RayInstance, out temp);
                    if (temp >= 0 && temp <= segment.Length)
                    {
                        poly.Intersects(ref segment.RayInstance, out temp);
                        if (temp >= 0 && temp <= segment.Length)
                        {
                            if (result[index] == -1 || temp < result[index])
                            {
                                result[index] = temp;
                            }
                            intersects = true;
                        }
                    }
                }
            }
            if (intersects)
            {
                info = new RaySegmentIntersectionInfo(result);
            }
            else
            {
                info = null;
            }
            return(intersects);
        }
예제 #2
0
        bool IRaySegmentsCollidable.TryGetRayCollision(Body thisBody, Body raysBody, RaySegmentsShape raySegments, out RaySegmentIntersectionInfo info)
        {
            bool intersects = false;

            RaySegment[]   segments = raySegments.Segments;
            Scalar[]       result   = new Scalar[segments.Length];
            BoundingCircle bounding = new BoundingCircle(Vector2D.Zero, this.radius);
            Matrix2x3      vertexM  = thisBody.Matrices.ToBody * raysBody.Matrices.ToWorld;

            for (int index = 0; index < segments.Length; ++index)
            {
                RaySegment segment = segments[index];
                Ray        ray2;

                Vector2D.Transform(ref vertexM, ref segment.RayInstance.Origin, out ray2.Origin);
                Vector2D.TransformNormal(ref vertexM, ref segment.RayInstance.Direction, out ray2.Direction);

                Scalar temp;
                bounding.Intersects(ref ray2, out temp);
                if (temp >= 0 && temp <= segment.Length)
                {
                    intersects    = true;
                    result[index] = temp;
                    continue;
                }
                else
                {
                    result[index] = -1;
                }
            }
            if (intersects)
            {
                info = new RaySegmentIntersectionInfo(result);
            }
            else
            {
                info = null;
            }
            return(intersects);
        }
예제 #3
0
 public static RaySegmentsShape CreateRays(RaySegment[] raySegments)
 {
     RaySegmentsShape rayShape = new RaySegmentsShape(raySegments);
     rayShape.Tag = new RaysSegmentsDrawable(rayShape);
     return rayShape;
 }
예제 #4
0
        public static DisposeCallback BasicDemoSetup(DemoOpenInfo info)
        {
            DisposeCallback dispose = null;
            IShape bombShape = ShapeFactory.CreateSprite(Cache<SurfacePolygons>.GetItem("rocket.png"), 2, 16, 3);
            dispose += DemoHelper.RegisterBombLaunching(info, bombShape, 120);
            dispose += DemoHelper.RegisterMousePicking(info);

            dispose += DemoHelper.RegisterBodyStreamSpawning(info,
                new Body(new PhysicsState(), ParticleShape.Default, 1, Coefficients.Duplicate(), new Lifespan(.5f)), 2, 120, 1000, Key.B);
            dispose += DemoHelper.RegisterMaintainSpawning(info, SdlDotNet.Input.Key.N,
                delegate(Vector2D position)
                {
                    ExplosionLogic result = new ExplosionLogic(position, Vector2D.Zero, 9000, .1f, 600, new Lifespan(.25f));
                    info.Scene.Engine.AddLogic(result);
                    return result;
                });

            List<RaySegment> segments = new List<RaySegment>();

            for (Scalar angle = 0; angle < MathHelper.PiOver2; angle += .05f)
            {
                RaySegment seg = new RaySegment();
                seg.Length = 500;
                seg.RayInstance = new Ray(Vector2D.Zero, Vector2D.FromLengthAndAngle(1, angle));
                segments.Add(seg);
            }

            IShape rayShape = ShapeFactory.CreateRays(segments.ToArray());
            dispose += DemoHelper.RegisterMaintainSpawning(info, SdlDotNet.Input.Key.M,
                delegate(Vector2D position)
                {
                    Body lazer = new Body(new PhysicsState(), rayShape, 1, new Coefficients(1, 1), new Lifespan());
                    lazer.State.Position.Linear = position;
                    lazer.State.Velocity.Angular = .91f;
                    lazer.IgnoresGravity = true;
                    lazer.ApplyPosition();
                    info.Scene.AddGraphic(CreateGraphic(lazer));
                    return lazer;
                });





            return dispose;
        }
예제 #5
0
        public void CalcBoundingRectangle(ref Matrix2x3 matrix, out BoundingRectangle rectangle)
        {
            Vector2D   v1, v2;
            RaySegment segment = segments[0];

            v1   = segment.RayInstance.Origin;
            v2.X = segment.RayInstance.Direction.X * segment.Length + v1.X;
            v2.Y = segment.RayInstance.Direction.Y * segment.Length + v1.Y;
            Vector2D.Transform(ref matrix, ref v1, out v1);
            Vector2D.Transform(ref matrix, ref v2, out v2);
            if (v1.X > v2.X)
            {
                rectangle.Min.X = v2.X;
                rectangle.Max.X = v1.X;
            }
            else
            {
                rectangle.Min.X = v1.X;
                rectangle.Max.X = v2.X;
            }
            if (v1.Y > v2.Y)
            {
                rectangle.Min.Y = v2.Y;
                rectangle.Max.Y = v1.Y;
            }
            else
            {
                rectangle.Min.Y = v1.Y;
                rectangle.Max.Y = v2.Y;
            }

            for (int index = 1; index < segments.Length; ++index)
            {
                segment = segments[index];
                v1      = segment.RayInstance.Origin;
                v2.X    = segment.RayInstance.Direction.X * segment.Length + v1.X;
                v2.Y    = segment.RayInstance.Direction.Y * segment.Length + v1.Y;
                Vector2D.Transform(ref matrix, ref v1, out v1);
                Vector2D.Transform(ref matrix, ref v2, out v2);
                if (v1.X > rectangle.Max.X)
                {
                    rectangle.Max.X = v1.X;
                }
                else if (v1.X < rectangle.Min.X)
                {
                    rectangle.Min.X = v1.X;
                }
                if (v1.Y > rectangle.Max.Y)
                {
                    rectangle.Max.Y = v1.Y;
                }
                else if (v1.Y < rectangle.Min.Y)
                {
                    rectangle.Min.Y = v1.Y;
                }

                if (v2.X > rectangle.Max.X)
                {
                    rectangle.Max.X = v2.X;
                }
                else if (v2.X < rectangle.Min.X)
                {
                    rectangle.Min.X = v2.X;
                }
                if (v2.Y > rectangle.Max.Y)
                {
                    rectangle.Max.Y = v2.Y;
                }
                else if (v2.Y < rectangle.Min.Y)
                {
                    rectangle.Min.Y = v2.Y;
                }
            }
        }
예제 #6
0
파일: Demo.cs 프로젝트: bsvercl/physics2d
        void AddRays()
        {
            List<RaySegment> segments = new List<RaySegment>();


            for (Scalar angle = 0; angle < MathHelper.PiOver2; angle += .05f)
            {
                RaySegment seg = new RaySegment();
                seg.Length = 500;
                seg.RayInstance = new Ray(Vector2D.Zero, Vector2D.FromLengthAndAngle(1, angle));
                segments.Add(seg);
            }

            lazer = new Body(new PhysicsState(), new RaySegmentsShape(segments.ToArray()), 1, new Coefficients(1, 1), new Lifespan());
            lazer.State.Position.Linear = sparkPoint;
            lazer.State.Velocity.Angular = .91f;
            lazer.IgnoresGravity = true;
            lazer.ApplyPosition();
            engine.AddBody(lazer);
            lazerLogic = new RaySegmentsCollisionLogic(lazer);
            engine.AddLogic(lazerLogic);
            lock (objects)
            {
                OpenGlObject o = new OpenGlObject(lazer, lazerLogic);
                lazer.Tag = o;
                objects.Add(o);
            }
        }
예제 #7
0
        /// <summary>
        /// Creates a shape to be used in the Physics Body. A physics shape is scaled to the
        /// size of the object. In addition, it has more vertices and some additional info
        /// that is used in collision detection.
        /// </summary>
        internal static IShape CreatePhysicsShape(Shape shape, Vector size, CollisionShapeParameters parameters)
        {
            if (shape is RaySegment)
            {
                RaySegment raySegment = (RaySegment)shape;
                Physics2DDotNet.Shapes.RaySegment singleSegment = new Physics2DDotNet.Shapes.RaySegment(
                    new Vector2D(raySegment.Origin.X, raySegment.Origin.Y),
                    new Vector2D(raySegment.Direction.X, raySegment.Direction.Y),
                    raySegment.Length);
                return(new RaySegmentsShape(singleSegment));
            }
            else if (shape is Ellipse)
            {
                Debug.Assert(shape.IsUnitSize);

                double smaller = Math.Min(size.X, size.Y);
                double bigger  = Math.Max(size.X, size.Y);
                // Average between width and height.
                double r           = smaller / 2 + (bigger - smaller) / 2;
                int    vertexCount = (int)Math.Ceiling((2 * Math.PI * r) / parameters.MaxVertexDistance);

                if (Math.Abs(size.X - size.Y) <= double.Epsilon)
                {
                    // We get more accurate results by using the circleshape.
                    // in addition, the circleshape does not need a DistanceGrid
                    // object (which is slow to initialize) because calculations
                    // for a circleshape are much simpler.
                    return(new CircleShape(r, vertexCount));
                }
                else
                {
                    Vector2D[] vertexes = new Vector2D[vertexCount];

                    double a = 0.5 * size.X;
                    double b = 0.5 * size.Y;

                    for (int i = 0; i < vertexCount; i++)
                    {
                        double t = (i * 2 * Math.PI) / vertexCount;
                        double x = a * Math.Cos(t);
                        double y = b * Math.Sin(t);
                        vertexes[i] = new Vector2D(x, y);
                    }

                    return(new PolygonShape(vertexes, parameters.DistanceGridSpacing));
                }
            }
            else
            {
                Vector2D[] originalVertexes = new Vector2D[shape.Cache.OutlineVertices.Length];
                for (int i = 0; i < shape.Cache.OutlineVertices.Length; i++)
                {
                    Vector v = shape.Cache.OutlineVertices[i];
                    if (shape.IsUnitSize)
                    {
                        v.X *= size.X;
                        v.Y *= size.Y;
                    }
                    originalVertexes[i] = new Vector2D(v.X, v.Y);
                }

                Vector2D[] polyVertexes = VertexHelper.Subdivide(originalVertexes, parameters.MaxVertexDistance);

                return(new PolygonShape(polyVertexes, parameters.DistanceGridSpacing));
            }
        }