protected override void build() { int index = 0; base.build(); Vector3 position = new Vector3((int)this.x + 0.5f, this.y - .2f, (int)this.z + 0.5f); LandPatch terrain = GameController.Instance.park.getTerrain(position); if (terrain == null) { return; } int lowest = terrain.getLowestHeight(); int start = Mathf.FloorToInt(this.y) - 1; if (start < lowest) { return; } for (int i = start; i >= lowest; i--) { index++; GameObject support; if (this.crossedTiles == 9 || this.crossedTiles == 3 || this.crossedTiles == 6 || this.crossedTiles == 12) { support = UnityEngine.Object.Instantiate <GameObject>(Main.AssetBundleManager.AngledSupportGo[(int)index % Main.AssetBundleManager.AngledSupportGo.Length]); } else { support = UnityEngine.Object.Instantiate <GameObject>(Main.AssetBundleManager.Support_Go[(int)index % Main.AssetBundleManager.Support_Go.Length]); } position.y = (float)i; support.transform.position = position; support.transform.parent = this.transform; support.isStatic = true; if (this.crossedTiles == 9) { support.transform.Rotate(Vector3.forward, 180f); } else if (this.crossedTiles == 3) { support.transform.Rotate(Vector3.forward, 90f); } else if (this.crossedTiles == 6) { support.transform.Rotate(Vector3.forward, 0f); } else if (this.crossedTiles == 12) { support.transform.Rotate(Vector3.forward, -90f); } else { support.transform.Rotate(Vector3.forward, ((index + 4) % 4) * 90f); } //support.GetComponent<Renderer> ().sharedMaterial = baseMaterial; GameObjectHelper.SetUV(support, 14, 15); BoundingBox boundingBox2 = this.instance.AddComponent <BoundingBox>(); boundingBox2.layers = BoundingVolume.Layers.Support; boundingBox2.setBounds(new Bounds(Vector3.up / 2f, Vector3.one)); boundingBox2.setManuallyPositioned(); boundingBox2.setPosition(position, support.transform.rotation); this.boundingVolumes.Add(boundingBox2); supportProxy.Add(boundingBox2, new SupportProxy(true, support)); support.SetActive(false); } RebuildMesh(); }
public override void afterExtrusion(TrackSegment4 trackSegment, GameObject putMeshOnGO) { base.afterExtrusion(trackSegment, putMeshOnGO); WriteToFile(trackSegment.track.TrackedRide.supportConfiguration.supportSettings [0].supportGO.ToString()); WriteToFile(trackSegment.track.TrackedRide.supportConfiguration.supportSettings [0].supportGO.GetType().ToString()); float supportInterval = trackSegment.getLength(0) / ((float)Mathf.RoundToInt(trackSegment.getLength(0) / this.crossBeamSpacing) * 2); float pos = 0; bool isTopperCrosstie = true; int index = 0; Vector3 previousSupportLeft = new Vector3(); Vector3 previousSupportRight = new Vector3(); Vector3 previousSupportTangent = new Vector3(); bool previousFlippedSupportPosts = false; while (pos <= trackSegment.getLength(0) + 0.1f) { index++; float tForDistance = trackSegment.getTForDistance(pos, 0); pos += supportInterval; isTopperCrosstie = !isTopperCrosstie; Vector3 normal = trackSegment.getNormal(tForDistance); Vector3 tangentPoint = trackSegment.getTangentPoint(tForDistance); Vector3 binormal = Vector3.Cross(normal, tangentPoint).normalized; Vector3 trackPivot = base.getTrackPivot(trackSegment.getPoint(tForDistance, 0), normal); if (isTopperCrosstie) { /* * metalTopperCrossTie_1.extrude(trackPivot + binormal * .3f, binormal, normal); * metalTopperCrossTie_1.extrude(trackPivot - binormal * .3f, binormal, normal); * metalTopperCrossTie_1.end(); * metalTopperCrossTie_2.extrude(trackPivot + binormal * .3f, binormal, normal); * metalTopperCrossTie_2.extrude(trackPivot - binormal * .3f, binormal, normal); * metalTopperCrossTie_2.end(); * metalTopperCrossTie_3.extrude(trackPivot - normal * -0.021113f, normal, -1f * binormal); * metalTopperCrossTie_3.extrude(trackPivot - normal * -0.150113f, normal, -1f * binormal); * metalTopperCrossTie_3.end(); * metalTopperCrossTie_4.extrude(trackPivot - normal * -0.021113f, normal, -1f * binormal); * metalTopperCrossTie_4.extrude(trackPivot - normal * -0.150113f, normal, -1f * binormal); * metalTopperCrossTie_4.end(); * metalTopperCrossTie_5.extrude(trackPivot - normal * -0.021113f, normal, -1f * binormal); * metalTopperCrossTie_5.extrude(trackPivot - normal * -0.150113f, normal, -1f * binormal); * metalTopperCrossTie_5.end(); * metalTopperCrossTie_6.extrude(trackPivot - normal * -0.021113f, normal, -1f * binormal); * metalTopperCrossTie_6.extrude(trackPivot - normal * -0.150113f, normal, -1f * binormal); * metalTopperCrossTie_6.end(); * metalTopperCrossTie_7.extrude(trackPivot + tangentPoint * -0.00213f, tangentPoint * -1, normal); * metalTopperCrossTie_7.extrude(trackPivot + tangentPoint * -0.00001f, tangentPoint * -1, normal); * metalTopperCrossTie_7.end(); * metalTopperCrossTie_8.extrude(trackPivot + tangentPoint * -0.00213f, tangentPoint, normal); * metalTopperCrossTie_8.extrude(trackPivot + tangentPoint * -0.00001f, tangentPoint, normal); * metalTopperCrossTie_8.end(); */ } else { float trackDirection = Mathf.Repeat(Mathf.Atan2(tangentPoint.x, tangentPoint.z) * Mathf.Rad2Deg, 360.0f); trackDirection += 45; bool trackFacingXPositive = false; bool trackFacingXNegative = false; bool trackFacingZPositive = false; bool trackFacingZNegative = false; if (trackDirection < 90) { trackFacingZPositive = true; } else if (trackDirection < 180) { trackFacingXPositive = true; } else if (trackDirection < 270) { trackFacingZNegative = true; } else { trackFacingXNegative = true; } float trackBanking = 0f; Vector3 bottomBeamDirection = new Vector3(); if (trackFacingXPositive) { trackBanking = Mathf.Repeat(Mathf.Atan2(normal.z, -normal.y), Mathf.PI * 2.0f) * Mathf.Rad2Deg; if (trackBanking > 180) { trackBanking -= 360; } Vector2 tangentProjection = new Vector2(tangentPoint.x, tangentPoint.z); Vector2 normalProjection = Rotate(tangentProjection, 90); bottomBeamDirection.z = normalProjection.y; bottomBeamDirection.x = normalProjection.x; bottomBeamDirection.Normalize(); bottomBeamDirection *= Math.Abs(trackBanking) > 90 ? 1.0f : -1.0f; } if (trackFacingXNegative) { trackBanking = Mathf.Repeat(Mathf.Atan2(-normal.z, -normal.y), Mathf.PI * 2.0f) * Mathf.Rad2Deg; if (trackBanking > 180) { trackBanking -= 360; } bottomBeamDirection.z = tangentPoint.x; bottomBeamDirection.x = tangentPoint.z; Vector2 tangentProjection = new Vector2(tangentPoint.x, tangentPoint.z); Vector2 normalProjection = Rotate(tangentProjection, 90); bottomBeamDirection.z = normalProjection.y; bottomBeamDirection.x = normalProjection.x; bottomBeamDirection.Normalize(); bottomBeamDirection *= Math.Abs(trackBanking) > 90 ? 1.0f : -1.0f; } if (trackFacingZPositive) { trackBanking = Mathf.Repeat(Mathf.Atan2(normal.x, -normal.y), Mathf.PI * 2.0f) * Mathf.Rad2Deg; if (trackBanking > 180) { trackBanking -= 360; } bottomBeamDirection.z = tangentPoint.x; bottomBeamDirection.x = tangentPoint.z; Vector2 tangentProjection = new Vector2(tangentPoint.x, tangentPoint.z); Vector2 normalProjection = Rotate(tangentProjection, 90); bottomBeamDirection.z = normalProjection.y; bottomBeamDirection.x = normalProjection.x; bottomBeamDirection.Normalize(); bottomBeamDirection *= Math.Abs(trackBanking) <= 90 ? -1.0f : 1.0f; } if (trackFacingZNegative) { trackBanking = Mathf.Repeat(Mathf.Atan2(-normal.x, -normal.y), Mathf.PI * 2.0f) * Mathf.Rad2Deg; if (trackBanking > 180) { trackBanking -= 360; } bottomBeamDirection.z = tangentPoint.x; bottomBeamDirection.x = tangentPoint.z; Vector2 tangentProjection = new Vector2(tangentPoint.x, tangentPoint.z); Vector2 normalProjection = Rotate(tangentProjection, 90); bottomBeamDirection.z = normalProjection.y; bottomBeamDirection.x = normalProjection.x; bottomBeamDirection.Normalize(); bottomBeamDirection *= Math.Abs(trackBanking) > 90 ? 1.0f : -1.0f; } //track beam Vector3 startPoint = trackPivot + normal * 0.159107f + binormal * (beamWidth / 2); Vector3 endPoint = trackPivot + normal * 0.159107f - binormal * (beamWidth / 2); bool equalHeight = Mathf.Abs(startPoint.y - endPoint.y) < 0.97f; //Bottom beam calculation Vector3 bottomBeamPivot = new Vector3(trackPivot.x, Mathf.Min(startPoint.y, endPoint.y), trackPivot.z); Vector3 bottomBeamStart = new Vector3(); Vector3 bottomBeamEnd = new Vector3(); Vector3 bottomBeamBinormal = bottomBeamDirection.normalized; Vector3 planePosition = new Vector3(); Vector3 planeSpanVector1 = endPoint - startPoint; Vector3 planeSpanVector2 = tangentPoint; Vector3 bottomLinePosition = new Vector3(); Vector3 topLinePosition = new Vector3(); Vector3 lineSpanVector = bottomBeamDirection; bool hasTopBars = false; bool attachToStartPoint = false; if (((trackFacingXNegative || trackFacingXPositive) ? -1.0f : 1.0) * ((Mathf.Abs(trackBanking) <= 90) ? -1.0f : 1.0f) * trackBanking < 0) { bottomBeamStart.x = endPoint.x; bottomBeamStart.z = endPoint.z; bottomBeamStart.y = endPoint.y > startPoint.y ? startPoint.y : endPoint.y; bottomBeamEnd = bottomBeamStart - bottomBeamDirection.normalized * beamWidth; planePosition = endPoint; bottomLinePosition = bottomBeamStart; topLinePosition = new Vector3(bottomLinePosition.x, Mathf.Max(startPoint.y, endPoint.y), bottomLinePosition.z); attachToStartPoint = false; } else { bottomBeamEnd.x = startPoint.x; bottomBeamEnd.z = startPoint.z; bottomBeamEnd.y = endPoint.y > startPoint.y ? startPoint.y : endPoint.y; bottomBeamStart = bottomBeamEnd + bottomBeamDirection.normalized * beamWidth; planePosition = startPoint; bottomLinePosition = bottomBeamEnd; topLinePosition = new Vector3(bottomLinePosition.x, Mathf.Max(startPoint.y, endPoint.y), bottomLinePosition.z); attachToStartPoint = true; } if (!(trackSegment is Station)) { if (Mathf.Abs(trackBanking) > 90) { bottomBeamStart.y -= ((Mathf.Abs(trackBanking) / 90) - 1) * invertHeadSpace; bottomBeamEnd.y -= ((Mathf.Abs(trackBanking) / 90) - 1) * invertHeadSpace; if (pos > supportInterval) { //Top beam extruding metalCrossTieExtrude(new Vector3(bottomBeamEnd.x, Mathf.Max(startPoint.y, endPoint.y), bottomBeamEnd.z), -1f * bottomBeamBinormal, Vector3.up); metalCrossTieExtrude(new Vector3(bottomBeamStart.x, Mathf.Max(startPoint.y, endPoint.y), bottomBeamStart.z), -1f * bottomBeamBinormal, Vector3.up); metalCrossTieEnd(); hasTopBars = true; } } //Bottom beam extruding if (Mathf.Abs(trackBanking) > iBeamBankingSwitch && pos > supportInterval) { metalCrossTieExtrude(bottomBeamEnd, -1f * bottomBeamBinormal, Vector3.up); metalCrossTieExtrude(bottomBeamStart, -1f * bottomBeamBinormal, Vector3.up); metalCrossTieEnd(); } Vector3 leftVerticalSupportPost = bottomBeamEnd; Vector3 rightVerticalSupportPost = bottomBeamStart; if (!hasTopBars) { if (trackBanking < iBeamBankingSwitch && trackBanking > -90f) { leftVerticalSupportPost = ((bottomBeamEnd - trackPivot) * 0.8f) + trackPivot; } if (trackBanking > -iBeamBankingSwitch && trackBanking < 90f) { rightVerticalSupportPost = ((bottomBeamStart - trackPivot) * 0.8f) + trackPivot; } } LandPatch terrain = GameController.Instance.park.getTerrain(trackPivot); if (terrain != null) { groundHeight = terrain.getLowestHeight(); groundHeight = Mathf.Min(trackSegment.getStartpoint().y, trackSegment.getEndpoint().y); } else { groundHeight = 0; } Vector3 projectedTangentDirection = tangentPoint; projectedTangentDirection.y = 0; projectedTangentDirection.Normalize(); if (Mathf.Abs(trackBanking) > 90) { leftVerticalSupportPost.y = Mathf.Max(startPoint.y, endPoint.y); rightVerticalSupportPost.y = Mathf.Max(startPoint.y, endPoint.y); } else { leftVerticalSupportPost.y = startPoint.y; rightVerticalSupportPost.y = endPoint.y; } if (pos > supportInterval) { //left post woodenVerticalSupportPostExtruder.extrude(new Vector3(leftVerticalSupportPost.x, leftVerticalSupportPost.y + supportBeamExtension, leftVerticalSupportPost.z), new Vector3(0, -1, 0), projectedTangentDirection); woodenVerticalSupportPostExtruder.extrude(new Vector3(leftVerticalSupportPost.x, groundHeight, leftVerticalSupportPost.z), new Vector3(0, -1, 0), projectedTangentDirection); woodenVerticalSupportPostExtruder.end(); //right post woodenVerticalSupportPostExtruder.extrude(new Vector3(rightVerticalSupportPost.x, rightVerticalSupportPost.y + supportBeamExtension, rightVerticalSupportPost.z), new Vector3(0, -1, 0), projectedTangentDirection); woodenVerticalSupportPostExtruder.extrude(new Vector3(rightVerticalSupportPost.x, groundHeight, rightVerticalSupportPost.z), new Vector3(0, -1, 0), projectedTangentDirection); woodenVerticalSupportPostExtruder.end(); if (Mathf.Abs(trackBanking) > 90 != previousFlippedSupportPosts) { Vector3 temp = previousSupportLeft; previousSupportLeft = previousSupportRight; previousSupportRight = temp; } //Horizontal beams float leftY = Mathf.Min(previousSupportLeft.y, leftVerticalSupportPost.y) - 0.06f; float rightY = Mathf.Min(previousSupportRight.y, rightVerticalSupportPost.y) - 0.06f; float connectionY = Mathf.Min(leftY, rightY); //left horizontal beams bool first = true; while (leftY > groundHeight) { woodenHorizontalSupportPostExtruder.extrude(new Vector3(previousSupportLeft.x, leftY, previousSupportLeft.z), previousSupportTangent, Vector3.up); woodenHorizontalSupportPostExtruder.extrude(new Vector3(leftVerticalSupportPost.x, leftY, leftVerticalSupportPost.z), projectedTangentDirection, Vector3.up); woodenHorizontalSupportPostExtruder.end(); if (first) { leftY -= woodenHorizontalSupportPostExtruder.height * 1.5f; leftY = Mathf.Floor(leftY / supportVerticalGrid) * supportVerticalGrid; first = false; } else { leftY -= supportVerticalGrid; } } first = true; //right horizontal beams while (rightY > groundHeight) { woodenHorizontalSupportPostExtruder.extrude(new Vector3(previousSupportRight.x, rightY, previousSupportRight.z), previousSupportTangent, Vector3.up); woodenHorizontalSupportPostExtruder.extrude(new Vector3(rightVerticalSupportPost.x, rightY, rightVerticalSupportPost.z), projectedTangentDirection, Vector3.up); woodenHorizontalSupportPostExtruder.end(); if (first) { rightY -= woodenHorizontalSupportPostExtruder.height * 1.5f; rightY = Mathf.Floor(rightY / supportVerticalGrid) * supportVerticalGrid; first = false; } else { rightY -= supportVerticalGrid; } } first = true; //connector beams while (connectionY > groundHeight) { if (connectionY < bottomBeamEnd.y) { woodenHorizontalSupportPostExtruder.extrude(new Vector3(rightVerticalSupportPost.x, connectionY, rightVerticalSupportPost.z), Vector3.Cross(projectedTangentDirection, Vector3.up), Vector3.up); woodenHorizontalSupportPostExtruder.extrude(new Vector3(leftVerticalSupportPost.x, connectionY, leftVerticalSupportPost.z), Vector3.Cross(projectedTangentDirection, Vector3.up), Vector3.up); woodenHorizontalSupportPostExtruder.end(); if (!first && connectionY > supportVerticalGrid) { woodenHorizontalSupportPostExtruder.extrude(new Vector3(rightVerticalSupportPost.x, connectionY, rightVerticalSupportPost.z), Vector3.Cross(projectedTangentDirection, Vector3.up), Vector3.up); woodenHorizontalSupportPostExtruder.extrude(new Vector3(leftVerticalSupportPost.x, connectionY - supportVerticalGrid, leftVerticalSupportPost.z), Vector3.Cross(projectedTangentDirection, Vector3.up), Vector3.up); woodenHorizontalSupportPostExtruder.end(); } } if (first) { connectionY -= woodenHorizontalSupportPostExtruder.height * 1.5f; connectionY = Mathf.Floor(connectionY / supportVerticalGrid) * supportVerticalGrid; first = false; } else { connectionY -= supportVerticalGrid; } } } previousSupportLeft = leftVerticalSupportPost; previousSupportRight = rightVerticalSupportPost; previousSupportTangent = projectedTangentDirection; previousFlippedSupportPosts = Mathf.Abs(trackBanking) > 90; } Vector3 intersectionPoint = new Vector3(); if (Math.Abs(trackBanking) > 90 && hasTopBars) { intersectionPoint = IntersectLineAndPlane(planePosition, planeSpanVector1, planeSpanVector2, topLinePosition, lineSpanVector); if (!float.IsNaN(intersectionPoint.x)) { if (attachToStartPoint) { endPoint = intersectionPoint; } else { startPoint = intersectionPoint; } } } else if (Math.Abs(trackBanking) > 0.1) { intersectionPoint = IntersectLineAndPlane(planePosition, planeSpanVector1, planeSpanVector2, bottomLinePosition, lineSpanVector); } if (Mathf.Abs(trackBanking) > 5 && !float.IsNaN(intersectionPoint.x) && (intersectionPoint - planePosition).magnitude > 0.5 && (intersectionPoint - planePosition).magnitude < 1.5) { WriteToFile("IntersectionPoint:" + intersectionPoint); WriteToFile("PlanePosition:" + planePosition); WriteToFile("Magnitude:" + (intersectionPoint - planePosition).magnitude); WriteToFile("Difference:" + (intersectionPoint - planePosition)); WriteToFile("TrackBanking" + trackBanking); WriteToFile("planeSpanVector1" + planeSpanVector1); WriteToFile("planeSpanVector2" + planeSpanVector2); WriteToFile("topLinePosition" + topLinePosition); WriteToFile("bottomLinePasition" + bottomLinePosition); WriteToFile("lineSpanVector" + lineSpanVector); if (attachToStartPoint) { endPoint = intersectionPoint; } else { startPoint = intersectionPoint; } } if (pos > supportInterval) { if (Mathf.Abs(trackBanking) > iBeamBankingSwitch) { metalIBeamExtrude(startPoint, -1f * binormal, equalHeight ? Vector3.up : normal); metalIBeamExtrude(endPoint, -1f * binormal, equalHeight ? Vector3.up : normal); metalIBeamEnd(); } else { float distance = 1 / Mathf.Sin((90 - Mathf.Abs(trackBanking)) * Mathf.Deg2Rad); if (attachToStartPoint) { endPoint = startPoint - ((startPoint - endPoint) * distance); } else { startPoint = endPoint - ((endPoint - startPoint) * distance); } metalCrossTieExtrude(startPoint, -1f * binormal, equalHeight ? Vector3.up : normal); metalCrossTieExtrude(endPoint, -1f * binormal, equalHeight ? Vector3.up : normal); metalCrossTieEnd(); } } } } List <ShapeExtruder> metalShapeExtruders = new List <ShapeExtruder>(); if (useTopperTrack) { metalShapeExtruders.Add(topperLeftRailExtruder); metalShapeExtruders.Add(topperRightRailExtruder); /* * metalShapeExtruders.Add(metalTopperCrossTie_1); * metalShapeExtruders.Add(metalTopperCrossTie_2); * metalShapeExtruders.Add(metalTopperCrossTie_3); * metalShapeExtruders.Add(metalTopperCrossTie_4); * metalShapeExtruders.Add(metalTopperCrossTie_5); * metalShapeExtruders.Add(metalTopperCrossTie_6); * metalShapeExtruders.Add(metalTopperCrossTie_7); * metalShapeExtruders.Add(metalTopperCrossTie_8); */ } else { metalShapeExtruders.Add(iboxLeftRailExtruder); metalShapeExtruders.Add(iboxRightRailExtruder); } if (metalFrontCrossTieExtruder_1.vertices.Count > 0) { metalShapeExtruders.Add(metalFrontCrossTieExtruder_1); metalShapeExtruders.Add(metalFrontCrossTieExtruder_2); metalShapeExtruders.Add(metalFrontCrossTieExtruder_3); metalShapeExtruders.Add(metalRearCrossTieExtruder_1); metalShapeExtruders.Add(metalRearCrossTieExtruder_2); metalShapeExtruders.Add(metalRearCrossTieExtruder_3); } if (metalIBeamExtruder_1.vertices.Count > 0) { metalShapeExtruders.Add(metalIBeamExtruder_1); metalShapeExtruders.Add(metalIBeamExtruder_2); metalShapeExtruders.Add(metalIBeamExtruder_3); } foreach (ShapeExtruder extruder in metalShapeExtruders) { GameObject gameObject = new GameObject("metalObject"); gameObject.transform.parent = putMeshOnGO.transform; gameObject.transform.localPosition = Vector3.zero; gameObject.transform.localRotation = Quaternion.identity; MeshRenderer meshRenderer = gameObject.AddComponent <MeshRenderer>(); meshRenderer.sharedMaterial = metalMaterial; MeshFilter meshFilter = gameObject.AddComponent <MeshFilter>(); Mesh mesh = extruder.getMesh(putMeshOnGO.transform.worldToLocalMatrix); trackSegment.addGeneratedMesh(mesh); meshFilter.mesh = mesh; } }