void StretchPiece(PlatformingElement toStretch, Vector3 displacement, int stretchIndex, int connectorToMove, int connectorToNotMove) { Vector3 fixedConnectorPos = toStretch.getConnectorPos(connectorToNotMove); Vector3 movingConnectorPos = toStretch.getConnectorPos(connectorToMove); float currDist = Mathf.Abs(movingConnectorPos [stretchIndex] - fixedConnectorPos [stretchIndex]); float newDist = currDist + Mathf.Abs(displacement [stretchIndex]); float scaleFactor = newDist / currDist; Vector3 localScale = toStretch.transform.TransformDirection(toStretch.transform.localScale); localScale [stretchIndex] *= scaleFactor; toStretch.transform.localScale = toStretch.transform.InverseTransformDirection(localScale); toStretch.transform.position = Vector3.zero; toStretch.transform.position -= toStretch.getConnectorPos(connectorToNotMove); toStretch.transform.position += fixedConnectorPos; }
Vector3 BuildPath(PlatformingElement start, PlatformingElement end, int startConn, int endConn, int depth, int directionMask, out LinkedList<PlatformingElement> newPieces) { foreach (PlatformingElement element in allPieces) { if(element.getAdjustedExclusionZone().Intersects(start.getAdjustedExclusionZone())) { newPieces = new LinkedList<PlatformingElement>(); return Vector3.zero; } } if (depth == 0) { newPieces = new LinkedList<PlatformingElement> (); return Vector3.one * float.NaN; } float tol = 0.95f; Vector3 diff = end.getConnectorPos (endConn) - start.getConnectorPos (startConn); Vector3[] targetDirs = Util.VecBreak (Util.VecSign (diff)); int neededDirsCount = 0; foreach (Vector3 v in targetDirs) { if (VecMaskCheck (directionMask, v)) { neededDirsCount ++; } } Vector3 startDir = start.getConnectorDir (startConn); Vector3 finalDir = end.getConnectorDir (endConn); if ((neededDirsCount == targetDirs.Length || (diff.sqrMagnitude < 0.001f)) && Vector3.Dot (startDir, finalDir) < -1 * tol) { start.connectors[startConn].connectedNode = end; end.connectors[endConn].connectedNode = start; newPieces = new LinkedList<PlatformingElement>(); return end.getConnectorPos (endConn) - start.getConnectorPos (startConn); } for (int obj = 0; obj < placeableObjects.Length; obj++) { for (int con = 0; con < placeableObjects[obj].connectors.Length; con++) { for (int rot = 0; rot < 4; rot ++) { Quaternion attachRot = Quaternion.FromToRotation (placeableObjects [obj].connectors [con].normal, startDir * -1); Quaternion pieceRot = Quaternion.AngleAxis (rot * 90, startDir); Quaternion conRot = pieceRot * attachRot; if (placeableObjects [obj].allowTilt || ((conRot * Vector3.up).y > tol)) for (int otherCon = 0; otherCon < placeableObjects[obj].connectors.Length; otherCon++) { if (con != otherCon) { Vector3 otherConTestDir = placeableObjects [obj].connectors [otherCon].normal; Vector3 stretchDir = Vector3.Scale (otherConTestDir, placeableObjects [obj].allowedScaling); if (stretchDir.sqrMagnitude > 0.001f) { if (!VecMaskCheck (directionMask, Util.VecSign (conRot * stretchDir))) { PlatformingElement newPiece = PlacePiece (start, startConn, obj, con, rot * 90); Vector3 displace = BuildPath (newPiece, end, otherCon, endConn, depth - 1, VecMaskAdd (directionMask, Util.VecSign (conRot * stretchDir)), out newPieces); if (Vector3.Dot (displace, conRot * stretchDir) > 0) { Vector3 projDir = Vector3.Project (displace, (conRot * stretchDir).normalized); displace = Vector3.Exclude (projDir, displace); newPiece.transform.position += displace; StretchPiece (newPiece, projDir, Util.VecSigIndex (projDir), otherCon, con); } else newPiece.transform.position += displace; newPieces.AddFirst(newPiece); return displace; } } for (int i = 0; i < targetDirs.Length; i ++) { if ((Vector3.Dot (conRot * otherConTestDir, targetDirs [i]) > tol) && !VecMaskCheck (directionMask, targetDirs [i])) { PlatformingElement newPiece = PlacePiece (start, startConn, obj, con, rot * 90); Vector3 displace = BuildPath (newPiece, end, otherCon, endConn, depth - 1, directionMask, out newPieces); newPiece.transform.position += displace; newPieces.AddFirst(newPiece); return displace; } } } } } } } if (Vector3.Dot (startDir, finalDir) > -1 * tol) for (int obj = 0; obj < placeableObjects.Length; obj++) { for (int con = 0; con < placeableObjects[obj].connectors.Length; con++) { for (int rot = 0; rot < 4; rot ++) { Quaternion conRot = Quaternion.AngleAxis (rot * 90, startDir) * Quaternion.FromToRotation (placeableObjects [obj].connectors [con].normal, startDir * -1); if (placeableObjects [obj].allowTilt || ((conRot * Vector3.up).y > tol)) for (int otherCon = 0; otherCon < placeableObjects[obj].connectors.Length; otherCon++) { if (con != otherCon) { Vector3 otherConTestDir = placeableObjects [obj].connectors [otherCon].normal; if ((Vector3.Dot (conRot * otherConTestDir, finalDir * -1) > tol)) { PlatformingElement newPiece = PlacePiece (start, startConn, obj, con, rot * 90); Vector3 displace = BuildPath (newPiece, end, otherCon, endConn, depth - 1, directionMask, out newPieces); newPiece.transform.position += displace; newPieces.AddFirst(newPiece); return displace; } } } } } } newPieces = new LinkedList<PlatformingElement> (); return Vector3.one * float.NaN; }
void StretchPiece(PlatformingElement toStretch, Vector3 displacement, int stretchIndex, int connectorToMove, int connectorToNotMove) { Vector3 fixedConnectorPos = toStretch.getConnectorPos (connectorToNotMove); Vector3 movingConnectorPos = toStretch.getConnectorPos (connectorToMove); float currDist = Mathf.Abs (movingConnectorPos [stretchIndex] - fixedConnectorPos [stretchIndex]); float newDist = currDist + Mathf.Abs (displacement [stretchIndex]); float scaleFactor = newDist / currDist; Vector3 localScale = toStretch.transform.TransformDirection (toStretch.transform.localScale); localScale [stretchIndex] *= scaleFactor; toStretch.transform.localScale = toStretch.transform.InverseTransformDirection (localScale); toStretch.transform.position = Vector3.zero; toStretch.transform.position -= toStretch.getConnectorPos (connectorToNotMove); toStretch.transform.position += fixedConnectorPos; }
Vector3 BuildPath(PlatformingElement start, PlatformingElement end, int startConn, int endConn, int depth, int directionMask, out LinkedList <PlatformingElement> newPieces) { foreach (PlatformingElement element in allPieces) { if (element.getAdjustedExclusionZone().Intersects(start.getAdjustedExclusionZone())) { newPieces = new LinkedList <PlatformingElement>(); return(Vector3.zero); } } if (depth == 0) { newPieces = new LinkedList <PlatformingElement> (); return(Vector3.one * float.NaN); } float tol = 0.95f; Vector3 diff = end.getConnectorPos(endConn) - start.getConnectorPos(startConn); Vector3[] targetDirs = Util.VecBreak(Util.VecSign(diff)); int neededDirsCount = 0; foreach (Vector3 v in targetDirs) { if (VecMaskCheck(directionMask, v)) { neededDirsCount++; } } Vector3 startDir = start.getConnectorDir(startConn); Vector3 finalDir = end.getConnectorDir(endConn); if ((neededDirsCount == targetDirs.Length || (diff.sqrMagnitude < 0.001f)) && Vector3.Dot(startDir, finalDir) < -1 * tol) { start.connectors[startConn].connectedNode = end; end.connectors[endConn].connectedNode = start; newPieces = new LinkedList <PlatformingElement>(); return(end.getConnectorPos(endConn) - start.getConnectorPos(startConn)); } for (int obj = 0; obj < placeableObjects.Length; obj++) { for (int con = 0; con < placeableObjects[obj].connectors.Length; con++) { for (int rot = 0; rot < 4; rot++) { Quaternion attachRot = Quaternion.FromToRotation(placeableObjects [obj].connectors [con].normal, startDir * -1); Quaternion pieceRot = Quaternion.AngleAxis(rot * 90, startDir); Quaternion conRot = pieceRot * attachRot; if (placeableObjects [obj].allowTilt || ((conRot * Vector3.up).y > tol)) { for (int otherCon = 0; otherCon < placeableObjects[obj].connectors.Length; otherCon++) { if (con != otherCon) { Vector3 otherConTestDir = placeableObjects [obj].connectors [otherCon].normal; Vector3 stretchDir = Vector3.Scale(otherConTestDir, placeableObjects [obj].allowedScaling); if (stretchDir.sqrMagnitude > 0.001f) { if (!VecMaskCheck(directionMask, Util.VecSign(conRot * stretchDir))) { PlatformingElement newPiece = PlacePiece(start, startConn, obj, con, rot * 90); Vector3 displace = BuildPath(newPiece, end, otherCon, endConn, depth - 1, VecMaskAdd(directionMask, Util.VecSign(conRot * stretchDir)), out newPieces); if (Vector3.Dot(displace, conRot * stretchDir) > 0) { Vector3 projDir = Vector3.Project(displace, (conRot * stretchDir).normalized); displace = Vector3.Exclude(projDir, displace); newPiece.transform.position += displace; StretchPiece(newPiece, projDir, Util.VecSigIndex(projDir), otherCon, con); } else { newPiece.transform.position += displace; } newPieces.AddFirst(newPiece); return(displace); } } for (int i = 0; i < targetDirs.Length; i++) { if ((Vector3.Dot(conRot * otherConTestDir, targetDirs [i]) > tol) && !VecMaskCheck(directionMask, targetDirs [i])) { PlatformingElement newPiece = PlacePiece(start, startConn, obj, con, rot * 90); Vector3 displace = BuildPath(newPiece, end, otherCon, endConn, depth - 1, directionMask, out newPieces); newPiece.transform.position += displace; newPieces.AddFirst(newPiece); return(displace); } } } } } } } } if (Vector3.Dot(startDir, finalDir) > -1 * tol) { for (int obj = 0; obj < placeableObjects.Length; obj++) { for (int con = 0; con < placeableObjects[obj].connectors.Length; con++) { for (int rot = 0; rot < 4; rot++) { Quaternion conRot = Quaternion.AngleAxis(rot * 90, startDir) * Quaternion.FromToRotation(placeableObjects [obj].connectors [con].normal, startDir * -1); if (placeableObjects [obj].allowTilt || ((conRot * Vector3.up).y > tol)) { for (int otherCon = 0; otherCon < placeableObjects[obj].connectors.Length; otherCon++) { if (con != otherCon) { Vector3 otherConTestDir = placeableObjects [obj].connectors [otherCon].normal; if ((Vector3.Dot(conRot * otherConTestDir, finalDir * -1) > tol)) { PlatformingElement newPiece = PlacePiece(start, startConn, obj, con, rot * 90); Vector3 displace = BuildPath(newPiece, end, otherCon, endConn, depth - 1, directionMask, out newPieces); newPiece.transform.position += displace; newPieces.AddFirst(newPiece); return(displace); } } } } } } } } newPieces = new LinkedList <PlatformingElement> (); return(Vector3.one * float.NaN); }