Esempio n. 1
0
        public static bool Intersects(ref Circle a, ref RectangleF b, out float depth, out Vector2 normal)
        {
            normal = new Vector2(a.Center.X - (b.X + b.Width / 2), a.Center.Y - (b.Y + b.Height / 2));
#if NETSTANDARD2_1
            Vector2 distance = new Vector2(MathF.Abs(normal.X), MathF.Abs(normal.Y));
#else
            Vector2 distance = new Vector2(Math.Abs(normal.X), Math.Abs(normal.Y));
#endif
            normal = Vector2.Normalize(normal);
            depth  = distance.Length();
            if (float.IsNaN(depth))
            {
                normal = new Vector2(0, 0);
                depth  = 0f;
                return(false);
            }
            if (distance.X > b.Width / 2 + a.Radius / 2 || distance.Y > b.Height / 2 + a.Radius / 2)
            {
                return(false);
            }
            if (distance.X <= b.Width / 2 || distance.Y <= b.Height / 2)
            {
                return(true);
            }

#if NETSTANDARD2_1
            float distanceSq = MathF.Pow(distance.X - b.Width / 2, 2) + MathF.Pow(distance.Y - b.Height / 2, 2);
            return(distanceSq <= MathF.Pow(a.Radius, 2));
#else
            double distanceSq = Math.Pow(distance.X - b.Width / 2, 2) + Math.Pow(distance.Y - b.Height / 2, 2);
            return(distanceSq <= Math.Pow(a.Radius, 2));
#endif
        }
Esempio n. 2
0
        void RenderVerts(System.Numerics.Vector2 position, System.Numerics.Vector2 lightPos, System.Numerics.Vector2[] verts)
        {
            // TODO: should we check to see if the light is inside the verts and early out?
            for (var i = 0; i < verts.Length; i++)
            {
                var vertex       = verts[i] + position;
                var nextVertex   = verts[(i + 1) % verts.Length] + position;
                var startToEnd   = nextVertex - vertex;
                var lightToStart = lightPos - vertex;
                var normal       = new System.Numerics.Vector2(startToEnd.Y, -startToEnd.X);
                normal.Normalize();

                var nDotL = System.Numerics.Vector2.Dot(normal, lightToStart);
                if (nDotL > 0)
                {
                    var midpoint = (nextVertex + vertex) * 0.5f;
                    Debug.DrawLine(vertex, nextVertex, Color.Green);
                    Debug.DrawLine(midpoint, midpoint + normal * 20, Color.Green);

                    var point1 = nextVertex + (System.Numerics.Vector2.Normalize(nextVertex - lightPos) * Screen.Width);
                    var point2 = vertex + (System.Numerics.Vector2.Normalize(vertex - lightPos) * Screen.Width);

                    var poly = new System.Numerics.Vector2[] { nextVertex, point1, point2, vertex };
                    _vertBuffer[0] = nextVertex;
                    _vertBuffer[1] = point1;
                    _vertBuffer[2] = point2;
                    _vertBuffer[3] = vertex;
                    _primitiveBatch.DrawPolygon(poly, 4, Color.Black);
                }
            }
        }
Esempio n. 3
0
        public static float IncludedAngleCos(Vector2 v1, Vector2 v2)
        {
            v1.Normalize(); v2.Normalize();
            float dot = Vector2.Dot(v1, v2);

            return(2 * dot / (v1.Length() + v2.Length()));
        }
Esempio n. 4
0
        public override void OnFixedUpdate()
        {
            if (Owner.NetIdentity == null || !Owner.NetIdentity.IsOwner)
            {
                return;
            }
            if (PhysicsObject == null)
            {
                PhysicsObject = Owner.GetComponent <PhysicsObject>();
            }

            Vector2 velocity = Vector2.Zero;

            if (UIManager.IsKeyboardFree())
            {
                velocity.Y = InputManager.AxisState(PlayerIndex, "PlayerVertical") * 256;
                velocity.X = InputManager.AxisState(PlayerIndex, "PlayerHorizontal") * 256;
            }
            if (MathF.Abs(velocity.Y) > 128f && MathF.Abs(velocity.X) > 128f)
            {
                velocity  = Vector2.Normalize(velocity);
                velocity *= 256;
            }
            PhysicsObject.Body.LinearVelocity = velocity;
            base.OnUpdate();
        }
