public CreateBridgeParameters(ValidBridgePoint startPoint, ValidBridgePoint endPoint) { BridgePoints = new List <ValidBridgePoint>() { startPoint, endPoint }; }
//////////////////////////////////////////////////////////////// public void DEBUG_DrawGizmos() { if (m_Bridge.IsValid()) { Gizmos.color = Color.white; for (int i = 0; i < m_Bridge.Points.Length; i++) { bool isFirst = i == 0; bool isLast = i == m_Bridge.Points.Length - 1; if (isFirst) { Gizmos.color = new Color(0.8f, 0.8f, 1.0f); } else if (isLast) { Gizmos.color = new Color(0.8f, 1.0f, 0.8f); } else { Gizmos.color = new Color(0.8f, 0.8f, 0.8f); } ValidBridgePoint bridgePoint = m_Bridge.Points[i]; Gizmos.DrawWireSphere(bridgePoint.PositionWS, 0.5f); if (!isLast) { Gizmos.DrawLine(m_Bridge.Points[i].PositionWS, m_Bridge.Points[i + 1].PositionWS); } //////////////////////////////////////////////////////////////// Gizmos.color = Color.black; Gizmos.DrawLine(bridgePoint.PositionWS, bridgePoint.PositionWS + bridgePoint.WallNormalWS * 0.65f); Gizmos.color = Color.magenta; Gizmos.DrawLine(bridgePoint.PositionWS, bridgePoint.PositionWS + bridgePoint.RightTangentWS * 0.65f); Gizmos.color = Color.cyan; Gizmos.DrawLine(bridgePoint.PositionWS, bridgePoint.PositionWS + bridgePoint.UpTangentWS * 0.65f); } } //////////////////////////////////////////////////////////////// if (m_FirstBridgePoint.IsValid()) { Gizmos.color = new Color(0f, 0f, 1f, 0.3f); Gizmos.DrawWireSphere(m_FirstBridgePoint.PositionWS, 1.0f); } if (m_SecondBridgePoint.IsValid()) { Gizmos.color = new Color(0f, 1f, 0f, 0.3f); Gizmos.DrawWireSphere(m_SecondBridgePoint.PositionWS, 1.0f); } //////////////////////////////////////////////////////////////// }
//////////////////////////////////////////////////////////////// static Vector3 GetFacingDirection(Bridge bridge, int index) { Debug.Assert(bridge.IsValid()); //////////////////////////////////////////////////////////////// ValidBridgePoint bridgePoint = bridge.Points[index]; Vector3 toNextVector = Vector3.zero; if (index != bridge.Points.Length - 1) { ValidBridgePoint previousBridgePoint = bridge.Points[index + 1]; toNextVector = -bridgePoint.PositionWS + previousBridgePoint.PositionWS; } else { ValidBridgePoint nextBridgePoint = bridge.Points[index - 1]; toNextVector = -nextBridgePoint.PositionWS + bridgePoint.PositionWS; } return(toNextVector); }
//////////////////////////////////////////////////////////////// /// <summary> /// Finds the UVs for all points along a bridge /// </summary> /// <param name="inOutBridgePoints"></param> private static void FindUVsForBridge(ref CreateBridgeParameters inOutBridgePoints, out float bridgeLength) { Assert.IsTrue(inOutBridgePoints.BridgePoints.Count >= 2); //////////////////////////////////////////////////////////////// bridgeLength = 0.0f; ValidBridgePoint startPoint = inOutBridgePoints.BridgePoints[0]; startPoint.UV = new Vector2(bridgeLength, 0.0f); for (int i = 0; i < inOutBridgePoints.BridgePoints.Count - 1; i++) { Vector3 pointA = inOutBridgePoints.BridgePoints[i].PositionWS; Vector3 pointB = inOutBridgePoints.BridgePoints[i + 1].PositionWS; bridgeLength += Vector3.Distance(pointA, pointB); ValidBridgePoint bridgePoint = inOutBridgePoints.BridgePoints[i + 1]; bridgePoint.UV = new Vector2(bridgeLength, 0.0f); inOutBridgePoints.BridgePoints[i + 1] = bridgePoint; } }
/*////////////////////////////////////////////////////////////// * //// Private Helpers //// * //////////////////////////////////////////////////////////////*/ /// <summary> /// Finds all bridge points a bridge would have. /// </summary> /// <param name="validBridgeInput"></param> /// <returns></returns> private static void FindMirrorPointsForBridge(ref CreateBridgeParameters inOutBridgePoints) { Assert.IsTrue(inOutBridgePoints.BridgePoints.Count >= 2); #if DEBUG int debugCount = 0; #endif //////////////////////////////////////////////////////////////// // For both start & end point of the bridge parameters: // If the point is a mirror, try to find the point before. Continue until no mirror is hit anymore. //////////////////////////////////////////////////////////////// int indexMirrorPoint = 0; int indexOther = 1; // Start Point while (inOutBridgePoints.BridgePoints[indexMirrorPoint].IsMirror) { Vector3 backToFront = inOutBridgePoints.BridgePoints[indexOther].PositionWS - inOutBridgePoints.BridgePoints[indexMirrorPoint].PositionWS; Vector3 mirroredVector = Vector3.Reflect(backToFront, inOutBridgePoints.BridgePoints[indexMirrorPoint].WallNormalWS); Vector3 mirroredVectorN = mirroredVector.normalized; Vector3 startPosition = inOutBridgePoints.BridgePoints[indexMirrorPoint].PositionWS + mirroredVectorN * BridgeOptions.RAYCAST_PADDING; Ray ray = new Ray(startPosition, mirroredVector * BridgeOptions.MAX_BRIDGE_LENGTH); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { RawBridgePoint newPoint; if (ValidateBridgePoint(hit, out newPoint) == BridgePointValidationResult.Success) { Vector3 wallExtendRight = Vector3.Cross(hit.normal, Vector3.up); ValidBridgePoint newValidPoint = new ValidBridgePoint(newPoint.PositionWS, newPoint.WallNormalWS, newPoint.IsMirror, wallExtendRight, Vector3.up, Vector3.zero); inOutBridgePoints.BridgePoints.Insert(indexMirrorPoint, newValidPoint); } #if DEBUG Assert.IsTrue(debugCount < 20); #endif continue; } break; } // End Point indexMirrorPoint = inOutBridgePoints.BridgePoints.Count - 1; indexOther = inOutBridgePoints.BridgePoints.Count - 2; // End Point while (inOutBridgePoints.BridgePoints[indexMirrorPoint].IsMirror) { Vector3 backToFront = inOutBridgePoints.BridgePoints[indexMirrorPoint].PositionWS - inOutBridgePoints.BridgePoints[indexOther].PositionWS; Vector3 mirroredVector = Vector3.Reflect(backToFront, inOutBridgePoints.BridgePoints[indexMirrorPoint].WallNormalWS); Vector3 mirroredVectorN = mirroredVector.normalized; Vector3 startPosition = inOutBridgePoints.BridgePoints[indexMirrorPoint].PositionWS + mirroredVectorN * BridgeOptions.RAYCAST_PADDING; Ray ray = new Ray(startPosition, mirroredVector * BridgeOptions.MAX_BRIDGE_LENGTH); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { RawBridgePoint newPoint; if (ValidateBridgePoint(hit, out newPoint) == BridgePointValidationResult.Success) { Vector3 wallExtendRight = Vector3.Cross(hit.normal, Vector3.up); ValidBridgePoint newValidPoint = new ValidBridgePoint(newPoint.PositionWS, newPoint.WallNormalWS, newPoint.IsMirror, wallExtendRight, Vector3.up, Vector3.zero); inOutBridgePoints.BridgePoints.Add(newValidPoint); } #if DEBUG Assert.IsTrue(debugCount < 20); #endif indexMirrorPoint = inOutBridgePoints.BridgePoints.Count - 1; indexOther = inOutBridgePoints.BridgePoints.Count - 2; continue; } break; } }
//////////////////////////////////////////////////////////////// static void AppendBridgeMeshVertices(ref List <BridgeMeshVertex> inOutBridgeMeshVertices, ValidBridgePoint bridgePoint, bool isEvenPoint) { BridgeMeshVertex leftVertex = new BridgeMeshVertex(); BridgeMeshVertex rightVertex = new BridgeMeshVertex(); //////////////////////////////////////////////////////////////// // General // Depending on if we are an even or uneven point, we need to invert our "right" to make sure it is also the bridges "right" float facingFactor = isEvenPoint ? 1.0f : -1.0f; //////////////////////////////////////////////////////////////// // Inner Position leftVertex.InnerPositionWS = bridgePoint.PositionWS; rightVertex.InnerPositionWS = bridgePoint.PositionWS; //////////////////////////////////////////////////////////////// // Position float halfBridgeWidth = BridgeOptions.WIDTH_WS / 2.0f; leftVertex.PositionWS = bridgePoint.PositionWS + facingFactor * bridgePoint.RightTangentWS * halfBridgeWidth; rightVertex.PositionWS = bridgePoint.PositionWS - facingFactor * bridgePoint.RightTangentWS * halfBridgeWidth; //////////////////////////////////////////////////////////////// // Normal leftVertex.NormalWS = Vector3.up; // TODO: Calculate this from the positions themselves to make it more accurate. rightVertex.NormalWS = Vector3.up; //////////////////////////////////////////////////////////////// // UV // As the left and the right vertex might be differently far away from the previous points, // we need to calculate the UVs per vertex and cannot use the UVs of the points. float leftVertexV = bridgePoint.UV.x; float rightVertexV = bridgePoint.UV.x; if (inOutBridgeMeshVertices.Count >= 2) { BridgeMeshVertex prevVertexLeft = inOutBridgeMeshVertices[inOutBridgeMeshVertices.Count - 2]; BridgeMeshVertex prevVertexRight = inOutBridgeMeshVertices[inOutBridgeMeshVertices.Count - 1]; leftVertexV = prevVertexLeft.UV.y + Vector3.Distance(prevVertexLeft.PositionWS, leftVertex.PositionWS); rightVertexV = prevVertexRight.UV.y + Vector3.Distance(prevVertexRight.PositionWS, rightVertex.PositionWS); } leftVertex.UV = new Vector2(0.0f, leftVertexV); rightVertex.UV = new Vector2(1.0f, rightVertexV); //////////////////////////////////////////////////////////////// inOutBridgeMeshVertices.Add(leftVertex); inOutBridgeMeshVertices.Add(rightVertex); }
public static BridgeMesh CreateBridgeMesh(Bridge bridge) { Debug.Assert(bridge.IsValid()); // For each bridgePoint [e.g, 0 or 1], we want to add the two bridge vertices [L, R] // // L0------------------L1 - // | | | // | | < BridgeWidth / 2 // | | | // 0-------------------1 - // | | // | | // | | // R0------------------R1 //////////////////////////////////////////////////////////////// int bridgePointCount = bridge.Points.Length; List <BridgeMeshVertex> vertices = new List <BridgeMeshVertex>(); for (int i = 0; i < bridgePointCount; i++) { ValidBridgePoint bridgePoint = bridge.Points[i]; //////////////////////////////////////////////////////////////// bool isEvenPoint = (i % 2 == 0); AppendBridgeMeshVertices(ref vertices, bridgePoint, isEvenPoint); } const int VERTS_PER_BRIDGEPOINT = 2; int triangleCount = VERTS_PER_BRIDGEPOINT * bridgePointCount; List <int> indicies = new List <int>(); for (int segementID = 0; segementID < bridgePointCount - 1; segementID++) { int nextSegmentID = segementID + 1; int vertexIDThisSegmentLeft = VERTS_PER_BRIDGEPOINT * segementID + 0; int vertexIDThisSegmentRight = VERTS_PER_BRIDGEPOINT * segementID + 1; int vertexIDNextSegmentLeft = VERTS_PER_BRIDGEPOINT * nextSegmentID + 0; int vertexIDNextSegmentRight = VERTS_PER_BRIDGEPOINT * nextSegmentID + 1; // Triangle 1: R0, L0, L1 indicies.Add(vertexIDThisSegmentRight); indicies.Add(vertexIDThisSegmentLeft); indicies.Add(vertexIDNextSegmentLeft); // Triangle 2: R0, L1, R1 indicies.Add(vertexIDThisSegmentRight); indicies.Add(vertexIDNextSegmentLeft); indicies.Add(vertexIDNextSegmentRight); } BridgeMesh bridgeMesh = new BridgeMesh(vertices, indicies); return(bridgeMesh); }