Coordinates CoordsFrontColumn(Coordinates coordinates, bool toUp) { Coordinates newCoords = coordinates; //calculate new face newCoords.face = WorldUtility.FindFaceFrontToUp(coordinates.face, toUp); //get coordinates x,y of face to the top or to the down if (coordinates.face == EFace.back || newCoords.face == EFace.back) { //if the prev face or next face is Face.back, then you Self_InverseInverse Vector2Int v = Vector2Math.Self_InverseInverse(coordinates.x, coordinates.y, world.worldConfig.NumberCells); newCoords.x = v.x; newCoords.y = v.y; } return(newCoords); }
Coordinates CoordsRightLeftColumn(Coordinates coordinates, bool toUp) { //calculate new face -> work the inverse, so we use !toUp coordinates.face = WorldUtility.FindFaceUpToRight(coordinates.face, !toUp); //get coordinates x,y of face to the top or face to the bottom if (toUp) { Vector2Int v = Vector2Math.InverseEqual(coordinates.x, coordinates.y, world.worldConfig.NumberCells); coordinates.x = v.x; coordinates.y = v.y; } else { Vector2Int v = Vector2Math.EqualInverse(coordinates.x, coordinates.y, world.worldConfig.NumberCells); coordinates.x = v.x; coordinates.y = v.y; } return(coordinates); }
Coordinates CoordsToRight(Coordinates coordinates, bool toRight) { //calculate new face coordinates.face = WorldUtility.FindFaceUpToRight(coordinates.face, toRight); //get coordinates x,y of face to the right or to the left if (toRight) { Vector2Int v = Vector2Math.EqualInverse(coordinates.x, coordinates.y, world.worldConfig.NumberCells); coordinates.x = v.x; coordinates.y = v.y; } else { Vector2Int v = Vector2Math.InverseEqual(coordinates.x, coordinates.y, world.worldConfig.NumberCells); coordinates.x = v.x; coordinates.y = v.y; } return(coordinates); }
Coordinates UpdateCoordinatesCompleteFace(Coordinates coordinates, bool forward) { if (forward) { //rotate the face, so change coordinates x and y, but not the face Vector2Int v = Vector2Math.InverseEqual(coordinates.x, coordinates.y, world.worldConfig.NumberCells); coordinates.x = v.x; coordinates.y = v.y; } else { //rotate the face, so change coordinates x and y, but not the face Vector2Int v = Vector2Math.EqualInverse(coordinates.x, coordinates.y, world.worldConfig.NumberCells); coordinates.x = v.x; coordinates.y = v.y; } return(coordinates); }
//------------------------------------------------------------------------------------- // Main Logic //------------------------------------------------------------------------------------- private void UpdateLightMesh() { geometryVertices.Clear(); geometryUvs.Clear(); _geometry.GetVertices(geometryVertices); _geometry.GetUVs(0, geometryUvs); var position = (Vector2)transform.position; validEdges.Clear(); vertices.Clear(); uvs.Clear(); indices.Clear(); // ///////////////// // Filter valid corners in geometry for (var i = 0; i < geometryVertices.Count; i += 2) { var pA = (Vector2)geometryVertices[i]; var pB = geometryUvs[i]; var closest = Vector2Math.ClosestPointOnEdge(pA, pB, position); if ((closest - position).sqrMagnitude > _range * _range) { continue; } validEdges.Add(new Vector4(pA.x, pA.y, pB.x, pB.y)); } // ///////////////// var q1 = Quaternion.AngleAxis(0.4f, Vector3.forward); var q2 = Quaternion.Inverse(q1); // ///////////////// // local helper functions void AddVertex(Vector2 point) { var angle = Vector2.SignedAngle((Vector2)transform.right, point - position); if (Mathf.Abs(angle) > _spotAngle / 2f + 0.2) { return; } vertices.Add(point); } float GeneratePoint(Vector2 dir) { float f = 1.0f; //var f = Vector2Math.Intersect(pA, pB, position, position + dir * _range); foreach (var point2 in validEdges) { var p2A = new Vector2(point2.x, point2.y); var p2B = new Vector2(point2.z, point2.w); var f2 = Vector2Math.Intersect(position, position + dir * _range, p2A, p2B); if (f2 < 1e-5) { continue; } f = Mathf.Min(f, f2); } AddVertex(position + f * _range * dir); return(f); } void SmoothCircle(Vector2 pA, Vector2 pB) { var amount = Vector2Math.FarthestPointOnEdge(pA, pB, position, _range, ref outVectors); for (int i = 0; i < amount; ++i) { var dir2 = outVectors[i] - position; var f = GeneratePoint(dir2); //AddVertex(position + f * _range * dir2); } } // ///////////////// // Add base rays, in the case that no obstacle is there var degree = (_spotAngle / (int)_minRayCount); for (int i = 0; i < (int)_minRayCount; ++i) { float j = i - (int)_minRayCount / 2f; var dir = (Vector2)(Quaternion.AngleAxis(j * degree, Vector3.forward) * transform.right); var f1 = GeneratePoint(dir); // AddVertex(position + f1 * _range * dir); } // ///////////////// // Send a ray to each geometry vertex in range foreach (var point in validEdges) { var pA = new Vector2(point.x, point.y); var pB = new Vector2(point.z, point.w); var dir = (pA - position).normalized; var f1 = GeneratePoint(dir); if (f1 > 0.999) { SmoothCircle(pA, pB); } else { var f = GeneratePoint(q1 * dir); bool b = f < 0.999; f = GeneratePoint(q2 * dir); b |= f < 0.999; if (b) { SmoothCircle(pA, pB); } } } // ///////////////// // vertices.Sort((v1, v2) => Vector2.SignedAngle((Vector2)transform.right, (Vector2)v1 - position).CompareTo( Vector2.SignedAngle((Vector2)transform.right, (Vector2)v2 - position) ) ); vertices.Insert(0, position); uvs.Add(new Vector2(0, 0)); for (var i = 1; i < vertices.Count; i++) { var distance_n = ((Vector2)vertices[i] - position).magnitude / (_range); uvs.Add(new Vector2(distance_n, 0)); indices.Add(0); indices.Add(i); indices.Add(i - 1); } if (_lightType != Light2DType.Spot) { indices.Add(0); indices.Add(1); indices.Add(vertices.Count - 1); } _lightMesh.Clear(); _lightMesh.SetVertices(vertices); _lightMesh.SetTriangles(indices, 0); _lightMesh.SetUVs(0, uvs); }