Esempio n. 5
0
        void IUpdatable.Update()
        {
            if (Math.Abs(_shakeIntensity) > 0f)
            {
                _shakeOffset = _shakeDirection;
                if (_shakeOffset.X != 0f || _shakeOffset.Y != 0f)
                {
                    _shakeOffset.Normalize();
                }
                else
                {
                    _shakeOffset.X = _shakeOffset.X + Random.NextFloat() - 0.5f;
                    _shakeOffset.Y = _shakeOffset.Y + Random.NextFloat() - 0.5f;
                }

                // TODO: this needs to be multiplied by camera zoom so that less shake gets applied when zoomed in
                _shakeOffset    *= _shakeIntensity;
                _shakeIntensity *= -_shakeDegredation;
                if (Math.Abs(_shakeIntensity) <= 0.01f)
                {
                    _shakeIntensity = 0f;
                    Enabled         = false;
                }
            }

            Entity.Scene.Camera.Position += _shakeOffset;
        }
Esempio n. 6
0
 protected override void OnUpdate()
 {
     timer -= Time.DeltaTime;
     if (timer < 0)
     {
         nodes = NavigationManager.NavGrids[0].FindPath(Owner.Transform.GlobalPositionInternal, Screen.MousePoint.HasValue ? Screen.MousePoint.Value : new Vector2(9999, 9999));
         timer = 0.333f;
     }
     if (nodes != null && nodes.Count > 0)
     {
         if (node == null || ((NavigationManager.NavGrids[0].GetPosition(node) - Owner.Transform.GlobalPositionInternal).Length() < 0.5f))
         {
             node = nodes.Pop();
         }
         if (node != null)
         {
             Vector2 diff = NavigationManager.NavGrids[0].GetPosition(node) - Owner.Transform.GlobalPositionInternal;
             lookAt = NavigationManager.NavGrids[0].GetPosition(node);
             diff   = Vector2.Normalize(diff);
             myPhysics.Body.LinearVelocity = diff * 192;
         }
     }
     Owner.Transform.Rotation = Owner.Transform.GlobalPositionInternal.GetRotationFacing(lookAt);
     base.OnUpdate();
 }
Esempio n. 7
0
        public void DrawArrow(System.Numerics.Vector2 start, System.Numerics.Vector2 end, float length, float width, bool drawStartIndicator, Color color)
        {
            // Draw connection segment between start- and end-point
            //drawLine( start, end, color );

            // Precalculate halfwidth
            var halfWidth = width / 2;

            // Create directional reference
            System.Numerics.Vector2 rotation = (start - end);
            rotation.Normalize();

            // Calculate angle of directional vector
            float angle = (float)Math.Atan2(rotation.X, -rotation.Y);

            // Create matrix for rotation
            Matrix2D rotMatrix = Matrix2D.CreateRotation(angle);

            // Create translation matrix for end-point
            Matrix2D endMatrix = Matrix2D.CreateTranslation(end.X, end.Y);

            // Setup arrow end shape
            System.Numerics.Vector2[] verts = new System.Numerics.Vector2[3];
            verts[0] = new System.Numerics.Vector2(0, 0);
            verts[1] = new System.Numerics.Vector2(-halfWidth, -length);
            verts[2] = new System.Numerics.Vector2(halfWidth, -length);

            // Rotate end shape
            Vector2Ext.Transform(verts, ref rotMatrix, verts);

            // Translate end shape
            Vector2Ext.Transform(verts, ref endMatrix, verts);

            // Draw arrow end shape
            DrawPolygon(verts, 3, color);

            if (drawStartIndicator)
            {
                // Create translation matrix for start
                Matrix2D startMatrix = Matrix2D.CreateTranslation(start.X, start.Y);

                // Setup arrow start shape
                System.Numerics.Vector2[] baseVerts = new System.Numerics.Vector2[4];
                baseVerts[0] = new System.Numerics.Vector2(-halfWidth, length / 4);
                baseVerts[1] = new System.Numerics.Vector2(halfWidth, length / 4);
                baseVerts[2] = new System.Numerics.Vector2(halfWidth, 0);
                baseVerts[3] = new System.Numerics.Vector2(-halfWidth, 0);

                // Rotate start shape
                Vector2Ext.Transform(baseVerts, ref rotMatrix, baseVerts);

                // Translate start shape
                Vector2Ext.Transform(baseVerts, ref startMatrix, baseVerts);

                // Draw start shape
                DrawPolygon(baseVerts, 4, color);
            }
        }
Esempio n. 8
0
        private static void _FillSegmentVertices(Span <POINT2> dst, POINT2 a, POINT2 b, float diameter)
        {
            var aa = a.XY;
            var bb = b.XY;

            var axisX = VECTOR2.Normalize(bb - aa) * diameter * 0.25f;
            var axisY = new VECTOR2(axisX.Y, -axisX.X);

            dst[0] = aa - axisY;
            dst[1] = aa + axisY;
            dst[2] = bb + axisY;
            dst[3] = bb - axisY;
        }
