static public Mesh GeneratePolygonMesh(Vector2D pos, Polygon2D.PolygonType polygonType, float polygonSize, float minVertexDistance, Transform transform, float lineWidth, float zPosition) { List <Mesh2DSubmesh> trianglesList = new List <Mesh2DSubmesh>(); Polygon2D slicePolygon = Polygon2D.Create(polygonType, polygonSize); slicePolygon.ToOffsetItself(pos); Vector2D vA, vB; foreach (Pair2D pair in Pair2D.GetList(slicePolygon.pointsList, true)) { vA = new Vector2D(pair.A); vB = new Vector2D(pair.B); vA.Push(Vector2D.Atan2(pair.A, pair.B), -minVertexDistance / 5); vB.Push(Vector2D.Atan2(pair.A, pair.B), minVertexDistance / 5); trianglesList.Add(Max2DMesh.CreateLine(new Pair2D(vA, vB), transform, lineWidth, zPosition)); } return(Max2DMesh.Export(trianglesList)); }
private void ComplexSlice(List <Vector2D> slice) { List <Slice2D> results = Slicer2D.ComplexSliceAll(slice, null); if (addForce == true) { foreach (Slice2D id in results) { foreach (GameObject gameObject in id.gameObjects) { Rigidbody2D rigidBody2D = gameObject.GetComponent <Rigidbody2D> (); if (rigidBody2D) { foreach (Pair2D p in Pair2D.GetList(id.collisions)) { float sliceRotation = (float)Vector2D.Atan2(p.B, p.A); Physics2DHelper.AddForceAtPosition(rigidBody2D, new Vector2(Mathf.Cos(sliceRotation) * addForceAmount, Mathf.Sin(sliceRotation) * addForceAmount), (p.A + p.B).ToVector2() / 2f); } } } } } }
static public Mesh GenerateComplexMesh(List <Vector2D> complexSlicerPointsList, Transform transform, float lineWidth, float minVertexDistance, float zPosition, float squareSize) { List <Mesh2DTriangle> trianglesList = new List <Mesh2DTriangle>(); float size = squareSize; Vector2D vA, vB; List <Pair2D> list = Pair2D.GetList(complexSlicerPointsList, false); foreach (Pair2D pair in list) { vA = new Vector2D(pair.A); vB = new Vector2D(pair.B); vA.Push(Vector2D.Atan2(pair.A, pair.B), -minVertexDistance / 4); vB.Push(Vector2D.Atan2(pair.A, pair.B), minVertexDistance / 4); trianglesList.Add(CreateLineNew(new Pair2D(vA, vB), transform, lineWidth, zPosition)); } Pair2D linearPair = Pair2D.Zero(); linearPair.A = new Vector2D(complexSlicerPointsList.First()); linearPair.B = new Vector2D(complexSlicerPointsList.Last()); trianglesList.Add(CreateLineNew(new Pair2D(new Vector2D(linearPair.A.x - size, linearPair.A.y - size), new Vector2D(linearPair.A.x + size, linearPair.A.y - size)), transform, lineWidth, zPosition)); trianglesList.Add(CreateLineNew(new Pair2D(new Vector2D(linearPair.A.x - size, linearPair.A.y - size), new Vector2D(linearPair.A.x - size, linearPair.A.y + size)), transform, lineWidth, zPosition)); trianglesList.Add(CreateLineNew(new Pair2D(new Vector2D(linearPair.A.x + size, linearPair.A.y + size), new Vector2D(linearPair.A.x + size, linearPair.A.y - size)), transform, lineWidth, zPosition)); trianglesList.Add(CreateLineNew(new Pair2D(new Vector2D(linearPair.A.x + size, linearPair.A.y + size), new Vector2D(linearPair.A.x - size, linearPair.A.y + size)), transform, lineWidth, zPosition)); trianglesList.Add(CreateLineNew(new Pair2D(new Vector2D(linearPair.B.x - size, linearPair.B.y - size), new Vector2D(linearPair.B.x + size, linearPair.B.y - size)), transform, lineWidth, zPosition)); trianglesList.Add(CreateLineNew(new Pair2D(new Vector2D(linearPair.B.x - size, linearPair.B.y - size), new Vector2D(linearPair.B.x - size, linearPair.B.y + size)), transform, lineWidth, zPosition)); trianglesList.Add(CreateLineNew(new Pair2D(new Vector2D(linearPair.B.x + size, linearPair.B.y + size), new Vector2D(linearPair.B.x + size, linearPair.B.y - size)), transform, lineWidth, zPosition)); trianglesList.Add(CreateLineNew(new Pair2D(new Vector2D(linearPair.B.x + size, linearPair.B.y + size), new Vector2D(linearPair.B.x - size, linearPair.B.y + size)), transform, lineWidth, zPosition)); return(ExportMesh2(trianglesList)); }
// This manages ball movement and collisions with level walls void UpdateMovement() { transform.Translate(direction * speed); // Balls vs Map Collisions foreach (Slicer2D slicer in Slicer2D.GetList()) { foreach (Pair2D id in Pair2D.GetList(slicer.GetPolygon().ToWorldSpace(slicer.transform).pointsList)) { if (Math2D.LineIntersectCircle(id, new Vector2D(transform.position), 1f) == true) { transform.Translate(direction * -speed); SetDirection(Math2D.ReflectAngle(direction, Vector2D.Atan2(id.A, id.B))); transform.Translate(direction * speed); } } } // Balls vs Balls Collision foreach (ThinSliceBall ball in ThinSliceBall.GetList()) { if (ball == this) { continue; } if (Vector2.Distance(transform.position, ball.transform.position) < 2) { ball.direction = Vector2D.RotToVec(Vector2D.Atan2(transform.position, ball.transform.position) - Mathf.PI).vector; direction = Vector2D.RotToVec(Vector2D.Atan2(transform.position, ball.transform.position)).vector; ball.transform.Translate(ball.direction * ball.speed); transform.Translate(direction * speed); } } }
// Not finished - still has some artifacts static public List <Vector2D> PreparePolygon(Polygon2D polygon) { Polygon2D newPolygon = new Polygon2D(); polygon.Normalize(); foreach (DoublePair2D pair in DoublePair2D.GetList(polygon.pointsList)) { float rotA = Vector2D.Atan2(pair.B, pair.A); float rotC = Vector2D.Atan2(pair.B, pair.C); Vector2D pairA = new Vector2D(pair.A); pairA.Push(rotA - Mathf.PI / 2, precision); Vector2D pairC = new Vector2D(pair.C); pairC.Push(rotC + Mathf.PI / 2, precision); Vector2D vecA = new Vector2D(pair.B); vecA.Push(rotA - Mathf.PI / 2, precision); vecA.Push(rotA, 10f); Vector2D vecC = new Vector2D(pair.B); vecC.Push(rotC + Mathf.PI / 2, precision); vecC.Push(rotC, 10f); Vector2D result = Math2D.GetPointLineIntersectLine(new Pair2D(pairA, vecA), new Pair2D(pairC, vecC)); if (result != null) { newPolygon.AddPoint(result); // } else { //Debug.LogError("Null"); } } return(newPolygon.pointsList); }
private void LinearSlice(Pair2D slice) { List <Slice2D> results = Slicer2D.LinearSliceAll(slice, null); // Adding Physics Forces if (addForce == true) { float sliceRotation = (float)Vector2D.Atan2(slice.B, slice.A); foreach (Slice2D id in results) { foreach (GameObject gameObject in id.GetGameObjects()) { Rigidbody2D rigidBody2D = gameObject.GetComponent <Rigidbody2D> (); if (rigidBody2D) { foreach (Vector2D p in id.GetCollisions()) { PhysicsHelper2D.AddForceAtPosition(rigidBody2D, new Vector2(Mathf.Cos(sliceRotation) * addForceAmount, Mathf.Sin(sliceRotation) * addForceAmount), p.ToVector2()); } } } } } }
static public List <Vector2D> GetLinearVertices(Pair2D pair, float minVertexDistance) { Vector2D startPoint = pair.A.Copy(); Vector2D endPoint = pair.B.Copy(); List <Vector2D> linearPoints = new List <Vector2D>(); int loopCount = 0; while ((Vector2D.Distance(startPoint, endPoint) > minVertexDistance)) { linearPoints.Add(startPoint.Copy()); float direction = (float)Vector2D.Atan2(endPoint, startPoint); startPoint.Push(direction, minVertexDistance); loopCount++; if (loopCount > 150) { break; } } linearPoints.Add(endPoint.Copy()); return(linearPoints); }
// Linear Slice static public Slice2D Slice(Polygon2D polygon, Pair2D slice) { Slice2D result = Slice2D.Create(null, slice); // Optimize: Cancel slicing for polygons that are not overlapping Rect sliceRect = Math2D.GetBounds(slice); Rect polygonRect = polygon.GetBounds(); if (sliceRect.Overlaps(polygonRect) == false) { return(result); } // Normalize into clockwise polygon.Normalize(); // Getting the list of intersections List <Vector2D> intersections = polygon.GetListLineIntersectPoly(slice); // Single collision cannot make a proper slice if (intersections.Count < 2) { return(result); } // Sorting intersections from one point intersections = Vector2DList.GetListSortedToPoint(intersections, slice.A); List <Pair2D> collisionList = new List <Pair2D>(); // Dividing intersections into single slices // Optimize this (polygon.PointInPoly) line // This method doesn't look like very reliable!!! foreach (Pair2D p in Pair2D.GetList(intersections, false)) { if (polygon.PointInPoly(new Vector2D((p.B.x + p.A.x) / 2, (p.B.y + p.A.y) / 2)) == true) { collisionList.Add(p); intersections.Remove(p.A); intersections.Remove(p.B); } } result.AddPolygon(polygon); // Slice line points generated from intersections list foreach (Pair2D id in collisionList) { result.AddCollision(id.A); result.AddCollision(id.B); Vector2D vec0 = new Vector2D(id.A); Vector2D vec1 = new Vector2D(id.B); double rot = Vector2D.Atan2(vec0, vec1); // Slightly pushing slice line so it intersect in all cases vec0.Push(rot, precision); vec1.Push(rot, -precision); Pair2D line = new Pair2D(vec0, vec1); // For each in polygons list attempt convex split foreach (Polygon2D poly in (new List <Polygon2D>(result.GetPolygons()))) { Slice2D resultList = SingleSlice(poly, line); if (resultList.slices.Count > 0) { foreach (List <Vector2D> i in resultList.slices) { result.AddSlice(i); } } if (resultList.GetPolygons().Count > 0) { result.AddSlice(line); foreach (Polygon2D i in resultList.GetPolygons()) { result.AddPolygon(i); } // If it's possible to perform splice, remove currently sliced polygon from result list result.RemovePolygon(poly); } } } result.RemovePolygon(polygon); return(result); }
public static void DrawLineImage(Transform transform, Pair2D pair, float z = 0f) { float size = Max2D.lineWidth * Max2D.setScale; float rot = Vector2D.Atan2(pair.A, pair.B); Vector2D A1 = new Vector2D(pair.A); Vector2D A2 = new Vector2D(pair.A); Vector2D B1 = new Vector2D(pair.B); Vector2D B2 = new Vector2D(pair.B); Vector2 scale = new Vector2(1f / transform.localScale.x, 1f / transform.localScale.y); A1.Push(rot + pi2, size, scale); A2.Push(rot - pi2, size, scale); B1.Push(rot + pi2, size, scale); B2.Push(rot - pi2, size, scale); GL.TexCoord2(0.5f + uv0, 0); GL.Vertex3(B1.vector.x, B1.vector.y, z); GL.TexCoord2(uv1, 0); GL.Vertex3(A1.vector.x, A1.vector.y, z); GL.TexCoord2(uv1, 1); GL.Vertex3(A2.vector.x, A2.vector.y, z); GL.TexCoord2(0.5f + uv0, 1); GL.Vertex3(B2.vector.x, B2.vector.y, z); A1 = new Vector2D(pair.A); A2 = new Vector2D(pair.A); Vector2D A3 = new Vector2D(pair.A); Vector2D A4 = new Vector2D(pair.A); A1.Push(rot + pi2, size, scale); A2.Push(rot - pi2, size, scale); A3.Push(rot + pi2, size, scale); A4.Push(rot - pi2, size, scale); A3.Push(rot + pi, -size, scale); A4.Push(rot + pi, -size, scale); GL.TexCoord2(uv0, 0); GL.Vertex3(A3.vector.x, A3.vector.y, z); GL.TexCoord2(uv0, 1); GL.Vertex3(A4.vector.x, A4.vector.y, z); GL.TexCoord2(0.5f - uv0, 1); GL.Vertex3(A2.vector.x, A2.vector.y, z); GL.TexCoord2(0.5f - uv0, 0); GL.Vertex3(A1.vector.x, A1.vector.y, z); B1 = new Vector2D(pair.B); B2 = new Vector2D(pair.B); Vector2D B3 = new Vector2D(pair.B); Vector2D B4 = new Vector2D(pair.B); B1.Push(rot + pi2, size, scale); B2.Push(rot - pi2, size, scale); B3.Push(rot + pi2, size, scale); B4.Push(rot - pi2, size, scale); B3.Push(rot + pi, size, scale); B4.Push(rot + pi, size, scale); GL.TexCoord2(uv0, 0); GL.Vertex3(B4.vector.x, B4.vector.y, z); GL.TexCoord2(uv0, 1); GL.Vertex3(B3.vector.x, B3.vector.y, z); GL.TexCoord2(0.5f - uv0, 1); GL.Vertex3(B1.vector.x, B1.vector.y, z); GL.TexCoord2(0.5f - uv0, 0); GL.Vertex3(B2.vector.x, B2.vector.y, z); }
void Update() { Vector3 worldPosition = (Vector2)(transform.position + new Vector3(body.centerOfMass.x, body.centerOfMass.y, 0)); body.AddForce(Vector2D.RotToVec(Vector2D.Atan2(transform.parent.position, worldPosition)).ToVector2() * 10f); }
public static void Draw(Vector2D offset, float z) { float sunDirection = LightingManager2D.GetSunDirection(); // Day Soft Shadows GL.PushMatrix(); Max2D.defaultMaterial.SetPass(0); GL.Begin(GL.TRIANGLES); GL.Color(Color.black); foreach (LightingCollider2D id in LightingCollider2D.GetList()) { if (id.dayHeight == false || id.height <= 0) { continue; } if (id.colliderType == LightingCollider2D.ColliderType.Mesh) { continue; } List <Polygon2D> polygons = null; switch (id.colliderType) { case LightingCollider2D.ColliderType.Collider: polygons = id.GetColliderPolygons(); break; case LightingCollider2D.ColliderType.SpriteCustomPhysicsShape: polygons = id.GetShapePolygons(); break; } Polygon2D poly; Vector3 vecA; Vector3 vecB; Vector3 vecC; foreach (Polygon2D polygon in polygons) { poly = polygon.ToWorldSpace(id.gameObject.transform); Polygon2D convexHull = Polygon2D.GenerateShadow(new Polygon2D(poly.pointsList), sunDirection, id.height); Mesh mesh = convexHull.CreateMesh(Vector2.zero, Vector2.zero); for (int i = 0; i < mesh.triangles.GetLength(0); i = i + 3) { vecA = mesh.vertices [mesh.triangles [i]]; vecB = mesh.vertices [mesh.triangles [i + 1]]; vecC = mesh.vertices [mesh.triangles [i + 2]]; Max2DMatrix.DrawTriangle(vecA.x, vecA.y, vecB.x, vecB.y, vecC.x, vecC.y, offset, z); } } } GL.End(); GL.PopMatrix(); GL.PushMatrix(); // Null Check? LightingManager2D.Get().shadowBlurMaterial.SetPass(0); GL.Begin(GL.TRIANGLES); Max2D.SetColor(Color.white); foreach (LightingCollider2D id in LightingCollider2D.GetList()) { if (id.dayHeight == false || id.height <= 0) { continue; } if (id.colliderType == LightingCollider2D.ColliderType.Mesh) { continue; } List <Polygon2D> polygons = null; switch (id.colliderType) { case LightingCollider2D.ColliderType.Collider: polygons = id.GetColliderPolygons(); break; case LightingCollider2D.ColliderType.SpriteCustomPhysicsShape: polygons = id.GetShapePolygons(); break; } foreach (Polygon2D polygon in polygons) { Polygon2D poly = polygon.ToWorldSpace(id.gameObject.transform); Polygon2D convexHull = Polygon2D.GenerateShadow(new Polygon2D(poly.pointsList), sunDirection, id.height); foreach (DoublePair2D p in DoublePair2D.GetList(convexHull.pointsList)) { Vector2D zA = new Vector2D(p.A + offset); Vector2D zB = new Vector2D(p.B + offset); Vector2D zC = zB.Copy(); Vector2D pA = zA.Copy(); Vector2D pB = zB.Copy(); zA.Push(Vector2D.Atan2(p.A, p.B) + pi2, .5f); zB.Push(Vector2D.Atan2(p.A, p.B) + pi2, .5f); zC.Push(Vector2D.Atan2(p.B, p.C) + pi2, .5f); GL.TexCoord2(uv0, uv0); Max2D.Vertex3(pB, z); GL.TexCoord2(0.5f - uv0, uv0); Max2D.Vertex3(pA, z); GL.TexCoord2(0.5f - uv0, uv1); Max2D.Vertex3(zA, z); GL.TexCoord2(uv0, uv1); Max2D.Vertex3(zA, z); GL.TexCoord2(0.5f - uv0, uv1); Max2D.Vertex3(zB, z); GL.TexCoord2(0.5f - uv0, uv0); Max2D.Vertex3(pB, z); GL.TexCoord2(uv0, uv1); Max2D.Vertex3(zB, z); GL.TexCoord2(0.5f - uv0, uv0); Max2D.Vertex3(pB, z); GL.TexCoord2(0.5f - uv0, uv1); Max2D.Vertex3(zC, z); } } } GL.End(); GL.PopMatrix(); #if UNITY_2018_1_OR_NEWER GL.PushMatrix(); Max2D.defaultMaterial.SetPass(0); GL.Begin(GL.TRIANGLES); GL.Color(Color.black); // Day Soft Shadows foreach (LightingTilemapCollider2D id in LightingTilemapCollider2D.GetList()) { if (id.map == null) { continue; } if (id.dayHeight == false) { continue; } for (int x = 0; x < id.area.size.x; x++) { for (int y = 0; y < id.area.size.y; y++) { if (id.map[x, y] == null) { DrawSoftShadowTile(offset + new Vector2D(x, y), z, id.height); } } } } GL.End(); GL.PopMatrix(); GL.PushMatrix(); LightingManager2D.Get().shadowBlurMaterial.SetPass(0); GL.Begin(GL.TRIANGLES); Max2D.SetColor(Color.white); // Day Soft Shadows foreach (LightingTilemapCollider2D id in LightingTilemapCollider2D.GetList()) { if (id.map == null) { continue; } if (id.dayHeight == false) { continue; } for (int x = 0; x < id.area.size.x; x++) { for (int y = 0; y < id.area.size.y; y++) { if (id.map[x, y] == null) { DrawSoftShadowTileBlur(offset + new Vector2D(x, y), z, id.height); } } } } GL.End(); GL.PopMatrix(); #endif /* * * Material material = LightingManager2D.Get().whiteSpriteMaterial; * foreach (LightingSprite2D id in LightingSprite2D.GetList()) { * if (id.GetSpriteRenderer() == null) { * continue; * } * material.mainTexture = id.GetSpriteRenderer().sprite.texture; //Debug.Log(sprite.pivot); * * Vector2 p = id.transform.position; * Vector2 scale = id.transform.lossyScale; * * if (id.GetSpriteRenderer().flipX) { * scale.x = -scale.x; * } * * if (id.GetSpriteRenderer().flipY) { * scale.y = -scale.y; * } * * Max2D.DrawImage(material, offset.ToVector2() + p, scale, id.transform.rotation.eulerAngles.z, z); * } */ float ratio = (float)Screen.width / Screen.height; Camera bufferCamera = LightingMainBuffer2D.Get().bufferCamera; Vector2 size = new Vector2(bufferCamera.orthographicSize * ratio, bufferCamera.orthographicSize); Vector3 pos = Camera.main.transform.position; Max2D.DrawImage(LightingManager2D.Get().additiveMaterial, new Vector2D(pos), new Vector2D(size), pos.z); // Day Lighting Masking foreach (LightingCollider2D id in LightingCollider2D.GetList()) { if (id.generateDayMask == false) { continue; } switch (id.maskType) { case LightingCollider2D.MaskType.SpriteCustomPhysicsShape: Max2D.SetColor(Color.white); Max2D.DrawMesh(Max2D.defaultMaterial, id.GetShapeMesh(), id.transform, offset, z); break; case LightingCollider2D.MaskType.Collider: Max2D.SetColor(Color.white); Max2D.DrawMesh(Max2D.defaultMaterial, id.GetColliderMesh(), id.transform, offset, z); break; case LightingCollider2D.MaskType.Sprite: if (id.spriteRenderer == null || id.spriteRenderer.sprite == null) { break; } Material material = LightingManager2D.Get().whiteSpriteMaterial; material.mainTexture = id.spriteRenderer.sprite.texture; Max2D.DrawSprite(material, id.spriteRenderer, new Vector2(id.transform.position.x, id.transform.position.y) + offset.ToVector2(), new Vector2(1, 1), id.transform.rotation.eulerAngles.z, z); break; } } }
public static void DrawLineImage(Pair2D pair, float z = 0f) { float size = Max2D.lineWidth * Max2D.setScale; float rot = (float)Vector2D.Atan2(pair.A, pair.B); Vector2D A1 = new Vector2D(pair.A); Vector2D A2 = new Vector2D(pair.A); Vector2D B1 = new Vector2D(pair.B); Vector2D B2 = new Vector2D(pair.B); A1.Push(rot + pi2, size); A2.Push(rot - pi2, size); B1.Push(rot + pi2, size); B2.Push(rot - pi2, size); GL.TexCoord2(0.5f + uv0, 0); GL.Vertex3((float)B1.x, (float)B1.y, z); GL.TexCoord2(uv1, 0); GL.Vertex3((float)A1.x, (float)A1.y, z); GL.TexCoord2(uv1, 1); GL.Vertex3((float)A2.x, (float)A2.y, z); GL.TexCoord2(0.5f + uv0, 1); GL.Vertex3((float)B2.x, (float)B2.y, z); A1 = new Vector2D(pair.A); A2 = new Vector2D(pair.A); Vector2D A3 = new Vector2D(pair.A); Vector2D A4 = new Vector2D(pair.A); A1.Push(rot + pi2, size); A2.Push(rot - pi2, size); A3.Push(rot + pi2, size); A4.Push(rot - pi2, size); A3.Push(rot + pi, -size); A4.Push(rot + pi, -size); GL.TexCoord2(uv0, 0); GL.Vertex3((float)A3.x, (float)A3.y, z); GL.TexCoord2(uv0, 1); GL.Vertex3((float)A4.x, (float)A4.y, z); GL.TexCoord2(0.5f - uv0, 1); GL.Vertex3((float)A2.x, (float)A2.y, z); GL.TexCoord2(0.5f - uv0, 0); GL.Vertex3((float)A1.x, (float)A1.y, z); B1 = new Vector2D(pair.B); B2 = new Vector2D(pair.B); Vector2D B3 = new Vector2D(pair.B); Vector2D B4 = new Vector2D(pair.B); B1.Push(rot + pi2, size); B2.Push(rot - pi2, size); B3.Push(rot + pi2, size); B4.Push(rot - pi2, size); B3.Push(rot + pi, size); B4.Push(rot + pi, size); GL.TexCoord2(uv0, 0); GL.Vertex3((float)B4.x, (float)B4.y, z); GL.TexCoord2(uv0, 1); GL.Vertex3((float)B3.x, (float)B3.y, z); GL.TexCoord2(0.5f - uv0, 1); GL.Vertex3((float)B1.x, (float)B1.y, z); GL.TexCoord2(0.5f - uv0, 0); GL.Vertex3((float)B2.x, (float)B2.y, z); }
public void UpdateSliceAnimations() { if (animationPairs.Count < 1) { return; } if (PointSlicerSlash.GetList().Count > 0) { return; } Pair2D animationPair = animationPairs.First(); Slicer2D.LinearSliceAll(animationPair, sliceLayer); Vector3 position = animationPair.A.ToVector2(); position.z = -1; GameObject particleGameObject = Instantiate(particlePrefab, position, Quaternion.Euler(0, 0, (float)Vector2D.Atan2(animationPair.A, animationPair.B) * Mathf.Rad2Deg)); PointSlicerSlash particle = particleGameObject.GetComponent <PointSlicerSlash>(); particle.moveTo = animationPair.B; animationPairs.Remove(animationPair); }
public static void Penumbra_Component(LightingBuffer2D buffer, LightingTilemapCollider2D id, float lightSizeSquared, float z) { Vector2D vA, pA, vB, pB; foreach (Polygon2D polygon in id.edgeColliders) { Vector2D polyOffset = new Vector2D(-buffer.lightSource.transform.position); Polygon2D poly = polygon.Copy(); poly.ToOffsetItself(polyOffset); foreach (Pair2D p in Pair2D.GetList(poly.pointsList, false)) { vA = p.A.Copy(); pA = p.A.Copy(); vB = p.B.Copy(); pB = p.B.Copy(); float angleA = (float)Vector2D.Atan2(vA, zero); float angleB = (float)Vector2D.Atan2(vB, zero); vA.Push(angleA, lightSizeSquared); pA.Push(angleA - Mathf.Deg2Rad * buffer.lightSource.occlusionSize, lightSizeSquared); vB.Push(angleB, lightSizeSquared); pB.Push(angleB + Mathf.Deg2Rad * buffer.lightSource.occlusionSize, lightSizeSquared); GL.TexCoord2(uv0, uv0); GL.Vertex3((float)p.A.x, (float)p.A.y, z); GL.TexCoord2(uv1, uv0); GL.Vertex3((float)vA.x, (float)vA.y, z); GL.TexCoord2((float)uv0, uv1); GL.Vertex3((float)pA.x, (float)pA.y, z); GL.TexCoord2(uv0, uv0); GL.Vertex3((float)p.B.x, (float)p.B.y, z); GL.TexCoord2(uv1, uv0); GL.Vertex3((float)vB.x, (float)vB.y, z); GL.TexCoord2(uv0, uv1); GL.Vertex3((float)pB.x, (float)pB.y, z); } //LightingDebug.penumbraGenerations ++; } foreach (Polygon2D polygon in id.polygonColliders) { Vector2D polyOffset = new Vector2D(-buffer.lightSource.transform.position); Polygon2D poly = polygon.Copy(); poly.ToOffsetItself(polyOffset); foreach (Pair2D p in Pair2D.GetList(poly.pointsList)) { vA = p.A.Copy(); pA = p.A.Copy(); vB = p.B.Copy(); pB = p.B.Copy(); float angleA = (float)Vector2D.Atan2(vA, zero); float angleB = (float)Vector2D.Atan2(vB, zero); vA.Push(angleA, lightSizeSquared); pA.Push(angleA - Mathf.Deg2Rad * buffer.lightSource.occlusionSize, lightSizeSquared); vB.Push(angleB, lightSizeSquared); pB.Push(angleB + Mathf.Deg2Rad * buffer.lightSource.occlusionSize, lightSizeSquared); GL.TexCoord2(uv0, uv0); GL.Vertex3((float)p.A.x, (float)p.A.y, z); GL.TexCoord2(uv1, uv0); GL.Vertex3((float)vA.x, (float)vA.y, z); GL.TexCoord2((float)uv0, uv1); GL.Vertex3((float)pA.x, (float)pA.y, z); GL.TexCoord2(uv0, uv0); GL.Vertex3((float)p.B.x, (float)p.B.y, z); GL.TexCoord2(uv1, uv0); GL.Vertex3((float)vB.x, (float)vB.y, z); GL.TexCoord2(uv0, uv1); GL.Vertex3((float)pB.x, (float)pB.y, z); } //LightingDebug.penumbraGenerations ++; } }
static public List <Vector2D> Get(Polygon2D polygon, float multiplier = 1f) { Polygon2D newPolygon = new Polygon2D(); polygon.Normalize(); Vector2D result; double rotA, rotC; Vector2D pB; for (int i = 0; i < polygon.pointsList.Count; i++) { pB = polygon.pointsList[i]; int indexB = polygon.pointsList.IndexOf(pB); int indexA = (indexB - 1); if (indexA < 0) { indexA += polygon.pointsList.Count; } int indexC = (indexB + 1); if (indexC >= polygon.pointsList.Count) { indexC -= polygon.pointsList.Count; } pair.A = polygon.pointsList[indexA]; pair.B = pB; pair.C = polygon.pointsList[indexC]; rotA = Vector2D.Atan2(pair.B, pair.A); rotC = Vector2D.Atan2(pair.B, pair.C); pairA.x = pair.A.x; pairA.y = pair.A.y; pairA.Push(rotA - Mathf.PI / 2, precision * multiplier); pairC.x = pair.C.x; pairC.y = pair.C.y; pairC.Push(rotC + Mathf.PI / 2, precision * multiplier); vecA.x = pair.B.x; vecA.y = pair.B.y; vecA.Push(rotA - Mathf.PI / 2, precision * multiplier); vecA.Push(rotA, 100f); vecC.x = pair.B.x; vecC.y = pair.B.y; vecC.Push(rotC + Mathf.PI / 2, precision * multiplier); vecC.Push(rotC, 100f); pair0.A = pairA; pair0.B = vecA; pair1.A = pairC; pair1.B = vecC; result = Math2D.GetPointLineIntersectLine(pair0, pair1); if (result != null) { newPolygon.AddPoint(result); } } return(newPolygon.pointsList); }
public List <Vector2D> GetPointsList(float multiplier = 1f) { if (pointsList == null) { Debug.LogError("Complex Cut generation issue"); return(new List <Vector2D>()); } float sizeM = size * multiplier; float sizeM2 = 2 * sizeM; List <Vector2D> list = new List <Vector2D>(pointsList); if (list.Count < 2) { return(new List <Vector2D>()); } List <Vector2D> newPointsListA = new List <Vector2D>(); List <Vector2D> newPointsListB = new List <Vector2D>(); if (list.Count > 2) { foreach (DoublePair2D pair in DoublePair2D.GetList(list)) { float rotA = (float)Vector2D.Atan2(pair.B, pair.A); float rotC = (float)Vector2D.Atan2(pair.B, pair.C); Vector2D pairA = new Vector2D(pair.A); pairA.Push(rotA - Mathf.PI / 2, sizeM); Vector2D pairC = new Vector2D(pair.C); pairC.Push(rotC + Mathf.PI / 2, sizeM); Vector2D vecA = new Vector2D(pair.B); vecA.Push(rotA - Mathf.PI / 2, sizeM); vecA.Push(rotA, 10f); Vector2D vecC = new Vector2D(pair.B); vecC.Push(rotC + Mathf.PI / 2, sizeM); vecC.Push(rotC, 10f); Vector2D result = Math2D.GetPointLineIntersectLine(new Pair2D(pairA, vecA), new Pair2D(pairC, vecC)); if (result != null) { newPointsListA.Add(result); } } if (newPointsListA.Count > 2) { newPointsListA.Remove(newPointsListA.First()); newPointsListA.Remove(newPointsListA.Last()); } foreach (DoublePair2D pair in DoublePair2D.GetList(list, false)) { float rotA = (float)Vector2D.Atan2(pair.B, pair.A); float rotC = (float)Vector2D.Atan2(pair.B, pair.C); Vector2D pairA = new Vector2D(pair.A); pairA.Push(rotA - Mathf.PI / 2, -sizeM); Vector2D pairC = new Vector2D(pair.C); pairC.Push(rotC + Mathf.PI / 2, -sizeM); Vector2D vecA = new Vector2D(pair.B); vecA.Push(rotA - Mathf.PI / 2, -sizeM); vecA.Push(rotA, 10f); Vector2D vecC = new Vector2D(pair.B); vecC.Push(rotC + Mathf.PI / 2, -sizeM); vecC.Push(rotC, 10f); Vector2D result = Math2D.GetPointLineIntersectLine(new Pair2D(pairA, vecA), new Pair2D(pairC, vecC)); if (result != null) { newPointsListB.Add(result); } } if (newPointsListB.Count > 2) { newPointsListB.Remove(newPointsListB.First()); newPointsListB.Remove(newPointsListB.Last()); } } List <Vector2D> newPointsList = new List <Vector2D>(); foreach (Vector2D p in newPointsListA) { newPointsList.Add(p); } Vector2D prevA = new Vector2D(list.ElementAt(list.Count - 2)); Vector2D pA = new Vector2D(list.Last()); pA.Push(Vector2D.Atan2(pA, prevA) - Mathf.PI / 6, sizeM2); newPointsList.Add(pA); pA = new Vector2D(list.Last()); pA.Push(Vector2D.Atan2(pA, prevA) + Mathf.PI / 6, sizeM2); newPointsList.Add(pA); newPointsListB.Reverse(); foreach (Vector2D p in newPointsListB) { newPointsList.Add(p); } Vector2D prevB = new Vector2D(list.ElementAt(1)); Vector2D pB = new Vector2D(list.First()); pB.Push(Vector2D.Atan2(pB, prevB) - Mathf.PI / 6, sizeM2); newPointsList.Add(pB); pB = new Vector2D(list.First()); pB.Push(Vector2D.Atan2(pB, prevB) + Mathf.PI / 6, sizeM2); newPointsList.Add(pB); return(newPointsList); }
static private Slice2D MultipleSlice(Polygon2D polygon, Pair2D slice) { Slice2D result = Slice2D.Create(null, slice); List <Pair2D> slices = GetSplitSlices(polygon, slice); //Debug.Log(slices.Count); //Debug.Log(slices[0].A.ToVector2() + " " + slices[0].B.ToVector2()); //Debug.Log(slices[1].A.ToVector2() + " " + slices[1].B.ToVector2()); if (slices.Count < 1) { return(result); } result.AddPolygon(polygon); // Slice line points generated from intersections list foreach (Pair2D id in slices) { result.AddCollision(id.A); result.AddCollision(id.B); Vector2D vec0 = new Vector2D(id.A); Vector2D vec1 = new Vector2D(id.B); double rot = Vector2D.Atan2(vec0, vec1); // Slightly pushing slice line so it intersect in all cases vec0.Push(rot, precision); vec1.Push(rot, -precision); Pair2D line = new Pair2D(vec0, vec1); // For each in polygons list attempt convex split foreach (Polygon2D poly in (new List <Polygon2D>(result.GetPolygons()))) { Slice2D resultList = SingleSlice(poly, line); if (resultList.GetPolygons().Count > 0) { if (resultList.slices.Count > 0) { foreach (List <Vector2D> i in resultList.slices) { result.AddSlice(i); } } result.AddSlice(line); foreach (Polygon2D i in resultList.GetPolygons()) { result.AddPolygon(i); } // If it's possible to perform splice, remove currently sliced polygon from result list result.RemovePolygon(poly); } } } result.RemovePolygon(polygon); return(result); }
static public Slice2D Slice(Polygon2D polygon, List <Vector2D> slice) { Slice2D result = Slice2D.Create(null, slice); if (slice.Count < 2) { return(result); } // Normalize into clockwise polygon.Normalize(); // Optimize slicing for polygons that are far away Rect sliceRect = Math2D.GetBounds(slice); Rect polygonRect = polygon.GetBounds(); if (sliceRect.Overlaps(polygonRect) == false) { return(result); } // Change if (Slicer2D.complexSliceType != Slicer2D.SliceType.Regular) { result = SlicePolygonInside(polygon, slice); if (result.GetPolygons().Count > 0) { return(result); } } // Optimization (holes?) // if (polygon.SliceIntersectPoly (slice) == false) // return(result); List <List <Vector2D> > slices = new List <List <Vector2D> >(); bool entered = polygon.PointInPoly(slice.First()); List <Vector2D> currentSlice = new List <Vector2D> (); Pair2D pair = Pair2D.Zero(); for (int i = 0; i < slice.Count - 1; i++) { pair.A = slice[i]; pair.B = slice[i + 1]; List <Vector2D> stackList = polygon.GetListLineIntersectPoly(pair); stackList = Vector2DList.GetListSortedToPoint(stackList, pair.A); foreach (Vector2D id in stackList) { if (entered == true) { currentSlice.Add(id); slices.Add(currentSlice); } else { currentSlice = new List <Vector2D> (); currentSlice.Add(id); } entered = !entered; } if (entered == true) { currentSlice.Add(pair.B); } } // Adjusting split lines before performing convex split result.AddPolygon(polygon); foreach (List <Vector2D> id in slices) { if (id.Count > 1) { foreach (Vector2D p in id) { result.AddCollision(p); } // Sclice line points generated from intersections list Vector2D vec0 = id.First(); vec0.Push(Vector2D.Atan2(vec0, id[1]), precision); Vector2D vec1 = id.Last(); vec1.Push(Vector2D.Atan2(vec1, id[id.Count - 2]), precision); // For each in polygons list attempt convex split List <Polygon2D> temp = new List <Polygon2D>(result.GetPolygons()); // necessary? foreach (Polygon2D poly in temp) { Slice2D resultList = SingleSlice(poly, id); if (resultList.slices.Count > 0) { foreach (List <Vector2D> i in resultList.slices) { result.AddSlice(i); } } if (resultList.GetPolygons().Count > 0) { foreach (Polygon2D i in resultList.GetPolygons()) { result.AddPolygon(i); } // If it's possible to perform convex split, remove parent polygon from result list result.RemovePolygon(poly); } } } } result.RemovePolygon(polygon); return(result); }
static private Slice2D MultipleSlice(Polygon2D polygon, List <Vector2D> slice) { Slice2D result = Slice2D.Create(null, slice); List <ComplexSlicerSplit> slices = ComplexSlicerSplit.GetSplitSlices(polygon, slice); if (slices.Count < 1) { return(result); } // Adjusting split lines before performing convex split result.AddPolygon(polygon); foreach (ComplexSlicerSplit id in slices) { if (id.points.Count > 1) { foreach (Vector2D p in id.points) { result.AddCollision(p); } // Sclice line points generated from intersections list Vector2D vec0 = id.points.First(); vec0.Push(Vector2D.Atan2(vec0, id.points[1]), precision); Vector2D vec1 = id.points.Last(); vec1.Push(Vector2D.Atan2(vec1, id.points[id.points.Count - 2]), precision); // For each in polygons list attempt convex split List <Polygon2D> resultPolygons = new List <Polygon2D>(result.GetPolygons()); // necessary? foreach (Polygon2D poly in resultPolygons) { Slice2D resultList = SingleSlice(poly, id); if (resultList.GetPolygons().Count > 0) { if (resultList.slices.Count > 0) { foreach (List <Vector2D> resultSlice in resultList.slices) { result.AddSlice(resultSlice); } } foreach (Polygon2D resultPoly in resultList.GetPolygons()) { result.AddPolygon(resultPoly); } // If it's possible to perform convex split, remove parent polygon from result list result.RemovePolygon(poly); } } } } //Debug.Log("1 " + slices[0].Count + " " + slices[0][0].ToVector2() + " " + slices[0][1].ToVector2()); //Debug.Log("2 " + slices[1].Count + " " + slices[1][0].ToVector2() + " " + slices[1][1].ToVector2()); // if exist then remove slice was not performed result.RemovePolygon(polygon); return(result); }
private void UpdateComplex(Vector2D pos) { if (Input.GetMouseButtonDown(0)) { pointsList.Clear(); pointsList.Add(pos); mouseDown = true; startedSlice = false; } if (pointsList.Count < 1) { return; } if (Input.GetMouseButton(0)) { Vector2D posMove = pointsList.Last().Copy(); bool added = false; int loopCount = 0; while ((Vector2D.Distance(posMove, pos) > minVertexDistance * visualScale)) { float direction = (float)Vector2D.Atan2(pos, posMove); posMove.Push(direction, minVertexDistance * visualScale); if (startSliceIfPossible == true && startedSlice == false) { if (InSlicerComponents(posMove.Copy())) { while (pointsList.Count > 2) { pointsList.RemoveAt(0); } startedSlice = true; } } pointsList.Add(posMove.Copy()); added = true; loopCount++; if (loopCount > 150) { break; } } if (endSliceIfPossible == true && added) { if (ComplexSlice(pointsList) == true) { mouseDown = false; pointsList.Clear(); if (startSliceIfPossible) { pointsList.Add(pos); mouseDown = true; startedSlice = false; } } } } if (mouseDown == true && Input.GetMouseButton(0) == false) { mouseDown = false; startedSlice = false; Slicer2D.complexSliceType = complexSliceType; ComplexSlice(pointsList); pointsList.Clear(); } }
// Slice From Point static public Slice2D SliceFromPoint(Polygon2D polygon, Vector2D point, float rotation) { Slice2D result = Slice2D.Create(point, rotation); // Normalize into clockwise polygon.Normalize(); Vector2D sliceA = new Vector2D(point); Vector2D sliceB = new Vector2D(point); sliceA.Push(rotation, 1e+10f / 2); sliceB.Push(rotation, -1e+10f / 2); if (polygon.PointInPoly(point) == false) { return(result); } // Getting the list of intersections List <Vector2D> intersectionsA = polygon.GetListLineIntersectPoly(new Pair2D(point, sliceA)); List <Vector2D> intersectionsB = polygon.GetListLineIntersectPoly(new Pair2D(point, sliceB)); // Sorting intersections from one point if (intersectionsA.Count > 0 && intersectionsB.Count > 0) { sliceA = Vector2DList.GetListSortedToPoint(intersectionsA, point) [0]; sliceB = Vector2DList.GetListSortedToPoint(intersectionsB, point) [0]; } else { return(result); } List <Pair2D> collisionList = new List <Pair2D>(); collisionList.Add(new Pair2D(sliceA, sliceB)); result.AddPolygon(polygon); foreach (Pair2D id in collisionList) { result.AddCollision(id.A); result.AddCollision(id.B); // Sclice line points generated from intersections list Vector2D vec0 = new Vector2D(id.A); Vector2D vec1 = new Vector2D(id.B); double rot = Vector2D.Atan2(vec0, vec1); // Slightly pushing slice line so it intersect in all cases vec0.Push(rot, LinearSlicer.precision); vec1.Push(rot, -LinearSlicer.precision); // For each in polygons list attempt convex split List <Polygon2D> temp = new List <Polygon2D>(result.polygons); // necessary? foreach (Polygon2D poly in temp) { // NO, that's the problem Slice2D resultList = LinearSlicer.Slice(poly, new Pair2D(vec0, vec1)); if (resultList.slices.Count > 0) { foreach (List <Vector2D> i in resultList.slices) { result.AddSlice(i); } } if (resultList.polygons.Count > 0) { foreach (Polygon2D i in resultList.polygons) { result.AddPolygon(i); } // If it's possible to perform splice, remove parent polygon from result list result.RemovePolygon(poly); } } } result.RemovePolygon(polygon); return(result); }
void GlobalSliceEvent(Slice2D slice) { Vector3 position = slice.slice[0].ToVector2(); position.z = -5; GameObject particleGameObject = Instantiate(particlePrefab, position, Quaternion.Euler(0, 0, (float)Vector2D.Atan2(slice.slice[0], slice.slice[1]) * Mathf.Rad2Deg)); PointSlicerSlash particle = particleGameObject.GetComponent <PointSlicerSlash>(); particle.moveTo = slice.slice[1]; }
public void Update() { input.Update(); if (visuals.drawSlicer == false) { return; } if (linearPair.A.ToVector2() == Vector2.zero && linearPair.B.ToVector2() == Vector2.zero) { return; } visuals.Clear(); visuals.GenerateLinearMesh(linearPair, transform); visuals.Draw(); if (target != null) { Polygon2D poly = target.shape.GetWorld(); int pointIDA = ((verticeID - 1) + poly.pointsList.Count) % poly.pointsList.Count; int pointIDB = verticeID; int pointIDC = (verticeID + 1) % poly.pointsList.Count; Vector2 pointA = poly.pointsList[pointIDA].ToVector2(); Vector2 pointB = poly.pointsList[pointIDB].ToVector2(); Vector2 pointC = poly.pointsList[pointIDC].ToVector2(); double angle = Math2D.FindAngle(pointA, pointB, pointC); Vector2D offset = new Vector2D(pointB); double angleZero = Vector2D.Atan2(new Vector2D(pointA), new Vector2D(pointB)); Debug.Log(angle * Mathf.Rad2Deg); offset.Push(-angle / 2 + angleZero, 0.5f); linearPair.A = offset; } if (Input.GetMouseButtonDown(1)) { Vector2D point = input.GetInputPosition(0); if (target != null) { Polygon2D poly = target.shape.GetWorld(); if (poly.PointInPoly(point) == false) { target = null; linearPair.A = Vector2D.Zero(); linearPair.B = Vector2D.Zero(); } } foreach (Slicer2D slicer in Slicer2D.GetList()) { Polygon2D poly = slicer.shape.GetWorld(); if (poly.PointInPoly(point)) { int id = 0; double distance = 1000000; foreach (Vector2D p in poly.pointsList) { double newDistance = Vector2D.Distance(p, point); if (newDistance < distance) { distance = newDistance; id = poly.pointsList.IndexOf(p); } } verticeID = id; target = slicer; break; } } } }
void DrawSoftShadows(Vector2D offset, float z) { float sunDirection = LightingManager2D.GetSunDirection(); // Day Soft Shadows foreach (LightingCollider2D id in LightingCollider2D.GetList()) { if (id.dayHeight && id.height > 0) { Polygon2D poly = id.GetPolygon(); poly = poly.ToWorldSpace(id.gameObject.transform); GL.PushMatrix(); Max2D.defaultMaterial.SetPass(0); GL.Begin(GL.TRIANGLES); GL.Color(Color.black); foreach (Pair2D p in Pair2D.GetList(poly.pointsList)) { Vector2D vA = p.A.Copy(); Vector2D vB = p.B.Copy(); vA.Push(sunDirection, id.height); vB.Push(sunDirection, id.height); Max2DMatrix.DrawTriangle(p.A, p.B, vA, offset, z); Max2DMatrix.DrawTriangle(vA, vB, p.B, offset, z); } GL.End(); GL.PopMatrix(); Polygon2D convexHull = id.GenerateShadow(new Polygon2D(poly.pointsList), sunDirection); Max2D.SetColor(Color.white); GL.PushMatrix(); LightingManager2D.Get().shadowBlurMaterial.SetPass(0); GL.Begin(GL.TRIANGLES); foreach (DoublePair2D p in DoublePair2D.GetList(convexHull.pointsList)) { Vector2D zA = new Vector2D(p.A + offset); Vector2D zB = new Vector2D(p.B + offset); Vector2D zC = new Vector2D(p.B + offset); Vector2D pA = zA.Copy(); Vector2D pB = zB.Copy(); zA.Push(Vector2D.Atan2(p.A, p.B) + pi2, .5f); zB.Push(Vector2D.Atan2(p.A, p.B) + pi2, .5f); zC.Push(Vector2D.Atan2(p.B, p.C) + pi2, .5f); GL.TexCoord2(uv0, uv0); Max2D.Vertex3(pB, z); GL.TexCoord2(0.5f - uv0, uv0); Max2D.Vertex3(pA, z); GL.TexCoord2(0.5f - uv0, uv1); Max2D.Vertex3(zA, z); GL.TexCoord2(uv0, uv1); Max2D.Vertex3(zA, z); GL.TexCoord2(0.5f - uv0, uv1); Max2D.Vertex3(zB, z); GL.TexCoord2(0.5f - uv0, uv0); Max2D.Vertex3(pB, z); GL.TexCoord2(uv0, uv1); Max2D.Vertex3(zB, z); GL.TexCoord2(0.5f - uv0, uv0); Max2D.Vertex3(pB, z); GL.TexCoord2(0.5f - uv0, uv1); Max2D.Vertex3(zC, z); } GL.End(); GL.PopMatrix(); } } foreach (LightingCollider2D id in LightingCollider2D.GetList()) { Max2D.SetColor(Color.white); Max2D.iDrawMesh(id.GetMesh(), id.transform, offset, z); } Vector2 size = new Vector2(bufferCamera.orthographicSize * ((float)Screen.width / Screen.height), bufferCamera.orthographicSize); Vector3 pos = Camera.main.transform.position; Max2D.iDrawImage(LightingManager2D.Get().additiveMaterial, new Vector2D(pos), new Vector2D(size), pos.z); }
public static void Shadow(LightingBuffer2D buffer, LightingCollider2D id, float lightSizeSquared, float z) { if (id.shape.colliderType != LightingCollider2D.ColliderType.Mesh) { return; } if (id.isVisibleForLight(buffer) == false) { return; } if (id.meshFilter == null) { return; } List <Polygon2D> polygons = new List <Polygon2D>(); Mesh mesh = id.meshFilter.sharedMesh; Vector3 vecA, vecB, vecC; Vector2D vA, pA, vB, pB; float angleA, angleB; for (int i = 0; i < mesh.triangles.GetLength(0); i = i + 3) { vecA = buffer.transform.TransformPoint(mesh.vertices [mesh.triangles [i]]); vecB = buffer.transform.TransformPoint(mesh.vertices [mesh.triangles [i + 1]]); vecC = buffer.transform.TransformPoint(mesh.vertices [mesh.triangles [i + 2]]); Polygon2D poly = new Polygon2D(); poly.AddPoint(vecA.x, vecA.y); poly.AddPoint(vecB.x, vecB.y); poly.AddPoint(vecC.x, vecC.y); //polygons.Add(poly); } if (polygons.Count < 1) { return; } Sprite penumbraSprite = LightingManager2D.Get().materials.GetAtlasPenumbraSprite(); Rect uvRect = new Rect((float)penumbraSprite.rect.x / penumbraSprite.texture.width, (float)penumbraSprite.rect.y / penumbraSprite.texture.height, (float)penumbraSprite.rect.width / penumbraSprite.texture.width, (float)penumbraSprite.rect.height / penumbraSprite.texture.height); uvRect.width += uvRect.x; uvRect.height += uvRect.y; uvRect.x += 1f / 2048; uvRect.y += 1f / 2048; uvRect.width -= 1f / 2048; uvRect.height -= 1f / 2048; GL.Color(Color.white); foreach (Polygon2D polygon in polygons) { Polygon2D poly = polygon.ToWorldSpace(id.gameObject.transform); poly.ToOffsetItself(new Vector2D(-buffer.lightSource.transform.position)); if (poly.PointInPoly(zero)) { continue; } foreach (Pair2D p in Pair2D.GetList(poly.pointsList)) { vA = p.A.Copy(); pA = p.A.Copy(); vB = p.B.Copy(); pB = p.B.Copy(); angleA = (float)Vector2D.Atan2(vA, zero); angleB = (float)Vector2D.Atan2(vB, zero); vA.Push(angleA, lightSizeSquared); pA.Push(angleA - Mathf.Deg2Rad * buffer.lightSource.occlusionSize, lightSizeSquared); vB.Push(angleB, lightSizeSquared); pB.Push(angleB + Mathf.Deg2Rad * buffer.lightSource.occlusionSize, lightSizeSquared); GL.TexCoord2(uvRect.x, uvRect.y); GL.Vertex3((float)p.A.x, (float)p.A.y, z); GL.TexCoord2(uvRect.width, uvRect.y); GL.Vertex3((float)vA.x, (float)vA.y, z); GL.TexCoord2((float)uvRect.x, uvRect.height); GL.Vertex3((float)pA.x, (float)pA.y, z); GL.TexCoord2(uvRect.x, uvRect.y); GL.Vertex3((float)p.B.x, (float)p.B.y, z); GL.TexCoord2(uvRect.width, uvRect.y); GL.Vertex3((float)vB.x, (float)vB.y, z); GL.TexCoord2(uvRect.x, uvRect.height); GL.Vertex3((float)pB.x, (float)pB.y, z); } //LightingDebug.penumbraGenerations ++; } GL.Color(Color.black); foreach (Polygon2D polygon in polygons) { Polygon2D poly = polygon.ToWorldSpace(id.gameObject.transform); poly.ToOffsetItself(new Vector2D(-buffer.lightSource.transform.position)); if (poly.PointInPoly(zero)) { continue; } foreach (Pair2D p in Pair2D.GetList(poly.pointsList, false)) { vA = p.A.Copy(); vB = p.B.Copy(); vA.Push(Vector2D.Atan2(vA, zero), lightSizeSquared); vB.Push(Vector2D.Atan2(vB, zero), lightSizeSquared); Max2DMatrix.DrawTriangle(p.A, p.B, vA, zero, z); Max2DMatrix.DrawTriangle(vA, vB, p.B, zero, z); } LightingDebug.shadowGenerations++; } }
public Collision(Polygon2D polygon, List <Vector2D> slice) { bool enterCollision = false; Pair2D pair = Pair2D.Zero(); // Generate correct intersected slice List <Vector2D> intersections; for (int i = 0; i < slice.Count - 1; i++) { pair.A = slice[i]; pair.B = slice[i + 1]; intersections = polygon.GetListLineIntersectPoly(pair); switch (intersections.Count) { case 1: collisionCount += 1; collisionSlice.Add(new Point(intersections[0], Point.Type.Intersection)); enterCollision = !enterCollision; break; case 2: collisionCount += 2; if (Vector2D.Distance(intersections[0], pair.A) < Vector2D.Distance(intersections[1], pair.A)) { collisionSlice.Add(new Point(intersections[0], Point.Type.Intersection)); collisionSlice.Add(new Point(intersections[1], Point.Type.Intersection)); } else { collisionSlice.Add(new Point(intersections[1], Point.Type.Intersection)); collisionSlice.Add(new Point(intersections[0], Point.Type.Intersection)); } intersection.A = intersections[0]; intersection.B = intersections[1]; break; case 0: break; default: error = true; break; } if (enterCollision == true) { collisionSlice.Add(new Point(pair.B, Point.Type.Inside)); } } List <Vector2D> insidePoints = GetPointsInside(); // Complex Points Generating if (insidePoints.Count > 0) { ///// Intersection Points intersection.A = First(); intersection.B = Last(); ///// Outside Points Vector2D first = insidePoints.First().Copy(); Vector2D last = insidePoints.Last().Copy(); Vector2D firstOutside = First().Copy(); Vector2D lastOutside = Last().Copy(); outside.A = firstOutside.Copy(); outside.B = lastOutside.Copy(); outside.A.Push(Vector2D.Atan2(firstOutside, first), precision); outside.B.Push(Vector2D.Atan2(lastOutside, last), precision); // Linear Points Generating } else { ///// Intersection Points intersections = GetIntersections(); if (intersections.Count == 2) { intersection.A = intersections.First(); intersection.B = intersections.Last(); } else { // How does this work with weird precision offset? intersection.A = slice.First(); intersection.B = slice.Last(); } // Outside Point Vector2D first = slice.Last().Copy(); Vector2D last = slice.First().Copy(); Vector2D firstOutside = slice.First().Copy(); Vector2D lastOutside = slice.Last().Copy(); outside.A = firstOutside.Copy(); outside.B = lastOutside.Copy(); outside.A.Push(Vector2D.Atan2(firstOutside, first), precision); outside.B.Push(Vector2D.Atan2(lastOutside, last), precision); } ///// Pairs Collided List <Vector2D> slicePoints = GetSlicePoints(); pair.A = polygon.pointsList.Last(); foreach (Vector2D p in polygon.pointsList) { pair.B = p; if (Math2D.LineIntersectSlice(pair, slicePoints) == true) { polygonCollisionPairs.Add(pair); } pair.A = pair.B; } foreach (Polygon2D hole in polygon.holesList) { pair.A = hole.pointsList.Last(); foreach (Vector2D p in hole.pointsList) { pair.B = p; if (Math2D.LineIntersectSlice(pair, slicePoints) == true) { polygonCollisionPairs.Add(pair); } pair.A = pair.B; } } }
static public void DrawColliders(Vector2D offset, float z) { float sunDirection = LightingManager2D.GetSunDirection(); LightingManager2D manager = LightingManager2D.Get(); // Day Soft Shadows GL.PushMatrix(); Max2D.defaultMaterial.SetPass(0); GL.Begin(GL.TRIANGLES); GL.Color(Color.black); Vector3 vecA, vecB, vecC; Vector2D zA, zB, zC; Vector2D pA, pB; foreach (LightingCollider2D id in LightingCollider2D.GetList()) { if (id.dayHeight == false || id.height <= 0) { continue; } if (id.shape.colliderType == LightingCollider2D.ColliderType.Mesh) { continue; } // Distance Check? if (id.InCamera() == false) { continue; } DayLightingShadowCollider shadow = id.GetDayLightingShadow(sunDirection * Mathf.Rad2Deg); foreach (Mesh mesh in shadow.meshes) { for (int i = 0; i < mesh.triangles.GetLength(0); i = i + 3) { vecA = mesh.vertices [mesh.triangles [i]]; vecB = mesh.vertices [mesh.triangles [i + 1]]; vecC = mesh.vertices [mesh.triangles [i + 2]]; Max2DMatrix.DrawTriangle(vecA.x, vecA.y, vecB.x, vecB.y, vecC.x, vecC.y, offset + new Vector2D(id.transform.position), z); } } } GL.End(); GL.PopMatrix(); GL.PushMatrix(); manager.materials.GetShadowBlur().SetPass(0); GL.Begin(GL.TRIANGLES); Max2D.SetColor(Color.white); foreach (LightingCollider2D id in LightingCollider2D.GetList()) { if (id.dayHeight == false || id.height <= 0) { continue; } if (id.shape.colliderType == LightingCollider2D.ColliderType.Mesh) { continue; } // Distance Check? if (id.InCamera() == false) { continue; } DayLightingShadowCollider shadow = id.GetDayLightingShadow(sunDirection * Mathf.Rad2Deg); Vector2D gameObjectOffset = new Vector2D(id.transform.position); foreach (Polygon2D polygon in shadow.polygons) { foreach (DoublePair2D p in DoublePair2D.GetList(polygon.pointsList)) { zA = p.A.Copy(); zA += offset + gameObjectOffset; zB = p.B.Copy(); zB += offset + gameObjectOffset; zC = zB.Copy(); pA = zA.Copy(); pB = zB.Copy(); zA.Push(Vector2D.Atan2(p.A, p.B) + pi2, .5f); zB.Push(Vector2D.Atan2(p.A, p.B) + pi2, .5f); zC.Push(Vector2D.Atan2(p.B, p.C) + pi2, .5f); GL.TexCoord2(uv0, uv0); Max2D.Vertex3(pB, z); GL.TexCoord2(0.5f - uv0, uv0); Max2D.Vertex3(pA, z); GL.TexCoord2(0.5f - uv0, uv1); Max2D.Vertex3(zA, z); GL.TexCoord2(uv0, uv1); Max2D.Vertex3(zA, z); GL.TexCoord2(0.5f - uv0, uv1); Max2D.Vertex3(zB, z); GL.TexCoord2(0.5f - uv0, uv0); Max2D.Vertex3(pB, z); GL.TexCoord2(uv0, uv1); Max2D.Vertex3(zB, z); GL.TexCoord2(0.5f - uv0, uv0); Max2D.Vertex3(pB, z); GL.TexCoord2(0.5f - uv0, uv1); Max2D.Vertex3(zC, z); } } } GL.End(); GL.PopMatrix(); }
static public Mesh2DSubmesh CreateLine(Pair2D pair, Vector3 transformScale, float lineWidth, float z = 0f) { Mesh2DSubmesh result = new Mesh2DSubmesh(18); float xuv0 = 0; float xuv1 = 1f - xuv0; float yuv0 = 0; float yuv1 = 1f - yuv0; float size = lineWidth / 6; float rot = (float)Vector2D.Atan2(pair.A, pair.B); A1.x = pair.A.x; A1.y = pair.A.y; A2.x = pair.A.x; A2.y = pair.A.y; B1.x = pair.B.x; B1.y = pair.B.y; B2.x = pair.B.x; B2.y = pair.B.y; Vector2 scale = new Vector2(1f / transformScale.x, 1f / transformScale.y); A1.Push(rot + pi2, size, scale); A2.Push(rot - pi2, size, scale); B1.Push(rot + pi2, size, scale); B2.Push(rot - pi2, size, scale); result.vertices[0] = new Vector3((float)B1.x, (float)B1.y, z); result.vertices[1] = new Vector3((float)A1.x, (float)A1.y, z); result.vertices[2] = new Vector3((float)A2.x, (float)A2.y, z); result.vertices[3] = new Vector3((float)A2.x, (float)A2.y, z); result.vertices[4] = new Vector3((float)B2.x, (float)B2.y, z); result.vertices[5] = new Vector3((float)B1.x, (float)B1.y, z); result.uv[0] = new Vector2(xuv1 / 3, yuv1); result.uv[1] = new Vector2(1 - xuv1 / 3, yuv1); result.uv[2] = new Vector2(1 - xuv1 / 3, yuv0); result.uv[3] = new Vector2(1 - xuv1 / 3, yuv0); result.uv[4] = new Vector2(yuv1 / 3, xuv0); result.uv[5] = new Vector2(xuv1 / 3, yuv1); A3.x = A1.x; A3.y = A1.y; A4.x = A1.x; A4.y = A1.y; A3.Push(rot - pi2, size, scale); A3.x = A1.x; A3.y = A1.y; A4.x = A2.x; A4.y = A2.y; A1.Push(rot, size, scale); A2.Push(rot, size, scale); result.vertices[6] = new Vector3((float)A3.x, (float)A3.y, z); result.vertices[7] = new Vector3((float)A1.x, (float)A1.y, z); result.vertices[8] = new Vector3((float)A2.x, (float)A2.y, z); result.vertices[9] = new Vector3((float)A2.x, (float)A2.y, z); result.vertices[10] = new Vector3((float)A4.x, (float)A4.y, z); result.vertices[11] = new Vector3((float)A3.x, (float)A3.y, z); result.uv[6] = new Vector2(xuv1 / 3, yuv1); result.uv[7] = new Vector2(xuv0, yuv1); result.uv[8] = new Vector2(xuv0, yuv0); result.uv[9] = new Vector2(xuv0, yuv0); result.uv[10] = new Vector2(yuv1 / 3, xuv0); result.uv[11] = new Vector2(xuv1 / 3, yuv1); A1.x = B1.x; A1.y = B1.y; A2.x = B2.x; A2.y = B2.y; B1.Push(rot - Mathf.PI, size, scale); B2.Push(rot - Mathf.PI, size, scale); result.vertices[12] = new Vector3((float)B1.x, (float)B1.y, z); result.vertices[13] = new Vector3((float)A1.x, (float)A1.y, z); result.vertices[14] = new Vector3((float)A2.x, (float)A2.y, z); result.vertices[15] = new Vector3((float)A2.x, (float)A2.y, z); result.vertices[16] = new Vector3((float)B2.x, (float)B2.y, z); result.vertices[17] = new Vector3((float)B1.x, (float)B1.y, z); result.uv[12] = new Vector2(xuv0, yuv1); result.uv[13] = new Vector2(xuv1 / 3, yuv1); result.uv[14] = new Vector2(xuv1 / 3, yuv0); result.uv[15] = new Vector2(xuv1 / 3, yuv0); result.uv[16] = new Vector2(yuv0, xuv0); result.uv[17] = new Vector2(xuv0, yuv1); return(result); }
void Update() { CheckIfUpdateNeeded(); LightingManager2D manager = LightingManager2D.Get(); bool disabled = manager.disableEngine; if (InCamera()) { if (update == true) { if (inScreen == false) { buffer = FBOManager.PullBuffer(LightingManager2D.GetTextureSize(textureSize), this); update = false; if (buffer != null) { if (disabled == false) { buffer.bufferCamera.enabled = true; // //UpdateLightBuffer(True) buffer.bufferCamera.orthographicSize = lightSize; } } //Debug.Log(3); inScreen = true; } else { update = false; if (buffer != null) { if (disabled == false) { buffer.bufferCamera.enabled = true; // //UpdateLightBuffer(True) buffer.bufferCamera.orthographicSize = lightSize; } } } } else { if (buffer != null) { // Debug.Log(1); } else { buffer = FBOManager.PullBuffer(LightingManager2D.GetTextureSize(textureSize), this); update = false; if (buffer != null) { if (disabled == false) { buffer.bufferCamera.enabled = true; // //UpdateLightBuffer(True) buffer.bufferCamera.orthographicSize = lightSize; } } inScreen = true; //Debug.Log(4); } } } else { ///// Free Buffer! if (buffer != null) { FBOManager.FreeBuffer(buffer); buffer = null; } inScreen = false; } if (eventHandling) { Vector2D zero = Vector2D.Zero(); float lightSizeSquared = Mathf.Sqrt(lightSize * lightSize + lightSize * lightSize); List <LightCollision2D> collisions = new List <LightCollision2D>(); foreach (LightingCollider2D id in LightingCollider2D.GetList()) { if (id.colliderType == LightingCollider2D.ColliderType.None) { continue; } if (LightingManager2D.culling && Vector2.Distance(id.transform.position, transform.position) > id.GetCullingDistance() + lightSize) { continue; } LightCollision2D collision = new LightCollision2D(); collision.lightSource = this; collision.collider = id; collision.pointsColliding = id.GetShadowCollisionPolygons()[0].ToWorldSpace(id.transform).ToOffset(new Vector2D(-transform.position)).pointsList; collisions.Add(collision); } foreach (LightingCollider2D id in LightingCollider2D.GetList()) { if (LightingManager2D.culling && Vector2.Distance(id.transform.position, transform.position) > id.GetCullingDistance() + lightSize) { continue; } if (id.colliderType == LightingCollider2D.ColliderType.None) { continue; } List <Polygon2D> polygons = id.GetShadowCollisionPolygons(); if (polygons.Count < 1) { continue; } foreach (Polygon2D polygon in polygons) { Polygon2D poly = polygon.ToWorldSpace(id.gameObject.transform); poly.ToOffsetItself(new Vector2D(-transform.position)); if (poly.PointInPoly(zero)) { continue; } Vector2D vA, pA, vB, pB; float angleA, angleB; foreach (Pair2D p in Pair2D.GetList(poly.pointsList, false)) { vA = p.A.Copy(); pA = p.A.Copy(); vB = p.B.Copy(); pB = p.B.Copy(); angleA = (float)Vector2D.Atan2(vA, zero); angleB = (float)Vector2D.Atan2(vB, zero); vA.Push(angleA, lightSizeSquared); pA.Push(angleA - Mathf.Deg2Rad * occlusionSize, lightSizeSquared); vB.Push(angleB, lightSizeSquared); pB.Push(angleB + Mathf.Deg2Rad * occlusionSize, lightSizeSquared); if (eventHandling) { Polygon2D triPoly = new Polygon2D(); triPoly.AddPoint(p.A); triPoly.AddPoint(p.B); triPoly.AddPoint(pB); triPoly.AddPoint(pA); foreach (LightCollision2D col in new List <LightCollision2D>(collisions)) { if (col.collider == id) { continue; } foreach (Vector2D point in new List <Vector2D>(col.pointsColliding)) { if (triPoly.PointInPoly(point)) { col.pointsColliding.Remove(point); } } if (col.pointsColliding.Count < 1) { collisions.Remove(col); } } } } LightingManager2D.LightingDebug.shadowGenerations++; } } if (collisions.Count > 0) { foreach (LightCollision2D collision in collisions) { collision.collider.CollisionEvent(collision); } } } }
public ComplexCollision(Polygon2D polygon, List <Vector2D> slice) { bool enterCollision = false; Pair2D pair = Pair2D.Zero(); // Generate correct intersected slice List <Vector2D> intersections; for (int i = 0; i < slice.Count - 1; i++) { pair.A = slice[i];; pair.B = slice[i + 1]; intersections = polygon.GetListLineIntersectPoly(pair); if (intersections.Count == 1) { //intersectionType = IntersectionType.DifferentPairs; collisionCount += 1; collisionSlice.Add(new Point(intersections[0], Point.Type.Intersection)); enterCollision = !enterCollision; } else if (intersections.Count == 2) { //intersectionType = IntersectionType.SamePair; collisionCount += intersections.Count; // Check if it's okay if (Vector2D.Distance(intersections[0], pair.A) < Vector2D.Distance(intersections[1], pair.A)) { collisionSlice.Add(new Point(intersections[0], Point.Type.Intersection)); collisionSlice.Add(new Point(intersections[1], Point.Type.Intersection)); } else { collisionSlice.Add(new Point(intersections[1], Point.Type.Intersection)); collisionSlice.Add(new Point(intersections[0], Point.Type.Intersection)); } } else if (intersections.Count > 2) { error = true; } if (enterCollision == true) { collisionSlice.Add(new Point(pair.B, Point.Type.Inside)); } } List <Vector2D> insidePoints = GetPointsInside(); // Complex Points Generating if (insidePoints.Count > 0) { ///// Outside Points Vector2D first = insidePoints.First(); Vector2D last = insidePoints.Last(); Vector2D firstOutside = First(); Vector2D lastOutside = Last(); outside.A = firstOutside.Copy(); outside.B = lastOutside.Copy(); outside.A.Push(Vector2D.Atan2(firstOutside, first), 0.001f); outside.B.Push(Vector2D.Atan2(lastOutside, last), 0.001f); ///// Inside Points Vector2D firstInside = First(); Vector2D lastInside = Last(); inside.A = firstInside.Copy(); inside.B = lastInside.Copy(); inside.A.Push(Vector2D.Atan2(first, firstInside), 0.001f); inside.B.Push(Vector2D.Atan2(last, lastInside), 0.001f); // Linear Points Generating } else { Vector2D first = slice.Last(); Vector2D last = slice.First(); Vector2D firstOutside = slice.First(); Vector2D lastOutside = slice.Last(); outside.A = firstOutside.Copy(); outside.B = lastOutside.Copy(); outside.A.Push(Vector2D.Atan2(firstOutside, first), 0.001f); outside.B.Push(Vector2D.Atan2(lastOutside, last), 0.001f); ///// Inside Points Vector2D firstInside = slice.First(); Vector2D lastInside = slice.Last(); inside.A = firstInside.Copy(); inside.B = lastInside.Copy(); inside.A.Push(Vector2D.Atan2(first, firstInside), 0.001f); inside.B.Push(Vector2D.Atan2(last, lastInside), 0.001f); } ///// Pairs Collided List <Vector2D> slicePoints = GetSlicePoints(); pair.A = polygon.pointsList.Last(); foreach (Vector2D p in polygon.pointsList) { pair.B = p; if (Math2D.LineIntersectSlice(pair, slicePoints) == true) { polygonCollisionPairs.Add(pair); } pair.A = pair.B; } foreach (Polygon2D hole in polygon.holesList) { pair.A = hole.pointsList.Last(); foreach (Vector2D p in hole.pointsList) { pair.B = p; if (Math2D.LineIntersectSlice(pair, slicePoints) == true) { polygonCollisionPairs.Add(pair); } pair.A = pair.B; } } }