public bool IsCollideableWith(Mesh2D target) { float d1 = centerOfGravity.SquaredDistanceTo(target.centerOfGravity); float d2 = (boundingRadiusSquared + target.boundingRadiusSquared); return(d1 < d2 * 4F); }
public void CreatePaddle(Mesh2D mesh) { Attributes a = mesh.Attributes; a["name"] = "paddle"; mesh.Color = Color.White; }
public void CreateWall(Mesh2D mesh) { Attributes a = mesh.Attributes; a["name"] = "wall"; mesh.Color = wc; }
public static Mesh2D Ball(float radius, P3 position, V3 velocity) { Mesh2D c = Mesh2D.Circle(radius, 16, position); c.Velocity = velocity; return(c); }
public bool IsCollideableWith(Mesh2D target) { float d1 = MidPoint().SquaredDistanceTo(target.CenterOfGravity); float rad = Length() / 2F; float d2 = (rad * rad + target.BoundingRadiusSquared); return(d1 < d2); }
public void CreateBall(Mesh2D mesh) { Attributes a = mesh.Attributes; a["projectile"] = true; a["name"] = "ball"; mesh.Color = Color.Red; }
public void AddVec(Edge e, Color c) { Mesh2D sideV = Mesh2D.Vector(e, 0.002F); sideV.Color = c; //System.Threading.Thread.Sleep(10); AddMesh("vectors", sideV); }
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); } } }
public void AddMesh(string key, Mesh2D mesh) { if (Meshes.ContainsKey(key)) { Meshes[key].Add(mesh); } else { Meshes.Add(key, new List <Mesh2D>(new Mesh2D[] { mesh })); } }
List <Mesh2D> GetCollideable(Mesh2D target, List <Mesh2D> candidates) { List <Mesh2D> found = new List <Mesh2D>(); for (int i = 0; i < candidates.Count; i++) { if (target.IsCollideableWith(candidates[i])) { found.Add(candidates[i]); } } return(found); }
List <Edge> GetCollideable(Mesh2D projectile, List <Edge> candidates) { List <Edge> found = new List <Edge>(); for (int i = 0; i < candidates.Count; i++) { if (candidates[i].IsCollideableWith(projectile)) { found.Add(candidates[i]); } } return(found); }
List <Mesh2D> GetCollidedMeshes(Mesh2D projectile, List <Mesh2D> collideable) { List <Mesh2D> results = new List <Mesh2D>(); for (int i = 0; i < collideable.Count; i++) { if (projectile.Intersects(collideable[i])) { results.Add(collideable[i]); } } return(results); }
public bool Intersects(Mesh2D other) { int tec = other.edges.Count; P3 var; for (int i = 0; i < edges.Count; i++) { for (int j = 0; j < tec; j++) { if (edges[i].IntersectsWith(other.edges[j], out var) == Edge.Result.Intersecting) { return(true); } } } return(false); }
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); }
public List <Edge> CollidesWith(Mesh2D other) { int tec = other.edges.Count; P3 var; List <Edge> collided = new List <Edge>(); for (int i = 0; i < edges.Count; i++) { for (int j = 0; j < tec; j++) { if (edges[i].IntersectsWith(other.edges[j], out var) == Edge.Result.Intersecting) { edges[i].Tag = var; collided.Add(edges[i]); } } } return(collided); }
public void CreateBrick(Mesh2D mesh, int hitpoints) { Attributes a = mesh.Attributes; a["hitpoints"] = hitpoints; a["destroyable"] = true; a["name"] = "brick"; if (hitpoints == 1) { mesh.Color = RandomBlue(); } else if (hitpoints == 2) { mesh.Color = RandomGreen(); } else { mesh.Color = RandomRed(); } }
public Edge GetCollisionEdge(Mesh2D next, Mesh2D projectile, List <Mesh2D> collided, out float distance) { //create rays leaving each vertex of the projectile in the direction of vel //intersect each edge with the target polygon edges and return the closest future bounce pos & deflection edge float rayLength = projectile.BoundingRadius * 5F + projectile.Position.DistanceTo(next.Position); V3 rayVel = projectile.Velocity.UnitVector * rayLength; Dictionary <Edge, float> raysOut = new Dictionary <Edge, float>(); //we'll keep the min dist so far per ray in a dictionary Dictionary <Edge, float> raysIn = new Dictionary <Edge, float>(); Edge ray; for (int j = 0; j < projectile.Vertices.Length; j++) { ray = new Edge(projectile.Vertices[j] + rayVel, projectile.Vertices[j]); //AddVec(ray, Color.Blue); if (!raysOut.ContainsKey(ray)) { raysOut.Add(ray, float.MaxValue); } } //for (int k = 0; k < collided.Count; k++) { // for (int j = 0; j < collided[k].Vertices.Length; j++) { // ray = new Edge(collided[k].Vertices[j] + rayVel.Clone().Flip(), collided[k].Vertices[j], collided[k]); // if (!raysIn.ContainsKey(ray)) raysIn.Add(ray, float.MaxValue);//AddVec(ray, Color.Blue); // } //} P3 isect; #region Projectile to Polygon float d; // iterate over each collided mesh edge and pick the closest intersection point (bounce pt) List <Edge> keys = new List <Edge>(raysOut.Keys); foreach (Edge edge in keys) { for (int k = 0; k < collided.Count; k++) { for (int j = 0; j < collided[k].Edges.Length; j++) { if (edge.IntersectsWith(collided[k].Edges[j], out isect) == Edge.Result.Intersecting) { d = edge.Tail.DistanceTo(isect); if (d < raysOut[edge]) { edge.Tag = collided[k].Edges[j]; raysOut[edge] = d; } } } } } d = float.MaxValue; Edge closest = null; foreach (Edge edge in keys) { if (raysOut[edge] < d) { d = raysOut[edge]; closest = edge; } } #endregion //float d2; //keys = new List<Edge>(raysIn.Keys); //foreach (Edge edge in keys) { // for (int j = 0; j < projectile.Edges.Length; j++) { // if (edge.IntersectsWith(projectile.Edges[j], out isect) == Edge.Result.Intersecting) { // d2 = edge.Tail.DistanceTo(isect); // if (d2 < raysIn[edge]) { // raysIn[edge] = d2; //this is useless for now since we don't know what edges the vertex is attached to // } // } // } //} //d2 = d; //foreach (Edge edge in keys) { // if (raysIn[edge] < d2) { // d2 = raysIn[edge]; // } //} distance = d; return((Edge)closest.Tag); }
public Edge(P3 head, P3 tail, Mesh2D parent) { Head = head; Tail = tail; this.Parent = parent; }
//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); }
public void RemoveMesh(string key, Mesh2D mesh) { Meshes[key].Remove(mesh); }
public Mesh2D Clone() { trash = new Mesh2D(P3.Clone(relativeVertices), position.Clone()); trash.velocity = this.velocity.Clone(); return(trash); }