Esempio n. 9
0
        static bool FindMinimumTranslationDistance(int iNumAxes, out System.Numerics.Vector2 normal, out float timeOfIntersection)
        {
            // find collision first
            var mini = -1;

            timeOfIntersection = 0f;
            normal             = new System.Numerics.Vector2(0, 0);

            for (var i = 0; i < iNumAxes; i++)
            {
                if (_satTimerPerAxis[i] > 0 && _satTimerPerAxis[i] > timeOfIntersection)
                {
                    mini = i;
                    timeOfIntersection = _satTimerPerAxis[i];
                    normal             = _satAxisArray[i];
                    normal.Normalize();
                }
            }

            // found one
            if (mini != -1)
            {
                return(true);
            }

            // nope, find overlaps
            mini = -1;
            for (var i = 0; i < iNumAxes; i++)
            {
                var n = _satAxisArray[i].Length();
                _satAxisArray[i].Normalize();
                _satTimerPerAxis[i] /= n;

                if (_satTimerPerAxis[i] > timeOfIntersection || mini == -1)
                {
                    mini = i;
                    timeOfIntersection = _satTimerPerAxis[i];
                    normal             = _satAxisArray[i];
                }
            }

            if (mini == -1)
            {
                Debug.Error("Error");
            }

            return(mini != -1);
        }
Esempio n. 10
0
        public static bool Intersects(ref Circle a, ref Circle b, out float depth, out Vector2 normal)
        {
            Vector2 distance = a.Center - b.Center;

            depth = distance.Length();
            if (float.IsNaN(depth))
            {
                normal = new Vector2(0, 0);
                depth  = 0f;
                return(false);
            }
            float radiusSum = a.Radius > b.Radius ? b.Radius : a.Radius;

            normal = Vector2.Normalize(distance);
            return(depth <= radiusSum);
        }
Esempio n. 11
0
        public Prismatic()
        {
            Body ground;
            {
                var bd = new BodyDef();
                ground = World.CreateBody(bd);

                var shape = new EdgeShape();
                shape.Set(new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f));
                ground.CreateFixture(shape, 0.0f);
            }

            {
                var shape = new PolygonShape();
                shape.SetAsBox(2.0f, 0.5f);

                var bd = new BodyDef();
                bd.BodyType = BodyType.DynamicBody;
                bd.Position.Set(-10.0f, 10.0f);
                bd.Angle      = 0.5f * Settings.Pi;
                bd.AllowSleep = false;
                var body = World.CreateBody(bd);
                body.CreateFixture(shape, 5.0f);

                var pjd = new PrismaticJointDef();

                // Bouncy limit
                var axis = new Vector2(2.0f, 1.0f);

                axis = Vector2.Normalize(axis);
                pjd.Initialize(ground, body, new Vector2(0.0f, 0.0f), axis);

                // Non-bouncy limit
                //pjd.Initialize(ground, body, new Vector2(-10.0f, 10.0f), new Vector2(1.0f, 0.0f));

                pjd.MotorSpeed       = 10.0f;
                pjd.MaxMotorForce    = 10000.0f;
                pjd.EnableMotor      = true;
                pjd.LowerTranslation = 0.0f;
                pjd.UpperTranslation = 20.0f;
                pjd.EnableLimit      = true;

                _joint = (PrismaticJoint)World.CreateJoint(pjd);
            }
        }
Esempio n. 12
0
        public static void FillRectangleVertices(this Span <POINT2> vertices, XFORM2 rect, float borderRadius, int arcVertexCount = 6)
        {
            var scaleX = new VECTOR2(rect.M11, rect.M12);
            var scaleY = new VECTOR2(rect.M21, rect.M22);
            var origin = new VECTOR2(rect.M31, rect.M32);

            if (vertices.Length == 4)
            {
                vertices[0] = origin;
                vertices[1] = origin + scaleX;
                vertices[2] = origin + scaleX + scaleY;
                vertices[3] = origin + scaleY;
                return;
            }

            int idx = 0;

            var sizeX = scaleX.Length();
            var axisX = VECTOR2.Normalize(scaleX);
            var sizeY = scaleY.Length();
            var axisY = VECTOR2.Normalize(scaleY);

            throw new NotImplementedException();

            // top
            vertices[idx++] = origin + axisX * borderRadius;
            vertices[idx++] = origin + axisX * (sizeX - borderRadius);

            // top right
            var center = origin + axisX * (sizeX - borderRadius) + axisY * borderRadius;

            foreach (var p in _GetRectangleCornerVertices(arcVertexCount, PI * 0.5f, 0f))
            {
                vertices[idx++] = center + (axisX * p.X + axisY * p.Y) * borderRadius;
            }

            // right
            vertices[idx++] = origin + axisX * (sizeX - borderRadius);
            vertices[idx++] = origin + new POINT2(sizeX, sizeY - borderRadius);

            // bottom right
            center = origin + new VECTOR2(sizeX - borderRadius, sizeY - borderRadius);
            foreach (var p in _GetRectangleCornerVertices(arcVertexCount, 0, -PI * 0.5f))
            {
                vertices[idx++] = center + p * borderRadius;
            }

            // bottom
            vertices[idx++] = origin + new POINT2(sizeX - borderRadius, sizeY);
            vertices[idx++] = origin + new POINT2(borderRadius, sizeY);

            // bottom left
            center = origin + new VECTOR2(borderRadius, sizeY - borderRadius);
            foreach (var p in _GetRectangleCornerVertices(arcVertexCount, -PI * 0.5f, -PI))
            {
                vertices[idx++] = center + p * borderRadius;
            }

            // left
            vertices[idx++] = origin + new POINT2(0, sizeY - borderRadius);
            vertices[idx++] = origin + new POINT2(0, borderRadius);

            // top left
            center = origin + new VECTOR2(borderRadius, borderRadius);
            foreach (var p in _GetRectangleCornerVertices(arcVertexCount, -PI, -PI * 1.5f))
            {
                vertices[idx++] = center + p * borderRadius;
            }
        }
