Beispiel #1
0
        public static Mesh2D Ball(float radius, P3 position, V3 velocity)
        {
            Mesh2D c = Mesh2D.Circle(radius, 16, position);

            c.Velocity = velocity;
            return(c);
        }
Beispiel #2
0
 void cache()
 {
     dirty = true;
     buildVertices();
     buildEdges();
     centerOfGravity       = P3.Average(vertices.ToArray());
     boundingRadiusSquared = centerOfGravity.SquaredDistanceTo(P3.Farthest(vertices.ToArray(), centerOfGravity));
 }
Beispiel #3
0
        // Inputs: plane origin, plane normal, ray origin ray vector.
        // NOTE: both vectors are assumed to be normalized
        float intersect(P3 planeOrigin, V3 planeNormal, P3 rayOrigin, V3 rayVector)
        {
            float d     = -(planeNormal * planeOrigin.ToV3());
            float numer = (planeNormal * rayOrigin.ToV3()) + d;
            float denom = (planeNormal * rayVector);

            return(-(numer / denom));
        }
Beispiel #4
0
 public static Mesh2D Rectangle(P3 topLeft, float width, float height, P3 position)
 {
     P3[] vertices = new P3[4];
     vertices[0] = topLeft;
     vertices[1] = new P3(topLeft.X + width, topLeft.Y, 0);             //tr
     vertices[2] = new P3(topLeft.X + width, topLeft.Y + height, 0);    //br
     vertices[3] = new P3(topLeft.X, topLeft.Y + height, 0);            //bl
     return(new Mesh2D(vertices, position));
 }
Beispiel #5
0
 P3[] GenerateVertices()
 {
     P3[] pts = new P3[relativeVertices.Length];
     for (int i = 0; i < pts.Length; i++)
     {
         pts[i] = relativeVertices[i] + Position;
     }
     return(pts);
 }
Beispiel #6
0
        public Level(Game parent, string[][] data)
        {
            Game  = parent;
            World = new World(this);
            buildHpColors();
            this.data = data;
            float pwid, ph; int nrows, ncols;

            Width        = 1.0F;
            Height       = 0.625F;
            nrows        = data.Length;
            ncols        = data[0].Length;
            BrickWidth   = Width / (float)ncols;           //100%
            BrickHeight  = Height / (float)nrows;          //100%
            pwid         = Width * 0.1F; ph = Height * 0.15F;
            Paddle       = Mesh2D.Paddle(new P3(-pwid / 2F, -ph / 2.0F, 0), pwid, ph, new P3(Width / 2.0F, Height - ph / 2F, 0), 0.98f);
            Paddle.Color = Color.Blue;
            CreatePaddle(Paddle);
            World.AddMesh("paddles", Paddle);
            PaddleStop = BrickWidth + pwid / 2F;
            World.Meshes.Add("vectors", new List <Mesh2D>());
            P3 ballStart = new P3(Width / 2F, Height - BrickHeight, 0);
            V3 vel       = new V3(new P3((float)r.NextDouble() * Width, Height / 2F, 0), ballStart);       //set random init direction

            vel.Magnitude = 1.0F;
            Ball          = Mesh2D.Ball(Width / 200.0F, ballStart, vel);
            CreateBall(Ball);
            World.AddMesh("balls", Ball);
            string type;
            Mesh2D m;

            for (int i = 0; i < data.Length; i++)
            {
                for (int j = 0; j < data[i].Length; j++)
                {
                    m    = Mesh2D.Rectangle(P3.Zero, BrickWidth, BrickHeight, P3.New(BrickWidth * j, BrickHeight * i));
                    type = data[i][j];
                    if (type == "W")
                    {
                        CreateWall(m);
                        World.AddMesh("walls", m);
                        continue;
                    }
                    int hp = int.Parse(type);
                    if (hp == 0)
                    {
                        continue;
                    }
                    CreateBrick(m, hp);
                    BricksLeft++;
                    World.AddMesh("bricks", m);
                }
            }
        }
