public List <Vector3> GetVerticies() { List <Vector3> points = new List <Vector3>(); Vector3 positionPoly = poly.transform.position; if (poly.transform.eulerAngles.z != 0) { float angle = poly.transform.eulerAngles.z * Mathf.Deg2Rad; foreach (Vector2 v in poly.points) { Vector3 rotatedPoint = Light_Tools.RotatePoint(new Vector2(v.x * poly.transform.localScale.x, v.y * poly.transform.localScale.y), angle); points.Add(rotatedPoint + positionPoly); } } else { foreach (Vector2 v in poly.points) { points.Add(new Vector3(v.x * poly.transform.localScale.x + positionPoly.x, v.y * poly.transform.localScale.y + positionPoly.y)); } } return(points); }
//trouve tous les points qui sont "visibles" par la lumière public List <Vector3> FindPoint(List <Vector3> points, DynamicLight light) { for (int i = 0; i < points.Count; i++) { Vector2 direction = points[i] - light.transform.position; float distance = Mathf.Sqrt(direction.x * direction.x + direction.y * direction.y) - 0.05f;; if (distance <= light.GetRadius()) { // on s'arrête juste avant le collider pour voir s'il touche quand même. Si c'est le cas alors le raycast se rentre dedans. RaycastHit2D hit = Physics2D.Raycast(light.transform.position, direction, distance - 0.05f, light.layer); // si le raycast ne touche rien alors le collider est en contacte direct avec la lumière if (!hit) { float angle = Light_Tools.GetAngle(direction); points[i] = new Vector3(points[i].x, points[i].y, angle); } // si le dernier point n'est pas le collider cela veut dire que, // normalement il aurait due être pris en compte mais un objet bloque la lumière else { points.Remove(points[i]); i--; } } else { points.Remove(points[i]); i--; } } return(points); }
// récupèretous les points du collider et les traites pour les rajouter à la liste de points // private void GetBoxVertices(BoxCollider2D box) { Light_Box l_box = new Light_Box(box); List <Vector3> points = l_box.GetVertices(); float box_radius = Vector2.Distance(box.transform.position, points[0]); float box_distance = Vector2.Distance(box.transform.position, transform.position); if (box_radius + box_distance > GetRadius()) { points = l_box.GetIntercections(points, this); } points = l_box.FindPoint(points, this); // si tout les points ne sont pas dans la lumière alors on regarde s'il n'y a pas d'intersection if (points.Count > 0) { points = Light_Tools.TrieAngle(points); points = l_box.CreateBoxLimit(points, box, this); foreach (Vector3 v in points) { pointList.Add(v); } } }
public List <Vector3> FindCirclePoint(List <Vector3> points, DynamicLight light) { for (int i = 0; i < points.Count; i++) { Vector2 direction = points[i] - light.transform.position; float distance = Mathf.Sqrt(direction.x * direction.x + direction.y * direction.y); RaycastHit2D[] hits = Physics2D.RaycastAll(light.transform.position, direction, distance, light.layer); bool touchAnotherCollider = false; foreach (RaycastHit2D h in hits) { if (h.collider != circle) { touchAnotherCollider = true; break; } } if (!touchAnotherCollider) { float angle = Light_Tools.GetAngle(direction); points[i] = new Vector3(points[i].x, points[i].y, angle); } else { points.Remove(points[i]); i--; } } return(points); }
//récupère les points d'un box collider public List <Vector3> GetVertices() { List <Vector3> points = new List <Vector3>(); if (box.transform.eulerAngles.z != 0) { float angle = box.transform.eulerAngles.z * Mathf.Deg2Rad; Vector2 vect = new Vector2(box.transform.localScale.x / 2, box.transform.localScale.y / 2); for (int i = -1; i < 2; i += 2) { for (int j = -1; j < 2; j += 2) { Vector3 rotatedPoint = new Vector3(vect.x * i, vect.y * j); rotatedPoint = Light_Tools.RotatePoint(rotatedPoint, angle); points.Add(center + rotatedPoint); } } } else { points.Add(new Vector3(center.x - size.x, center.y - size.y, 0)); points.Add(new Vector3(center.x - size.x, center.y + size.y, 0)); points.Add(new Vector3(center.x + size.x, center.y + size.y, 0)); points.Add(new Vector3(center.x + size.x, center.y - size.y, 0)); } return(points); }
public List <Vector3> GetIntercections(List <Vector3> points, DynamicLight light) { for (int i = 0; i < points.Count; i++) { Light_Tools.GetIntersection(points[i], points[(i + 1) % (points.Count)], points, light); } return(points); }
private void GetCircleVertices(CircleCollider2D circle) { List <Vector3> points = new List <Vector3>(); Light_Circle l_circle = new Light_Circle(circle); points = l_circle.GetVertices(points, this); points = l_circle.FindCirclePoint(points, this); if (points.Count > 0) { points = Light_Tools.TrieAngle(points); points = l_circle.CreateCircleLimit(points, this); foreach (Vector3 v in points) { pointList.Add(v); } } }
public List <Vector3> GetVertices(List <Vector3> points, DynamicLight light) { // --- bool inversion = false; // on cherche la tangentes à du cercle passant par l'origine de la lumiére // le cercle du colider float x0 = center.x - light.transform.position.x; float y0 = center.y - light.transform.position.y; float r0 = circle.radius * circle.transform.localScale.x; // le cercle qui à pour point l'origine de la lumière, le centre du cercle collider, et les points des tangentes float x1 = x0 / 2; float y1 = y0 / 2; float r1 = Mathf.Sqrt(x1 * x1 + y1 * y1); if (Mathf.Abs(y0 - y1) < 0.3f) { inversion = true; float _ = x0; x0 = y0; y0 = _; _ = x1; x1 = y1; y1 = _; } float A, B, C, N, a, delta; // un coef utile pour ne pas répéter le calcul a = (x0 - x1) / (y0 - y1); // pareil N = (r1 * r1 - r0 * r0 - x1 * x1 + x0 * x0 - y1 * y1 + y0 * y0) / (2 * (y0 - y1)); // on a une équation du second degrés du type Ax² + Bx + C =0 A = a * a + 1; B = 2 * y0 * a - 2 * N * a - 2 * x0; C = x0 * x0 + y0 * y0 + N * N - r0 * r0 - 2 * y0 * N; // on trouve le delta delta = Mathf.Sqrt(B * B - 4 * A * C); // on en déduit les deux solutions for (int i = -1; i < 2; i += 2) { float x = (-B - delta * i) / (2 * A); float y = N - x * a; if (inversion) { float _ = y; y = x; x = _; } points.Add(new Vector3(x + light.transform.position.x, y + light.transform.position.y)); } for (int i = 0; i < 2; i++) { Vector3 direction = points[i] - light.transform.position; points[i] = new Vector3(points[i].x, points[i].y, Light_Tools.GetAngle(direction)); } return(points); }
// fait les tests pour les projections pour les ombres ( cercle ) // public List <Vector3> CreateCircleLimit(List <Vector3> points, DynamicLight light) { for (int i = 0; i < points.Count; i++) { Vector3 limite = Vector3.zero; Vector3 direction = points[i] - light.transform.position; float distance = Mathf.Sqrt(direction.x * direction.x + direction.y * direction.y); if (light.GetRadius() - distance > 0) { RaycastHit2D[] hit = Physics2D.RaycastAll(points[i], direction, light.GetRadius() - distance, light.layer); float angle = direction.z; foreach (RaycastHit2D h in hit) { if (h.collider != circle) { limite = h.point; break; } } if (limite == Vector3.zero) { limite = new Vector3(light.transform.position.x + Mathf.Cos(angle) * light.GetRadius() , light.transform.position.y + Mathf.Sin(angle) * light.GetRadius() ); } limite.z = angle; // redondance if (i < points.Count - 1) { points.Insert(i, limite); i++; } else if (points.Count == 1) { float angleCollider = Light_Tools.GetAngle(circle.transform.position - light.transform.position); if (points[0].z <angleCollider || points[0].z - angleCollider> Mathf.PI) { points.Insert(0, limite); } else { points.Add(limite); } } else { points.Add(limite); i++; } } } if (Mathf.PI < Mathf.Abs(points[points.Count - 1].z) - Mathf.Abs(points[0].z)) { Vector3 _ = points[0]; points[0] = points[1]; points[1] = _; _ = points[points.Count - 1]; points[points.Count - 1] = points[points.Count - 2]; points[points.Count - 2] = _; } return(points); }
public List <Vector3> CreateBoxLimit(List <Vector3> points, Collider2D collider, DynamicLight light) { int nbPoint = points.Count; for (int i = 0; i < nbPoint; i++) { float angle = Mathf.Abs(points[i].z); // le facteur permet de positionner un peu plus loin l'origine du point pour éviter que le raycast commence à la limite du collider Vector3 facteur = new Vector3(0.1f * Mathf.Cos(angle), 0.1f * Mathf.Sin(angle)); Vector2 origine = points[i] + facteur; // la distance entre le centre de la lumière et le point d'origine de notre raycast c'est pour éviter que le raycast ne dépasse la limite du cercle if (!Physics2D.OverlapPoint(origine, light.layer)) { Vector3 limite = new Vector3(); Vector3 direction = points[i] - light.transform.position; float distance = Mathf.Sqrt(direction.x * direction.x + direction.y * direction.y); RaycastHit2D hit = Physics2D.Raycast(origine, direction, light.GetRadius() - distance, light.layer); if (hit) { limite = hit.point; } else { limite = new Vector3(light.transform.position.x + Mathf.Cos(angle) * light.GetRadius() , light.transform.position.y + Mathf.Sin(angle) * light.GetRadius() ); } limite += new Vector3(0, 0, direction.z); float angleCollider = Light_Tools.GetAngle(collider.transform.position - light.transform.position); if (limite.z < angleCollider) { if (Mathf.Abs(limite.z - angleCollider) > Mathf.PI) { points.Add(limite); } else { points.Insert(i, limite); i++; nbPoint++; } } else if (limite.z > angleCollider) { if (Mathf.Abs(limite.z - angleCollider) > Mathf.PI) { points.Insert(i, limite); i++; nbPoint++; } else { points.Add(limite); } } } } if (Mathf.PI < Mathf.Abs(points[points.Count - 1].z) - Mathf.Abs(points[0].z)) { Vector3 _ = points[0]; points[0] = points[1]; points[1] = _; _ = points[points.Count - 1]; points[points.Count - 1] = points[points.Count - 2]; points[points.Count - 2] = _; } return(points); }