Esempio n. 13
0
 /// <summary>
 /// 朝向方向(入参为一个代表方向的向量)
 /// </summary>
 /// <param name="body"></param>
 /// <param name="targetPoint"></param>
 /// <param name="angularVelocityProc"></param>
 /// <returns></returns>
 public static float MoveForward(this Body body, Vector2 targetPoint, float angularVelocityProc)
 {
     targetPoint.Normalize();
     return(FowardToTarget(body, targetPoint + body.GetPosition(), angularVelocityProc));
 }
Esempio n. 14
0
        private void CreateOutline(IEnumerable <Vector2> shape, bool createFace)
        {
            Contract.Requires(shape != null);

            var vertices = (IReadOnlyList <Vertex>)shape.Select(_mesh.GetOrConstructVertex).ToArray();
            var edges    = new List <HalfEdge>(vertices.Count * 3);

            // Create the outer edges of the floor
            for (var i = 0; i < vertices.Count; i++)
            {
                //Start and end vertex of this wall
                var b = vertices[i];
                var c = vertices[(i + 1) % vertices.Count];

                //Create a series of edges between these two vertices (not just one edge, because we drop seeds along the line as we go)
                CreateImpassableEdge(b, c, edges);

                //We want to measure the internal angle at vertex "b", for that we need the previous vertex (which we'll call "a")
                var a = vertices[(i + vertices.Count - 1) % vertices.Count];

                //Calculate the inner angle between these vectors (not always clockwise!)
                var ab    = Vector2.Normalize(b.Position - a.Position);
                var bc    = Vector2.Normalize(c.Position - b.Position);
                var dot   = Vector2.Dot(bc, -ab);
                var det   = bc.Cross(-ab);
                var angle = (float)(Math.Atan2(det, dot) % (Math.PI * 2));
                angle = det < 0 ? angle * -1 : (float)Math.PI * 2 - angle;

                if (angle < Math.PI * 0.51)
                {
                    //0 -> 90 degrees
                    //Do nothing!
                }
                else if (angle <= Math.PI * 1.01)
                {
                    //90 -> 180
                    if (_random.RandomBoolean())
                    {
                        PerpendicularSeed(b, ab);
                    }
                    else
                    {
                        PerpendicularSeed(b, bc);
                    }
                }
                else if (angle <= Math.PI * 1.51)
                {
                    //180 -> 270
                    //if (_random.RandomBoolean())
                    //    BisectorSeed(b, -ab, -bc);  //Negated, to ensure bisection is on the correct side (angle is > 180, so by default bisection would be on wrong side)
                    //else
                    {
                        PerpendicularSeed(b, ab);
                        PerpendicularSeed(b, bc);
                    }
                }
                else
                {
                    //270 -> 360
                    //BisectorSeed(b, -ab, -bc);  //Negated, to ensure bisection is on the correct side (angle is > 180, so by default bisection would be on wrong side)
                    PerpendicularSeed(b, ab);
                    PerpendicularSeed(b, bc);
                }
            }

            if (createFace)
            {
                //Ensure we're always creating the clockwise face
                if (!edges.Select(a => a.EndVertex.Position).IsClockwise())
                {
                    edges.Reverse();
                    for (var i = 0; i < edges.Count; i++)
                    {
                        edges[i] = edges[i].Pair;
                    }
                }

                //Create face
                //todo: attach spacespec metadata (passed in instead of bool:createFace)
                var f = _mesh.GetOrConstructFace(edges);
                f.Tag = new FloorplanFaceTag(false);
            }
        }