Beispiel #7
0
        public static Mesh2D Circle(float radius, int numPoints, P3 position)
        {
            float theta = 2.0F * (float)(Math.PI / (double)numPoints);             //2*pi rad

            P3[] vertices = new P3[numPoints];
            for (int i = 0; i < numPoints; i++)
            {
                vertices[i] = new P3((float)Math.Cos(i * theta) * radius, (float)Math.Sin(i * theta) * radius, 0);
            }
            return(new Mesh2D(vertices, position));
        }
Beispiel #8
0
 void Init(P3[] relativeVertices, P3 position)
 {
     if (relativeVertices.Length < 3)
     {
         throw new Exception("need at least 3 pts for a poly");
     }
     relativeVertices      = P3.Clone(relativeVertices);
     this.relativeVertices = relativeVertices;
     this.position         = position;
     cache();
 }
Beispiel #9
0
        public bool Contains(P3 point)
        {
            int numverts = vertices.Count;

            float[] xp = new float[numverts];
            float[] yp = new float[numverts];
            for (int i = 0; i < numverts; i++)
            {
                xp[i] = vertices[i].X;
                yp[i] = vertices[i].Y;
            }
            return(pnpoly(numverts, xp, yp, point.X, point.Y));
        }
Beispiel #10
0
        public static Mesh2D Paddle(P3 topLeft, float width, float height, P3 position, float roofPct)
        {
            P3[] vertices = new P3[paddleVerts.Length + 2];

            int i; float dx = width / (paddleVerts.Length - 1), dy = roofPct * height;

            for (i = 0; i < paddleVerts.Length; i++)
            {
                vertices[i] = V3.New(topLeft.X + dx * i, topLeft.Y + dy * (1 - (float)paddleVerts[i]), 0);
            }
            vertices[i]     = new V3(topLeft.X + width, topLeft.Y + height, 0);     //br
            vertices[i + 1] = new V3(topLeft.X, topLeft.Y + height, 0);             //bl
            return(new Mesh2D(vertices, position));
        }
Beispiel #11
0
        //(the inputs are the ray’s origin and normalized direction vector, as well as the sphere’s origin and radius)
        float intersectSphere(P3 rO, V3 rV, P3 sO, float sR)
        {
            V3    Q = new V3(sO, rO);
            float c = Q.Magnitude;             // length of Q;
            float v = Q * rV;
            float d = sR * sR - (c * c - v * v);

            // If there was no intersection, return -1
            if (d < 0.0F)
            {
                return(-1.0F);
            }
            // Return the distance to the [first] intersecting point
            return(v - (float)Math.Sqrt(d));
        }
Beispiel #12
0
        public static Mesh2D Vector(V3 direction, P3 position, float width)
        {
            P3[] vertices = new P3[3];
            V3   perp     = direction.Perpendicular2DLeftHanded();

            perp.Magnitude = width;
            V3 perp2 = perp.Clone().Flip();

            vertices[0] = direction.ToPoint();
            vertices[2] = perp.ToPoint();
            vertices[1] = perp2.ToPoint();
            Mesh2D c = new Mesh2D(vertices, position);

            c.Color = System.Drawing.Color.Magenta;
            return(c);
        }
