public static CutResult Cut( Vector2 lineStart, Vector2 lineEnd, Collider2D[] colliders ) { CutResult result = new CutResult(); result.firstSideColliderRepresentations = new List<PolygonColliderParametersRepresentation>(); result.secondSideColliderRepresentations = new List<PolygonColliderParametersRepresentation>(); foreach ( Collider2D collider in colliders ) { List<Vector2[]> paths = ColliderPathsCreator.GetPolygonColliderPathsFrom( collider ); foreach ( Vector2[] path in paths ) { ShapeCutter.CutResult cutResult = ShapeCutter.CutShapeIntoTwo( lineStart, lineEnd, path ); if ( cutResult.firstSidePoints.Length > 0 ) { PolygonColliderParametersRepresentation repr = new PolygonColliderParametersRepresentation(); repr.CopyParametersFrom( collider ); repr.paths.Add( cutResult.firstSidePoints ); result.firstSideColliderRepresentations.Add( repr ); } if ( cutResult.secondSidePoints.Length > 0 ) { PolygonColliderParametersRepresentation repr = new PolygonColliderParametersRepresentation(); repr.CopyParametersFrom( collider ); repr.paths.Add( cutResult.secondSidePoints ); result.secondSideColliderRepresentations.Add( repr ); } } } return result; }
void DoDraw() { Debug.Log(template.points.Count); template.Inflate(0.01f); template.DrawDebug(); try { CutResult res = API.tmp(canvas, template); if (res != null) { res.DestroyObject(); foreach (CutObj obj in res.NegativeResults) { obj .CopyParent() .CopyMaterial() .WithCollider() .Instantiate() .tag = "CutCanvas"; } } } catch (MeshUtilsException e) { Debug.LogException(e); canvas.GetComponent <Collider>().isTrigger = false; } lastDraw = DateTime.Now; canvas = null; template = null; }
public static CutResult Cut(Vector2 lineStart, Vector2 lineEnd, Collider2D[] colliders) { CutResult result = new CutResult(); result.firstSideColliderRepresentations = new List <PolygonColliderParametersRepresentation>(); result.secondSideColliderRepresentations = new List <PolygonColliderParametersRepresentation>(); foreach (Collider2D collider in colliders) { List <Vector2[]> paths = ColliderPathsCreator.GetPolygonColliderPathsFrom(collider); foreach (Vector2[] path in paths) { ShapeCutter.CutResult cutResult = ShapeCutter.CutShapeIntoTwo(lineStart, lineEnd, path); if (cutResult.firstSidePoints.Length > 0) { PolygonColliderParametersRepresentation repr = new PolygonColliderParametersRepresentation(); repr.CopyParametersFrom(collider); repr.paths.Add(cutResult.firstSidePoints); result.firstSideColliderRepresentations.Add(repr); } if (cutResult.secondSidePoints.Length > 0) { PolygonColliderParametersRepresentation repr = new PolygonColliderParametersRepresentation(); repr.CopyParametersFrom(collider); repr.paths.Add(cutResult.secondSidePoints); result.secondSideColliderRepresentations.Add(repr); } } } return(result); }
/// <summary> /// Cuts out a part of the route and returns the customers contained. /// </summary> /// <param name="weights"></param> /// <param name="start"></param> /// <param name="weight"></param> /// <param name="length"></param> /// <returns></returns> public CutResult CutAndRemove(IProblemWeights weights, double weight, int start, int length) { double weight_difference = 0; int[] next_array = _next_array.Clone() as int[]; List <int> cut_part = new List <int>(); int position = 0; int current_customer = this.First; // keep moving next until the start. while (position < start - 1) { position++; // increase the position. current_customer = next_array[current_customer]; } // cut the actual part. int start_customer = current_customer; int previous_customer = current_customer; while (position < start + length - 1) { // move next. position++; // increase the position. current_customer = next_array[current_customer]; // set the current customer. cut_part.Add(current_customer); // add the weigth difference. weight_difference = weight_difference - weights.WeightMatrix[previous_customer][current_customer]; previous_customer = current_customer; } // move to the next customer. current_customer = next_array[current_customer]; weight_difference = weight_difference - weights.WeightMatrix[previous_customer][current_customer]; // set the next customer. next_array[start_customer] = current_customer; weight_difference = weight_difference + weights.WeightMatrix[start_customer][current_customer]; // create cut result. CutResult result = new CutResult(); result.Weight = weight + weight_difference; result.Route = new DynamicAsymmetricRoute(this.First, next_array, true); result.CutPart = cut_part; if (!result.Route.IsValid()) { throw new Exception(); } return(result); }
void HandleInput() { CutResult result = BrickCutter.CutBrick(newBrick, prevBrick, spawner.curAxis, cutTreshold); if (result.isSuccess) { score++; if (result.cutPiece == null) { Vector3 newPos = newBrick.transform.position; Vector3 prevPos = prevBrick.transform.position; newBrick.transform.position = new Vector3(prevPos.x, newPos.y, prevPos.z); } else { GameObject piece = Instantiate(piecePrefab, result.cutPiece.position, Quaternion.identity, root.transform); piece.transform.localScale = result.cutPiece.localScale; MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock(); propertyBlock.SetColor("_BaseColor", newBrick.color); piece.GetComponent <Renderer>().SetPropertyBlock(propertyBlock); SetRandomMovement(piece, result.axis); } } else { BlockInput(); GameObject piece = Instantiate(piecePrefab, newBrick.transform.position, Quaternion.identity, root.transform); piece.transform.localScale = newBrick.transform.localScale; MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock(); propertyBlock.SetColor("_BaseColor", newBrick.color); piece.GetComponent <Renderer>().SetPropertyBlock(propertyBlock); Destroy(newBrick.gameObject); SetRandomMovement(piece, result.axis); SetState((int)GameState.GameOver); return; } prevBrick.MakeStatic(); newBrick.movement.ToggletMovement(); prevBrick = newBrick; prevBrick.transform.parent = root.transform; cameraController.FocusOnBrick(prevBrick); newBrick = spawner.SpawnBrick(prevBrick, prevBrick.transform.position, curSpeed); skyController.SetSkyByColor(newBrick.color); if (curSpeed < maxSpeed) { curSpeed += speedStep; if (curSpeed > maxSpeed) { curSpeed = maxSpeed; } } }
List <GameObject> IterativeCut(GameObject obj, int count) { CutParams param = new CutParams(false, false, false, false, Vector3.zero, float.PositiveInfinity, 0, Vector3.zero); try { CutResult res = API.PerformCut(obj, CuttingPlane.RandomInWorldSpace(obj.transform.position), param); res.DestroyObject(); if (res == null) { return(new List <GameObject>()); } if (count > 1) { List <GameObject> ret = new List <GameObject>(); foreach (CutObj robj in res.Results) { ret.AddRange( IterativeCut( robj .CopyParent() .CopyMaterial() .CopyVelocity() .WithDriftVelocity(0.2f) .Instantiate(), count - 1 ) ); } return(ret); } else { return(res.ConvertAll( robj => robj .CopyParent() .CopyMaterial() .WithCollider() .WithRenderer() .CopyVelocity() .WithDriftVelocity(0.2f) .Instantiate() )); } } catch (MeshUtilsException e) { Debug.LogWarning(e); obj.AddComponent <Rigidbody>(); obj.AddComponent <MeshRenderer>(); obj.AddComponent <MeshCollider>(); return(new List <GameObject>() { obj }); } }
public static CutResult CutShapeIntoTwo(Vector2 lineStart, Vector2 lineEnd, Vector2[] shape) { List <Vector2> firstSide = new List <Vector2>(); List <Vector2> secondSide = new List <Vector2>(); InfiniteLine cuttingLine = new InfiniteLine(lineStart, lineEnd); int intersectionsFound = 0; for (int i = 0; i < shape.Length; i++) { Vector2 point = shape[i]; Vector2 previousPoint; if (i == 0) { previousPoint = shape[shape.Length - 1]; } else { previousPoint = shape[i - 1]; } if (cuttingLine.IntersectsWithSegment(previousPoint, point)) { InfiniteLine lastTwoPointsLine = new InfiniteLine(previousPoint, point); Vector2 intersectionPoint = cuttingLine.IntersectionWithOtherLine(lastTwoPointsLine); firstSide.Add(intersectionPoint); secondSide.Add(intersectionPoint); intersectionsFound++; } if (cuttingLine.PointBelowLine(point)) { firstSide.Add(point); } else { secondSide.Add(point); } } if (intersectionsFound > 2) { //throw new System.Exception( "SpriteCutter cannot cut through non-convex shapes! Adjust your colliders shapes to be convex!" ); } CutResult result = new CutResult(); result.firstSidePoints = firstSide.ToArray(); result.secondSidePoints = secondSide.ToArray(); return(result); }
public static CutResult Cut( Vector2 lineStart, Vector2 lineEnd, Mesh mesh ) { CutResult result = new CutResult(); Vector2[] shape = ConvertVerticesToShape( mesh.vertices ); ShapeCutter.CutResult shapeCutResult = ShapeCutter.CutShapeIntoTwo( lineStart, lineEnd, shape ); if ( shapeCutResult.firstSidePoints.Length < 3 || shapeCutResult.secondSidePoints.Length < 3 ) { return result; } result.firstSideMesh = GenerateHalfMeshFrom( mesh, shapeCutResult.firstSidePoints ); result.secondSideMesh = GenerateHalfMeshFrom( mesh, shapeCutResult.secondSidePoints ); return result; }
public static CutResult Cut(Vector2 lineStart, Vector2 lineEnd, Mesh mesh) { CutResult result = new CutResult(); Vector2[] shape = ConvertVerticesToShape(mesh.vertices); ShapeCutter.CutResult shapeCutResult = ShapeCutter.CutShapeIntoTwo(lineStart, lineEnd, shape); if (shapeCutResult.firstSidePoints.Length < 3 || shapeCutResult.secondSidePoints.Length < 3) { return(result); } result.firstSideMesh = GenerateHalfMeshFrom(mesh, shapeCutResult.firstSidePoints); result.secondSideMesh = GenerateHalfMeshFrom(mesh, shapeCutResult.secondSidePoints); return(result); }
/// <summary> /// Actual cutting mehtod /// </summary> /// <param name="p_spriteObj"></param> /// <param name="objectPos">Transform.positon couldn;t be obtain inside Threading, so give it individually here</param> /// <param name="p_point1"></param> /// <param name="p_point2"></param> /// <param name="p_callback"></param> private void RunCut(OneCutObject p_spriteObj, Vector2 objectPos, Vector2 p_point1, Vector2 p_point2, System.Action <CutResult, bool> p_callback) { List <Triangle> originalTrig = p_spriteObj.triangles; CutResult cutResult = mainAlgorithm.CutSpriteToMesh(p_spriteObj, objectPos, p_point1, p_point2); var newArea = System.Math.Round(cutResult.mainSprite.area + cutResult.subSprite.area, 2); var oriArea = System.Math.Round(cutResult.originSprite.area, 2); bool isSuccess = (newArea >= oriArea); lock (results) { results.Enqueue(new TaskResult(cutResult, isSuccess, p_callback)); } if (debugMode) { p_spriteObj.SetDebugVaraible(cutResult.intersectionPoints, cutResult.mainSprite.meshVert, cutResult.subSprite.meshVert); } }
public static CutResult CutShapeIntoTwo( Vector2 lineStart, Vector2 lineEnd, Vector2[] shape ) { List<Vector2> firstSide = new List<Vector2>(); List<Vector2> secondSide = new List<Vector2>(); InfiniteLine cuttingLine = new InfiniteLine( lineStart, lineEnd ); int intersectionsFound = 0; for ( int i = 0; i < shape.Length; i++ ) { Vector2 point = shape[ i ]; Vector2 previousPoint; if ( i == 0 ) { previousPoint = shape[ shape.Length - 1 ]; } else { previousPoint = shape[ i - 1 ]; } if ( cuttingLine.IntersectsWithSegment( previousPoint, point ) ) { InfiniteLine lastTwoPointsLine = new InfiniteLine( previousPoint, point ); Vector2 intersectionPoint = cuttingLine.IntersectionWithOtherLine( lastTwoPointsLine ); firstSide.Add( intersectionPoint ); secondSide.Add( intersectionPoint ); intersectionsFound++; } if ( cuttingLine.PointBelowLine( point ) ) { firstSide.Add( point ); } else { secondSide.Add( point ); } } if ( intersectionsFound > 2 ) { throw new System.Exception( "SpriteCutter cannot cut through non-convex shapes! Adjust your colliders shapes to be convex!" ); } CutResult result = new CutResult(); result.firstSidePoints = firstSide.ToArray(); result.secondSidePoints = secondSide.ToArray(); return result; }
public void OnCollisionEnter(Collision col) { if (ignoreColliders.Contains(col.collider)) { ignoreColliders.Remove(col.collider); return; } Cuttable cuttable; if (!col.gameObject.TryGetComponent <Cuttable>(out cuttable)) { return; } Vector3 cutDir = directionsAreNormals ? TransformNormal(cutDirection, transform) : transform.TransformDirection(cutDirection); float relVel = (col.relativeVelocity - Vector3.Project(col.relativeVelocity, cutDir)).magnitude; // Debug.Log("vel: "+relVel); // Debug.DrawRay(col.GetContact(0).point,col.relativeVelocity-Vector3.Project(col.relativeVelocity,cutDir)/relVel,Color.blue,1); if (minimumVelocity > relVel) { return; } Vector3 dir = omnidirectionalMode ? -col.relativeVelocity : cutDir; Vector3 edge = directionsAreNormals ? TransformNormal(edgeDirection, transform) : transform.TransformDirection(edgeDirection); Vector3 angleProjection = Vector3.ProjectOnPlane(gameObject.GetComponentInParent <Rigidbody>().velocity, edge); // Debug.Log("angle: "+Vector3.Angle(angleProjection,cutDir)); // if (Vector3.Angle(angleProjection,cutDir) > 70) Debug.Break(); // Debug.DrawRay(col.GetContact(0).point,angleProjection,Color.red,1); // Debug.DrawRay(col.GetContact(0).point,cutDir,Color.green,1); // Debug.DrawRay(col.GetContact(0).point,-col.relativeVelocity,Color.blue,1); if (Vector3.Angle(angleProjection, cutDir) > maxAngle) { return; } Vector3 normal = Vector3.Cross(dir, edge).normalized; Vector3 pointInPlane = useContactPoint ? col.GetContact(0).point : transform.position; CuttingPlane plane = CuttingPlane.InWorldSpace(normal, pointInPlane); CutParams param = new CutParams( cuttable.checkForHoles, true, cuttable.closeOpenSurfaces, cuttable.allowOpenSurfaces, Vector3.zero, float.PositiveInfinity, 0, cuttable.innerTextureCoordinate ); CutResult result = PerformCut(col.gameObject, plane, param); if (result != null) { if (cuttable.polySeparate) { result.PolySeparate(); } result.DestroyObject(); foreach (CutObj res in result.Results) { GameObject resObj = res .UseDefaults() .WithDriftVelocity(driftVelocity) .WithSeperationDistance(seperationDistance) .WithRingWidth(cuttable.highlightWidth) .WithRingColor(cuttable.highLightColor) .FallbackToColor(new Color(1, 0.1f, 0.1f)) .Instantiate(); cuttable.CopyTo(resObj); ignoreColliders.Add(resObj.GetComponent <Collider>()); } } }
public CutObj(MeshPart part, CutResult res, bool isPolySeperated) : base(part, res, isPolySeperated) { }
public FriendlyCutObj(MeshPart part, CutResult result, bool isPolySeperated) { this.part = part; this.cutResult = result; this.isPolySeperated = isPolySeperated; }
public static CutResult CutBrick(Brick brickToCut, Brick brick, BrickAxis axis, float threshold) { if (axis == BrickAxis.X) { Vector2 brickToCut_A = brickToCut.GetPointByNumber(1); Vector2 brickToCut_B = brickToCut.GetPointByNumber(4); Vector2 brick_A = brick.GetPointByNumber(1); Vector2 brick_B = brick.GetPointByNumber(4); if (brickToCut_B.x < brick_A.x || brickToCut_A.x > brick_B.x) { // Player missed! return(CutResult.Fail(axis)); } if (brickToCut_B.x < brick_B.x) { if (brick_B.x - brickToCut_B.x <= threshold) { return(CutResult.Success(axis)); } else { float newScaleX = (brickToCut_B.x - brick_A.x); float newPosX = brickToCut_B.x - newScaleX / 2; Vector3 brickScale = brickToCut.transform.localScale; brickToCut.transform.localScale = new Vector3(newScaleX, brickScale.y, brickScale.z); Vector3 brickPos = brickToCut.transform.position; brickToCut.transform.position = new Vector3(newPosX, brickPos.y, brickPos.z); Vector3 pieceScale = new Vector3(brick_A.x - brickToCut_A.x, brickScale.y, brickScale.z); Vector3 piecePos = new Vector3(brickToCut_A.x + pieceScale.x / 2, brickPos.y, brickPos.z); return(CutResult.Partial(piecePos, pieceScale, axis)); } } if (brickToCut_A.x > brick_A.x) { if (brickToCut_A.x - brick_A.x <= threshold) { return(CutResult.Success(axis)); } else { float newScaleX = (brick_B.x - brickToCut_A.x); float newPosX = brickToCut_A.x + newScaleX / 2; Vector3 brickScale = brickToCut.transform.localScale; brickToCut.transform.localScale = new Vector3(newScaleX, brickScale.y, brickScale.z); Vector3 brickPos = brickToCut.transform.position; brickToCut.transform.position = new Vector3(newPosX, brickPos.y, brickPos.z); Vector3 pieceScale = new Vector3(brickToCut_A.x - brick_A.x, brickScale.y, brickScale.z); Vector3 piecePos = new Vector3(brick_B.x + pieceScale.x / 2, brickPos.y, brickPos.z); return(CutResult.Partial(piecePos, pieceScale, axis)); } } } if (axis == BrickAxis.Z) { Vector2 brickToCut_A = brickToCut.GetPointByNumber(3); Vector2 brickToCut_B = brickToCut.GetPointByNumber(4); Vector2 brick_A = brick.GetPointByNumber(3); Vector2 brick_B = brick.GetPointByNumber(4); if (brickToCut_B.y > brick_A.y || brickToCut_A.y < brick_B.y) { // Player missed return(CutResult.Fail(axis)); } if (brickToCut_B.y > brick_B.y) { if (brickToCut_B.y - brick_B.y <= threshold) { return(CutResult.Success(axis)); } else { float newScaleZ = (brick_A.y - brickToCut_B.y); float newPosZ = brickToCut_B.y + newScaleZ / 2; Vector3 brickScale = brickToCut.transform.localScale; brickToCut.transform.localScale = new Vector3(brickScale.x, brickScale.y, newScaleZ); Vector3 brickPos = brickToCut.transform.position; brickToCut.transform.position = new Vector3(brickPos.x, brickPos.y, newPosZ); Vector3 pieceScale = new Vector3(brickScale.x, brickScale.y, brickToCut_A.y - brick_A.y); Vector3 piecePos = new Vector3(brickPos.x, brickPos.y, brick_A.y + pieceScale.z / 2); return(CutResult.Partial(piecePos, pieceScale, axis)); } } if (brickToCut_A.y < brick_A.y) { if (brick_A.y - brickToCut_A.y <= threshold) { return(CutResult.Success(axis)); } else { float newScaleZ = (brickToCut_A.y - brick_B.y); float newPosZ = brickToCut_A.y - newScaleZ / 2; Vector3 brickScale = brickToCut.transform.localScale; brickToCut.transform.localScale = new Vector3(brickScale.x, brickScale.y, newScaleZ); Vector3 brickPos = brickToCut.transform.position; brickToCut.transform.position = new Vector3(brickPos.x, brickPos.y, newPosZ); Vector3 pieceScale = new Vector3(brickScale.x, brickScale.y, brick_B.y - brickToCut_B.y); Vector3 piecePos = new Vector3(brickPos.x, brickPos.y, brick_B.y - pieceScale.z / 2); return(CutResult.Partial(piecePos, pieceScale, axis)); } } } return(CutResult.Fail(axis)); }
public TaskResult(CutResult p_cutResult, bool p_isSuccess, System.Action <CutResult, bool> p_callback) { cutResult = p_cutResult; isSuccess = p_isSuccess; callback = p_callback; }