Beispiel #13
0
        public Result IntersectsWith(Edge other, out P3 intersectionPoint)
        {
            intersectionPoint = null;
            float denom = ((other.Tail.Y - other.Head.Y) * (Tail.X - Head.X)) - ((other.Tail.X - other.Head.X) * (Tail.Y - Head.Y));
            float numeA = ((other.Tail.X - other.Head.X) * (Head.Y - other.Head.Y)) - ((other.Tail.Y - other.Head.Y) * (Head.X - other.Head.X));
            float numeB = ((Tail.X - Head.X) * (Head.Y - other.Head.Y)) - ((Tail.Y - Head.Y) * (Head.X - other.Head.X));

            if (denom == 0)
            {
                if (numeA == 0 && numeB == 0)                   //find out if coincident seg touches us
                {
                    V3   n     = other.ToVector().Perpendicular2DLeftHanded().UnitVector;
                    Edge perp  = new Edge(other.Head + n, other.Head);
                    Edge perp2 = new Edge(other.Tail + n, other.Tail);
                    P3   o;
                    if (Edge.Result.Intersecting == perp.IntersectsWith(this, out o))
                    {
                        intersectionPoint = o;
                        return(Edge.Result.Intersecting);
                    }
                    if (Edge.Result.Intersecting == perp2.IntersectsWith(this, out o))
                    {
                        intersectionPoint = o;
                        return(Edge.Result.Intersecting);
                    }
                    return(Result.Coincident);
                }
                return(Result.Parallel);
            }
            float ua = numeA / denom;
            float ub = numeB / denom;

            if (ua >= 0 && ua <= 1.0 && ub >= 0 && ub <= 1.0)
            {
                // Get the intersection point.
                intersectionPoint = V3.New(Head.X + ua * (Tail.X - Head.X), Head.Y + ua * (Tail.Y - Head.Y), 0);
                return(Result.Intersecting);
            }
            return(Result.NotIntersecting);
        }
Beispiel #14
0
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Edge e  = new Edge(P3.New(0, 0), P3.New(0, -1));
            Edge e2 = new Edge(P3.New(0, -1), P3.New(0, 0));
            V3   v  = new V3(1, 1, 0);
            V3   v2 = new V3(0.5F, 0, 0);
            V3   v3 = new V3(0, 1, 0);

            v3.RotateBy2D(-0.78f);
            v3.RotateBy2D(0.78f * 2);
            float d = v.ProjectionDistance(v2);
            Dictionary <Edge, int> dic = new Dictionary <Edge, int>();
            //dic.Add(e, 0);
            //dic.Add(e2, 0);
            V3 n  = e.GetNormal2DRightHanded();
            V3 n2 = e2.GetNormal2DRightHanded();
            P3 p;

            Application.Run(new Form1());
        }
Beispiel #15
0
 public Edge(P3 head, P3 tail, Mesh2D parent)
 {
     Head = head; Tail = tail; this.Parent = parent;
 }
Beispiel #16
0
        //http://www.gamedev.net/reference/articles/article1026.asp
        void collideWithWorld(Mesh2D projectile, float deltaTimeInSec)
        {
            P3 sourcePoint    = projectile.Position;
            V3 velocityVector = projectile.Velocity.Clone() * deltaTimeInSec;
            // How far do we need to go?
            float distanceToTravel = velocityVector.Magnitude;             //length of velocityVector;

            // Do we need to bother?
            if (distanceToTravel < float.Epsilon)
            {
                return;
            }
            // What's our destination?
            P3 destinationPoint = sourcePoint + velocityVector;
            // Whom might we collide with?
            List <Mesh2D> potentialColliders = null;          //= GetObstacles(projectile);

            // If there are none, we can safely move to the destination and bail
            if (potentialColliders.Count == 0)
            {
                projectile.MoveNext(deltaTimeInSec);
                return;
            }
            // Determine the nearest collider from the list potentialColliders
            bool   firstTimeThrough                = true;
            float  nearestDistance                 = -1.0F;
            Mesh2D nearestCollider                 = null;
            P3     nearestIntersectionPoint        = null;
            P3     nearestPolygonIntersectionPoint = null;

            for (int i = 0; i < potentialColliders.Count; i++)
            {
                // Plane origin/normal
                P3 pOrigin = potentialColliders[i].Vertices[0];                                  //any vertex from the current polygon;
                V3 pNormal = potentialColliders[i].Edges[0].GetNormal2DRightHanded().UnitVector; //surface normal from the current polygon;
                // Determine the distance from the plane to the source
                float pDist = intersect(sourcePoint, -pNormal, pOrigin, pNormal);
                //P3 sphereIntersectionPoint;
                P3 planeIntersectionPoint;
                // The radius of the ellipsoid (in the direction of pNormal)
                //V3 directionalRadius = -pNormal * new V3(projectile.BoundingRadius, projectile.BoundingRadius, 0);
                float radius = projectile.BoundingRadius;                 //directionalRadius.Magnitude;
                // Is the plane embedded?
                if (Math.Abs(pDist) <= radius)
                {
                    // Calculate the plane intersection point
                    V3 pN = -pNormal;
                    pN.Magnitude           = pDist;           //-pNormal with length set to pDist
                    planeIntersectionPoint = sourcePoint + pN;
                }
                else
                {
                    // Calculate the ellipsoid intersection point
                    V3 pN = -pNormal;
                    pN.Magnitude = radius;                     //-pNormal with length set to radius
                    P3 ellipsoidIntersectionPoint = sourcePoint + pN;
                    // Calculate the plane intersection point
                    //Ray    ray(sphereIntersectionPoint, Velocity);
                    float tt = intersect(ellipsoidIntersectionPoint, velocityVector, pOrigin, pNormal);
                    // Calculate the plane intersection point
                    V3 VV = velocityVector.Clone();
                    VV.Magnitude           = tt;           // velocityVector with length set to t;
                    planeIntersectionPoint = ellipsoidIntersectionPoint + VV;
                }
                // Unless otherwise stated, our polygonIntersectionPoint is the
                // same point as planeIntersectionPoint

                P3 polygonIntersectionPoint = planeIntersectionPoint.Clone();
                // So… are they the same?
                if (!potentialColliders[i].Contains(planeIntersectionPoint))                                       //planeIntersectionPoint is not within the current polygon)
                {
                    polygonIntersectionPoint = P3.Closest(potentialColliders[i].Vertices, planeIntersectionPoint); //nearest point on polygon's perimeter to planeIntersectionPoint;
                }
                // Invert the velocity vector
                V3 negativeVelocityVector = -velocityVector;
                // Using the polygonIntersectionPoint, we need to reverse-intersect
                // with the ellipsoid
                float t = intersectSphere(polygonIntersectionPoint, negativeVelocityVector, sourcePoint, projectile.BoundingRadius);
                // Was there an intersection with the ellipsoid?
                if (t >= 0.0F && t <= distanceToTravel)
                {
                    V3 VV = negativeVelocityVector.Clone();                     //negativeVelocityVector with length set to t;
                    VV.Magnitude = t;
                    // Where did we intersect the ellipsoid?
                    V3 intersectionPoint = (polygonIntersectionPoint + VV).ToV3();
                    // Closest intersection thus far?
                    if (firstTimeThrough || t < nearestDistance)
                    {
                        nearestDistance                 = t;
                        nearestCollider                 = potentialColliders[i];
                        nearestIntersectionPoint        = intersectionPoint;
                        nearestPolygonIntersectionPoint = polygonIntersectionPoint;
                        firstTimeThrough                = false;
                    }
                }
            }
            // If we never found a collision, we can safely move to the destination
            // and bail
            if (firstTimeThrough)
            {
                projectile.MoveNext(deltaTimeInSec);
                return;
            }
            // Move to the nearest collision
            V3 V = velocityVector.Clone();             //velocityVector with length set to (nearestDistance - EPSILON);

            V.Magnitude = nearestDistance;
            sourcePoint = sourcePoint + V;

            // Determine the sliding plane (we do this now, because we're about to
            // change sourcePoint)
            P3 slidePlaneOrigin = nearestPolygonIntersectionPoint;
            V3 slidePlaneNormal = new V3(nearestPolygonIntersectionPoint, sourcePoint);
            // We now project the destination point onto the sliding plane
            float time = intersect(destinationPoint, slidePlaneNormal, slidePlaneOrigin, slidePlaneNormal);
            //Set length of slidePlaneNormal to time;
            V3 destinationProjectionNormal = slidePlaneNormal;
            P3 newDestinationPoint         = destinationPoint + destinationProjectionNormal;
            // Generate the slide vector, which will become our new velocity vector
            // for the next iteration
            V3 newVelocityVector = new V3(newDestinationPoint, nearestPolygonIntersectionPoint);

            // Recursively slide (without adding gravity)
            projectile.Position = sourcePoint;
            projectile.Velocity = newVelocityVector;
            collideWithWorld(projectile, deltaTimeInSec);
        }
Beispiel #17
0
 public Mesh2D(P3[] relativeVertices, P3 position)
 {
     Init(relativeVertices, position);
 }
Beispiel #18
0
		public V3(P3 v) : base(v) { }
Beispiel #19
0
 public Mesh2D Clone()
 {
     trash          = new Mesh2D(P3.Clone(relativeVertices), position.Clone());
     trash.velocity = this.velocity.Clone();
     return(trash);
 }
Beispiel #20
0
		public V3(P3 head, P3 tail) {
			Set(head.X - tail.X, head.Y - tail.Y, head.Z - tail.Z);
		}
Beispiel #21
0
 public Edge(P3 head, P3 tail)
 {
     Head = head; Tail = tail;
 }
Beispiel #22
0
		public static new V3 New(P3 p) {
			return new V3(p);
		}
Beispiel #23
0
        //1w to 0.625h

        /// <returns>true if a collision occured</returns>
        public void ResolveCollisions2(float deltaTimeInSec, bool moveNext)
        {
            List <Mesh2D> obstacles = new List <Mesh2D>();
            List <Mesh2D> collideable;

            obstacles.AddRange(Meshes["bricks"]);
            obstacles.AddRange(Meshes["walls"]);
            obstacles.AddRange(Meshes["paddles"]);
            Mesh2D next; Mesh2D projectile;

            for (int i = 0; i < Meshes["balls"].Count; i++)
            {
                projectile = Meshes["balls"][i];
                next       = projectile.Clone();
                next.MoveNext(deltaTimeInSec);                 //AddVec(next.Trajectory(), Color.Blue);
                collideable = GetCollideable(next, obstacles); //find hittable meshes
                if (collideable.Count > 0)
                {
                    List <Mesh2D> collided = GetCollidedMeshes(next, collideable);
                    if (collided.Count > 0)
                    {
                        float d;
                        Edge  closest = GetCollisionEdge(next, projectile, collided, out d);
                        if (closest != null)
                        {
                            projectile.DeflectAgainst(closest.GetNormal2DRightHanded().UnitVector);
                            if (closest.Parent.Attributes.Get <string>("name") == "brick")
                            {
                                int hp = closest.Parent.Attributes.Get <int>("hitpoints");
                                Level.Game.Score += 100 * hp;
                                hp--;
                                if (hp == 0)
                                {
                                    closest.Parent.Position = P3.New(2, 2);
                                }
                                closest.Parent.Attributes["hitpoints"] = hp;
                                Level.Game.Sound.PlaySFX("brickhit");
                                Level.BricksLeft--;
                                if (Level.BricksLeft == 0)
                                {
                                    Level.Game.NextLevel();
                                }
                            }
                            else if (closest.Parent.Attributes.Get <string>("name") == "wall" || closest.Parent.Attributes.Get <string>("name") == "paddle")
                            {
                                Level.Game.Sound.PlaySFX("wallhit");
                            }
                        }
                        else
                        {
                            if (moveNext)
                            {
                                projectile.MoveNext(deltaTimeInSec);
                            }
                        }
                    }
                    else                         //collided.count==0
                    {
                        if (moveNext)
                        {
                            projectile.MoveNext(deltaTimeInSec);
                        }
                    }
                }
                else                     //if collideable.count==0
                {
                    if (moveNext)
                    {
                        projectile.MoveNext(deltaTimeInSec);
                    }
                }
            }
        }
Beispiel #24
0
 CustomVertex.TransformedColored Make(P3 point, Color color)
 {
     return(new CustomVertex.TransformedColored(point.X, point.Y, point.Z, 1F, color.ToArgb()));
 }